X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fao_radio.c;h=3fb4afd7d4831d87c556a201634655e70ba95b3c;hp=ca1ec7e8fcaa1cbdb8ca49a40ad53f184167bd58;hb=d1005f68376d695039c314b8d7a68bbf9acbca4f;hpb=210dbaa23cdacf3a6f2d6e23493e96ee2ac9bca7 diff --git a/src/ao_radio.c b/src/ao_radio.c index ca1ec7e8..3fb4afd7 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: * @@ -77,6 +69,29 @@ #define DEVIATION_M 6 #define DEVIATION_E 3 +/* + * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone), + * so the DRATE_E and DRATE_M values are: + * + * M is 94 and E is 6 + * + * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes + */ + +#define RDF_DRATE_E 6 +#define RDF_DRATE_M 94 +#define RDF_PACKET_LEN 50 + +/* + * RDF deviation should match the normal NFM value of 5kHz + * + * M is 6 and E is 1 + * + */ + +#define RDF_DEVIATION_M 6 +#define RDF_DEVIATION_E 1 + /* This are from the table for 433MHz */ #define RF_POWER_M30_DBM 0x12 @@ -101,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), @@ -184,6 +195,27 @@ static __code uint8_t radio_setup[] = { RF_IOCFG0_OFF, 0x00, }; +static __code uint8_t rdf_setup[] = { + RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | + (RDF_DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), + RF_MDMCFG3_OFF, (RDF_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_DIS | + RF_MDMCFG1_NUM_PREAMBLE_2 | + (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), + + RF_DEVIATN_OFF, ((RDF_DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) | + (RDF_DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)), + + /* packet length is set in-line */ + RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| + PKTCTRL1_ADR_CHK_NONE), + RF_PKTCTRL0_OFF, (RF_PKTCTRL0_PKT_FORMAT_NORMAL| + RF_PKTCTRL0_LENGTH_CONFIG_FIXED), +}; static __code uint8_t telemetry_setup[] = { RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | @@ -211,29 +243,105 @@ static __code uint8_t telemetry_setup[] = { RF_PKTCTRL0_LENGTH_CONFIG_FIXED), }; +static __code uint8_t packet_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_packet), + 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), +}; + __xdata uint8_t ao_radio_dma; __xdata uint8_t ao_radio_dma_done; +__xdata uint8_t ao_radio_done; __xdata uint8_t ao_radio_mutex; -static void +void +ao_radio_general_isr(void) __interrupt 16 +{ + S1CON &= ~0x03; + if (RFIF & RFIF_IM_TIMEOUT) { + ao_dma_abort(ao_radio_dma); + 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) +{ + 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]; +} + +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 struct ao_telemetry *telemetry) __reentrant +{ + ao_radio_get(); + ao_radio_done = 0; ao_dma_set_transfer(ao_radio_dma, telemetry, &RFDXADDR, @@ -246,18 +354,15 @@ 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(); } -void +uint8_t ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant { - ao_config_get(); - ao_mutex_get(&ao_radio_mutex); - ao_radio_idle(); - RF_CHANNR = ao_config.radio_channel; + ao_radio_get(); ao_dma_set_transfer(ao_radio_dma, &RFDXADDR, radio, @@ -272,15 +377,117 @@ ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant RFST = RFST_SRX; __critical while (!ao_radio_dma_done) ao_sleep(&ao_radio_dma_done); - ao_mutex_put(&ao_radio_mutex); + ao_radio_put(); + return (ao_radio_dma_done & AO_DMA_DONE); } +__xdata ao_radio_rdf_running; +__xdata ao_radio_rdf_value = 0x55; + +void +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: + * + * 2000 bps (for a 1kHz tone) + * so, for 'ms' milliseconds, we need + * 2 * ms bits, or ms / 4 bytes + */ + if (ms > (255 * 4)) + ms = 255 * 4; + pkt_len = ms >> 2; + RF[RF_PKTLEN_OFF] = pkt_len; + + ao_dma_set_transfer(ao_radio_dma, + &ao_radio_rdf_value, + &RFDXADDR, + pkt_len, + DMA_CFG0_WORDSIZE_8 | + DMA_CFG0_TMODE_SINGLE | + DMA_CFG0_TRIGGER_RADIO, + DMA_CFG1_SRCINC_0 | + DMA_CFG1_DESTINC_0 | + 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) +{ + ao_dma_abort(ao_radio_dma); + ao_radio_idle(); +} + +void +ao_radio_rdf_abort(void) +{ + if (ao_radio_rdf_running) + ao_radio_abort(); +} + + +/* Output carrier */ +void +ao_radio_test(void) +{ + uint8_t mode = 2; + ao_cmd_white(); + if (ao_cmd_lex_c != '\n') { + ao_cmd_decimal(); + mode = (uint8_t) ao_cmd_lex_u32; + } + mode++; + if (mode & 2) { + ao_set_monitor(0); + ao_packet_slave_stop(); + ao_radio_get(); + RFST = RFST_STX; + } + if (mode == 3) { + printf ("Hit a character to stop..."); flush(); + getchar(); + putchar('\n'); + } + if (mode & 1) { + ao_radio_idle(); + ao_radio_put(); + } +} + +__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 }, +}; + void 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_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]); }