Kernel: ds1302: Start clock on boot if it is stopped
authorWill Sowerbutts <will@sowerbutts.com>
Sun, 22 Jan 2017 22:43:58 +0000 (22:43 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Sun, 22 Jan 2017 22:43:58 +0000 (22:43 +0000)
Kernel/dev/ds1302.c
Kernel/dev/ds1302.h
Kernel/dev/ds1302_discard.c

index 95c3d38..b400987 100644 (file)
@@ -3,6 +3,8 @@
 /* 2014-12-30 Will Sowerbutts                                            */
 /*-----------------------------------------------------------------------*/
 
+#define _DS1302_PRIVATE
+
 #include <kernel.h>
 #include <kdata.h>
 #include <stdbool.h>
index e57129b..94f3f83 100644 (file)
@@ -4,9 +4,12 @@
 /* public interface */
 void ds1302_init(void);
 uint8_t rtc_secs(void);
+
+#ifdef _DS1302_PRIVATE
 /* consult the DS1302 datasheet for data format;
    http://datasheets.maximintegrated.com/en/ds/DS1302.pdf table 3 */
 void ds1302_read_clock(uint8_t *buffer, uint8_t length);
+void ds1302_send_byte(uint8_t byte);
 
 uint8_t uint8_from_bcd(uint8_t value);
 
@@ -16,5 +19,6 @@ void ds1302_set_pin_ce(bool state);
 void ds1302_set_pin_data(bool state);
 bool ds1302_get_pin_data(void);
 void ds1302_set_pin_data_driven(bool state); /* 0=tristate for input, 1=driven for output */
+#endif
 
 #endif
index 13aeecb..b26a6cf 100644 (file)
@@ -3,6 +3,8 @@
 /* 2014-12-30 Will Sowerbutts                                            */
 /*-----------------------------------------------------------------------*/
 
+#define _DS1302_PRIVATE
+
 #include <kernel.h>
 #include <kdata.h>
 #include <stdbool.h>
@@ -65,6 +67,24 @@ muldone:
 
 static const uint16_t mktime_moffset[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
 
+void ds1302_write_register(uint8_t reg, uint8_t val)
+{
+    ds1302_set_pin_ce(true);
+    ds1302_send_byte(reg);
+    ds1302_send_byte(val);
+    ds1302_set_pin_ce(false);
+    ds1302_set_pin_clk(false);
+}
+
+void ds1302_write_seconds(uint8_t seconds)
+{
+    irqflags_t irq = di();
+    ds1302_write_register(0x8E, 0x00);    /* write to control register: disable write-protect */
+    ds1302_write_register(0x80, seconds); /* write to seconds register (bit 7 set: halts clock) */
+    ds1302_write_register(0x8E, 0x80);    /* write to control register: enable write-protect */
+    irqrestore(irq);
+}
+
 uint32_t ds1302_read_rtc(void)
 {
     uint32_t ret;
@@ -83,6 +103,11 @@ uint32_t ds1302_read_rtc(void)
     minute = uint8_from_bcd(buffer[1]);
     second = uint8_from_bcd(buffer[0] & 0x7F);
 
+    if(buffer[0] & 0x80){ /* is the clock halted? */
+        kputs("ds1302: start clock\n");
+        ds1302_write_seconds(second); /* start it */
+    }
+
     if(year < 70)
         year += 100;