Skip to content

Commit e10d9e9

Browse files
committed
Add example showing RTC wakeup
1 parent e919709 commit e10d9e9

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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.
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 ~4.2uA in deep sleep
14+
with a wake up every 5 seconds to blink the LED. The RTC is used to trigger an interrupt
15+
every second.
16+
17+
To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach
18+
a DMM via IC hooks (https://www.sparkfun.com/products/506).
19+
20+
The USB to serial bridge draws some current:
21+
Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096)
22+
FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873)
23+
24+
*/
25+
26+
static uint32_t g_RTCseconds = 0;
27+
28+
void setup()
29+
{
30+
Serial.begin(115200);
31+
Serial.println("Low power sleep example");
32+
33+
pinMode(LED_BUILTIN, OUTPUT);
34+
35+
//Turn off ADC
36+
power_adc_disable();
37+
38+
// Set the clock frequency.
39+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
40+
41+
// Set the default cache configuration
42+
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
43+
am_hal_cachectrl_enable();
44+
45+
// Initialize for low power in the power control block
46+
am_hal_pwrctrl_low_power_init();
47+
48+
// The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source.
49+
// The HFRC appears to take over 60 uA when it is running, so this is a big source of extra
50+
// current consumption in deep sleep.
51+
// For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running.
52+
// However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz
53+
// XTAL clock source instead the measured deepsleep power drops by about 64 uA.
54+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
55+
56+
// This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock"
57+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
58+
59+
// This option would be available to systems that don't care about passing time, but might be set
60+
// to wake up on a GPIO transition interrupt.
61+
//am_hal_stimer_config(AM_HAL_STIMER_NO_CLK);
62+
63+
//Turn OFF Flash1
64+
if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K))
65+
{
66+
while (1)
67+
;
68+
}
69+
70+
// Power down SRAM
71+
PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K;
72+
73+
setupRTC();
74+
75+
Serial.println("Going to sleep...");
76+
delay(100); //Wait for print to complete
77+
Serial.end(); //Disable Serial
78+
79+
// Enable interrupts to the core.
80+
am_hal_interrupt_master_enable();
81+
}
82+
83+
void loop()
84+
{
85+
// Go to Deep Sleep.
86+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
87+
}
88+
89+
void setupRTC()
90+
{
91+
// Enable the XT for the RTC.
92+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START, 0);
93+
94+
// Select XT for RTC clock source
95+
am_hal_rtc_osc_select(AM_HAL_RTC_OSC_XT);
96+
97+
// Enable the RTC.
98+
am_hal_rtc_osc_enable();
99+
100+
// Set the alarm repeat interval to be every second.
101+
am_hal_rtc_alarm_interval_set(AM_HAL_RTC_ALM_RPT_SEC);
102+
103+
// Clear the RTC alarm interrupt.
104+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
105+
106+
// Enable the RTC alarm interrupt.
107+
am_hal_rtc_int_enable(AM_HAL_RTC_INT_ALM);
108+
109+
// Enable RTC interrupts to the NVIC.
110+
NVIC_EnableIRQ(RTC_IRQn);
111+
}
112+
113+
extern "C" void am_rtc_isr(void)
114+
{
115+
// Clear the RTC alarm interrupt.
116+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
117+
118+
// Check the desired number of seconds until LED is toggled.
119+
if (++g_RTCseconds >= 5)
120+
{
121+
// Reset the seconds counter.
122+
g_RTCseconds = 0;
123+
124+
// Toggle LED
125+
digitalWrite(LED_BUILTIN, HIGH);
126+
delay(100);
127+
digitalWrite(LED_BUILTIN, LOW);
128+
}
129+
}

0 commit comments

Comments
 (0)