From 602d6a2424a5c16e22febf6b4e6b3816022261c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jun 2014 00:41:17 -0700 Subject: altos/aprs: Encode last serial number in SSID. Transmit serial in comment This makes it a lot easier to tell which device is sending information, and to receive data from multiple devices on the same receiver. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 8a1b6a4d..c33016f0 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -261,6 +261,7 @@ static uint8_t TNC_AX25_HEADER[] = { #define TNC_CALLSIGN_OFF 7 #define TNC_CALLSIGN_LEN 6 +#define TNC_SSID_OFF 13 static void tncSetCallsign(void) @@ -275,6 +276,7 @@ tncSetCallsign(void) } for (; i < TNC_CALLSIGN_LEN; i++) TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1; + TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_serial_number % 10) << 1); #endif } @@ -530,6 +532,7 @@ static int tncComment(uint8_t *buf) #ifdef AO_SENSE_MAIN " M%d.%d" #endif + " %d" , ao_gps_locked(), ao_num_sats(), battery/10, @@ -542,6 +545,7 @@ static int tncComment(uint8_t *buf) , main/10, main%10 #endif + , ao_serial_number ); #else return sprintf((char *) buf, -- cgit v1.2.3 From 3f3382126bf1122b1a78abe8458af5ec112a1f95 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 22 Jun 2014 21:05:05 -0700 Subject: altos: Make APRS SSID configurable This uses the low-digit from the serial number by default, but lets the user change it if desired. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 100 ++++++++++++++++++++++++++----------------------- src/kernel/ao_config.c | 34 +++++++++++++++++ src/kernel/ao_config.h | 5 ++- 3 files changed, 91 insertions(+), 48 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index c33016f0..a9047149 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -1,11 +1,11 @@ -/** +/** * http://ad7zj.net/kd7lmo/aprsbeacon_code.html * * @mainpage Pico Beacon * * @section overview_sec Overview * - * The Pico Beacon is an APRS based tracking beacon that operates in the UHF 420-450MHz band. The device utilizes a + * The Pico Beacon is an APRS based tracking beacon that operates in the UHF 420-450MHz band. The device utilizes a * Microchip PIC 18F2525 embedded controller, Motorola M12+ GPS engine, and Analog Devices AD9954 DDS. The device is capable * of generating a 1200bps A-FSK and 9600 bps FSK AX.25 compliant APRS (Automatic Position Reporting System) message. @@ -24,7 +24,7 @@ * (4) corrected size of LOG_COORD block when searching for end of log. * * @subsection v303 V3.03 - * 15 Sep 2005, Change include; (1) removed AD9954 setting SDIO as input pin, + * 15 Sep 2005, Change include; (1) removed AD9954 setting SDIO as input pin, * (2) additional comments and Doxygen tags, * (3) integration and test code calculates DDS FTW, * (4) swapped bus and reference analog input ports (hardware change), @@ -38,7 +38,7 @@ * (2) Doxygen documentation clean up and additions, and * (3) added integration and test code to baseline. * - * + * * @subsection v301 V3.01 * 13 Jan 2005, Renamed project and files to Pico Beacon. * @@ -54,28 +54,28 @@ * (8) added flight data recorder, and * (9) added diagnostics terminal mode. * - * + * * @subsection v201 V2.01 - * 30 Jan 2004, Change include; (1) General clean up of in-line documentation, and + * 30 Jan 2004, Change include; (1) General clean up of in-line documentation, and * (2) changed temperature resolution to 0.1 degrees F. * - * + * * @subsection v200 V2.00 * 26 Oct 2002, Change include; (1) Micro Beacon II hardware changes including PIC18F252 processor, - * (2) serial EEPROM, - * (3) GPS power control, - * (4) additional ADC input, and - * (5) LM60 temperature sensor. + * (2) serial EEPROM, + * (3) GPS power control, + * (4) additional ADC input, and + * (5) LM60 temperature sensor. * * * @subsection v101 V1.01 - * 5 Dec 2001, Change include; (1) Changed startup message, and + * 5 Dec 2001, Change include; (1) Changed startup message, and * (2) applied SEPARATE pragma to several methods for memory usage. * * * @subsection v100 V1.00 * 25 Sep 2001, Initial release. Flew ANSR-3 and ANSR-4. - * + * * @@ -102,11 +102,11 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * - * - * + * + * * @section design Design Details * * Provides design details on a variety of the components that make up the Pico Beacon. @@ -118,29 +118,33 @@ * @page power Power Consumption * * Measured DC power consumption. - * - * 3VDC prime power current + * + * 3VDC prime power current * - * 7mA Held in reset + * 7mA Held in reset - * 18mA Processor running, all I/O off + * 18mA Processor running, all I/O off - * 110mA GPS running + * 110mA GPS running - * 120mA GPS running w/antenna + * 120mA GPS running w/antenna - * 250mA DDS running and GPS w/antenna + * 250mA DDS running and GPS w/antenna - * 420mA DDS running, GPS w/antenna, and PA chain on with no RF + * 420mA DDS running, GPS w/antenna, and PA chain on with no RF - * 900mA Transmit + * 900mA Transmit * */ #ifndef AO_APRS_TEST #include + +#if !HAS_APRS +#error HAS_APRS not set +#endif #endif #include @@ -176,11 +180,11 @@ static uint16_t sysCRC16(const uint8_t *buffer, uint8_t length, uint16_t crc) { uint8_t i, bit, value; - for (i = 0; i < length; ++i) + for (i = 0; i < length; ++i) { value = buffer[i]; - for (bit = 0; bit < 8; ++bit) + for (bit = 0; bit < 8; ++bit) { crc ^= (value & 0x01); crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 ); @@ -253,7 +257,7 @@ typedef enum /// AX.25 compliant packet header that contains destination, station call sign, and path. /// 0x76 for SSID-11, 0x78 for SSID-12 -static uint8_t TNC_AX25_HEADER[] = { +static uint8_t TNC_AX25_HEADER[] = { 'A' << 1, 'P' << 1, 'A' << 1, 'M' << 1, ' ' << 1, ' ' << 1, 0x60, 'N' << 1, '0' << 1, 'C' << 1, 'A' << 1, 'L' << 1, 'L' << 1, 0x78, 'W' << 1, 'I' << 1, 'D' << 1, 'E' << 1, '2' << 1, ' ' << 1, 0x65, @@ -276,7 +280,9 @@ tncSetCallsign(void) } for (; i < TNC_CALLSIGN_LEN; i++) TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1; - TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_serial_number % 10) << 1); + + /* Fill in the SSID with the low digit of the serial number */ + TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_config.aprs_ssid & 0xf) << 1); #endif } @@ -304,7 +310,7 @@ static uint8_t tncBitStuff; /// Buffer to hold the message portion of the AX.25 packet as we prepare it. static uint8_t tncBuffer[TNC_BUFFER_SIZE]; -/** +/** * Initialize the TNC internal variables. */ static void tncInit() @@ -325,7 +331,7 @@ static void tnc1200TimerTick() else timeNCOFreq = 0x3aab; - switch (tncMode) + switch (tncMode) { case TNC_TX_READY: // Generate a test signal alteranting between high and low tones. @@ -341,16 +347,16 @@ static void tnc1200TimerTick() else tncTxBit = 0; } - + // When the flag is done, determine if we need to send more or data. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; tncShift = 0x7e; // Once we transmit x mS of flags, send the data. // txDelay bytes * 8 bits/byte * 833uS/bit = x mS - if (++tncIndex == TNC_TX_DELAY) + if (++tncIndex == TNC_TX_DELAY) { tncIndex = 0; tncShift = TNC_AX25_HEADER[0]; @@ -363,7 +369,7 @@ static void tnc1200TimerTick() case TNC_TX_HEADER: // Determine if we have sent 5 ones in a row, if we have send a zero. - if (tncBitStuff == 0x1f) + if (tncBitStuff == 0x1f) { if (tncTxBit == 0) tncTxBit = 1; @@ -383,17 +389,17 @@ static void tnc1200TimerTick() tncTxBit = 0; } - // Save the data stream so we can determine if bit stuffing is + // Save the data stream so we can determine if bit stuffing is // required on the next bit time. tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f; // If all the bits were shifted, get the next byte. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; // After the header is sent, then send the data. - if (++tncIndex == sizeof(TNC_AX25_HEADER)) + if (++tncIndex == sizeof(TNC_AX25_HEADER)) { tncIndex = 0; tncShift = tncBuffer[0]; @@ -408,7 +414,7 @@ static void tnc1200TimerTick() case TNC_TX_DATA: // Determine if we have sent 5 ones in a row, if we have send a zero. - if (tncBitStuff == 0x1f) + if (tncBitStuff == 0x1f) { if (tncTxBit == 0) tncTxBit = 1; @@ -428,17 +434,17 @@ static void tnc1200TimerTick() tncTxBit = 0; } - // Save the data stream so we can determine if bit stuffing is + // Save the data stream so we can determine if bit stuffing is // required on the next bit time. tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f; // If all the bits were shifted, get the next byte. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; // If everything was sent, transmit closing flags. - if (++tncIndex == tncLength) + if (++tncIndex == tncLength) { tncIndex = 0; tncShift = 0x7e; @@ -453,7 +459,7 @@ static void tnc1200TimerTick() case TNC_TX_END: // The variable tncShift contains the lastest data byte. - // NRZI enocde the data stream. + // NRZI enocde the data stream. if ((tncShift & 0x01) == 0x00) { if (tncTxBit == 0) tncTxBit = 1; @@ -462,13 +468,13 @@ static void tnc1200TimerTick() } // If all the bits were shifted, get the next one. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; tncShift = 0x7e; - + // Transmit two closing flags. - if (++tncIndex == 2) + if (++tncIndex == 2) { tncMode = TNC_TX_READY; @@ -763,7 +769,7 @@ tncFill(uint8_t *buf, int16_t len) return l; } -/** +/** * Prepare an AX.25 data packet. Each time this method is called, it automatically * rotates through 1 of 3 messages. * diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 71445335..58fa7354 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -61,6 +61,7 @@ __xdata uint8_t ao_config_mutex; #define AO_CONFIG_DEFAULT_RADIO_POWER 0x60 #endif #define AO_CONFIG_DEFAULT_RADIO_AMP 0 +#define AO_CONFIG_DEFAULT_APRS_SSID (ao_serial_number % 10) #if HAS_EEPROM static void @@ -191,6 +192,10 @@ _ao_config_get(void) #if AO_PYRO_NUM if (minor < 18) ao_config.pyro_time = AO_CONFIG_DEFAULT_PYRO_TIME; +#endif +#if HAS_APRS + if (minor < 19) + ao_config.aprs_ssid = AO_CONFIG_DEFAULT_APRS_SSID; #endif ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; @@ -283,6 +288,7 @@ ao_config_frequency_set(void) __reentrant ao_radio_recv_abort(); #endif } + #endif #if HAS_FLIGHT @@ -737,6 +743,30 @@ ao_config_pyro_time_set(void) } #endif +#if HAS_APRS +void +ao_config_aprs_ssid_show(void) +{ + printf ("APRS SSID: %d\n", + ao_config.aprs_ssid); +} + +void +ao_config_aprs_ssid_set(void) +{ + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + if (15 < ao_cmd_lex_i) { + ao_cmd_status = ao_cmd_lex_error; + return; + } + _ao_config_edit_start(); + ao_config.aprs_ssid = ao_cmd_lex_i; + _ao_config_edit_finish(); +} +#endif /* HAS_APRS */ + struct ao_config_var { __code char *str; void (*set)(void) __reentrant; @@ -816,6 +846,10 @@ __code struct ao_config_var ao_config_vars[] = { #if HAS_TRACKER { "t \0Tracker configuration", ao_config_tracker_set, ao_config_tracker_show }, +#endif +#if HAS_APRS + { "S \0Set APRS SSID (0-15)", + ao_config_aprs_ssid_set, ao_config_aprs_ssid_show }, #endif { "s\0Show", ao_config_show, 0 }, diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 2b5cd352..70f9f33b 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -53,7 +53,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 18 +#define AO_CONFIG_MINOR 19 #define AO_AES_LEN 16 @@ -102,6 +102,9 @@ struct ao_config { #if AO_PYRO_NUM uint16_t pyro_time; /* minor version 18 */ #endif +#if HAS_APRS + uint8_t aprs_ssid; /* minor version 19 */ +#endif }; #define AO_IGNITE_MODE_DUAL 0 -- cgit v1.2.3 From 8935e29e5aa9c01cd00b275a35dd7b99c00980c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:41:20 -0700 Subject: altos: Add 2400 and 9600 baud telemetry support to cc115l driver Signed-off-by: Keith Packard --- src/drivers/ao_cc115l.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index f250e714..b5103f9b 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -269,16 +269,30 @@ ao_radio_idle(void) * (256 + 131) * (2 ** 10) / (2**28) * 26e6 = 38383 * * DATARATE_M = 131 - * DATARATE_E = 10 + * DATARATE_E_384 = 10 + * DATARATE_E_96 = 8 + * DATARATE_E_24 = 6 */ -#define PACKET_DRATE_E 10 -#define PACKET_DRATE_M 131 +#define PACKET_DRATE_M 131 + +#define PACKET_DRATE_E_384 10 +#define PACKET_DRATE_E_96 8 +#define PACKET_DRATE_E_24 6 + +static const uint16_t packet_rate_setup[] = { + [AO_RADIO_RATE_38400] = ((0xf << 4) | + (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)), + + [AO_RADIO_RATE_9600] = ((0xf << 4) | + (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)), + + [AO_RADIO_RATE_2400] = ((0xf << 4) | + (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)), +}; static const uint16_t packet_setup[] = { CC115L_DEVIATN, ((PACKET_DEV_E << CC115L_DEVIATN_DEVIATION_E) | (PACKET_DEV_M << CC115L_DEVIATN_DEVIATION_M)), - CC115L_MDMCFG4, ((0xf << 4) | - (PACKET_DRATE_E << CC115L_MDMCFG4_DRATE_E)), CC115L_MDMCFG3, (PACKET_DRATE_M), CC115L_MDMCFG2, (0x00 | (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | @@ -403,9 +417,12 @@ ao_radio_set_mode(uint16_t new_mode) return; changes = new_mode & (~ao_radio_mode); - if (changes & AO_RADIO_MODE_BITS_PACKET_TX) + if (changes & AO_RADIO_MODE_BITS_PACKET_TX) { + ao_radio_reg_write(CC115L_MDMCFG4, packet_rate_setup[ao_config.radio_rate]); + for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2) ao_radio_reg_write(packet_setup[i], packet_setup[i+1]); + } if (changes & AO_RADIO_MODE_BITS_RDF) for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2) @@ -494,6 +511,7 @@ static void ao_radio_get(void) { static uint32_t last_radio_setting; + static uint8_t last_radio_rate; ao_mutex_get(&ao_radio_mutex); if (!ao_radio_configured) @@ -504,6 +522,10 @@ ao_radio_get(void) ao_radio_reg_write(CC115L_FREQ0, ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; } + if (ao_config.radio_rate != last_radio_rate) { + ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET_TX; + last_radio_rate = ao_config.radio_rate; + } } static void -- cgit v1.2.3 From 91461251f3aa8e1b37a3456f8fb94ab16bc0bec2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 4 Jul 2014 23:42:30 -0700 Subject: altos: Packet reception tuning for cc1120 driver This adjusts the cc1120 receive parameters to increase sensitivity at the expense of reporting many more invalid packets to the UI. Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.h | 2 +- src/drivers/ao_cc1120_CC1120.h | 56 ++++++++++++++---------------------------- 2 files changed, 20 insertions(+), 38 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h index a1d78c01..5d24c49a 100644 --- a/src/drivers/ao_cc1120.h +++ b/src/drivers/ao_cc1120.h @@ -294,7 +294,7 @@ #define CC1120_SETTLING_CFG_FS_AUTOCAL_MASK 3 #define CC1120_SETTLING_CFG_LOCK_TIME 1 #define CC1120_SETTLING_CFG_LOCK_TIME_50_20 0 -#define CC1120_SETTLING_CFG_LOCK_TIME_70_30 1 +#define CC1120_SETTLING_CFG_LOCK_TIME_75_30 1 #define CC1120_SETTLING_CFG_LOCK_TIME_100_40 2 #define CC1120_SETTLING_CFG_LOCK_TIME_150_60 3 #define CC1120_SETTLING_CFG_LOCK_TIME_MASK 3 diff --git a/src/drivers/ao_cc1120_CC1120.h b/src/drivers/ao_cc1120_CC1120.h index 399abc4d..21a31a89 100644 --- a/src/drivers/ao_cc1120_CC1120.h +++ b/src/drivers/ao_cc1120_CC1120.h @@ -31,20 +31,23 @@ CC1120_SYNC0, 0x91, /* Sync Word Configuration [7:0] */ CC1120_SYNC_CFG1, /* Sync Word Detection Configuration */ - (CC1120_SYNC_CFG1_DEM_CFG_PQT_GATING_ENABLED << CC1120_SYNC_CFG1_DEM_CFG) | - (0x07 << CC1120_SYNC_CFG1_SYNC_THR), + (CC1120_SYNC_CFG1_DEM_CFG_PQT_GATING_DISABLED << CC1120_SYNC_CFG1_DEM_CFG) | + (0xc << CC1120_SYNC_CFG1_SYNC_THR), CC1120_SYNC_CFG0, (CC1120_SYNC_CFG0_SYNC_MODE_16_BITS << CC1120_SYNC_CFG0_SYNC_MODE) | - (CC1120_SYNC_CFG0_SYNC_NUM_ERROR_2 << CC1120_SYNC_CFG0_SYNC_NUM_ERROR), - CC1120_DCFILT_CFG, 0x1c, /* Digital DC Removal Configuration */ + (CC1120_SYNC_CFG0_SYNC_NUM_ERROR_DISABLED << CC1120_SYNC_CFG0_SYNC_NUM_ERROR), + CC1120_DCFILT_CFG, 0x15, /* Digital DC Removal Configuration */ CC1120_PREAMBLE_CFG1, /* Preamble Length Configuration */ (CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD), CC1120_PREAMBLE_CFG0, - (1 << CC1120_PREAMBLE_CFG0_PQT_EN) | - (0x6 << CC1120_PREAMBLE_CFG0_PQT), - CC1120_FREQ_IF_CFG, 0x40, /* RX Mixer Frequency Configuration */ - CC1120_IQIC, 0x46, /* Digital Image Channel Compensation Configuration */ + (0 << CC1120_PREAMBLE_CFG0_PQT_EN) | + (0xe << CC1120_PREAMBLE_CFG0_PQT), + + /* Adjust PQT lower to accept fewer packets */ + + CC1120_FREQ_IF_CFG, 0x3a, /* RX Mixer Frequency Configuration */ + CC1120_IQIC, 0x00, /* Digital Image Channel Compensation Configuration */ CC1120_CHAN_BW, 0x02, /* Channel Filter Configuration */ CC1120_MDMCFG1, /* General Modem Parameter Configuration */ @@ -53,12 +56,12 @@ (0 << CC1120_MDMCFG1_MANCHESTER_EN) | (0 << CC1120_MDMCFG1_INVERT_DATA_EN) | (0 << CC1120_MDMCFG1_COLLISION_DETECT_EN) | - (CC1120_MDMCFG1_DVGA_GAIN_9 << CC1120_MDMCFG1_DVGA_GAIN) | + (CC1120_MDMCFG1_DVGA_GAIN_0 << CC1120_MDMCFG1_DVGA_GAIN) | (0 << CC1120_MDMCFG1_SINGLE_ADC_EN), - CC1120_MDMCFG0, 0x05, /* General Modem Parameter Configuration */ + CC1120_MDMCFG0, 0x0d, /* General Modem Parameter Configuration */ /* AGC reference = 10 * log10(receive BW) - 4 = 10 * log10(100e3) - 4 = 46 */ - CC1120_AGC_REF, 46, /* AGC Reference Level Configuration */ + CC1120_AGC_REF, 0x36, /* AGC Reference Level Configuration */ /* Carrier sense threshold - 25dB above the noise */ CC1120_AGC_CS_THR, 25, /* Carrier Sense Threshold Configuration */ @@ -93,7 +96,7 @@ CC1120_SETTLING_CFG, /* Frequency Synthesizer Calibration and Settling Configuration */ (CC1120_SETTLING_CFG_FS_AUTOCAL_IDLE_TO_ON << CC1120_SETTLING_CFG_FS_AUTOCAL) | - (CC1120_SETTLING_CFG_LOCK_TIME_50_20 << CC1120_SETTLING_CFG_LOCK_TIME) | + (CC1120_SETTLING_CFG_LOCK_TIME_75_30 << CC1120_SETTLING_CFG_LOCK_TIME) | (CC1120_SETTLING_CFG_FSREG_TIME_60 << CC1120_SETTLING_CFG_FSREG_TIME), CC1120_FS_CFG, /* Frequency Synthesizer Configuration */ @@ -109,7 +112,7 @@ CC1120_PKT_CFG1, 0x45, /* Packet Configuration, Reg 1 */ CC1120_PKT_CFG0, 0x00, /* Packet Configuration, Reg 0 */ #endif - CC1120_RFEND_CFG1, 0x0f, /* RFEND Configuration, Reg 1 */ + CC1120_RFEND_CFG1, 0x0e, /* RFEND Configuration, Reg 1 */ CC1120_RFEND_CFG0, 0x00, /* RFEND Configuration, Reg 0 */ // CC1120_PA_CFG2, 0x3f, /* Power Amplifier Configuration, Reg 2 */ CC1120_PA_CFG2, 0x3f, /* Power Amplifier Configuration, Reg 2 */ @@ -117,8 +120,8 @@ CC1120_PA_CFG0, 0x7b, /* Power Amplifier Configuration, Reg 0 */ CC1120_PKT_LEN, 0xff, /* Packet Length Configuration */ CC1120_IF_MIX_CFG, 0x00, /* IF Mix Configuration */ - CC1120_FREQOFF_CFG, 0x22, /* Frequency Offset Correction Configuration */ - CC1120_TOC_CFG, 0x0b, /* Timing Offset Correction Configuration */ + CC1120_FREQOFF_CFG, 0x20, /* Frequency Offset Correction Configuration */ + CC1120_TOC_CFG, 0x0a, /* Timing Offset Correction Configuration */ CC1120_MARC_SPARE, 0x00, /* MARC Spare */ CC1120_ECG_CFG, 0x00, /* External Clock Frequency Configuration */ CC1120_SOFT_TX_DATA_CFG, 0x00, /* Soft TX Data Configuration */ @@ -167,7 +170,7 @@ CC1120_XOSC4, 0xa0, /* Crystal Oscillator Configuration, Reg 4 */ CC1120_XOSC3, 0x03, /* Crystal Oscillator Configuration, Reg 3 */ CC1120_XOSC2, 0x04, /* Crystal Oscillator Configuration, Reg 2 */ - CC1120_XOSC1, 0x01, /* Crystal Oscillator Configuration, Reg 1 */ + CC1120_XOSC1, 0x03, /* Crystal Oscillator Configuration, Reg 1 */ CC1120_XOSC0, 0x00, /* Crystal Oscillator Configuration, Reg 0 */ CC1120_ANALOG_SPARE, 0x00, /* */ CC1120_PA_CFG3, 0x00, /* Power Amplifier Configuration, Reg 3 */ @@ -196,31 +199,10 @@ CC1120_AGC_GAIN2, 0xd1, /* AGC Gain, Reg 2 */ CC1120_AGC_GAIN1, 0x00, /* AGC Gain, Reg 1 */ CC1120_AGC_GAIN0, 0x3f, /* AGC Gain, Reg 0 */ - CC1120_SOFT_RX_DATA_OUT, 0x00, /* Soft Decision Symbol Data */ - CC1120_SOFT_TX_DATA_IN, 0x00, /* Soft TX Data Input Register */ - CC1120_ASK_SOFT_RX_DATA, 0x30, /* AGC ASK Soft Decision Output */ CC1120_RNDGEN, 0x7f, /* Random Number Value */ - CC1120_MAGN2, 0x00, /* Signal Magnitude after CORDIC [16] */ - CC1120_MAGN1, 0x00, /* Signal Magnitude after CORDIC [15:8] */ - CC1120_MAGN0, 0x00, /* Signal Magnitude after CORDIC [7:0] */ - CC1120_ANG1, 0x00, /* Signal Angular after CORDIC [9:8] */ - CC1120_ANG0, 0x00, /* Signal Angular after CORDIC [7:0] */ - CC1120_CHFILT_I2, 0x08, /* Channel Filter Data Real Part [18:16] */ - CC1120_CHFILT_I1, 0x00, /* Channel Filter Data Real Part [15:8] */ - CC1120_CHFILT_I0, 0x00, /* Channel Filter Data Real Part [7:0] */ - CC1120_CHFILT_Q2, 0x00, /* Channel Filter Data Imaginary Part [18:16] */ - CC1120_CHFILT_Q1, 0x00, /* Channel Filter Data Imaginary Part [15:8] */ - CC1120_CHFILT_Q0, 0x00, /* Channel Filter Data Imaginary Part [7:0] */ - CC1120_GPIO_STATUS, 0x00, /* GPIO Status */ CC1120_FSCAL_CTRL, 0x01, /* */ CC1120_PHASE_ADJUST, 0x00, /* */ - CC1120_PARTNUMBER, 0x00, /* Part Number */ - CC1120_PARTVERSION, 0x00, /* Part Revision */ CC1120_SERIAL_STATUS, 0x00, /* Serial Status */ - CC1120_RX_STATUS, 0x01, /* RX Status */ - CC1120_TX_STATUS, 0x00, /* TX Status */ - CC1120_MARC_STATUS1, 0x00, /* MARC Status, Reg 1 */ - CC1120_MARC_STATUS0, 0x00, /* MARC Status, Reg 0 */ CC1120_PA_IFAMP_TEST, 0x00, /* */ CC1120_FSRF_TEST, 0x00, /* */ CC1120_PRE_TEST, 0x00, /* */ -- cgit v1.2.3 From e0ee2ac6bc68b73e13bf34fac3ffd4a3b79dce98 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:34:48 -0700 Subject: altos: Add telemetry rate support to CC1120 driver This supports the new 2400 and 9600 baud rates Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 121 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 27 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 31225939..5d51fbcd 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -245,7 +245,7 @@ ao_radio_check_marc_status(void) { ao_radio_mcu_wake = 0; ao_radio_marc_status = ao_radio_get_marc_status(); - + /* Anyt other than 'tx/rx finished' means an error occurred */ if (ao_radio_marc_status & ~(CC1120_MARC_STATUS1_TX_FINISHED|CC1120_MARC_STATUS1_RX_FINISHED)) ao_radio_abort = 1; @@ -297,26 +297,47 @@ ao_radio_idle(void) #define PACKET_DEV_M 80 /* - * For our packet data, set the symbol rate to 38400 Baud + * For our packet data * * (2**20 + DATARATE_M) * 2 ** DATARATE_E * Rdata = -------------------------------------- * fosc * 2 ** 39 * + * Symbol rate 38400 Baud: * * DATARATE_M = 239914 * DATARATE_E = 9 + * CHANBW = 74.42 (round to 100) + * + * Symbol rate 9600 Baud: + * + * DATARATE_M = 239914 + * DATARATE_E = 7 + * CHANBW = 58.58 (round to 62.5) + * + * Symbol rate 2400 Baud: + * + * DATARATE_M = 239914 + * DATARATE_E = 5 + * CHANBW = 47.61 (round to 50) */ -#define PACKET_DRATE_E 9 + #define PACKET_DRATE_M 239914 +#define PACKET_DRATE_E_384 9 +#define PACKET_CHAN_BW_384 0x02 /* 200 / 2 = 100 */ + +#define PACKET_DRATE_E_96 7 +#define PACKET_CHAN_BW_96 0x42 /* 125 / 2 = 62.5 */ + +#define PACKET_DRATE_E_24 5 +#define PACKET_CHAN_BW_24 0x04 /* 200 / 4 = 50 */ + static const uint16_t packet_setup[] = { CC1120_DEVIATION_M, PACKET_DEV_M, CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | (PACKET_DEV_E << CC1120_MODCFG_DEV_E_DEV_E)), - CC1120_DRATE2, ((PACKET_DRATE_E << CC1120_DRATE2_DATARATE_E) | - (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), CC1120_DRATE1, ((PACKET_DRATE_M >> 8) & 0xff), CC1120_DRATE0, ((PACKET_DRATE_M >> 0) & 0xff), CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) | @@ -335,6 +356,27 @@ static const uint16_t packet_setup[] = { AO_CC1120_MARC_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP, }; +static const uint16_t packet_setup_384[] = { + CC1120_DRATE2, ((PACKET_DRATE_E_384 << CC1120_DRATE2_DATARATE_E) | + (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), + CC1120_CHAN_BW, PACKET_CHAN_BW_384, + CC1120_PA_CFG0, 0x7b, +}; + +static const uint16_t packet_setup_96[] = { + CC1120_DRATE2, ((PACKET_DRATE_E_96 << CC1120_DRATE2_DATARATE_E) | + (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), + CC1120_CHAN_BW, PACKET_CHAN_BW_96, + CC1120_PA_CFG0, 0x7d, +}; + +static const uint16_t packet_setup_24[] = { + CC1120_DRATE2, ((PACKET_DRATE_E_24 << CC1120_DRATE2_DATARATE_E) | + (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), + CC1120_CHAN_BW, PACKET_CHAN_BW_24, + CC1120_PA_CFG0, 0x7e, +}; + static const uint16_t packet_tx_setup[] = { CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) | (CC1120_PKT_CFG2_PKT_FORMAT_NORMAL << CC1120_PKT_CFG2_PKT_FORMAT)), @@ -397,6 +439,7 @@ static const uint16_t rdf_setup[] = { (0 << CC1120_PKT_CFG0_UART_SWAP_EN)), CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), + CC1120_PA_CFG0, 0x7e, }; /* @@ -443,6 +486,7 @@ static const uint16_t aprs_setup[] = { (0 << CC1120_PKT_CFG1_APPEND_STATUS)), CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), + CC1120_PA_CFG0, 0x7d, }; /* @@ -505,24 +549,49 @@ static uint16_t ao_radio_mode; #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_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) +static void +_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]); + regs += 2; + } +} + +#define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1) + static void ao_radio_set_mode(uint16_t new_mode) { uint16_t changes; - unsigned int i; if (new_mode == ao_radio_mode) return; changes = new_mode & (~ao_radio_mode); - if (changes & AO_RADIO_MODE_BITS_PACKET) - for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2) - ao_radio_reg_write(packet_setup[i], packet_setup[i+1]); + + if (changes & AO_RADIO_MODE_BITS_PACKET) { + ao_radio_set_regs(packet_setup); + + switch (ao_config.radio_rate) { + default: + case AO_RADIO_RATE_38400: + ao_radio_set_regs(packet_setup_384); + break; + case AO_RADIO_RATE_9600: + ao_radio_set_regs(packet_setup_96); + break; + case AO_RADIO_RATE_2400: + ao_radio_set_regs(packet_setup_24); + break; + } + } if (changes & AO_RADIO_MODE_BITS_PACKET_TX) - for (i = 0; i < sizeof (packet_tx_setup) / sizeof (packet_tx_setup[0]); i += 2) - ao_radio_reg_write(packet_tx_setup[i], packet_tx_setup[i+1]); - + ao_radio_set_regs(packet_tx_setup); + if (changes & AO_RADIO_MODE_BITS_TX_BUF) ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_TXFIFO_THR); @@ -530,20 +599,16 @@ ao_radio_set_mode(uint16_t new_mode) ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG); if (changes & AO_RADIO_MODE_BITS_PACKET_RX) - for (i = 0; i < sizeof (packet_rx_setup) / sizeof (packet_rx_setup[0]); i += 2) - ao_radio_reg_write(packet_rx_setup[i], packet_rx_setup[i+1]); - + ao_radio_set_regs(packet_rx_setup); + if (changes & AO_RADIO_MODE_BITS_RDF) - for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2) - ao_radio_reg_write(rdf_setup[i], rdf_setup[i+1]); + ao_radio_set_regs(rdf_setup); if (changes & AO_RADIO_MODE_BITS_APRS) - for (i = 0; i < sizeof (aprs_setup) / sizeof (aprs_setup[0]); i += 2) - ao_radio_reg_write(aprs_setup[i], aprs_setup[i+1]); + ao_radio_set_regs(aprs_setup); if (changes & AO_RADIO_MODE_BITS_TEST) - for (i = 0; i < sizeof (test_setup) / sizeof (test_setup[0]); i += 2) - ao_radio_reg_write(test_setup[i], test_setup[i+1]); + ao_radio_set_regs(test_setup); if (changes & AO_RADIO_MODE_BITS_INFINITE) ao_radio_reg_write(CC1120_PKT_CFG0, AO_PKT_CFG0_INFINITE); @@ -563,12 +628,9 @@ static uint8_t ao_radio_configured = 0; static void ao_radio_setup(void) { - unsigned int i; - ao_radio_strobe(CC1120_SRES); - for (i = 0; i < sizeof (radio_setup) / sizeof (radio_setup[0]); i += 2) - ao_radio_reg_write(radio_setup[i], radio_setup[i+1]); + ao_radio_set_regs(radio_setup); ao_radio_mode = 0; @@ -592,6 +654,7 @@ static void ao_radio_get(uint8_t len) { static uint32_t last_radio_setting; + static uint8_t last_radio_rate; ao_mutex_get(&ao_radio_mutex); @@ -603,6 +666,10 @@ ao_radio_get(uint8_t len) ao_radio_reg_write(CC1120_FREQ0, ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; } + if (ao_config.radio_rate != last_radio_rate) { + ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET; + last_radio_rate = ao_config.radio_rate; + } ao_radio_set_len(len); } @@ -696,7 +763,7 @@ ao_radio_test_cmd(void) ao_radio_set_mode(AO_RADIO_MODE_TEST); ao_radio_strobe(CC1120_STX); #if CC1120_TRACE - { int t; + { int t; for (t = 0; t < 10; t++) { printf ("status: %02x\n", ao_radio_status()); ao_delay(AO_MS_TO_TICKS(100)); @@ -793,7 +860,7 @@ ao_radio_send(const void *d, uint8_t size) } else { ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); } - + fifo_space = ao_radio_wait_tx(encode_len != 0); if (ao_radio_abort) { ao_radio_idle(); -- cgit v1.2.3 From 292cb8380b478542555b5f370e8252eafa2f74ac Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Jul 2014 00:04:06 -0700 Subject: altos: Rework packet receive for cc1120 Instead of blocking on PQT, just set up the receiver to start going and when the first bit interrupt comes in, grab the SPI bus if possible and configure it for reception. This improves sensitivity in the radio by a significant amount while making the code conceptually a bit nicer. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 3 + src/drivers/ao_cc1120.c | 160 +++++++++++++++++++++++++++++++----------------- src/kernel/ao.h | 3 + src/kernel/ao_mutex.c | 23 +++++++ src/lpc/ao_arch_funcs.h | 17 ++--- src/stm/ao_arch_funcs.h | 25 ++++++-- src/stm/ao_spi_stm.c | 51 +++++++++++++-- 7 files changed, 208 insertions(+), 74 deletions(-) (limited to 'src/drivers') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 83a3c774..1bc3d716 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -58,6 +58,7 @@ #define HAS_MONITOR 0 #define HAS_TELEMETRY 1 #define HAS_RADIO_RATE 0 /* not enough space for this */ + #define HAS_MUTEX_TRY 0 #endif #if defined(TELEMETRUM_V_1_1) @@ -100,6 +101,7 @@ #define HAS_MONITOR 0 #define HAS_TELEMETRY 1 #define HAS_RADIO_RATE 0 /* not enough space for this */ + #define HAS_MUTEX_TRY 0 #endif #if defined(TELEMETRUM_V_1_2) @@ -142,6 +144,7 @@ #define HAS_MONITOR 0 #define HAS_TELEMETRY 1 #define HAS_RADIO_RATE 0 /* not enough space for this */ + #define HAS_MUTEX_TRY 0 #endif #if defined(TELEDONGLE_V_0_2) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 5d51fbcd..1b907940 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -41,8 +41,10 @@ extern const uint32_t ao_radio_cal; #define FOSC 32000000 +#define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz, task_id) #define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS) +#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1120_SPI_BUS) @@ -107,7 +109,7 @@ ao_radio_reg_write(uint16_t addr, uint8_t value) } static void -ao_radio_burst_read_start (uint16_t addr) +_ao_radio_burst_read_start (uint16_t addr) { uint8_t data[2]; uint8_t d; @@ -124,8 +126,8 @@ ao_radio_burst_read_start (uint16_t addr) addr); d = 1; } - ao_radio_select(); - ao_radio_spi_send(data, d); + + ao_radio_spi_send_sync(data, d); } static void @@ -209,7 +211,7 @@ ao_radio_tx_fifo_space(void) return CC1120_FIFO_SIZE - ao_radio_reg_read(CC1120_NUM_TXBYTES); } -#if 0 +#if CC1120_DEBUG static uint8_t ao_radio_status(void) { @@ -275,11 +277,13 @@ static void ao_radio_idle(void) { for (;;) { - uint8_t state = ao_radio_strobe(CC1120_SIDLE); - if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_IDLE) + uint8_t state = (ao_radio_strobe(CC1120_SIDLE) >> CC1120_STATUS_STATE) & CC1120_STATUS_STATE_MASK; + if (state == CC1120_STATUS_STATE_IDLE) break; - if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_TX_FIFO_ERROR) + if (state == CC1120_STATUS_STATE_TX_FIFO_ERROR) ao_radio_strobe(CC1120_SFTX); + if (state == CC1120_STATUS_STATE_RX_FIFO_ERROR) + ao_radio_strobe(CC1120_SFRX); } /* Flush any pending TX bytes */ ao_radio_strobe(CC1120_SFTX); @@ -948,6 +952,11 @@ static uint16_t rx_data_consumed; static uint16_t rx_data_cur; static uint8_t rx_ignore; static uint8_t rx_waiting; +static uint8_t rx_starting; +static uint8_t rx_task_id; +static uint32_t rx_fast_start; +static uint32_t rx_slow_start; +static uint32_t rx_missed; #if AO_PROFILE static uint32_t rx_start_tick, rx_packet_tick, rx_done_tick, rx_last_done_tick; @@ -962,13 +971,34 @@ ao_radio_rx_isr(void) { uint8_t d; + if (rx_task_id) { + if (ao_radio_try_select(rx_task_id)) { + ++rx_fast_start; + rx_task_id = 0; + _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT); + } else { + if (rx_ignore) + --rx_ignore; + else { + ao_radio_abort = 1; + rx_missed++; + } + return; + } + } + if (rx_starting) { + rx_starting = 0; + ao_wakeup(&ao_radio_wake); + } d = AO_CC1120_SPI.dr; AO_CC1120_SPI.dr = 0; if (rx_ignore == 0) { - if (rx_data_cur >= rx_data_count) - ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); - else + if (rx_data_cur < rx_data_count) rx_data[rx_data_cur++] = d; + if (rx_data_cur >= rx_data_count) { + ao_spi_clr_cs(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN)); + ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); + } if (rx_waiting && rx_data_cur - rx_data_consumed >= AO_FEC_DECODE_BLOCK) { #if AO_PROFILE if (!rx_packet_tick) @@ -987,24 +1017,20 @@ ao_radio_rx_isr(void) static uint16_t ao_radio_rx_wait(void) { - do { - if (ao_radio_mcu_wake) - ao_radio_check_marc_status(); - ao_alarm(AO_MS_TO_TICKS(100)); - ao_arch_block_interrupts(); - rx_waiting = 1; - while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK && - !ao_radio_abort && - !ao_radio_mcu_wake) - { - if (ao_sleep(&ao_radio_wake)) - ao_radio_abort = 1; - } - rx_waiting = 0; - ao_arch_release_interrupts(); - ao_clear_alarm(); - } while (ao_radio_mcu_wake); - if (ao_radio_abort) + ao_alarm(AO_MS_TO_TICKS(100)); + ao_arch_block_interrupts(); + rx_waiting = 1; + while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK && + !ao_radio_abort && + !ao_radio_mcu_wake) + { + if (ao_sleep(&ao_radio_wake)) + ao_radio_abort = 1; + } + rx_waiting = 0; + ao_arch_release_interrupts(); + ao_clear_alarm(); + if (ao_radio_abort || ao_radio_mcu_wake) return 0; rx_data_consumed += AO_FEC_DECODE_BLOCK; #if AO_PROFILE @@ -1044,48 +1070,67 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) */ ao_radio_abort = 0; - /* configure interrupt pin */ ao_radio_get(len); - ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX); ao_radio_wake = 0; ao_radio_mcu_wake = 0; - AO_CC1120_SPI.cr2 = 0; - - /* clear any RXNE */ - (void) AO_CC1120_SPI.dr; + ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX); - /* Have the radio signal when the preamble quality goes high */ - ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_PQT_REACHED); + /* configure interrupt pin */ + ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT); ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, - AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH); - ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr); + AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); + + ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr); ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); - ao_exti_enable(AO_CC1120_MCU_WAKEUP_PORT, AO_CC1120_MCU_WAKEUP_PIN); + + rx_starting = 1; + rx_task_id = ao_cur_task->task_id; ao_radio_strobe(CC1120_SRX); - /* Wait for the preamble to appear */ - ao_radio_wait_isr(timeout); + if (timeout) + ao_alarm(timeout); + ao_arch_block_interrupts(); + while (rx_starting && !ao_radio_abort) { + if (ao_sleep(&ao_radio_wake)) + ao_radio_abort = 1; + } + uint8_t rx_task_id_save = rx_task_id; + rx_task_id = 0; + rx_starting = 0; + ao_arch_release_interrupts(); + if (timeout) + ao_clear_alarm(); + if (ao_radio_abort) { ret = 0; + rx_task_id = 0; goto abort; } - ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT); - ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, - AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); - - ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr); - ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); - - ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT); + if (rx_task_id_save) { + ++rx_slow_start; + ao_radio_select(); + _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT); + if (rx_ignore) { + uint8_t ignore = AO_CC1120_SPI.dr; + (void) ignore; + AO_CC1120_SPI.dr = 0; + --rx_ignore; + } + } ret = ao_fec_decode(rx_data, rx_data_count, d, size + 2, ao_radio_rx_wait); ao_radio_burst_read_stop(); + if (ao_radio_mcu_wake) + ao_radio_check_marc_status(); + if (ao_radio_abort) + ret = 0; + abort: /* Convert from 'real' rssi to cc1111-style values */ @@ -1100,7 +1145,7 @@ abort: radio_rssi = AO_RADIO_FROM_RSSI (rssi); } - ao_radio_strobe(CC1120_SIDLE); + ao_radio_idle(); ao_radio_put(); @@ -1139,7 +1184,7 @@ struct ao_cc1120_reg { char *name; }; -const static struct ao_cc1120_reg ao_cc1120_reg[] = { +static const struct ao_cc1120_reg ao_cc1120_reg[] = { { .addr = CC1120_IOCFG3, .name = "IOCFG3" }, { .addr = CC1120_IOCFG2, .name = "IOCFG2" }, { .addr = CC1120_IOCFG1, .name = "IOCFG1" }, @@ -1320,7 +1365,7 @@ const static struct ao_cc1120_reg ao_cc1120_reg[] = { static void ao_radio_show(void) { uint8_t status = ao_radio_status(); - int i; + unsigned int i; ao_radio_get(0xff); status = ao_radio_status(); @@ -1331,6 +1376,10 @@ static void ao_radio_show(void) { for (i = 0; i < AO_NUM_CC1120_REG; i++) printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1120_reg[i].addr), ao_cc1120_reg[i].name); + + printf("RX fast start: %u\n", rx_fast_start); + printf("RX slow start: %u\n", rx_slow_start); + printf("RX missed: %u\n", rx_missed); ao_radio_put(); } @@ -1354,12 +1403,12 @@ static void ao_radio_packet(void) { } void -ao_radio_test_recv() +ao_radio_test_recv(void) { uint8_t bytes[34]; uint8_t b; - if (ao_radio_recv(bytes, 34)) { + if (ao_radio_recv(bytes, 34, 0)) { if (bytes[33] & 0x80) printf ("CRC OK"); else @@ -1375,13 +1424,12 @@ ao_radio_test_recv() #include static void -ao_radio_aprs() +ao_radio_aprs(void) { ao_packet_slave_stop(); ao_aprs_send(); } #endif - #endif static const struct ao_cmds ao_radio_cmds[] = { diff --git a/src/kernel/ao.h b/src/kernel/ao.h index c11aa028..a225bc4a 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -132,6 +132,9 @@ ao_clock_init(void); */ #ifndef ao_mutex_get +uint8_t +ao_mutex_try(__xdata uint8_t *ao_mutex, uint8_t task_id) __reentrant; + void ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant; diff --git a/src/kernel/ao_mutex.c b/src/kernel/ao_mutex.c index 952ff462..a36fe939 100644 --- a/src/kernel/ao_mutex.c +++ b/src/kernel/ao_mutex.c @@ -17,6 +17,29 @@ #include "ao.h" +#ifndef HAS_MUTEX_TRY +#define HAS_MUTEX_TRY 1 +#endif + +#if HAS_MUTEX_TRY + +uint8_t +ao_mutex_try(__xdata uint8_t *mutex, uint8_t task_id) __reentrant +{ + uint8_t ret; + if (*mutex == task_id) + ao_panic(AO_PANIC_MUTEX); + ao_arch_critical( + if (*mutex) + ret = 0; + else { + *mutex = task_id; + ret = 1; + }); + return ret; +} +#endif + void ao_mutex_get(__xdata uint8_t *mutex) __reentrant { diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 0891903e..21a7a8e5 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -161,16 +161,17 @@ static inline void ao_arch_restore_stack(void) { #endif /* HAS_TASK */ -#define ao_arch_wait_interrupt() do { \ - asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \ - ao_arch_release_interrupts(); \ - ao_arch_block_interrupts(); \ +#define ao_arch_wait_interrupt() do { \ + asm("\twfi\n"); \ + ao_arch_release_interrupts(); \ + asm(".global ao_idle_loc\n\nao_idle_loc:"); \ + ao_arch_block_interrupts(); \ } while (0) -#define ao_arch_critical(b) do { \ - ao_arch_block_interrupts(); \ - do { b } while (0); \ - ao_arch_release_interrupts(); \ +#define ao_arch_critical(b) do { \ + uint32_t __mask = ao_arch_irqsave(); \ + do { b } while (0); \ + ao_arch_irqrestore(__mask); \ } while (0) /* diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index b461cd3f..7ad3b4b8 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -64,6 +64,9 @@ #define AO_SPI_INDEX(id) ((id) & AO_SPI_INDEX_MASK) #define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK) +uint8_t +ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id); + void ao_spi_get(uint8_t spi_index, uint32_t speed); @@ -76,6 +79,9 @@ ao_spi_send(void *block, uint16_t len, uint8_t spi_index); void ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); +void +ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index); + void ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); @@ -95,6 +101,15 @@ ao_spi_init(void); ao_spi_set_cs(reg,mask); \ } while (0) +static inline uint8_t +ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t speed, uint8_t task_id) +{ + if (!ao_spi_try_get(bus, speed, task_id)) + return 0; + ao_spi_set_cs(reg, mask); + return 1; +} + #define ao_spi_put_mask(reg,mask,bus) do { \ ao_spi_clr_cs(reg,mask); \ ao_spi_put(bus); \ @@ -252,6 +267,8 @@ extern struct ao_stm_usart ao_stm_usart3; #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) +typedef uint32_t ao_arch_irq_t; + static inline uint32_t ao_arch_irqsave(void) { uint32_t primask; @@ -369,10 +386,10 @@ static inline void ao_arch_start_scheduler(void) { ao_arch_block_interrupts(); \ } while (0) -#define ao_arch_critical(b) do { \ - ao_arch_block_interrupts(); \ - do { b } while (0); \ - ao_arch_release_interrupts(); \ +#define ao_arch_critical(b) do { \ + uint32_t __mask = ao_arch_irqsave(); \ + do { b } while (0); \ + ao_arch_irqrestore(__mask); \ } while (0) #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 56329c24..885af544 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -153,6 +153,28 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) ao_dma_done_transfer(miso_dma_index); } +void +ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index) +{ + uint8_t *b = block; + struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (0 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); + + /* Clear RXNE */ + (void) stm_spi->dr; + + while (len--) { + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))); + stm_spi->dr = *b++; + } +} + void ao_spi_recv(void *block, uint16_t len, uint8_t spi_index) { @@ -356,13 +378,11 @@ ao_spi_enable_index(uint8_t spi_index) } } -void -ao_spi_get(uint8_t spi_index, uint32_t speed) +static void +ao_spi_config(uint8_t spi_index, uint32_t speed) { uint8_t id = AO_SPI_INDEX(spi_index); struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; - - ao_mutex_get(&ao_spi_mutex[id]); stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */ (0 << STM_SPI_CR1_BIDIOE) | (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ @@ -378,7 +398,7 @@ ao_spi_get(uint8_t spi_index, uint32_t speed) (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ (0 << STM_SPI_CR1_CPHA)); if (spi_index != ao_spi_index[id]) { - + /* Disable old config */ ao_spi_disable_index(ao_spi_index[id]); @@ -386,13 +406,32 @@ ao_spi_get(uint8_t spi_index, uint32_t speed) /* Enable new config */ ao_spi_enable_index(spi_index); - + /* Remember current config */ ao_spi_index[id] = spi_index; } } +uint8_t +ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + + if (!ao_mutex_try(&ao_spi_mutex[id], task_id)) + return 0; + ao_spi_config(spi_index, speed); + return 1; +} + +void +ao_spi_get(uint8_t spi_index, uint32_t speed) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + ao_mutex_get(&ao_spi_mutex[id]); + ao_spi_config(spi_index, speed); +} + void ao_spi_put(uint8_t spi_index) { -- cgit v1.2.3 From 34d5be68ca23e8beb05db9a480faef63ecc911d0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:07:48 -0700 Subject: altos: Extend GPS altitudes to at least 24 bits everywhere Telemetry gets a special 'mode' flag indicating that 24-bit data is present; log files get new data and log readers are expected to detect that via the firmware version number. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 1 + src/drivers/ao_aprs.c | 2 +- src/drivers/ao_gps_skytraq.c | 3 ++- src/drivers/ao_gps_ublox.c | 2 +- src/kernel/ao_gps_report.c | 8 ++++++-- src/kernel/ao_gps_report_mega.c | 7 ++++--- src/kernel/ao_gps_report_metrum.c | 3 ++- src/kernel/ao_gps_show.c | 8 +++++++- src/kernel/ao_log.h | 23 +++++++++++++++-------- src/kernel/ao_log_gps.c | 3 ++- src/kernel/ao_log_gps.h | 3 --- src/kernel/ao_telemetry.c | 2 +- src/kernel/ao_telemetry.h | 34 ++++++++++++++++++++++++++-------- src/kernel/ao_tracker.c | 13 +++++++------ src/test/ao_aprs_test.c | 7 +++---- src/test/ao_flight_test.c | 7 +++++-- src/test/ao_gps_test.c | 5 ++++- src/test/ao_gps_test_skytraq.c | 4 ++++ src/test/ao_gps_test_ublox.c | 9 ++++++++- 19 files changed, 99 insertions(+), 45 deletions(-) (limited to 'src/drivers') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 1bc3d716..4db49215 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,7 @@ #define HAS_RADIO 1 #define DISABLE_LOG_SPACE 1 +#define HAS_WIDE_GPS 0 #if defined(TELEMETRUM_V_1_0) /* Discontinued and was never built with CC1111 chips needing this */ diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index a9047149..19beb78f 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -713,7 +713,7 @@ static int tncPositionPacket(void) if (ao_gps_data.flags & AO_GPS_VALID) { latitude = ao_gps_data.latitude; longitude = ao_gps_data.longitude; - altitude = ao_gps_data.altitude; + altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data); if (altitude < 0) altitude = 0; } diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 944a37f9..81178051 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -287,7 +287,8 @@ ao_nmea_gga(void) ao_gps_next.hdop = i; ao_gps_skip_field(); - ao_gps_next.altitude = ao_gps_decimal(0xff); + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_next, ao_gps_decimal(0xff)); + ao_gps_skip_field(); /* skip any fractional portion */ ao_nmea_finish(); diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 077698a9..48765998 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -728,7 +728,7 @@ ao_gps(void) __reentrant if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC)) ao_gps_data.flags |= AO_GPS_DATE_VALID; - ao_gps_data.altitude = nav_posllh.alt_msl / 1000; + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, nav_posllh.alt_msl / 1000); ao_gps_data.latitude = nav_posllh.lat; ao_gps_data.longitude = nav_posllh.lon; diff --git a/src/kernel/ao_gps_report.c b/src/kernel/ao_gps_report.c index 07201ac2..7ef98a97 100644 --- a/src/kernel/ao_gps_report.c +++ b/src/kernel/ao_gps_report.c @@ -52,8 +52,12 @@ ao_gps_report(void) gps_log.u.gps_longitude = gps_data.longitude; ao_log_data(&gps_log); gps_log.type = AO_LOG_GPS_ALT; - gps_log.u.gps_altitude.altitude = gps_data.altitude; - gps_log.u.gps_altitude.unused = 0xffff; + gps_log.u.gps_altitude.altitude_low = gps_data.altitude_low; +#if HAS_WIDE_GPS + gps_log.u.gps_altitude.altitude_high = gps_data.altitude_high; +#else + gps_log.u.gps_altitude.altitude_high = 0xffff; +#endif ao_log_data(&gps_log); if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { gps_log.type = AO_LOG_GPS_DATE; diff --git a/src/kernel/ao_gps_report_mega.c b/src/kernel/ao_gps_report_mega.c index cb0c0fd9..f3711fb1 100644 --- a/src/kernel/ao_gps_report_mega.c +++ b/src/kernel/ao_gps_report_mega.c @@ -78,7 +78,8 @@ ao_gps_report_mega(void) #if GPS_SPARSE_LOG /* Don't log data if GPS has a fix and hasn't moved for a while */ if ((gps_data.flags & AO_GPS_VALID) && - !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, gps_data.altitude)) + !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, + AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data)) continue; #endif if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { @@ -87,8 +88,8 @@ ao_gps_report_mega(void) gps_log.type = AO_LOG_GPS_TIME; gps_log.u.gps.latitude = gps_data.latitude; gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; - + gps_log.u.gps.altitude_low = gps_data.altitude_low; + gps_log.u.gps.altitude_high = gps_data.altitude_high; gps_log.u.gps.hour = gps_data.hour; gps_log.u.gps.minute = gps_data.minute; gps_log.u.gps.second = gps_data.second; diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c index 696a833b..31939385 100644 --- a/src/kernel/ao_gps_report_metrum.c +++ b/src/kernel/ao_gps_report_metrum.c @@ -44,7 +44,8 @@ ao_gps_report_metrum(void) gps_log.type = AO_LOG_GPS_POS; gps_log.u.gps.latitude = gps_data.latitude; gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; + gps_log.u.gps.altitude_low = gps_data.altitude_low; + gps_log.u.gps.altitude_high = gps_data.altitude_high; ao_log_metrum(&gps_log); gps_log.type = AO_LOG_GPS_TIME; diff --git a/src/kernel/ao_gps_show.c b/src/kernel/ao_gps_show.c index 3a05e35a..e45cd795 100644 --- a/src/kernel/ao_gps_show.c +++ b/src/kernel/ao_gps_show.c @@ -19,6 +19,8 @@ #include #endif +#include + void ao_gps_show(void) __reentrant { @@ -27,7 +29,11 @@ ao_gps_show(void) __reentrant printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day); printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second); printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude); - printf ("Alt: %d\n", ao_gps_data.altitude); +#if HAS_WIDE_GPS + printf ("Alt: %ld\n", (long) AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#else + printf ("Alt: %d\n", AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#endif printf ("Flags: 0x%x\n", ao_gps_data.flags); printf ("Sats: %d", ao_gps_tracking_data.channels); for (i = 0; i < ao_gps_tracking_data.channels; i++) diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 33cda3eb..080cfb02 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -176,8 +176,8 @@ struct ao_log_record { int32_t gps_latitude; int32_t gps_longitude; struct { - int16_t altitude; - uint16_t unused; + uint16_t altitude_low; + int16_t altitude_high; } gps_altitude; struct { uint16_t svid; @@ -246,7 +246,7 @@ struct ao_log_mega { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ + uint16_t altitude_low; /* 12 */ uint8_t hour; /* 14 */ uint8_t minute; /* 15 */ uint8_t second; /* 16 */ @@ -261,7 +261,8 @@ struct ao_log_mega { uint8_t hdop; /* 27 */ uint8_t vdop; /* 28 */ uint8_t mode; /* 29 */ - } gps; /* 30 */ + int16_t altitude_high; /* 30 */ + } gps; /* 32 */ /* AO_LOG_GPS_SAT */ struct { uint16_t channels; /* 4 */ @@ -273,6 +274,11 @@ struct ao_log_mega { } u; }; +#define AO_LOG_MEGA_GPS_ALTITUDE(l) ((int32_t) ((l)->u.gps.altitude_high << 16) | ((l)->u.gps.altitude_low)) +#define AO_LOG_MEGA_SET_GPS_ALTITUDE(l,a) (((l)->u.gps.mode |= AO_GPS_MODE_ALTITUDE_24), \ + ((l)->u.gps.altitude_high = (a) >> 16), \ + (l)->u.gps.altitude_low = (a)) + struct ao_log_metrum { char type; /* 0 */ uint8_t csum; /* 1 */ @@ -306,8 +312,9 @@ struct ao_log_metrum { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ - } gps; /* 14 */ + uint16_t altitude_low; /* 12 */ + int16_t altitude_high; /* 14 */ + } gps; /* 16 */ /* AO_LOG_GPS_TIME */ struct { uint8_t hour; /* 4 */ @@ -381,7 +388,7 @@ struct ao_log_gps { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ + uint16_t altitude_low; /* 12 */ uint8_t hour; /* 14 */ uint8_t minute; /* 15 */ uint8_t second; /* 16 */ @@ -396,7 +403,7 @@ struct ao_log_gps { uint8_t hdop; /* 27 */ uint8_t vdop; /* 28 */ uint8_t mode; /* 29 */ - uint8_t state; /* 30 */ + int16_t altitude_high; /* 30 */ } gps; /* 31 */ /* AO_LOG_GPS_SAT */ struct { diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c index 3b728c25..a5a6358b 100644 --- a/src/kernel/ao_log_gps.c +++ b/src/kernel/ao_log_gps.c @@ -75,7 +75,8 @@ ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data) log.type = AO_LOG_GPS_TIME; log.u.gps.latitude = gps_data->latitude; log.u.gps.longitude = gps_data->longitude; - log.u.gps.altitude = gps_data->altitude; + log.u.gps.altitude_low = gps_data->altitude_low; + log.u.gps.altitude_high = gps_data->altitude_high; log.u.gps.hour = gps_data->hour; log.u.gps.minute = gps_data->minute; diff --git a/src/kernel/ao_log_gps.h b/src/kernel/ao_log_gps.h index 5851f4d1..a9e8c831 100644 --- a/src/kernel/ao_log_gps.h +++ b/src/kernel/ao_log_gps.h @@ -21,9 +21,6 @@ #ifndef _AO_LOG_GPS_H_ #define _AO_LOG_GPS_H_ -uint8_t -ao_log_gps_should_log(int32_t lat, int32_t lon, int16_t alt); - void ao_log_gps_flight(void); diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index d321c8ff..56bd715e 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -344,7 +344,7 @@ ao_send_location(void) ao_mutex_get(&ao_gps_mutex); ao_xmemcpy(&telemetry.location.flags, &ao_gps_data.flags, - 26); + 27); telemetry.location.tick = ao_gps_tick; ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index be7d0340..83d432cf 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -86,12 +86,9 @@ struct ao_telemetry_configuration { #define AO_TELEMETRY_LOCATION 0x05 -#define AO_GPS_MODE_NOT_VALID 'N' -#define AO_GPS_MODE_AUTONOMOUS 'A' -#define AO_GPS_MODE_DIFFERENTIAL 'D' -#define AO_GPS_MODE_ESTIMATED 'E' -#define AO_GPS_MODE_MANUAL 'M' -#define AO_GPS_MODE_SIMULATED 'S' +/* Mode bits */ + +#define AO_GPS_MODE_ALTITUDE_24 (1 << 0) /* reports 24-bits of altitude */ struct ao_telemetry_location { uint16_t serial; /* 0 */ @@ -99,7 +96,7 @@ struct ao_telemetry_location { uint8_t type; /* 4 */ uint8_t flags; /* 5 Number of sats and other flags */ - int16_t altitude; /* 6 GPS reported altitude (m) */ + uint16_t altitude_low; /* 6 GPS reported altitude (m) */ int32_t latitude; /* 8 latitude (degrees * 10⁷) */ int32_t longitude; /* 12 longitude (degrees * 10⁷) */ uint8_t year; /* 16 (- 2000) */ @@ -115,10 +112,31 @@ struct ao_telemetry_location { uint16_t ground_speed; /* 26 cm/s */ int16_t climb_rate; /* 28 cm/s */ uint8_t course; /* 30 degrees / 2 */ - uint8_t unused; /* 31 unused */ + int8_t altitude_high; /* 31 high byte of altitude */ /* 32 */ }; +#if HAS_GPS + +#ifndef HAS_WIDE_GPS +#define HAS_WIDE_GPS 1 +#endif + +#if HAS_WIDE_GPS +typedef int32_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode |= AO_GPS_MODE_ALTITUDE_24), \ + ((l)->altitude_high = (a) >> 16), \ + ((l)->altitude_low = (a))) +#else +typedef int16_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((gps_alt_t) (l)->altitude_low) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode = 0, \ + (l)->altitude_low = (a))) +#endif /* HAS_WIDE_GPS */ + +#endif /* HAS_GPS */ + #define AO_TELEMETRY_SATELLITE 0x06 struct ao_telemetry_satellite_info { diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index 9febc7f0..d9434048 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -36,9 +36,9 @@ ao_usb_connected(void) #endif struct gps_position { - int32_t latitude; - int32_t longitude; - int16_t altitude; + int32_t latitude; + int32_t longitude; + gps_alt_t altitude; }; #define GPS_RING 16 @@ -122,12 +122,13 @@ ao_tracker(void) { uint8_t ring; uint8_t moving = 0; + gps_alt_t altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data); for (ring = ao_gps_ring_next(gps_head); ring != gps_head; ring = ao_gps_ring_next(ring)) { ground_distance = ao_distance(gps_data.latitude, gps_data.longitude, gps_position[ring].latitude, gps_position[ring].longitude); - height = gps_position[ring].altitude - gps_data.altitude; + height = gps_position[ring].altitude - altitude; if (height < 0) height = -height; @@ -153,7 +154,7 @@ ao_tracker(void) ao_log_gps_data(gps_tick, &gps_data); gps_position[gps_head].latitude = gps_data.latitude; gps_position[gps_head].longitude = gps_data.longitude; - gps_position[gps_head].altitude = gps_data.altitude; + gps_position[gps_head].altitude = altitude; gps_head = ao_gps_ring_next(gps_head); ao_mutex_put(&tracker_mutex); } @@ -203,7 +204,7 @@ ao_tracker_set_telem(void) printf ("log_started: %d\n", log_started); printf ("latitude: %ld\n", (long) gps_data.latitude); printf ("longitude: %ld\n", (long) gps_data.longitude); - printf ("altitude: %d\n", gps_data.altitude); + printf ("altitude: %ld\n", AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data)); printf ("log_running: %d\n", ao_log_running); printf ("log_start_pos: %ld\n", (long) ao_log_start_pos); printf ("log_cur_pos: %ld\n", (long) ao_log_current_pos); diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c index 573b5cb2..ae505dea 100644 --- a/src/test/ao_aprs_test.c +++ b/src/test/ao_aprs_test.c @@ -21,6 +21,8 @@ #include #include +#define HAS_GPS 1 + #include #define AO_GPS_NUM_SAT_MASK (0xf << 0) @@ -100,14 +102,11 @@ audio_gap(int secs) // This is where we go after reset. int main(int argc, char **argv) { - int e, x; - int a; - audio_gap(1); ao_gps_data.latitude = (45.0 + 28.25 / 60.0) * 10000000; ao_gps_data.longitude = (-(122 + 44.2649 / 60.0)) * 10000000; - ao_gps_data.altitude = 84; + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, 84); ao_gps_data.flags = (AO_GPS_VALID|AO_GPS_RUNNING); /* Transmit one packet */ diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 1ab22e5b..314998c1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -175,7 +175,7 @@ ao_gps_angle(void) ao_gps_static.latitude / 1e7, ao_gps_static.longitude / 1e7, &dist, &bearing); - height = ao_gps_static.altitude - ao_gps_prev.altitude; + height = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_static) - AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_prev); angle = atan2(dist, height); return angle * 180/M_PI; @@ -756,7 +756,10 @@ ao_sleep(void *wchan) ao_gps_static.tick = tick; ao_gps_static.latitude = int32(bytes, 0); ao_gps_static.longitude = int32(bytes, 4); - ao_gps_static.altitude = int32(bytes, 8); + { + int32_t altitude = int32(bytes, 8); + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_static, altitude); + } ao_gps_static.flags = bytes[13]; if (!ao_gps_count) ao_gps_first = ao_gps_static; diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index e799ab0f..543bbcc3 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -53,6 +53,9 @@ struct ao_gps_orig { uint16_t v_error; /* m */ }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) + #define SIRF_SAT_STATE_ACQUIRED (1 << 0) #define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2) @@ -433,7 +436,7 @@ ao_dump_state(void *wchan) if (wchan != &ao_gps_new) return; - + if (ao_gps_new & AO_GPS_NEW_DATA) { ao_gps_print(&ao_gps_data); putchar('\n'); diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 1b590d5e..5eb7118d 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -16,6 +16,7 @@ */ #define AO_GPS_TEST +#define HAS_GPS 1 #include "ao_host.h" #include #include @@ -53,6 +54,9 @@ struct ao_gps_orig { uint16_t v_error; /* m */ }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) + #define SIRF_SAT_STATE_ACQUIRED (1 << 0) #define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2) diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 4eb4b837..5ea205d6 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -16,6 +16,7 @@ */ #define AO_GPS_TEST +#define HAS_GPS 1 #include "ao_host.h" #include #include @@ -44,7 +45,7 @@ struct ao_telemetry_location { uint8_t flags; int32_t latitude; /* degrees * 10⁷ */ int32_t longitude; /* degrees * 10⁷ */ - int16_t altitude; /* m */ + int16_t altitude_low; /* m */ uint16_t ground_speed; /* cm/s */ uint8_t course; /* degrees / 2 */ uint8_t pdop; /* * 5 */ @@ -53,8 +54,14 @@ struct ao_telemetry_location { int16_t climb_rate; /* cm/s */ uint16_t h_error; /* m */ uint16_t v_error; /* m */ + int16_t altitude_high; /* m */ }; +typedef int32_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \ + ((l)->altitude_low = (a))) + #define UBLOX_SAT_STATE_ACQUIRED (1 << 0) #define UBLOX_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define UBLOX_SAT_BIT_SYNC_COMPLETE (1 << 2) -- cgit v1.2.3 From 47e62bb26984f6c84660c1d0451f77c2d6ad7e5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:13:09 -0700 Subject: altos: Scale DOP values by 10 in GPS drivers sky traq was scaling by 5, ublox was scaling by 100. Signed-off-by: Keith Packard --- src/drivers/ao_gps_skytraq.c | 6 +++--- src/drivers/ao_gps_ublox.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 81178051..066df6ff 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -278,10 +278,10 @@ ao_nmea_gga(void) ao_gps_lexchar(); i = ao_gps_decimal(0xff); - if (i <= 50) { - i = (uint8_t) 5 * i; + if (i <= 25) { + i = (uint8_t) 10 * i; if (ao_gps_char == '.') - i = (i + ((uint8_t) ao_gps_decimal(1) >> 1)); + i = (i + ((uint8_t) ao_gps_decimal(1))); } else i = 255; ao_gps_next.hdop = i; diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 48765998..74c29e0a 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -740,11 +740,11 @@ ao_gps(void) __reentrant ao_gps_data.minute = nav_timeutc.min; ao_gps_data.second = nav_timeutc.sec; - ao_gps_data.pdop = nav_dop.pdop; - ao_gps_data.hdop = nav_dop.hdop; - ao_gps_data.vdop = nav_dop.vdop; - - /* mode is not set */ + /* we report dop scaled by 10, but ublox provides dop scaled by 100 + */ + ao_gps_data.pdop = nav_dop.pdop / 10; + ao_gps_data.hdop = nav_dop.hdop / 10; + ao_gps_data.vdop = nav_dop.vdop / 10; ao_gps_data.ground_speed = nav_velned.g_speed; ao_gps_data.climb_rate = -nav_velned.vel_d; -- cgit v1.2.3 From a60ba449ec237ad3b8dade9dcea603b349dbccb1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Jul 2014 23:52:05 -0700 Subject: altos/telefire,telelco: Add HAS_RADIO_RATE to launch system software This lets us set the rate to a lower value to improve range. 9600 baud works great; 2400 baud makes the initial search take a long time. Signed-off-by: Keith Packard --- src/drivers/ao_lco_func.c | 16 +++++++++++++++- src/telefire-v0.2/ao_pins.h | 1 + src/telelco-v0.2/ao_lco.c | 2 +- src/telelco-v0.2/ao_pins.h | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c index 9e642836..32c00068 100644 --- a/src/drivers/ao_lco_func.c +++ b/src/drivers/ao_lco_func.c @@ -28,7 +28,21 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset) { int8_t r; uint16_t sent_time; + uint16_t timeout = AO_MS_TO_TICKS(10); +#if HAS_RADIO_RATE + switch (ao_config.radio_rate) { + case AO_RADIO_RATE_38400: + default: + break; + case AO_RADIO_RATE_9600: + timeout = AO_MS_TO_TICKS(20); + break; + case AO_RADIO_RATE_2400: + timeout = AO_MS_TO_TICKS(80); + break; + } +#endif ao_mutex_get(&ao_lco_mutex); command.tick = ao_time() - *tick_offset; command.box = box; @@ -36,7 +50,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset) command.channels = 0; ao_radio_cmac_send(&command, sizeof (command)); sent_time = ao_time(); - r = ao_radio_cmac_recv(query, sizeof (*query), AO_MS_TO_TICKS(10)); + r = ao_radio_cmac_recv(query, sizeof (*query), timeout); if (r == AO_RADIO_CMAC_OK) *tick_offset = sent_time - query->tick; ao_mutex_put(&ao_lco_mutex); diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index 9e6631ce..ef2d4822 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -19,6 +19,7 @@ #define _AO_PINS_H_ #define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 0 #define HAS_FLIGHT 0 diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index b3f5bb16..4b5f7a9b 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -258,7 +258,7 @@ ao_lco_search(void) for (box = 0; box < AO_PAD_MAX_BOXES; box++) { if ((box % 10) == 0) ao_lco_set_box(box); - for (try = 0; try < 5; try++) { + for (try = 0; try < 3; try++) { tick_offset = 0; r = ao_lco_query(box, &ao_pad_query, &tick_offset); PRINTD("box %d result %d\n", box, r); diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index a6fd4ff8..da790b14 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -48,6 +48,7 @@ #define HAS_USB 1 #define HAS_BEEP 1 #define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 0 #define HAS_AES 1 -- cgit v1.2.3 From adc46e2f1346d98ef4f6c2351fef95fbc8ddf831 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 3 Sep 2014 22:12:15 -0700 Subject: altos/telefire: Add firing length to manual pad command This adds an optional length of time (in 1/10s of a second) to the ao_pad_manual function to enable testing of igniters without needing to use TeleLCO. Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index 144cbd70..dc2c83fe 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -362,14 +362,26 @@ ao_pad_test(void) void ao_pad_manual(void) { + uint8_t ignite; + int repeat; ao_cmd_white(); if (!ao_match_word("DoIt")) return; ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; - ao_pad_ignite = 1 << ao_cmd_lex_i; - ao_wakeup(&ao_pad_ignite); + ignite = 1 << ao_cmd_lex_i; + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) { + repeat = 1; + ao_cmd_status = ao_cmd_success; + } else + repeat = ao_cmd_lex_i; + while (repeat-- > 0) { + ao_pad_ignite = ignite; + ao_wakeup(&ao_pad_ignite); + ao_delay(AO_PAD_FIRE_TIME>>1); + } } static __xdata struct ao_task ao_pad_task; -- cgit v1.2.3 From f395bcaa620490954d4a42de9b4870bc12bedc91 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Sep 2014 20:39:37 -0700 Subject: altos: Reduce deviation at 2400/9600 baud There's no reason to use 20.5kHz deviation at 2400 and 9600 baud, and if we get a better receiver, we'll want to use narrower deviation to have less bandwidth sucking noise into the radio. The new values are (nominally) 5.125kHz deviation for 9600 baud and 1.5kHz deviation for 2400 baud. Signed-off-by: Keith Packard --- src/cc1111/ao_radio.c | 77 ++++++++++++++++++++++++++++++++----------------- src/drivers/ao_cc1120.c | 69 +++++++++++++++++++++++++++++++++++--------- src/drivers/ao_cc1120.h | 6 ++++ src/drivers/ao_cc115l.c | 64 ++++++++++++++++++++++++++++++---------- 4 files changed, 160 insertions(+), 56 deletions(-) (limited to 'src/drivers') diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index 8f519958..b9821a42 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -60,19 +60,19 @@ * * M = 1, E = 3, bw = 75kHz * - * 20.5 kHz deviation, 9.6kbps signal + * 5.125 kHz deviation, 9.6kbps signal * - * m = 41 / 9.6, which is < 5.5: + * m = 10.25 / 9.6, which is < 5.5: * - * bw = 2.6 * 20.5 + 0.55 * 9.6 = 58.58kHz + * bw = 2.6 * 5.125 + 0.55 * 9.6 = 18.6kHz * - * M = 2, E = 3, bw = 62.5kHz + * M = 2, E = 3, bw = 53.6kHz * - * 20.5kHz deviation, 2.4kbps signal + * 1.28125kHz deviation, 2.4kbps signal * - * m = 41 / 2.4, which is > 5.5: + * m = 2.565 / 2.4, which is < 5.5: * - * bw = 2.1 * 20.5 + 1.9 * 2.4 = 47.61kHz + * bw = 2.6 * 20.5 + 1.9 * 2.4 = 47.61kHz * * M = 3, E = 3, bw = 53.6kHz * @@ -84,7 +84,7 @@ */ #define CHANBW_M_384 1 -#define CHANBW_M_96 2 +#define CHANBW_M_96 3 #define CHANBW_M_24 3 #define CHANBW_E 3 @@ -115,11 +115,19 @@ * * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E * - * So M is 6 and E is 3 + * For 20.5kHz deviation, M is 6 and E is 3 + * For 5.125kHz deviation, M is 6 and E is 1 + * For 1.28125kHz deviation, M is 0 and E is 0 */ -#define DEVIATION_M 6 -#define DEVIATION_E 3 +#define DEVIATION_M_384 6 +#define DEVIATION_E_384 3 + +#define DEVIATION_M_96 6 +#define DEVIATION_E_96 1 + +#define DEVIATION_M_24 0 +#define DEVIATION_E_24 0 /* * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone), @@ -182,9 +190,6 @@ static __code uint8_t radio_setup[] = { RF_CHANNR_OFF, 0, - RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) | - (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)), - /* SmartRF says set LODIV_BUF_CURRENT_TX to 0 * And, we're not using power ramping, so use PA_POWER 0 */ @@ -284,8 +289,10 @@ static __code uint8_t fixed_pkt_setup[] = { 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)), +#if !HAS_RADIO_RATE + RF_DEVIATN_OFF, ((DEVIATION_E_384 << RF_DEVIATN_DEVIATION_E_SHIFT) | + (DEVIATION_M_384 << RF_DEVIATN_DEVIATION_M_SHIFT)), +#endif /* max packet length -- now set inline */ RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| @@ -298,19 +305,34 @@ static __code uint8_t fixed_pkt_setup[] = { }; #if HAS_RADIO_RATE -static __code uint8_t packet_rate_setup[] = { +static __code struct { + uint8_t mdmcfg4; + uint8_t deviatn; +} packet_rate_setup[] = { /* 38400 */ - ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | - (CHANBW_M_384 << RF_MDMCFG4_CHANBW_M_SHIFT) | - (DRATE_E_384 << RF_MDMCFG4_DRATE_E_SHIFT)), + { + ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M_384 << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E_384 << RF_MDMCFG4_DRATE_E_SHIFT)), + ((DEVIATION_E_384 << RF_DEVIATN_DEVIATION_E_SHIFT) | + (DEVIATION_M_384 << RF_DEVIATN_DEVIATION_M_SHIFT)), + }, /* 9600 */ - ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | - (CHANBW_M_96 << RF_MDMCFG4_CHANBW_M_SHIFT) | - (DRATE_E_96 << RF_MDMCFG4_DRATE_E_SHIFT)), + { + ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M_96 << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E_96 << RF_MDMCFG4_DRATE_E_SHIFT)), + ((DEVIATION_E_96 << RF_DEVIATN_DEVIATION_E_SHIFT) | + (DEVIATION_M_96 << RF_DEVIATN_DEVIATION_M_SHIFT)), + }, /* 2400 */ - ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | - (CHANBW_M_24 << RF_MDMCFG4_CHANBW_M_SHIFT) | - (DRATE_E_24 << RF_MDMCFG4_DRATE_E_SHIFT)), + { + ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M_24 << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E_24 << RF_MDMCFG4_DRATE_E_SHIFT)), + ((DEVIATION_E_24 << RF_DEVIATN_DEVIATION_E_SHIFT) | + (DEVIATION_M_24 << RF_DEVIATN_DEVIATION_M_SHIFT)), + }, }; #endif @@ -380,7 +402,8 @@ ao_radio_get(uint8_t len) RF_FREQ0 = (uint8_t) (ao_config.radio_setting); RF_PKTLEN = len; #if HAS_RADIO_RATE - RF_MDMCFG4 = packet_rate_setup[ao_config.radio_rate]; + RF_MDMCFG4 = packet_rate_setup[ao_config.radio_rate].mdmcfg4; + RF_DEVIATN = packet_rate_setup[ao_config.radio_rate].deviatn; #endif } diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 1b907940..3ea8b704 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -290,15 +290,32 @@ ao_radio_idle(void) } /* - * Packet deviation is 20.5kHz + * Packet deviation * * fdev = fosc >> 24 * (256 + dev_m) << dev_e * + * Deviation for 38400 baud should be 20.5kHz: + * * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 5) = 20508Hz + * + * Deviation for 9600 baud should be 5.125kHz: + * + * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 3) = 5127Hz + * + * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and + * cc115l can't do that, so we'll use 1.5kHz instead: + * + * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 1) = 1499Hz */ -#define PACKET_DEV_E 5 -#define PACKET_DEV_M 80 +#define PACKET_DEV_M_384 80 +#define PACKET_DEV_E_384 5 + +#define PACKET_DEV_M_96 80 +#define PACKET_DEV_E_96 3 + +#define PACKET_DEV_M_24 137 +#define PACKET_DEV_E_24 1 /* * For our packet data @@ -307,41 +324,55 @@ ao_radio_idle(void) * Rdata = -------------------------------------- * fosc * 2 ** 39 * + * Given the bit period of the baseband, T, the bandwidth of the + * baseband signal is B = 1/(2T). The overall bandwidth of the + * modulated signal is then Channel bandwidth = 2Δf + 2B. + * + * 38400 -- 2 * 20500 + 38400 = 79.4 kHz + * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz + * 2400 -- 2 * 1.5 + 2400 = 5.4 khz + * * Symbol rate 38400 Baud: * * DATARATE_M = 239914 * DATARATE_E = 9 - * CHANBW = 74.42 (round to 100) + * CHANBW = 79.4 (round to 100) * * Symbol rate 9600 Baud: * * DATARATE_M = 239914 * DATARATE_E = 7 - * CHANBW = 58.58 (round to 62.5) + * CHANBW = 19.9 (round to 20) * * Symbol rate 2400 Baud: * * DATARATE_M = 239914 * DATARATE_E = 5 - * CHANBW = 47.61 (round to 50) + * CHANBW = 5.0 (round to 8.0) */ #define PACKET_DRATE_M 239914 #define PACKET_DRATE_E_384 9 -#define PACKET_CHAN_BW_384 0x02 /* 200 / 2 = 100 */ + +/* 200 / 2 = 100 */ +#define PACKET_CHAN_BW_384 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \ + (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \ + (2 << CC1120_CHAN_BW_BB_CIC_DECFACT)) #define PACKET_DRATE_E_96 7 -#define PACKET_CHAN_BW_96 0x42 /* 125 / 2 = 62.5 */ +/* 200 / 10 = 20 */ +#define PACKET_CHAN_BW_96 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \ + (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \ + (10 << CC1120_CHAN_BW_BB_CIC_DECFACT)) #define PACKET_DRATE_E_24 5 -#define PACKET_CHAN_BW_24 0x04 /* 200 / 4 = 50 */ +/* 200 / 25 = 8 */ +#define PACKET_CHAN_BW_24 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \ + (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \ + (25 << CC1120_CHAN_BW_BB_CIC_DECFACT)) static const uint16_t packet_setup[] = { - CC1120_DEVIATION_M, PACKET_DEV_M, - CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | - (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | - (PACKET_DEV_E << CC1120_MODCFG_DEV_E_DEV_E)), CC1120_DRATE1, ((PACKET_DRATE_M >> 8) & 0xff), CC1120_DRATE0, ((PACKET_DRATE_M >> 0) & 0xff), CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) | @@ -361,6 +392,10 @@ static const uint16_t packet_setup[] = { }; static const uint16_t packet_setup_384[] = { + CC1120_DEVIATION_M, PACKET_DEV_M_384, + CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | + (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | + (PACKET_DEV_E_384 << CC1120_MODCFG_DEV_E_DEV_E)), CC1120_DRATE2, ((PACKET_DRATE_E_384 << CC1120_DRATE2_DATARATE_E) | (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), CC1120_CHAN_BW, PACKET_CHAN_BW_384, @@ -368,6 +403,10 @@ static const uint16_t packet_setup_384[] = { }; static const uint16_t packet_setup_96[] = { + CC1120_DEVIATION_M, PACKET_DEV_M_96, + CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | + (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | + (PACKET_DEV_E_96 << CC1120_MODCFG_DEV_E_DEV_E)), CC1120_DRATE2, ((PACKET_DRATE_E_96 << CC1120_DRATE2_DATARATE_E) | (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), CC1120_CHAN_BW, PACKET_CHAN_BW_96, @@ -375,6 +414,10 @@ static const uint16_t packet_setup_96[] = { }; static const uint16_t packet_setup_24[] = { + CC1120_DEVIATION_M, PACKET_DEV_M_24, + CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | + (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | + (PACKET_DEV_E_24 << CC1120_MODCFG_DEV_E_DEV_E)), CC1120_DRATE2, ((PACKET_DRATE_E_24 << CC1120_DRATE2_DATARATE_E) | (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), CC1120_CHAN_BW, PACKET_CHAN_BW_24, diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h index 5d24c49a..943f3449 100644 --- a/src/drivers/ao_cc1120.h +++ b/src/drivers/ao_cc1120.h @@ -189,6 +189,12 @@ #define CC1120_FREQ_IF_CFG 0x0f #define CC1120_IQIC 0x10 #define CC1120_CHAN_BW 0x11 +#define CC1120_CHAN_BW_CHFILT_BYPASS 7 +#define CC1120_CHAN_BW_ADC_CIC_DECFACT 6 +#define CC1120_CHAN_BW_ADC_CIC_DECFACT_20 0 +#define CC1120_CHAN_BW_ADC_CIC_DECFACT_32 1 +#define CC1120_CHAN_BW_BB_CIC_DECFACT 0 + #define CC1120_MDMCFG1 0x12 #define CC1120_MDMCFG1_CARRIER_SENSE_GATE 7 #define CC1120_MDMCFG1_FIFO_EN 6 diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index b5103f9b..cf61acfe 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -249,23 +249,41 @@ ao_radio_idle(void) } /* - * Packet deviation is 20.5kHz + * Packet deviation * * fdev = fosc >> 17 * (8 + dev_m) << dev_e * + * For 38400 baud, use 20.5kHz: + * * 26e6 / (2 ** 17) * (8 + 5) * (2 ** 3) = 20630Hz + * + * For 9600 baud, use 5.125kHz: + * + * 26e6 / (2 ** 17) * (8 + 5) * (2 ** 1) = 5157Hz + * + * For 2400 baud, use 1.5kHz: + * + * 26e6 / (2 ** 17) * (8 + 0) * (2 ** 0) = 1587Hz */ -#define PACKET_DEV_E 3 -#define PACKET_DEV_M 5 +#define PACKET_DEV_E_384 3 +#define PACKET_DEV_M_384 5 + +#define PACKET_DEV_E_96 1 +#define PACKET_DEV_M_96 5 + +#define PACKET_DEV_E_24 0 +#define PACKET_DEV_M_24 0 /* - * For our packet data, set the symbol rate to 38400 Baud + * For our packet data: * * (256 + DATARATE_M) * 2 ** DATARATE_E * Rdata = -------------------------------------- * fosc * 2 ** 28 * + * For 38400 baud: + * * (256 + 131) * (2 ** 10) / (2**28) * 26e6 = 38383 * * DATARATE_M = 131 @@ -279,20 +297,33 @@ ao_radio_idle(void) #define PACKET_DRATE_E_96 8 #define PACKET_DRATE_E_24 6 -static const uint16_t packet_rate_setup[] = { - [AO_RADIO_RATE_38400] = ((0xf << 4) | - (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)), - - [AO_RADIO_RATE_9600] = ((0xf << 4) | - (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)), - - [AO_RADIO_RATE_2400] = ((0xf << 4) | - (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)), +static const struct { + uint8_t mdmcfg4; + uint8_t deviatn; +} packet_rate_setup[] = { + [AO_RADIO_RATE_38400] = { + .mdmcfg4 = ((0xf << 4) | + (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)), + .deviatn = ((PACKET_DEV_E_384 << CC115L_DEVIATN_DEVIATION_E) | + (PACKET_DEV_M_384 << CC115L_DEVIATN_DEVIATION_M)), + }, + + [AO_RADIO_RATE_9600] = { + .mdmcfg4 = ((0xf << 4) | + (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)), + .deviatn = ((PACKET_DEV_E_96 << CC115L_DEVIATN_DEVIATION_E) | + (PACKET_DEV_M_96 << CC115L_DEVIATN_DEVIATION_M)), + }, + + [AO_RADIO_RATE_2400] = { + .mdmcfg4 = ((0xf << 4) | + (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)), + .deviatn = ((PACKET_DEV_E_24 << CC115L_DEVIATN_DEVIATION_E) | + (PACKET_DEV_M_24 << CC115L_DEVIATN_DEVIATION_M)), + }, }; static const uint16_t packet_setup[] = { - CC115L_DEVIATN, ((PACKET_DEV_E << CC115L_DEVIATN_DEVIATION_E) | - (PACKET_DEV_M << CC115L_DEVIATN_DEVIATION_M)), CC115L_MDMCFG3, (PACKET_DRATE_M), CC115L_MDMCFG2, (0x00 | (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | @@ -418,7 +449,8 @@ ao_radio_set_mode(uint16_t new_mode) changes = new_mode & (~ao_radio_mode); if (changes & AO_RADIO_MODE_BITS_PACKET_TX) { - ao_radio_reg_write(CC115L_MDMCFG4, packet_rate_setup[ao_config.radio_rate]); + ao_radio_reg_write(CC115L_MDMCFG4, packet_rate_setup[ao_config.radio_rate].mdmcfg4); + ao_radio_reg_write(CC115L_DEVIATN, packet_rate_setup[ao_config.radio_rate].deviatn); for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2) ao_radio_reg_write(packet_setup[i], packet_setup[i+1]); -- cgit v1.2.3 From d83afa9320c24056469984873af0a3c70bee0962 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Sep 2014 20:44:30 -0700 Subject: altos: Scale packet master receive delay by baud rate Increase the time we wait for return packets based on the remote protocol baud rate. Signed-off-by: Keith Packard --- src/drivers/ao_packet_master.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c index d6c99cbd..23545049 100644 --- a/src/drivers/ao_packet_master.c +++ b/src/drivers/ao_packet_master.c @@ -57,6 +57,12 @@ static __xdata uint16_t ao_packet_master_time; #define AO_PACKET_MASTER_DELAY_LONG AO_MS_TO_TICKS(1000) #define AO_PACKET_MASTER_DELAY_TIMEOUT AO_MS_TO_TICKS(2000) +#if HAS_RADIO_RATE +#define AO_PACKET_MASTER_RECV_DELAY AO_MS_TO_TICKS(100) << (ao_config.radio_rate << 1) +#else +#define AO_PACKET_MASTER_RECV_DELAY AO_MS_TO_TICKS(100) +#endif + static void ao_packet_master_busy(void) { @@ -91,7 +97,7 @@ ao_packet_master(void) if (ao_tx_packet.len) ao_packet_master_busy(); ao_packet_master_check_busy(); - ao_alarm(ao_packet_master_delay); + ao_alarm(AO_PACKET_MASTER_RECV_DELAY); r = ao_packet_recv(); ao_clear_alarm(); if (r) { -- cgit v1.2.3