From a83ffb208f53a91aeab09b933e3544ec29919ce1 Mon Sep 17 00:00:00 2001 From: Christi Scarborough Date: Sun, 6 Feb 2005 17:21:42 +0000 Subject: [PATCH] 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 --- apps/alarm_menu.c | 18 +++++++----------- apps/lang/english.lang | 8 +++++++- firmware/drivers/rtc.c | 36 +++++++++++++++++++++++++++--------- firmware/export/rtc.h | 1 + firmware/powermgmt.c | 22 ++++++++++++++++++++-- 5 files changed, 62 insertions(+), 23 deletions(-) diff --git a/apps/alarm_menu.c b/apps/alarm_menu.c index 20b2f51821..47d2c1226b 100644 --- a/apps/alarm_menu.c +++ b/apps/alarm_menu.c @@ -82,20 +82,11 @@ bool alarm_screen(void) lcd_update(); rtc_init(); rtc_set_alarm(h,m); - /* 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_enable_alarm(true)) { /* error occured */ - sleep(HZ / 10); - rtc_init(); - rtc_set_alarm(h,m); - } - sleep(HZ); + rtc_enable_alarm(true); lcd_puts(0,1,str(LANG_ALARM_MOD_SHUTDOWN)); lcd_update(); sleep(HZ); - power_off(); + done = true; } else { lcd_clear_display(); lcd_puts(0,0,str(LANG_ALARM_MOD_ERROR)); @@ -150,6 +141,11 @@ bool alarm_screen(void) case BUTTON_STOP: case BUTTON_MENU: #endif + lcd_clear_display(); + lcd_puts(0,0,str(LANG_ALARM_MOD_DISABLE)); + lcd_update(); + sleep(HZ); + rtc_enable_alarm(false); done = true; break; } diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 827ec0d002..82e3da494c 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -1155,7 +1155,7 @@ new: id: LANG_ALARM_MOD_SHUTDOWN desc: The text that tells the user that the alarm time is ok and the device shuts off (for the RTC alarm mod). -eng: "Shutting Down..." +eng: "Alarm Set" voice: "" new: @@ -3003,3 +3003,9 @@ desc: Start Rockbox in Recording screen eng: "Show recording screen on startup" voice: "Show recording screen on startup" new: + +id: LANG_ALARM_MOD_DISABLE +desc: Announce that the RTC alarm has been turned off +eng: "Alarm Disabled" +voice: "Alarm Disabled" +new: 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 */ diff --git a/firmware/export/rtc.h b/firmware/export/rtc.h index 7c2bd94d9c..fd793bc887 100644 --- a/firmware/export/rtc.h +++ b/firmware/export/rtc.h @@ -32,6 +32,7 @@ void rtc_set_alarm(int h, int m); void rtc_get_alarm(int *h, int *m); bool rtc_enable_alarm(bool enable); bool rtc_check_alarm_started(bool release_alarm); +bool rtc_check_alarm_flag(void); #endif /* HAVE_ALARM_MOD */ #endif /* HAVE_RTC */ diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 4495f58d74..37715abcdd 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -36,6 +36,7 @@ #include "powermgmt.h" #include "backlight.h" #include "lcd.h" +#include "rtc.h" #ifdef CONFIG_TUNER #include "fmradio.h" #endif @@ -441,6 +442,15 @@ static void car_adapter_mode_processing(void) } #endif +/* Check to see whether or not we've received an alarm in the last second */ +#ifdef HAVE_ALARM_MOD +static void power_thread_rtc_process(void) +{ + + rtc_check_alarm_flag(); +} +#endif + /* * This function is called to do the relativly long sleep waits from within the * main power_thread loop while at the same time servicing any other periodic @@ -456,6 +466,9 @@ static void power_thread_sleep(int ticks) ticks -= small_ticks; car_adapter_mode_processing(); +#ifdef HAVE_ALARM_MOD + power_thread_rtc_process(); +#endif } #else sleep(ticks); /* no fast-processing functions, sleep the whole time */ @@ -491,7 +504,10 @@ static void power_thread(void) { /* never read power while disk is spinning, unless in USB mode */ if (ata_disk_is_active() && !usb_inserted()) { - sleep(HZ * 2); +#ifdef HAVE_ALARM_MOD + power_thread_rtc_process(); +#endif + sleep(HZ); continue; } @@ -876,7 +892,9 @@ void powermgmt_init(void) #endif /* SIMULATOR */ -void shutdown_hw(void) { +/* Various hardware housekeeping tasks relating to shutting down the jukebox */ +void shutdown_hw(void) +{ #ifndef SIMULATOR mpeg_stop(); ata_flush();