mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-22 14:10:37 +02:00
atusb/fw/mac.c: remove queued_rx; buffer frames in the MCU instead
queued_rx held a frame in the transceiver's receive buffer until we could transfer it. This may cause frame loss if a new reception begins. We now retrieve frames from the transceiver immediately and buffer them in the MCU.
This commit is contained in:
parent
6416fa8d0b
commit
b73d5fc1af
@ -22,15 +22,18 @@
|
|||||||
#include "mac.h"
|
#include "mac.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define RX_BUFS 2
|
||||||
|
|
||||||
|
|
||||||
bool (*mac_irq)(void) = NULL;
|
bool (*mac_irq)(void) = NULL;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t rx_buf[MAX_PSDU+2]; /* PHDR+payload+LQ */
|
static uint8_t rx_buf[RX_BUFS][MAX_PSDU+2]; /* PHDR+payload+LQ */
|
||||||
|
static bool rx_in = 0, rx_out = 0;
|
||||||
static uint8_t tx_buf[MAX_PSDU];
|
static uint8_t tx_buf[MAX_PSDU];
|
||||||
static uint8_t tx_size = 0;
|
static uint8_t tx_size = 0;
|
||||||
static bool txing = 0;
|
static bool txing = 0;
|
||||||
static bool queued_tx_ack = 0;
|
static bool queued_tx_ack = 0;
|
||||||
static bool queued_rx = 0;
|
|
||||||
static uint8_t next_seq, this_seq, queued_seq;
|
static uint8_t next_seq, this_seq, queued_seq;
|
||||||
|
|
||||||
|
|
||||||
@ -62,27 +65,45 @@ static void reg_write(uint8_t reg, uint8_t value)
|
|||||||
/* ----- Interrupt handling ------------------------------------------------ */
|
/* ----- Interrupt handling ------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
static void receive_frame(void);
|
static void rx_done(void *user);
|
||||||
|
static void tx_ack_done(void *user);
|
||||||
|
|
||||||
|
|
||||||
|
static void usb_next(void)
|
||||||
|
{
|
||||||
|
const uint8_t *buf;
|
||||||
|
|
||||||
|
if (rx_in != rx_out) {
|
||||||
|
buf = rx_buf[rx_out];
|
||||||
|
led(1);
|
||||||
|
usb_send(&eps[1], buf, buf[0]+2, rx_done, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queued_tx_ack) {
|
||||||
|
usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
|
||||||
|
queued_tx_ack = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void tx_ack_done(void *user)
|
||||||
|
{
|
||||||
|
usb_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rx_done(void *user)
|
static void rx_done(void *user)
|
||||||
{
|
{
|
||||||
led(0);
|
led(0);
|
||||||
if (queued_rx) {
|
rx_out = (rx_out+1) & (RX_BUFS-1);
|
||||||
receive_frame();
|
usb_next();
|
||||||
queued_rx = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (queued_tx_ack) {
|
|
||||||
usb_send(&eps[1], &queued_seq, 1, rx_done, NULL);
|
|
||||||
queued_tx_ack = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void receive_frame(void)
|
static void receive_frame(void)
|
||||||
{
|
{
|
||||||
uint8_t size, i;
|
uint8_t size, i;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
spi_begin();
|
spi_begin();
|
||||||
if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) {
|
if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) {
|
||||||
@ -95,20 +116,16 @@ static void receive_frame(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_buf[0] = size;
|
buf = rx_buf[rx_in];
|
||||||
for (i = 0; i != size+1; i++)
|
for (i = 0; i != size+1; i++)
|
||||||
rx_buf[i+1] = spi_recv();
|
buf[i+1] = spi_recv();
|
||||||
spi_end();
|
spi_end();
|
||||||
led(1);
|
|
||||||
usb_send(&eps[1], rx_buf, size+2, rx_done, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
buf[0] = size;
|
||||||
|
rx_in = (rx_in+1) & (RX_BUFS-1);
|
||||||
|
|
||||||
static void flush_queued_rx(void)
|
if (eps[1].state == EP_IDLE)
|
||||||
{
|
usb_next();
|
||||||
if (queued_rx)
|
|
||||||
receive_frame();
|
|
||||||
queued_rx = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,7 +139,7 @@ static bool handle_irq(void)
|
|||||||
|
|
||||||
if (txing) {
|
if (txing) {
|
||||||
if (eps[1].state == EP_IDLE) {
|
if (eps[1].state == EP_IDLE) {
|
||||||
usb_send(&eps[1], &this_seq, 1, rx_done, NULL);
|
usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
|
||||||
} else {
|
} else {
|
||||||
queued_tx_ack = 1;
|
queued_tx_ack = 1;
|
||||||
queued_seq = this_seq;
|
queued_seq = this_seq;
|
||||||
@ -131,13 +148,9 @@ static bool handle_irq(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlikely */
|
/* likely */
|
||||||
if (eps[1].state != EP_IDLE) {
|
if (eps[1].state == EP_IDLE || rx_in != rx_out)
|
||||||
queued_rx = 1;
|
receive_frame();
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
receive_frame();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -193,9 +206,7 @@ static void do_tx(void *user)
|
|||||||
*/
|
*/
|
||||||
reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
|
reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
|
||||||
|
|
||||||
flush_queued_rx();
|
|
||||||
handle_irq();
|
handle_irq();
|
||||||
queued_rx = 0;
|
|
||||||
|
|
||||||
spi_begin();
|
spi_begin();
|
||||||
spi_send(AT86RF230_BUF_WRITE);
|
spi_send(AT86RF230_BUF_WRITE);
|
||||||
@ -233,7 +244,7 @@ void mac_reset(void)
|
|||||||
mac_irq = NULL;
|
mac_irq = NULL;
|
||||||
txing = 0;
|
txing = 0;
|
||||||
queued_tx_ack = 0;
|
queued_tx_ack = 0;
|
||||||
queued_rx = 0;
|
rx_in = rx_out = 0;
|
||||||
next_seq = this_seq = queued_seq = 0;
|
next_seq = this_seq = queued_seq = 0;
|
||||||
|
|
||||||
/* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */
|
/* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */
|
||||||
|
Loading…
Reference in New Issue
Block a user