2014-05-14 10:36:45 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 INRIA
|
|
|
|
*
|
2014-07-31 19:45:27 +02:00
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
* directory for more details.
|
2014-05-14 10:36:45 +02:00
|
|
|
*/
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-09-29 20:34:38 +02:00
|
|
|
/**
|
|
|
|
* @ingroup drivers_at86rf231
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @brief RX related functionality for the AT86RF231 device driver
|
|
|
|
*
|
|
|
|
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
|
|
|
|
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
|
|
|
*
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2013-12-16 17:54:58 +01:00
|
|
|
#include "at86rf231.h"
|
2014-02-20 03:05:35 +01:00
|
|
|
#include "at86rf231_spi.h"
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-08-05 23:54:24 +02:00
|
|
|
#include "kernel_types.h"
|
2013-12-16 17:54:58 +01:00
|
|
|
#include "transceiver.h"
|
|
|
|
#include "msg.h"
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2013-12-16 17:54:58 +01:00
|
|
|
#define ENABLE_DEBUG (0)
|
|
|
|
#include "debug.h"
|
2013-07-12 12:31:16 +02:00
|
|
|
|
|
|
|
at86rf231_packet_t at86rf231_rx_buffer[AT86RF231_RX_BUF_SIZE];
|
2015-01-23 19:37:45 +01:00
|
|
|
static uint8_t buffer[AT86RF231_RX_BUF_SIZE][AT86RF231_MAX_PKT_LENGTH];
|
2013-07-12 12:31:16 +02:00
|
|
|
volatile uint8_t rx_buffer_next;
|
2014-10-20 16:46:53 +02:00
|
|
|
extern netdev_802154_raw_packet_cb_t at86rf231_raw_packet_cb;
|
2013-07-12 12:31:16 +02:00
|
|
|
|
|
|
|
void at86rf231_rx_handler(void)
|
|
|
|
{
|
2013-08-15 19:13:00 +02:00
|
|
|
uint8_t lqi, fcs_rssi;
|
2014-10-20 16:46:53 +02:00
|
|
|
/* read packet length */
|
2013-08-15 19:13:00 +02:00
|
|
|
at86rf231_read_fifo(&at86rf231_rx_buffer[rx_buffer_next].length, 1);
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* read psdu, read packet with length as first byte and lqi as last byte. */
|
2013-08-15 19:13:00 +02:00
|
|
|
uint8_t *buf = buffer[rx_buffer_next];
|
|
|
|
at86rf231_read_fifo(buf, at86rf231_rx_buffer[rx_buffer_next].length);
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* read lqi which is appended after the psdu */
|
2013-08-15 19:13:00 +02:00
|
|
|
lqi = buf[at86rf231_rx_buffer[rx_buffer_next].length - 1];
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* read fcs and rssi, from a register */
|
2013-08-15 19:13:00 +02:00
|
|
|
fcs_rssi = at86rf231_reg_read(AT86RF231_REG__PHY_RSSI);
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* build package */
|
2013-08-15 19:13:00 +02:00
|
|
|
at86rf231_rx_buffer[rx_buffer_next].lqi = lqi;
|
2014-10-20 16:46:53 +02:00
|
|
|
/* RSSI has no meaning here, it should be read during packet reception. */
|
2015-01-12 16:40:21 +01:00
|
|
|
at86rf231_rx_buffer[rx_buffer_next].rssi = fcs_rssi & 0x1F; /* bit[4:0] */
|
2014-10-20 16:46:53 +02:00
|
|
|
/* bit7, boolean, 1 FCS valid, 0 FCS not valid */
|
2013-08-15 19:13:00 +02:00
|
|
|
at86rf231_rx_buffer[rx_buffer_next].crc = (fcs_rssi >> 7) & 0x01;
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2013-08-15 19:13:00 +02:00
|
|
|
if (at86rf231_rx_buffer[rx_buffer_next].crc == 0) {
|
2014-11-13 15:00:46 +01:00
|
|
|
DEBUG("at86rf231: Got packet with invalid crc.\n");
|
2013-08-15 19:13:00 +02:00
|
|
|
return;
|
|
|
|
}
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-12-03 22:59:14 +01:00
|
|
|
#if ENABLE_DEBUG
|
2014-11-04 15:11:54 +01:00
|
|
|
DEBUG("pkg: ");
|
|
|
|
for (int i = 1; i < at86rf231_rx_buffer[rx_buffer_next].length; i++) {
|
|
|
|
DEBUG("%x ", buf[i]);
|
|
|
|
}
|
|
|
|
DEBUG("\n");
|
|
|
|
#endif
|
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* read buffer into ieee802154_frame */
|
2013-09-18 14:42:13 +02:00
|
|
|
ieee802154_frame_read(&buf[1], &at86rf231_rx_buffer[rx_buffer_next].frame,
|
2014-02-20 14:35:46 +01:00
|
|
|
at86rf231_rx_buffer[rx_buffer_next].length);
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* if packet is no ACK */
|
2014-11-05 11:53:18 +01:00
|
|
|
if (at86rf231_rx_buffer[rx_buffer_next].frame.fcf.frame_type != IEEE_802154_ACK_FRAME) {
|
2014-12-03 22:59:14 +01:00
|
|
|
#if ENABLE_DEBUG
|
2013-09-18 14:42:13 +02:00
|
|
|
ieee802154_frame_print_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame);
|
2013-07-12 12:31:16 +02:00
|
|
|
#endif
|
2014-10-20 16:46:53 +02:00
|
|
|
if (at86rf231_raw_packet_cb != NULL) {
|
|
|
|
at86rf231_raw_packet_cb(&at86rf231_netdev, (void*)buf,
|
|
|
|
at86rf231_rx_buffer[rx_buffer_next].length,
|
|
|
|
fcs_rssi, lqi, (fcs_rssi >> 7));
|
|
|
|
}
|
|
|
|
#ifdef MODULE_TRANSCEIVER
|
2013-08-15 19:13:00 +02:00
|
|
|
/* notify transceiver thread if any */
|
2014-08-06 11:52:00 +02:00
|
|
|
if (transceiver_pid != KERNEL_PID_UNDEF) {
|
2013-08-15 19:13:00 +02:00
|
|
|
msg_t m;
|
|
|
|
m.type = (uint16_t) RCV_PKT_AT86RF231;
|
|
|
|
m.content.value = rx_buffer_next;
|
|
|
|
msg_send_int(&m, transceiver_pid);
|
|
|
|
}
|
2014-10-20 16:46:53 +02:00
|
|
|
#endif
|
2013-08-15 19:13:00 +02:00
|
|
|
}
|
|
|
|
else {
|
2014-10-20 16:46:53 +02:00
|
|
|
/* This should not happen, ACKs are consumed by hardware */
|
2014-12-03 22:59:14 +01:00
|
|
|
#if ENABLE_DEBUG
|
2013-08-15 19:13:00 +02:00
|
|
|
DEBUG("GOT ACK for SEQ %u\n", at86rf231_rx_buffer[rx_buffer_next].frame.seq_nr);
|
2013-09-18 14:42:13 +02:00
|
|
|
ieee802154_frame_print_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame);
|
2013-07-12 12:31:16 +02:00
|
|
|
#endif
|
2013-08-15 19:13:00 +02:00
|
|
|
}
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* shift to next buffer element */
|
2013-08-15 19:13:00 +02:00
|
|
|
if (++rx_buffer_next == AT86RF231_RX_BUF_SIZE) {
|
|
|
|
rx_buffer_next = 0;
|
|
|
|
}
|
2013-07-12 12:31:16 +02:00
|
|
|
|
2014-10-20 16:46:53 +02:00
|
|
|
/* Read IRQ to clear it */
|
2013-08-15 19:13:00 +02:00
|
|
|
at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS);
|
2013-07-12 12:31:16 +02:00
|
|
|
}
|