[riot-devel] at86rf2xx and PHR filtering

Alexander Aring alex.aring at gmail.com
Fri Apr 1 12:24:50 CEST 2016

On Fri, Apr 01, 2016 at 10:04:40AM +0000, Wachtler, Axel wrote:
> What I did mean, there are various reasons, why a frame can be invalid. 
> The reserved PHR bit is one thing, invalid CRC another. The CRC calculation 
> inside the transceivers is done without the reserved PHR bit, the PHR value
> is not part of the CRC itself.


> For RX_AACK: I would suggest not trying to be a software nanny for  the hardware,
> e.g. not trying to track the *_BUSY states. (this is just an temporary/transient information 
> and when you receive this information in SW, it might already be outdated)
> The state change commands in RF23x are queued commands (except FORCE_TRX_OFF, FORCE_PLL_ON)
> That means any ongoing transaction is completed before the next command is effective
> (transaction = receiving or tranmistting a frame). 
> E.g. if you are in BUSY_RX and you write CMD_PLL_ON, at first the entire frame received and after it,
> the TRX switches to PLL_ON.
> In all basic RX and TX states, including TX_ARET_ON, a transaction ends with a TRX_END IRQ.
> This is not true for RX_AACK, reasons for this are: either a CRC error or address match error 
> (see address filtering in DS). This means that in case of a max length 
> frame the TRX stays in BUSY_RX_AACK for 4.xms before it switches back to RX_AACK_ON. 
> To end RX_AACK use either CMD_TRX_OFF or CMD_PLL_ON and wait until the desired state is reached
> or one of the FORCE_commands if you need the transceiver immediately to stop the ongoing transaction 
> (e.g. when a Beacon needs to be sent)

I looked now in RIOT code [0].

So they will call at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
with state as RX_AACK_ON, but at the end they call:

_set_state(at86rf2xx_t *dev, uint8_t state)

with RX_AACK_ON, so it could be that RIOT has this behaviour:

MCU       -> at86rf2xx_set_state(foo, RX_AACK_ON)
at86rf2xx -> going into RX_AACK_ON
at86rf2xx -> detected SFD, going into RX_AACK_BUSY
  MCU       -> _set_state(foo, RX_AACK_ON)
    MCU       ->  while (at86rf2xx_get_status(dev) != state) -> stucks inside this loop
at86rf2xx -> receiving done, going into RX_AACK_ON
    MCU       ->  while (at86rf2xx_get_status(dev) != state) -> loop ends

The stucking inside the loop for assertion is here a possible case which
is bad. But okay it's unlikely I also get such issues only when I make
really big traffic.

- Alex

[0] https://github.com/RIOT-OS/RIOT/blob/master/drivers/at86rf2xx/at86rf2xx_getset.c#L420

More information about the devel mailing list