44#include " log.h"
55#include " lte.h"
66#include " sequans_controller.h"
7+ #include " timeout_timer.h"
78
89#include < Arduino.h>
910#include < Wire.h>
1011#include < avr/io.h>
1112#include < avr/sleep.h>
13+ #include < util/delay.h>
1214
1315#define AT_COMMAND_DISABLE_EDRX " AT+SQNEDRX=0"
1416#define AT_COMMAND_ENABLE_PSM " AT+CPSMS=1,,,\" %s\" ,\" %s\" "
@@ -214,7 +216,7 @@ attemptToEnterPowerSaveModeForModem(const unsigned long waiting_time_ms) {
214216 SequansController.setPowerSaveMode (0 , NULL );
215217
216218 do {
217- delay (50 );
219+ _delay_ms (50 );
218220 SequansController.clearReceiveBuffer ();
219221 } while (SequansController.isRxReady ());
220222
@@ -223,11 +225,11 @@ attemptToEnterPowerSaveModeForModem(const unsigned long waiting_time_ms) {
223225 ring_line_activity = false ;
224226
225227 // Now we wait until the ring line to stabilize
228+ const TimeoutTimer timeout_timer (waiting_time_ms);
226229 unsigned long last_time_active = millis ();
227- const unsigned long start_time = millis ();
228230
229231 do {
230- delay (PSM_WAITING_TIME_DELTA_MS);
232+ _delay_ms (PSM_WAITING_TIME_DELTA_MS);
231233
232234 // Reset timer if there has been activity or the RING line is high
233235 if (ring_line_activity || RING_PORT.IN & RING_PIN_bm) {
@@ -239,7 +241,7 @@ attemptToEnterPowerSaveModeForModem(const unsigned long waiting_time_ms) {
239241 modem_is_in_power_save = true ;
240242 return true ;
241243 }
242- } while (millis () - start_time < waiting_time_ms );
244+ } while (!timeout_timer. hasTimedOut () );
243245
244246 return false ;
245247}
@@ -314,6 +316,7 @@ static void enablePIT(void) {
314316 temp = CLKCTRL.XOSC32KCTRLA ;
315317 temp &= ~CLKCTRL_ENABLE_bm;
316318 _PROTECTED_WRITE (CLKCTRL.XOSC32KCTRLA , temp);
319+
317320 while (CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm) {
318321 __asm__ __volatile__ (" nop\n\t " );
319322 }
@@ -330,16 +333,21 @@ static void enablePIT(void) {
330333 temp |= CLKCTRL_ENABLE_bm;
331334 _PROTECTED_WRITE (CLKCTRL.XOSC32KCTRLA , temp);
332335
336+ RTC.CLKSEL |= RTC_CLKSEL_XOSC32K_gc;
337+
333338 // Wait for registers to synchronize
334339 while (RTC.PITSTATUS ) { __asm__ __volatile__ (" nop\n\t " ); }
335340
336- RTC.CLKSEL |= RTC_CLKSEL_XOSC32K_gc;
337341 RTC.PITINTCTRL |= RTC_PI_bm;
338342 RTC.PITCTRLA |= RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
339343
344+ // Wait for registers to synchronize
345+ while (RTC.PITSTATUS ) { __asm__ __volatile__ (" nop\n\t " ); }
346+
340347 // The first PIT intterupt will not necessarily be at the period specified,
341348 // so we just wait until it has triggered and track the reminaing time from
342349 // there
350+
343351 while (!pit_triggered) { __asm__ __volatile__ (" nop\n\t " ); }
344352 pit_triggered = false ;
345353}
@@ -629,7 +637,7 @@ static void enableLDO(void) {
629637 digitalWrite (LOWQ_PIN, HIGH);
630638
631639 // Wait a little to let LDO mode settle
632- delay (100 );
640+ _delay_ms (100 );
633641}
634642
635643/* *
@@ -640,7 +648,7 @@ static void disableLDO(void) {
640648 digitalWrite (LOWQ_PIN, LOW);
641649
642650 // Wait a little to let PWM mode settle
643- delay (100 );
651+ _delay_ms (100 );
644652}
645653
646654/* *
@@ -785,8 +793,7 @@ void LowPowerClass::powerSave(void) {
785793
786794 enableLDO ();
787795
788- // It's important that we stop the millis after enabling the LDO, as it
789- // uses delay() to wait for the LDO mode to settle
796+ // Stop millis interrupt
790797 stop_millis ();
791798
792799 sleep_cpu ();
@@ -816,8 +823,7 @@ void LowPowerClass::powerDown(const uint32_t power_down_time_seconds) {
816823 enablePIT ();
817824 enableLDO ();
818825
819- // It's important that we stop the millis after enabling the LDO, as it uses
820- // delay() to wait for the LDO mode to settle
826+ // Stop millis interrupt to prevent the timer waking up the core
821827 stop_millis ();
822828
823829 uint32_t remaining_time_seconds = power_down_time_seconds;
0 commit comments