basic implemtation general purpose clock and tinyprintf
[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 #include <drivers/led.h>
22
23
24 static void periodic_intr() {
25
26         while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
27         rsetbit(RTC_CRL, 4); // start configure
28         
29         rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt
30         
31         while(!rchkbit(RTC_CRL, 5)); 
32
33         rwrite(RTC_PRLL, 0x7FFF); // 1 second
34         rclrbit(RTC_CRL, 4); // stop configure
35         while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
36         rsetbit(NVIC_ISER0, 3); // enable in register vector
37 }
38
39 static void calibrate_rtc() {
40
41
42 //      rsetbit(BKP_RTCCR, 7); // enable CC0, 
43 //      while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
44 //      rsetbit(RTC_CRL, 4);
45
46         // Set up and check tamper pin
47         
48 //      rclrbit(RTC_CRL, 4);
49 //      while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
50 }
51
52 void * rtc_handler() {
53
54         //cputs("TICKING IN REAL TIME\n");
55         //uint32_t curr = *RTC_CNTL;
56         int even = *RTC_CNTL % 2;
57         (!even) ? led_off() : led_on();
58
59         rclrbit(RTC_CRL, 0);
60 }
61
62 static void setup_rtc() {
63
64 // TODO: long time to get stable?
65         /* Enable PWREN and BKPEN */
66         rsetbit(RCC_APB1ENR, 28);
67         rsetbit(RCC_APB1ENR, 27);
68
69         /* Enable access to backup registers and RTC */
70         rsetbit(PWR_CR, 8);
71
72         rsetbit(RCC_BDCR, 0); /* LSE enable */
73         while(!rchkbit(RCC_BDCR, 1)); /* wait for LSE to come up */
74         
75         rsetbitsfrom(RCC_BDCR, 8, 0x1); /* use LSE as RTC source */
76         rsetbit(RCC_BDCR, 15); /* enable RTC */
77         
78         ivt_set_gate(19, rtc_handler, 0); /* setup interrupt handler */
79
80 //      calibrate_rtc(); TODO: TAMPER PIN?
81         
82         periodic_intr();// setup periodic interrupt
83
84 }
85
86 void rtc_init() {
87
88 #ifdef ENABLE_RTC
89         setup_rtc();
90 #endif
91
92 }