summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2007-02-03 13:10:17 +0000
committerBarry Wardell <rockbox@barrywardell.net>2007-02-03 13:10:17 +0000
commit1a2dddc346e60211210c8f3b0b378be54108f652 (patch)
tree1ab8e8742b62dcc90e448d95e11658510bf5cbeb
parent28aa1316d4213043a7ead1655dfdee83370a181b (diff)
downloadrockbox-1a2dddc346e60211210c8f3b0b378be54108f652.tar.gz
rockbox-1a2dddc346e60211210c8f3b0b378be54108f652.zip
RTC support for Sansa.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12185 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/drivers/rtc/rtc_as3514.c165
-rw-r--r--firmware/export/config-e200.h2
-rw-r--r--firmware/export/config.h1
4 files changed, 169 insertions, 1 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 4a1aa3f244..15e8cf0603 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -138,6 +138,8 @@ drivers/rtc/rtc_pcf50605.c
drivers/rtc/rtc_e8564.c
#elif (CONFIG_RTC == RTC_S3C2440)
drivers/rtc/rtc_s3c2440.c
+#elif (CONFIG_RTC == RTC_AS3514)
+drivers/rtc/rtc_as3514.c
#endif /* (CONFIG_RTC == RTC_) */
#endif /* SIMULATOR */
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c
new file mode 100644
index 0000000000..8b234fcafe
--- /dev/null
+++ b/firmware/drivers/rtc/rtc_as3514.c
@@ -0,0 +1,165 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: rtc_as3514.c 12131 2007-01-27 20:48:48Z dan_a $
+ *
+ * Copyright (C) 2007 by Barry Wardell
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "rtc.h"
+#include "i2c-pp.h"
+#include <stdbool.h>
+
+#define MINUTE_SECONDS 60
+#define HOUR_SECONDS 3600
+#define DAY_SECONDS 86400
+#define WEEK_SECONDS 604800
+#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};
+
+static inline bool is_leapyear(int year)
+{
+ if( ((year%4)==0) && (((year%100)!=0) || ((year%400)==0)) )
+ return true;
+ else
+ return false;
+}
+
+void rtc_init(void)
+{
+}
+
+int rtc_read_datetime(unsigned char* buf)
+{
+ char tmp[4];
+ int year;
+ int i;
+ unsigned int seconds;
+
+ /* RTC_AS3514's slave address is 0x46*/
+ for (i=0;i<4;i++){
+ tmp[i] = i2c_readbyte(0x46,0x2a+i);
+ }
+ seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24);
+
+ /* 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 + 1) % 7;
+
+ /* Year */
+ year = 1980;
+ while(seconds>=LEAP_YEAR_SECONDS)
+ {
+ year++;
+
+ if(is_leapyear(year)){
+ seconds -= LEAP_YEAR_SECONDS;
+ } else {
+ seconds -= YEAR_SECONDS;
+ }
+ }
+
+ if(is_leapyear(year)) {
+ days_in_month[1] = 29;
+ } else {
+ days_in_month[1] = 28;
+ if(seconds>YEAR_SECONDS){
+ year++;
+ seconds -= YEAR_SECONDS;
+ }
+ }
+ buf[6] = year%100;
+
+ /* Month */
+ for(i=0; i<12; i++)
+ {
+ if(seconds < days_in_month[i]*DAY_SECONDS){
+ buf[5] = i+1;
+ break;
+ }
+
+ seconds -= days_in_month[i]*DAY_SECONDS;
+ }
+
+ /* Month Day */
+ buf[4] = seconds/DAY_SECONDS;
+ seconds -= buf[4]*DAY_SECONDS;
+
+ /* Hour */
+ buf[2] = seconds/HOUR_SECONDS;
+ seconds -= buf[2]*HOUR_SECONDS;
+
+ /* Minute */
+ buf[1] = seconds/MINUTE_SECONDS;
+ seconds -= buf[1]*MINUTE_SECONDS;
+
+ /* Second */
+ buf[0] = seconds;
+
+ /* Convert to Binary Coded Decimal format */
+ for(i=0; i<7; i++)
+ buf[i] = DEC2BCD(buf[i]);
+
+ return 7;
+}
+
+int rtc_write_datetime(unsigned char* buf)
+{
+ 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];
+
+ if(is_leapyear(year)) {
+ days_in_month[1] = 29;
+ } else {
+ days_in_month[1] = 28;
+ }
+
+ /* Number of days in months gone by this year*/
+ for(i=0; i<(buf[5]-1); 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]/4 + 6;
+
+ /* Convert to seconds since 1-Jan-1980 */
+ seconds = buf[0]
+ + buf[1]*MINUTE_SECONDS
+ + buf[2]*HOUR_SECONDS
+ + buf[4]*DAY_SECONDS
+ + month_days*DAY_SECONDS
+ + year_days*DAY_SECONDS;
+
+ /* Send data to RTC */
+ for (i=0;i<4;i++){
+ pp_i2c_send(0x46, 0x2a+i,((seconds>>(8*i)) & 0xff));
+ }
+ return 1;
+}
+
diff --git a/firmware/export/config-e200.h b/firmware/export/config-e200.h
index 4c9e1b2d47..4eb4840709 100644
--- a/firmware/export/config-e200.h
+++ b/firmware/export/config-e200.h
@@ -37,7 +37,7 @@
/* define this if you have a real-time clock */
#ifndef BOOTLOADER
-#define CONFIG_RTC RTC_E8564 /* TODO: figure this out */
+#define CONFIG_RTC RTC_AS3514
#endif
/* Define this if you have a software controlled poweroff */
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 20fdc1d770..ab1cfeafec 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -151,6 +151,7 @@
#define RTC_PCF50606 3 /* iriver H300 */
#define RTC_S3C2440 4
#define RTC_E8564 5 /* iriver H10 */
+#define RTC_AS3514 6 /* Sandisk Sansa e200 series */
/* USB On-the-go */
#define USBOTG_ISP1362 1362