diff options
-rw-r--r-- | apps/alarm_menu.c | 18 | ||||
-rw-r--r-- | apps/lang/english.lang | 8 | ||||
-rw-r--r-- | firmware/drivers/rtc.c | 36 | ||||
-rw-r--r-- | firmware/export/rtc.h | 1 | ||||
-rw-r--r-- | 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) | |||
82 | lcd_update(); | 82 | lcd_update(); |
83 | rtc_init(); | 83 | rtc_init(); |
84 | rtc_set_alarm(h,m); | 84 | rtc_set_alarm(h,m); |
85 | /* in some cases enabling the alarm results in an activated AF flag */ | 85 | rtc_enable_alarm(true); |
86 | /* this should not happen, but it does */ | ||
87 | /* if you know why, tell me! */ | ||
88 | /* for now, we try again forever in this case */ | ||
89 | while (rtc_enable_alarm(true)) { /* error occured */ | ||
90 | sleep(HZ / 10); | ||
91 | rtc_init(); | ||
92 | rtc_set_alarm(h,m); | ||
93 | } | ||
94 | sleep(HZ); | ||
95 | lcd_puts(0,1,str(LANG_ALARM_MOD_SHUTDOWN)); | 86 | lcd_puts(0,1,str(LANG_ALARM_MOD_SHUTDOWN)); |
96 | lcd_update(); | 87 | lcd_update(); |
97 | sleep(HZ); | 88 | sleep(HZ); |
98 | power_off(); | 89 | done = true; |
99 | } else { | 90 | } else { |
100 | lcd_clear_display(); | 91 | lcd_clear_display(); |
101 | lcd_puts(0,0,str(LANG_ALARM_MOD_ERROR)); | 92 | lcd_puts(0,0,str(LANG_ALARM_MOD_ERROR)); |
@@ -150,6 +141,11 @@ bool alarm_screen(void) | |||
150 | case BUTTON_STOP: | 141 | case BUTTON_STOP: |
151 | case BUTTON_MENU: | 142 | case BUTTON_MENU: |
152 | #endif | 143 | #endif |
144 | lcd_clear_display(); | ||
145 | lcd_puts(0,0,str(LANG_ALARM_MOD_DISABLE)); | ||
146 | lcd_update(); | ||
147 | sleep(HZ); | ||
148 | rtc_enable_alarm(false); | ||
153 | done = true; | 149 | done = true; |
154 | break; | 150 | break; |
155 | } | 151 | } |
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: | |||
1155 | 1155 | ||
1156 | id: LANG_ALARM_MOD_SHUTDOWN | 1156 | id: LANG_ALARM_MOD_SHUTDOWN |
1157 | desc: The text that tells the user that the alarm time is ok and the device shuts off (for the RTC alarm mod). | 1157 | desc: The text that tells the user that the alarm time is ok and the device shuts off (for the RTC alarm mod). |
1158 | eng: "Shutting Down..." | 1158 | eng: "Alarm Set" |
1159 | voice: "" | 1159 | voice: "" |
1160 | new: | 1160 | new: |
1161 | 1161 | ||
@@ -3003,3 +3003,9 @@ desc: Start Rockbox in Recording screen | |||
3003 | eng: "Show recording screen on startup" | 3003 | eng: "Show recording screen on startup" |
3004 | voice: "Show recording screen on startup" | 3004 | voice: "Show recording screen on startup" |
3005 | new: | 3005 | new: |
3006 | |||
3007 | id: LANG_ALARM_MOD_DISABLE | ||
3008 | desc: Announce that the RTC alarm has been turned off | ||
3009 | eng: "Alarm Disabled" | ||
3010 | voice: "Alarm Disabled" | ||
3011 | 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 @@ | |||
20 | #ifdef HAVE_RTC | 20 | #ifdef HAVE_RTC |
21 | #include "i2c.h" | 21 | #include "i2c.h" |
22 | #include "rtc.h" | 22 | #include "rtc.h" |
23 | #include "kernel.h" | ||
23 | #include <stdbool.h> | 24 | #include <stdbool.h> |
24 | 25 | ||
25 | #define RTC_ADR 0xd0 | 26 | #define RTC_ADR 0xd0 |
@@ -31,7 +32,7 @@ void rtc_init(void) | |||
31 | unsigned char data; | 32 | unsigned char data; |
32 | 33 | ||
33 | #ifdef HAVE_ALARM_MOD | 34 | #ifdef HAVE_ALARM_MOD |
34 | /* Check + save alarm bit first, since something in rtc_init resets AF */ | 35 | /* Check + save alarm bit first, before the power thread starts watching */ |
35 | rtc_check_alarm_started(false); | 36 | rtc_check_alarm_started(false); |
36 | #endif | 37 | #endif |
37 | 38 | ||
@@ -67,7 +68,6 @@ void rtc_init(void) | |||
67 | otherwise the player can't be turned off. */ | 68 | otherwise the player can't be turned off. */ |
68 | rtc_write(8, rtc_read(8) | 0x80); | 69 | rtc_write(8, rtc_read(8) | 0x80); |
69 | 70 | ||
70 | rtc_enable_alarm(false); | ||
71 | #endif | 71 | #endif |
72 | } | 72 | } |
73 | 73 | ||
@@ -85,12 +85,23 @@ bool rtc_check_alarm_started(bool release_alarm) | |||
85 | alarm_state &= ~release_alarm; | 85 | alarm_state &= ~release_alarm; |
86 | } else { | 86 | } else { |
87 | /* This call resets AF, so we store the state for later recall */ | 87 | /* This call resets AF, so we store the state for later recall */ |
88 | rc = alarm_state = ((rtc_read(0x0f) & 0x40) != 0); | 88 | rc = alarm_state = rtc_check_alarm_flag(); |
89 | run_before = true; | 89 | run_before = true; |
90 | } | 90 | } |
91 | 91 | ||
92 | return rc; | 92 | return rc; |
93 | } | 93 | } |
94 | /* | ||
95 | * Checks the AL register. This call resets AL once read. | ||
96 | * | ||
97 | * We're only interested if ABE is set. AL is still raised regardless | ||
98 | * even if the unit is off when the alarm occurs. | ||
99 | */ | ||
100 | bool rtc_check_alarm_flag(void) | ||
101 | { | ||
102 | return ( ( (rtc_read(0x0f) & 0x40) != 0) && | ||
103 | (rtc_read(0x0a) & 0x20) ); | ||
104 | } | ||
94 | 105 | ||
95 | /* set alarm time registers to the given time (repeat once per day) */ | 106 | /* set alarm time registers to the given time (repeat once per day) */ |
96 | void rtc_set_alarm(int h, int m) | 107 | void rtc_set_alarm(int h, int m) |
@@ -140,14 +151,21 @@ bool rtc_enable_alarm(bool enable) | |||
140 | rtc_write(0x0a, data); | 151 | rtc_write(0x0a, data); |
141 | 152 | ||
142 | /* check if alarm flag AF is off (as it should be) */ | 153 | /* check if alarm flag AF is off (as it should be) */ |
143 | if ((rtc_read(0x0f) & 0x40) != 0) /* on */ | 154 | /* in some cases enabling the alarm results in an activated AF flag */ |
155 | /* this should not happen, but it does */ | ||
156 | /* if you know why, tell me! */ | ||
157 | /* for now, we try again forever in this case */ | ||
158 | while (rtc_check_alarm_flag()) /* on */ | ||
144 | { | 159 | { |
145 | data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ | 160 | data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ |
146 | rtc_write(0x0a, data); | 161 | rtc_write(0x0a, data); |
147 | return true; | 162 | sleep(HZ / 10); |
148 | } else { | 163 | rtc_check_alarm_flag(); |
149 | return false; /* all ok */ | 164 | data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */ |
165 | rtc_write(0x0a, data); | ||
150 | } | 166 | } |
167 | |||
168 | return false; /* all ok */ | ||
151 | } | 169 | } |
152 | 170 | ||
153 | #endif /* HAVE_ALARM_MOD */ | 171 | #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); | |||
32 | void rtc_get_alarm(int *h, int *m); | 32 | void rtc_get_alarm(int *h, int *m); |
33 | bool rtc_enable_alarm(bool enable); | 33 | bool rtc_enable_alarm(bool enable); |
34 | bool rtc_check_alarm_started(bool release_alarm); | 34 | bool rtc_check_alarm_started(bool release_alarm); |
35 | bool rtc_check_alarm_flag(void); | ||
35 | #endif /* HAVE_ALARM_MOD */ | 36 | #endif /* HAVE_ALARM_MOD */ |
36 | 37 | ||
37 | #endif /* HAVE_RTC */ | 38 | #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 @@ | |||
36 | #include "powermgmt.h" | 36 | #include "powermgmt.h" |
37 | #include "backlight.h" | 37 | #include "backlight.h" |
38 | #include "lcd.h" | 38 | #include "lcd.h" |
39 | #include "rtc.h" | ||
39 | #ifdef CONFIG_TUNER | 40 | #ifdef CONFIG_TUNER |
40 | #include "fmradio.h" | 41 | #include "fmradio.h" |
41 | #endif | 42 | #endif |
@@ -441,6 +442,15 @@ static void car_adapter_mode_processing(void) | |||
441 | } | 442 | } |
442 | #endif | 443 | #endif |
443 | 444 | ||
445 | /* Check to see whether or not we've received an alarm in the last second */ | ||
446 | #ifdef HAVE_ALARM_MOD | ||
447 | static void power_thread_rtc_process(void) | ||
448 | { | ||
449 | |||
450 | rtc_check_alarm_flag(); | ||
451 | } | ||
452 | #endif | ||
453 | |||
444 | /* | 454 | /* |
445 | * This function is called to do the relativly long sleep waits from within the | 455 | * This function is called to do the relativly long sleep waits from within the |
446 | * main power_thread loop while at the same time servicing any other periodic | 456 | * main power_thread loop while at the same time servicing any other periodic |
@@ -456,6 +466,9 @@ static void power_thread_sleep(int ticks) | |||
456 | ticks -= small_ticks; | 466 | ticks -= small_ticks; |
457 | 467 | ||
458 | car_adapter_mode_processing(); | 468 | car_adapter_mode_processing(); |
469 | #ifdef HAVE_ALARM_MOD | ||
470 | power_thread_rtc_process(); | ||
471 | #endif | ||
459 | } | 472 | } |
460 | #else | 473 | #else |
461 | sleep(ticks); /* no fast-processing functions, sleep the whole time */ | 474 | sleep(ticks); /* no fast-processing functions, sleep the whole time */ |
@@ -491,7 +504,10 @@ static void power_thread(void) | |||
491 | { | 504 | { |
492 | /* never read power while disk is spinning, unless in USB mode */ | 505 | /* never read power while disk is spinning, unless in USB mode */ |
493 | if (ata_disk_is_active() && !usb_inserted()) { | 506 | if (ata_disk_is_active() && !usb_inserted()) { |
494 | sleep(HZ * 2); | 507 | #ifdef HAVE_ALARM_MOD |
508 | power_thread_rtc_process(); | ||
509 | #endif | ||
510 | sleep(HZ); | ||
495 | continue; | 511 | continue; |
496 | } | 512 | } |
497 | 513 | ||
@@ -876,7 +892,9 @@ void powermgmt_init(void) | |||
876 | 892 | ||
877 | #endif /* SIMULATOR */ | 893 | #endif /* SIMULATOR */ |
878 | 894 | ||
879 | void shutdown_hw(void) { | 895 | /* Various hardware housekeeping tasks relating to shutting down the jukebox */ |
896 | void shutdown_hw(void) | ||
897 | { | ||
880 | #ifndef SIMULATOR | 898 | #ifndef SIMULATOR |
881 | mpeg_stop(); | 899 | mpeg_stop(); |
882 | ata_flush(); | 900 | ata_flush(); |