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.