ao_packet_send(void)
{
ao_led_on(AO_LED_RED);
- ao_radio_get();
-
/* 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_packet_tx_used = 0;
ao_wakeup(&tx_data);
}
- ao_radio_done = 0;
- 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_radio_put();
+ ao_radio_send(&ao_tx_packet, sizeof (ao_tx_packet));
ao_led_off(AO_LED_RED);
}
#ifdef AO_LED_GREEN
ao_led_on(AO_LED_GREEN);
#endif
- ao_radio_get();
- 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_radio_put();
+ 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
* 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 */