X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fao_radio.c;h=7b7c5161fb0ac95c2d730f7f44b91136a292c84b;hp=55a0c297eda633431eb4c1a3638f77e62e02b441;hb=d3bc27fabb6159ce58b14d0f7929b0f46f67c378;hpb=9b31f07fe3556896b3e997bba156e30ef5777a80 diff --git a/src/ao_radio.c b/src/ao_radio.c index 55a0c297..7b7c5161 100644 --- a/src/ao_radio.c +++ b/src/ao_radio.c @@ -28,14 +28,6 @@ * RX filter: 93.75 kHz */ -/* - * For 434.550MHz, the frequency value is: - * - * 434.550e6 / (24e6 / 2**16) = 1186611.2 - */ - -#define FREQ_CONTROL 1186611 - /* * For IF freq of 140.62kHz, the IF value is: * @@ -124,10 +116,6 @@ static __code uint8_t radio_setup[] = { RF_PA_TABLE1_OFF, RF_POWER, RF_PA_TABLE0_OFF, RF_POWER, - RF_FREQ2_OFF, (FREQ_CONTROL >> 16) & 0xff, - RF_FREQ1_OFF, (FREQ_CONTROL >> 8) & 0xff, - RF_FREQ0_OFF, (FREQ_CONTROL >> 0) & 0xff, - RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT), RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT), @@ -281,6 +269,25 @@ static __code uint8_t packet_setup[] = { RF_PKTCTRL0_LENGTH_CONFIG_FIXED), }; +__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 +ao_radio_general_isr(void) __interrupt 16 +{ + S1CON &= ~0x03; + if (RFIF & RFIF_IM_TIMEOUT) { + ao_radio_recv_abort(); + RFIF &= ~ RFIF_IM_TIMEOUT; + } else if (RFIF & RFIF_IM_DONE) { + ao_radio_done = 1; + ao_wakeup(&ao_radio_done); + RFIF &= ~RFIF_IM_DONE; + } +} void ao_radio_set_telemetry(void) @@ -306,33 +313,40 @@ ao_radio_set_rdf(void) RF[rdf_setup[i]] = rdf_setup[i+1]; } -__xdata uint8_t ao_radio_dma; -__xdata uint8_t ao_radio_dma_done; -__xdata uint8_t ao_radio_mutex; - void ao_radio_idle(void) { if (RF_MARCSTATE != RF_MARCSTATE_IDLE) { - RFST = RFST_SIDLE; do { + RFST = RFST_SIDLE; ao_yield(); } while (RF_MARCSTATE != RF_MARCSTATE_IDLE); } } void -ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant +ao_radio_get(void) { ao_config_get(); ao_mutex_get(&ao_radio_mutex); ao_radio_idle(); RF_CHANNR = ao_config.radio_channel; + 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); +} + + +void +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, @@ -341,22 +355,20 @@ ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant 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_mutex_put(&ao_radio_mutex); + __critical while (!ao_radio_done) + ao_sleep(&ao_radio_done); + ao_radio_put(); } uint8_t -ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant +ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant { - ao_config_get(); - ao_mutex_get(&ao_radio_mutex); - ao_radio_idle(); - RF_CHANNR = ao_config.radio_channel; + 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, @@ -365,13 +377,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); - ao_mutex_put(&ao_radio_mutex); - return (ao_radio_dma_done & AO_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; +} + +/* + * 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 @@ -379,9 +415,10 @@ ao_radio_rdf(int ms) { uint8_t i; uint8_t pkt_len; - ao_mutex_get(&ao_radio_mutex); - ao_radio_idle(); - ao_radio_rdf_running = 1; + + ao_radio_abort = 0; + ao_radio_get(); + ao_radio_done = 0; for (i = 0; i < sizeof (rdf_setup); i += 2) RF[rdf_setup[i]] = rdf_setup[i+1]; @@ -409,47 +446,58 @@ 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_mutex_put(&ao_radio_mutex); -} - -void -ao_radio_abort(uint8_t reason) -{ - ao_dma_abort(ao_radio_dma, reason); - ao_radio_idle(); + 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); } + /* Output carrier */ void ao_radio_test(void) { - ao_config_get(); - ao_mutex_get(&ao_radio_mutex); - ao_radio_idle(); - printf ("Hit a character to stop..."); flush(); - RFST = RFST_STX; - getchar(); - ao_radio_idle(); - ao_mutex_put(&ao_radio_mutex); - 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 }, }; @@ -462,5 +510,8 @@ ao_radio_init(void) ao_radio_set_telemetry(); ao_radio_dma_done = 1; ao_radio_dma = ao_dma_alloc(&ao_radio_dma_done); + RFIF = 0; + RFIM = RFIM_IM_TIMEOUT|RFIM_IM_DONE; + IEN2 |= IEN2_RFIE; ao_cmd_register(&ao_radio_cmds[0]); }