diff --git a/atusb/fw/board_app.c b/atusb/fw/board_app.c index cbbbf84..d996593 100644 --- a/atusb/fw/board_app.c +++ b/atusb/fw/board_app.c @@ -157,8 +157,8 @@ uint8_t irq_serial; ISR(INT0_vect) { if (mac_irq) { - mac_irq(); - return; + if (mac_irq()) + return; } if (eps[1].state == EP_IDLE) { led(1); diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c index 51681c0..a5ea8d2 100644 --- a/atusb/fw/mac.c +++ b/atusb/fw/mac.c @@ -20,7 +20,7 @@ #include "mac.h" -void (*mac_irq)(void) = NULL; +int (*mac_irq)(void) = NULL; static uint8_t rx_buf[MAX_PSDU+2]; /* PHDR+payload+LQ */ @@ -51,35 +51,30 @@ static void reg_write(uint8_t reg, uint8_t value) } -static void handle_irq(void) +static int handle_irq(void) { uint8_t irq; uint8_t size, i; - irq = reg_read(REG_IRQ_STATUS); - if (!(irq & IRQ_TRX_END)) - return; - - /* - * @@@ we probably also have to handle at least IRQ_PLL_UNLOCK, because - * a PLL unlock should cause a transition out of BUSY_TX without - * TRX_END. - */ if (txing) { txing = 0; - return; + return 0; } + irq = reg_read(REG_IRQ_STATUS); + if (!(irq & IRQ_TRX_END)) + return 1; + /* unlikely */ if (eps[1].state != EP_IDLE) - return; + return 1; spi_begin(); spi_send(AT86RF230_BUF_READ); size = spi_recv(); if (size & 0x80) { spi_end(); - return; + return 1; } rx_buf[0] = size; @@ -87,6 +82,7 @@ static void handle_irq(void) rx_buf[i+1] = spi_recv(); spi_end(); usb_send(&eps[1], rx_buf, size+2, NULL, NULL); + return 1; } diff --git a/atusb/fw/mac.h b/atusb/fw/mac.h index a04e015..b75833e 100644 --- a/atusb/fw/mac.h +++ b/atusb/fw/mac.h @@ -16,7 +16,7 @@ #include -extern void (*mac_irq)(void); +extern int (*mac_irq)(void); int mac_rx(int on); int mac_tx(uint16_t flags, uint16_t len); diff --git a/tools/include/atrf.h b/tools/include/atrf.h index 70d0320..4917a43 100644 --- a/tools/include/atrf.h +++ b/tools/include/atrf.h @@ -57,4 +57,10 @@ uint8_t atrf_sram_read(struct atrf_dsc *dsc, uint8_t addr); int atrf_interrupt_wait(struct atrf_dsc *dsc, int timeout_ms); +/* HardMAC operations */ + +void atrf_rx_mode(struct atrf_dsc *dsc, int on); +int atrf_rx(struct atrf_dsc *dsc, void *buf, int size, uint8_t *lqi); +void atrf_tx(struct atrf_dsc *dsc, const void *buf, int size); + #endif /* !ATRF_H */ diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index 57371e4..1ea295a 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -322,3 +322,25 @@ int atrf_interrupt_wait(struct atrf_dsc *dsc, int timeout_ms) { return dsc->driver->interrupt_wait(dsc->handle, timeout_ms); } + + +void atrf_rx_mode(struct atrf_dsc *dsc, int on) +{ + if (dsc->driver->rx_mode) + dsc->driver->rx_mode(dsc->handle, on); +} + + +int atrf_rx(struct atrf_dsc *dsc, void *buf, int size, uint8_t *lqi) +{ + if (!dsc->driver->rx) + return 0; + return dsc->driver->rx(dsc->handle, buf, size, lqi); +} + + +void atrf_tx(struct atrf_dsc *dsc, const void *buf, int size) +{ + if (dsc->driver->tx) + dsc->driver->tx(dsc->handle, buf, size); +} diff --git a/tools/lib/driver.h b/tools/lib/driver.h index c82c46b..b07f2f7 100644 --- a/tools/lib/driver.h +++ b/tools/lib/driver.h @@ -36,6 +36,9 @@ struct atrf_driver { void (*sram_write)(void *dsc, uint8_t addr, uint8_t value); uint8_t (*sram_read)(void *dsc, uint8_t addr); int (*interrupt_wait)(void *dsc, int timeout_ms); + void (*rx_mode)(void *dsc, int on); + int (*rx)(void *dsc, void *buf, int size, uint8_t *lqi); + void (*tx)(void *dsc, const void *buf, int size); };