X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fdrivers%2Fao_cc1200.c;h=727097441007fee784b2e570fd57d7d315ec7466;hb=bf51520898fb30b289b2e03b31a1719c172cf422;hp=45f5711ee3e465c18176543c8c1d58b5d97d98fb;hpb=c417ab1de2a083b5fcff2e081e4feb2a65887903;p=fw%2Faltos diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index 45f5711e..72709744 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -25,6 +25,8 @@ #include #endif +static uint8_t cc1201; + static uint8_t ao_radio_mutex; static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */ @@ -51,9 +53,7 @@ extern const uint32_t ao_radio_cal; #define FOSC 40000000 #endif -#ifndef AO_CC1200_SPI_SPEED -#error AO_CC1200_SPI_SPEED undefined -#endif +#define AO_CC1200_SPI_SPEED ao_spi_speed(7700000) /* 7.7MHz max for extended memory reads */ #define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_CC1200_SPI_SPEED) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS) @@ -75,12 +75,12 @@ ao_radio_reg_read(uint16_t addr) data[0] = ((1 << CC1200_READ) | (0 << CC1200_BURST) | CC1200_EXTENDED); - data[1] = addr; + data[1] = (uint8_t) addr; d = 2; } else { data[0] = ((1 << CC1200_READ) | (0 << CC1200_BURST) | - addr); + (uint8_t) addr); d = 1; } ao_radio_select(); @@ -106,12 +106,12 @@ ao_radio_reg_write(uint16_t addr, uint8_t value) data[0] = ((0 << CC1200_READ) | (0 << CC1200_BURST) | CC1200_EXTENDED); - data[1] = addr; + data[1] = (uint8_t) addr; d = 2; } else { data[0] = ((0 << CC1200_READ) | (0 << CC1200_BURST) | - addr); + (uint8_t) addr); d = 1; } data[d] = value; @@ -192,7 +192,7 @@ ao_radio_fifo_write_fixed(uint8_t data, uint8_t len) static uint8_t ao_radio_int_pin(void) { - return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_CC1200_INT); + return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); } static uint8_t @@ -204,6 +204,7 @@ ao_radio_status(void) void ao_radio_recv_abort(void) { + ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); ao_radio_abort = 1; ao_wakeup(&ao_radio_wake); } @@ -213,7 +214,6 @@ ao_radio_recv_abort(void) static void ao_radio_isr(void) { - ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); ao_radio_wake = 1; ao_wakeup(&ao_radio_wake); } @@ -221,14 +221,12 @@ ao_radio_isr(void) static void ao_radio_start_tx(void) { - ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); ao_radio_strobe(CC1200_STX); } static void ao_radio_start_rx(void) { - ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); ao_radio_strobe(CC1200_SRX); } @@ -331,13 +329,24 @@ ao_radio_idle(void) #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) +/* + * CC1201 doesn't support our low bandwidth receive setups, so we use + * larger values for that part, leaving the bandwidth at over 50kHz + */ + /* 200 / 10 = 20 */ -#define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ - (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) +#define PACKET_CHAN_BW_96_CC1200 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ + (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) + +#define PACKET_CHAN_BW_96_CC1201 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ + (8 << CC1200_CHAN_BW_BB_CIC_DECFACT)) /* 200 / 25 = 8 */ -#define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ - (44 << CC1200_CHAN_BW_BB_CIC_DECFACT)) +#define PACKET_CHAN_BW_24_CC1200 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ + (44 << CC1200_CHAN_BW_BB_CIC_DECFACT)) + +#define PACKET_CHAN_BW_24_CC1201 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ + (8 << CC1200_CHAN_BW_BB_CIC_DECFACT)) static const uint16_t packet_setup[] = { CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff), @@ -379,7 +388,6 @@ static const uint16_t packet_setup_96[] = { (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)), CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) | (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), - CC1200_CHAN_BW, PACKET_CHAN_BW_96, CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | @@ -394,7 +402,6 @@ static const uint16_t packet_setup_24[] = { (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)), CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) | (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), - CC1200_CHAN_BW, PACKET_CHAN_BW_24, CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | @@ -566,8 +573,7 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_BITS_PACKET 1 #define AO_RADIO_MODE_BITS_TX_BUF 4 -#define AO_RADIO_MODE_BITS_TX_FINISH 8 -#define AO_RADIO_MODE_BITS_RX 16 +#define AO_RADIO_MODE_BITS_FINISH 8 #define AO_RADIO_MODE_BITS_RDF 32 #define AO_RADIO_MODE_BITS_APRS 64 #define AO_RADIO_MODE_BITS_TEST 128 @@ -575,12 +581,12 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_BITS_FIXED 512 #define AO_RADIO_MODE_NONE 0 -#define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) -#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_RX) -#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH) +#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH) +#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH) #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF) -#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH) #define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) static void @@ -589,7 +595,7 @@ _ao_radio_set_regs(const uint16_t *regs, int nreg) int i; for (i = 0; i < nreg; i++) { - ao_radio_reg_write(regs[0], regs[1]); + ao_radio_reg_write(regs[0], (uint8_t) regs[1]); regs += 2; } } @@ -604,7 +610,7 @@ ao_radio_set_mode(uint16_t new_mode) if (new_mode == ao_radio_mode) return; - changes = new_mode & (~ao_radio_mode); + changes = (uint16_t) (new_mode & (~ao_radio_mode)); if (changes & AO_RADIO_MODE_BITS_PACKET) { ao_radio_set_regs(packet_setup); @@ -616,26 +622,27 @@ ao_radio_set_mode(uint16_t new_mode) break; case AO_RADIO_RATE_9600: ao_radio_set_regs(packet_setup_96); + if (cc1201) + ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_96_CC1201); + else + ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_96_CC1200); break; case AO_RADIO_RATE_2400: ao_radio_set_regs(packet_setup_24); + if (cc1201) + ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_24_CC1201); + else + ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_24_CC1200); break; } } if (changes & AO_RADIO_MODE_BITS_TX_BUF) { ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR); - ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); } - if (changes & AO_RADIO_MODE_BITS_TX_FINISH) { + if (changes & AO_RADIO_MODE_BITS_FINISH) { ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX); - ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); - } - - if (changes & AO_RADIO_MODE_BITS_RX) { - ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP); - ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH); } if (changes & AO_RADIO_MODE_BITS_RDF) @@ -665,6 +672,11 @@ static uint8_t ao_radio_configured = 0; static void ao_radio_setup(void) { + uint8_t partnumber = ao_radio_reg_read(CC1200_PARTNUMBER); + + if (partnumber == CC1200_PARTNUMBER_CC1201) + cc1201 = 1; + ao_radio_strobe(CC1200_SRES); ao_radio_set_regs(radio_setup); @@ -694,22 +706,35 @@ ao_radio_get(uint8_t len) { static uint32_t last_radio_setting; static uint8_t last_radio_rate; + static uint8_t last_radio_10mw; ao_mutex_get(&ao_radio_mutex); if (!ao_radio_configured) ao_radio_setup(); if (ao_config.radio_setting != last_radio_setting) { - ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16); - ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8); - ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting); + ao_radio_reg_write(CC1200_FREQ2, (uint8_t) (ao_config.radio_setting >> 16)); + ao_radio_reg_write(CC1200_FREQ1, (uint8_t) (ao_config.radio_setting >> 8)); + ao_radio_reg_write(CC1200_FREQ0, (uint8_t) ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; ao_radio_strobe(CC1200_SCAL); } if (ao_config.radio_rate != last_radio_rate) { - ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET; + ao_radio_mode &= (uint16_t) ~AO_RADIO_MODE_BITS_PACKET; last_radio_rate = ao_config.radio_rate; } + if(ao_config.radio_10mw != last_radio_10mw) { + last_radio_10mw = ao_config.radio_10mw; + /* + * 0x37 "should" be 10dBm, but measurements on TBT + * v4.0 show that too hot, so use * 0x32 to make sure + * we're in spec. + */ + if (ao_config.radio_10mw) + ao_radio_reg_write(CC1200_PA_CFG1, 0x32); + else + ao_radio_reg_write(CC1200_PA_CFG1, 0x3f); + } ao_radio_set_len(len); } @@ -721,8 +746,8 @@ ao_radio_state(void) return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK; } -#if CC1200_DEBUG -void +#if CC1200_DEBUG_ +static void ao_radio_show_state(char *where) { printf("%s: state %d len %d rxbytes %d\n", @@ -737,12 +762,18 @@ ao_radio_show_state(char *where) /* Wait for the radio to signal an interrupt */ static void -ao_radio_wait_isr(uint16_t timeout) +_ao_radio_wait_isr(AO_TICK_TYPE timeout) { - ao_arch_block_interrupts(); while (!ao_radio_wake && !ao_radio_abort) if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; +} + +static void +ao_radio_wait_isr(AO_TICK_TYPE timeout) +{ + ao_arch_block_interrupts(); + _ao_radio_wait_isr(timeout); ao_arch_release_interrupts(); } @@ -859,7 +890,7 @@ ao_radio_test_cmd(void) uint8_t mode = 2; ao_cmd_white(); if (ao_cmd_lex_c != '\n') - mode = ao_cmd_decimal(); + mode = (uint8_t) ao_cmd_decimal(); mode++; if ((mode & 2)) ao_radio_test_on(); @@ -905,14 +936,15 @@ ao_radio_send_aprs(ao_radio_fill_func fill) /* At the last buffer, set the total length */ if (done) - ao_radio_set_len(total & 0xff); + ao_radio_set_len((uint8_t) (total & 0xff)); /* Wait for some space in the fifo */ + ao_arch_block_interrupts(); while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) { ao_radio_wake = 0; - ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); + _ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); } + ao_arch_release_interrupts(); if (ao_radio_abort) break; @@ -921,18 +953,19 @@ ao_radio_send_aprs(ao_radio_fill_func fill) else ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); - ao_radio_fifo_write(buf, cnt); + ao_radio_fifo_write(buf, (uint8_t) cnt); if (!started) { ao_radio_strobe(CC1200_STX); started = 1; } } /* Wait for the transmitter to go idle */ + ao_arch_block_interrupts(); while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) { ao_radio_wake = 0; - ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); + _ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); } + ao_arch_release_interrupts(); if (ao_radio_abort) ao_radio_idle(); ao_radio_put(); @@ -986,7 +1019,7 @@ ao_radio_dump_state(struct ao_radio_state *s) #endif uint8_t -ao_radio_recv(void *d, uint8_t size, uint8_t timeout) +ao_radio_recv(void *d, uint8_t size, AO_TICK_TYPE timeout) { uint8_t success = 0; @@ -998,6 +1031,8 @@ ao_radio_recv(void *d, uint8_t size, uint8_t timeout) while (!ao_radio_abort) { ao_radio_wait_isr(timeout); + if (ao_radio_abort) + break; if (ao_radio_wake) { uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1); @@ -1047,13 +1082,13 @@ ao_radio_recv(void *d, uint8_t size, uint8_t timeout) switch (ao_config.radio_rate) { default: case AO_RADIO_RATE_38400: - timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 384) + 1; + timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 384) + 1; break; case AO_RADIO_RATE_9600: - timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 96) + 1; + timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 96) + 1; break; case AO_RADIO_RATE_2400: - timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 24) + 1; + timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 24) + 1; break; } } @@ -1074,7 +1109,7 @@ ao_radio_recv(void *d, uint8_t size, uint8_t timeout) rssi = -11; /* Write it back to the packet */ - ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi); + ((uint8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi); } else { ao_radio_idle(); ao_radio_rssi = 0; @@ -1322,7 +1357,7 @@ static void ao_radio_packet(void) { ao_radio_send(packet, sizeof (packet)); } -void +static void ao_radio_test_recv(void) { static uint8_t bytes[34]; @@ -1446,5 +1481,7 @@ ao_radio_init(void) AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH, ao_radio_isr); + ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); + ao_cmd_register(&ao_radio_cmds[0]); }