X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_cc1200.c;h=6f04380300c59c8547e2fd3e3f85cf811dc7d426;hp=df4bd335a974ba3d6df76143f4faf9b67de14d58;hb=c89268c1fa70fbdc661ac0963b9f8fe22c42bbfe;hpb=4af4e36cda96d053458eeb040e35886890917385 diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index df4bd335..6f043803 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,6 +21,11 @@ #include #include #include +#if HAS_PAD +#include +#endif + +static uint8_t cc1201; static uint8_t ao_radio_mutex; @@ -41,9 +47,15 @@ int8_t ao_radio_rssi; /* Last received RSSI value */ extern const uint32_t ao_radio_cal; +#ifdef AO_CC1200_FOSC +#define FOSC AO_CC1200_FOSC +#else #define FOSC 40000000 +#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_SPI_SPEED_FAST) +#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) #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS) #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS) @@ -178,9 +190,9 @@ ao_radio_fifo_write_fixed(uint8_t data, uint8_t len) } static uint8_t -ao_radio_tx_fifo_space(void) +ao_radio_int_pin(void) { - return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES); + return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); } static uint8_t @@ -301,23 +313,42 @@ ao_radio_idle(void) * CHANBW = 5.0 (round to 9.5) */ +#if FOSC == 40000000 #define PACKET_SYMBOL_RATE_M 1013008 - #define PACKET_SYMBOL_RATE_E_384 8 +#define PACKET_SYMBOL_RATE_E_96 6 +#define PACKET_SYMBOL_RATE_E_24 4 +#endif + +#if FOSC == 32000000 +#define PACKET_SYMBOL_RATE_M 239914 +#define PACKET_SYMBOL_RATE_E_384 9 +#define PACKET_SYMBOL_RATE_E_96 7 +#define PACKET_SYMBOL_RATE_E_24 5 +#endif /* 200 / 2 = 100 */ #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)) -#define PACKET_SYMBOL_RATE_E_96 6 +/* + * 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)) -#define PACKET_SYMBOL_RATE_E_24 4 /* 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), @@ -359,7 +390,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) | @@ -374,7 +404,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) | @@ -467,6 +496,7 @@ static const uint16_t rdf_setup[] = { */ #define APRS_SYMBOL_RATE_E 6 #define APRS_SYMBOL_RATE_M 1013008 +#define APRS_BUFFER_SIZE 64 static const uint16_t aprs_setup[] = { CC1200_DEVIATION_M, APRS_DEV_M, @@ -501,6 +531,9 @@ static const uint16_t aprs_setup[] = { (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | (0 << CC1200_MDMCFG2_CFM_DATA_EN)), + CC1200_FIFO_CFG, + ((0 << CC1200_FIFO_CFG_CRC_AUTOFLUSH) | + (APRS_BUFFER_SIZE << CC1200_FIFO_CFG_FIFO_THR)), }; /* @@ -592,9 +625,17 @@ 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; } } @@ -641,6 +682,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); @@ -697,8 +743,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", @@ -783,23 +829,20 @@ ao_radio_rdf_abort(void) ao_wakeup(&ao_radio_wake); } -static void -ao_radio_test_cmd(void) +static uint8_t radio_on; + +void +ao_radio_test_on(void) { - uint8_t mode = 2; - static uint8_t 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) { + if (!radio_on) { #if HAS_MONITOR ao_monitor_disable(); #endif #if PACKET_HAS_SLAVE ao_packet_slave_stop(); +#endif +#if HAS_PAD + ao_pad_disable(); #endif ao_radio_get(0xff); ao_radio_set_mode(AO_RADIO_MODE_TEST); @@ -814,21 +857,43 @@ ao_radio_test_cmd(void) #endif radio_on = 1; } - if (mode == 3) { - printf ("Hit a character to stop..."); flush(); - getchar(); - putchar('\n'); - } - if ((mode & 1) && radio_on) { +} + +void +ao_radio_test_off(void) +{ + if (radio_on) { ao_radio_idle(); ao_radio_put(); radio_on = 0; #if HAS_MONITOR ao_monitor_enable(); +#endif +#if HAS_PAD + ao_pad_enable(); #endif } } +static void +ao_radio_test_cmd(void) +{ + uint8_t mode = 2; + ao_cmd_white(); + if (ao_cmd_lex_c != '\n') + mode = ao_cmd_decimal(); + mode++; + if ((mode & 2)) + ao_radio_test_on(); + if (mode == 3) { + printf ("Hit a character to stop..."); flush(); + getchar(); + putchar('\n'); + } + if ((mode & 1)) + ao_radio_test_off(); +} + void ao_radio_send(const void *d, uint8_t size) { @@ -840,105 +905,58 @@ ao_radio_send(const void *d, uint8_t size) ao_radio_run(); } - -#define AO_RADIO_LOTS 64 - void ao_radio_send_aprs(ao_radio_fill_func fill) { - uint8_t buf[AO_RADIO_LOTS], *b; + uint8_t buf[APRS_BUFFER_SIZE]; int cnt; int total = 0; uint8_t done = 0; uint8_t started = 0; - uint8_t fifo_space; ao_radio_abort = 0; ao_radio_get(0xff); - fifo_space = CC1200_FIFO_SIZE; - while (!done) { + ao_radio_wake = 0; + while (!done && !ao_radio_abort) { cnt = (*fill)(buf, sizeof(buf)); if (cnt < 0) { done = 1; cnt = -cnt; } -#if CC1200_APRS_TRACE - printf("APRS fill %d bytes done %d\n", cnt, done); -#endif total += cnt; /* At the last buffer, set the total length */ if (done) ao_radio_set_len(total & 0xff); - b = buf; - while (cnt) { - uint8_t this_len = cnt; - - /* Wait for some space in the fifo */ - while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) { -#if CC1200_APRS_TRACE - printf("APRS space %d cnt %d\n", fifo_space, cnt); flush(); -#endif - ao_radio_wake = 0; - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); - } - if (ao_radio_abort) - break; - if (this_len > fifo_space) - this_len = fifo_space; - - cnt -= this_len; - - if (done) { - if (cnt) - ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF); - else - ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); - } else - ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); - + /* Wait for some space in the fifo */ + 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_fifo_write(b, this_len); - b += this_len; -#if CC1200_APRS_TRACE - printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space()); -#endif - if (!started) { -#if CC1200_APRS_TRACE - printf("APRS start\n"); -#endif - ao_radio_strobe(CC1200_STX); -#if CC1200_APRS_TRACE - { int t; - for (t = 0; t < 20; t++) { - uint8_t status = ao_radio_status(); - uint8_t space = ao_radio_tx_fifo_space(); - printf ("status: %02x fifo %d\n", status, space); - if ((status >> 4) == 2) - break; - ao_delay(AO_MS_TO_TICKS(0)); - } - } -#endif - started = 1; - } + ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); } - if (ao_radio_abort) { - ao_radio_idle(); + if (ao_radio_abort) break; + + if (done) + ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); + else + ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); + + ao_radio_fifo_write(buf, cnt); + if (!started) { + ao_radio_strobe(CC1200_STX); + started = 1; } } /* Wait for the transmitter to go idle */ - ao_radio_wake = 0; -#if CC1200_APRS_TRACE - printf("APRS wait idle\n"); flush(); -#endif - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); -#if CC1200_APRS_TRACE - printf("APRS abort %d\n", ao_radio_abort); -#endif + 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)); + } + if (ao_radio_abort) + ao_radio_idle(); ao_radio_put(); } @@ -990,7 +1008,7 @@ ao_radio_dump_state(struct ao_radio_state *s) #endif uint8_t -ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) +ao_radio_recv(void *d, uint8_t size, uint8_t timeout) { uint8_t success = 0; @@ -1326,10 +1344,10 @@ static void ao_radio_packet(void) { ao_radio_send(packet, sizeof (packet)); } -void +static void ao_radio_test_recv(void) { - uint8_t bytes[34]; + static uint8_t bytes[34]; uint8_t b; if (ao_radio_recv(bytes, 34, 0)) { @@ -1364,14 +1382,15 @@ ao_radio_aprs(void) static void ao_radio_strobe_test(void) { + uint8_t addr; uint8_t r; - ao_cmd_hex(); + addr = ao_cmd_hex(); if (ao_cmd_status != ao_cmd_success) return; - r = ao_radio_strobe(ao_cmd_lex_i); + r = ao_radio_strobe(addr); printf ("Strobe %02x -> %02x (rdy %d state %d)\n", - ao_cmd_lex_i, + addr, r, r >> 7, (r >> 4) & 0x7); @@ -1383,14 +1402,12 @@ ao_radio_write_test(void) uint16_t addr; uint8_t data; - ao_cmd_hex(); + addr = ao_cmd_hex(); if (ao_cmd_status != ao_cmd_success) return; - addr = ao_cmd_lex_i; - ao_cmd_hex(); + data = ao_cmd_hex(); if (ao_cmd_status != ao_cmd_success) return; - data = ao_cmd_lex_i; printf ("Write %04x = %02x\n", addr, data); ao_radio_reg_write(addr, data); } @@ -1401,10 +1418,9 @@ ao_radio_read_test(void) uint16_t addr; uint8_t data; - ao_cmd_hex(); + addr = ao_cmd_hex(); if (ao_cmd_status != ao_cmd_success) return; - addr = ao_cmd_lex_i; data = ao_radio_reg_read(addr); printf ("Read %04x = %02x\n", addr, data); }