From c174ebb82a5927b5919942056751f868f1a8d7d6 Mon Sep 17 00:00:00 2001 From: Nicholas Slugocki Date: Fri, 29 Jul 2022 15:17:27 -0700 Subject: [PATCH 1/3] Add PCF8523 alarm functionality --- examples/pcf8523Alarm/pcf8523Alarm.ino | 83 ++++++++++++++++++++++++++ src/RTC_PCF8523.cpp | 76 ++++++++++++++++++++++- src/RTClib.h | 16 +++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 examples/pcf8523Alarm/pcf8523Alarm.ino diff --git a/examples/pcf8523Alarm/pcf8523Alarm.ino b/examples/pcf8523Alarm/pcf8523Alarm.ino new file mode 100644 index 00000000..210e1625 --- /dev/null +++ b/examples/pcf8523Alarm/pcf8523Alarm.ino @@ -0,0 +1,83 @@ +#include "RTClib.h" + +// Change this to reflect the interrupt pin you would like to use +#define INTERRUPT_PIN 3 + +RTC_PCF8523 rtc; + +bool alarm_triggered = false; + +void setAlarmExample(); +void alarmISR(); +void handleAlarmTriggered(); + +void setup() { + Serial.begin(57600); + + // Ensure RTC initializes + if (!rtc.begin()) { + Serial.println("Couldn't find RTC"); + Serial.flush(); + while (1) delay(10); + } + + doAlarmExample(); +} + +void loop() { + if (alarm_triggered) { + handleAlarmTriggered(); + } else { + Serial.println("Alarm not triggered. The time is " + rtc.now().timestamp()); + delay(1000); + } +} + +/* + * Sets alarm one minute later. + */ +void doAlarmExample() +{ + // Make alarm trigger one minute after current time, but not accounting for seconds + // as the PCF8523 alarm doesn't have an alarm seconds register. So for example if + // current_time is 12:00:50, and alarm_time is 12:01:50, it will trigger at + // the exact minute, e.g. 12:01:00, because the PCF8523 hardware does not allow + // for seconds to be set on the alarm and ignores them. + DateTime current_time = rtc.now(); + TimeSpan alarm_offset(0, 0, 1, 0); // One minute + DateTime alarm_time(current_time + alarm_offset); + + // Good to clear other timers and such. + rtc.deconfigureAllTimers(); + + rtc.enableAlarmTimer(alarm_time, PCF8523_AlarmDate); + + // Print the current time for demonstration purposes. + char current_time_buf[] = "YYYY, MMM, DD, DDD, hh:mm:ss AP"; + Serial.println(String("Current Time: ") + current_time.toString(current_time_buf)); + Serial.flush(); + + // Print when the alarm should trigger. + char alarm_time_buf[] = "YYYY, MMM, DD, DDD, hh:mm:00 AP"; + Serial.println(String("Alarm Time: ") + alarm_time.toString(alarm_time_buf)); + Serial.flush(); + + // Set the interrupt. + pinMode(INTERRUPT_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), alarmISR, LOW); +} + +void handleAlarmTriggered() +{ + alarm_triggered = false; + rtc.disableAlarmTimer(); + Serial.println("Alarm triggered.\n"); + doAlarmExample(); + +} + +void alarmISR() +{ + alarm_triggered = true; + detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN)); +} diff --git a/src/RTC_PCF8523.cpp b/src/RTC_PCF8523.cpp index 17debef7..e2c3a682 100644 --- a/src/RTC_PCF8523.cpp +++ b/src/RTC_PCF8523.cpp @@ -5,11 +5,18 @@ #define PCF8523_CONTROL_1 0x00 ///< Control and status register 1 #define PCF8523_CONTROL_2 0x01 ///< Control and status register 2 #define PCF8523_CONTROL_3 0x02 ///< Control and status register 3 +#define PCF8523_ALARM_REG 0x0A ///< Alarm register +#define PCF8523_ALARM_WEEKDAY_REG 0x0D ///< Alarm Weekday register #define PCF8523_TIMER_B_FRCTL 0x12 ///< Timer B source clock frequency control #define PCF8523_TIMER_B_VALUE 0x13 ///< Timer B value (number clock periods) #define PCF8523_OFFSET 0x0E ///< Offset register #define PCF8523_STATUSREG 0x03 ///< Status register +#define PCF8523_ALARM_MINUTE 0x01 +#define PCF8523_ALARM_HOUR 0x02 +#define PCF8523_ALARM_DATE 0x04 +#define PCF8523_ALARM_WEEKDAY 0x08 + /**************************************************************************/ /*! @brief Start I2C for the PCF8523 and test succesful connection @@ -64,7 +71,7 @@ void RTC_PCF8523::adjust(const DateTime &dt) { bin2bcd(dt.minute()), bin2bcd(dt.hour()), bin2bcd(dt.day()), - bin2bcd(0), // skip weekdays + bin2bcd(dt.dayOfTheWeek()), bin2bcd(dt.month()), bin2bcd(dt.year() - 2000U)}; i2c_dev->write(buffer, 8); @@ -168,6 +175,73 @@ void RTC_PCF8523::disableSecondTimer() { read_register(PCF8523_CONTROL_1) & ~(1 << 2)); } +/**************************************************************************/ +/*! + @brief Enables alarm timer with current date/time and alarm mode. + @details The alarm will trigger at the specified date and time. The + INT/SQW pin will be pulled low when the specified time is reached. The + CLKOUT square wave will be disabled during the operation of the timer as + they interrupt on the same pin. Alarm modes are offered in the + Pcf8523AlarmMode enum. + + If the alarm mode is set to PCF8523_AlarmWeekday, it will repeat on the + weekday of the original date/time setting. + @param dt Date/Time for the alarm. + @param alarmMode Sets the alarm mode from the Pcf8523AlarmMode enum. +*/ +/**************************************************************************/ +void RTC_PCF8523::enableAlarmTimer(const DateTime &dt, + const Pcf8523AlarmMode alarmMode) { + // Disable square wave generation on SQW/INT pin, otherwise interrupt + // will trigger. + writeSqwPinMode(PCF8523_OFF); + + write_register(PCF8523_CONTROL_2, ~(1 << 3) + & read_register(PCF8523_CONTROL_2)); // Clear alarm interrupt flag + + write_register(PCF8523_CONTROL_1, (1 << 1) + | read_register(PCF8523_CONTROL_1)); // Enable alarm interrupts + + // Converts number to BCD then sets enable bit (bit 7) to 0 or 1 + // based on the alarm mode. + uint8_t alarmMinute = (uint8_t)((bin2bcd(dt.minute()) | (1 << 7)) + & ~((alarmMode & PCF8523_ALARM_MINUTE) << 7)); + uint8_t alarmHour = (uint8_t)((bin2bcd(dt.hour()) | (1 << 7)) + & ~((alarmMode & PCF8523_ALARM_HOUR) << 6)); + uint8_t alarmDate = (uint8_t)((bin2bcd(dt.day()) | (1 << 7)) + & ~((alarmMode & PCF8523_ALARM_DATE) << 5)); + uint8_t alarmWeekday = (uint8_t)((bin2bcd(dt.dayOfTheWeek())) | (1 << 7)) + & ~((alarmMode & PCF8523_ALARM_WEEKDAY) << 4); + + uint8_t buffer[5] = { PCF8523_ALARM_REG, + alarmMinute, + alarmHour, + alarmDate, + alarmWeekday}; + + i2c_dev->write(buffer, 5); +} + +/**************************************************************************/ +/*! + @brief Disables alarm timer and resets alarm interrupt. + @details Turns off alarm timer in Control Register 2 and clears + interrupt flag. + + Note: enableAlarmTimer() disables CLKOUT square wave feature. CLKOUT + square wave remains disabled after using this function. Use + writeSqwPinMode() to reactivate if required. +*/ +/**************************************************************************/ +void RTC_PCF8523::disableAlarmTimer() { + write_register(PCF8523_CONTROL_2, ~(1 << 3) + & read_register(PCF8523_CONTROL_2)); // Clear alarm interrupt bit + write_register(PCF8523_CONTROL_1, ~(1 << 1) + & read_register(PCF8523_CONTROL_1)); // Disable alarm activation flag +} + + + /**************************************************************************/ /*! @brief Enable the Countdown Timer Interrupt on the PCF8523. diff --git a/src/RTClib.h b/src/RTClib.h index a018a8dd..c06695b8 100644 --- a/src/RTClib.h +++ b/src/RTClib.h @@ -115,6 +115,18 @@ enum Pcf8523OffsetMode { PCF8523_OneMinute = 0x80 /**< Offset made every minute */ }; +/** PCF8523 alarm modes */ +enum Pcf8523AlarmMode { + PCF8523_AlarmMinute = 0x1, /**< Alarm when minutes match */ + + PCF8523_AlarmHour = 0x3, /**< Alarm when hours and minutes match */ + + PCF8523_AlarmDate = 0x07, /**< Alarm when date (day of month), hours + and minutes match */ + PCF8523_AlarmWeekday = 0x0B, /**< Alarm when day (day of week), hours + and minutes match */ +}; + /** PCF8563 CLKOUT pin mode settings */ enum Pcf8563SqwPinMode { PCF8563_SquareWaveOFF = 0x00, /**< Off */ @@ -413,6 +425,10 @@ class RTC_PCF8523 : RTC_I2C { void writeSqwPinMode(Pcf8523SqwPinMode mode); void enableSecondTimer(void); void disableSecondTimer(void); + void enableAlarmTimer(const DateTime &dt, const Pcf8523AlarmMode alarmMode, + uint8_t alarmWeekday); + void enableAlarmTimer(const DateTime &dt, const Pcf8523AlarmMode alarmMode); + void disableAlarmTimer(); void enableCountdownTimer(PCF8523TimerClockFreq clkFreq, uint8_t numPeriods, uint8_t lowPulseWidth); void enableCountdownTimer(PCF8523TimerClockFreq clkFreq, uint8_t numPeriods); From 2d3f98aa338a932b059a154dc92d14f271882a49 Mon Sep 17 00:00:00 2001 From: Sloogs Date: Wed, 3 Aug 2022 14:16:23 -0700 Subject: [PATCH 2/3] Implement suggested changes from GitHub review --- examples/pcf8523Alarm/pcf8523Alarm.ino | 33 ++++++++++---------------- src/RTC_PCF8523.cpp | 6 ++--- src/RTClib.h | 10 ++++---- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/examples/pcf8523Alarm/pcf8523Alarm.ino b/examples/pcf8523Alarm/pcf8523Alarm.ino index 210e1625..bf171477 100644 --- a/examples/pcf8523Alarm/pcf8523Alarm.ino +++ b/examples/pcf8523Alarm/pcf8523Alarm.ino @@ -5,11 +5,7 @@ RTC_PCF8523 rtc; -bool alarm_triggered = false; - -void setAlarmExample(); -void alarmISR(); -void handleAlarmTriggered(); +volatile bool alarm_triggered = false; void setup() { Serial.begin(57600); @@ -26,7 +22,10 @@ void setup() { void loop() { if (alarm_triggered) { - handleAlarmTriggered(); + alarm_triggered = false; + rtc.disableAlarm(); + Serial.println("Alarm triggered.\n"); + doAlarmExample(); } else { Serial.println("Alarm not triggered. The time is " + rtc.now().timestamp()); delay(1000); @@ -50,15 +49,16 @@ void doAlarmExample() // Good to clear other timers and such. rtc.deconfigureAllTimers(); - rtc.enableAlarmTimer(alarm_time, PCF8523_AlarmDate); + rtc.enableAlarm(alarm_time, PCF8523_AlarmDate); - // Print the current time for demonstration purposes. - char current_time_buf[] = "YYYY, MMM, DD, DDD, hh:mm:ss AP"; - Serial.println(String("Current Time: ") + current_time.toString(current_time_buf)); + // Print the current time in ISO8601 format. + Serial.println(String("Current Time: ") + current_time.timestamp()); Serial.flush(); - // Print when the alarm should trigger. - char alarm_time_buf[] = "YYYY, MMM, DD, DDD, hh:mm:00 AP"; + // Print when the alarm should trigger. Using a custom ISO8601 format + // because as stated above, PCF8523 can only trigger on the :00th second + // so seconds don't matter. + char alarm_time_buf[] = "YYYY-MM-DDThh:mm:00"; Serial.println(String("Alarm Time: ") + alarm_time.toString(alarm_time_buf)); Serial.flush(); @@ -67,15 +67,6 @@ void doAlarmExample() attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), alarmISR, LOW); } -void handleAlarmTriggered() -{ - alarm_triggered = false; - rtc.disableAlarmTimer(); - Serial.println("Alarm triggered.\n"); - doAlarmExample(); - -} - void alarmISR() { alarm_triggered = true; diff --git a/src/RTC_PCF8523.cpp b/src/RTC_PCF8523.cpp index e2c3a682..4d5fafd7 100644 --- a/src/RTC_PCF8523.cpp +++ b/src/RTC_PCF8523.cpp @@ -190,8 +190,8 @@ void RTC_PCF8523::disableSecondTimer() { @param alarmMode Sets the alarm mode from the Pcf8523AlarmMode enum. */ /**************************************************************************/ -void RTC_PCF8523::enableAlarmTimer(const DateTime &dt, - const Pcf8523AlarmMode alarmMode) { +void RTC_PCF8523::enableAlarm(const DateTime &dt, + const Pcf8523AlarmMode alarmMode) { // Disable square wave generation on SQW/INT pin, otherwise interrupt // will trigger. writeSqwPinMode(PCF8523_OFF); @@ -233,7 +233,7 @@ void RTC_PCF8523::enableAlarmTimer(const DateTime &dt, writeSqwPinMode() to reactivate if required. */ /**************************************************************************/ -void RTC_PCF8523::disableAlarmTimer() { +void RTC_PCF8523::disableAlarm() { write_register(PCF8523_CONTROL_2, ~(1 << 3) & read_register(PCF8523_CONTROL_2)); // Clear alarm interrupt bit write_register(PCF8523_CONTROL_1, ~(1 << 1) diff --git a/src/RTClib.h b/src/RTClib.h index c06695b8..00f2b33b 100644 --- a/src/RTClib.h +++ b/src/RTClib.h @@ -117,9 +117,9 @@ enum Pcf8523OffsetMode { /** PCF8523 alarm modes */ enum Pcf8523AlarmMode { - PCF8523_AlarmMinute = 0x1, /**< Alarm when minutes match */ + PCF8523_AlarmMinute = 0x01, /**< Alarm when minutes match */ - PCF8523_AlarmHour = 0x3, /**< Alarm when hours and minutes match */ + PCF8523_AlarmHour = 0x03, /**< Alarm when hours and minutes match */ PCF8523_AlarmDate = 0x07, /**< Alarm when date (day of month), hours and minutes match */ @@ -425,10 +425,8 @@ class RTC_PCF8523 : RTC_I2C { void writeSqwPinMode(Pcf8523SqwPinMode mode); void enableSecondTimer(void); void disableSecondTimer(void); - void enableAlarmTimer(const DateTime &dt, const Pcf8523AlarmMode alarmMode, - uint8_t alarmWeekday); - void enableAlarmTimer(const DateTime &dt, const Pcf8523AlarmMode alarmMode); - void disableAlarmTimer(); + void enableAlarm(const DateTime &dt, const Pcf8523AlarmMode alarmMode); + void disableAlarm(); void enableCountdownTimer(PCF8523TimerClockFreq clkFreq, uint8_t numPeriods, uint8_t lowPulseWidth); void enableCountdownTimer(PCF8523TimerClockFreq clkFreq, uint8_t numPeriods); From 6242b21695903bc9690b39a7ee3dcee460039a59 Mon Sep 17 00:00:00 2001 From: Sloogs Date: Wed, 3 Aug 2022 18:44:02 -0700 Subject: [PATCH 3/3] Ran clang-format --- examples/pcf8523Alarm/pcf8523Alarm.ino | 87 +++++++++++++------------- src/RTC_PCF8523.cpp | 62 +++++++++--------- src/RTClib.h | 12 ++-- 3 files changed, 79 insertions(+), 82 deletions(-) diff --git a/examples/pcf8523Alarm/pcf8523Alarm.ino b/examples/pcf8523Alarm/pcf8523Alarm.ino index bf171477..962049fc 100644 --- a/examples/pcf8523Alarm/pcf8523Alarm.ino +++ b/examples/pcf8523Alarm/pcf8523Alarm.ino @@ -8,67 +8,66 @@ RTC_PCF8523 rtc; volatile bool alarm_triggered = false; void setup() { - Serial.begin(57600); + Serial.begin(57600); - // Ensure RTC initializes - if (!rtc.begin()) { - Serial.println("Couldn't find RTC"); - Serial.flush(); - while (1) delay(10); - } + // Ensure RTC initializes + if (!rtc.begin()) { + Serial.println("Couldn't find RTC"); + Serial.flush(); + while (1) + delay(10); + } - doAlarmExample(); + doAlarmExample(); } void loop() { - if (alarm_triggered) { - alarm_triggered = false; - rtc.disableAlarm(); - Serial.println("Alarm triggered.\n"); - doAlarmExample(); - } else { - Serial.println("Alarm not triggered. The time is " + rtc.now().timestamp()); - delay(1000); - } + if (alarm_triggered) { + alarm_triggered = false; + rtc.disableAlarm(); + Serial.println("Alarm triggered.\n"); + doAlarmExample(); + } else { + Serial.println("Alarm not triggered. The time is " + rtc.now().timestamp()); + delay(1000); + } } /* * Sets alarm one minute later. */ -void doAlarmExample() -{ - // Make alarm trigger one minute after current time, but not accounting for seconds - // as the PCF8523 alarm doesn't have an alarm seconds register. So for example if - // current_time is 12:00:50, and alarm_time is 12:01:50, it will trigger at - // the exact minute, e.g. 12:01:00, because the PCF8523 hardware does not allow - // for seconds to be set on the alarm and ignores them. - DateTime current_time = rtc.now(); - TimeSpan alarm_offset(0, 0, 1, 0); // One minute - DateTime alarm_time(current_time + alarm_offset); +void doAlarmExample() { + // Make alarm trigger one minute after current time, but not accounting for + // seconds as the PCF8523 alarm doesn't have an alarm seconds register. So for + // example if current_time is 12:00:50, and alarm_time is 12:01:50, it will + // trigger at the exact minute, e.g. 12:01:00, because the PCF8523 hardware + // does not allow for seconds to be set on the alarm and ignores them. + DateTime current_time = rtc.now(); + TimeSpan alarm_offset(0, 0, 1, 0); // One minute + DateTime alarm_time(current_time + alarm_offset); - // Good to clear other timers and such. - rtc.deconfigureAllTimers(); + // Good to clear other timers and such. + rtc.deconfigureAllTimers(); - rtc.enableAlarm(alarm_time, PCF8523_AlarmDate); + rtc.enableAlarm(alarm_time, PCF8523_AlarmDate); - // Print the current time in ISO8601 format. - Serial.println(String("Current Time: ") + current_time.timestamp()); - Serial.flush(); + // Print the current time in ISO8601 format. + Serial.println(String("Current Time: ") + current_time.timestamp()); + Serial.flush(); - // Print when the alarm should trigger. Using a custom ISO8601 format - // because as stated above, PCF8523 can only trigger on the :00th second - // so seconds don't matter. - char alarm_time_buf[] = "YYYY-MM-DDThh:mm:00"; - Serial.println(String("Alarm Time: ") + alarm_time.toString(alarm_time_buf)); - Serial.flush(); + // Print when the alarm should trigger. Using a custom ISO8601 format + // because as stated above, PCF8523 can only trigger on the :00th second + // so seconds don't matter. + char alarm_time_buf[] = "YYYY-MM-DDThh:mm:00"; + Serial.println(String("Alarm Time: ") + alarm_time.toString(alarm_time_buf)); + Serial.flush(); - // Set the interrupt. - pinMode(INTERRUPT_PIN, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), alarmISR, LOW); + // Set the interrupt. + pinMode(INTERRUPT_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), alarmISR, LOW); } -void alarmISR() -{ +void alarmISR() { alarm_triggered = true; detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN)); } diff --git a/src/RTC_PCF8523.cpp b/src/RTC_PCF8523.cpp index 4d5fafd7..39f057ef 100644 --- a/src/RTC_PCF8523.cpp +++ b/src/RTC_PCF8523.cpp @@ -1,12 +1,12 @@ #include "RTClib.h" -#define PCF8523_ADDRESS 0x68 ///< I2C address for PCF8523 -#define PCF8523_CLKOUTCONTROL 0x0F ///< Timer and CLKOUT control register -#define PCF8523_CONTROL_1 0x00 ///< Control and status register 1 -#define PCF8523_CONTROL_2 0x01 ///< Control and status register 2 -#define PCF8523_CONTROL_3 0x02 ///< Control and status register 3 +#define PCF8523_ADDRESS 0x68 ///< I2C address for PCF8523 +#define PCF8523_CLKOUTCONTROL 0x0F ///< Timer and CLKOUT control register +#define PCF8523_CONTROL_1 0x00 ///< Control and status register 1 +#define PCF8523_CONTROL_2 0x01 ///< Control and status register 2 +#define PCF8523_CONTROL_3 0x02 ///< Control and status register 3 #define PCF8523_ALARM_REG 0x0A ///< Alarm register -#define PCF8523_ALARM_WEEKDAY_REG 0x0D ///< Alarm Weekday register +#define PCF8523_ALARM_WEEKDAY_REG 0x0D ///< Alarm Weekday register #define PCF8523_TIMER_B_FRCTL 0x12 ///< Timer B source clock frequency control #define PCF8523_TIMER_B_VALUE 0x13 ///< Timer B value (number clock periods) #define PCF8523_OFFSET 0x0E ///< Offset register @@ -181,7 +181,7 @@ void RTC_PCF8523::disableSecondTimer() { @details The alarm will trigger at the specified date and time. The INT/SQW pin will be pulled low when the specified time is reached. The CLKOUT square wave will be disabled during the operation of the timer as - they interrupt on the same pin. Alarm modes are offered in the + they interrupt on the same pin. Alarm modes are offered in the Pcf8523AlarmMode enum. If the alarm mode is set to PCF8523_AlarmWeekday, it will repeat on the @@ -195,29 +195,27 @@ void RTC_PCF8523::enableAlarm(const DateTime &dt, // Disable square wave generation on SQW/INT pin, otherwise interrupt // will trigger. writeSqwPinMode(PCF8523_OFF); + // Clear alarm interrupt flag + write_register(PCF8523_CONTROL_2, + ~(1 << 3) & read_register(PCF8523_CONTROL_2)); - write_register(PCF8523_CONTROL_2, ~(1 << 3) - & read_register(PCF8523_CONTROL_2)); // Clear alarm interrupt flag - - write_register(PCF8523_CONTROL_1, (1 << 1) - | read_register(PCF8523_CONTROL_1)); // Enable alarm interrupts + // Enable alarm interrupts + write_register(PCF8523_CONTROL_1, + (1 << 1) | read_register(PCF8523_CONTROL_1)); // Converts number to BCD then sets enable bit (bit 7) to 0 or 1 // based on the alarm mode. - uint8_t alarmMinute = (uint8_t)((bin2bcd(dt.minute()) | (1 << 7)) - & ~((alarmMode & PCF8523_ALARM_MINUTE) << 7)); - uint8_t alarmHour = (uint8_t)((bin2bcd(dt.hour()) | (1 << 7)) - & ~((alarmMode & PCF8523_ALARM_HOUR) << 6)); - uint8_t alarmDate = (uint8_t)((bin2bcd(dt.day()) | (1 << 7)) - & ~((alarmMode & PCF8523_ALARM_DATE) << 5)); - uint8_t alarmWeekday = (uint8_t)((bin2bcd(dt.dayOfTheWeek())) | (1 << 7)) - & ~((alarmMode & PCF8523_ALARM_WEEKDAY) << 4); - - uint8_t buffer[5] = { PCF8523_ALARM_REG, - alarmMinute, - alarmHour, - alarmDate, - alarmWeekday}; + uint8_t alarmMinute = (uint8_t)((bin2bcd(dt.minute()) | (1 << 7)) & + ~((alarmMode & PCF8523_ALARM_MINUTE) << 7)); + uint8_t alarmHour = (uint8_t)((bin2bcd(dt.hour()) | (1 << 7)) & + ~((alarmMode & PCF8523_ALARM_HOUR) << 6)); + uint8_t alarmDate = (uint8_t)((bin2bcd(dt.day()) | (1 << 7)) & + ~((alarmMode & PCF8523_ALARM_DATE) << 5)); + uint8_t alarmWeekday = (uint8_t)((bin2bcd(dt.dayOfTheWeek())) | (1 << 7)) & + ~((alarmMode & PCF8523_ALARM_WEEKDAY) << 4); + + uint8_t buffer[5] = {PCF8523_ALARM_REG, alarmMinute, alarmHour, alarmDate, + alarmWeekday}; i2c_dev->write(buffer, 5); } @@ -234,14 +232,14 @@ void RTC_PCF8523::enableAlarm(const DateTime &dt, */ /**************************************************************************/ void RTC_PCF8523::disableAlarm() { - write_register(PCF8523_CONTROL_2, ~(1 << 3) - & read_register(PCF8523_CONTROL_2)); // Clear alarm interrupt bit - write_register(PCF8523_CONTROL_1, ~(1 << 1) - & read_register(PCF8523_CONTROL_1)); // Disable alarm activation flag + // Clear alarm interrupt bit + write_register(PCF8523_CONTROL_2, + ~(1 << 3) & read_register(PCF8523_CONTROL_2)); + // Disable alarm activation flag + write_register(PCF8523_CONTROL_1, + ~(1 << 1) & read_register(PCF8523_CONTROL_1)); } - - /**************************************************************************/ /*! @brief Enable the Countdown Timer Interrupt on the PCF8523. diff --git a/src/RTClib.h b/src/RTClib.h index 00f2b33b..7d62918c 100644 --- a/src/RTClib.h +++ b/src/RTClib.h @@ -117,14 +117,14 @@ enum Pcf8523OffsetMode { /** PCF8523 alarm modes */ enum Pcf8523AlarmMode { - PCF8523_AlarmMinute = 0x01, /**< Alarm when minutes match */ + PCF8523_AlarmMinute = 0x01, /**< Alarm when minutes match */ - PCF8523_AlarmHour = 0x03, /**< Alarm when hours and minutes match */ + PCF8523_AlarmHour = 0x03, /**< Alarm when hours and minutes match */ - PCF8523_AlarmDate = 0x07, /**< Alarm when date (day of month), hours - and minutes match */ - PCF8523_AlarmWeekday = 0x0B, /**< Alarm when day (day of week), hours - and minutes match */ + PCF8523_AlarmDate = 0x07, /**< Alarm when date (day of month), hours + and minutes match */ + PCF8523_AlarmWeekday = 0x0B, /**< Alarm when day (day of week), hours + and minutes match */ }; /** PCF8563 CLKOUT pin mode settings */