at86rf2xx: correct framebuffer release

This PR sets the tranceiver in PLL_ON state to avoid corruption of the
data in the frame buffer and sets it back to the last state which the
 transceiver had before changing into transmit mode after the data is
read out. This is done to avoid data corruption when `_recv(...)` is
called to retrieve the buffer size and frame buffer protection is released.
This commit is contained in:
Josarn 2018-07-06 14:03:09 +02:00 committed by josar
parent f139dfdad2
commit d1261a7ef0
2 changed files with 26 additions and 3 deletions

View File

@ -44,6 +44,7 @@ void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params)
netdev->driver = &at86rf2xx_driver;
/* initialize device descriptor */
memcpy(&dev->params, params, sizeof(at86rf2xx_params_t));
/* State to return after receiving or transmitting */
dev->idle_state = AT86RF2XX_STATE_TRX_OFF;
/* radio state is P_ON when first powered-on */
dev->state = AT86RF2XX_STATE_P_ON;
@ -123,6 +124,8 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
/* clear interrupt flags */
at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
/* State to return after receiving or transmitting */
dev->idle_state = AT86RF2XX_STATE_RX_AACK_ON;
/* go into RX state */
at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_AACK_ON);

View File

@ -131,8 +131,11 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
uint8_t phr;
size_t pkt_len;
/* frame buffer protection will be unlocked as soon as at86rf2xx_fb_stop()
* is called*/
/* frame buffer protection will be unlocked as soon as at86rf2xx_fb_stop() is called,
* Set receiver to PLL_ON state to be able to free the SPI bus and avoid loosing data. */
at86rf2xx_set_state(dev, AT86RF2XX_STATE_PLL_ON);
/* start frame buffer access */
at86rf2xx_fb_start(dev);
/* get the size of the received packet */
@ -141,14 +144,27 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
/* ignore MSB (refer p.80) and substract length of FCS field */
pkt_len = (phr & 0x7f) - 2;
/* just return length when buf == NULL */
/* return length when buf == NULL */
if (buf == NULL) {
/* release SPI bus */
at86rf2xx_fb_stop(dev);
/* drop packet, continue receiving */
if (len > 0) {
/* set device back in operation state which was used before last transmission.
* e.g RX_AACK_ON */
at86rf2xx_set_state(dev, dev->idle_state);
}
return pkt_len;
}
/* not enough space in buf */
if (pkt_len > len) {
at86rf2xx_fb_stop(dev);
/* set device back in operation state which was used before last transmission.
* e.g RX_AACK_ON */
at86rf2xx_set_state(dev, dev->idle_state);
return -ENOBUFS;
}
#ifdef MODULE_NETSTATS_L2
@ -202,6 +218,10 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
at86rf2xx_fb_stop(dev);
}
/* set device back in operation state which was used before last transmission.
* e.g RX_AACK_ON */
at86rf2xx_set_state(dev, dev->idle_state);
return pkt_len;
}