Index: firmware/export/rtc.h =================================================================== --- firmware/export/rtc.h (revision 22521) +++ firmware/export/rtc.h (arbetskopia) @@ -24,13 +24,19 @@ #include #include "system.h" #include "config.h" +#include "time.h" +/* Macros used to convert to and from BCD, used in various rtc drivers + this is the wrong place but misc.h is in apps... */ +#define BCD2DEC(X) (((((X)>>4) & 0x0f) * 10) + ((X) & 0xf)) +#define DEC2BCD(X) ((((X)/10)<<4) | ((X)%10)) + #if CONFIG_RTC /* Common functions for all targets */ void rtc_init(void); -int rtc_read_datetime(unsigned char* buf); -int rtc_write_datetime(unsigned char* buf); +int rtc_read_datetime(struct tm *tm); +int rtc_write_datetime(const struct tm *tm); #if CONFIG_RTC == RTC_M41ST84W Index: firmware/include/timefuncs.h =================================================================== --- firmware/include/timefuncs.h (revision 22521) +++ firmware/include/timefuncs.h (arbetskopia) @@ -35,3 +35,4 @@ #endif #endif /* _TIMEFUNCS_H_ */ + Index: firmware/common/timefuncs.c =================================================================== --- firmware/common/timefuncs.c (revision 22521) +++ firmware/common/timefuncs.c (arbetskopia) @@ -27,9 +27,7 @@ #include "timefuncs.h" #include "debug.h" -#if !defined SIMULATOR || !CONFIG_RTC static struct tm tm; -#endif /* !defined SIMULATOR || !CONFIG_RTC */ #if !CONFIG_RTC static void fill_default_tm(struct tm *tm) @@ -62,7 +60,6 @@ struct tm *get_time(void) { -#ifndef SIMULATOR #if CONFIG_RTC static long timeout = 0; @@ -71,77 +68,26 @@ { /* Once per second, 1/10th of a second off */ timeout = HZ * (current_tick / HZ + 1) + HZ / 5; -#if CONFIG_RTC != RTC_JZ47XX - char rtcbuf[7]; - rtc_read_datetime(rtcbuf); + rtc_read_datetime(&tm); - tm.tm_sec = ((rtcbuf[0] & 0x70) >> 4) * 10 + (rtcbuf[0] & 0x0f); - tm.tm_min = ((rtcbuf[1] & 0x70) >> 4) * 10 + (rtcbuf[1] & 0x0f); - tm.tm_hour = ((rtcbuf[2] & 0x30) >> 4) * 10 + (rtcbuf[2] & 0x0f); - tm.tm_wday = rtcbuf[3] & 0x07; - tm.tm_mday = ((rtcbuf[4] & 0x30) >> 4) * 10 + (rtcbuf[4] & 0x0f); - tm.tm_mon = ((rtcbuf[5] & 0x10) >> 4) * 10 + (rtcbuf[5] & 0x0f) - 1; -#ifdef IRIVER_H300_SERIES - /* Special kludge to coexist with the iriver firmware. The iriver firmware - stores the date as 1965+nn, and allows a range of 1980..2064. We use - 1964+nn here to make leap years work correctly, so the date will be one - year off in the iriver firmware but at least won't be reset anymore. */ - tm.tm_year = ((rtcbuf[6] & 0xf0) >> 4) * 10 + (rtcbuf[6] & 0x0f) + 64; -#else /* Not IRIVER_H300_SERIES */ - tm.tm_year = ((rtcbuf[6] & 0xf0) >> 4) * 10 + (rtcbuf[6] & 0x0f) + 100; -#endif /* IRIVER_H300_SERIES */ - tm.tm_yday = 0; /* Not implemented for now */ tm.tm_isdst = -1; /* Not implemented for now */ -#else /* CONFIG_RTC == RTC_JZ47XX */ - rtc_read_datetime((unsigned char*)&tm); -#endif /* CONFIG_RTC */ } #else /* No RTC */ fill_default_tm(&tm); #endif /* RTC */ return &tm; - -#else /* SIMULATOR */ -#if CONFIG_RTC - time_t now = time(NULL); - return localtime(&now); -#else /* Simulator, no RTC */ - fill_default_tm(&tm); - return &tm; -#endif -#endif /* SIMULATOR */ } int set_time(const struct tm *tm) { #if CONFIG_RTC int rc; -#if CONFIG_RTC != RTC_JZ47XX - char rtcbuf[7]; -#endif - + if (valid_time(tm)) { -#if CONFIG_RTC != RTC_JZ47XX - rtcbuf[0]=((tm->tm_sec/10) << 4) | (tm->tm_sec%10); - rtcbuf[1]=((tm->tm_min/10) << 4) | (tm->tm_min%10); - rtcbuf[2]=((tm->tm_hour/10) << 4) | (tm->tm_hour%10); - rtcbuf[3]=tm->tm_wday; - rtcbuf[4]=((tm->tm_mday/10) << 4) | (tm->tm_mday%10); - rtcbuf[5]=(((tm->tm_mon+1)/10) << 4) | ((tm->tm_mon+1)%10); -#ifdef IRIVER_H300_SERIES - /* Iriver firmware compatibility kludge, see get_time(). */ - rtcbuf[6]=(((tm->tm_year-64)/10) << 4) | ((tm->tm_year-64)%10); -#else - rtcbuf[6]=(((tm->tm_year-100)/10) << 4) | ((tm->tm_year-100)%10); -#endif + rc = rtc_write_datetime(tm); - rc = rtc_write_datetime(rtcbuf); -#else - rc = rtc_write_datetime((unsigned char*)tm); -#endif - if (rc < 0) return -1; else @@ -151,10 +97,10 @@ { return -2; } -#else +#else /* No RTC */ (void)tm; return 0; -#endif +#endif /* RTC */ } #if CONFIG_RTC @@ -196,11 +142,12 @@ void set_day_of_week(struct tm *tm) { - int y=tm->tm_year+1900; - int d=tm->tm_mday; - int m=tm->tm_mon; - static const char mo[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; + int y=tm->tm_year+1900; + int d=tm->tm_mday; + int m=tm->tm_mon; + static const char mo[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; - if(m == 0 || m == 1) y--; - tm->tm_wday = (d + mo[m] + y + y/4 - y/100 + y/400) % 7; + if(m == 0 || m == 1) y--; + tm->tm_wday = (d + mo[m] + y + y/4 - y/100 + y/400) % 7; } + Index: firmware/drivers/rtc/rtc_s35390a.c =================================================================== --- firmware/drivers/rtc/rtc_s35390a.c (revision 22521) +++ firmware/drivers/rtc/rtc_s35390a.c (arbetskopia) @@ -58,35 +58,49 @@ { } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - unsigned char data[7]; + unsigned char buf[7]; int i, ret; - ret = i2c_read(RTC_ADDR | (REALTIME_DATA1 << 1), -1, sizeof(data), data); - reverse_bits(data, sizeof(data)); + ret = i2c_read(RTC_ADDR | (REALTIME_DATA1 << 1), -1, sizeof(buf), buf); + reverse_bits(buf, sizeof(buf)); buf[4] &= 0x3f; /* mask out p.m. flag */ + + for (i = 0; i < sizeof(buf); i++) + BCD2DEC(buf[i]); + + tm->tm_sec = buf[6]; + tm->tm_min = buf[5]; + tm->tm_hour = buf[4]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[2]; + tm->tm_mon = buf[1] - 1; + tm->tm_year = buf[0] + 100; - for (i = 0; i < 7; i++) { - buf[i] = data[6 - i]; - } - return ret; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - unsigned char data[7]; + unsigned char buf[7]; int i, ret; - for (i = 0; i < 7; i++) { - data[i] = buf[6 - i]; - } - - reverse_bits(data, sizeof(data)); - ret = i2c_write(RTC_ADDR | (REALTIME_DATA1 << 1), -1, sizeof(data), data); - + buf[6] = tm->tm_sec; + buf[5] = tm->tm_min; + buf[4] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[2] = tm->tm_mday; + buf[1] = tm->tm_mon + 1; + buf[0] = tm->tm_year - 100; + + for (i = 0; i < sizeof(buf); i++) + DEC2BCD(buf[i]); + + reverse_bits(buf, sizeof(buf)); + ret = i2c_write(RTC_ADDR | (REALTIME_DATA1 << 1), -1, sizeof(buf), buf); + return ret; } Index: firmware/drivers/rtc/rtc_pcf50605.c =================================================================== --- firmware/drivers/rtc/rtc_pcf50605.c (revision 22521) +++ firmware/drivers/rtc/rtc_pcf50605.c (arbetskopia) @@ -36,14 +36,45 @@ rtc_check_alarm_started(false); } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - return pcf50605_read_multiple(0x0a, buf, 7); + unsigned int i; + int rc; + unsigned char buf[7]; + rc = pcf50605_read_multiple(0x0a, buf, sizeof(buf)); + + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + + return rc; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - pcf50605_write_multiple(0x0a, buf, 7); + unsigned int i; + unsigned char buf[7]; + + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[4] = tm->tm_mday; + buf[5] = tm->tm_mon + 1; + buf[6] = tm->tm_year - 100; + + for (i = 0; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); + + pcf50605_write_multiple(0x0a, buf, sizeof(buf)); + return 1; } @@ -121,17 +152,17 @@ /* Set us to wake at the first second of the specified time */ pcf50605_write(0x11, 0); /* Convert to BCD */ - pcf50605_write(0x12, ((m/10) << 4) | m%10); - pcf50605_write(0x13, ((h/10) << 4) | h%10); + pcf50605_write(0x12, DEC2BCD(m)); + pcf50605_write(0x13, DEC2BCD(h)); } void rtc_get_alarm(int *h, int *m) { char buf[2]; - pcf50605_read_multiple(0x12, buf, 2); + pcf50605_read_multiple(0x12, buf, sizeof(buf)); /* Convert from BCD */ - *m = ((buf[0] >> 4) & 0x7)*10 + (buf[0] & 0x0f); - *h = ((buf[1] >> 4) & 0x3)*10 + (buf[1] & 0x0f); + *m = BCD2DEC(buf[0]); + *h = BCD2DEC(buf[1]); } Index: firmware/drivers/rtc/rtc_rx5x348ab.c =================================================================== --- firmware/drivers/rtc/rtc_rx5x348ab.c (revision 22521) +++ firmware/drivers/rtc/rtc_rx5x348ab.c (arbetskopia) @@ -22,7 +22,6 @@ #include "config.h" #include "spi.h" #include "rtc.h" -#include /* Choose one of: */ #define ADDR_READ 0x04 #define ADDR_WRITE 0x00 @@ -33,20 +32,48 @@ { } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { + unsigned int i; + unsigned char buf[7]; char command = ADDR_READ|ADDR_BURST; /* burst read from the start of the time/date reg */ - spi_block_transfer(SPI_target_RX5X348AB, &command, 1, buf, 7); + + spi_block_transfer(SPI_target_RX5X348AB, &command, 1, buf, sizeof(buf)); + + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + return 1; } -int rtc_write_datetime(unsigned char* buf) + +int rtc_write_datetime(const struct tm *tm) { + unsigned int i; char command = ADDR_WRITE|ADDR_BURST; /* burst read from the start of the time/date reg */ - char data[8]; - int i; - data[0] = command; - for (i=1;i<8;i++) - data[i] = buf[i-1]; - spi_block_transfer(SPI_target_RX5X348AB, data, 8, NULL, 0); + unsigned char buf[8]; + + buf[0] = command; + buf[1] = tm->tm_sec; + buf[2] = tm->tm_min; + buf[3] = tm->tm_hour; + buf[4] = tm->tm_wday; + buf[5] = tm->tm_mday; + buf[6] = tm->tm_mon + 1; + buf[7] = tm->tm_year - 100; + + /* don't encode the comand byte */ + for (i = 1; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); + + spi_block_transfer(SPI_target_RX5X348AB, buf, sizeof(buf), NULL, 0); return 1; } + Index: firmware/drivers/rtc/rtc_pcf50606.c =================================================================== --- firmware/drivers/rtc/rtc_pcf50606.c (revision 22521) +++ firmware/drivers/rtc/rtc_pcf50606.c (arbetskopia) @@ -24,28 +24,71 @@ #include "kernel.h" #include "system.h" #include "pcf50606.h" -#include void rtc_init(void) { } -int rtc_read_datetime(unsigned char* buf) { - int rc; - int oldlevel = disable_irq_save(); - - rc = pcf50606_read_multiple(0x0a, buf, 7); +int rtc_read_datetime(struct tm *tm) +{ + unsigned int i; + int rc, oldlevel; + unsigned char buf[7]; + oldlevel = disable_irq_save(); + + rc = pcf50606_read_multiple(0x0a, buf, sizeof(buf)); + restore_irq(oldlevel); + + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; +#ifdef IRIVER_H300_SERIES + /* Special kludge to coexist with the iriver firmware. The iriver firmware + stores the date as 1965+nn, and allows a range of 1980..2064. We use + 1964+nn here to make leap years work correctly, so the date will be one + year off in the iriver firmware but at least won't be reset anymore. */ + tm->tm_year = buf[6] + 64; +#else /* Not IRIVER_H300_SERIES */ + tm->tm_year = buf[6] + 100; +#endif /* IRIVER_H300_SERIES */ + return rc; } -int rtc_write_datetime(unsigned char* buf) { - int rc; - int oldlevel = disable_irq_save(); - - rc = pcf50606_write_multiple(0x0a, buf, 7); +int rtc_write_datetime(const struct tm *tm) +{ + unsigned int i; + int rc, oldlevel; + unsigned char buf[7]; + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[4] = tm->tm_mday; + buf[5] = tm->tm_mon + 1; +#ifdef IRIVER_H300_SERIES + /* Iriver firmware compatibility kludge, see rtc_read_datetime(). */ + buf[6] = tm->tm_year - 64; +#else /* Not IRIVER_H300_SERIES */ + buf[6] = tm->tm_year - 100; +#endif /* IRIVER_H300_SERIES */ + + for (i = 0; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); + + oldlevel = disable_irq_save(); + + rc = pcf50606_write_multiple(0x0a, buf, sizeof(buf)); + restore_irq(oldlevel); return rc; Index: firmware/drivers/rtc/rtc_e8564.c =================================================================== --- firmware/drivers/rtc/rtc_e8564.c (revision 22521) +++ firmware/drivers/rtc/rtc_e8564.c (arbetskopia) @@ -68,37 +68,46 @@ pp_i2c_send(0x51, RTC_CTRL2,tmp); } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - unsigned char tmp; - int read; - + int i, read; + unsigned char buf[7]; + /*RTC_E8564's slave address is 0x51*/ - read = i2c_readbytes(0x51,0x02,7,buf); + read = i2c_readbytes(0x51, 0x02, sizeof(buf), buf); - /* swap wday and mday to be compatible with - * get_time() from firmware/common/timefuncs.c */ - tmp=buf[3]; - buf[3]=buf[4]; - buf[4]=tmp; - + /* Convert from BCD to decimal */ + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[4]; + tm->tm_mday = buf[3]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + return read; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { int i; - unsigned char tmp; - - /* swap wday and mday to be compatible with - * set_time() in firmware/common/timefuncs.c */ - tmp=buf[3]; - buf[3]=buf[4]; - buf[4]=tmp; + unsigned char buf[7]; - for (i=0;i<7;i++){ - pp_i2c_send(0x51, 0x02+i,buf[i]); + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[4] = tm->tm_wday; + buf[3] = tm->tm_mday; + buf[5] = tm->tm_mon + 1; + buf[6] = tm->tm_year - 100; + + for (i=0; itm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + return rc; } -int rtc_write_datetime(unsigned char* buf) { - int i; +int rtc_write_datetime(const struct tm *tm) +{ + unsigned int i; int rc = 0; - + unsigned char buf[7]; + + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[4] = tm->tm_mday; + buf[5] = tm->tm_mon + 1; + buf[6] = tm->tm_year - 100; + /* Adjust weekday */ - if(buf[3] == 0) + if (buf[3] == 0) buf[3] = 7; - for (i = 0; i < 7 ; i++) + for (i = 0; i < sizeof(buf) ; i++) { - rc |= rtc_write(i+1, buf[i]); + rc |= rtc_write(i+1, DEC2BCD(buf[i])); } rc |= rtc_write(8, 0x80); /* Out=1, calibration = 0 */ return rc; } + Index: firmware/drivers/rtc/rtc_mr100.c =================================================================== --- firmware/drivers/rtc/rtc_mr100.c (revision 22521) +++ firmware/drivers/rtc/rtc_mr100.c (arbetskopia) @@ -124,31 +124,49 @@ } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - int i; - unsigned char v[7]; + unsigned int i; + int rc; + unsigned char buf[7]; - i = sw_i2c(SW_I2C_READ, RTC_CMD_DATA, v, 7); + rc = sw_i2c(SW_I2C_READ, RTC_CMD_DATA, buf, sizeof(buf)); - v[4] &= 0x3f; /* mask out p.m. flag */ + buf[4] &= 0x3f; /* mask out p.m. flag */ - for(i=0; i<7; i++) - buf[i] = v[6-i]; - - return i; + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[6]; + tm->tm_min = buf[5]; + tm->tm_hour = buf[4]; + tm->tm_wday = buf[3]; + tm->tm_mday = buf[2]; + tm->tm_mon = buf[1] - 1; + tm->tm_year = buf[0] + 100; + + return rc; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - int i; - unsigned char v[7]; + unsigned int i; + int rc; + unsigned char buf[7]; - for(i=0; i<7; i++) - v[i]=buf[6-i]; - - i = sw_i2c(SW_I2C_WRITE, RTC_CMD_DATA, v, 7); - - return i; + buf[6] = tm->tm_sec; + buf[5] = tm->tm_min; + buf[4] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[2] = tm->tm_mday; + buf[1] = tm->tm_mon + 1; + buf[0] = tm->tm_year - 100; + + for (i = 0; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); + + rc = sw_i2c(SW_I2C_WRITE, RTC_CMD_DATA, buf, sizeof(buf)); + + return rc; } Index: firmware/drivers/rtc/rtc_as3514.c =================================================================== --- firmware/drivers/rtc/rtc_as3514.c (revision 22521) +++ firmware/drivers/rtc/rtc_as3514.c (arbetskopia) @@ -38,9 +38,6 @@ #define YEAR_SECONDS 31536000 #define LEAP_YEAR_SECONDS 31622400 -#define BCD2DEC(X) (((((X)>>4) & 0x0f) * 10) + ((X) & 0xf)) -#define DEC2BCD(X) ((((X)/10)<<4) | ((X)%10)) - /* Days in each month */ static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -56,31 +53,30 @@ { } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { char tmp[4]; - int year; - int i; + int i, year, mday, hour, min; unsigned int seconds; - + /* RTC_AS3514's slave address is 0x46*/ - for (i=0;i<4;i++){ + for (i = 0; i < 4; i++){ tmp[i] = ascodec_read(AS3514_RTC_0 + i); } seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24); seconds -= SECS_ADJUST; - + /* Convert seconds since Jan-1-1980 to format compatible with * get_time() from firmware/common/timefuncs.c */ - + /* weekday */ - buf[3] = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; - + tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; + /* Year */ year = 1980; - while(seconds>=LEAP_YEAR_SECONDS) + while (seconds >= LEAP_YEAR_SECONDS) { - if(is_leapyear(year)){ + if (is_leapyear(year)){ seconds -= LEAP_YEAR_SECONDS; } else { seconds -= YEAR_SECONDS; @@ -88,8 +84,8 @@ year++; } - - if(is_leapyear(year)) { + + if (is_leapyear(year)) { days_in_month[1] = 29; } else { days_in_month[1] = 28; @@ -98,54 +94,48 @@ seconds -= YEAR_SECONDS; } } - buf[6] = year%100; - + tm->tm_year = year%100 + 100; + /* Month */ - for(i=0; i<12; i++) + for (i = 0; i < 12; i++) { - if(seconds < days_in_month[i]*DAY_SECONDS){ - buf[5] = i+1; + if (seconds < days_in_month[i]*DAY_SECONDS){ + tm->tm_mon = i; break; } - + seconds -= days_in_month[i]*DAY_SECONDS; } - + /* Month Day */ - buf[4] = seconds/DAY_SECONDS; - seconds -= buf[4]*DAY_SECONDS; - buf[4]++; /* 1 ... 31 */ + mday = seconds/DAY_SECONDS; + seconds -= mday*DAY_SECONDS; + tm->tm_mday = mday + 1; /* 1 ... 31 */ /* Hour */ - buf[2] = seconds/HOUR_SECONDS; - seconds -= buf[2]*HOUR_SECONDS; - + hour = seconds/HOUR_SECONDS; + seconds -= hour*HOUR_SECONDS; + tm->tm_hour = hour; + /* Minute */ - buf[1] = seconds/MINUTE_SECONDS; - seconds -= buf[1]*MINUTE_SECONDS; - + min = seconds/MINUTE_SECONDS; + seconds -= min*MINUTE_SECONDS; + tm->tm_min = min; + /* Second */ - buf[0] = seconds; - - /* Convert to Binary Coded Decimal format */ - for(i=0; i<7; i++) - buf[i] = DEC2BCD(buf[i]); - + tm->tm_sec = seconds; + return 7; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { int i, year; unsigned int year_days = 0; unsigned int month_days = 0; unsigned int seconds = 0; - - /* Convert from Binary Coded Decimal format */ - for(i=0; i<7; i++) - buf[i] = BCD2DEC(buf[i]); - year = 2000 + buf[6]; + year = 2000 + tm->tm_year - 100; if(is_leapyear(year)) { days_in_month[1] = 29; @@ -154,24 +144,24 @@ } /* Number of days in months gone by this year*/ - for(i=0; i<(buf[5]-1); i++){ + for(i = 0; i < tm->tm_mon; i++){ month_days += days_in_month[i]; } /* Number of days in years gone by since 1-Jan-1980 */ - year_days = 365*(buf[6]+20) + (buf[6]-1)/4 + 6; + year_days = 365*(tm->tm_year+20) + (tm->tm_year-1)/4 + 6; /* Convert to seconds since 1-Jan-1980 */ - seconds = buf[0] - + buf[1]*MINUTE_SECONDS - + buf[2]*HOUR_SECONDS - + (buf[4]-1)*DAY_SECONDS + seconds = tm->tm_sec + + tm->tm_min*MINUTE_SECONDS + + tm->tm_hour*HOUR_SECONDS + + (tm->tm_mday-1)*DAY_SECONDS + month_days*DAY_SECONDS + year_days*DAY_SECONDS; seconds += SECS_ADJUST; /* Send data to RTC */ - for (i=0;i<4;i++){ + for (i=0; i<4; i++){ ascodec_write(AS3514_RTC_0 + i, ((seconds >> (8 * i)) & 0xff)); } return 1; Index: firmware/drivers/rtc/rtc_jz4740.c =================================================================== --- firmware/drivers/rtc/rtc_jz4740.c (revision 22521) +++ firmware/drivers/rtc/rtc_jz4740.c (arbetskopia) @@ -116,11 +116,10 @@ *year += 2000; } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - struct tm rtc_tm; unsigned int sec,mon,mday,wday,year,hour,min; - + /* * Only the values that we read from the RTC are set. We leave * tm_wday, tm_yday and tm_isdst untouched. Even though the @@ -131,37 +130,32 @@ year -= 2000; - rtc_tm.tm_sec = sec; - rtc_tm.tm_min = min; - rtc_tm.tm_hour = hour; - rtc_tm.tm_mday = mday; - rtc_tm.tm_wday = wday; + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = mday; + tm->tm_wday = wday; /* Don't use centry, but start from year 1970 */ - rtc_tm.tm_mon = mon; + tm->tm_mon = mon; if (year <= 69) year += 100; - rtc_tm.tm_year = year; - - rtc_tm.tm_yday = 0; /* Not implemented for now */ - rtc_tm.tm_isdst = -1; /* Not implemented for now */ - - (*((struct tm*)buf)) = rtc_tm; + tm->tm_year = year; + return 1; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - struct tm *rtc_tm = (struct tm*)buf; unsigned int year, lval; - year = rtc_tm->tm_year; + year = tm->tm_year; /* Don't use centry, but start from year 1970 */ if (year > 69) year -= 100; year += 2000; - lval = jz_mktime(year, rtc_tm->tm_mon, rtc_tm->tm_mday, rtc_tm->tm_hour, - rtc_tm->tm_min, rtc_tm->tm_sec); + lval = jz_mktime(year, tm->tm_mon, tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec); __cpm_start_rtc(); udelay(100); Index: firmware/drivers/rtc/rtc_s3c2440.c =================================================================== --- firmware/drivers/rtc/rtc_s3c2440.c (revision 22521) +++ firmware/drivers/rtc/rtc_s3c2440.c (arbetskopia) @@ -30,28 +30,28 @@ RTCCON |= 1; } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - buf[0] = BCDSEC; - buf[1] = BCDMIN; - buf[2] = BCDHOUR; - buf[3] = BCDDAY-1; /* timefuncs wants 0..6 for wday */ - buf[4] = BCDDATE; - buf[5] = BCDMON; - buf[6] = BCDYEAR; + tm->tm_sec = BCD2DEC(BCDSEC); + tm->tm_min = BCD2DEC(BCDMIN); + tm->tm_hour = BCD2DEC(BCDHOUR); + tm->tm_wday = BCD2DEC(BCDDAY) - 1; /* timefuncs wants 0..6 for wday */ + tm->tm_mday = BCD2DEC(BCDDATE); + tm->tm_mon = BCD2DEC(BCDMON) - 1; + tm->tm_year = BCD2DEC(BCDYEAR) + 100; return 1; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - BCDSEC = buf[0]; - BCDMIN = buf[1]; - BCDHOUR = buf[2]; - BCDDAY = buf[3]+1; /* chip wants 1..7 for wday */ - BCDDATE = buf[4]; - BCDMON = buf[5]; - BCDYEAR = buf[6]; + BCDSEC = DEC2BCD(tm->tm_sec); + BCDMIN = DEC2BCD(tm->tm_min); + BCDHOUR = DEC2BCD(tm->tm_hour); + BCDDAY = DEC2BCD(tm->tm_wday) + 1; /* chip wants 1..7 for wday */ + BCDDATE = DEC2BCD(tm->tm_mday); + BCDMON = DEC2BCD(tm->tm_mon + 1); + BCDYEAR = DEC2BCD(tm->tm_year - 100); return 1; } @@ -88,15 +88,15 @@ /* set alarm time registers to the given time (repeat once per day) */ void rtc_set_alarm(int h, int m) { - ALMMIN=(((m / 10) << 4) | (m % 10)) & 0x7f; /* minutes */ - ALMHOUR=(((h / 10) << 4) | (h % 10)) & 0x3f; /* hour */ + ALMMIN = DEC2BCD(m); /* minutes */ + ALMHOUR = DEC2BCD(h); /* hour */ } /* read out the current alarm time */ void rtc_get_alarm(int *h, int *m) { - *m=((ALMMIN & 0x70) >> 4) * 10 + (ALMMIN & 0x0f); - *h=((ALMHOUR & 0x30) >> 4) * 10 + (ALMHOUR & 0x0f); + *m = BCD2DEC(ALMMIN); + *h = BCD2DEC(ALMHOUR); } /* turn alarm on or off by setting the alarm flag enable Index: firmware/drivers/rtc/rtc_ds1339_ds3231.c =================================================================== --- firmware/drivers/rtc/rtc_ds1339_ds3231.c (revision 22521) +++ firmware/drivers/rtc/rtc_ds1339_ds3231.c (arbetskopia) @@ -115,26 +115,47 @@ #endif /* HAVE_RTC_ALARM */ -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { - int i; + unsigned int i; + int rc; + unsigned char buf[7]; - i = sw_i2c_read(RTC_ADDR, 0, buf, 7); - - buf[3]--; /* timefuncs wants 0..6 for wday */ + rc = sw_i2c_read(RTC_ADDR, 0, buf, sizeof(buf)); - return i; + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_wday = buf[3] - 1; /* timefuncs wants 0..6 for wday */ + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + + return rc; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - int i; + unsigned int i; + int rc; + unsigned char buf[7]; - buf[3]++; /* chip wants 1..7 for wday */ - buf[5]|=0x80; /* chip wants century (always 20xx) */ + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[3] = tm->tm_wday + 1; /* chip wants 1..7 for wday */ + buf[4] = tm->tm_mday; + buf[5] = (tm->tm_mon + 1) | 0x80; /* chip wants century (always 20xx) */ + buf[6] = tm->tm_year - 100; - i = sw_i2c_write(RTC_ADDR, 0, buf, 7); + for (i = 0; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); - return i; + rc = sw_i2c_write(RTC_ADDR, 0, buf, sizeof(buf)); + + return rc; } Index: firmware/drivers/rtc/rtc_mc13783.c =================================================================== --- firmware/drivers/rtc/rtc_mc13783.c (revision 22521) +++ firmware/drivers/rtc/rtc_mc13783.c (arbetskopia) @@ -46,18 +46,6 @@ #define RTC_BASE_YEAR 1970 #endif -enum rtc_buffer_field_indexes -{ - RTC_I_SECONDS = 0, - RTC_I_MINUTES, - RTC_I_HOURS, - RTC_I_WEEKDAY, - RTC_I_DAY, - RTC_I_MONTH, - RTC_I_YEAR, - RTC_NUM_FIELDS, -}; - enum rtc_registers_indexes { RTC_REG_TIME = 0, @@ -82,26 +70,6 @@ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, }; -static inline void to_bcd(unsigned char *bcd, const unsigned char *buf, - int len) -{ - while (len-- > 0) - { - unsigned char d = *buf++; - *bcd++ = ((d / 10) << 4) | (d % 10); - } -} - -static inline void from_bcd(unsigned char *buf, const unsigned char *bcd, - int len) -{ - while (len-- > 0) - { - unsigned char d = *bcd++; - *buf++ = ((d >> 4) & 0x0f) * 10 + (d & 0xf); - } -} - /* Get number of leaps since the reference date of 1601/01/01 */ static int get_leap_count(int d) { @@ -127,10 +95,10 @@ } } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { uint32_t regs[RTC_NUM_REGS]; - int year, leap, month, day; + int year, leap, month, day, hour, min; /* Read time, day, time - 2nd read of time should be the same or * greater */ @@ -147,19 +115,21 @@ while (regs[RTC_REG_TIME2] < regs[RTC_REG_TIME]); /* TOD: = 0 to 86399 */ - buf[RTC_I_HOURS] = regs[RTC_REG_TIME] / 3600; - regs[RTC_REG_TIME] -= buf[RTC_I_HOURS]*3600; + hour = regs[RTC_REG_TIME] / 3600; + regs[RTC_REG_TIME] -= hour*3600; + tm->tm_hour = hour; - buf[RTC_I_MINUTES] = regs[RTC_REG_TIME] / 60; - regs[RTC_REG_TIME] -= buf[RTC_I_MINUTES]*60; + min = regs[RTC_REG_TIME] / 60; + regs[RTC_REG_TIME] -= min*60; + tm->tm_min = min; - buf[RTC_I_SECONDS] = regs[RTC_REG_TIME]; + tm->tm_sec = regs[RTC_REG_TIME]; /* DAY: 0 to 32767 */ day = regs[RTC_REG_DAY] + RTC_BASE_DAY_COUNT; /* Weekday */ - buf[RTC_I_WEEKDAY] = (day + 1) % 7; /* 1601/01/01 = Monday */ + tm->tm_wday = (day + 1) % 7; /* 1601/01/01 = Monday */ /* Get number of leaps for today */ leap = get_leap_count(day); @@ -186,29 +156,24 @@ day -= days; } - buf[RTC_I_DAY] = day + 1; /* 1 to 31 */ - buf[RTC_I_MONTH] = month + 1; /* 1 to 12 */ - buf[RTC_I_YEAR] = year % 100; + tm->tm_mday = day + 1; /* 1 to 31 */ + tm->tm_mon = month; /* 0 to 11 */ + tm->tm_year = year % 100 + 100; - to_bcd(buf, buf, RTC_NUM_FIELDS); - return 7; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { uint32_t regs[2]; - unsigned char fld[RTC_NUM_FIELDS]; int year, leap, month, day, i, base_yearday; - from_bcd(fld, buf, RTC_NUM_FIELDS); + regs[RTC_REG_TIME] = tm->tm_sec + + tm->tm_min*60 + + tm->tm_hour*3600; - regs[RTC_REG_TIME] = fld[RTC_I_SECONDS] + - fld[RTC_I_MINUTES]*60 + - fld[RTC_I_HOURS]*3600; + year = tm->tm_year - 100; - year = fld[RTC_I_YEAR]; - if (year < RTC_BASE_YEAR - 1900) year += 2000; else @@ -230,18 +195,18 @@ /* Find the number of days passed this year up to the 1st of the * month. */ leap = is_leap_year(year); - month = fld[RTC_I_MONTH] - 1; + month = tm->tm_mon; for (i = 0; i < month; i++) { day += month_table[leap][i]; } - regs[RTC_REG_DAY] = day + fld[RTC_I_DAY] - 1 - base_yearday; + regs[RTC_REG_DAY] = day + tm->tm_mday - 1 - base_yearday; if (mc13783_write_regset(rtc_registers, regs, 2) == 2) { - return RTC_NUM_FIELDS; + return 7; } return 0; Index: uisimulator/common/stubs.c =================================================================== --- uisimulator/common/stubs.c (revision 22521) +++ uisimulator/common/stubs.c (arbetskopia) @@ -142,25 +142,17 @@ return 0; } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { time_t now = time(NULL); - struct tm *teem = localtime(&now); + *tm = *localtime(&now); - buf[0] = (teem->tm_sec%10) | ((teem->tm_sec/10) << 4); - buf[1] = (teem->tm_min%10) | ((teem->tm_min/10) << 4); - buf[2] = (teem->tm_hour%10) | ((teem->tm_hour/10) << 4); - buf[3] = (teem->tm_wday); - buf[4] = (teem->tm_mday%10) | ((teem->tm_mday/10) << 4); - buf[5] = ((teem->tm_year-100)%10) | (((teem->tm_year-100)/10) << 4); - buf[6] = ((teem->tm_mon+1)%10) | (((teem->tm_mon+1)/10) << 4); - return 0; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { - (void)buf; + (void)tm; return 0; }