-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy path03_power.ino
147 lines (126 loc) · 3.95 KB
/
03_power.ino
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
void readBattery()
{
// Start loop timer
unsigned long loopStartTime = millis();
// Stop the loop timer
timer.battery = millis() - loopStartTime;
}
// Enter deep sleep
void goToSleep()
{
#if DEBUG
Serial.end(); // Close Serial port
#endif
Wire.end(); // Disable I2C
SPI.end(); // Disable SPI
power_adc_disable(); // Disable ADC
digitalWrite(LED_BUILTIN, LOW); // Turn off LED
// Force peripherals off
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
// Disable all pads except G1 (33), G2 (34) and LED_BUILTIN (19)
for (int x = 0; x < 50; x++)
{
if ((x != 33) && (x != 34) && (x != 19))
{
am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
}
}
// Disable power to Qwiic connector
qwiicPowerOff();
// Disable power to peripherals
peripheralPowerOff();
// Clear online/offline flags
online.gnss = false;
online.microSd = false;
online.logGnss = false;
online.logDebug = false;
// Power down flash, SRAM, cache
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Power down all memory during deepsleep
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);
// Enter deep sleep
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
/*
Processor sleeps and awaits RTC or WDT ISR
*/
// Wake up
wakeUp();
}
// Wake from deep sleep
void wakeUp()
{
// Return 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);
ap3_adc_setup(); // Enable ADC
Wire.begin(); // Enable I2C
Wire.setClock(400000); // Set I2C clock speed to 400 kHz
SPI.begin(); // Enable SPI
#if DEBUG
Serial.begin(115200); // Open Serial port
#endif
}
// Enable power to Qwiic connector
void qwiicPowerOn()
{
digitalWrite(PIN_QWIIC_POWER, HIGH);
myDelay(2500); // Non-blocking delay to allow Qwiic devices time to power up
}
// Disable power to Qwiic connector
void qwiicPowerOff()
{
digitalWrite(PIN_QWIIC_POWER, LOW);
}
// Enable power to microSD and peripherals
void peripheralPowerOn()
{
digitalWrite(PIN_PWC_POWER, HIGH);
myDelay(250); // Non-blocking delay
}
// Disable power to microSD and peripherals
void peripheralPowerOff()
{
myDelay(250); // Non-blocking delay
digitalWrite(PIN_PWC_POWER, LOW);
}
// Non-blocking blink LED (https://forum.arduino.cc/index.php?topic=503368.0)
void blinkLed(byte ledFlashes, unsigned int ledDelay)
{
byte i = 0;
while (i < ledFlashes * 2)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= ledDelay)
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
previousMillis = currentMillis;
i++;
}
}
// Turn off LED
digitalWrite(LED_BUILTIN, LOW);
}
// Non-blocking delay (ms: duration)
// https://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover
void myDelay(unsigned long ms)
{
unsigned long start = millis(); // Start: timestamp
for (;;)
{
petDog(); // Reset watchdog timer
unsigned long now = millis(); // Now: timestamp
unsigned long elapsed = now - start; // Elapsed: duration
if (elapsed >= ms) // Comparing durations: OK
return;
}
}