diff options
| author | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-22 00:28:03 +0000 |
|---|---|---|
| committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-22 00:28:03 +0000 |
| commit | 172fc967b07f59e4928db9ca331f2f7a3a383c04 (patch) | |
| tree | c87f3d76efae7b84f0061336ed555d1e5a1f38c8 /firmware/drivers/rtc | |
| parent | 2e004fd4047a03e0e57bdb02a67a85a729a3caaa (diff) | |
| download | rockbox-172fc967b07f59e4928db9ca331f2f7a3a383c04.zip rockbox-172fc967b07f59e4928db9ca331f2f7a3a383c04.tar.gz rockbox-172fc967b07f59e4928db9ca331f2f7a3a383c04.tar.bz2 rockbox-172fc967b07f59e4928db9ca331f2f7a3a383c04.tar.xz | |
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
Diffstat (limited to 'firmware/drivers/rtc')
| -rw-r--r-- | firmware/drivers/rtc/rtc_as3514.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index 8597d13..fe2921b 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; } - |