Date:2013-07-24 12:57:35 (6 years 4 months ago)
Author:Werner Almesberger
Commit:b73d5fc1af46d739e841af89bf3841fd6a84bdf7
Message: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.
Files: atusb/fw/mac.c (7 diffs)

Change Details

atusb/fw/mac.c
2222#include "mac.h"
2323
2424
25#define RX_BUFS 2
26
27
2528bool (*mac_irq)(void) = NULL;
2629
2730
28static uint8_t rx_buf[MAX_PSDU+2]; /* PHDR+payload+LQ */
31static uint8_t rx_buf[RX_BUFS][MAX_PSDU+2]; /* PHDR+payload+LQ */
32static bool rx_in = 0, rx_out = 0;
2933static uint8_t tx_buf[MAX_PSDU];
3034static uint8_t tx_size = 0;
3135static bool txing = 0;
3236static bool queued_tx_ack = 0;
33static bool queued_rx = 0;
3437static uint8_t next_seq, this_seq, queued_seq;
3538
3639
...... 
6265/* ----- Interrupt handling ------------------------------------------------ */
6366
6467
65static void receive_frame(void);
68static void rx_done(void *user);
69static void tx_ack_done(void *user);
6670
6771
68static void rx_done(void *user)
72static void usb_next(void)
6973{
70    led(0);
71    if (queued_rx) {
72        receive_frame();
73        queued_rx = 0;
74        return;
74    const uint8_t *buf;
75
76    if (rx_in != rx_out) {
77        buf = rx_buf[rx_out];
78        led(1);
79        usb_send(&eps[1], buf, buf[0]+2, rx_done, NULL);
7580    }
81
7682    if (queued_tx_ack) {
77        usb_send(&eps[1], &queued_seq, 1, rx_done, NULL);
83        usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
7884        queued_tx_ack = 0;
7985    }
8086}
8187
8288
89static void tx_ack_done(void *user)
90{
91    usb_next();
92}
93
94
95static void rx_done(void *user)
96{
97    led(0);
98    rx_out = (rx_out+1) & (RX_BUFS-1);
99    usb_next();
100}
101
102
83103static void receive_frame(void)
84104{
85105    uint8_t size, i;
106    uint8_t *buf;
86107
87108    spi_begin();
88109    if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) {
...... 
95116        return;
96117    }
97118
98    rx_buf[0] = size;
119    buf = rx_buf[rx_in];
99120    for (i = 0; i != size+1; i++)
100        rx_buf[i+1] = spi_recv();
121        buf[i+1] = spi_recv();
101122    spi_end();
102    led(1);
103    usb_send(&eps[1], rx_buf, size+2, rx_done, NULL);
104}
105123
124    buf[0] = size;
125    rx_in = (rx_in+1) & (RX_BUFS-1);
106126
107static void flush_queued_rx(void)
108{
109    if (queued_rx)
110        receive_frame();
111    queued_rx = 0;
127    if (eps[1].state == EP_IDLE)
128        usb_next();
112129}
113130
114131
...... 
122139
123140    if (txing) {
124141        if (eps[1].state == EP_IDLE) {
125            usb_send(&eps[1], &this_seq, 1, rx_done, NULL);
142            usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
126143        } else {
127144            queued_tx_ack = 1;
128145            queued_seq = this_seq;
...... 
131148        return 1;
132149    }
133150
134    /* unlikely */
135    if (eps[1].state != EP_IDLE) {
136        queued_rx = 1;
137        return 1;
138    }
139
140    receive_frame();
151    /* likely */
152    if (eps[1].state == EP_IDLE || rx_in != rx_out)
153        receive_frame();
141154
142155    return 1;
143156}
...... 
193206     */
194207    reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
195208
196    flush_queued_rx();
197209    handle_irq();
198    queued_rx = 0;
199210
200211    spi_begin();
201212    spi_send(AT86RF230_BUF_WRITE);
...... 
233244    mac_irq = NULL;
234245    txing = 0;
235246    queued_tx_ack = 0;
236    queued_rx = 0;
247    rx_in = rx_out = 0;
237248    next_seq = this_seq = queued_seq = 0;
238249
239250    /* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */

Archive Download the corresponding diff file



interactive