#include <rtc.h>
#include <ds1302.h>
+uint8_t ds1302_present;
+
void ds1302_send_byte(uint8_t byte)
{
uint8_t i;
uint8_t platform_rtc_secs(void)
{
uint8_t buffer;
- ds1302_read_clock(&buffer, 1); /* read out only the seconds value */
- return uint8_from_bcd(buffer & 0x7F); /* mask off top bit (clock-halt) */
+ if (ds1302_present) {
+ ds1302_read_clock(&buffer, 1); /* read out only the seconds value */
+ return uint8_from_bcd(buffer & 0x7F); /* mask off top bit (clock-halt) */
+ }
+ return 0xFF;
}
static uint8_t rtc_buf[8];
struct cmos_rtc cmos;
uint8_t *p = cmos.data.bytes;
+ if (!ds1302_present) {
+ udata.u_error = EOPNOTSUPP;
+ return -1;
+ }
+
if (udata.u_count < len)
len = udata.u_count;
int platform_rtc_write(void)
{
- udata.u_error = -EOPNOTSUPP;
+ udata.u_error = EOPNOTSUPP;
return -1;
}
#define __DS1302_DOT_H__
/* public interface */
-void ds1302_init(void);
+uint8_t ds1302_init(void);
uint8_t platform_rtc_secs(void);
void ds1302_read_clock(uint8_t *buffer, uint8_t length);
int platform_rtc_read(void);
int platform_rtc_write(void);
+extern uint8_t ds1302_present;
+
#ifdef _DS1302_PRIVATE
/* consult the DS1302 datasheet for data format;
http://datasheets.maximintegrated.com/en/ds/DS1302.pdf table 3 */
irqrestore(irq);
}
-void ds1302_check_rtc(void)
+static uint8_t bad_bcd(uint8_t x, uint8_t max)
+{
+ uint8_t c;
+
+ c = x >> 4;
+ x &= 15;
+ if (c > 9 || x > 9)
+ return 1;
+ c = c * 10 + x;
+ if (c > max)
+ return 1;
+ return 0;
+}
+
+uint8_t ds1302_check_rtc(void)
{
uint8_t buffer[7];
ds1302_read_clock(buffer, 7); /* read all calendar data */
+ if (bad_bcd(buffer[0] & 0x7F, 59) ||
+ bad_bcd(buffer[1], 59) ||
+ bad_bcd(buffer[3], 31) ||
+ bad_bcd(buffer[4], 12) ||
+ bad_bcd(buffer[5], 7) ||
+ bad_bcd(buffer[6], 99))
+ return 0;
+
if(buffer[0] & 0x80){ /* is the clock halted? */
kputs("ds1302: start clock\n");
ds1302_write_seconds(buffer[0] & 0x7F); /* start it */
}
+ ds1302_read_clock(buffer, 7);
+ if (buffer[0] & 0x80)
+ return 0;
+ return 1;
}
-void ds1302_init(void)
+uint8_t ds1302_init(void)
{
- time_t tod;
-
/* initialise the hardware into a sensible state */
ds1302_set_pin_data_driven(true);
ds1302_set_pin_data(false);
ds1302_set_pin_ce(false);
ds1302_set_pin_clk(false);
- ds1302_check_rtc();
- wrtime(&tod);
+ if (ds1302_check_rtc() == 0)
+ return 0;
+ ds1302_present = 1;
+ return 1;
}