st7735s: signs of life
[cortex-from-scratch] / rtc.c
diff --git a/rtc.c b/rtc.c
index 9ffffc7..a6a834f 100644 (file)
--- a/rtc.c
+++ b/rtc.c
@@ -1,10 +1,17 @@
 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
  * 
  * $LOG$
- * 2019/7/30 - ROBIN KRENS     
+ * 2019/8/14 - ROBIN KRENS     
  * Initial version 
  * 
  * $DESCRIPTION$
+ * Real Time Clock configuration. A Real Time Clock is configured to use
+ * the more accurate external chrystal (LSE) and ticks at exactly
+ * one second. (Can be further calibrated using a tamper pin)
+ * Each clock tick triggers an interrupt and invokes the real time clock
+ * service routine.
+ *
+ * Note: this is not the Cortex M3/M4 SysTick!
  * 
  * */
 
 #include <sys/mmap.h>
 
 #include <lib/regfunc.h>
-#include <lib/stdio.h>
+#include <lib/tinyprintf.h>
 
+#include <drivers/led.h>
+#include <drivers/tm1637.h>
+#include <drivers/mk450_joystick.h>
 
-static void periodic_intr() {
 
-       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
-       rsetbit(RTC_CRL, 4);
-       
-       rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt
-       
-       while(!rchkbit(RTC_CRL, 5)); 
+/* This handler is invoked each clock tick. I've included two examples 
+ * one is writing the clock count to a 4 grid led display. Another is a simple LED blink */
+void * rtc_handler() {
 
-       rwrite(RTC_PRLL, 0x7FFF); // 1 second
-       rclrbit(RTC_CRL, 4);
-       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
-}
+       // Real time clock output on a LED display 
+       /* int cntvalue = *RTC_CNTL;
+       if (cntvalue < 9999) {
 
-static void calibrate_rtc() {
+       unsigned char dn[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};
+               
+       int grid0, grid1, grid2, grid3;
 
+       grid0 = cntvalue % 10;
+       grid1 = ((cntvalue % 100) - grid0) / 10;
+       grid2 = ((cntvalue % 1000) - grid0 - grid1) / 100;
+        grid3 = ((cntvalue % 10000) - grid0 - grid1 - grid2) / 1000;
 
-//     rsetbit(BKP_RTCCR, 7); // enable CC0, 
-//     while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
-//     rsetbit(RTC_CRL, 4);
+       //printf("%d, %d, %d, %d\n", grid0, grid1, grid2, grid3);
+       
+       char current[4] = { dn[grid3], dn[grid2], dn[grid1], dn[grid0] }; 
 
-       // Set up and check tamper pin
+       for (int i = 0; i < 4; i++) {
+               set_grid(i, current[i], false);
+       }
+
+       set_display(true, 0); 
+       } */
+
+       // Simple LED blink 
+       uint32_t curr = *RTC_CNTL;
+       int even = *RTC_CNTL % 2;
+       (!even) ? led_off() : led_on();
        
-//     rclrbit(RTC_CRL, 4);
-//     while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+       // Double Axis Joystick 
+       //printf("X: %x\n", mk450_getx());
+       //printf("Y: %x\n", mk450_gety());
+
+       rclrbit(RTC_CRL, 0); /* clear interrupt flag */
 }
 
-void * rtc_handler() {
+/* Enable a periodic interrupt. At each clock count a interrupt is triggered
+ * and consequently the handler is invoked. */
+static void periodic_intr() {
 
-       //cputs("TICKING IN REAL TIME\n");
-       rclrbit(RTC_CRL, 0);
+       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+       rsetbit(RTC_CRL, 4); // start configure
+       rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt
+       
+       while(!rchkbit(RTC_CRL, 5)); 
+       rwrite(RTC_PRLL, 0x7FFF); // 0x7FFF equals 1 second clock configuration 
+       rclrbit(RTC_CRL, 4); // stop configure
+       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+       rsetbit(NVIC_ISER0, 3); // enable in register vector
 }
 
+/* Setup the Real time clock to work with the Low speed external 
+ * chrystal (32.768 kHz) */
 static void setup_rtc() {
 
-// TODO: long time to get stable?
        /* Enable PWREN and BKPEN */
        rsetbit(RCC_APB1ENR, 28);
        rsetbit(RCC_APB1ENR, 27);
@@ -70,12 +104,23 @@ static void setup_rtc() {
        
        ivt_set_gate(19, rtc_handler, 0); /* setup interrupt handler */
 
-//     calibrate_rtc(); TODO: TAMPER PIN?
+       //calibrate_rtc(); // uncomment if need, needs TAMPER PIN
        
        periodic_intr();// setup periodic interrupt
 
 }
 
+/* Function to calibrate the RTC even more accurate. 
+ * Output to a so-called tamper pin. Uncomment if needed */
+static void calibrate_rtc() {
+               /* rsetbit(BKP_RTCCR, 7); // enable CC0, 
+       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+       rsetbit(RTC_CRL, 4);
+       // Set up and check tamper pin
+       rclrbit(RTC_CRL, 4);
+       while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated */
+}
+
 void rtc_init() {
 
 #ifdef ENABLE_RTC