All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Enhanced ShockBurst User Guide


This user guide describes what Enhanced ShockBurst (ESB) is and how to use it with an nRF51 device.

Enhanced ShockBurst (ESB) is a basic protocol supporting two-way data packet communication including packet buffering, packet acknowledgement, and automatic retransmission of lost packets.

The ESB protocol was embedded in hardware in the legacy nRF24L Series. The nRF51 ESB software library enables an nRF51 device to communicate with an nRF24L device using the ESB protocol.

ESB features automatic packet transaction handling for easy implementation of a reliable bi-directional data link. A transaction is a packet exchange between two transceivers, with one transceiver acting as the Primary Receiver (PRX) and the other transceiver acting as the Primary Transmitter (PTX).

ESB is provided for customers who want to communicate with nRF24Lxx products. We recommend using Gazell for new nRF51 proprietary radio designs as Gazell achieves superior wireless coexistence performance without sacrificing power consumption, code space, or ease of use.

Enhanced ShockBurst network


  • Supports a star network topology with typically one Primary Receiver (PRX) and up to 8 Primary Transmitters (PTX).
  • 1 to 32 bytes dynamic payload length.
  • Bi-directional data transfer between each PTX and the PRX.
  • Packet acknowledgement and automatic packet retransmission functionality.
  • Individual TX and RX FIFOs for every pipe.
  • Backward compatible with legacy nRF24Lxx Enhanced ShockBurst.


ESB makes use of a fixed set of resources and requires exclusive access to them for ESB to ensure correct operation. There are two options for what set of resources to be used:

  1. esb_arm.lib
  • Radio (NRF_RADIO)
  • Timer: NRF_TIMER2)
  • PPI channels 0, 1, and 2
  • Software interrupt 0
  1. esb_sd_resources_arm.lib (reusing the same resources used by the S1xx Bluetooth Smart softdevice library from Nordic):
  • Radio (NRF_RADIO)
  • Timer: NRF_TIMER0)
  • PPI Channels 8, 9, and 10
  • Software interrupt 1

Note: There is no MPU enforcement of this exclusive access, so manipulating these resources will give undefined behavior.

The radio and timer interrupt handlers run at priority level 0 (highest level), and the ESB callback functions run at priority level 1. Other interrupts used by the application must use priority level 2 or higher to ensure correct operation.

Backwards Compatibility

ESB for nRF51 supports the following minimum timeslot periods:

  • 600 us timeslot period, nRF51 PTX to nRF51 PRX.
  • 504 us timeslot period, nRF51 PTX to nRF24Lxx PRX.

When using 504 us timeslot period, the following restrictions apply:

  • Max payload size is 17 bytes
  • Max ack payload size is 10 bytes

The nRF24Lxx ESB examples found in the legacy nRFgo SDK do not work out of the box with the nRF51 ESB examples. The retransmit delay and channel tables require the following adjustment:

  • The legacy examples use RF channel 2 (not 10 as the nRF51 examples).
  • The legacy examples do not use "payload in ACK" or dynamic payload length.

The legacy examples need to add the following in order to work with the nRF51 examples. In addition, the legacy PTX example must add code for handling the payloads received in ACK.


Packet transaction

An Enhanced ShockBurst packet transaction is initiated by a packet transmission from the PTX and successfully completed when the PTX has received an acknowledgment packet (ACK packet) from the PRX.

To enable a bi-directional data link the PRX is allowed to attach a data payload to the ACK packet. This can be done by uploading packet(s) to the TX FIFO(s) on the PRX.

PTX to PRX packet transaction

If the PTX does not receive the ACK after the initial transmitted packet, it will attempt to retransmit the packet until the ACK is finally being received. The maximum number of allowed retransmission attempts are specified by the nrf_esb_set_max_number_of_tx_attempts() function, and the delay in between each transmission attempt is specified using the nrf_esb_set_retransmit_delay() function.

The retransmission delay is defined as the duration between the start of each transmission attempt. Note that this differs from the legacy nRF24L Series hardware implementation, where this delay was defined as the duration from the end of a packet transmission until the start of the retransmission.

If the ACK packet sent from the PRX to the PTX is lost, but both the initial packet and the subsequent retransmission attempts are being successfully received by the PRX, the repeated packets will be discarded by the PRX. This prevents the PRX application from receiving duplicate packets.

Note: Repeated packets will always be ACKed by the PRX even though they are being discarded.

Failed package transaction.

A PTX can select that individual packets transmitted to the PRX will not require an ACK to be sent in return from the PRX. This decision is taken by the application when uploading a packet to the TX FIFO using the packet_type parameter of the nrf_esb_add_packet_to_tx_fifo() function.

When the PRX receives a packet not requiring an ACK it will not send an ACK packet to the PTX, and as a result the PTX will continue retransmitting the packet until the maximum number of allowed retransmission attempts is reached.

Setting up an ESB application

Perform the following steps to set up and send and receive packets:

  1. Initialize ESB using nrf_esb_init().
  2. Reconfigure the ESB default parameters if needed.
  3. Enable ESB using nrf_esb_enable().
  4. If the node is a PTX, start sending:
  5. If the node is a PRX, start listening:
    • Handle the received data packets when the nrf_esb_rx_data_ready() callback is called. The received packets are fetched from the RX FIFO using the nrf_esb_fetch_packet_from_rx_fifo() function.
    • Payloads to can be attached to ACK packets by adding these to the TX FIFO using nrf_esb_add_packet_to_tx_fifo(). If an ACK payload is assumed successfully received by the PTX, that is when a new packet sent from the PTX is received by the PRX, the nrf_esb_tx_success() callback will be called and the sent packet is automatically removed from the TX FIFO.

ESB can also be disabled at any time using the nrf_esb_disable() function. When this is called ESB will complete any ongoing transaction before being disabled. When any ongoing transaction is completed and ESB has been disabled, the nrf_esb_disabled() callback will be called.

Frequency selection

ESB can send or receive packets using any of the channels that the nRF51 chip can use as selected by using the function nrf_esb_set_channel().

PTX and a PRX must be configured using the same frequency to exchange packets.

Pipes and addressing

Each logical address on the nodes is termed a pipe. Each pipe maps to one on-air address used when transmitting or receiving packets.

The on-air addresses are composed of a 2-4 byte long "base address" in addition to a 1 byte prefix address. Note that the nRF51 radio uses an alternating sequence of 0s and 1s as the preamble of the packet. Therefore, for packets to be received correctly, the most significant byte of the base address should not be an alternating sequence of 0s and 1s, that is, it should not be 0x55 or 0xAA.

Pipe 0 has its own unique base address, which is base address 0, while pipes 1-7 use the same base address, which is base address 1.

Each of the 8 pipes have a unique byte-long prefix address.

On-air, the most significant bit of each address byte will be transmitted first. The most significant byte of the 4 byte long base address is the first transmitted address byte, while the prefix byte is transmitted last.

Note: The byte ordering in ESB and the nRF51 radio peripheral are not the same, this is because the address bytes are rearranged in ESB to match the nRF24L radios.

Packet identification

Any packet transmitted from a PTX to a PRX is uniquely identified by a two-bit packet ID field (PID) in the packet header together with the packet's Cyclic Redundancy Check (CRC) field. This packet ID is used to distinguish a new packet from the previous packet if it has the same payload.

At the PRX, retransmitted packets will be discarded and not added to an RX FIFO. The nrf_esb_rx_data_ready() will not be called.

The CRC is used in addition to the PID to identify a unique packet. This reduces the likelihood of a packet being falsely identified as a retransmission attempt and discarded by the PRX when several consecutive failed packet transmission attempts occur. This feature is helpful as the PID is only two bits.


All eight pipes on both the PTX and the PRX have two multi-level FIFOs that can hold packets, that is, each pipe's TX FIFO and RX FIFO. For example, the total number of packets in the FIFOs is 6, while every individual TX or RX FIFO (8 pipes x 2 = 16 in total) can store 3 packets.

PTX FIFO handling

When ESB is enabled in PTX mode, any packets uploaded to a TX FIFO will be transmitted at the next opportunity. For one TX FIFO the packets will be transmitted in the same order as they were written to the FIFO. But several TX FIFOs will be serviced in a round robin fashion, meaning that only one packet is transmitted from a FIFO before a packet from the next FIFO is transmitted.

When an ACK is successfully received from a PRX, it implies that the payload was successfully received and added to the PRX's RX FIFO, the successfully transmitted packet will be removed from the TX FIFO so that the next packet in the FIFO can be transmitted.

If an ACK received by a PTX contains a payload, this payload will be added to the pipe's RX FIFO.

If the RX FIFO for a specific pipe on a PTX is full and can not accommodate any new packets, no new packets will be sent from the PTX on this pipe. In this case, we will never end up in the situation where a payload received in an ACK will have to be discarded due to the pipe's RX FIFO being full.

PRX FIFO handling

When ESB is enabled in PRX mode, all enabled pipes (addresses) are simultaneously monitored for incoming packets.

If a new packet not previously added to the pipe's RX FIFO is received, and the pipe's RX FIFO has available space for the packet, the packet will be added to the RX FIFO and an ACK will be sent in return to the PTX. If the pipe's TX FIFO contains any packets, the next serviceable packet in the TX FIFO will be attached as a payload in the ACK packet. In order for a TX packet to be attached to an ACK, this TX packet would have to be uploaded to the TX FIFO before the packet is received.

PRX cannot ensure that the ACK will always be successfully received by the PTX, the data payload added to the ACK will not be removed from the TX FIFO immediately. This TX packet will be removed from the TX FIFO when a new packet (new packet ID or CRC) is received on the same pipe. In this case, the new packet sent as an ACK will serve as an acknowledgment from the PTX saying that the previous ACK from the PRX was successfully received by the PTX. ACKs sent in reply to retransmission attempts will all contain the same TX payload.

Callback queuing

ESB contains an internal callback queue for queuing pending callbacks. This allows the application to queue callback functions while the application is already servicing a previously called callback function. In addition, this allows the ESB process to function uninterrupted.

For example, if a new packet is being received while the application is already servicing the nrf_esb_rx_data_ready() callback from a previously received packet, the nrf_esb_rx_data_ready() callback for the latest packet will be added to the callback queue and serviced at a later opportunity. In this case, nrf_esb_rx_data_ready() will be called one time for every received packet, and the application does not need to handle the potential race condition scenario where a new packet is being received just before the application is about to exit the nrf_esb_rx_data_ready() function.

Similarly, ESB will call the nrf_esb_tx_success() once for every transmitted packet, even when a new packet is being transmitted while the application is servicing the nrf_esb_tx_success() callback of a previously transmitted packet.

The callback queue can hold up to 10 pending callback functions.