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

Gzll fifo handling

To the kind attention of Nordic support team,
I have been putting to the test a scenario where three devices are used: one gzll host and two gzll devices. When devices are transmitting both at the same time a continuous input data stream towards the host, it happens that one of devices suddenly stops and it is not able to communicate anymore (it could be device A or device B that is not able to communicate, it is not always the same that stops). It appears that problem is in the host handling of pipes' fifo. And by doing an host reset, devices are indeed able to start communicating again, without resetting them too. Host is sending a custom ack to device A and is receiving crypto messages from device B. It seems the fifo level is always about 4-5, and this, occasionally, create the problem. When fifo level is about 2 neither of devices stop transmitting correctly to the host. So in an rtos thread that is elaborating gzll, I put a check like this(the one you can see below) to control fifo occupation level, and to flush any time that level is equal, more than two.This approach is somehow ok for me. It seems that host remains always able to receive from both devices. I would like to ask if this approach may have some inconvenience that I'm missing. It seems to be the simplest one, at least in my situation. May have please your suggestion about that? What can prevent to receive from a device? My goal it is here to avoid a situation where host cannot receive from a device anymore. From tests I did, I also saw that performance of both devices is dramatically going down when using them at the same time with data transmission at the higher rate possible, inside a test loop. I don't know if there is a way to better set radio timing parameters to mitigate what I saw, but it appear clear to me that ESB must be used as a building block for customized high speed transmission schema. Having said that, it seems that considering physical radio limitations a reasonable high speed schema should permit two devices transmitting every let's say about 500[us] * 2 each.

Other than the following check, I also used in the host this routine nrf_gzll_ok_to_add_packet_to_tx_fifo so to do a flush when I got an error, but it seems that it is not enough to do a flush when nrf_gzll_ok_to_add_packet_to_tx_fifo is returning an error. Maybe it is already too late.

I used this check with n=2 ant it seems to be ok for me, but I'm waiting to better understand if it may be a valid thing to do:

void gzllCheckRxFifo(uint8_t n){
if((nrf_gzll_get_rx_fifo_packet_count(0)+
nrf_gzll_get_rx_fifo_packet_count(1)+
nrf_gzll_get_rx_fifo_packet_count(2)+
nrf_gzll_get_rx_fifo_packet_count(3)+
nrf_gzll_get_rx_fifo_packet_count(4)+
nrf_gzll_get_rx_fifo_packet_count(5)+
nrf_gzll_get_rx_fifo_packet_count(6)+
nrf_gzll_get_rx_fifo_packet_count(7))>= n)
{
nrf_gzll_flush_rx_fifo(0);
nrf_gzll_flush_rx_fifo(1);
nrf_gzll_flush_rx_fifo(2);
nrf_gzll_flush_rx_fifo(3);
nrf_gzll_flush_rx_fifo(4);
nrf_gzll_flush_rx_fifo(5);
nrf_gzll_flush_rx_fifo(6);
nrf_gzll_flush_rx_fifo(7);
#ifdef MY_UART_ENABLED
SerialDebugString("gzllCheckRxFifo\r\n");
#endif
}
}

void gzllCheckTxFifo(uint8_t n){
if((nrf_gzll_get_tx_fifo_packet_count(0)+
nrf_gzll_get_tx_fifo_packet_count(1)+
nrf_gzll_get_tx_fifo_packet_count(2)+
nrf_gzll_get_tx_fifo_packet_count(3)+
nrf_gzll_get_tx_fifo_packet_count(4)+
nrf_gzll_get_tx_fifo_packet_count(5)+
nrf_gzll_get_tx_fifo_packet_count(6)+
nrf_gzll_get_tx_fifo_packet_count(7))>= n)
{
nrf_gzll_flush_tx_fifo(0);
nrf_gzll_flush_tx_fifo(1);
nrf_gzll_flush_tx_fifo(2);
nrf_gzll_flush_tx_fifo(3);
nrf_gzll_flush_tx_fifo(4);
nrf_gzll_flush_tx_fifo(5);
nrf_gzll_flush_tx_fifo(6);
nrf_gzll_flush_tx_fifo(7);
#ifdef MY_UART_ENABLED
SerialDebugString("gzllCheckTxFifo\r\n");
#endif
}
}
  • Hi,

    Your workaround seems good, but I am unsure what might trigger it yes. It seems to be related to the host based on your description.

    So based on your description it seems that calling gzp_crypt_user_data_read() / nrf_gzll_fetch_packet_from_rx_fifo() have no effect to the buffer? Or is the problem that TX buffers on the host is going full?

    Is it possible that you are writing too large packets (length field is wrong) from the host to the device?

    Best regards,
    Kenneth

  • Hi Kenneth, thank you for you kindness.

    I have got a freertos task that is doing gzll work. So, workaround is checking continuously fifo in the gzll dedicated thread loop, it is like a polling to check fifo. Not a particular trigger, in this case. This polling seems to prevent any troubles, at least in my case.

    About your second question, I'm going to check with a step by step debugging and calling  nrf_gzll_get_total_allocated_packet_count before and after reception routines, to see if I can immediately see an effect on rx fifo.

    Yes, tx buffers on the host is going to be full, at least in my case, I can get nrf_gzll_ok_to_add_packet_to_tx_fifo error printed on a serial port, and it is about that moment that host cannot communicate anymore with one of the two devices, when not using workaround. I'll try to print a more complete report using serial port, so that it can be useful to describe what happens. 

    I want to try to theoretically find a succession of events that can block communication, reading in documentation what is default tx rx behavior.

    I'll also give a look to ack lenght, as you kindly suggested and I'll update here.

    Thank you very much

Related