diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-07-02 00:36:21 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-07-02 00:45:00 +0200 |
commit | d8024df1052966aa554424d88712244ae5978f2a (patch) | |
tree | c017a18d4570695d05c4afdee20697d1f30f8c59 | |
parent | 277367373300bc4bb034f0ef57809989eeb2d233 (diff) | |
download | rockbox-d8024df1052966aa554424d88712244ae5978f2a.tar.gz rockbox-d8024df1052966aa554424d88712244ae5978f2a.zip |
imx233: implement alarm wake up
This adds the application part of alarm wake up. On some targets
like the Fuze+, it will also require a bootloader change to make
sure that the device doesn't power down on alarm wake up (for
example on the Fuze+ the bootloader requires the power button to
be hold sufficiently long, thus preventing alarm wake up to work)
Change-Id: I5d01957852355fddbd48110d3d75a5533f07879e
-rw-r--r-- | firmware/drivers/rtc/rtc_imx233.c | 61 | ||||
-rw-r--r-- | firmware/target/arm/imx233/rtc-imx233.c | 10 | ||||
-rw-r--r-- | firmware/target/arm/imx233/rtc-imx233.h | 8 |
3 files changed, 67 insertions, 12 deletions
diff --git a/firmware/drivers/rtc/rtc_imx233.c b/firmware/drivers/rtc/rtc_imx233.c index 9ed8540b5d..e4dfcd89e9 100644 --- a/firmware/drivers/rtc/rtc_imx233.c +++ b/firmware/drivers/rtc/rtc_imx233.c @@ -28,15 +28,18 @@ #define YEAR1980 315532800 /* 1980/1/1 00:00:00 in UTC */ +#if defined(SANSA_FUZEPLUS) || defined(CREATIVE_ZENXFI3) +#define USE_PERSISTENT +#endif + void rtc_init(void) { /* rtc-imx233 is initialized by the system */ } -int rtc_read_datetime(struct tm *tm) +static void seconds_to_datetime(uint32_t seconds, struct tm *tm) { - uint32_t seconds = imx233_rtc_read_seconds(); -#if defined(SANSA_FUZEPLUS) || defined(CREATIVE_ZENXFI3) +#ifdef USE_PERSISTENT /* The OF uses PERSISTENT2 register to keep the adjustment and only changes * SECONDS if necessary. */ seconds += imx233_rtc_read_persistent(2); @@ -47,7 +50,11 @@ int rtc_read_datetime(struct tm *tm) #endif gmtime_r(&seconds, tm); +} +int rtc_read_datetime(struct tm *tm) +{ + seconds_to_datetime(imx233_rtc_read_seconds(), tm); return 0; } @@ -57,7 +64,7 @@ int rtc_write_datetime(const struct tm *tm) seconds = mktime((struct tm *)tm); -#if defined(SANSA_FUZEPLUS) || defined(CREATIVE_ZENXFI3) +#ifdef USE_PERSISTENT /* The OF uses PERSISTENT2 register to keep the adjustment and only changes * SECONDS if necessary. * NOTE: the OF uses this mechanism to prevent roll back in time. Although @@ -75,28 +82,58 @@ int rtc_write_datetime(const struct tm *tm) void rtc_set_alarm(int h, int m) { - (void) h; - (void) m; + /* transform alarm time to absolute time */ + struct tm tm; + seconds_to_datetime(imx233_rtc_read_seconds(), &tm); + /* if same date and hour/min is in the past, advance one day */ + if(h < tm.tm_hour || (h == tm.tm_hour && m <= tm.tm_min)) + seconds_to_datetime(imx233_rtc_read_seconds() + 3600 * 60, &tm); + tm.tm_hour = h; + tm.tm_min = m; + tm.tm_sec = 0; + + uint32_t seconds = mktime(&tm); +#ifdef USE_PERSISTENT + imx233_rtc_write_alarm(seconds - imx233_rtc_read_persistent(2)); +#else + imx233_rtc_write_alarm(seconds - YEAR1980); +#endif } void rtc_get_alarm(int *h, int *m) { - (void) h; - (void) m; + struct tm tm; + seconds_to_datetime(imx233_rtc_read_alarm(), &tm); + *m = tm.tm_min; + *h = tm.tm_hour; } void rtc_enable_alarm(bool enable) { - (void) enable; + BF_CLR(RTC_CTRL, ALARM_IRQ_EN); + BF_CLR(RTC_CTRL, ALARM_IRQ); + uint32_t val = imx233_rtc_read_persistent(0); + BF_WRX(val, RTC_PERSISTENT0, ALARM_EN, enable); + BF_WRX(val, RTC_PERSISTENT0, ALARM_WAKE_EN, enable); + BF_WRX(val, RTC_PERSISTENT0, ALARM_WAKE, 0); + imx233_rtc_write_persistent(0, val); } +/** + * Check if alarm caused unit to start. + */ bool rtc_check_alarm_started(bool release_alarm) { - (void) release_alarm; - return false; + bool res = BF_RDX(imx233_rtc_read_persistent(0), RTC_PERSISTENT0, ALARM_WAKE); + if(release_alarm) + rtc_enable_alarm(false); + return res; } +/** + * Checks if an alarm interrupt has triggered since last we checked. + */ bool rtc_check_alarm_flag(void) { - return false; + return BF_RD(RTC_CTRL, ALARM_IRQ); } diff --git a/firmware/target/arm/imx233/rtc-imx233.c b/firmware/target/arm/imx233/rtc-imx233.c index 31a82df86b..557c1e177b 100644 --- a/firmware/target/arm/imx233/rtc-imx233.c +++ b/firmware/target/arm/imx233/rtc-imx233.c @@ -38,6 +38,11 @@ void imx233_rtc_write_persistent(int idx, uint32_t val) imx233_rtc_write_reg(&HW_RTC_PERSISTENTn(idx), val); } +void imx233_rtc_write_alarm(uint32_t seconds) +{ + imx233_rtc_write_reg(&HW_RTC_ALARM, seconds); +} + struct imx233_rtc_info_t imx233_rtc_get_info(void) { struct imx233_rtc_info_t info; @@ -45,5 +50,10 @@ struct imx233_rtc_info_t imx233_rtc_get_info(void) info.seconds = HW_RTC_SECONDS; for(int i = 0; i < 6; i++) info.persistent[i] = HW_RTC_PERSISTENTn(i); + info.alarm = imx233_rtc_read_alarm(); + info.alarm_en = BF_RD(RTC_PERSISTENT0, ALARM_EN); + info.alarm_wake_en = BF_RD(RTC_PERSISTENT0, ALARM_WAKE_EN); + info.alarm_wake = BF_RD(RTC_PERSISTENT0, ALARM_WAKE); + info.alarm_irq = BF_RD(RTC_CTRL, ALARM_IRQ); return info; } diff --git a/firmware/target/arm/imx233/rtc-imx233.h b/firmware/target/arm/imx233/rtc-imx233.h index 3ad523bdbe..8a5f4d035c 100644 --- a/firmware/target/arm/imx233/rtc-imx233.h +++ b/firmware/target/arm/imx233/rtc-imx233.h @@ -33,6 +33,8 @@ struct imx233_rtc_info_t { uint32_t seconds; uint32_t persistent[6]; + uint32_t alarm; + bool alarm_en, alarm_wake_en, alarm_wake, alarm_irq; }; static inline void imx233_rtc_init(void) @@ -64,8 +66,14 @@ static inline void imx233_rtc_enable_msec_irq(bool enable) BF_CLR(RTC_CTRL, ONEMSEC_IRQ_EN); } +static inline uint32_t imx233_rtc_read_alarm(void) +{ + return HW_RTC_ALARM; +} + void imx233_rtc_write_seconds(uint32_t seconds); void imx233_rtc_write_persistent(int idx, uint32_t val); +void imx233_rtc_write_alarm(uint32_t seconds); struct imx233_rtc_info_t imx233_rtc_get_info(void); |