}
uint8_t
-ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant
+ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant
{
ao_radio_abort = 0;
ao_radio_get(size - 2);
/* Wait for DMA to be done, for the radio receive process to
* get aborted or for a receive timeout to fire
*/
+ if (timeout)
+ ao_alarm(timeout);
__critical while (!ao_radio_dma_done && !ao_radio_abort)
if (ao_sleep(&ao_radio_dma_done))
break;
+ if (timeout)
+ ao_clear_alarm();
/* If recv was aborted, clean up by stopping the DMA engine
* and idling the radio
#if HAS_RADIO_RECV
uint8_t
-ao_radio_recv(__xdata void *d, uint8_t size) __reentrant;
+ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) __reentrant;
void
ao_radio_recv_abort(void);
size = ao_monitoring;
break;
}
- if (!ao_radio_recv(&ao_monitor_ring[ao_monitor_head], size + 2))
+ if (!ao_radio_recv(&ao_monitor_ring[ao_monitor_head], size + 2, 0))
continue;
ao_monitor_head = ao_monitor_ring_next(ao_monitor_head);
ao_wakeup(DATA_TO_XDATA(&ao_monitor_head));
#if HAS_MONITOR
ao_monitor_set(0);
#endif
- if (timeout)
- ao_alarm(timeout);
-
- i = ao_radio_recv(cmac_data, len + AO_CMAC_KEY_LEN + 2);
- ao_clear_alarm();
+ i = ao_radio_recv(cmac_data, len + AO_CMAC_KEY_LEN + 2, timeout);
if (!i) {
ao_radio_cmac_rssi = 0;
}
static void
-ao_radio_wait_isr(void)
+ao_radio_wait_isr(uint16_t timeout)
{
+ if (timeout)
+ ao_alarm(timeout);
ao_arch_block_interrupts();
while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort)
- ao_sleep(&ao_radio_wake);
+ if (ao_sleep(&ao_radio_wake))
+ ao_radio_abort = 1;
ao_arch_release_interrupts();
+ if (timeout)
+ ao_clear_alarm();
if (ao_radio_mcu_wake)
ao_radio_check_marc_status();
}
uint8_t fifo_space = 0;
do {
- ao_radio_wait_isr();
+ ao_radio_wait_isr(0);
if (!wait_fifo)
return 0;
fifo_space = ao_radio_tx_fifo_space();
/* Wait for some space in the fifo */
while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
ao_radio_wake = 0;
- ao_radio_wait_isr();
+ ao_radio_wait_isr(0);
}
if (ao_radio_abort)
break;
}
/* Wait for the transmitter to go idle */
ao_radio_wake = 0;
- ao_radio_wait_isr();
+ ao_radio_wait_isr(0);
}
ao_radio_put();
}
}
uint8_t
-ao_radio_recv(__xdata void *d, uint8_t size)
+ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
{
uint8_t len;
uint16_t i;
ao_radio_strobe(CC1120_SRX);
/* Wait for the preamble to appear */
- ao_radio_wait_isr();
+ ao_radio_wait_isr(timeout);
if (ao_radio_abort)
goto abort;
#ifdef AO_LED_GREEN
ao_led_on(AO_LED_GREEN);
#endif
- dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv));
+ dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), 0);
#ifdef AO_LED_GREEN
ao_led_off(AO_LED_GREEN);
#endif
uint8_t
-ao_radio_recv(__xdata void *d, uint8_t size)
+ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
{
int8_t ret;
uint8_t recv;
ao_radio_get(AO_RADIO_SPI_RECV, 0);
ao_radio_spi_request.recv_len = size;
+ ao_radio_spi_request.timeout = timeout;
recv = ao_radio_master_send();
if (!recv) {
ao_radio_put();
ao_config.radio_setting = ao_radio_spi_request.setting;
ao_led_on(AO_LED_RX);
ao_radio_spi_reply.status = ao_radio_recv(&ao_radio_spi_reply.payload,
- ao_radio_spi_request.recv_len);
+ ao_radio_spi_request.recv_len,
+ ao_radio_spi_request.timeout);
ao_led_off(AO_LED_RX);
ao_radio_spi_reply.rssi = 0;
ao_spi_send(&ao_radio_spi_reply,