From 5a92a7c8cf607ec6e7640e049ffd58563cacd6a3 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Thu, 17 Oct 2019 21:31:05 -0600 Subject: [PATCH 1/5] Define power pads on Edge2.2 --- variants/SparkFun_Edge2/config/variant.cpp | 4 ++-- variants/SparkFun_Edge2/config/variant.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/variants/SparkFun_Edge2/config/variant.cpp b/variants/SparkFun_Edge2/config/variant.cpp index 8c2c4e7..70300d7 100644 --- a/variants/SparkFun_Edge2/config/variant.cpp +++ b/variants/SparkFun_Edge2/config/variant.cpp @@ -24,7 +24,7 @@ SOFTWARE. // Apollo3 pads 30 and 46 are not exposed by Artemis module const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = { - AP3_GPIO_PAD_UNUSED, + 0, //Mic VDD AP3_GPIO_PAD_UNUSED, AP3_GPIO_PAD_UNUSED, AP3_GPIO_PAD_UNUSED, @@ -65,7 +65,7 @@ const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = { AP3_GPIO_PAD_UNUSED, 39, //Qwiic SCL 40, //Qwiic SDA - AP3_GPIO_PAD_UNUSED, + 41, //Accel VDD 42, //Accel SCL 43, //Accel SDA 44, //GPIO 44 diff --git a/variants/SparkFun_Edge2/config/variant.h b/variants/SparkFun_Edge2/config/variant.h index 700cbc6..93643b1 100644 --- a/variants/SparkFun_Edge2/config/variant.h +++ b/variants/SparkFun_Edge2/config/variant.h @@ -57,4 +57,8 @@ extern Uart Serial; #define MIC_DATA 29 #define MIC_CLOCK 12 +#define MIC_VDD 0 +#define ACCEL_VDD 41 +#define CAMERA_VDD 32 + #endif // _AP3_VARIANT_H_ \ No newline at end of file From e9197092b0358efd2fdf3b5588effe0be21d7e7f Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Thu, 17 Oct 2019 21:42:52 -0600 Subject: [PATCH 2/5] Add low power example --- .../examples/Advanced/LowPower/LowPower.ino | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 libraries/Examples/examples/Advanced/LowPower/LowPower.ino diff --git a/libraries/Examples/examples/Advanced/LowPower/LowPower.ino b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino new file mode 100644 index 0000000..ed809f7 --- /dev/null +++ b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino @@ -0,0 +1,94 @@ +/* + Artemis Low Power: How low can we go? + By: Nathan Seidle + SparkFun Electronics + Date: October 17th, 2019 + License: This code is public domain. Based on deepsleep.c from Ambiq SDK v2.2.0. + A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement. + + SparkFun labored with love to create this code. Feel like supporting open source hardware? + Buy a board from SparkFun! https://www.sparkfun.com/products/15376 + + How close can we get to 2.7uA in deep sleep? + This example shows how decrease the Artemis current consumption to less than 3uA in deep sleep. + + To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach + a DMM via IC hooks (https://www.sparkfun.com/products/506). + + The USB to serial bridge draws some current: + Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096) + FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873) + + The various components on the Edge2 can be powered on/off as well + PDM microphones (2) - ~50.9uA + Accelerometer (POR mode) - ~79.7uA + Camera regulator enabled (no camera) - ~96.8uA +*/ + +void setup() +{ + Serial.begin(115200); + Serial.println("Low power sleep example"); + +#if defined(ARDUINO_SFE_EDGE2) + pinMode(ACCEL_VDD, OUTPUT); + digitalWrite(ACCEL_VDD, LOW); + + pinMode(MIC_VDD, OUTPUT); + digitalWrite(MIC_VDD, LOW); + + pinMode(CAMERA_VDD, OUTPUT); + digitalWrite(CAMERA_VDD, LOW); +#endif + + //Turn off ADC + power_adc_disable(); + + // Initialize for low power in the power control block + am_hal_pwrctrl_low_power_init(); + + // Stop the XTAL. + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_STOP, 0); + + // Disable the RTC. + am_hal_rtc_osc_disable(); + + // The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source. + // The HFRC appears to take over 60 uA when it is running, so this is a big source of extra + // current consumption in deep sleep. + // For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running. + // However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz + // XTAL clock source instead the measured deepsleep power drops by about 64 uA. + am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); + + // This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock" + am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ); + + // This option would be available to systems that don't care about passing time, but might be set + // to wake up on a GPIO transition interrupt. + // am_hal_stimer_config(AM_HAL_STIMER_NO_CLK); + + // Turn OFF Flash1 + if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K)) + { + while (1) + ; + } + + // Power down SRAM + PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K; + + Serial.println("Going to sleep..."); + delay(100); //Wait for print to complete + + Serial.end(); //Disable Serial + + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); + + //We should never get here. +} + +void loop() +{ + //Do nothing +} \ No newline at end of file From e10d9e90d0dbb4590626833a029ab0d0dc84cdf9 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Fri, 18 Oct 2019 15:11:34 -0600 Subject: [PATCH 3/5] Add example showing RTC wakeup --- .../LowPower_WithWake/LowPower_WithWake.ino | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino diff --git a/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino new file mode 100644 index 0000000..c151019 --- /dev/null +++ b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino @@ -0,0 +1,129 @@ +/* + Artemis Low Power: How low can we go? + By: Nathan Seidle + SparkFun Electronics + Date: October 17th, 2019 + License: This code is public domain. Based on deepsleep_wake.c from Ambiq SDK v2.2.0. + A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement. + + SparkFun labored with love to create this code. Feel like supporting open source hardware? + Buy a board from SparkFun! https://www.sparkfun.com/products/15376 + + How close can we get to 2.7uA in deep sleep? + This example shows how decrease the Artemis current consumption to ~4.2uA in deep sleep + with a wake up every 5 seconds to blink the LED. The RTC is used to trigger an interrupt + every second. + + To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach + a DMM via IC hooks (https://www.sparkfun.com/products/506). + + The USB to serial bridge draws some current: + Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096) + FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873) + +*/ + +static uint32_t g_RTCseconds = 0; + +void setup() +{ + Serial.begin(115200); + Serial.println("Low power sleep example"); + + pinMode(LED_BUILTIN, OUTPUT); + + //Turn off ADC + power_adc_disable(); + + // Set the clock frequency. + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); + + // Set the default cache configuration + am_hal_cachectrl_config(&am_hal_cachectrl_defaults); + am_hal_cachectrl_enable(); + + // Initialize for low power in the power control block + am_hal_pwrctrl_low_power_init(); + + // The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source. + // The HFRC appears to take over 60 uA when it is running, so this is a big source of extra + // current consumption in deep sleep. + // For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running. + // However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz + // XTAL clock source instead the measured deepsleep power drops by about 64 uA. + am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); + + // This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock" + am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ); + + // This option would be available to systems that don't care about passing time, but might be set + // to wake up on a GPIO transition interrupt. + //am_hal_stimer_config(AM_HAL_STIMER_NO_CLK); + + //Turn OFF Flash1 + if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K)) + { + while (1) + ; + } + + // Power down SRAM + PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K; + + setupRTC(); + + Serial.println("Going to sleep..."); + delay(100); //Wait for print to complete + Serial.end(); //Disable Serial + + // Enable interrupts to the core. + am_hal_interrupt_master_enable(); +} + +void loop() +{ + // Go to Deep Sleep. + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); +} + +void setupRTC() +{ + // Enable the XT for the RTC. + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START, 0); + + // Select XT for RTC clock source + am_hal_rtc_osc_select(AM_HAL_RTC_OSC_XT); + + // Enable the RTC. + am_hal_rtc_osc_enable(); + + // Set the alarm repeat interval to be every second. + am_hal_rtc_alarm_interval_set(AM_HAL_RTC_ALM_RPT_SEC); + + // Clear the RTC alarm interrupt. + am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM); + + // Enable the RTC alarm interrupt. + am_hal_rtc_int_enable(AM_HAL_RTC_INT_ALM); + + // Enable RTC interrupts to the NVIC. + NVIC_EnableIRQ(RTC_IRQn); +} + +extern "C" void am_rtc_isr(void) +{ + // Clear the RTC alarm interrupt. + am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM); + + // Check the desired number of seconds until LED is toggled. + if (++g_RTCseconds >= 5) + { + // Reset the seconds counter. + g_RTCseconds = 0; + + // Toggle LED + digitalWrite(LED_BUILTIN, HIGH); + delay(100); + digitalWrite(LED_BUILTIN, LOW); + } +} \ No newline at end of file From bc156fdac2260434f2df62497893b7ace64cfaa4 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Fri, 18 Oct 2019 15:14:58 -0600 Subject: [PATCH 4/5] Add note about silicon revision and errata --- libraries/Examples/examples/Advanced/LowPower/LowPower.ino | 3 +++ .../examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libraries/Examples/examples/Advanced/LowPower/LowPower.ino b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino index ed809f7..e551798 100644 --- a/libraries/Examples/examples/Advanced/LowPower/LowPower.ino +++ b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino @@ -12,6 +12,9 @@ How close can we get to 2.7uA in deep sleep? This example shows how decrease the Artemis current consumption to less than 3uA in deep sleep. + Note that Artemis modules with revision A0/A1 silicon will use ~30uA. Please see the + Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf + To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach a DMM via IC hooks (https://www.sparkfun.com/products/506). diff --git a/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino index c151019..f7ba4f1 100644 --- a/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino +++ b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino @@ -14,6 +14,9 @@ with a wake up every 5 seconds to blink the LED. The RTC is used to trigger an interrupt every second. + Note that Artemis modules with revision A0/A1 silicon will use ~30uA. Please see the + Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf + To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach a DMM via IC hooks (https://www.sparkfun.com/products/506). From 9a0a5c80151bcfca3d9854161734fc06f5c35dae Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Fri, 18 Oct 2019 15:30:21 -0600 Subject: [PATCH 5/5] Add disabling of SWD pins and UART pins to lower by another 1uA. --- .../examples/Advanced/LowPower/LowPower.ino | 14 ++++++++++++-- .../LowPower_WithWake/LowPower_WithWake.ino | 17 ++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/libraries/Examples/examples/Advanced/LowPower/LowPower.ino b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino index e551798..cdb86b4 100644 --- a/libraries/Examples/examples/Advanced/LowPower/LowPower.ino +++ b/libraries/Examples/examples/Advanced/LowPower/LowPower.ino @@ -10,9 +10,9 @@ Buy a board from SparkFun! https://www.sparkfun.com/products/15376 How close can we get to 2.7uA in deep sleep? - This example shows how decrease the Artemis current consumption to less than 3uA in deep sleep. + This example shows how decrease the Artemis current consumption to less than ~2.5uA in deep sleep. - Note that Artemis modules with revision A0/A1 silicon will use ~30uA. Please see the + Note that Artemis modules with revision A1 silicon will use ~30uA. Please see the Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach @@ -56,6 +56,16 @@ void setup() // Disable the RTC. am_hal_rtc_osc_disable(); + // Disabling the debugger GPIOs saves about 1.2 uA total: + am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_HAL_GPIO_DISABLE); + am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_HAL_GPIO_DISABLE); + + // These two GPIOs are critical: the TX/RX connections between the Artemis module and the CH340S on the Blackboard + // are prone to backfeeding each other. To stop this from happening, we must reconfigure those pins as GPIOs + // and then disable them completely: + am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_HAL_GPIO_DISABLE); + am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_HAL_GPIO_DISABLE); + // The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source. // The HFRC appears to take over 60 uA when it is running, so this is a big source of extra // current consumption in deep sleep. diff --git a/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino index f7ba4f1..24300b4 100644 --- a/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino +++ b/libraries/Examples/examples/Advanced/LowPower_WithWake/LowPower_WithWake.ino @@ -4,17 +4,18 @@ SparkFun Electronics Date: October 17th, 2019 License: This code is public domain. Based on deepsleep_wake.c from Ambiq SDK v2.2.0. - A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement. + A big thanks to robin_hodgson for pointing out the HFRC shutdown requirement and + turning off the SWD pins. SparkFun labored with love to create this code. Feel like supporting open source hardware? Buy a board from SparkFun! https://www.sparkfun.com/products/15376 How close can we get to 2.7uA in deep sleep? - This example shows how decrease the Artemis current consumption to ~4.2uA in deep sleep + This example shows how decrease the Artemis current consumption to ~2.4uA in deep sleep with a wake up every 5 seconds to blink the LED. The RTC is used to trigger an interrupt every second. - Note that Artemis modules with revision A0/A1 silicon will use ~30uA. Please see the + Note that Artemis modules with revision A1 silicon will use ~30uA. Please see the Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf To monitor the current to the Edge cut the MEAS jumper, solder in headers, and attach @@ -48,6 +49,16 @@ void setup() // Initialize for low power in the power control block am_hal_pwrctrl_low_power_init(); + // Disabling the debugger GPIOs saves about 1.2 uA total: + am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_HAL_GPIO_DISABLE); + am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_HAL_GPIO_DISABLE); + + // These two GPIOs are critical: the TX/RX connections between the Artemis module and the CH340S on the Blackboard + // are prone to backfeeding each other. To stop this from happening, we must reconfigure those pins as GPIOs + // and then disable them completely: + am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_HAL_GPIO_DISABLE); + am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_HAL_GPIO_DISABLE); + // The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source. // The HFRC appears to take over 60 uA when it is running, so this is a big source of extra // current consumption in deep sleep.