This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2520: Manipulating the pending bit in ACK frames using PENDING_OR, SACK/SACKPEND

Other Parts Discussed in Thread: CC2520

Setting the PENDING_OR in FRMCTRL1 seems to override any manual setting made using the SACK and SACKPEND strobes, i.e. issuing SACK has the same result as SACKPEND when PENDING_OR = 1.

Is there a way to avoid this behavior other than clearing the PENDING_OR flag prior to issuing the SACK command?

Since this is in a timing-critical path, I would like to avoid an unnecessary SPI transfer.

Is there a way to have the pending bit = 0 in the ACK frame, if the ACKed frame is not a MAC data poll command using hardware features of CC2520?

Thanks

Arasch

  • Hi,
    I recommend using AUTOACK and AUTOPEND feature of the CC2520. This is what we are using in our stack products where timing critical operations are involved.
    With auto-ack, the chip responds automatically with an acknowledgment transmission if FCS is OK and the frame had the ack bit set.
    No need to strobe the SACK signal from the host.
    With autopend, you can configure the child to be in the source matching table of the CC2520 and the chip will also set the pending bit in the acknowledgment, only for MAC-DATA Req frames.

    Please check out 20.30.5 from www.ti.com/.../cc2520.pdf

    Thanks,
    TheDarkSide
  • Actually, that is what we did in the past and it was really a nice solution to avoid timing-critical paths. However, with the advent of ZigBee 3.0 Child Aging as specified in the current ZigBee Specification R21 draft, this does no longer work. A router must able to inject indirect messages "on-the-fly" for any device that polls the router, but is not (or no longer) one of the end-devices the router takes care of. So there are the following cases:

    1. Data poll and a pending message available -> ACK with pending = 1
    2. Data poll, no pending message, child is known and valid -> ACK with pending = 0
    3. Data poll, no pending message, child is unknown -> ACK with pending = 1, inject NWK leave or ZDO leave generated "on-the-fly" with rejoin = 1
    4. Other message than data poll -> ACK with pending = 0

    The problem is the "child is known" predicate. There is no address cache in CC2520, which could be used to distinguish known/unknown child devices. That's why we have to do it in software. That is all fine, but the issue is that when the CPU is busy servicing higher priority interrupts or when interrupts are disabled, the ISR latency might be too long to issue the SACK/SACKPEND/SNACK strobes. Therefore, our idea is to set the PENDING_OR flag to make sure the pending flag is set. If the CPU get's a chance to influence the ACK bit in time, it can clear the flag for a particular instance, such that the end-device can enter sleep mode as quickly as possible. However, in our experiments we found that PENDING_OR will override the SACK/SACKPEND strobe, i.e. if the bit is set, all ACK frames will have their pending bit set, even if a manual SACK strobe is issued in time.

    What would be your recommendation how to implement this bevhavior?

    Thanks

    Arasch

  • Hi,
    I think there are two things you could potentially do.
    First of all though, please note that 1, 2 and 4 are all supported with AUTOPEND and AUTOACK feature enabled, as long as all the legitimate children are in the source matching table and the automatic pending bit is enabled for that corresponding device. Only the frames which are correctly received will be ack-ed and the pending bit will be set only when DATA-POLL is received and a valid frame exists to be sent for that device.
    The only case that is not covered is 3. However, you could in theory implement a scheme like this:
    - When the DATA-POLL is received, you program the RX FIFO buffer to generate an interrupt just when the header is received, and in the ISR set the PENDING_OR bit when the device is not your child (basically you are preparing yourself to potentially set the pending bit).
    - When the frame is received completely, you have by spec at least 192 usecs (by 802.15.4 spec) before the ACK is actually transmitted. If FCS is OK, then you leave the PENDING_OR bit set and you clear it only when the MAC ACK is transmitted (you can program an RF ISR for that)
    - If instead the FCS is not OK the MAC ACK won't be transmitted by the HW, but you should anyway clear the PENDING_OR bit to prevent overriding the pending bit set automatically by the HW.

    This mechanism relies on guaranteeing a fast interrupt latency of ~ 192 usecs at worst.

    Another scheme you can use is the following.
    You keep the AUTOPEND and the AUTOACK feature set, and the source matching table will contain only the legitimate children.
    Then when you detect a child which is unknown, you notify the upper layers which will then schedule the NWK-LEAVE command at the next polling event. In this case, the unknown child is temporarily inserted in the source matching table and then at the next polling event, automatically the HW with AUTOPEND and AUTOACK feature set will set the bits accordingly as the MAC is notified of the buffered NWK-LEAVE.

    This second mechanism is safer from a timing perspective, as you have all the time to schedule in advance the NWK-LEAVE and you rely on the HW to to the necessary timing critical operations.
    The only 'disadvantage' is that you are not kicking out the unknown child right away, but you would need to program that one polling event earlier.
    I hope this helps.
    Thanks,
    TheDarkSide
  • Thank you again for the detailed response and the suggestions.

    We've found a reliable way to implement the desired behavior by using some of the techniques you mentioned above, keeping CC2520's hardware features and playing with the PENDING_OR bit. The bit is set by default and only when the CPU get's a chance to service the ISR in time, it would clear the bit. This ensures reliable operation and in those instances where the ISR is missed, the pending flag remains set, which is acceptable. If the ACK was due to a data poll we inject an emtpy data frame to let the child shut off its receiver without waiting for too long. If it was an ACK to any ohter command it does not have any effect (though its not "nice" that it remains set, but ok). So there is a timing critical path there, but missing the opportunity window does not have a critical impact.

    Arasch

  • ok good happy to know this got solved. Yes, I guess that is another way to workaround it with minimal impact on the system design.
    Thanks,
    TheDarkSide