From ad56fb322ce339ec3e61680600f0459004f5d928 Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 09:32:30 +0100 Subject: [PATCH 1/7] Fixed a bug in setHours() Previously was always subtracting 12 hours from the set hour value (in H12 mode) this cause a bug if the set hour was <=12. --- src/RTCZero.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 1923867..24cb6c2 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -119,7 +119,7 @@ void RTCZero::setMinutes(uint8_t minutes) void RTCZero::setHours(uint8_t hours) { - if (__time24) { + if ((__time24) || (hours < 13)) { RTC->MODE2.CLOCK.bit.HOUR = hours; } else { RTC->MODE2.CLOCK.bit.HOUR = hours - 12; From 9f14dccc7661de104902d2921f39d7282ddd1fc4 Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 09:34:46 +0100 Subject: [PATCH 2/7] Set XOSC23K to run in standby. --- src/RTCZero.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 24cb6c2..55f52b3 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -171,6 +171,7 @@ void RTCZero::setDate(uint8_t day, uint8_t month, uint8_t year) void RTCZero::config32kOSC() { SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | + SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_EN32K | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_STARTUP(6) | From a2af43d276d1fca2e133aafd03b1629a9201c577 Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 09:59:54 +0100 Subject: [PATCH 3/7] Added IRQ for alarm, alarm is disable by default. --- src/RTCZero.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 55f52b3..ed86a35 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -58,6 +58,14 @@ void RTCZero::begin(bool timeRep) RTC->MODE2.READREQ.reg &= ~RTC_READREQ_RCONT; // disable continuously mode RTC->MODE2.CTRL.reg = tmp_reg; + while (RTCisSyncing()) + ; + + NVIC_EnableIRQ(RTC_IRQn); // enable RTC interrupt + NVIC_SetPriority(RTC_IRQn, 0x00); + + RTC->MODE2.INTENSET.reg &= ~RTC_MODE2_INTENSET_ALARM0; // disable alarm interrupt by default + while (RTCisSyncing()) ; @@ -65,6 +73,11 @@ void RTCZero::begin(bool timeRep) RTCresetRemove(); } +void RTC_Handler(void) +{ + RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0; // must clear flag at end +} + /* * Get Functions */ From a2508d4b7af95addc5d060a615c9f76622b1ded3 Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 10:13:36 +0100 Subject: [PATCH 4/7] Added Get/Set methods for alarm time/date --- src/RTCZero.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ src/RTCZero.h | 18 ++++++++++ 2 files changed, 109 insertions(+) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index ed86a35..9131940 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -112,6 +112,36 @@ uint8_t RTCZero::getYear() return RTC->MODE2.CLOCK.bit.YEAR; } +uint8_t RTCZero::getAlarmSeconds() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND; +} + +uint8_t RTCZero::getAlarmMinutes() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.MINUTE; +} + +uint8_t RTCZero::getAlarmHours() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.HOUR; +} + +uint8_t RTCZero::getAlarmDay() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.DAY; +} + +uint8_t RTCZero::getAlarmMonth() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.MONTH; +} + +uint8_t RTCZero::getAlarmYear() +{ + return RTC->MODE2.Mode2Alarm[0].ALARM.bit.YEAR; +} + /* * Set Functions */ @@ -176,6 +206,67 @@ void RTCZero::setDate(uint8_t day, uint8_t month, uint8_t year) setYear(year); } +void RTCZero::setAlarmSeconds(uint8_t seconds) +{ + RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND = seconds; + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmMinutes(uint8_t minutes) +{ + RTC->MODE2.Mode2Alarm[0].ALARM.bit.MINUTE = minutes; + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmHours(uint8_t hours) +{ + if ((__time24) || (hours < 13)) { + RTC->MODE2.Mode2Alarm[0].ALARM.bit.HOUR = hours; + } + else { + RTC->MODE2.Mode2Alarm[0].ALARM.bit.HOUR = hours - 12; + } + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds) +{ + setAlarmSeconds(seconds); + setAlarmMinutes(minutes); + setAlarmHours(hours); +} + +void RTCZero::setAlarmDay(uint8_t day) +{ + RTC->MODE2.Mode2Alarm[0].ALARM.bit.DAY = day; + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmMonth(uint8_t month) +{ + RTC->MODE2.Mode2Alarm[0].ALARM.bit.MONTH = month; + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmYear(uint8_t year) +{ + RTC->MODE2.Mode2Alarm[0].ALARM.bit.YEAR = year; + while (RTCisSyncing()) + ; +} + +void RTCZero::setAlarmDate(uint8_t day, uint8_t month, uint8_t year) +{ + setAlarmDay(day); + setAlarmMonth(month); + setAlarmYear(year); +} + /* * Private Utility Functions */ diff --git a/src/RTCZero.h b/src/RTCZero.h index 243ed81..5c7ddc0 100644 --- a/src/RTCZero.h +++ b/src/RTCZero.h @@ -40,6 +40,14 @@ class RTCZero { uint8_t getMonth(); uint8_t getYear(); + uint8_t getAlarmSeconds(); + uint8_t getAlarmMinutes(); + uint8_t getAlarmHours(); + + uint8_t getAlarmDay(); + uint8_t getAlarmMonth(); + uint8_t getAlarmYear(); + /* Set Functions */ void setSeconds(uint8_t seconds); @@ -52,6 +60,16 @@ class RTCZero { void setYear(uint8_t year); void setDate(uint8_t day, uint8_t month, uint8_t year); + void setAlarmSeconds(uint8_t seconds); + void setAlarmMinutes(uint8_t minutes); + void setAlarmHours(uint8_t hours); + void setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds); + + void setAlarmDay(uint8_t day); + void setAlarmMonth(uint8_t month); + void setAlarmYear(uint8_t year); + void setAlarmDate(uint8_t day, uint8_t month, uint8_t year); + private: void config32kOSC(void); bool RTCisSyncing(void); From 656c8a2ab192aad28ff131d2a1574267e858b4af Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 10:46:33 +0100 Subject: [PATCH 5/7] Added the ability to set the match/compare mask Now by default the interrupt is enabled but the mask is set to no compare. --- src/RTCZero.cpp | 17 ++++++++++++++++- src/RTCZero.h | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 9131940..54c5011 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -64,7 +64,8 @@ void RTCZero::begin(bool timeRep) NVIC_EnableIRQ(RTC_IRQn); // enable RTC interrupt NVIC_SetPriority(RTC_IRQn, 0x00); - RTC->MODE2.INTENSET.reg &= ~RTC_MODE2_INTENSET_ALARM0; // disable alarm interrupt by default + RTC->MODE2.INTENSET.reg |= RTC_MODE2_INTENSET_ALARM0; // enable alarm interrupt + RTC->MODE2.Mode2Alarm[0].MASK.bit.SEL = MATCH_OFF; // default alarm match is off (disabled) while (RTCisSyncing()) ; @@ -78,6 +79,20 @@ void RTC_Handler(void) RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0; // must clear flag at end } +void RTCZero::enableAlarm(Alarm_Match match) +{ + RTC->MODE2.Mode2Alarm[0].MASK.bit.SEL = match; + while (RTCisSyncing()) + ; +} + +void RTCZero::disableAlarm() +{ + RTC->MODE2.Mode2Alarm[0].MASK.bit.SEL = 0x00; + while (RTCisSyncing()) + ; +} + /* * Get Functions */ diff --git a/src/RTCZero.h b/src/RTCZero.h index 5c7ddc0..3fbc7be 100644 --- a/src/RTCZero.h +++ b/src/RTCZero.h @@ -27,8 +27,22 @@ class RTCZero { public: + enum Alarm_Match: uint8_t + { + MATCH_OFF = 0x00, + MATCH_SS = 0x01, + MATCH_MMSS = 0x02, + MATCH_HHMMSS = 0x03, + MATCH_DHHMMSS = 0x04, + MATCH_MMDDHHMMSS = 0x05, + MATCH_YYMMDDHHMMSS = 0x06 + }; + RTCZero() {}; void begin(bool timeRep); + + void enableAlarm(Alarm_Match match); + void disableAlarm(); /* Get Functions */ From b8504c91d191eea4c91241c0553ce613c389c0a5 Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Mon, 14 Sep 2015 11:20:35 +0100 Subject: [PATCH 6/7] Added attachable ISR. This is not strictly required for a wake alarm as the IRQ routine will wake the board. --- src/RTCZero.cpp | 16 ++++++++++++++++ src/RTCZero.h | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 54c5011..8e7501e 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -21,6 +21,8 @@ static bool __time24 = false; +voidFuncPtr RTC_callBack = NULL; + void RTCZero::begin(bool timeRep) { uint16_t tmp_reg = 0; @@ -76,6 +78,10 @@ void RTCZero::begin(bool timeRep) void RTC_Handler(void) { + if (RTC_callBack != NULL) { + RTC_callBack(); + } + RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0; // must clear flag at end } @@ -93,6 +99,16 @@ void RTCZero::disableAlarm() ; } +void RTCZero::attachInterrupt(voidFuncPtr callback) +{ + RTC_callBack = callback; +} + +void RTCZero::detachInterrupt() +{ + RTC_callBack = NULL; +} + /* * Get Functions */ diff --git a/src/RTCZero.h b/src/RTCZero.h index 3fbc7be..530ff60 100644 --- a/src/RTCZero.h +++ b/src/RTCZero.h @@ -24,6 +24,8 @@ #include "Arduino.h" +typedef void(*voidFuncPtr)(void); + class RTCZero { public: @@ -43,6 +45,9 @@ class RTCZero { void enableAlarm(Alarm_Match match); void disableAlarm(); + + void attachInterrupt(voidFuncPtr callback); + void detachInterrupt(); /* Get Functions */ From 9590892eb5a251176c675c9ff5eb66b64efe88ce Mon Sep 17 00:00:00 2001 From: Gabriel Notman Date: Tue, 15 Sep 2015 18:34:10 +0100 Subject: [PATCH 7/7] Updated the Alarm_Match enum Now the identifiers from /component/rtc.h are used. --- src/RTCZero.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/RTCZero.h b/src/RTCZero.h index 530ff60..d42b42a 100644 --- a/src/RTCZero.h +++ b/src/RTCZero.h @@ -29,15 +29,15 @@ typedef void(*voidFuncPtr)(void); class RTCZero { public: - enum Alarm_Match: uint8_t + enum Alarm_Match: uint8_t // Should we have this enum or just use the identifiers from /component/rtc.h ? { - MATCH_OFF = 0x00, - MATCH_SS = 0x01, - MATCH_MMSS = 0x02, - MATCH_HHMMSS = 0x03, - MATCH_DHHMMSS = 0x04, - MATCH_MMDDHHMMSS = 0x05, - MATCH_YYMMDDHHMMSS = 0x06 + MATCH_OFF = RTC_MODE2_MASK_SEL_OFF_Val, + MATCH_SS = RTC_MODE2_MASK_SEL_SS_Val, + MATCH_MMSS = RTC_MODE2_MASK_SEL_MMSS_Val, + MATCH_HHMMSS = RTC_MODE2_MASK_SEL_HHMMSS_Val, + MATCH_DHHMMSS = RTC_MODE2_MASK_SEL_DDHHMMSS_Val, + MATCH_MMDDHHMMSS = RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val, + MATCH_YYMMDDHHMMSS = RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val }; RTCZero() {};