diff options
author | Leo C | 2014-08-23 19:34:22 +0200 |
---|---|---|
committer | Leo C | 2014-08-23 19:34:22 +0200 |
commit | 61b0cfe9df810db4fbca78e5f880d61c5063f324 (patch) | |
tree | ec9b73a87afa5fdd90acc3c7309104399db104b7 /avr/pcf8583.c | |
parent | 21a24f90c5aaaaf13f91716208b32cde163c5918 (diff) | |
download | z180-stamp-61b0cfe9df810db4fbca78e5f880d61c5063f324.zip |
Add date rtc i2c
Diffstat (limited to 'avr/pcf8583.c')
-rw-r--r-- | avr/pcf8583.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/avr/pcf8583.c b/avr/pcf8583.c new file mode 100644 index 0000000..d33c9b0 --- /dev/null +++ b/avr/pcf8583.c @@ -0,0 +1,106 @@ +/* + * Date & Time support for Philips PCF8583 RTC + */ + +/* #define DEBUG */ + +#include "common.h" +#include <stdlib.h> +#include "debug.h" +#include "command.h" +#include "rtc.h" +#include "i2c.h" + +#define REG_CS 0x00 /* control/status */ +#define REG_CSEC 0x01 /* hundredth of a second */ +#define REG_SEC 0x02 /* seconds */ +#define REG_MIN 0x03 /* minutes */ +#define REG_HOUR 0x04 /* hours */ +#define REG_YRDATE 0x05 /* year/date */ +#define REG_WDMON 0x06 /* weekdays/months */ +#define NR_OF_REGS 7 + + +/* ------------------------------------------------------------------------- */ + +static uint_fast8_t bcd2bin(uint8_t val) +{ + return (val >> 4) * 10 + (val & 0x0f); +} + +static uint8_t bin2bcd (uint_fast8_t val) +{ + div_t d = div(val, 10); + + return (d.quot << 4) | d.rem; +} + + +int rtc_get (struct rtc_time *tmp) +{ + int rel = 0; + uint8_t rtcbuf[NR_OF_REGS]; + uint16_t year; + + i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, rtcbuf, NR_OF_REGS); + i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0x10, 1, (uint8_t *) &year, 2); + + debug("Get RTC year: %u, year/date: %02x, wdays/month: %02x, " + "hour: %02x, min: %02x, sec: %02x, (stat: %02x)\n", year, + rtcbuf[6], rtcbuf[5], rtcbuf[4], rtcbuf[3], rtcbuf[2], rtcbuf[0]); + + tmp->tm_sec = bcd2bin (rtcbuf[REG_SEC] & 0x7F); + tmp->tm_min = bcd2bin (rtcbuf[REG_MIN] & 0x7F); + tmp->tm_hour = bcd2bin (rtcbuf[REG_HOUR] & 0x3F); + tmp->tm_mday = bcd2bin (rtcbuf[REG_YRDATE] & 0x3F); + tmp->tm_mon = bcd2bin (rtcbuf[REG_WDMON] & 0x1F); + while (year%4 < (rtcbuf[REG_YRDATE]>>6)) { + year++; + /* TODO: update RTC ram */ + } + tmp->tm_year = year; + tmp->tm_wday = rtcbuf[REG_WDMON] >> 5; + tmp->tm_yday = 0; + tmp->tm_isdst= 0; + + + debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; +} + +int rtc_set (struct rtc_time *tmp) +{ + uint8_t rtcbuf[NR_OF_REGS]; + + debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + rtcbuf[REG_CS] = 0x84; + rtcbuf[REG_CSEC] = 0x00; + rtcbuf[REG_WDMON ] = bin2bcd(tmp->tm_mon) | ((tmp->tm_wday) << 5); + rtcbuf[REG_YRDATE] = ((tmp->tm_year % 4) << 6) | bin2bcd(tmp->tm_mday); + rtcbuf[REG_HOUR ] = bin2bcd(tmp->tm_hour); + rtcbuf[REG_MIN ] = bin2bcd(tmp->tm_min); + rtcbuf[REG_SEC ] = bin2bcd(tmp->tm_sec); + + i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, rtcbuf, NR_OF_REGS); + i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0x10, 1, (uint8_t *) &tmp->tm_year, 2); + rtcbuf[REG_CS] = 0x04; + i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, rtcbuf, 1); + + + return 0; +} + +void rtc_reset (void) +{ + uint8_t c = 0; + + i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, &c, 1); +} + + |