From 4c662f61a0c913aafe00684a54ea5ac105a8b74b Mon Sep 17 00:00:00 2001 From: Will Sowerbutts Date: Sun, 22 Jan 2017 22:43:58 +0000 Subject: [PATCH] Kernel: ds1302: Start clock on boot if it is stopped --- Kernel/dev/ds1302.c | 2 ++ Kernel/dev/ds1302.h | 4 ++++ Kernel/dev/ds1302_discard.c | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Kernel/dev/ds1302.c b/Kernel/dev/ds1302.c index 95c3d381..b4009872 100644 --- a/Kernel/dev/ds1302.c +++ b/Kernel/dev/ds1302.c @@ -3,6 +3,8 @@ /* 2014-12-30 Will Sowerbutts */ /*-----------------------------------------------------------------------*/ +#define _DS1302_PRIVATE + #include #include #include diff --git a/Kernel/dev/ds1302.h b/Kernel/dev/ds1302.h index e57129b6..94f3f835 100644 --- a/Kernel/dev/ds1302.h +++ b/Kernel/dev/ds1302.h @@ -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 diff --git a/Kernel/dev/ds1302_discard.c b/Kernel/dev/ds1302_discard.c index 13aeecb8..b26a6cfe 100644 --- a/Kernel/dev/ds1302_discard.c +++ b/Kernel/dev/ds1302_discard.c @@ -3,6 +3,8 @@ /* 2014-12-30 Will Sowerbutts */ /*-----------------------------------------------------------------------*/ +#define _DS1302_PRIVATE + #include #include #include @@ -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; -- 2.34.1