Lora expLoRaBLE deep sleep/ low power mode

Using the [SparkFun Ambiq Apollo3 Arduino Core package and trying the [RTC example 6, the lowest current consumption I’m able to measure is 1.285 mA. This is with the LED jumper on the back of the board cut.

The only thing connected to the board is the U.FL antenna.

Are there any further options to reduce the current consumption to a few µA? According to [ the datasheet, the Apollo3 chip only consumes 1 µA in deep sleep mode with RTC at 3.3V. Thank you.](https://cdn.sparkfun.com/assets/6/3/9/3/1/Apollo3_Blue_MCU_Data_Sheet_v0_9_1.pdf)](Arduino_Apollo3/libraries/RTC/examples/Example6_LowPower_Alarm at main · sparkfun/Arduino_Apollo3 · GitHub)](GitHub - sparkfun/Arduino_Apollo3: Arduino core to support the Apollo3 microcontroller from Ambiq Micro)

Does anything change if you decrease the output power? https://github.com/jgromes/RadioLib/blo … ttings.ino

How long is it entering sleep? Maybe extend the sleep cycle and see if that helps

Thank you for the response. I’m currently just trying the RTC low power example, so no communication.

Initially, the sleep duration was 10s. I increased it to a minute but the current consumption remains the same. A screenshot is attached. You can see peaks approximately every minute. The code I’m using can be seen below.

#include "RTC.h"

void setup()
{
  Serial.begin(115200);
  Serial.println("SparkFun RTC Low-power Alarm Example");

  // // Easily set RTC using the system __DATE__ and __TIME__ macros from compiler
  // RTC.setToCompilerTime();

  // Manually set RTC date and time
  rtc.setTime(0, 0, 0, 9, 21, 4, 23); // 9:00:00.000, April 4th, 2023 (hund, ss, mm, hh, dd, mm, yy)

  // Set the RTC's alarm
  rtc.setAlarm(0, 0, 1, 9, 21, 4); // 9:01:00.000, June 3rd (hund, ss, mm, hh, dd, mm). Note: No year alarm register


  rtc.setAlarmMode(6); // Set the RTC alarm to match on minutes rollover
  rtc.attachInterrupt(); // Attach RTC alarm interrupt
}

void loop()
{
  // Print date and time of RTC alarm trigger
  Serial.print("Alarm interrupt: "); printDateTime();

  // Enter deep sleep and await RTC alarm interrupt
  goToSleep();
}

// Print the RTC's current date and time
void printDateTime()
{
  rtc.getTime();

  Serial.printf("20%02d-%02d-%02d %02d:%02d:%02d.%03d\n",
          rtc.year, rtc.month, rtc.dayOfMonth,
          rtc.hour, rtc.minute, rtc.seconds, rtc.hundredths);
  Serial.println();
}

// Power down gracefully
void goToSleep()
{
  // Disable UART
  Serial.end();

  // Disable ADC
  powerControlADC(false);

  // Force the peripherals off
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_MAX);
  /*am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);*/

  // Disable all pads (except UART TX/RX)
  for (int x = 0 ; x < 48 ; x++)
    am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);

  //Power down CACHE, flashand SRAM
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Turn off CACHE and flash
  am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM); // Retain all SRAM (0.6 uA)
  
  // Keep the 32kHz clock running for RTC
  am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);

  am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); // Sleep forever

  // And we're back!
  wakeUp();
}

// Power up gracefully
void wakeUp()
{
  // Go back to using the main clock
  am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);

  // Power up SRAM, turn on entire Flash
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);

  // Go back to using the main clock
  am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);

  // Renable UART0 pins
  am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX);
  am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX);

  // Renable power to UART0
  am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);
  
  // Enable ADC
  initializeADC();

  // Enable Serial
  Serial.begin(115200);
}

// Interrupt handler for the RTC
extern "C" void am_rtc_isr(void)
{
  // Clear the RTC alarm interrupt
  rtc.clearInterrupt();
}

I don’t see a difference with/ without the antenna connected.

Does the charging controller add to the current consumption? If so, is there a way to disable it?

You powering through the battery connector? If so, the voltage regulator is burning some current.

Correct, I’m powering through the battery connector. is the current consumption of the regulator that much?

AM_HAL_PWRCTRL_PERIPH_MAX does not do ANYTHING. It is just defining the last entry. (see am_hal_pwrctrl.h)

You need to disable all the peripherals as in the original low-power example and thus in the way you have commented out.

Also the low-power example is not shutting down basicmac/ SX1262 and not shutting down BLE.

Where they set for running before and does that have impact ?

You will have a challenge however to get started again AFTER wake-up. SPI does NOT recover in V2.x.x.

Have a look at the information on https://github.com/paulvha/apollo3/tree … PowerCntrl.

  • There is a document that I have created around deep sleep. It is in ODT- format so you can read this with nearly all word processors.

  • There also a sketch with 2 tabs that will help you to see the peripheral power status
  • Thank you Paul for the reply.

    Disabling the peripherals leaves the TX LED on which increases the current consumption to about 2.5mA.

    The SX1262 and BLE were not set for running, only the low power example is being executed. However I measure around 1.3 mA when running the basicmac OTAA example, when not transmitting.

    Running the code you linked on github, I get the following:

    SUPPLYSRC 0x1

    BLE Buck is enabled

    SUPPLYSTATUS 0x1

    SIMO Buck is ON

    LDO is supplying the BLE/Burst power domain

    Can these be turned off in software?

    no… needs to happen BEFORE reset. The BLE BUCK was used with some Apollo3A but is not connected to the new Apollo3. The SIMO is not used as the LDO is providing the power(when turned on). The current Apollo3 boards do not have an external Inductor. That said, I don’t know about the internals NM180100. Reading the datasheet there is no mention of this.

    How is this for the other peripherals? Are they now turned off?

    The peripherals turned on when running the example:

    DEVPWREN 0x180
    	UART0 is set on
    	UART1 is set on
    
    DEVPWRSTATUS 0xE0000007
    	MCUL (DMA and Fabrics) is set on
    	MCUH (ARM core) is set on
    	HCPA (IOS,UART0,UART1) is set on
    

    The UART definitely gets turned off. Due to the TX LED being on, I don’t notice a reduction in the consumption. Do you by any chance have a sketch that I can try? Maybe I’m doing something wrong.

    Use the standard Exampl6 low-power sketch. I have attached it and added LMIC_shutdown and BLE.end() to go to sleep (just to be sure).

    Make sure to use ArduinoBLE V1.3.4 (there is a problem with V 1.3.3)

    The fact that you see UARTO and UART1 is because you had to enable UART0 to get the output. In that case, the HCPA power group is enabled that feeds power to IOS, UART0 and UART1

    Example6_LowPower_Alarm_Lmic_BLE.zip (2.14 KB)

    Thank you Paul. Executing without BLE reduces the current consumption to about 582 µA. Executing with BLE (adding BLE.begin() in setup(). Because without it, I get a hardfault), the current consumption fluctuates quite a bit but it also stays around 582 µA in sleep. It seems the RTC timer is not respected.

    I don’t know if the current consumption can be lowered any further?

    Many thanks for your help!

    which version of the Apollo3 library do you use ? V2.x or V1.x?

    I’m using V2.x

    The reason for asking is because :

    1. ArduinoBLE is crashing (which is only supported on V2) Never had ArduinoBLE crash on me with a hardfault.

    2. The RTC.setalarm time order changed between V1 and V2, hence you will get a different experience (it looks it is not working):

    v1:setAlarm(uint8_t hour, uint8_t min, uint8_t sec, uint8_t hund, uint8_t dayOfMonth, uint8_t month)

    V2 : setAlarm(uint8_t hund, uint8_t sec, uint8_t min, uint8_t hour, uint8_t dayOfMonth, uint8_t month)

    Else I would not know what else you can do to reduce power consumption.

    I assume you have no other devices connected to the board, then maybe it is because of the SX1262… but i can not test as I don’t have one.

    edit : also have a look at this post… https://forum.sparkfun.com/viewtopic.php?f=169&t=58873.

    The hardfault only occurred because BLE was not initialized, which I guess is the normal behaviour?

    From the post you linked, I tried the code to see if BLE is turned off and it gets turned off:

    BLE test
    Before: 0x0
    After begin(): 0x1
    After end(): 0x0
    

    But it seems whether it gets turned off or not does not have an influence on the current consumption (in the low power alarm example)

    Adding ```
    am_hal_ctimer_stop(7, AM_HAL_CTIMER_TIMERB);

    
    Concerning the RTC, the alarm interrupt occurs after 10 seconds the first time but then increases to a minute. Is this normal?
    
    

    SparkFun RTC Low-power Alarm Example
    Alarm interrupt: 2020-6-3 12:59:50.0
    Alarm interrupt: 2020-6-3 13:0:0.1
    Alarm interrupt: 2020-6-3 13:1:0.1
    Alarm interrupt: 2020-6-3 13:2:0.1
    Alarm interrupt: 2020-6-3 13:3:0.1
    Alarm interrupt: 2020-6-3 13:4:0.1
    Alarm interrupt: 2020-6-3 13:5:0.1

    
    Indeed there are no other devices connected to the board, so it's strange that even in low power mode, the consumption is that high.

    am_hal_ctimer_stop(7, AM_HAL_CTIMER_TIMERB);

    aaahh I forgot about the am_hal_ctimer_stop () I have changed the ArduinoBLE library as the timer is not needed at all for the Apollo3 BLE driver. Sorry for that.

    Concerning the RTC, the alarm interrupt occurs after 10 seconds the first time but then increases to a minute. Is this normal?[/i]
    yes. The alarm is set to trigger on the minute change. As the time at start is set as 12.59.50 it will take 10 seconds to get to 13.00.00 (the alarmtime). From there it will take a minute to the next
    The alarm is set to trigger on the minute change.
    On the power consumption, I hope someone else who has this board can give it a try and let you know.
    just a last point, even if you can get the power consumption lower, there is still the issue with recovery SPI during wakeup. See the document in the earlier powercntrl link.