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

ESB on nRF52 SDK11: not sending ACK payloads

I'm trying to set up an ESB PRX on an nRF52 that has to communicate with an nRF24L01 chip acting as PTX. Because I want to react to the received data as quickly as possible, I tend to call nrf_esb_flush_tx() before writing a new payload into the TX FIFO via nrf_esb_write_payload().

I noticed that transmission of any ACK payload beyond the first one seem to fail. In nrf_esb.c, I stumbled on the following piece of code in the on_radio_disabled_rx() handler:

// Pipe stays in ACK with payload until TX fifo is empty
// Do not report TX success on first ack payload or retransmit
if (p_pipe_info->m_ack_payload != 0 && !retransmit_payload)
{
    if(++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE)
    {
        m_tx_fifo.exit_point = 0;
    }

    m_tx_fifo.count--;
    // ACK payloads also require TX_DS
    // (page 40 of the 'nRF24LE1_Product_Specification_rev1_6.pdf').
    m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK;
}

This code seems to be at least part of the cause for my problem. I don't really understand what is supposed to happen here. The m_ack_payload flag is set when there is at least one entry in the m_tx_fifo (immediately after the above snippet). The flag seems to only be reset if either on_radio_disabled_rx() is called while the TX FIFO is empty or if the ESB driver is initialized or disabled. This leads to the above code being executed when receiving the second ESB packet. Because in the meantime, the FIFO has been flushed, incrementing the FIFO exit point will make the current TX payload be an invalid payload.

According to the referenced page 40 in nRF24LE1_Product_Specification_rev1_6.pdf, the TX_DS event is only relevant for a PTX after receiving an ACK payload. Since on_radio_disabled_rx() is called on the PRX side, I don't see, why a TX success event has to be generated here.

In my opinion, a cleaner solution would be to always increment the FIFO exit point after the FIFOs contents have been copied to the current TX payload buffer in on_radio_disabled_rx().

I'm sure there is a good reason for the above code to exist, so I'd be happy if someone could clarify why this is needed and what would go wrong if I removed it and instead called tx_fifo_remove_last() after copying the current FIFO exit point data to the actual TX buffer.

Parents Reply
  • Well, I just made a buffer for each pipe which holds the ACK-Payload for the respective pipe, and created two additional functions to access this buffer externally.

    uint32_t nrf_esb_preload_ack(uint8_t pipe, const uint8_t *p_data, uint8_t len);
    uint32_t nrf_esb_flush_ack(uint8_t pipe)

    Last but not least, I had to modify on_radio_disabled_rx to use my ACK-payload buffer instead of the original FIFO. Unfortunately, I can't share this code as I had to do a tonne of additional modifications to the ESB-library for it to properly work in my scenario-

Children
No Data
Related