1+ #include " led_ctrl.h"
12#include " log.h"
23#include " low_power.h"
34#include " lte.h"
5051#define TIMER_LENGTH 11
5152#define TIMER_SLEEP_INDEX 8
5253
53- #define RING_PORT VPORTC
54+ #define RING_PORT VPORTC
55+
56+ #ifdef __AVR_AVR128DB48__ // MINI
57+
58+ #define RING_PIN_bm PIN6_bm
59+
60+ #else
61+
62+ #ifdef __AVR_AVR128DB64__ // Non-Mini
63+
5464#define RING_PIN_bm PIN4_bm
5565
66+ #else
67+ #error "INCOMPATIBLE_DEVICE_SELECTED"
68+ #endif
69+ #endif
70+
5671// Singleton. Defined for use of the rest of the library.
5772LowPowerClass LowPower = LowPowerClass::instance();
5873
@@ -64,6 +79,9 @@ static SleepMode sleep_mode;
6479static bool retrieved_sleep_time = false ;
6580static uint32_t sleep_time = 0 ;
6681
82+ static uint8_t cell_led_state = 0 ;
83+ static uint8_t con_led_state = 0 ;
84+
6785ISR (RTC_PIT_vect) {
6886 RTC.PITINTFLAGS = RTC_PI_bm;
6987 pit_triggered = true ;
@@ -93,7 +111,7 @@ static void uint8ToStringOfBits(const uint8_t value, char *string) {
93111
94112static uint8_t stringOfBitsToUint8 (const char *string) {
95113
96- uint8_t value;
114+ uint8_t value = 0 ;
97115
98116 for (uint8_t i = 0 ; i < 8 ; i++) {
99117 // We assume all other values are zero, so we only shift the ones
@@ -257,9 +275,6 @@ static void enablePIT(void) {
257275 RTC.PITINTCTRL |= RTC_PI_bm;
258276 RTC.PITCTRLA |= RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
259277
260- // Now we setup the sleep mode so it is ready.
261- SLPCTRL.CTRLA |= SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm;
262-
263278 // The first PIT intterupt will not necessarily be at the period specified,
264279 // so we just wait until it has triggered and track the reminaing time from
265280 // there
@@ -269,13 +284,33 @@ static void enablePIT(void) {
269284
270285static void disablePIT (void ) {
271286
272- SLPCTRL.CTRLA &= ~SLPCTRL_SEN_bm;
273-
274287 // Disable external clock and turn off RTC PIT
275288 CLKCTRL.XOSC32KCTRLA &= (~CLKCTRL_ENABLE_bm);
276289 RTC.PITCTRLA &= ~RTC_PITEN_bm;
277290}
278291
292+ static void powerDownPeripherals (void ) {
293+
294+ cell_led_state = digitalRead (LedCtrl.getLedPin (Led::CELL));
295+ con_led_state = digitalRead (LedCtrl.getLedPin (Led::CON));
296+
297+ LedCtrl.off (Led::CELL, true );
298+ LedCtrl.off (Led::CON, true );
299+ LedCtrl.off (Led::DATA, true );
300+ LedCtrl.off (Led::ERROR, true );
301+ LedCtrl.off (Led::USER, true );
302+ }
303+
304+ static void powerUpPeripherals (void ) {
305+ if (cell_led_state) {
306+ LedCtrl.on (Led::CELL, true );
307+ }
308+
309+ if (con_led_state) {
310+ LedCtrl.on (Led::CON, true );
311+ }
312+ }
313+
279314/* *
280315 * Modem sleeping and CPU deep sleep.
281316 */
@@ -289,6 +324,7 @@ static WakeUpReason regularSleep(void) {
289324 sleep_time = retrieveOperatorSleepTime ();
290325
291326 if (sleep_time == 0 ) {
327+ Log.debugf (" Got invalid sleep time: %d\r\n " , sleep_time);
292328 return WakeUpReason::INVALID_SLEEP_TIME;
293329 } else {
294330 retrieved_sleep_time = true ;
@@ -297,7 +333,8 @@ static WakeUpReason regularSleep(void) {
297333
298334 // The timeout here is arbitrary as we attempt to put the modem in sleep in
299335 // a loop, so we just choose 30 seconds = 30000 ms
300- while (!attemptToEnterPowerSaveModeForModem (30000 )) {}
336+ while (!attemptToEnterPowerSaveModeForModem (30000 ) &&
337+ millis () - start_time_ms < sleep_time * 1000 ) {}
301338
302339 // If we surpassed the sleep time during setting the LTE to sleep, we
303340 // don't have any more time to sleep the CPU, so just return.
@@ -360,17 +397,13 @@ static WakeUpReason deepSleep(void) {
360397 const unsigned long start_time_ms = millis ();
361398
362399 Lte.end ();
363-
364400 enablePIT ();
365401
366402 uint32_t remaining_time_seconds =
367403 sleep_time - (uint32_t )(((millis () - start_time_ms) / 1000 .0f ));
368404
369405 while (remaining_time_seconds > 0 ) {
370406
371- Log.debugf (" Remaining time: %d \r\n " , remaining_time_seconds);
372- delay (10 );
373-
374407 sleep_cpu ();
375408
376409 if (pit_triggered) {
@@ -380,7 +413,6 @@ static WakeUpReason deepSleep(void) {
380413 }
381414
382415 disablePIT ();
383-
384416 Lte.begin ();
385417
386418 return WakeUpReason::OK;
@@ -453,12 +485,19 @@ bool LowPowerClass::begin(const SleepMultiplier sleep_multiplier,
453485}
454486
455487WakeUpReason LowPowerClass::sleep (void ) {
488+
489+ powerDownPeripherals ();
490+ SLPCTRL.CTRLA |= SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm;
491+
456492 switch (sleep_mode) {
457493 case SleepMode::REGULAR:
458494 return regularSleep ();
459495 case SleepMode::DEEP:
460496 return deepSleep ();
461497 }
462498
499+ SLPCTRL.CTRLA &= ~SLPCTRL_SEN_bm;
500+ powerUpPeripherals ();
501+
463502 return WakeUpReason::OK;
464503}
0 commit comments