Using AT86RF231 driver

Hi RIOT team,

We're currently using RIOT on a custom board, based on STM32F1 and AT86RF231 transceiver. I'm not sure I understand correctly the steps that are required for a transmission. These are the steps that we follow:

- call at86rf231_initialize - construct an ieee802154_frame_t - construct an at86rf231_packet_t - call at86rf231_send, giving the packet as argument

The thing is, RIOT crashes (HARD FAULT), somewhere in the call to at86rf231_transmit_tx_buf (which is called by at86rf231_send), I suspect at this line [1].

Am I missing anything or doing something wrong here?

Thanks! Eriza

[1] https://github.com/RIOT-OS/RIOT/blob/master/drivers/at86rf231/at86rf231_tx.c#L173

Hi Eriza,

The thing is, RIOT crashes (HARD FAULT), somewhere in the call to at86rf231_transmit_tx_buf (which is called by at86rf231_send), I suspect at this line [1].

Your problem seems somehow related to this one on github [1]. My analysis so far indicates this happen due to a race condition under very special conditions. To track this down, could you test two approaches for me?

1. On your board, does the radio device has its own SPI bus? Could you report your results when removing all `spi_acquire` and `spi_release` calls in at86rf231_spi.c?

2. Try to compile your application without compiler optimisation by changing the the `CFLAGS` in Makefile.include from `-Os` to `-O0`. (If applicable).

Best, Thomas

[1] iot-lab_M3: hard fault with RPL_UDP example on the testbed · Issue #2418 · RIOT-OS/RIOT · GitHub

Hi Thomas,

We implemented your tests, but still got a hard fault.

Strangely, though, if we put at86rf231_switch_to_rx right after at86rf231_send, the crash is gone; we haven't checked if sending and receiving actually works, but at least it's not crashing anymore. It looks a bit hacky to me, but I don't know if it should indeed be done that way...

Thanks, Eriza

Hi Eriza,

We implemented your tests, but still got a hard fault.

Too bad. I’m currently refactoring this radio driver so I won’t be able to put much effort into debugging this right now.

Strangely, though, if we put at86rf231_switch_to_rx right after at86rf231_send, the crash is gone; we haven't checked if sending and receiving actually works, but at least it's not crashing anymore. It looks a bit hacky to me, but I don't know if it should indeed be done that way…

Did it crash on every attempt to send before? I’m asking because _switch_to_rx gets called by the current driver implementation as soon as the radio device issues an interrupt signalling it finished transmission. (at86rf231.c:208)

I hope my refactoring and all needed additional changes will be ready by Friday. I would kindly ask you to give the new implementation a try then?

Best, Thomas

Hi Thomas,

We implemented your tests, but still got a hard fault.

Too bad. I’m currently refactoring this radio driver so I won’t be able to put much effort into debugging this right now.

That's fine.

Strangely, though, if we put at86rf231_switch_to_rx right after at86rf231_send, the crash is gone; we haven't checked if sending and receiving actually works, but at least it's not crashing anymore. It looks a bit hacky to me, but I don't know if it should indeed be done that way…

Did it crash on every attempt to send before? I’m asking because _switch_to_rx gets called by the current driver implementation as soon as the radio device issues an interrupt signalling it finished transmission. (at86rf231.c:208)

Yes, it crashed every time. I also figured that _switch_to_rx should be called by _rx_irq. That _rx_irq was not triggered at all made me a bit suspicious that there might be something wrong with our port of RIOT. We'll be looking on it tomorrow.

I hope my refactoring and all needed additional changes will be ready by Friday. I would kindly ask you to give the new implementation a try then?

Well, of course! Thanks for all the effort!

Eriza

Hi Eriza,

That _rx_irq was not triggered at all made me a bit suspicious that there might be something wrong with our port of RIOT. We'll be looking on it tomorrow.

For this to work there are three things which have to be configured correctly:

1.) AT86RF231_INT (see boards/fox/include/board.h:L61) 2.) the reverse IRQ mapping (see boards/fox/include/periph_conf.h:L138) 3.) the external interrupt controller setting (see boards/fox/include/periph_conf.h:L224 and L225)

Especially with the reverse mapping my brain often gets dizzy. Hope this helps somehow.

Best, Thomas