Skip to content

Commit 8f523cf

Browse files
committed
Example demonstrating IOM ending.
1 parent e3db691 commit 8f523cf

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
Artemis Low Power: How low can we go?
3+
By: Nathan Seidle
4+
SparkFun Electronics
5+
Date: February 26th, 2020
6+
License: This code is public domain.
7+
8+
This example demonstrates how to do some work (talk to a device over I2C / IOM),
9+
enter deep sleep, then wake and continue work.
10+
11+
SparkFun labored with love to create this code. Feel like supporting open source hardware?
12+
Buy a board from SparkFun! https://www.sparkfun.com/products/15376
13+
14+
How close can we get to 2.7uA in deep sleep?
15+
This example shows how decrease the Artemis current consumption to ~2.4uA in deep sleep
16+
with a wake up every 5 seconds to read a sensor.
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 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+
518uA on RedBoard running while(1);
29+
28uA on RedBoard running this sketch with MS5637 attached
30+
2.93uA on RedBoard with microphone VCC trace cut (mic was using ~25uA)
31+
2.78uA on RedBoard with MS5637 detached
32+
*/
33+
34+
#include <Wire.h>
35+
36+
#include "SparkFun_MS5637_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_MS5637
37+
MS5637 barometricSensor;
38+
39+
#include <SPI.h>
40+
#define SPI_SPEED 1000000
41+
#define SPI_ORDER MSBFIRST
42+
#define SPI_MODE SPI_MODE0
43+
SPISettings mySettings(SPI_SPEED, SPI_ORDER, SPI_MODE);
44+
45+
uint32_t msToSleep = 5000; //This is the user editable number of ms to sleep between RTC checks
46+
#define TIMER_FREQ 32768L //Counter/Timer 6 will use the 32kHz clock
47+
uint32_t sysTicksToSleep = msToSleep * TIMER_FREQ / 1000;
48+
49+
const byte STAT_LED = 13;
50+
51+
int counter = 0;
52+
53+
void setup(void) {
54+
Serial.begin(115200);
55+
Serial.println("Artemis Low Power Example");
56+
57+
//We don't really use Serial1 in this example but we power it up and use it just to show its use.
58+
Serial1.begin(115200);
59+
Serial1.println("Serial1 now online!");
60+
61+
Wire.begin();
62+
63+
//We don't really use SPI in this example but we power it up and use it just to show its use.
64+
SPI.begin();
65+
SPI.beginTransaction(mySettings);
66+
SPI.transfer(0xAA);
67+
SPI.endTransaction();
68+
69+
if (barometricSensor.begin() == false)
70+
Serial.println("MS5637 sensor did not respond. Please check wiring.");
71+
else
72+
Serial.println("MS5637 sensor detected.");
73+
}
74+
75+
void loop(void) {
76+
77+
float temperature = barometricSensor.getTemperature();
78+
float pressure = barometricSensor.getPressure();
79+
80+
Serial.print("Temperature=");
81+
Serial.print(temperature, 1);
82+
Serial.print("(C)");
83+
84+
Serial.print(" Pressure=");
85+
Serial.print(pressure, 3);
86+
Serial.print("(hPa or mbar)");
87+
88+
Serial.print(" counter=");
89+
Serial.print(counter++);
90+
91+
Serial.println();
92+
93+
digitalWrite(STAT_LED, HIGH);
94+
delay(100);
95+
digitalWrite(STAT_LED, LOW);
96+
97+
goToSleep();
98+
}
99+
100+
//Power everything down and wait for interrupt wakeup
101+
void goToSleep()
102+
{
103+
Wire.end(); //Power down I2C
104+
105+
SPI.end(); //Power down SPI
106+
//SPI1.end(); //This example doesn't use SPI1 but you will need to end any instance you may have created
107+
108+
power_adc_disable(); //Power down ADC. It it started by default before setup().
109+
110+
Serial.end(); //Power down UART
111+
Serial1.end();
112+
113+
//Disable all pads
114+
for (int x = 0 ; x < 50 ; x++)
115+
am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE);
116+
117+
//We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available
118+
//CT 7 is used for Software Serial. All CTs are used for Servo.
119+
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6
120+
am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6
121+
122+
//Use the lower power 32kHz clock. Use it to run CT6 as well.
123+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
124+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE);
125+
126+
//Setup interrupt to trigger when the number of ms have elapsed
127+
am_hal_stimer_compare_delta_set(6, sysTicksToSleep);
128+
129+
//Power down Flash, SRAM, cache
130+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE
131+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k
132+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k
133+
//am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)
134+
135+
//Enable the timer interrupt in the NVIC.
136+
NVIC_EnableIRQ(STIMER_CMPR6_IRQn);
137+
138+
//Go to Deep Sleep.
139+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
140+
141+
//Turn off interrupt
142+
NVIC_DisableIRQ(STIMER_CMPR6_IRQn);
143+
144+
//We're BACK!
145+
wakeFromSleep();
146+
}
147+
148+
//Power everything up gracefully
149+
void wakeFromSleep()
150+
{
151+
//Power up SRAM, turn on entire Flash
152+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
153+
154+
//Go back to using the main clock
155+
am_hal_stimer_int_enable(AM_HAL_STIMER_INT_OVERFLOW);
156+
NVIC_EnableIRQ(STIMER_IRQn);
157+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
158+
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
159+
160+
//Turn on ADC
161+
ap3_adc_setup();
162+
163+
//Set any pinModes
164+
pinMode(STAT_LED, OUTPUT);
165+
166+
//Turn on Serial
167+
Serial.begin(115200);
168+
delay(10);
169+
Serial.println("Back on");
170+
171+
//Turn on I2C
172+
Wire.begin();
173+
174+
//Restart Sensors
175+
if (barometricSensor.begin() == false)
176+
{
177+
Serial.println("MS5637 sensor did not respond. Please check wiring.");
178+
}
179+
}
180+
181+
//Called once number of milliseconds has passed
182+
extern "C" void am_stimer_cmpr6_isr(void)
183+
{
184+
uint32_t ui32Status = am_hal_stimer_int_status_get(false);
185+
if (ui32Status & AM_HAL_STIMER_INT_COMPAREG)
186+
{
187+
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG);
188+
}
189+
}

0 commit comments

Comments
 (0)