summaryrefslogtreecommitdiff
path: root/firmware/drivers/rtc.c
diff options
context:
space:
mode:
authorChristi Scarborough <christi@coraline.org>2005-02-06 17:21:42 +0000
committerChristi Scarborough <christi@coraline.org>2005-02-06 17:21:42 +0000
commita83ffb208f53a91aeab09b933e3544ec29919ce1 (patch)
tree1aa7f5fe667b2d65cf3482a5488539d7d25cec90 /firmware/drivers/rtc.c
parent59eb461f8255b636800c120d7640d10d6a15e175 (diff)
downloadrockbox-a83ffb208f53a91aeab09b933e3544ec29919ce1.tar.gz
rockbox-a83ffb208f53a91aeab09b933e3544ec29919ce1.zip
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
Diffstat (limited to 'firmware/drivers/rtc.c')
-rw-r--r--firmware/drivers/rtc.c36
1 files changed, 27 insertions, 9 deletions
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 */
100bool 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) */
96void rtc_set_alarm(int h, int m) 107void 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 */