@@ -302,7 +302,9 @@ static void enablePIT(void) {
302302 temp = CLKCTRL.XOSC32KCTRLA ;
303303 temp &= ~CLKCTRL_ENABLE_bm;
304304 _PROTECTED_WRITE (CLKCTRL.XOSC32KCTRLA , temp);
305- while (CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm) {}
305+ while (CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm) {
306+ __asm__ __volatile__ (" nop\n\t " );
307+ }
306308
307309 // We want the external crystal to run in standby and in low power mode
308310 temp = CLKCTRL.XOSC32KCTRLA ;
@@ -317,7 +319,7 @@ static void enablePIT(void) {
317319 _PROTECTED_WRITE (CLKCTRL.XOSC32KCTRLA , temp);
318320
319321 // Wait for registers to synchronize
320- while (RTC.PITSTATUS ) { delay ( 1 ); }
322+ while (RTC.PITSTATUS ) { __asm__ __volatile__ ( " nop \n\t " ); }
321323
322324 RTC.CLKSEL |= RTC_CLKSEL_XOSC32K_gc;
323325 RTC.PITINTCTRL |= RTC_PI_bm;
@@ -326,7 +328,7 @@ static void enablePIT(void) {
326328 // The first PIT intterupt will not necessarily be at the period specified,
327329 // so we just wait until it has triggered and track the reminaing time from
328330 // there
329- while (!pit_triggered) { delay ( 1 ); }
331+ while (!pit_triggered) { __asm__ __volatile__ ( " nop \n\t " ); }
330332 pit_triggered = false ;
331333}
332334
@@ -442,9 +444,6 @@ static void powerDownPeripherals(const bool keep_modem_active) {
442444
443445 savePinState ();
444446
445- // Disable millis() timer
446- stop_millis ();
447-
448447 // For low power, the following configuration should be used.
449448 // If no comment is specified, the pin is set to input with input buffer
450449 // disabled and pull-up on
@@ -604,8 +603,6 @@ static void powerUpPeripherals() {
604603
605604 restorePinState ();
606605
607- restart_millis ();
608-
609606 // ADC for analogRead
610607 init_ADC0 ();
611608}
@@ -723,11 +720,8 @@ void LowPowerClass::powerSave(void) {
723720
724721 retrieved_period = true ;
725722 }
726-
727- // Retrieving the operator sleep time will call CEREG, which will
728- // trigger led ctrl, so we just disable it again.
729- // LedCtrl.off(Led::CELL, true);
730723 }
724+
731725 if (!attemptToEnterPowerSaveModeForModem (30000 )) {
732726 Log.error (
733727 " Failed to put cellular modem in sleep. Power save functionality "
@@ -739,8 +733,15 @@ void LowPowerClass::powerSave(void) {
739733 SLPCTRL.CTRLA |= SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm;
740734
741735 enableLDO ();
736+
737+ // It's important that we stop the millis after enabling the LDO, as it
738+ // uses delay() to wait for the LDO mode to settle
739+ stop_millis ();
740+
742741 sleep_cpu ();
743742
743+ restart_millis ();
744+
744745 // Will sleep here until we get the RING line activity and wake up
745746 disableLDO ();
746747
@@ -750,8 +751,6 @@ void LowPowerClass::powerSave(void) {
750751 modem_is_in_power_save = false ;
751752 }
752753
753- // LedCtrl.on(Led::CELL, true);
754-
755754 SequansController.setPowerSaveMode (0 , NULL );
756755}
757756
@@ -761,12 +760,15 @@ void LowPowerClass::powerDown(const uint32_t power_down_time_seconds) {
761760
762761 Lte.end ();
763762
764- // TODO: somehow this prevents the modem to sleep...
765763 powerDownPeripherals (false );
766764
767765 enablePIT ();
768766 enableLDO ();
769767
768+ // It's important that we stop the millis after enabling the LDO, as it uses
769+ // delay() to wait for the LDO mode to settle
770+ stop_millis ();
771+
770772 uint32_t remaining_time_seconds = power_down_time_seconds;
771773
772774 while (remaining_time_seconds > 0 ) {
@@ -782,6 +784,8 @@ void LowPowerClass::powerDown(const uint32_t power_down_time_seconds) {
782784 }
783785 }
784786
787+ restart_millis ();
788+
785789 disableLDO ();
786790 disablePIT ();
787791 SLPCTRL.CTRLA &= ~SLPCTRL_SEN_bm;
0 commit comments