X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fao_radio.c;h=4c382bb9685b1f66045678066553e0d7e7378ffe;hp=b2105ff89c41e3add1f5a86aade8d650952ed953;hb=6492218fc316f8cf6214a577807a8dd0a80a9b6a;hpb=54468e5dc567aaac5c5c20e921859b7cec28bb88 diff --git a/src/ao_radio.c b/src/ao_radio.c index b2105ff8..4c382bb9 100644 --- a/src/ao_radio.c +++ b/src/ao_radio.c @@ -161,8 +161,6 @@ static __code uint8_t radio_setup[] = { RF_SYNC0_OFF, 0x91, /* max packet length */ - RF_PKTLEN_OFF, sizeof (struct ao_telemetry), - RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| PKTCTRL1_APPEND_STATUS| PKTCTRL1_ADR_CHK_NONE), @@ -217,33 +215,7 @@ static __code uint8_t rdf_setup[] = { RF_PKTCTRL0_LENGTH_CONFIG_FIXED), }; -static __code uint8_t telemetry_setup[] = { - RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | - (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | - (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), - RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT), - RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF | - RF_MDMCFG2_MOD_FORMAT_GFSK | - RF_MDMCFG2_SYNC_MODE_15_16_THRES), - RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN | - RF_MDMCFG1_NUM_PREAMBLE_4 | - (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), - - RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) | - (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)), - - /* max packet length */ - RF_PKTLEN_OFF, sizeof (struct ao_telemetry), - RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| - PKTCTRL1_APPEND_STATUS| - PKTCTRL1_ADR_CHK_NONE), - RF_PKTCTRL0_OFF, (RF_PKTCTRL0_WHITE_DATA| - RF_PKTCTRL0_PKT_FORMAT_NORMAL| - RF_PKTCTRL0_CRC_EN| - RF_PKTCTRL0_LENGTH_CONFIG_FIXED), -}; - -static __code uint8_t packet_setup[] = { +static __code uint8_t fixed_pkt_setup[] = { RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), @@ -258,8 +230,7 @@ static __code uint8_t packet_setup[] = { RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) | (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)), - /* max packet length */ - RF_PKTLEN_OFF, sizeof (struct ao_packet), + /* max packet length -- now set inline */ RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| PKTCTRL1_APPEND_STATUS| PKTCTRL1_ADR_CHK_NONE), @@ -272,6 +243,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 +251,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; @@ -288,28 +260,12 @@ ao_radio_general_isr(void) __interrupt 16 } } -void -ao_radio_set_telemetry(void) -{ - uint8_t i; - for (i = 0; i < sizeof (telemetry_setup); i += 2) - RF[telemetry_setup[i]] = telemetry_setup[i+1]; -} - void ao_radio_set_packet(void) { uint8_t i; - for (i = 0; i < sizeof (packet_setup); i += 2) - RF[packet_setup[i]] = packet_setup[i+1]; -} - -void -ao_radio_set_rdf(void) -{ - uint8_t i; - for (i = 0; i < sizeof (rdf_setup); i += 2) - RF[rdf_setup[i]] = rdf_setup[i+1]; + for (i = 0; i < sizeof (fixed_pkt_setup); i += 2) + RF[fixed_pkt_setup[i]] = fixed_pkt_setup[i+1]; } void @@ -325,7 +281,7 @@ ao_radio_idle(void) } void -ao_radio_get(void) +ao_radio_get(uint8_t len) { ao_config_get(); ao_mutex_get(&ao_radio_mutex); @@ -334,18 +290,19 @@ ao_radio_get(void) RF_FREQ2 = (uint8_t) (ao_config.radio_cal >> 16); RF_FREQ1 = (uint8_t) (ao_config.radio_cal >> 8); RF_FREQ0 = (uint8_t) (ao_config.radio_cal); + RF_PKTLEN = len; } 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_get(size); 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 +317,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_get(); + ao_radio_abort = 0; + ao_radio_get(size - 2); 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 +333,37 @@ 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); + + /* Wait for DMA to be done, for the radio receive process to + * get aborted or for a receive timeout to fire + */ + __critical while (!ao_radio_dma_done && !ao_radio_abort) + if (ao_sleep(&ao_radio_dma_done)) + break; + + /* 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,11 +372,6 @@ ao_radio_rdf(int ms) uint8_t i; uint8_t pkt_len; - ao_radio_get(); - ao_radio_rdf_running = 1; - for (i = 0; i < sizeof (rdf_setup); i += 2) - RF[rdf_setup[i]] = rdf_setup[i+1]; - /* * Compute the packet length as follows: * @@ -405,7 +382,12 @@ ao_radio_rdf(int ms) if (ms > (255 * 4)) ms = 255 * 4; pkt_len = ms >> 2; - RF[RF_PKTLEN_OFF] = pkt_len; + + ao_radio_abort = 0; + ao_radio_get(pkt_len); + ao_radio_done = 0; + for (i = 0; i < sizeof (rdf_setup); i += 2) + RF[rdf_setup[i]] = rdf_setup[i+1]; ao_dma_set_transfer(ao_radio_dma, &ao_radio_rdf_value, @@ -419,31 +401,21 @@ 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(); - 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) -{ - /* Only abort if a task is waiting to receive data */ - if (RFST == RFST_SRX) { + __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(); } + ao_radio_set_packet(); + ao_radio_put(); } void ao_radio_rdf_abort(void) { - if (ao_radio_rdf_running) - ao_radio_abort(); + ao_radio_abort = 1; + ao_wakeup(&ao_radio_done); } @@ -452,32 +424,37 @@ void ao_radio_test(void) { 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) { + if ((mode & 2) && !radio_on) { ao_set_monitor(0); +#if PACKET_HAS_SLAVE ao_packet_slave_stop(); - ao_radio_get(); +#endif + ao_radio_get(0xff); RFST = RFST_STX; + radio_on = 1; } if (mode == 3) { printf ("Hit a character to stop..."); flush(); getchar(); putchar('\n'); } - if (mode & 1) { + 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 <1 start, 0 stop, none both> Radio carrier test" }, - { 0, ao_radio_test, NULL }, + { ao_radio_test, "C <1 start, 0 stop, none both>\0Radio carrier test" }, + { 0, NULL }, }; void @@ -486,7 +463,7 @@ ao_radio_init(void) uint8_t i; for (i = 0; i < sizeof (radio_setup); i += 2) RF[radio_setup[i]] = radio_setup[i+1]; - ao_radio_set_telemetry(); + ao_radio_set_packet(); ao_radio_dma_done = 1; ao_radio_dma = ao_dma_alloc(&ao_radio_dma_done); RFIF = 0;