From 667743be39d02a8ca8de7a8cd2b2b83c7f1feb23 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 4 Jul 2023 18:16:33 +0200 Subject: [PATCH] new example to configure RTC alarm in MIX mode and wakeup the system --- .../mixRTCAlarmSleep/mixRTCAlarmSleep.ino | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 examples/mixRTCAlarmSleep/mixRTCAlarmSleep.ino diff --git a/examples/mixRTCAlarmSleep/mixRTCAlarmSleep.ino b/examples/mixRTCAlarmSleep/mixRTCAlarmSleep.ino new file mode 100644 index 0000000..62de96d --- /dev/null +++ b/examples/mixRTCAlarmSleep/mixRTCAlarmSleep.ino @@ -0,0 +1,123 @@ +/* + mixRTCAlarmSleep + + This sketch shows how to configure the RTC alarm in MIX mode and go to sleep + + Creation 12 Dec 2017 + by Wi6Labs + Modified 03 Jul 2020 + by Frederic Pillon for STMicroelectronics + Modified 03 Jul 2023 + by Francois Ramu for STMicroelectronics + + This example code is in the public domain. + + https://github.com/stm32duino/STM32RTC +*/ + +#include "STM32LowPower.h" +#include + +/* Get the rtc object */ +STM32RTC& rtc = STM32RTC::getInstance(); + +/* Change this value to set alarm match offset */ +/* Note that STM32F1xx does not manage subsecond only second */ +static uint32_t atime = 148; /* in MIX mode, this is 148 ticks * 3.9ms/tick = 578 ms */ + +// Declare it volatile since it's incremented inside an interrupt +volatile int alarmMatch_counter = 0; + +/* Change these values to set the current initial time */ +const byte seconds = 05; +const byte minutes = 14; +const byte hours = 16; + +/* Change these values to set the current initial date */ +const byte day = 25; +const byte month = 9; +const byte year = 15; + +uint32_t timeout; + +void setup() +{ + Serial.begin(115200); + + // Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK. + // By default the LSI is selected as source : choose LSE + rtc.setClockSource(STM32RTC::LSE_CLOCK); +#if defined(RTC_BINARY_NONE) + rtc.setBinaryMode(STM32RTC::MODE_MIX); + rtc.begin(true); /* reset the RTC else the binary mode is not changed */ +#else + rtc.begin(); +#endif /* RTC_BINARY_NONE */ + // Configure low power + LowPower.begin(); + + rtc.setTime(hours, minutes, seconds); + rtc.setDate(day, month, year); + + /* wait for a while */ + delay(200); + + pinMode(LED_BUILTIN, OUTPUT); + + LowPower.enableWakeupFrom(&rtc, alarmMatch, &atime); + rtc.disableAlarm(STM32RTC::ALARM_A); + /* program Alarm in mix mode + * Configure first alarm in 2 second : 2000ms is 512 ticks + * then it will be done in the rtc callback + */ + timeout = rtc.getSubSeconds() + 512; + + rtc.setAlarmSubSeconds(timeout, STM32RTC::ALARM_A); + rtc.enableAlarm(rtc.MATCH_SUBSEC, STM32RTC::ALARM_A); + + Serial.printf("set Alarm at = %d\r\n", timeout); + +} + +void loop() +{ + Serial.print("Alarm Match: "); + Serial.print(alarmMatch_counter); + Serial.println(" times."); + Serial.flush(); + digitalWrite(LED_BUILTIN, HIGH); + LowPower.deepSleep(); + digitalWrite(LED_BUILTIN, LOW); + LowPower.deepSleep(); +} + + +void alarmMatch(void *data) +{ + // This function will be called once on device wakeup + // You can do some little operations here (like changing variables which will be used in the loop) + // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context + uint32_t epoc; + uint32_t _millis = 1000; + + if (data != NULL) { + _millis = *(uint32_t*)data; + } + +#ifdef STM32F1xx + uint32_t epoc_ms; + uint32_t sec = 0; + + sec = _millis / 1000; + // Minimum is 1 second + if (sec == 0) { + sec = 1; + } + epoc = rtc.getEpoch(&epoc_ms); +#else + epoc = rtc.getSubSeconds() + _millis; //in ms +#endif + alarmMatch_counter++; + rtc.setAlarmSubSeconds(epoc, STM32RTC::ALARM_A); +} +