From a83ffb208f53a91aeab09b933e3544ec29919ce1 Mon Sep 17 00:00:00 2001 From: Christi Scarborough Date: Sun, 6 Feb 2005 17:21:42 +0000 Subject: A proper alarm clock for the V2/FM (and v1 with mod) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5818 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/rtc.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'firmware/drivers/rtc.c') diff --git a/firmware/drivers/rtc.c b/firmware/drivers/rtc.c index 5f60c23bdd..0e65a8be5b 100644 --- a/firmware/drivers/rtc.c +++ b/firmware/drivers/rtc.c @@ -20,6 +20,7 @@ #ifdef HAVE_RTC #include "i2c.h" #include "rtc.h" +#include "kernel.h" #include #define RTC_ADR 0xd0 @@ -31,7 +32,7 @@ void rtc_init(void) unsigned char data; #ifdef HAVE_ALARM_MOD - /* Check + save alarm bit first, since something in rtc_init resets AF */ + /* Check + save alarm bit first, before the power thread starts watching */ rtc_check_alarm_started(false); #endif @@ -67,7 +68,6 @@ void rtc_init(void) otherwise the player can't be turned off. */ rtc_write(8, rtc_read(8) | 0x80); - rtc_enable_alarm(false); #endif } @@ -85,12 +85,23 @@ bool rtc_check_alarm_started(bool release_alarm) alarm_state &= ~release_alarm; } else { /* This call resets AF, so we store the state for later recall */ - rc = alarm_state = ((rtc_read(0x0f) & 0x40) != 0); + rc = alarm_state = rtc_check_alarm_flag(); run_before = true; } return rc; } +/* + * Checks the AL register. This call resets AL once read. + * + * We're only interested if ABE is set. AL is still raised regardless + * even if the unit is off when the alarm occurs. + */ +bool rtc_check_alarm_flag(void) +{ + return ( ( (rtc_read(0x0f) & 0x40) != 0) && + (rtc_read(0x0a) & 0x20) ); +} /* set alarm time registers to the given time (repeat once per day) */ void rtc_set_alarm(int h, int m) @@ -140,14 +151,21 @@ bool rtc_enable_alarm(bool enable) rtc_write(0x0a, data); /* check if alarm flag AF is off (as it should be) */ - if ((rtc_read(0x0f) & 0x40) != 0) /* on */ + /* in some cases enabling the alarm results in an activated AF flag */ + /* this should not happen, but it does */ + /* if you know why, tell me! */ + /* for now, we try again forever in this case */ + while (rtc_check_alarm_flag()) /* on */ { - data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ - rtc_write(0x0a, data); - return true; - } else { - return false; /* all ok */ + data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ + rtc_write(0x0a, data); + sleep(HZ / 10); + rtc_check_alarm_flag(); + data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */ + rtc_write(0x0a, data); } + + return false; /* all ok */ } #endif /* HAVE_ALARM_MOD */ -- cgit v1.2.3