X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fao_packet.c;h=f627e02b4022ee8004fd5400a4eb20d0d0ed60d8;hp=3ce7e9ab24c0bdfc957f690aa0b9c9ad8a5527e4;hb=2681a17500913cbaf3966f09380bb1d6b59e3863;hpb=7db9d86178ecfd58cc1c17ac9fcbdcfd2f13aaec diff --git a/src/ao_packet.c b/src/ao_packet.c index 3ce7e9ab..f627e02b 100644 --- a/src/ao_packet.c +++ b/src/ao_packet.c @@ -33,8 +33,7 @@ void ao_packet_send(void) { ao_led_on(AO_LED_RED); - ao_config_get(); - ao_mutex_get(&ao_radio_mutex); + /* If any tx data is pending then copy it into the tx packet */ if (ao_packet_tx_used && ao_tx_packet.len == 0) { memcpy(&ao_tx_packet.d, tx_data, ao_packet_tx_used); ao_tx_packet.len = ao_packet_tx_used; @@ -42,24 +41,7 @@ ao_packet_send(void) ao_packet_tx_used = 0; ao_wakeup(&tx_data); } - ao_radio_idle(); - ao_radio_done = 0; - RF_CHANNR = ao_config.radio_channel; - ao_dma_set_transfer(ao_radio_dma, - &ao_tx_packet, - &RFDXADDR, - sizeof (struct ao_packet), - DMA_CFG0_WORDSIZE_8 | - DMA_CFG0_TMODE_SINGLE | - DMA_CFG0_TRIGGER_RADIO, - DMA_CFG1_SRCINC_1 | - DMA_CFG1_DESTINC_0 | - DMA_CFG1_PRIORITY_HIGH); - ao_dma_start(ao_radio_dma); - RFST = RFST_STX; - __critical while (!ao_radio_done) - ao_sleep(&ao_radio_done); - ao_mutex_put(&ao_radio_mutex); + ao_radio_send(&ao_tx_packet, sizeof (ao_tx_packet)); ao_led_off(AO_LED_RED); } @@ -68,55 +50,66 @@ ao_packet_recv(void) { uint8_t dma_done; +#ifdef AO_LED_GREEN ao_led_on(AO_LED_GREEN); - ao_config_get(); - ao_mutex_get(&ao_radio_mutex); - ao_radio_idle(); - RF_CHANNR = ao_config.radio_channel; - ao_dma_set_transfer(ao_radio_dma, - &RFDXADDR, - &ao_rx_packet, - sizeof (struct ao_packet_recv), - DMA_CFG0_WORDSIZE_8 | - DMA_CFG0_TMODE_SINGLE | - DMA_CFG0_TRIGGER_RADIO, - DMA_CFG1_SRCINC_0 | - DMA_CFG1_DESTINC_1 | - DMA_CFG1_PRIORITY_HIGH); - ao_dma_start(ao_radio_dma); - RFST = RFST_SRX; - __critical while (!ao_radio_dma_done) - if (ao_sleep(&ao_radio_dma_done) != 0) - ao_radio_abort(); - dma_done = ao_radio_dma_done; - ao_mutex_put(&ao_radio_mutex); +#endif + dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv)); +#ifdef AO_LED_GREEN ao_led_off(AO_LED_GREEN); +#endif - if (dma_done & AO_DMA_DONE) { - if (!(ao_rx_packet.status & PKT_APPEND_STATUS_1_CRC_OK)) - return AO_DMA_ABORTED; - if (ao_rx_packet.packet.len == AO_PACKET_SYN) { + /* Check to see if we got a valid packet */ + if (!dma_done) + return 0; + if (!(ao_rx_packet.status & PKT_APPEND_STATUS_1_CRC_OK)) + return 0; + + /* SYN packets carry no data */ + if (ao_rx_packet.packet.len == AO_PACKET_SYN) { + rx_seq = ao_rx_packet.packet.seq; + ao_tx_packet.seq = ao_rx_packet.packet.ack; + ao_tx_packet.ack = rx_seq; + } else if (ao_rx_packet.packet.len) { + + /* Check for incoming data at the next sequence and + * for an empty data buffer + */ + if (ao_rx_packet.packet.seq == (uint8_t) (rx_seq + (uint8_t) 1) && + ao_packet_rx_used == ao_packet_rx_len) { + + /* Copy data to the receive data buffer and set up the + * offsets + */ + memcpy(rx_data, ao_rx_packet.packet.d, ao_rx_packet.packet.len); + ao_packet_rx_used = 0; + ao_packet_rx_len = ao_rx_packet.packet.len; + + /* Mark the sequence that we've received to + * let the sender know when we return a packet + */ rx_seq = ao_rx_packet.packet.seq; - ao_tx_packet.seq = ao_rx_packet.packet.ack; ao_tx_packet.ack = rx_seq; - } else if (ao_rx_packet.packet.len) { - if (ao_rx_packet.packet.seq == (uint8_t) (rx_seq + (uint8_t) 1) && ao_packet_rx_used == ao_packet_rx_len) { - memcpy(rx_data, ao_rx_packet.packet.d, ao_rx_packet.packet.len); - ao_packet_rx_used = 0; - ao_packet_rx_len = ao_rx_packet.packet.len; - rx_seq = ao_rx_packet.packet.seq; - ao_tx_packet.ack = rx_seq; - ao_wakeup(&ao_stdin_ready); - } - } - if (ao_rx_packet.packet.ack == ao_tx_packet.seq) { - ao_tx_packet.len = 0; - ao_wakeup(&ao_tx_packet); + + /* Poke anyone looking for received data */ + ao_wakeup(&ao_stdin_ready); } } - return dma_done; + + /* If the other side has seen the latest data we queued, + * wake up any task waiting to send data and let them go again + */ + if (ao_rx_packet.packet.ack == ao_tx_packet.seq) { + ao_tx_packet.len = 0; + ao_wakeup(&ao_tx_packet); + } + return 1; } +#ifndef PACKET_HAS_MASTER +#define PACKET_HAS_MASTER 1 +#endif + +#if PACKET_HAS_MASTER void ao_packet_flush(void) { @@ -124,14 +117,17 @@ ao_packet_flush(void) * then poke the master to send all queued data */ if (ao_packet_tx_used && ao_packet_master_sleeping) - ao_wake_task(&ao_packet_task); + ao_wakeup(&ao_packet_master_sleeping); } +#endif /* PACKET_HAS_MASTER */ void ao_packet_putchar(char c) __reentrant { while (ao_packet_tx_used == AO_PACKET_MAX && ao_packet_enable) { +#if PACKET_HAS_MASTER ao_packet_flush(); +#endif ao_sleep(&tx_data); }