altos: clean up radio abort paths. Share radio code.
[fw/altos] / src / ao_packet.c
index d52f2a68b89815ee9f89896dbc874e8eed966cc2..9896149cbff480efe10c67d5e3846c670554fe14 100644 (file)
@@ -33,8 +33,6 @@ void
 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);
@@ -43,22 +41,7 @@ ao_packet_send(void)
                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);
 }
 
@@ -70,51 +53,56 @@ ao_packet_recv(void)
 #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