Open janvrska opened 1 year ago
Hi @janvrska, using rtc.begin(true) to reset the RTC after modem.begin(EU868) helped for me.
Did you try to add a small delay after the modem begin? Did you try this example: https://github.com/stm32duino/STM32LoRaWAN/blob/main/examples/LowPowerBasic/LowPowerBasic.ino Is it working?
Hi @fpistm, I tried the example on the RAK3172T and unfortunately it is not working. The example send the data package every 6 seconds. Using rtc.begin(true) to reset the RTC after modem.begin(EU868) helped here as well.
Using rtc.begin(true) to reset the RTC after modem.begin(EU868) helped here as well.
Seems strange as the modem.begin()
call the rtc.begin(true)
.
https://github.com/stm32duino/STM32LoRaWAN/blob/192c1234a8661f72f1635e5675db0d11fb110920/src/STM32LoRaWAN.cpp#L73C1-L75
My guess is something is pending which wake up the mcu. Calling deepSleep()
simply enter in STOP mode 2 but several source (event) can wake it (LPUART, PWR_WKUP pin, RTC...). So before entering in deepSleep you have to ensure you can.
@janvrska Some notes, we do not support PIO only Arduino IDE. We saw several times misalignment on PIO setup and so would not invest time on wrong configurations.
Your code is not correct:
void loop() {
//Serial.begin(115200); --> Avoid to init each loop the instance
Serial.println("wakes up");
//delay(1000); --> Simply do a flush to prevent Serial IT to wakeup the board.
Serial.flush();
LowPower.deepSleep();
}
and tried in my main code to: rtc.detachInterrupt, rtc.detachSecondsInterrupt, rtc.disableAlarm (both A ,B), but none of it worked.
Only when I after modem.begin() called rtc.end() and then rtc.begin() it stops waking up, but after joining the network (which was successfull), modem.send() didn't send any message (propably some problem with RTC settings that should have been set in modem.begin() and was cleared after rtc.end())
That is normal you can't send anything, if you remove the callback required for the modem timing or by reseting yourself the RTC as is do not set those callback.
I tried within my LoRa-E5 mini and the low power is functional. Please try he example then give us your feedback (preferably with Arduino).
@HelgeSeidel I don't understand your point:
I tried the example on the RAK3172T and unfortunately it is not working. The example send the data package every 6 seconds. Using rtc.begin(true) to reset the RTC after modem.begin(EU868) helped here as well.
This mean that if you call rtc.begin(true)
after modem.begin()
, it works? If true as stated before, seems very strange as we already reset the RTC in the begin
. Or one explanation, could be you have a battery, in that case RTC always running and alarm configured. So maybe an alarm IT still pending in this timeframe but I doubt on this as with begin(true)
the backup domain is reset.
This board/module is not supported, you even enter yourself this #34 so not very relevant here as maybe other issue related to this.
@fpistm Same behaviour on the RAK3172 Evaluation Board which is supported. Running the example as is will send the packet every 6 seconds. Calling rtc.begin(true) after modem.begin() and the example worked as expected.
No battery connected to the board / RTC.
Thank you for quick response. I tried LowPowerBasic example in ArduinoIDE and have same result as @HelgeSeidel
After adding rtc.begin(true) after modem.begin, example works as expected
@FRASTM do you have any idea on this subject?
Just to confirm that I also have the same issue on RAK3172 module (waking up after ~1s). Adding rtc.begin(true) solved issue.
Whoever came to this (temporary) solution - thank you a lot for saving lot of nerves! @HelgeSeidel
In case of rtc reset, rtc.begin(true)
, the RCC BDCR register bits RTCEN and RTCSEL are 0.
__HAL_RCC_RTC_ENABLE() will set the RTCEN bit but RTCSEL should also be set with else no source is selected to clock the RTC. The RTC peripheral is not supposed to be accessed before RTC clock is selected.
Resetting the Backup domain earlier in the RTC_init will also give more clock cycles to access the RCC BDCR register
Can you please try with this:
diff --git a/src/rtc.c b/src/rtc.c
index 73c911f..23cb143 100644
--- a/src/rtc.c
+++ b/src/rtc.c
@@ -411,6 +411,20 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool
bool isAlarmBSet = false;
#endif
+ /* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */
+ enableBackupDomain();
+
+ if (reset) {
+ resetBackupDomain();
+ /* After Backup domain reset, RTC is disabled and no RTC clock selected */
+ }
+
+#ifdef __HAL_RCC_RTCAPB_CLK_ENABLE
+ __HAL_RCC_RTCAPB_CLK_ENABLE();
+#endif
+ __HAL_RCC_RTC_ENABLE();
+ /* Also need to select the RTC clock source asap with RTC_initClock */
+
initFormat = format;
initMode = mode;
/* Ensure all RtcHandle properly set */
@@ -431,22 +445,6 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool
#endif /* RTC_OUTPUT_REMAP_NONE */
#endif /* STM32F1xx */
- /* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */
- enableBackupDomain();
-
- if (reset) {
- resetBackupDomain();
- }
-
-#ifdef __HAL_RCC_RTCAPB_CLK_ENABLE
- __HAL_RCC_RTCAPB_CLK_ENABLE();
-#endif
- __HAL_RCC_RTC_ENABLE();
-
- isAlarmASet = RTC_IsAlarmSet(ALARM_A);
-#ifdef RTC_ALARM_B
- isAlarmBSet = RTC_IsAlarmSet(ALARM_B);
-#endif
#if defined(STM32F1xx)
uint32_t BackupDate;
BackupDate = getBackupRegister(RTC_BKP_DATE) << 16;
@@ -510,6 +508,12 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool
#else
RTC_setPrediv(predivAsync, predivSync);
#endif
+
+ isAlarmASet = RTC_IsAlarmSet(ALARM_A);
+#ifdef RTC_ALARM_B
+ isAlarmBSet = RTC_IsAlarmSet(ALARM_B);
+#endif
+
if (isAlarmASet) {
RTC_GetAlarm(ALARM_A, &alarmDay, &alarmHours, &alarmMinutes, &alarmSeconds, &alarmSubseconds, &alarmPeriod, &alarmMask);
}
In case of rtc reset,
rtc.begin(true)
, the RCC BDCR register bits RTCEN and RTCSEL are 0. __HAL_RCC_RTC_ENABLE() will set the RTCEN bit but RTCSEL should also be set with else no source is selected to clock the RTC. The RTC peripheral is not supposed to be accessed before RTC clock is selected. Resetting the Backup domain earlier in the RTC_init will also give more clock cycles to access the RCC BDCR registerCan you please try with this: ...
I've tried suggested change, but behaviour is the same.
I also saw that setting up LoRaWAN (modem.begin) will reset time and date which are set up prior to that call
If the rtc has already been initialized, we could skip the rtc init sequence requested by the Lorawan (calling a _rtc.begin(false,STM32RTC::HOUR_24);
instead ) and only set the binary mode to MIX mode (if differs).
The Lorawan setting the binary mode will only update the RTC binary mode bits, without changing calendar registers.
This is possible when the first rtc initialisation has configured the same LSE clock as the lorawan requires the LSE
Change the STM32RTC : RTC_init function to force the update of the RTC ICS BIN and BDCU register in case of RTC is already initiliazed. See https://github.com/stm32duino/STM32RTC/pull/106
I had the same issue and as reported, calling rtc.begin(true) after modem.begin() made it work. Thanks a lot for reporting it in this issues, I was already on the verge of questioning my sanity :).
One difference seen inside the modem.begin() is that after the _rtc.begin(), there are two attachInterrupt :
_rtc.attachInterrupt(UTIL_TIMER_IRQ_MAP_PROCESS, STM32RTC::ALARM_B);
_rtc.attachSecondsInterrupt(TIMER_IF_SSRUCallback);
Especially the attachSecondsInterrupt which also set the RTC WakeUpTimer interrupt.
When rtc.begin() is called (independently) after the modem.init, the rtc.begin(true) is resetting the RTC registers, including wakeup Interrupt Enable bit, etc. The wakeUp Interrupt is no more enabled
Could that explain the issue
Does the issue change if the STM32LoRaWAN::begin
has not
rtc.attachSecondsInterrupt(TIMER_IF_SSRUCallback); ?
This indeed explains the issue, why the STM wakes up every second. Removing the attachSecondsInterrupt line solves this issue, as then the deepSleep works as expected. I tested this on a RAK3172.
I also looked into why rtc.detachSecondsInterrupt after the modem.begin() does not work. In the RTC library, the detach seems to only detach the callback, but lets the one-second-wakeup in place.
Expected Behavior
After setting
modem.begin(EU868)
andLowPower.deepSleep()
it goes sleep, and the chip will not wake up.Current Behavior
After setting
modem.begin(EU868)
andLowPower.deepSleep()
it goes sleep, but after around 900ms it wakes up.If
modem.begin(EU868)
isn't used then it works as intended, and the chip will not wake up.Minimal example
Power Profiler screenshot with modem.begin()
Power Profiler screenshot without modem.begin()
Details (what I tried)
I tried to look on https://github.com/stm32duino/STM32LoRaWAN/blob/192c1234a8661f72f1635e5675db0d11fb110920/src/STM32LoRaWAN.cpp#L62-L81 and tried in my main code to:
rtc.detachInterrupt, rtc.detachSecondsInterrupt, rtc.disableAlarm (both A ,B), but none of it worked.
Only when I after modem.begin() called rtc.end() and then rtc.begin() it stops waking up, but after joining the network (which was successfull), modem.send() didn't send any message (propably some problem with RTC settings that should have been set in modem.begin() and was cleared after rtc.end())
Context
I'm using supported LORA-E5 chip (STM32WLE5JC) on custom PCB
platformio.ini: