X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fao_radio.c;h=362b73aa3053c67452ace38ce15fa879aed4d0bb;hp=f4a9d3b265edb1a82ea37ee95cac9568022da9c6;hb=07213dc34fa20470a4b36a327a83d75b0f010ebb;hpb=2923cf5057f9cef110dd547d8677ea5b60e00796 diff --git a/src/ao_radio.c b/src/ao_radio.c index f4a9d3b2..362b73aa 100644 --- a/src/ao_radio.c +++ b/src/ao_radio.c @@ -272,6 +272,7 @@ static __code uint8_t packet_setup[] = { __xdata uint8_t ao_radio_dma; __xdata uint8_t ao_radio_dma_done; __xdata uint8_t ao_radio_done; +__xdata uint8_t ao_radio_abort; __xdata uint8_t ao_radio_mutex; void @@ -279,7 +280,7 @@ ao_radio_general_isr(void) __interrupt 16 { S1CON &= ~0x03; if (RFIF & RFIF_IM_TIMEOUT) { - ao_dma_abort(ao_radio_dma); + ao_radio_recv_abort(); RFIF &= ~ RFIF_IM_TIMEOUT; } else if (RFIF & RFIF_IM_DONE) { ao_radio_done = 1; @@ -338,14 +339,14 @@ ao_radio_get(void) void -ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant +ao_radio_send(__xdata void *packet, uint8_t size) __reentrant { ao_radio_get(); ao_radio_done = 0; ao_dma_set_transfer(ao_radio_dma, - telemetry, + packet, &RFDXADDR, - sizeof (struct ao_telemetry), + size, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | DMA_CFG0_TRIGGER_RADIO, @@ -360,13 +361,14 @@ ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant } uint8_t -ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant +ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant { + ao_radio_abort = 0; ao_radio_get(); ao_dma_set_transfer(ao_radio_dma, &RFDXADDR, - radio, - sizeof (struct ao_radio_recv), + packet, + size, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | DMA_CFG0_TRIGGER_RADIO, @@ -375,13 +377,32 @@ ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant DMA_CFG1_PRIORITY_HIGH); ao_dma_start(ao_radio_dma); RFST = RFST_SRX; - __critical while (!ao_radio_dma_done) - ao_sleep(&ao_radio_dma_done); + __critical while (!ao_radio_dma_done && !ao_radio_abort) + ao_sleep(&ao_radio_dma_done); + + /* If recv was aborted, clean up by stopping the DMA engine + * and idling the radio + */ + if (!ao_radio_dma_done) { + ao_dma_abort(ao_radio_dma); + ao_radio_idle(); + } ao_radio_put(); - return (ao_radio_dma_done & AO_DMA_DONE); + return ao_radio_dma_done; +} + +/* + * Wake up a task waiting to receive a radio packet + * and tell them to abort the transfer + */ + +void +ao_radio_recv_abort(void) +{ + ao_radio_abort = 1; + ao_wakeup(&ao_radio_dma_done); } -__xdata ao_radio_rdf_running; __xdata ao_radio_rdf_value = 0x55; void @@ -390,8 +411,9 @@ ao_radio_rdf(int ms) uint8_t i; uint8_t pkt_len; + ao_radio_abort = 0; ao_radio_get(); - ao_radio_rdf_running = 1; + ao_radio_done = 0; for (i = 0; i < sizeof (rdf_setup); i += 2) RF[rdf_setup[i]] = rdf_setup[i+1]; @@ -419,28 +441,22 @@ ao_radio_rdf(int ms) DMA_CFG1_PRIORITY_HIGH); ao_dma_start(ao_radio_dma); RFST = RFST_STX; - - __critical while (!ao_radio_dma_done) - ao_sleep(&ao_radio_dma_done); - ao_radio_rdf_running = 0; - ao_radio_idle(); + __critical while (!ao_radio_done && !ao_radio_abort) + ao_sleep(&ao_radio_done); + if (!ao_radio_done) { + ao_dma_abort(ao_radio_dma); + ao_radio_idle(); + } for (i = 0; i < sizeof (telemetry_setup); i += 2) RF[telemetry_setup[i]] = telemetry_setup[i+1]; ao_radio_put(); } -void -ao_radio_abort(void) -{ - ao_dma_abort(ao_radio_dma); - ao_radio_idle(); -} - void ao_radio_rdf_abort(void) { - if (ao_radio_rdf_running) - ao_radio_abort(); + ao_radio_abort = 1; + ao_wakeup(&ao_radio_done); } @@ -448,19 +464,35 @@ ao_radio_rdf_abort(void) void ao_radio_test(void) { - ao_set_monitor(0); - ao_packet_slave_stop(); - ao_radio_get(); - printf ("Hit a character to stop..."); flush(); - RFST = RFST_STX; - getchar(); - ao_radio_idle(); - ao_radio_put(); - putchar('\n'); + uint8_t mode = 2; + static __xdata radio_on; + ao_cmd_white(); + if (ao_cmd_lex_c != '\n') { + ao_cmd_decimal(); + mode = (uint8_t) ao_cmd_lex_u32; + } + mode++; + if ((mode & 2) && !radio_on) { + ao_set_monitor(0); + ao_packet_slave_stop(); + ao_radio_get(); + RFST = RFST_STX; + radio_on = 1; + } + if (mode == 3) { + printf ("Hit a character to stop..."); flush(); + getchar(); + putchar('\n'); + } + if ((mode & 1) && radio_on) { + ao_radio_idle(); + ao_radio_put(); + radio_on = 0; + } } __code struct ao_cmds ao_radio_cmds[] = { - { 'C', ao_radio_test, "C Radio carrier test" }, + { 'C', ao_radio_test, "C <1 start, 0 stop, none both> Radio carrier test" }, { 0, ao_radio_test, NULL }, };