mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-12-22 19:48:39 +02:00
Merge branch 'buffer-frames'
This commit is contained in:
commit
08f4ac98fa
@ -22,18 +22,32 @@
|
||||
#include "mac.h"
|
||||
|
||||
|
||||
#define RX_BUFS 2
|
||||
|
||||
|
||||
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 uint8_t tx_buf[MAX_PSDU];
|
||||
static uint8_t tx_size = 0;
|
||||
static bool txing = 0;
|
||||
static bool queued_tx_ack = 0;
|
||||
static bool queued_rx = 0;
|
||||
static uint8_t next_seq, this_seq, queued_seq;
|
||||
|
||||
|
||||
/* ----- Receive buffer management ----------------------------------------- */
|
||||
|
||||
|
||||
static uint8_t rx_in = 0, rx_out = 0;
|
||||
|
||||
|
||||
static inline void next_buf(uint8_t *index)
|
||||
{
|
||||
*index = (*index+1) % RX_BUFS;
|
||||
}
|
||||
|
||||
|
||||
/* ----- Register access --------------------------------------------------- */
|
||||
|
||||
|
||||
@ -62,27 +76,45 @@ static void reg_write(uint8_t reg, uint8_t value)
|
||||
/* ----- Interrupt handling ------------------------------------------------ */
|
||||
|
||||
|
||||
static void receive_frame(void);
|
||||
static void rx_done(void *user);
|
||||
static void tx_ack_done(void *user);
|
||||
|
||||
|
||||
static void rx_done(void *user)
|
||||
static void usb_next(void)
|
||||
{
|
||||
led(0);
|
||||
if (queued_rx) {
|
||||
receive_frame();
|
||||
queued_rx = 0;
|
||||
return;
|
||||
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, rx_done, NULL);
|
||||
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)
|
||||
{
|
||||
led(0);
|
||||
next_buf(&rx_out);
|
||||
usb_next();
|
||||
}
|
||||
|
||||
|
||||
static void receive_frame(void)
|
||||
{
|
||||
uint8_t size, i;
|
||||
uint8_t size;
|
||||
uint8_t *buf;
|
||||
|
||||
spi_begin();
|
||||
if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) {
|
||||
@ -95,20 +127,15 @@ static void receive_frame(void)
|
||||
return;
|
||||
}
|
||||
|
||||
rx_buf[0] = size;
|
||||
for (i = 0; i != size+1; i++)
|
||||
rx_buf[i+1] = spi_recv();
|
||||
buf = rx_buf[rx_in];
|
||||
spi_recv_block(buf+1, size+1);
|
||||
spi_end();
|
||||
led(1);
|
||||
usb_send(&eps[1], rx_buf, size+2, rx_done, NULL);
|
||||
}
|
||||
|
||||
buf[0] = size;
|
||||
next_buf(&rx_in);
|
||||
|
||||
static void flush_queued_rx(void)
|
||||
{
|
||||
if (queued_rx)
|
||||
receive_frame();
|
||||
queued_rx = 0;
|
||||
if (eps[1].state == EP_IDLE)
|
||||
usb_next();
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +149,7 @@ static bool handle_irq(void)
|
||||
|
||||
if (txing) {
|
||||
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 {
|
||||
queued_tx_ack = 1;
|
||||
queued_seq = this_seq;
|
||||
@ -131,13 +158,9 @@ static bool handle_irq(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* unlikely */
|
||||
if (eps[1].state != EP_IDLE) {
|
||||
queued_rx = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
receive_frame();
|
||||
/* likely */
|
||||
if (eps[1].state == EP_IDLE || rx_in != rx_out)
|
||||
receive_frame();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -193,9 +216,7 @@ static void do_tx(void *user)
|
||||
*/
|
||||
reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
|
||||
|
||||
flush_queued_rx();
|
||||
handle_irq();
|
||||
queued_rx = 0;
|
||||
|
||||
spi_begin();
|
||||
spi_send(AT86RF230_BUF_WRITE);
|
||||
@ -233,7 +254,7 @@ void mac_reset(void)
|
||||
mac_irq = NULL;
|
||||
txing = 0;
|
||||
queued_tx_ack = 0;
|
||||
queued_rx = 0;
|
||||
rx_in = rx_out = 0;
|
||||
next_seq = this_seq = queued_seq = 0;
|
||||
|
||||
/* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */
|
||||
|
@ -47,6 +47,21 @@ void spi_end(void)
|
||||
}
|
||||
|
||||
|
||||
void spi_recv_block(uint8_t *buf, uint8_t n)
|
||||
{
|
||||
if (!n)
|
||||
return;
|
||||
UDR1 = 0;
|
||||
while (--n) {
|
||||
while (!(UCSR1A & 1 << RXC1));
|
||||
*buf++ = UDR1;
|
||||
UDR1 = 0;
|
||||
}
|
||||
while (!(UCSR1A & 1 << RXC1));
|
||||
*buf++ = UDR1;
|
||||
}
|
||||
|
||||
|
||||
void spi_off(void)
|
||||
{
|
||||
spi_initialized = 0;
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* fw/spi.h - ATmega8 family SPI I/O
|
||||
*
|
||||
* Written 2011 by Werner Almesberger
|
||||
* Copyright 2011 Werner Almesberger
|
||||
* Written 2011, 2013 by Werner Almesberger
|
||||
* Copyright 2011, 2013 Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,4 +25,6 @@ void spi_init(void);
|
||||
#define spi_send(v) (void) spi_io(v)
|
||||
#define spi_recv(v) spi_io(0)
|
||||
|
||||
void spi_recv_block(uint8_t *buf, uint8_t n);
|
||||
|
||||
#endif /* !SPI_H */
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -74,6 +75,7 @@ enum mode {
|
||||
|
||||
|
||||
static volatile int run = 1;
|
||||
static bool quick = 0;
|
||||
|
||||
|
||||
/* ----- Helper functions -------------------------------------------------- */
|
||||
@ -237,7 +239,9 @@ static void receive_pcap(struct atrf_dsc *dsc, const char *name)
|
||||
write_pcap_hdr(file);
|
||||
while (run) {
|
||||
wait_for_interrupt(dsc,
|
||||
IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START | IRQ_AMI, 0);
|
||||
IRQ_TRX_END,
|
||||
quick ? 0xff : IRQ_TRX_END | IRQ_RX_START | IRQ_AMI,
|
||||
quick ? -1 : 0);
|
||||
if (!run)
|
||||
break;
|
||||
gettimeofday(&now, NULL);
|
||||
@ -249,7 +253,8 @@ static void receive_pcap(struct atrf_dsc *dsc, const char *name)
|
||||
continue;
|
||||
}
|
||||
write_pcap_rec(file, &now, buf, n-1);
|
||||
(void) write(2, ".", 1);
|
||||
if (!quick)
|
||||
(void) write(2, ".", 1);
|
||||
count++;
|
||||
}
|
||||
if (fclose(file) == EOF) {
|
||||
@ -666,7 +671,7 @@ static void usage(const char *name)
|
||||
" command shell command to run while transmitting (default: wait for\n"
|
||||
" SIGINT instead)\n\n"
|
||||
" common options: [-c channel|-f freq] [-C mhz] [-d driver[:arg]] [-o file]\n"
|
||||
" [-p power] [-r rate] [-t trim]\n"
|
||||
" [-p power] [-q] [-r rate] [-t trim]\n"
|
||||
" -c channel channel number, 11 to 26 (default %d)\n"
|
||||
" -C mhz output clock at 1, 2, 4, 8, or 16 MHz (default: off)\n"
|
||||
" -d driver[:arg]\n"
|
||||
@ -674,6 +679,8 @@ static void usage(const char *name)
|
||||
" -f freq frequency in MHz, 2405 to 2480 (default %d)\n"
|
||||
" -o file write received data to a file in pcap format\n"
|
||||
" -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n"
|
||||
" -q quick and quiet - suppress progress reports and warnings,\n"
|
||||
" poll aggressively (currently only used when capturing)\n"
|
||||
" -r rate data rate, 250k, 500k, 1M, or 2M (default: 250k)\n"
|
||||
" -t trim trim capacitor, 0 to 15 (default %d)\n"
|
||||
, name, name, name, name, name, name,
|
||||
@ -718,7 +725,7 @@ int main(int argc, char *const *argv)
|
||||
const char *pcap_file = NULL;
|
||||
struct atrf_dsc *dsc;
|
||||
|
||||
while ((c = getopt(argc, argv, "c:C:d:E:f:Ho:p:Pr:Rt:T:x")) != EOF)
|
||||
while ((c = getopt(argc, argv, "c:C:d:E:f:Ho:p:Pqr:Rt:T:x")) != EOF)
|
||||
switch (c) {
|
||||
case 'c':
|
||||
channel = strtoul(optarg, &end, 0);
|
||||
@ -767,6 +774,9 @@ int main(int argc, char *const *argv)
|
||||
case 'P':
|
||||
set_mode(&mode, mode_ping);
|
||||
break;
|
||||
case 'q':
|
||||
quick = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if (!strcmp(optarg, "250k"))
|
||||
rate = OQPSK_DATA_RATE_250;
|
||||
|
@ -19,6 +19,14 @@
|
||||
|
||||
|
||||
void flush_interrupts(struct atrf_dsc *dsc);
|
||||
|
||||
/*
|
||||
* timeout_ms:
|
||||
* > 0: time out after that many milliseconds
|
||||
* == 0: wait forever
|
||||
* < 0: wait forever and eliminate poll delays (for high-speed capture)
|
||||
*/
|
||||
|
||||
uint8_t wait_for_interrupt(struct atrf_dsc *dsc, uint8_t wait_for,
|
||||
uint8_t ignore, int timeout_ms);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* lib/atben.c - ATRF access functions library (Ben 8:10 card version)
|
||||
*
|
||||
* Written 2010-2011 by Werner Almesberger
|
||||
* Copyright 2010-2011 Werner Almesberger
|
||||
* Written 2010-2011, 2013 by Werner Almesberger
|
||||
* Copyright 2010-2011, 2013 Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -439,10 +439,10 @@ int atben_interrupt_wait(void *handle, int timeout_ms)
|
||||
int timedout = 0;
|
||||
uint8_t irq;
|
||||
|
||||
if (timeout_ms)
|
||||
if (timeout_ms > 0)
|
||||
timeout_start(&to, timeout_ms);
|
||||
while (1) {
|
||||
if (timeout_ms)
|
||||
if (timeout_ms > 0)
|
||||
timedout = timeout_reached(&to);
|
||||
if (atben_interrupt(handle)) {
|
||||
irq = atben_reg_read(handle, REG_IRQ_STATUS);
|
||||
@ -452,7 +452,8 @@ int atben_interrupt_wait(void *handle, int timeout_ms)
|
||||
}
|
||||
if (timedout)
|
||||
return 0;
|
||||
usleep(1000);
|
||||
if (timeout_ms >= 0)
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -221,7 +221,7 @@ int atusb_interrupt_wait(void *handle, int timeout_ms)
|
||||
return 0;
|
||||
|
||||
res = usb_bulk_read(dsc->dev, 1,
|
||||
(char *) &buf, sizeof(buf), timeout_ms);
|
||||
(char *) &buf, sizeof(buf), timeout_ms < 0 : 0 : timeout_ms);
|
||||
if (res == -ETIMEDOUT)
|
||||
return 0;
|
||||
if (res < 0) {
|
||||
|
@ -62,14 +62,14 @@ uint8_t wait_for_interrupt(struct atrf_dsc *dsc, uint8_t wait_for,
|
||||
|
||||
sigint = 0;
|
||||
old_sig = signal(SIGINT, die);
|
||||
if (timeout_ms) {
|
||||
if (timeout_ms > 0) {
|
||||
if (timeout_ms < MIN_TIMEOUT_MS)
|
||||
timeout_ms = MIN_TIMEOUT_MS;
|
||||
timeout_start(&to, timeout_ms);
|
||||
}
|
||||
while (!sigint && !timedout) {
|
||||
while (!sigint && !timedout) {
|
||||
if (timeout_ms) {
|
||||
if (timeout_ms > 0) {
|
||||
ms = timeout_left_ms(&to);
|
||||
if (ms <= 0) {
|
||||
timedout = 1;
|
||||
@ -78,7 +78,8 @@ uint8_t wait_for_interrupt(struct atrf_dsc *dsc, uint8_t wait_for,
|
||||
} else {
|
||||
ms = 0;
|
||||
}
|
||||
irq = atrf_interrupt_wait(dsc, ms);
|
||||
irq = atrf_interrupt_wait(dsc,
|
||||
timeout_ms < 0 ? -1 : ms);
|
||||
if (irq)
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user