So what you’re implying is that it is not possible to get to the 25nA sleep mode advertised on page 1 of the datasheet if I use the radio/kernel, right? The peripheral_server_sleep_ext is not a particularly easy read, either. I take it that the ‘bb_timer_bypass’ variable is determining whether the radio is shut down or not? Also the fact that you’ve got Sys_PowerModes_Sleep as a weak symbol that’s also defined in library code is pretty nasty. This example willy happily link and not run if I rename that function in the example code. And Sys_PowerModes_Sleep must be getting called from ROM somewhere too, right?
Second question: EXACTLY how does one disable RAM retention to get to the 40nA sleep? Just setting sleep_mode_env->mem_power_cfg to zero in Sleep_Mode_Configure() does not appear to work.
The question stands – I thought I had configured sleep_mode_env->mem_power_config as zero and was incorrect. So I do need to know how to disable RAM retention in that example.
More information: For my medical application, I don’t want to immediately turn on the radio. I want to enable the radio on command from the controlling processor, advertise at a high rate for a length of time, advertise at a low-power, low-rate for a length of time, and finally turn completely off. The power scheme implemented in these examples are difficult to break apart into the pieces needed for my application. It looks like you have to start the kernel to get any interrupts into the application. So I first need to just start up, start the kernel so I can get serial port and other interrupts, and then possibly go into deep sleep. Fighting this example code into something like this is a real pain.
I’m getting very tired of trying to find this. Exactly where in your example is the watchdog being disabled?
You are correct, when using the BLE Stack it is not possible to achieve the 25nA due to the RAM Retention used to retain the BB register settings during Sleep. It is possible to remove this retention and you can get much closer to the 25na (usually ~50nA), but this will incur a relatively massive increase to the wakeup time (>100ms in active mode) that is required to reconfigure the BLE Stack and BB registers. This extra time and current is magnitudes larger than the current consumption used when running sleep mode at 50nA vs 160nA.
You are also correct about the ‘bb_timer_bypass’ variable. It will be used to decide if the desired number of ADV have been sent out, and will then allow the device to go into Deep Sleep instead of the BB/BLE Sleep. In this case though, the memory retention is still required (and therefore you will see the ~110nA Deep Sleep current) to enable a quick wakeup and BB settings restoration.
This weak symbol was a work-around to enable this Deep Sleep/BLE Sleep functionality to co-exist at the Application level. Originally, the Deep Sleep and BLE Sleep were assigned their own respective library functions that could be used to enter the Sleep mode. When you are trying to use both in the same application, it becomes necessary to change how this Library code behaves due to function dependencies. To get around having to make the entire BLE Sleep Library into external source code, this compromise was made. The ‘Sys_PowerModes_Sleep’ function is called within the ‘BLE_Power_Mode_Enter’ library code, which is where these dependencies arise.
I would be perfectly happy to take the 100ms hit, my product is an implantable medical device with a small battery.
Just fyi, the last time I went to the trouble of merging example code to implement the “light stack”, I discovered that the hard-coded heap sizes for the light stack are too small to support high-security bonding – that you run out of memory and there’s nothing you can do. Also not good for an implantable.
I’m still seeing the watchdog go off as I try to modify my application to do what the peripheral_server_sleep_ext is doing. It’s ridiculous that I have to try calling into binaries and ROM code to figure this out. Note that I can’t use the debugger because of the power modes I’m cycling through. Why isn’t there a specific set of instructions to shut down the radio somewhere in the documentation? Surely there are specific steps that can be followed to do this. What are they?
For that matter, there should be a way to adjust the sizes of the three or four heaps you implement for the kernel, and there should be an exposed API to monitor them. Otherwise you need to reverse them, which is doable but a pain (and I’ve done that).
EXACTLY how does one disable RAM retention to get to the 40nA sleep?
Memory retention can be changed by altering the ‘mem_power_cfg’ & ‘mem_power_cfg_wakeup’ variables within the ‘sleep_mode_init_env_tag’ structure of the ‘Sleep_Mode_Configure()’ function. It should be noted that the ‘Sys_PowerModes_Sleep_Init()’ & ‘Sys_PowerModes_Wakeup()’ functions used in our ‘peripheral_server_sleep_ext’ sample make use of this structure to enable the automatic restoration of the BB Registers using the DMA and RAM Retention. Removing RAM retention and attempting to use these functions will likely not behave as expected. In this case, the entire BB should be shut down and the ‘Sys_PowerModes_Sleep_WakeupFromFlash()’ function should be used instead (this will require a full reconfiguration of the BLE stack and no memory will be retained).
Exactly where in your example is the watchdog being disabled?
This is not directly performed anywhere in the code. When the device enters Sleep or Standby modes, the CM3 processor is not longer in a state where it will increment the Watchdog Reset timer or acknowledge any interrupts. This is why you will not see any Watchdog Resets during Sleep or Standby operation. If you are trying to disable the Watchdog while is active/running mode, please refer to Section 12.4 in our RSL10 Hardware Reference.
Surely there are specific steps that can be followed to do this. What are they?
Unfortunately, most of the BLE specific processing and variables required to properly configure the device for BLE Sleep in contained within the Library code and cannot be accessed at the Application level to perform the exact same steps. This has been abstracted into the single ‘BLE_Power_Modes_Enter()’ function for simplicity. As general guidelines, you should ensure that: no BLE operations are occurring (advertising or an active connection), the BB has been disabled, and that no residual BLE sleep setup is being executed by the firmware, before you attempt to put the device into Deep Sleep mode.
The issue turns out to have been the line
ACS_RTC_CTRL->ENABLE_ALIAS = RTC_DISABLE_BITBAND;
that I had added to shut the RTC off when trying to power down. The sleep code examples must leave this enabled to work.
To summarize for anyone else trying to cycle through multiple power modes on the RSL10, here’s the summary:
- The RSL10 firmware does not support 25 nA Deep Sleep, I/O Wakeup mentioned in the datasheet.
- If you want to use secure bonding (anything more than just works), the RSL10 does not support the 40 nA Deep Sleep, Active External 32 kHz oscillator mentioned in the datasheet because heap sizes in the light version of the kernel are hard coded and too small to support secure bonding.
- The watchdog is DISABLED in deep sleep mode.
- Use the peripheral_server_sleep_ext example for power modes if you need the RSL10 in a sleep mode that’s essentially off for extended periods of time and don’t disable ACS_RTC_CTRL->ENABLE_ALIAS.