RSL10 Eddystone with wake-up


We want to use the RSL10 to send 10 eddystone packages every wake-up trigger.

→ Wake-up → eddystone 10x → sleep
→ Wake-up → eddystone 10x → sleep
→ Wake-up → eddystone 10x → sleep

We use:

  • IDE [2019-06(4.12.0)]
  • RSL10-001GEVB
  • Energy Harvesting Bluetooth Low Energy Switch Eddystone Firmware example (from the energy harvesting switch)

Got this working but we still get a wakeup every 30-32S ± and don’t see where this comes from (tried RTC disable etc but doesn’t seem to work), so we get periodical wake-ups from an unknown source.

We notice that this wakeup behaviour is related to: Peripheral_server_sleep Example

1 Like

Hi Thomas

This timer cannot be disabled while the BLE hardware is initialized due to time keeping purposes.
The BLE needs to wake up to update its internal time reference as we are limited by 32-bit hardware counter in deep sleep.
I typically use this as a watchdog during deep sleep so I can make sure that device wakes up if expected external wake-up does not occur.

From your description you do not seem to need the long term time keeping or RTC so the wake-ups can be disabled during your sleep phase.
Assuming this you can enter deep sleep with external DIO wake-up configuration with no RAM retention and no low power oscillators while waiting for your wake-up signal.

The diagram below shows the application cycle with this approach:

The code for APP_EnterFlashSleep could be based on below code snippet.
This is adapted from the sleep_RAM_retention example in a more condensed form.

void APP_EnterFlashSleep(void)
    struct sleep_mode_flash_env_tag power_down_sleep_env;

    /* Clear all reset flags. */

    /* Set wake-up configuration.
     * Button DIO is the only active wake-up source.
     * Wake-up on falling edge -> button press.
    power_down_sleep_env.wakeup_cfg = WAKEUP_DELAY_32              |
                                      WAKEUP_WAKEUP_PAD_RISING     |
                                      WAKEUP_DCDC_OVERLOAD_DISABLE |
                                      WAKEUP_DIO0_FALLING          |
                                      WAKEUP_DIO1_FALLING          |
                                      WAKEUP_DIO2_FALLING          |

    /* Set wake-up mode for boot from flash.
     * Pad retention must be enabled to provide internal pull-up to the button
     * DIO.
    power_down_sleep_env.wakeup_ctrl = PADS_RETENTION_ENABLE         |
                                       BOOT_FLASH_APP_REBOOT_DISABLE |
                                       BOOT_FLASH_XTAL_DISABLE       |
                                       WAKEUP_DCDC_OVERLOAD_CLEAR    |
                                       WAKEUP_PAD_EVENT_CLEAR        |
                                       WAKEUP_RTC_ALARM_CLEAR        |
                                       WAKEUP_BB_TIMER_CLEAR         |
                                       WAKEUP_DIO3_EVENT_CLEAR       |
                                       WAKEUP_DIO2_EVENT_CLEAR       |
                                       WAKEUP_DIO1_EVENT_CLEAR       |

    /* Disable memory retention. */
    power_down_sleep_env.mem_power_cfg = 0;
    power_down_sleep_env.VDDMRET_enable = VDDMRET_DISABLE_BITBAND;

    /* Disconnect logic from power supply. */
    power_down_sleep_env.VDDCRET_enable = VDDCRET_DISABLE_BITBAND;

    /* Disconnect baseband timer from power supply. */
    power_down_sleep_env.VDDTRET_enable = VDDTRET_DISABLE_BITBAND;

    /* Disable Base Band timer. */

    /* Disable RTC. */

    /* Disable low power oscillators. */

    /* Disable Clock Detection. */

    /* Load sleep configuration onto ACS registers and enter sleep. */

The line with ACS_BB_TIMER_CTRL->BB_TIMER_NRESET_ALIAS = BB_TIMER_RESET_BITBAND; is where this periodic wake-up is disabled (well, if we kept the low power oscillator running afterwards).

Hope this helps,

Thank you for this very detailed info! We will check this now!

Hi @lukas.mandak and @thomas

I am using the peripheral_server_sleep_ext and I found also the current spikes every 30 seconds when I have the deep sleep mode running.

I’d tried to extend this time to 20 minutes with BLE_Sleep_MaxDuration_Set function like says in this thread Peripheral_server_sleep Example - #4 by lukas.mandak. But it doesn’t works.

In fact this deep sleep time configuration should be infinite because the requirements of the project I am working (we don’t know the period of sending data)

Also I’d tried to configure the system like @lukas.mandak suggested but it make that the system can’t wakeup successfully.

Could you kindly help me to configure my project? What would you do in this situation?

Thank you very much,

Enric Puigvert

Hi @epuigvert

Can you specify at which part does the program stop working?

One problem I had initially was that I did not ensure that DIO Pad Retention is disabled in my regular initialization code in Device_Initialize.
This caused failure after RSL10 woke up, cause DIO were not accessible after sleep when execution started from Flash as normal.

Hi @lukas.mandak,

First, I am sorry for my late response.

I configure like you said in this thread on the post I cite you. What I can see is that when I disable the FLASH boot and xtal with the configuration of wakeup_ctrl it never wakeups.

My theory about this is that I need the flash memory because I am doing an application with peripheral_server_sleep_ext which I understood that needs to save some configurations from BLE stack to not loose the connection parameters (it is that correct? I am not very sure about it).

Also I have a doubt: I saw that you use sleep_mode_flash_env_tag struct for the configuration of the sleep mode. In peripheral_server_sleep_ext I saw that it is used sleep_mode_init_env struct and also the sleep_mode_env->wakeup_ctrl struct. Which are they differences? Which I should use if I need that system only wakes up by DIO0 rise pulse and I need to maintain it into sleep mode by large amounts of time (minimmum 15 min)

I apreciate your suggestions,

Thank you very much

Enric Puigvert

Hi @epuigvert

If you use the listed code as is then that pretty much shuts down the RSL10.
I use it for power down mode (transport) and the only way to wake up is reset by toggling NRESET, which is fine for me as I have reset button available.

If you want to be able to wake up you need to modify the power_down_sleep_env.wakeup_ctrl to enable wake-up on one of the 4 DIO pads and also configure the DIO pad as DIO_MODE_INPUT before entering sleep. Or use the WAKEUP pad directly.

If you need to wake-up at specified time then you need to modify to keep the XTAL32K and RTC running and enable RTC Alarm. I did not try flash sleep with this configuration yet.

That said the Flash wake-up is pretty much reset that retains the state of DIO pads.
So no data or BLE configuration is retained.
Ideally only the knowledge of the reset source (DIG status, ACS wakeup status) should be all you need to know to resume your application as nothing else is available.

The structures and Sys_PowerModes_Sleep_* functions represent two specific use cases of sleep mode, so they contain only parameters relevant to them.
Flash mode does not use the init structure or function cause it assumes you need to restart BLE after wake up so no backup of BLE registers is made.

Best regards,

Hi @lukas.mandak,

Thank you very much for your answers,

I see what you say. Then I would like to ask you how could I configure sleep_mode_init to maintain BLE Stack active (to not loose my BLE configurations) but also disable the RTC Alarm to make disable the periodic wakeups my Peripheral Device is doing.
Could you give some advice about it?

Thank you very much

Enric Puigvert

Hi Enric,

I think both approaches are equally usable for your purposes.
The main deciding factors I see are power consumption and latency after wake-up.

  • Flash sleep - lower power consumption since no RAM is retained, longer wake-up time
  • peripheral_server_sleep_ext approach - larger power consumption due to RAM retention, faster wake-up time

I think exactly this is done in the peripheral_server_sleep_ext example.
RTC is configured separately from BLE (they just use the same clock while in deep sleep) and RTC Alarm is disabled in the example code.


Hi again @lukas.mandak,

Thank you for your response.

I’d been working on peripheral_server_sleep_ext and after 30 seconds from transmitting I see a peak of current periodically. You can see this behavior in the graph below:

Seeing this I’d tried to configure ACS CFG and CTRL like this:

sleep_mode_init_env.wakeup_cfg = WAKEUP_DELAY_32          |
                                         WAKEUP_WAKEUP_PAD_RISING |
    									 WAKEUP_DIO0_RISING		  |
                                         WAKEUP_DIO3_DISABLE      |
                                         WAKEUP_DIO2_DISABLE      |
                                         WAKEUP_DIO1_DISABLE      |

sleep_mode_env->wakeup_ctrl = PADS_RETENTION_ENABLE         |
                                  BOOT_FLASH_APP_REBOOT_DISABLE |
                                  BOOT_CUSTOM                   |
                                  WAKEUP_DCDC_OVERLOAD_CLEAR    |
                                  WAKEUP_PAD_EVENT_CLEAR        |
                                  WAKEUP_RTC_ALARM_CLEAR        |
                                  WAKEUP_BB_TIMER_CLEAR         |
                                  WAKEUP_DIO3_EVENT_CLEAR       |
                                  WAKEUP_DIO2_EVENT_CLEAR       |
                                  WAKEUP_DIO1_EVENT_CLEAR       |

But it doesn’t work. I am missing somethink… What do you think?

Best regards,

Enric Puigvert

Hi @epuigvert

The example is set up to transmit certain amount of advertising packets with deep sleep in between.
After 100 packets the advertising is cancelled and the long term sleep with timer gating is enabled.

Maybe you do not set the feature on as I see only 1 packet after power on?
See GAPM_CmpEvt handler in ble_std.cwhich enables the bb_timer_bypass after the advertising operation is cancelled.

        case (GAPM_ADV_NON_CONN):
            if(param->status == GAP_ERR_CANCELED)

                /* Go to the ready state */
                ble_env.state = APPM_READY;

                /* Reset the number of completed Advertising events */
                adv_cnt = 0;

                /* Enable BB timer bypass */
                bb_timer_bypass = BB_TIMER_BYPASS_ENABLED;


ADV_CNT_MAX macro in app.h controls the number of packets before bypass is enabled.

Best regards,

Hi @lukas.mandak

The reason to see only 1 packet after power on is that there is a central client which connects instantly with peripheral server. So it pass directly to the connected state.

Also, I made an if condition to eliminate the advertising after a disconnection is done to try to achieve in the minimum time the deep sleep mode. This is why you only see a single interval before the connection begin.

My issue is with the spikes I have in 35 secs and 93 secs where should be in deep sleep mode and not consumming ~1.5mA. It is very important for my ultra low power requirements.

How could eliminate them?

Thank you very much for your suggestions

Enric Puigvert