This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Who and how wakes up CPU when BLE notification is received?

Ok, so please bear with me as I'm quite a greenhorn both in embedded world as in nRF series chips. My aim is to understand how deep sleep works. I might use wrong terminology too.

This is my current understanding:

I have one nRF chipset (does not matter which one specifically), let's call it chip Central which is bonded with another nRF, say chip Peripheral. Central is waiting for notifications on BLE service from Peripheral. In the meantime, it goes to deep sleep with sd_app_evt_wait() which calls underlying ARM's __WFI instruction.

Where it gets foggy:

Now, something from the outside world of CPU (radio circuitry?) on chip Central needs to listen all the time and when BLE signal is detected, it wakes up the CPU by turning on a pin which triggers CPU interrupt. Is this correct? But then "radio circuitry" runs all the time (or maybe in intervals?) and uses power?

I would also be glad for any hint on where to read up on this.

  • If you are in a connection it is actually the peripheral/slave that is listening for packets from the central/master. It doesn't need to listen all the time, because the master have a told the slave what connection interval to use. On every connection interval there is a connection event. RTC0 is used to keep track of when the master should transmit, and when the slave should listen. So every connection interval the master transmits a packet, and the slave listens and receives it. Then the master listens and the slave transmits a packet. One packet will be sent each way on every connection event(if the slave doesn't use slave latency). If there is no data to send, they will be empty.

    If the slave has a notification to send, it will have to wait for the next connection event, then it receives a packet from the master, and then it sends the notification.

  • No it's simpler than that.

    Your question says 'bonded' but I don't know if you mean that or just 'connected to'. Dealing with the connected case first.

    When two devices are in a connection they exchange timing information about when each connection event will start (this is all in the bluetooth spec). So all the central has to do is wake up just before that time, send out a packet and listen, then it goes back to sleep until the next event. The peripheral does likewise, except it may be allowed to skip events and only reply occasionally, so it can sleep for longer, just waking up in time to listen for the central. That ability to skip events is 'slave latency'.

    So the thing which wakes up the CPU is just a timer. Timer interrupts cause __WFE and __WFI to return and the CPU processes them.

    To complete the picture, if the devices aren't in a connection then one is advertising and one is listening. Again these are timed. The peripheral sends out some advertising packets, then goes to sleep for a defined time + a bit of randomness, then sends out the next one. Similarly the central wakes up, listens for a while on each of the channels, then sleeps for a time. It requires the central to happen to be listening when the peripheral happens to be sending advertising packets, before the devices discover each other, that's why discovery can take a long time.

    In all cases however, the softdevice knows when it's going to wake up and send, or listen, before it goes to sleep, so it just uses a timer to wake it up. Nothing is listening all the time .. this is one of the reasons that BTLE is low energy.

  • Thanks, this shed even more light on the whole procedure, especially on advertising/connecting phase.

  • Just to make sure; the interval between packets are determined by ble_gap_conn_params_t, with min and min_conn_interval, right?

Related