rtc implementation
[cortex-from-scratch] / rtc.c
1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
2  * 
3  * $LOG$
4  * 2019/7/30 - ROBIN KRENS      
5  * Initial version 
6  * 
7  * $DESCRIPTION$
8  * 
9  * */
10
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include <sys/robsys.h>
16 #include <sys/mmap.h>
17
18 #include <lib/regfunc.h>
19 #include <lib/stdio.h>
20
21
22 static void periodic_intr() {
23
24         while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
25         rsetbit(RTC_CRL, 4);
26         
27         rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt
28         
29         while(!rchkbit(RTC_CRL, 5)); 
30
31         rwrite(RTC_PRLL, 0x7FFF); // 1 second
32         rclrbit(RTC_CRL, 4);
33         while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
34 }
35
36 static void calibrate_rtc() {
37
38
39 //      rsetbit(BKP_RTCCR, 7); // enable CC0, 
40 //      while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
41 //      rsetbit(RTC_CRL, 4);
42
43         // Set up and check tamper pin
44         
45 //      rclrbit(RTC_CRL, 4);
46 //      while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
47 }
48
49 void * rtc_handler() {
50
51         //cputs("TICKING IN REAL TIME\n");
52         rclrbit(RTC_CRL, 0);
53 }
54
55 static void setup_rtc() {
56
57 // TODO: long time to get stable?
58         /* Enable PWREN and BKPEN */
59         rsetbit(RCC_APB1ENR, 28);
60         rsetbit(RCC_APB1ENR, 27);
61
62         /* Enable access to backup registers and RTC */
63         rsetbit(PWR_CR, 8);
64
65         rsetbit(RCC_BDCR, 0); /* LSE enable */
66         while(!rchkbit(RCC_BDCR, 1)); /* wait for LSE to come up */
67         
68         rsetbitsfrom(RCC_BDCR, 8, 0x1); /* use LSE as RTC source */
69         rsetbit(RCC_BDCR, 15); /* enable RTC */
70         
71         ivt_set_gate(19, rtc_handler, 0); /* setup interrupt handler */
72
73 //      calibrate_rtc(); TODO: TAMPER PIN?
74         
75         periodic_intr();// setup periodic interrupt
76
77 }
78
79 void rtc_init() {
80
81 #ifdef ENABLE_RTC
82         setup_rtc();
83 #endif
84
85 }