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

IEEE 802.15.4 ACK Frame seems to get lost

I am developing an IEEE 802.15.4 Application on the nRF52840 using the Radio Driver (v1.8.0). I have a problem with the transmit call function. Very often in nrf_802154_transmitted_timestamp_raw(...) p_ack is NULL even when there was an ACK frame. So I check p_frame if the ACK request Bit was set and if it was I assume that we received an ACK, otherwise nrf_802154_transmit_failed(...) would have been called. The problem with this is, that I don't know if the pending bit was set in the ACK frame. In Wireshark I can see the ACK frames and that they are sent within 500us. Can you give me advice where the ACK frame could have ended and if I could access it anyways?
void nrf_802154_transmitted_timestamp_raw(const uint8_t *p_frame, uint8_t *p_ack, int8_t power, uint8_t lqi, uint32_t time) {
  if (p_ack != NULL) {
    /* ACK received, check if pending bit is set */
    ack = (p_ack[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT) ? IEEE802154_ACK_PENDING : IEEE802154_ACK_NO_PENDING;
    nrf_802154_buffer_free_raw(p_ack);
  } else {
    if ((p_frame[1] & 0x20) == 0x20) {
      /* the ACK frame seem to have been lost */
      ack = IEEE802154_ACK_NO_PENDING;
    } else {
      /* no ACK requested */
      ack = IEEE802154_ACK_NO;
    }
  }
}
Parents
  • Hello,

    I am not sure I understand your reasoning. (I have not tried to set it up like this on this level). Do you have any projects that you used to conclude with this? And how do you expect it to work? Also, do you have a sniffer trace of this? Do you see from the sniffer trace that the packets require ACKs? And does the sniffer trace contain any ACKs?

    Best regards,

    Edvin

Reply
  • Hello,

    I am not sure I understand your reasoning. (I have not tried to set it up like this on this level). Do you have any projects that you used to conclude with this? And how do you expect it to work? Also, do you have a sniffer trace of this? Do you see from the sniffer trace that the packets require ACKs? And does the sniffer trace contain any ACKs?

    Best regards,

    Edvin

Children
  • I changes the code from above (Line 9):

    void nrf_802154_transmitted_timestamp_raw(const uint8_t *p_frame, uint8_t *p_ack, int8_t power, uint8_t lqi, uint32_t time) {
      if (p_ack != NULL) {
        /* ACK received, check if pending bit is set */
        ack = (p_ack[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT) ? IEEE802154_ACK_PENDING : IEEE802154_ACK_NO_PENDING;
        nrf_802154_buffer_free_raw(p_ack);
      } else {
        if ((p_frame[1] & 0x20) == 0x20) {
          /* the ACK frame seem to have been lost */
          ack = IEEE802154_ACK_INVALID;
        } else {
          /* no ACK requested */
          ack = IEEE802154_ACK_NO;
        }
      }
    }

    ack.pcapng

    The first Frames have the ACK request bit set but there is no ACK, nrf_802154_transmit_failed() is called. Frame 5 (seq_no 3) is a Ping from the nRF device with ACK request that is ACKed with pending Bit set (Frame 6). As it should be, nrf_802154_transmitted_timestamp_raw() is called with the p_ack set and ack is set to IEEE802154_ACK_PENDING. So far so good.


    All the other Frames have the ACK request Bit set as well and nrf_802154_transmitted_timestamp_raw() is called as it should be, but p_ack is 0x0 and ack is set to IEEE802154_ACK_INVALID. Imho that shouldn't happen. If there is an ACK, p_ack should be set, if there is no ACK nrf_802154_transmit_failed() should be called instead of nrf_802154_transmitted_timestamp_raw().

  • I threw the debugger onto the problem and checked the NRF_RADIO register in both cases. The Registers differ in 4 values. When I receive an ACK frame:

    EVENTS_DEVMISS: 0x00000001
    EVENTS_CCASTOPPED: 0x00000000
    RXCRC: 0x000028b4
    RSSISAMPLE: 0x0000001c

    When the ACK is NULL the values are

    EVENTS_DEVMISS: 0x00000000
    EVENTS_CCASTOPPED: 0x00000001
    RXCRC: 0x000096f5
    RSSISAMPLE: 0x0000001b

    RXCRC and RSSISAMPLE need to be different, maybe the two events help finding the problem.

  • I tracked it down to ack_is_requested() in nrf_802154_core.c. In this function the destination address is compared to the own address to determine if an ack is requested (Yes, that has nothing to do with the ack request). I replaced this with the implementation from the v1.9.0 driver - just check if the ack request bit is set. Maybe I should update the driver in my environment.

Related