summaryrefslogtreecommitdiff
path: root/firmware
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
parent59eb461f8255b636800c120d7640d10d6a15e175 (diff)
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')
-rw-r--r--firmware/drivers/rtc.c36
-rw-r--r--firmware/export/rtc.h1
-rw-r--r--firmware/powermgmt.c22
3 files changed, 48 insertions, 11 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 @@
#ifdef HAVE_RTC
#include "i2c.h"
#include "rtc.h"
+#include "kernel.h"
#include <stdbool.h>
#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();