[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rockbox-cvs
Subject:    nls: r22839 - in trunk: firmware/common firmware/drivers/rtc
From:       mailer () svn ! rockbox ! org
Date:       2009-09-26 14:58:32
Message-ID: 200909261458.n8QEwWIS025106 () giant ! haxx ! se
[Download RAW message or body]

Date: 2009-09-26 16:58:32 +0200 (Sat, 26 Sep 2009)
New Revision: 22839

Log Message:
FS#10569 RTC driver cleanup
Change the RTC drivers so that the rtc_(read|write)_datetime functions now deal \
directly with the tm struct instead of passing a string of bcd digits to/from \
(set|get)_time . This simplifies drivers for rtc's that do not use a bcd \
representation internally and cleans up some target specific code and #ifdefs in \
generic code. Implement simple stubs for the sim to avoid #ifdefing for that too.


Modified:
   trunk/firmware/common/timefuncs.c
   trunk/firmware/drivers/rtc/rtc_as3514.c
   trunk/firmware/drivers/rtc/rtc_ds1339_ds3231.c
   trunk/firmware/drivers/rtc/rtc_e8564.c
   trunk/firmware/drivers/rtc/rtc_jz4740.c
   trunk/firmware/drivers/rtc/rtc_m41st84w.c
   trunk/firmware/drivers/rtc/rtc_mc13783.c
   trunk/firmware/drivers/rtc/rtc_mr100.c
   trunk/firmware/drivers/rtc/rtc_pcf50605.c
   trunk/firmware/drivers/rtc/rtc_pcf50606.c
   trunk/firmware/drivers/rtc/rtc_rx5x348ab.c
   trunk/firmware/drivers/rtc/rtc_s35390a.c
   trunk/firmware/drivers/rtc/rtc_s3c2440.c
   trunk/firmware/export/rtc.h
   trunk/firmware/include/timefuncs.h
   trunk/uisimulator/common/stubs.c

Modified: trunk/firmware/common/timefuncs.c
===================================================================
--- trunk/firmware/common/timefuncs.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/common/timefuncs.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;
 }
+

Modified: trunk/firmware/drivers/rtc/rtc_as3514.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_as3514.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_as3514.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;

Modified: trunk/firmware/drivers/rtc/rtc_ds1339_ds3231.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_ds1339_ds3231.c	2009-09-26 10:47:10 UTC (rev \
                22838)
+++ trunk/firmware/drivers/rtc/rtc_ds1339_ds3231.c	2009-09-26 14:58:32 UTC (rev \
22839) @@ -115,26 +115,46 @@
 
 #endif /* HAVE_RTC_ALARM */ 
 
-int rtc_read_datetime(unsigned char* buf)
+int rtc_read_datetime(struct tm *tm)
 {
-    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;
+    /* convert from bcd, avoid getting extra bits */
+    tm->tm_sec  = BCD2DEC(buf[0] & 0x7f);
+    tm->tm_min  = BCD2DEC(buf[1] & 0x7f);
+    tm->tm_hour = BCD2DEC(buf[2] & 0x3f);
+    tm->tm_wday = BCD2DEC(buf[3] & 0x3) - 1; /* timefuncs wants 0..6 for wday */
+    tm->tm_mday = BCD2DEC(buf[4] & 0x3f);
+    tm->tm_mon  = BCD2DEC(buf[5] & 0x1f) - 1;
+    tm->tm_year = BCD2DEC(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;
+    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;
+    buf[5] |= 0x80; /* chip wants century (always 20xx) */
+
+    rc = sw_i2c_write(RTC_ADDR, 0, buf, sizeof(buf));
+
+    return rc;
 }
 

Modified: trunk/firmware/drivers/rtc/rtc_e8564.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_e8564.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_e8564.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -27,6 +27,9 @@
 #include "i2c-pp.h"
 #include <stdbool.h>
 
+/*RTC_E8564's slave address is 0x51*/
+#define RTC_ADDR   0x51
+
 /* RTC registers */
 #define RTC_CTRL1          0x00
 #define RTC_CTRL2          0x01
@@ -59,94 +62,96 @@
     
     /* initialize Control 1 register */
     tmp = 0;
-    pp_i2c_send(0x51, RTC_CTRL1,tmp);
+    pp_i2c_send(RTC_ADDR, RTC_CTRL1, tmp);
     
     /* read value of the Control 2 register - we'll need it to preserve alarm and \
                timer interrupt assertion flags */
-    rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+    rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
     /* preserve alarm and timer interrupt flags */
     tmp &= (RTC_TF | RTC_AF | RTC_TIE | RTC_AIE);
-    pp_i2c_send(0x51, RTC_CTRL2,tmp);
+    pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp);
 }
 
-int rtc_read_datetime(unsigned char* buf)
+int rtc_read_datetime(struct tm *tm)
 {
-    unsigned char tmp;
     int read;
-    
-    /*RTC_E8564's slave address is 0x51*/
-    read = i2c_readbytes(0x51,0x02,7,buf);
+    unsigned char buf[7];
 
-    /* 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;
-    
+    read = i2c_readbytes(RTC_ADDR, 0x02, sizeof(buf), buf);
+
+    /* convert from bcd, avoid getting extra bits */
+    tm->tm_sec  = BCD2DEC(buf[0] & 0x7f);
+    tm->tm_min  = BCD2DEC(buf[1] & 0x7f);
+    tm->tm_hour = BCD2DEC(buf[2] & 0x3f);
+    tm->tm_mday = BCD2DEC(buf[3] & 0x3f);
+    tm->tm_wday = BCD2DEC(buf[4] & 0x3);
+    tm->tm_mon  = BCD2DEC(buf[5] & 0x1f) - 1;
+    tm->tm_year = BCD2DEC(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 int i;
+    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[3] = tm->tm_mday;
+    buf[4] = tm->tm_wday;
+    buf[5] = tm->tm_mon + 1;
+    buf[6] = tm->tm_year - 100;
+
+    for (i = 0; i < sizeof(buf); i++)
+        pp_i2c_send(RTC_ADDR, 0x02 + i, DEC2BCD(buf[i]));
+
     return 1;
 }
 
 void rtc_set_alarm(int h, int m)
 {
-    unsigned char buf[4]={0};
-    int rv=0;
-    int i=0;
-    
+    unsigned char buf[4] = {0};
+    int i, rv;
+
     /* clear alarm interrupt */
-    rv = i2c_readbytes(0x51,RTC_CTRL2,1,buf);
+    rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, buf);
     buf[0] &= RTC_AF;
-    pp_i2c_send(0x51, RTC_CTRL2,buf[0]);
-    
+    pp_i2c_send(RTC_ADDR, RTC_CTRL2, buf[0]);
+
     /* prepare new alarm */
     if( m >= 0 )
-        buf[0] = (((m/10) << 4) | m%10);
+        buf[0] = DEC2BCD(m);
     else
         /* ignore minutes comparison query */
         buf[0] = RTC_AE;
     
     if( h >= 0 )
-        buf[1] = (((h/10) << 4) | h%10);
+        buf[1] = DEC2BCD(h);
     else
         /* ignore hours comparison query */
         buf[1] = RTC_AE;
-    
+
     /* ignore day and wday */
     buf[2] = RTC_AE;
     buf[3] = RTC_AE;
-    
+
     /* write new alarm */
-    for(;i<4;i++)
-        pp_i2c_send(0x51, RTC_ALARM_MINUTES+i,buf[i]);
-    
+    for(i = 0; i < 4; i++)
+        pp_i2c_send(RTC_ADDR, RTC_ALARM_MINUTES + i, buf[i]);
+
     /* note: alarm is not enabled at the point */
 }
 
 void rtc_get_alarm(int *h, int *m)
 {
     unsigned char buf[4]={0};
-    
+
     /* get alarm preset */
-    i2c_readbytes(0x51, RTC_ALARM_MINUTES,4,buf);
+    i2c_readbytes(RTC_ADDR, RTC_ALARM_MINUTES, 4 ,buf);
 
-    *m = ((buf[0] >> 4) & 0x7)*10 + (buf[0] & 0x0f);
-    *h = ((buf[1] >> 4) & 0x3)*10 + (buf[1] & 0x0f);
-
+    *m = BCD2DEC(buf[0] & 0x7f);
+    *h = BCD2DEC(buf[0] & 0x3f);
 }
 
 bool rtc_enable_alarm(bool enable)
@@ -157,10 +162,10 @@
     if(enable)
     {
         /* enable alarm interrupt */
-        rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+        rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
         tmp |= RTC_AIE;
         tmp &= ~RTC_AF;
-        pp_i2c_send(0x51, RTC_CTRL2,tmp);
+        pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp);
     }
     else
     {
@@ -168,9 +173,9 @@
         if(rtc_lock_alarm_clear)
             /* lock disabling alarm before it was checked whether or not the unit \
was started by RTC alarm */  return false;        
-        rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+        rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
         tmp &= ~(RTC_AIE | RTC_AF);
-        pp_i2c_send(0x51, RTC_CTRL2,tmp);
+        pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp);
     }
     
     return false;
@@ -186,21 +191,21 @@
     if (run_before)
     {
         started = alarm_state;
-        alarm_state &= ~release_alarm;         
+        alarm_state &= ~release_alarm;
     } 
     else 
     { 
         /* read Control 2 register which contains alarm flag */
-        rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+        rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
 
         alarm_state = started = ( (tmp & RTC_AF) && (tmp & RTC_AIE) );
         
         if(release_alarm && started)
         {
-            rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+            rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
             /* clear alarm interrupt enable and alarm flag */
             tmp &= ~(RTC_AF | RTC_AIE);
-            pp_i2c_send(0x51, RTC_CTRL2,tmp);
+            pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp);
         }
         run_before = true;
         rtc_lock_alarm_clear = false;
@@ -215,7 +220,8 @@
     int rv=0;
     
     /* read Control 2 register which contains alarm flag */
-    rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp);
+    rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp);
 
     return (tmp & RTC_AF);
 }
+

Modified: trunk/firmware/drivers/rtc/rtc_jz4740.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_jz4740.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_jz4740.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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);

Modified: trunk/firmware/drivers/rtc/rtc_m41st84w.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_m41st84w.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_m41st84w.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -110,10 +110,10 @@
 
     /* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */
     
-    rtc_write(0x0e, 0x00);                       /* seconds 0 and RTP1 */
-    rtc_write(0x0d, ((m / 10) << 4) | (m % 10)); /* minutes and RPT2 */
-    rtc_write(0x0c, ((h / 10) << 4) | (h % 10)); /* hour and RPT3 */
-    rtc_write(0x0b, 0xc1);                       /* set date 01 and RPT4 and RTP5 */
+    rtc_write(0x0e, 0x00);      /* seconds 0 and RTP1 */
+    rtc_write(0x0d, DEC2BCD(m); /* minutes and RPT2 */
+    rtc_write(0x0c, DEC2BCD(h); /* hour and RPT3 */
+    rtc_write(0x0b, 0xc1);      /* set date 01 and RPT4 and RTP5 */
     
     /* set month to 1, if it's invalid, the rtc does an alarm every second instead \
*/  data = rtc_read(0x0a);
@@ -128,10 +128,10 @@
     unsigned char data;
 
     data = rtc_read(0x0c);
-    *h = ((data & 0x30) >> 4) * 10 + (data & 0x0f);
+    *h = BCD2DEC(data & 0x3f);
     
     data = rtc_read(0x0d);
-    *m = ((data & 0x70) >> 4) * 10 + (data & 0x0f);
+    *m = BCD2DEC(data & 0x7f);
 }
 
 /* turn alarm on or off by setting the alarm flag enable */
@@ -250,31 +250,53 @@
     return ret;
 }
 
-int rtc_read_datetime(unsigned char* buf) {
+int rtc_read_datetime(struct tm *tm)
+{
     int rc;
+    unsigned char buf[7];
 
-    rc = rtc_read_multiple(1, buf, 7);
+    rc = rtc_read_multiple(1, buf, sizeof(buf));
 
+    /* convert from bcd, avoid getting extra bits */
+    tm->tm_sec  = BCD2DEC(buf[0] & 0x7f);
+    tm->tm_min  = BCD2DEC(buf[1] & 0x7f);
+    tm->tm_hour = BCD2DEC(buf[2] & 0x3f);
+    tm->tm_wday = BCD2DEC(buf[3] & 0x3);
+    tm->tm_mday = BCD2DEC(buf[4] & 0x3f);
+    tm->tm_mon  = BCD2DEC(buf[5] & 0x1f) - 1;
+    tm->tm_year = BCD2DEC(buf[6]) + 100;
+
     /* Adjust weekday */
-    if(buf[3] == 7)
-        buf[3]=0;
+    if (tm->tm_wday == 7)
+        tm->tm_wday = 0;
 
     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;
 }
+

Modified: trunk/firmware/drivers/rtc/rtc_mc13783.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_mc13783.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_mc13783.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;

Modified: trunk/firmware/drivers/rtc/rtc_mr100.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_mr100.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_mr100.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;
 }
 

Modified: trunk/firmware/drivers/rtc/rtc_pcf50605.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_pcf50605.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_pcf50605.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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]);
 }
 

Modified: trunk/firmware/drivers/rtc/rtc_pcf50606.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_pcf50606.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_pcf50606.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -24,28 +24,71 @@
 #include "kernel.h"
 #include "system.h"
 #include "pcf50606.h"
-#include <stdbool.h>
 
 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;

Modified: trunk/firmware/drivers/rtc/rtc_rx5x348ab.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_rx5x348ab.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_rx5x348ab.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -22,31 +22,60 @@
 #include "config.h"
 #include "spi.h"
 #include "rtc.h"
-#include <stdbool.h>
+
 /* Choose one of: */
 #define ADDR_READ       0x04
 #define ADDR_WRITE      0x00
 /* and one of: */
 #define ADDR_ONE        0x08
 #define ADDR_BURST      0x00
+
 void rtc_init(void)
 {
 }
     
-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;
 }
+

Modified: trunk/firmware/drivers/rtc/rtc_s35390a.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_s35390a.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_s35390a.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;
 }
 

Modified: trunk/firmware/drivers/rtc/rtc_s3c2440.c
===================================================================
--- trunk/firmware/drivers/rtc/rtc_s3c2440.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/drivers/rtc/rtc_s3c2440.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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

Modified: trunk/firmware/export/rtc.h
===================================================================
--- trunk/firmware/export/rtc.h	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/export/rtc.h	2009-09-26 14:58:32 UTC (rev 22839)
@@ -24,13 +24,19 @@
 #include <stdbool.h> 
 #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
 
@@ -53,3 +59,4 @@
 #endif /* CONFIG_RTC */
 
 #endif
+

Modified: trunk/firmware/include/timefuncs.h
===================================================================
--- trunk/firmware/include/timefuncs.h	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/firmware/include/timefuncs.h	2009-09-26 14:58:32 UTC (rev 22839)
@@ -35,3 +35,4 @@
 #endif
 
 #endif /* _TIMEFUNCS_H_ */
+

Modified: trunk/uisimulator/common/stubs.c
===================================================================
--- trunk/uisimulator/common/stubs.c	2009-09-26 10:47:10 UTC (rev 22838)
+++ trunk/uisimulator/common/stubs.c	2009-09-26 14:58:32 UTC (rev 22839)
@@ -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;
 }
 

_______________________________________________
rockbox-cvs mailing list
rockbox-cvs@cool.haxx.se
http://cool.haxx.se/cgi-bin/mailman/listinfo/rockbox-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic