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

GZLL transmit fails periodically - dropping burst of packets in a row

I have a somewhat unique GZLL configuration and am running into a bug that I don't really understand.

"Maximum tx retries" is set to 1 using nrf_gzll_set_max_tx_attempts.  The reason for this is that in the case of a packet drop our application has no need to retry the old packet because by the time the retry arrives it is out of date.  We do need to know that it failed so we can send another packet with newer data right away.

When I have data to send in my application I call:
nrf_gzll_add_packet_to_tx_fifo
And monitor:
nrf_gzll_device_tx_success / nrf_gzll_device_tx_failed
To see what the result of the transmit was.
This appears to work as expected with the exception that every 600 packets or so, it hits a tx window where the next 20 or so will all fail reliably (see image from analyzer, pattern is continuous,)
This doesn't seem lik an interference or a resource interrupt issue because if I change the timeslot period it shifts when the stall occurs, linking it pretty clearly to something like "after X number of packets / timeslots " rather than "every X time interval"
Maybe someone with insight into the GZLL / gazell library could shine some light on this?  Appreciate any help.
  • Hi,

     

    Which version of the SDK are you using? I checked with my colleagues wrt. this issue, and it was mentioned that this has been observed on older SDKs (like in this thread: https://devzone.nordicsemi.com/f/nordic-q-a/11404/gazell-frame-rate-too-low/42985#42985)

     

    Kind regards,

    Håkon

  • This is a new design using SDK version 16.0.0.  This issue is our top priority, so we appreciate any other suggestions, thank you.

  • Hi,

     

    I see a "delay" (ie: no packets received) of 18,75 ms after approx. 1 second, similar as you do.

    There are two modes, in sync and out of sync, and these two have different timing parameters.

    When "in sync", and packets are lost (for instance due to drift), the default "in sync" period is 15 (shown in nrf_gzll_constants.h::NRF_GZLL_DEFAULT_SYNC_LIFETIME, note this is a reference; changing the define will not do anything, it must be set via nrf_gzll_ function).

    This means that if you lose packets, it will take 15 timeslots (9 ms) still trying to "follow" the RF channel tab that the host is using.

    When this "in sync" period has elapsed, the device is entering "out of sync", where he default time the device spends on a channel is also 15 timeslots.

     

    These two parameters will cause a delay in the case you're drifting.

    The parameter for out-of-sync is recommended to be greater than one "round trip" for the host, in your case 10 timeslots (2*5 channels):

    /**
     * @brief Set the number of timeslots that a Gazell shall
     * reside on a single channel before switching to another channel when
     * in the "out of sync" state.
     *
     * This value should be set so that the Device transmits on one channel
     * while the Host goes through a full channel rotation, i.e.,
     * channel_table_size*timeslots_per_channel.
     * This ensures that the channels on the Device and Host will coincide
     * at some point.
     * Further increasing the value has been observed to provide better performance
     * in the presence of interferers.
     *
     * @param timeslots The number of timeslots to reside on
     * each channel before channel switch.
     *
     * @retval true  If the parameter was set.
     * @retval false If Gazell was enabled.
     */
    bool nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(uint32_t timeslots);

     

    The parameter for in-sync should be set on an application-specific level, meaning it should be set per how often you send data (+ added time in case a packet is lost):

    /**
     * @brief Set the number of timeslots after a successful
     * reception of a Device or Host packet that the Gazell Link Layer shall assume
     * that the link is synchronized. A value of 0 implies that the
     * link is always out of sync.
     *
     * @param lifetime The sync lifetime in number of timeslots.
     *
     * @retval true  If the sync lifetime was set.
     * @retval false If Gazell was enabled.
     */
    bool nrf_gzll_set_sync_lifetime(uint32_t lifetime);

     

    When adjusting down the value of "in sync" period, using nrf_gzll_set_sync_lifetime(), I see that this idle time period is reduced. Could you try adjusting this down and see if you see similar behavior? Try setting a value that is asynchronous to the round trip of the host, or is equal to the round trip.

     

    Kind regards,

    Håkon

  • Thank you for this info, this is very helpful for understanding the limitations of the gzll protocol.  I will continue to play with these timings.

Related