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

MAX_RT interrupt still happens even if retransmit is off

Dear Nordic,

I met a problem while using nRF24L01+ about MAX_RT interrupt.

In my codes, I disabled RF HW retransmit (hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);) because I use our software codes to handle retransmit. Therefore, RF should not report "HAL_NRF_MAX_RT" interrupt. However, I still receive "HAL_NRF_MAX_RT" in very rare situations. I saw twice so far for a very long time.

My question is since RF module auto retransmition is off, why does nRF24L01+ still report "HAL_NRF_MAX_RT" interrupt?? Is this nRF24L01+ bug? Or how could I do to get rid of these
MAX_RT interrupt?

Parents
  • Hi Harry

    The MAX_RT interrupt occurs if no ACK is received, even when no retransmits are enabled. 

    In other words this will happen if you don't get an ACK on your TX packet. 

    Best regards
    Torbjørn

  • Thank your update.

    One more information: in our codes, we have disabled ACK by 

    hal_nrf_open_pipe(HAL_NRF_PIPE0, false);       // Open pipe0, without/autoack

    This means the receiver will never ACK the sender's TX.

    Two more questions:

    1. Based on your reply, MAX_RT occurs if no ACK. Since we have disabled ACK, I guess we should see MAX_RT interrupt very frequently, but why do we just rarely see the MAX_RT interrupt? (I saw twice so far for a very long time)

    2. We have used software to handle re-transmit. If we don't want MAX_RT interrupt, how could we do?

  • Hi

    This might explain the problem. Using features like ACK payload, dynamic payload length or dynamic ACK are not compatible with clearing the EN_AA register (ie disabling ACK's). 

    Either you have to enable ACK's through the EN_AA register and use these features, or you have to disable these features completely. 

    If you want to disable ACK's while using the dynamic payload length feature you should enable ACK in the EN_AA register and enable the dynamic ACK feature, so that you can send packet without ACK even if EN_AA is enabled. 

    I did some testing on my own, and after a million packets I don't see a single MAX_RT interrupt occur, but in my testing I didn't enable ack payload and dynamic payload length. 

    Best regards
    Torbjørn

  • If you want to disable ACK's while using the dynamic payload length feature you should enable ACK in the EN_AA register and enable the dynamic ACK feature, so that you can send packet without ACK even if EN_AA is enabled

    Based on your comments, so my codes need to change as follows, right? (Please help to confirm).

      hal_nrf_open_pipe(HAL_NRF_PIPE0, true);  // Then open pipe0, w/autoack  -> Harry: enable EN_AA Ack

      // hal_nrf_enable_ack_pl(); // Try to enable ack payload -> Harry: comment out two lines of these codes

    However, I have one question. Since I don't want ACK, why can I disable EN_AA as well, i.e., 

      hal_nrf_open_pipe(HAL_NRF_PIPE0, false);

  • Hi 

    Do you need dynamic payload length or not?

    If you don't need dynamic payload length you can just run hal_nrf_open_pipe(HAL_NRF_PIPE0, false), and make sure not to run hal_nrf_enable_ack_pl(), hal_nrf_enable_ack_pl(), hal_nrf_enable_dynamic_pl() or hal_nrf_setup_dyn_pl(ALL_PIPES). 

    If you need dynamic payload length the only way to achieve this is to run hal_nrf_open_pipe(HAL_NRF_PIPE0, true), hal_nrf_setup_dyn_pl(ALL_PIPES) and hal_nrf_enable_dynamic_pl().

    The reason for this is that enabling the pipe with EN_AA = 0 removes the 9 bit PCF field in the payload which is used to support the dynamic payload length, ACK payload and dynamic ACK features. 

    In the documentation this might be referred to as either Shockburst mode (EN_AA = 0), or Enhanced Shockburst mode (EN_AA = 1). 

    Best regards
    Torbjørn

  • Yes, I need dynamic payload length.

    Therefore, my codes will call

    * run hal_nrf_open_pipe(HAL_NRF_PIPE0, true), 

    * hal_nrf_setup_dyn_pl(ALL_PIPES)

    * hal_nrf_enable_dynamic_pl().

    and will NOT call (comment out)

    * hal_nrf_enable_ack_pl();

    Got it. thank you very much.

  • Hi 

    That sounds good. 

    If you have any more problems just let me know Slight smile

    Best regards
    Torbjørn

Reply Children
  • Hi Torbjorn,

    I follow your comments, but RF does not produce any TX_DS interrupt event anymore. The whole system cannot work.

    I just copy my codes below (remove all comments to save space). Could you please help to check what's matter.

    void radio_pl_init (uint8_t *address, hal_nrf_operation_mode_t operational_mode,
    uint8_t rfChannel, hal_nrf_datarate_t airRate)
    {
    hal_nrf_close_pipe(HAL_NRF_ALL);
    hal_nrf_open_pipe(HAL_NRF_PIPE0, true);
    hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
    hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);
    hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
    hal_nrf_set_address(HAL_NRF_TX, address);
    hal_nrf_set_address(HAL_NRF_PIPE0, address);

    //hal_nrf_enable_ack_pl(); // Try to enable ack payload

    if(hal_nrf_read_reg(FEATURE) == 0x00 && (hal_nrf_read_reg(DYNPD) == 0x00))
    {
    hal_nrf_lock_unlock (); // Activate features
    //hal_nrf_enable_ack_pl(); // Enables payload in ack
    }

    hal_nrf_enable_dynamic_pl();
    hal_nrf_setup_dyn_pl(ALL_PIPES);

    if(operational_mode == HAL_NRF_PTX)
    {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
    }
    else
    {
    hal_nrf_set_operation_mode(HAL_NRF_PRX);

    // Disable this. Use dynamic payload, so no need to set the fixed payload length.
    //hal_nrf_set_rx_pload_width((uint8_t)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
    }

    hal_nrf_set_rf_channel(rfChannel);
    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
    hal_nrf_set_datarate(airRate);
    start_timer(RF_POWER_UP_DELAY);
    wait_for_timer();

    //radio_set_status (RF_IDLE);
    }

  • Hi 

    Are you able to send me the implementation of the hal_nrf_enable_dynamic_pl() function?

    In my version of the HAL library this function needs to be provided a bool argument, allowing you to enable or disable the feature. 

    I realize now that I forgot to mention that you have to call  hal_nrf_enable_dynamic_ack(true) also if you want to use the noack feature. 

    Below is my own test code to verify that this is working: 

    hal_nrf_set_operation_mode((config->mode == APP_RADIO_MODE_PTX) ? HAL_NRF_PTX : HAL_NRF_PRX);

    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

    nrf_delay_us(1500);

    hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);

    hal_nrf_set_auto_retr(0, 500);

    hal_nrf_close_pipe(HAL_NRF_ALL);
    hal_nrf_open_pipe(HAL_NRF_PIPE0, true);

    hal_nrf_set_address_width(5);

    hal_nrf_setup_dynamic_payload(0x3F);
    hal_nrf_enable_dynamic_payload(true);
    hal_nrf_enable_dynamic_ack(true);

    hal_nrf_set_datarate(HAL_NRF_2MBPS);

    hal_nrf_set_rf_channel(2);


    if(config->mode == APP_RADIO_MODE_PTX)
    {
      hal_nrf_flush_tx();
    }
    else
    {
      hal_nrf_flush_rx();
      hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, 8);
    }

    And then I send my packets using the hal_nrf_write_tx_payload_noack(..) function, which removes the ACK requirement from the packet.

    Best regards
    Torbjørn

  • Are you able to send me the implementation of the hal_nrf_enable_dynamic_pl() function?

    Here you are.

    void hal_nrf_enable_dynamic_pl(void)
    {
    hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x04));
    }

    void hal_nrf_disable_dynamic_pl(void)
    {
    hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x04));
    }

  • Hi

    That looks fine, I guess it's a slightly different implementation of the hal_nrf libraries. 

    Did you add the dynamic ACK configuration?

    If yes, did it change the behavior?

    If it still doesn't work, can you send me the code you use to upload packets, and a printout of your config register after you have configured the device?

    Best regards
    Torbjørn

  • Hi Torbjorn,

    I check my code. I use `hal_nrf_write_tx_pload()` to send payload.

    I want to try your codes, but I found my nRF libraries does not have `hal_nrf_write_tx_payload_noack(..)` this function. Could you paste this function to me?

    Another question: I saw you call `hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, 8);`. My question is since we already enable dynamic payload `hal_nrf_enable_dynamic_payload(true);`, why do we still need to call set payload width?

    By the way, the data rate in my test is 250K bps (yours is HAL_NRF_2MBPS). I think this will not affect anything, but still mention this difference.

Related