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