diff options
author | Thom Johansen <thomj@rockbox.org> | 2007-02-28 21:55:11 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2007-02-28 21:55:11 +0000 |
commit | 8fd6d658a1caeddc0a84dd69ffe45739bd466e74 (patch) | |
tree | 91f79d4d40d898a303998710a18ae62d8b8c7082 /firmware/drivers | |
parent | ab66955664f8987d064247dc6d585b5618745d29 (diff) | |
download | rockbox-8fd6d658a1caeddc0a84dd69ffe45739bd466e74.tar.gz rockbox-8fd6d658a1caeddc0a84dd69ffe45739bd466e74.zip |
Add wake on alarm support for Ipods. Rename HAVE_ALARM_MOD to HAVE_ALARM_RTC since it's not always a mod. Make Ipod PCF driver keep other flags in OOCC1 that have been set instead of overwriting them.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12522 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/pcf50605.c | 10 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_ds1339_ds3231.c | 6 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_m41st84w.c | 8 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_pcf50605.c | 94 |
4 files changed, 102 insertions, 16 deletions
diff --git a/firmware/drivers/pcf50605.c b/firmware/drivers/pcf50605.c index 0610f41aec..cf4ea9fecb 100644 --- a/firmware/drivers/pcf50605.c +++ b/firmware/drivers/pcf50605.c | |||
@@ -89,10 +89,9 @@ int pcf50605_write(int address, unsigned char val) | |||
89 | 89 | ||
90 | int pcf50605_write_multiple(int address, const unsigned char* buf, int count) | 90 | int pcf50605_write_multiple(int address, const unsigned char* buf, int count) |
91 | { | 91 | { |
92 | /* TODO */ | 92 | int i; |
93 | (void)address; | 93 | for (i = 0; i < count; i++) |
94 | (void)buf; | 94 | pp_i2c_send(0x8, address + i, buf[i]); |
95 | (void)count; | ||
96 | return 0; | 95 | return 0; |
97 | } | 96 | } |
98 | 97 | ||
@@ -102,7 +101,8 @@ int pcf50605_write_multiple(int address, const unsigned char* buf, int count) | |||
102 | power on your iPod again. */ | 101 | power on your iPod again. */ |
103 | void pcf50605_standby_mode(void) | 102 | void pcf50605_standby_mode(void) |
104 | { | 103 | { |
105 | pcf50605_write(OOCC1, GOSTDBY | CHGWAK | EXTONWAK); | 104 | const char mask = pcf50605_read(OOCC1) | GOSTDBY | CHGWAK | EXTONWAK; |
105 | pcf50605_write(OOCC1, mask); | ||
106 | } | 106 | } |
107 | 107 | ||
108 | void pcf50605_init(void) | 108 | void pcf50605_init(void) |
diff --git a/firmware/drivers/rtc/rtc_ds1339_ds3231.c b/firmware/drivers/rtc/rtc_ds1339_ds3231.c index df67fed735..7396c2e0a1 100644 --- a/firmware/drivers/rtc/rtc_ds1339_ds3231.c +++ b/firmware/drivers/rtc/rtc_ds1339_ds3231.c | |||
@@ -33,14 +33,14 @@ void rtc_init(void) | |||
33 | /* read one byte from RTC; 0 on success */ | 33 | /* read one byte from RTC; 0 on success */ |
34 | rtc_detected = !sw_i2c_read(RTC_ADDR, 0, &byte, 1); | 34 | rtc_detected = !sw_i2c_read(RTC_ADDR, 0, &byte, 1); |
35 | 35 | ||
36 | #ifdef HAVE_ALARM_MOD | 36 | #ifdef HAVE_RTC_ALARM |
37 | /* Check + save alarm bit first, before the power thread starts watching */ | 37 | /* Check + save alarm bit first, before the power thread starts watching */ |
38 | rtc_check_alarm_started(false); | 38 | rtc_check_alarm_started(false); |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | } | 41 | } |
42 | 42 | ||
43 | #ifdef HAVE_ALARM_MOD | 43 | #ifdef HAVE_RTC_ALARM |
44 | 44 | ||
45 | /* check whether the unit has been started by the RTC alarm function */ | 45 | /* check whether the unit has been started by the RTC alarm function */ |
46 | /* (check for A2F, which => started using wakeup alarm) */ | 46 | /* (check for A2F, which => started using wakeup alarm) */ |
@@ -117,7 +117,7 @@ bool rtc_enable_alarm(bool enable) | |||
117 | return false; /* all ok */ | 117 | return false; /* all ok */ |
118 | } | 118 | } |
119 | 119 | ||
120 | #endif /* HAVE_ALARM_MOD */ | 120 | #endif /* HAVE_RTC_ALARM */ |
121 | 121 | ||
122 | int rtc_read_datetime(unsigned char* buf) | 122 | int rtc_read_datetime(unsigned char* buf) |
123 | { | 123 | { |
diff --git a/firmware/drivers/rtc/rtc_m41st84w.c b/firmware/drivers/rtc/rtc_m41st84w.c index 1d76867e13..4e861692d8 100644 --- a/firmware/drivers/rtc/rtc_m41st84w.c +++ b/firmware/drivers/rtc/rtc_m41st84w.c | |||
@@ -31,7 +31,7 @@ void rtc_init(void) | |||
31 | { | 31 | { |
32 | unsigned char data; | 32 | unsigned char data; |
33 | 33 | ||
34 | #ifdef HAVE_ALARM_MOD | 34 | #ifdef HAVE_RTC_ALARM |
35 | /* Check + save alarm bit first, before the power thread starts watching */ | 35 | /* Check + save alarm bit first, before the power thread starts watching */ |
36 | rtc_check_alarm_started(false); | 36 | rtc_check_alarm_started(false); |
37 | #endif | 37 | #endif |
@@ -52,7 +52,7 @@ void rtc_init(void) | |||
52 | rtc_write(0x0c,data); | 52 | rtc_write(0x0c,data); |
53 | } | 53 | } |
54 | 54 | ||
55 | #ifdef HAVE_ALARM_MOD | 55 | #ifdef HAVE_RTC_ALARM |
56 | 56 | ||
57 | /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */ | 57 | /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */ |
58 | /* without this, the alarm won't work! */ | 58 | /* without this, the alarm won't work! */ |
@@ -71,7 +71,7 @@ void rtc_init(void) | |||
71 | #endif | 71 | #endif |
72 | } | 72 | } |
73 | 73 | ||
74 | #ifdef HAVE_ALARM_MOD | 74 | #ifdef HAVE_RTC_ALARM |
75 | 75 | ||
76 | /* check whether the unit has been started by the RTC alarm function */ | 76 | /* check whether the unit has been started by the RTC alarm function */ |
77 | /* (check for AF, which => started using wakeup alarm) */ | 77 | /* (check for AF, which => started using wakeup alarm) */ |
@@ -168,7 +168,7 @@ bool rtc_enable_alarm(bool enable) | |||
168 | return false; /* all ok */ | 168 | return false; /* all ok */ |
169 | } | 169 | } |
170 | 170 | ||
171 | #endif /* HAVE_ALARM_MOD */ | 171 | #endif /* HAVE_RTC_ALARM */ |
172 | 172 | ||
173 | int rtc_write(unsigned char address, unsigned char value) | 173 | int rtc_write(unsigned char address, unsigned char value) |
174 | { | 174 | { |
diff --git a/firmware/drivers/rtc/rtc_pcf50605.c b/firmware/drivers/rtc/rtc_pcf50605.c index 1bc40146ff..fedcdd3cdf 100644 --- a/firmware/drivers/rtc/rtc_pcf50605.c +++ b/firmware/drivers/rtc/rtc_pcf50605.c | |||
@@ -24,8 +24,12 @@ | |||
24 | #include "pcf50605.h" | 24 | #include "pcf50605.h" |
25 | #include <stdbool.h> | 25 | #include <stdbool.h> |
26 | 26 | ||
27 | /* Values which each disable one alarm time register */ | ||
28 | static char alarm_disable[] = { 0x7f, 0x7f, 0x3f, 0x07, 0x3f, 0x1f, 0xff }; | ||
29 | |||
27 | void rtc_init(void) | 30 | void rtc_init(void) |
28 | { | 31 | { |
32 | rtc_check_alarm_started(false); | ||
29 | } | 33 | } |
30 | 34 | ||
31 | int rtc_read_datetime(unsigned char* buf) | 35 | int rtc_read_datetime(unsigned char* buf) |
@@ -35,11 +39,93 @@ int rtc_read_datetime(unsigned char* buf) | |||
35 | 39 | ||
36 | int rtc_write_datetime(unsigned char* buf) | 40 | int rtc_write_datetime(unsigned char* buf) |
37 | { | 41 | { |
38 | int i; | 42 | pcf50605_write_multiple(0x0a, buf, 7); |
43 | return 1; | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * Checks the PCF interrupt 1 register bit 7 to see if an alarm interrupt has | ||
48 | * triggered since last we checked. | ||
49 | */ | ||
50 | bool rtc_check_alarm_flag(void) | ||
51 | { | ||
52 | return pcf50605_read(0x02) & 0x80; | ||
53 | } | ||
39 | 54 | ||
40 | for (i=0;i<7;i++) { | 55 | /** |
41 | pcf50605_write(0x0a+i, buf[i]); | 56 | * Enables or disables the alarm. |
57 | * The Ipod bootloader clears all PCF interrupt registers and always enables | ||
58 | * the "wake on RTC" bit on OOCC1, so we have to rely on other means to find | ||
59 | * out if we just woke from an alarm. | ||
60 | * Return value is always false for us. | ||
61 | */ | ||
62 | bool rtc_enable_alarm(bool enable) | ||
63 | { | ||
64 | if (enable) { | ||
65 | /* Tell the PCF to ignore everything but second, minute and hour, so | ||
66 | * that an alarm will trigger the next time the alarm time occurs. | ||
67 | */ | ||
68 | pcf50605_write_multiple(0x14, alarm_disable + 3, 4); | ||
69 | /* Unmask the alarm interrupt (might be unneeded) */ | ||
70 | pcf50605_write(0x5, pcf50605_read(0x5) & ~0x80); | ||
71 | /* Make sure wake on RTC is set */ | ||
72 | pcf50605_write(0x8, pcf50605_read(0x8) | 0x10); | ||
73 | } else { | ||
74 | /* We use this year to indicate a disabled alarm. If you happen to live | ||
75 | * around this time and are annoyed by this, feel free to seek out my | ||
76 | * grave and do something nasty to it. | ||
77 | */ | ||
78 | pcf50605_write(0x17, 0x99); | ||
42 | } | 79 | } |
80 | return false; | ||
81 | } | ||
43 | 82 | ||
44 | return 1; | 83 | /** |
84 | * Check if alarm caused unit to start. | ||
85 | */ | ||
86 | bool rtc_check_alarm_started(bool release_alarm) | ||
87 | { | ||
88 | static bool run_before = false, alarm_state; | ||
89 | bool rc; | ||
90 | |||
91 | if (run_before) { | ||
92 | rc = alarm_state; | ||
93 | alarm_state &= ~release_alarm; | ||
94 | } else { | ||
95 | char rt[3], at[3]; | ||
96 | /* The Ipod bootloader seems to read (and thus clear) the PCF interrupt | ||
97 | * registers, so we need to find some other way to detect if an alarm | ||
98 | * just happened | ||
99 | */ | ||
100 | pcf50605_read_multiple(0x0a, rt, 3); | ||
101 | pcf50605_read_multiple(0x11, at, 3); | ||
102 | |||
103 | /* If alarm time and real time match within 10 seconds of each other, we | ||
104 | * assume an alarm just triggered | ||
105 | */ | ||
106 | rc = alarm_state = rt[1] == at[1] && rt[2] == at[2] | ||
107 | && (rt[0] - at[0]) <= 10; | ||
108 | run_before = true; | ||
109 | } | ||
110 | return rc; | ||
111 | } | ||
112 | |||
113 | void rtc_set_alarm(int h, int m) | ||
114 | { | ||
115 | /* Set us to wake at the first second of the specified time */ | ||
116 | pcf50605_write(0x11, 0); | ||
117 | /* Convert to BCD */ | ||
118 | pcf50605_write(0x12, ((m/10) << 4) | m%10); | ||
119 | pcf50605_write(0x13, ((h/10) << 4) | h%10); | ||
45 | } | 120 | } |
121 | |||
122 | void rtc_get_alarm(int *h, int *m) | ||
123 | { | ||
124 | char buf[2]; | ||
125 | |||
126 | pcf50605_read_multiple(0x12, buf, 2); | ||
127 | /* Convert from BCD */ | ||
128 | *m = ((buf[0] >> 4) & 0x7)*10 + (buf[0] & 0x0f); | ||
129 | *h = ((buf[1] >> 4) & 0x3)*10 + (buf[1] & 0x0f); | ||
130 | } | ||
131 | |||