-
Notifications
You must be signed in to change notification settings - Fork 7
/
sleep_manager.cpp
155 lines (125 loc) · 4.69 KB
/
sleep_manager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "sleep_manager.h"
// NOTE: the recommended source of sleep code is from the Artemis OpenLog
// https://github.com/sparkfun/OpenLog_Artemis/blob/69682123ea2ae3ceb3983a7d8260eaef6259a0e2/Firmware/OpenLog_Artemis/lowerPower.ino
//--------------------------------------------------------------------------------
void sleep_for_seconds(long number_of_seconds, int nbr_blinks){
Serial.print(F("sleep for "));
Serial.print(number_of_seconds);
Serial.println(F(" seconds"));
prepare_to_sleep();
unsigned long int millis_lost {0};
unsigned long int last_millis {0};
for (long i=0; i<number_of_seconds; i++){
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
wdt.restart();
#if (PERFORM_SLEEP_BLINK == 1)
last_millis = millis();
if (i % interval_between_sleep_LED_blink_seconds == 0){
for (int j=0; j<nbr_blinks; j++){
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
delay(duration_sleep_LED_blink_milliseconds);
digitalWrite(LED, LOW);
delay(duration_sleep_LED_blink_milliseconds);
}
}
millis_lost += millis() - last_millis;
if (millis_lost > 1000UL){
i++;
millis_lost -= 1000UL;
}
#endif
}
wake_up();
}
void sleep_until_posix(time_t posix_timestamp){
Serial.print(F("sleep until posix "));
Serial.println((long)posix_timestamp);
prepare_to_sleep();
if (board_time_manager.posix_timestamp_is_valid()){
while (board_time_manager.get_posix_timestamp() < posix_timestamp){
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
wdt.restart();
}
}
else{
Serial.println(F("no valid posix timestamp, cannot sleep to posix; sleep for default 1 hour"));
for (long i=0; i<3600; i++){
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
wdt.restart();
}
}
wake_up();
}
//--------------------------------------------------------------------------------
void prepare_to_sleep(void){
turn_gnss_off();
turn_iridium_off();
digitalWrite(busVoltageMonEN, LOW);
digitalWrite(LED, LOW);
turn_qwiic_switch_off();
turn_thermistors_off();
delay(50);
Serial.println(F("power down ArtemisWire"));
ArtemisWire.end();
wdt.restart();
delay(100);
Serial.println(F("power down board"));
Serial.println(F("------ SLEEP ------"));
delay(100);
Serial.flush();
Serial.end();
delay(50);
// Turn off ADC
power_adc_disable();
// Disabling the debugger GPIOs saves about 1.2 uA total:
am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_HAL_GPIO_DISABLE);
am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_HAL_GPIO_DISABLE);
// These two GPIOs are critical: the TX/RX connections between the Artemis module and the CH340S
// are prone to backfeeding each other. To stop this from happening, we must reconfigure those pins as GPIOs
// and then disable them completely:
am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_HAL_GPIO_DISABLE);
am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_HAL_GPIO_DISABLE);
//Power down Flash, SRAM, cache
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Power down all flash and cache
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM
//Keep the 32kHz clock running for RTC
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
}
void wake_up(void){
//Power up SRAM, turn on entire Flash
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
//Go back to using the main clock
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
// Restore the TX/RX connections between the Artemis module and the CH340S on the Blackboard
am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_BSP_GPIO_COM_UART_TX);
am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_BSP_GPIO_COM_UART_RX);
// Reenable the debugger GPIOs
am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_BSP_GPIO_SWDCK);
am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_BSP_GPIO_SWDIO);
//Turn on ADC
ap3_adc_setup();
ap3_set_pin_to_analog(busVoltagePin);
Serial.begin(baudrate_debug_serial);
delay(100);
Serial.println();
Serial.println(F("------ WAKE UP ------"));
Serial.println(F("powered up board"));
ArtemisWire.begin();
delay(100);
ArtemisWire.setClock(1000000);
delay(100);
wdt.restart();
Serial.println(F("started ArtemisWire"));
Serial.println(F("start qwiic switch"));
if (qwiic_switch.begin(ArtemisWire) == false){
Serial.println(F("Qwiic Power Switch not detected at default I2C address. Please check wiring. Freezing."));
while (true){;}
}
turn_qwiic_switch_off();
setup_pins();
turn_gnss_off();
turn_iridium_off();
}