From 172fc967b07f59e4928db9ca331f2f7a3a383c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?= Date: Sat, 22 May 2010 00:28:03 +0000 Subject: [PATCH] as3525v2: RTC alarm A specific poweroff function needs to be used for wake-up to work Disable RTC in bootloaders for consistency with other Sansas git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26243 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/rtc/rtc_as3514.c | 107 +++++++++++++++++++++- firmware/export/as3514.h | 4 + firmware/export/config/sansaclipplus.h | 5 +- firmware/export/config/sansaclipv2.h | 5 +- firmware/export/config/sansafuzev2.h | 6 +- firmware/target/arm/as3525/power-as3525.c | 8 ++ 6 files changed, 131 insertions(+), 4 deletions(-) diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index 8597d138fb..fe2921b433 100644 --- a/firmware/drivers/rtc/rtc_as3514.c +++ b/firmware/drivers/rtc/rtc_as3514.c @@ -51,6 +51,112 @@ static inline bool is_leapyear(int year) return false; } +#ifdef HAVE_RTC_ALARM /* as3543 */ +static int wakeup_h; +static int wakeup_m; +static bool alarm_enabled = false; + +void rtc_set_alarm(int h, int m) +{ + wakeup_h = h; + wakeup_m = m; +} + +void rtc_get_alarm(int *h, int *m) +{ + *h = wakeup_h; + *m = wakeup_m; +} + +void rtc_alarm_poweroff(void) +{ + if(!alarm_enabled) + return; + + struct tm tm; + rtc_read_datetime(&tm); + int hours = wakeup_h - tm.tm_hour; + int mins = wakeup_m - tm.tm_min; + if(mins < 0) + { + mins += 60; + hours -= 1; + } + if(hours < 0) + hours += 24; + + uint32_t seconds = hours*3600 + mins*60; + if(seconds == 0) + seconds = 24*3600; + + seconds -= tm.tm_sec; + + disable_irq(); + + ascodec_write_pmu(0x1a, 4, 0x0); // In_Cntr : disable hearbeat source + + ascodec_write(AS3543_WAKEUP, seconds); + seconds >>= 8; + ascodec_write(AS3543_WAKEUP, seconds); + seconds >>= 8; + seconds |= 1<<7; /* enable bit */ + ascodec_write(AS3543_WAKEUP, seconds); + + /* write our watermark : desired time of wake up */ + ascodec_write(AS3543_WAKEUP, wakeup_h); + ascodec_write(AS3543_WAKEUP, wakeup_m); + + ascodec_write(AS3514_SYSTEM, (1<<3) | (1<<0)); // enable hearbeat watchdog + + while(1); +} + +bool rtc_enable_alarm(bool enable) +{ + return alarm_enabled = enable; +} + +bool rtc_check_alarm_started(bool release_alarm) +{ + (void) release_alarm; + + /* was it an alarm that triggered power on ? */ + bool alarm_start = false; + + /* 3 first reads give the 23 bits counter and enable bit */ + ascodec_read(AS3543_WAKEUP); /* bits 7:0 */ + ascodec_read(AS3543_WAKEUP); /* bits 15:8 */ + if(ascodec_read(AS3543_WAKEUP) & (1<<7)) /* enable bit */ + { + alarm_enabled = true; + + /* subsequent reads give the 16 bytes static SRAM */ + wakeup_h = ascodec_read(AS3543_WAKEUP); + wakeup_m = ascodec_read(AS3543_WAKEUP); + + struct tm tm; + rtc_read_datetime(&tm); + + /* do we wake up at the programmed time, or for another reason ? */ + if(wakeup_h == tm.tm_hour && wakeup_m == tm.tm_min) + alarm_start = true; + } + + /* disable alarm */ + ascodec_write(AS3543_WAKEUP, 0); /* bits 7:0 */ + ascodec_write(AS3543_WAKEUP, 0); /* bits 15:8 */ + ascodec_write(AS3543_WAKEUP, 0); /* bits 22:16 + enable bit */ + + return alarm_start; +} + +bool rtc_check_alarm_flag(void) +{ + /* We don't need to do anything special if it has already fired */ + return false; +} +#endif /* HAVE_RTC_ALARM */ + void rtc_init(void) { } @@ -168,4 +274,3 @@ int rtc_write_datetime(const struct tm *tm) } return 1; } - diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h index e9eda62ee3..31253724a7 100644 --- a/firmware/export/as3514.h +++ b/firmware/export/as3514.h @@ -96,6 +96,10 @@ extern void audiohw_set_lineout_vol(int vol_l, int vol_r); #define AS3514_SUPERVISOR 0x24 #endif +#ifdef HAVE_AS3543 +#define AS3543_WAKEUP 0x22 +#endif + /* AS3543 has 2 IRQ_ENRD registers at 0x23 and 0x24, but we don't use them * We call the real IRQ_ENRD2 register, IRQ_ENRD0, to stay compatible with * as3514, because the bits we use are the same diff --git a/firmware/export/config/sansaclipplus.h b/firmware/export/config/sansaclipplus.h index ab4408afe5..9382b22cbd 100644 --- a/firmware/export/config/sansaclipplus.h +++ b/firmware/export/config/sansaclipplus.h @@ -101,9 +101,12 @@ #define HAVE_AS3514 #define HAVE_AS3543 -/* define this if you have a real-time clock */ #ifndef BOOTLOADER +/* define this if you have a real-time clock */ #define CONFIG_RTC RTC_AS3514 + +/* Define if the device can wake from an RTC alarm */ +#define HAVE_RTC_ALARM #endif /* Define this if you have a software controlled poweroff */ diff --git a/firmware/export/config/sansaclipv2.h b/firmware/export/config/sansaclipv2.h index 262ed36167..3ae09b7003 100644 --- a/firmware/export/config/sansaclipv2.h +++ b/firmware/export/config/sansaclipv2.h @@ -97,9 +97,12 @@ #define HAVE_AS3514 #define HAVE_AS3543 -/* define this if you have a real-time clock */ #ifndef BOOTLOADER +/* define this if you have a real-time clock */ #define CONFIG_RTC RTC_AS3514 + +/* Define if the device can wake from an RTC alarm */ +#define HAVE_RTC_ALARM #endif /* Define this if you have a software controlled poweroff */ diff --git a/firmware/export/config/sansafuzev2.h b/firmware/export/config/sansafuzev2.h index a21eb34f94..8b13217dce 100644 --- a/firmware/export/config/sansafuzev2.h +++ b/firmware/export/config/sansafuzev2.h @@ -61,10 +61,14 @@ /* define this if you can invert the colours on your LCD */ //#define HAVE_LCD_INVERT - +#ifndef BOOTLOADER /* define this if you have a real-time clock */ #define CONFIG_RTC RTC_AS3514 +/* Define if the device can wake from an RTC alarm */ +#define HAVE_RTC_ALARM +#endif + /* There is no hardware tone control */ #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/target/arm/as3525/power-as3525.c b/firmware/target/arm/as3525/power-as3525.c index 7b93dd1cd1..21ce98bd75 100644 --- a/firmware/target/arm/as3525/power-as3525.c +++ b/firmware/target/arm/as3525/power-as3525.c @@ -26,6 +26,14 @@ void power_off(void) { +#ifdef HAVE_RTC_ALARM + /* as3543 RTC wake-up needs a specific power down */ + + extern void rtc_alarm_poweroff(void); /* in drivers/rtc/rtc_as3514.c */ + + rtc_alarm_poweroff(); /* will return if wake-up isn't enabled */ +#endif /* HAVE_RTC_ALARM */ + /* clear bit 0 of system register */ ascodec_write(AS3514_SYSTEM, ascodec_read(AS3514_SYSTEM) & ~1);