Skip to content

Commit 04b6f9c

Browse files
authored
Merge pull request #77 from sparkfun/lowPower
Add examples demoing low power config
2 parents 84135f4 + 9a0a5c8 commit 04b6f9c

File tree

4 files changed

+256
-2
lines changed

4 files changed

+256
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
Artemis Low Power: How low can we go?
3+
By: Nathan Seidle
4+
SparkFun Electronics
5+
Date: October 17th, 2019
6+
License: This code is public domain. Based on deepsleep.c from Ambiq SDK v2.2.0.
7+
A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement.
8+
9+
SparkFun labored with love to create this code. Feel like supporting open source hardware?
10+
Buy a board from SparkFun! https://www.sparkfun.com/products/15376
11+
12+
How close can we get to 2.7uA in deep sleep?
13+
This example shows how decrease the Artemis current consumption to less than ~2.5uA in deep sleep.
14+
15+
Note that Artemis modules with revision A1 silicon will use ~30uA. Please see the
16+
Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf
17+
18+
To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach
19+
a DMM via IC hooks (https://www.sparkfun.com/products/506).
20+
21+
The USB to serial bridge draws some current:
22+
Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096)
23+
FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873)
24+
25+
The various components on the Edge2 can be powered on/off as well
26+
PDM microphones (2) - ~50.9uA
27+
Accelerometer (POR mode) - ~79.7uA
28+
Camera regulator enabled (no camera) - ~96.8uA
29+
*/
30+
31+
void setup()
32+
{
33+
Serial.begin(115200);
34+
Serial.println("Low power sleep example");
35+
36+
#if defined(ARDUINO_SFE_EDGE2)
37+
pinMode(ACCEL_VDD, OUTPUT);
38+
digitalWrite(ACCEL_VDD, LOW);
39+
40+
pinMode(MIC_VDD, OUTPUT);
41+
digitalWrite(MIC_VDD, LOW);
42+
43+
pinMode(CAMERA_VDD, OUTPUT);
44+
digitalWrite(CAMERA_VDD, LOW);
45+
#endif
46+
47+
//Turn off ADC
48+
power_adc_disable();
49+
50+
// Initialize for low power in the power control block
51+
am_hal_pwrctrl_low_power_init();
52+
53+
// Stop the XTAL.
54+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_STOP, 0);
55+
56+
// Disable the RTC.
57+
am_hal_rtc_osc_disable();
58+
59+
// Disabling the debugger GPIOs saves about 1.2 uA total:
60+
am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_HAL_GPIO_DISABLE);
61+
am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_HAL_GPIO_DISABLE);
62+
63+
// These two GPIOs are critical: the TX/RX connections between the Artemis module and the CH340S on the Blackboard
64+
// are prone to backfeeding each other. To stop this from happening, we must reconfigure those pins as GPIOs
65+
// and then disable them completely:
66+
am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_HAL_GPIO_DISABLE);
67+
am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_HAL_GPIO_DISABLE);
68+
69+
// The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source.
70+
// The HFRC appears to take over 60 uA when it is running, so this is a big source of extra
71+
// current consumption in deep sleep.
72+
// For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running.
73+
// However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz
74+
// XTAL clock source instead the measured deepsleep power drops by about 64 uA.
75+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
76+
77+
// This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock"
78+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
79+
80+
// This option would be available to systems that don't care about passing time, but might be set
81+
// to wake up on a GPIO transition interrupt.
82+
// am_hal_stimer_config(AM_HAL_STIMER_NO_CLK);
83+
84+
// Turn OFF Flash1
85+
if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K))
86+
{
87+
while (1)
88+
;
89+
}
90+
91+
// Power down SRAM
92+
PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K;
93+
94+
Serial.println("Going to sleep...");
95+
delay(100); //Wait for print to complete
96+
97+
Serial.end(); //Disable Serial
98+
99+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
100+
101+
//We should never get here.
102+
}
103+
104+
void loop()
105+
{
106+
//Do nothing
107+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
Artemis Low Power: How low can we go?
3+
By: Nathan Seidle
4+
SparkFun Electronics
5+
Date: October 17th, 2019
6+
License: This code is public domain. Based on deepsleep_wake.c from Ambiq SDK v2.2.0.
7+
A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement and
8+
turning off the SWD pins.
9+
10+
SparkFun labored with love to create this code. Feel like supporting open source hardware?
11+
Buy a board from SparkFun! https://www.sparkfun.com/products/15376
12+
13+
How close can we get to 2.7uA in deep sleep?
14+
This example shows how decrease the Artemis current consumption to ~2.4uA in deep sleep
15+
with a wake up every 5 seconds to blink the LED. The RTC is used to trigger an interrupt
16+
every second.
17+
18+
Note that Artemis modules with revision A1 silicon will use ~30uA. Please see the
19+
Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf
20+
21+
To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach
22+
a DMM via IC hooks (https://www.sparkfun.com/products/506).
23+
24+
The USB to serial bridge draws some current:
25+
Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096)
26+
FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873)
27+
28+
*/
29+
30+
static uint32_t g_RTCseconds = 0;
31+
32+
void setup()
33+
{
34+
Serial.begin(115200);
35+
Serial.println("Low power sleep example");
36+
37+
pinMode(LED_BUILTIN, OUTPUT);
38+
39+
//Turn off ADC
40+
power_adc_disable();
41+
42+
// Set the clock frequency.
43+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
44+
45+
// Set the default cache configuration
46+
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
47+
am_hal_cachectrl_enable();
48+
49+
// Initialize for low power in the power control block
50+
am_hal_pwrctrl_low_power_init();
51+
52+
// Disabling the debugger GPIOs saves about 1.2 uA total:
53+
am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_HAL_GPIO_DISABLE);
54+
am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_HAL_GPIO_DISABLE);
55+
56+
// These two GPIOs are critical: the TX/RX connections between the Artemis module and the CH340S on the Blackboard
57+
// are prone to backfeeding each other. To stop this from happening, we must reconfigure those pins as GPIOs
58+
// and then disable them completely:
59+
am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_HAL_GPIO_DISABLE);
60+
am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_HAL_GPIO_DISABLE);
61+
62+
// The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source.
63+
// The HFRC appears to take over 60 uA when it is running, so this is a big source of extra
64+
// current consumption in deep sleep.
65+
// For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running.
66+
// However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz
67+
// XTAL clock source instead the measured deepsleep power drops by about 64 uA.
68+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
69+
70+
// This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock"
71+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
72+
73+
// This option would be available to systems that don't care about passing time, but might be set
74+
// to wake up on a GPIO transition interrupt.
75+
//am_hal_stimer_config(AM_HAL_STIMER_NO_CLK);
76+
77+
//Turn OFF Flash1
78+
if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K))
79+
{
80+
while (1)
81+
;
82+
}
83+
84+
// Power down SRAM
85+
PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K;
86+
87+
setupRTC();
88+
89+
Serial.println("Going to sleep...");
90+
delay(100); //Wait for print to complete
91+
Serial.end(); //Disable Serial
92+
93+
// Enable interrupts to the core.
94+
am_hal_interrupt_master_enable();
95+
}
96+
97+
void loop()
98+
{
99+
// Go to Deep Sleep.
100+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
101+
}
102+
103+
void setupRTC()
104+
{
105+
// Enable the XT for the RTC.
106+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START, 0);
107+
108+
// Select XT for RTC clock source
109+
am_hal_rtc_osc_select(AM_HAL_RTC_OSC_XT);
110+
111+
// Enable the RTC.
112+
am_hal_rtc_osc_enable();
113+
114+
// Set the alarm repeat interval to be every second.
115+
am_hal_rtc_alarm_interval_set(AM_HAL_RTC_ALM_RPT_SEC);
116+
117+
// Clear the RTC alarm interrupt.
118+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
119+
120+
// Enable the RTC alarm interrupt.
121+
am_hal_rtc_int_enable(AM_HAL_RTC_INT_ALM);
122+
123+
// Enable RTC interrupts to the NVIC.
124+
NVIC_EnableIRQ(RTC_IRQn);
125+
}
126+
127+
extern "C" void am_rtc_isr(void)
128+
{
129+
// Clear the RTC alarm interrupt.
130+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
131+
132+
// Check the desired number of seconds until LED is toggled.
133+
if (++g_RTCseconds >= 5)
134+
{
135+
// Reset the seconds counter.
136+
g_RTCseconds = 0;
137+
138+
// Toggle LED
139+
digitalWrite(LED_BUILTIN, HIGH);
140+
delay(100);
141+
digitalWrite(LED_BUILTIN, LOW);
142+
}
143+
}

variants/SparkFun_Edge2/config/variant.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ SOFTWARE.
2424

2525
// Apollo3 pads 30 and 46 are not exposed by Artemis module
2626
const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = {
27-
AP3_GPIO_PAD_UNUSED,
27+
0, //Mic VDD
2828
AP3_GPIO_PAD_UNUSED,
2929
AP3_GPIO_PAD_UNUSED,
3030
AP3_GPIO_PAD_UNUSED,
@@ -65,7 +65,7 @@ const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = {
6565
AP3_GPIO_PAD_UNUSED,
6666
39, //Qwiic SCL
6767
40, //Qwiic SDA
68-
AP3_GPIO_PAD_UNUSED,
68+
41, //Accel VDD
6969
42, //Accel SCL
7070
43, //Accel SDA
7171
44, //GPIO 44

variants/SparkFun_Edge2/config/variant.h

+4
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,8 @@ extern Uart Serial;
5757
#define MIC_DATA 29
5858
#define MIC_CLOCK 12
5959

60+
#define MIC_VDD 0
61+
#define ACCEL_VDD 41
62+
#define CAMERA_VDD 32
63+
6064
#endif // _AP3_VARIANT_H_

0 commit comments

Comments
 (0)