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

Why nRFGo Gazell "gzll_radio_isr_function()" need to modify timer period every time received TX_DS interrupt?

Hi,

I am study nRFGo Gazell now and I got confused on timer period change in gzll_radio_isr_function().

Per my understanding the Gazell link layer modify timer period every time Transmit Packet (TX_DS interrupt) successes.

Can someone help me to understand the purpose? will sync loss because of several times timer period modify?

// source code list on below 

//If "data sent" interrupt from radio
if(irq_flags & (1<<TX_DS))
{
  hal_nrf_clear_irq_flag(TX_DS);

  #ifndef GZLL_HOST_ONLY
  if(gzll_state_var == GZLL_DEVICE_ACTIVE)
  {
     gzll_timer_period_modified = 1;

     timer_mod_period = gzll_dyn_params[GZLL_PARAM_RX_PERIOD] - (gzll_dyn_params[GZLL_PARAM_RX_PERIOD_MODIFIER] +

                                                            ((uint16_t)((GZLL_CONST_BYTES_PR_PACKET * 2) + gzll_current_tx_payload_length) * GZLL_US_PR_BYTE));
     if(irq_flags & ((1<<RX_DR)))
       {
          timer_mod_period -= (GZLL_US_PR_BYTE * GZLL_INTERNAL_ACK_PAYLOAD_LENGTH);
        }

      gzll_set_timer_period(timer_mod_period);

Br,

Kenny Chien

Parents
  • Hi,

     

    This is because it modifies its local timer to match the ACK from the receiver, to ensure that any drift in oscillators will be "inherited" from the gazell host device.

    It's basically to ensure that it always hits the gazell hosts receive window, when the device is in a synchronous mode.

     

    Kind regards,

    Håkon

  • Hi Hakon,

    Thanks about the answer and I also think in this way, but because there is no timing information feedback from host.

    How can I know the timer modify could make device timer more with in host receive window?

    Br,

    Kenny Chien

  • Hi Kenny,

     

    If you look at the calculation:

    timer_mod_period = gzll_dyn_params[GZLL_PARAM_RX_PERIOD] - (gzll_dyn_params[GZLL_PARAM_RX_PERIOD_MODIFIER] + ((uint16_t)((GZLL_CONST_BYTES_PR_PACKET * 2) + gzll_current_tx_payload_length) * GZLL_US_PR_BYTE));
    if(irq_flags & ((1<<RX_DR)))
    {
      timer_mod_period -= (GZLL_US_PR_BYTE * GZLL_INTERNAL_ACK_PAYLOAD_LENGTH);
    }

    What it does here is to "backtrack" to when the ACK was sent by the host, and then use that as a timing anchor (actually; a bit before the host sends an ACK).

    If the RX period is 1008 us (default), and the RX_PERIO_MODIFIER is 410 (default), the calculation would be:

    1008 - 410 + ((9*2) + current_payload_len) * GZLL_US_PR_BYTE.

    If we assume 2 MBit mode, GZLL_US_PR_BYTE is 4 us, and a payload length of 8 bytes, the modified timer look like this:

    1008 - 410 + (18 + 8) * 4 = 702.

     

    What it does is that it rather re-sends one payload before the RX window on that specific channel is opened, than end up in a situation where you have to re-send many times until the gazell host listens on that specific RX channel.

    Lets say that you end up with one retransmit every 12 payloads now, compared to ending up retransmitting 20 times every 100 payloads, due to device and host drifting over time.

     

    Kind regards,

    Håkon

Reply
  • Hi Kenny,

     

    If you look at the calculation:

    timer_mod_period = gzll_dyn_params[GZLL_PARAM_RX_PERIOD] - (gzll_dyn_params[GZLL_PARAM_RX_PERIOD_MODIFIER] + ((uint16_t)((GZLL_CONST_BYTES_PR_PACKET * 2) + gzll_current_tx_payload_length) * GZLL_US_PR_BYTE));
    if(irq_flags & ((1<<RX_DR)))
    {
      timer_mod_period -= (GZLL_US_PR_BYTE * GZLL_INTERNAL_ACK_PAYLOAD_LENGTH);
    }

    What it does here is to "backtrack" to when the ACK was sent by the host, and then use that as a timing anchor (actually; a bit before the host sends an ACK).

    If the RX period is 1008 us (default), and the RX_PERIO_MODIFIER is 410 (default), the calculation would be:

    1008 - 410 + ((9*2) + current_payload_len) * GZLL_US_PR_BYTE.

    If we assume 2 MBit mode, GZLL_US_PR_BYTE is 4 us, and a payload length of 8 bytes, the modified timer look like this:

    1008 - 410 + (18 + 8) * 4 = 702.

     

    What it does is that it rather re-sends one payload before the RX window on that specific channel is opened, than end up in a situation where you have to re-send many times until the gazell host listens on that specific RX channel.

    Lets say that you end up with one retransmit every 12 payloads now, compared to ending up retransmitting 20 times every 100 payloads, due to device and host drifting over time.

     

    Kind regards,

    Håkon

Children
Related