From c2a7420edfc90986dfc550bdfa3591c180682c00 Mon Sep 17 00:00:00 2001 From: Goebish Date: Fri, 6 Sep 2019 23:51:29 +0200 Subject: [PATCH] Basic cc2500 spectrum scanner --- Multiprotocol/Multiprotocol.ino | 8 +- Multiprotocol/Scanner_cc2500.ino | 147 +++++++++---------------------- Multiprotocol/_Config.h | 4 +- 3 files changed, 52 insertions(+), 107 deletions(-) diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index ca92421..6887ca1 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -23,7 +23,7 @@ #include //#define DEBUG_PIN // Use pin TX for AVR and SPI_CS for STM32 => DEBUG_PIN_on, DEBUG_PIN_off, DEBUG_PIN_toggle -#define DEBUG_SERIAL // Only for STM32_BOARD, compiled with Upload method "Serial"->usart1, "STM32duino bootloader"->USB serial +//#define DEBUG_SERIAL // Only for STM32_BOARD, compiled with Upload method "Serial"->usart1, "STM32duino bootloader"->USB serial #ifdef __arm__ // Let's automatically select the board if arm is selected #define STM32_BOARD @@ -114,7 +114,11 @@ uint8_t armed, arm_flags, arm_channel_previous; uint8_t num_ch; #ifdef CC2500_INSTALLED - uint8_t calData[50]; + #ifdef SCANNER_CC2500_INO + uint8_t calData[255]; + #else + uint8_t calData[50]; + #endif #endif #ifdef CHECK_FOR_BOOTLOADER diff --git a/Multiprotocol/Scanner_cc2500.ino b/Multiprotocol/Scanner_cc2500.ino index 137cc16..eef164f 100644 --- a/Multiprotocol/Scanner_cc2500.ino +++ b/Multiprotocol/Scanner_cc2500.ino @@ -15,27 +15,18 @@ #if defined(SCANNER_CC2500_INO) -// Ported from DeviationTX frequency scanner - #include "iface_cc2500.h" struct Scanner { - uint8_t rssi[255]; uint8_t chan_min; uint8_t chan_max; - uint16_t averaging; } Scanner; #define MIN_RADIOCHANNEL 0x00 -#define MAX_RADIOCHANNEL 255 //0x62 -#define CHANNEL_LOCK_TIME 300 // slow scan_channel requires 270 usec for synthesizer to settle -#define INTERNAL_AVERAGE 1 -#define AVERAGE_INTVL 50 - -static int scan_averages, scan_channel, scan_state; -static uint32_t rssi_sum; -static uint8_t calibration[MAX_RADIOCHANNEL]; -static uint8_t calibration_fscal2, calibration_fscal3; +#define MAX_RADIOCHANNEL 255 +#define CHANNEL_LOCK_TIME 300 // with precalibration, channel requires only 90 usec for synthesizer to settle +#define INTERNAL_AVERAGE 6 +#define AVERAGE_INTVL 30 enum ScanStates { SCAN_CHANNEL_CHANGE = 0, @@ -45,64 +36,30 @@ enum ScanStates { static void __attribute__((unused)) Scanner_cc2500_init() { /* Initialize CC2500 chip */ - /*CC2500_WriteReg(0x30, 0x3d); // soft reset - CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x00); // packet automation control - CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x00); // packet automation control - CC2500_WriteReg(CC2500_0A_CHANNR, 0x00); // scan_channel number - CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x08); // frequency synthesizer control - CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00); // frequency synthesizer control - CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // frequency control word, high byte - CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // frequency control word, middle byte - CC2500_WriteReg(CC2500_0F_FREQ0, 0xDE); // frequency control word, low byte - CC2500_WriteReg(CC2500_10_MDMCFG4, 0x86); // modem configuration - CC2500_WriteReg(CC2500_11_MDMCFG3, 0x83); // modem configuration - CC2500_WriteReg(CC2500_12_MDMCFG2, 0x00); // modem configuration FSK for better sensitivity - CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // modem configuration - CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // modem configuration - CC2500_WriteReg(CC2500_15_DEVIATN, 0x44); // modem deviation setting 38.085938 - CC2500_WriteReg(CC2500_17_MCSM1, 0x0F); // always stay in RX mode - CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // disable auto-calibration - CC2500_WriteReg(CC2500_19_FOCCFG, 0x16); // frequency offset compensation configuration - CC2500_WriteReg(CC2500_1A_BSCFG, 0x6C); // bit synchronization configuration - CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0x03); // agc control - CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x40); // agc control - CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0x91); // agc control - CC2500_WriteReg(CC2500_21_FREND1, 0x56); // front end rx configuration - CC2500_WriteReg(CC2500_22_FREND0, 0x10); // front end tx configuration - CC2500_WriteReg(CC2500_23_FSCAL3, 0xA9); // frequency synthesizer calibration - CC2500_WriteReg(CC2500_24_FSCAL2, 0x0A); // frequency synthesizer calibration - CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // frequency synthesizer calibration - CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // frequency synthesizer calibration - CC2500_WriteReg(CC2500_2C_TEST2, 0x88); // various test settings - CC2500_WriteReg(CC2500_2D_TEST1, 0x31); // various test settings - CC2500_WriteReg(CC2500_2E_TEST0, 0x0B); // various test settings - CC2500_WriteReg(CC2500_3E_PATABLE, 0xfe); + CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x12); // Packet Automation Control + CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control + CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00); // Frequency Synthesizer Control + CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency Control Word, High Byte + CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency Control Word, Middle Byte + CC2500_WriteReg(CC2500_0F_FREQ0, 0xC3); // Frequency Control Word, Low Byte + CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration + CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration + CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration + CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration + CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // Modem Configuration + CC2500_WriteReg(CC2500_15_DEVIATN, 0x62); // Modem Deviation Setting + CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration + CC2500_WriteReg(CC2500_19_FOCCFG, 0x1D); // Frequency Offset Compensation Configuration + CC2500_WriteReg(CC2500_1A_BSCFG, 0x1C); // Bit Synchronization Configuration + CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7); // AGC Control + CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control + CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0); // AGC Control + CC2500_WriteReg(CC2500_21_FREND1, 0xB6); // Front End RX Configuration + CC2500_SetTxRxMode(RX_EN); // Receive mode CC2500_Strobe(CC2500_SIDLE); - CC2500_Strobe(CC2500_SRX);*/ + CC2500_Strobe(CC2500_SRX); - CC2500_WriteReg(0x30, 0x3D); // software reset - CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0F); // Frequency Synthesizer Control (0x0F) - CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x12); // Packet Automation Control (0x12) - CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency control word, high byte - CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency control word, middle byte - CC2500_WriteReg(CC2500_0F_FREQ0, 0xDE); // Frequency control word, low byte - CC2500_WriteReg(CC2500_10_MDMCFG4, 0x0D); // Modem Configuration - CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration (0x3B) - CC2500_WriteReg(CC2500_12_MDMCFG2, 0x00); // Modem Configuration 0x30 - OOK modulation, 0x00 - FSK modulation (better sensitivity) - CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration - CC2500_WriteReg(CC2500_14_MDMCFG0, 0xFF); // Modem Configuration (0xFF) - CC2500_WriteReg(CC2500_17_MCSM1, 0x0F); // Always stay in RX mode - CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration (0x04) - CC2500_WriteReg(CC2500_19_FOCCFG, 0x15); // Frequency Offset Compensation configuration - CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0x83); // AGC Control (0x83) - CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control - CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0x91); // AGC Control - CC2500_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration - CC2500_WriteReg(CC2500_24_FSCAL2, 0x0A); // Frequency Synthesizer Calibration - CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration - CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration - CC2500_SetTxRxMode(RX_EN); delayMicroseconds(1000); // wait for RX to activate } @@ -113,30 +70,23 @@ static void __attribute__((unused)) _calibrate() CC2500_WriteReg(CC2500_0A_CHANNR, c); CC2500_Strobe(CC2500_SCAL); delayMicroseconds(900); - calibration[c] = CC2500_ReadReg(CC2500_25_FSCAL1); + calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1); } - calibration_fscal3 = CC2500_ReadReg(CC2500_23_FSCAL3); // only needs to be done once - calibration_fscal2 = CC2500_ReadReg(CC2500_24_FSCAL2); // only needs to be done once CC2500_Strobe(CC2500_SIDLE); } static void __attribute__((unused)) _scan_next() { - CC2500_WriteReg(CC2500_0A_CHANNR, Scanner.chan_min + scan_channel); - - CC2500_WriteReg(CC2500_23_FSCAL3, calibration_fscal3); - CC2500_WriteReg(CC2500_24_FSCAL2, calibration_fscal2); - CC2500_WriteReg(CC2500_25_FSCAL1, calibration[scan_channel]); - - //debugln("_scan_next %d", Scanner.chan_min + scan_channel); + CC2500_WriteReg(CC2500_0A_CHANNR, Scanner.chan_min + rf_ch_num); + CC2500_WriteReg(CC2500_25_FSCAL1, calData[rf_ch_num]); + CC2500_Strobe(CC2500_SFRX); + CC2500_Strobe(CC2500_SRX); } static int __attribute__((unused)) _scan_rssi() { - uint8_t rssi = CC2500_ReadReg(0x40 | CC2500_34_RSSI); // 0.5 db/count, RSSI value read from the RSSI status register is a 2’s complement number - - - + uint8_t rssi; + rssi = CC2500_ReadReg(0x40 | CC2500_34_RSSI); // 0.5 db/count, RSSI value read from the RSSI status register is a 2’s complement number uint8_t rssi_rel; if (rssi >= 128) { rssi_rel = rssi - 128; // relative power levels 0-127 (equals -137 to -72 dBm) @@ -144,29 +94,26 @@ static int __attribute__((unused)) _scan_rssi() else { rssi_rel = rssi + 128; // relativ power levels 128-255 (equals -73 to -10 dBm) } - debugln("rssi %d", rssi_rel); return rssi_rel; } uint16 Scanner_callback() { int rssi_value; - switch (scan_state) { + switch (phase) { case SCAN_CHANNEL_CHANGE: - scan_channel++; - if (scan_channel >= (Scanner.chan_max - Scanner.chan_min + 1)) - scan_channel = 0; + rf_ch_num++; + if (rf_ch_num >= (Scanner.chan_max - Scanner.chan_min + 1)) + rf_ch_num = 0; _scan_next(); - scan_state = SCAN_GET_RSSI; + phase = SCAN_GET_RSSI; return CHANNEL_LOCK_TIME; case SCAN_GET_RSSI: rssi_value = _scan_rssi(); - scan_state = SCAN_CHANNEL_CHANGE; - - // debugln("%d\t%d", scan_channel, CC2500_ReadReg(CC2500_34_RSSI)); + phase = SCAN_CHANNEL_CHANGE; // send data to TX - pkt[0] = scan_channel; // scan_channel - pkt[1] = rssi_value; // Scanner.rssi[scan_channel]; // power + pkt[0] = rf_ch_num; + pkt[1] = rssi_value; telemetry_link = 1; } return AVERAGE_INTVL; @@ -174,20 +121,14 @@ uint16 Scanner_callback() uint16_t initScanner(void) { - Scanner.chan_min = 1;//MIN_RADIOCHANNEL; - Scanner.chan_max = 1;//MAX_RADIOCHANNEL; - - scan_averages = 0; - scan_channel = 0; - scan_state = SCAN_CHANNEL_CHANGE; - memset(Scanner.rssi, 0, sizeof(Scanner.rssi)); // clear old rssi values + Scanner.chan_min = 0; // 2400 MHz + Scanner.chan_max = 249; // 2483 Mhz + rf_ch_num = 0; + phase = SCAN_CHANNEL_CHANGE; CC2500_Reset(); Scanner_cc2500_init(); - CC2500_SetPower(); CC2500_Strobe(CC2500_SRX); _calibrate(); - CC2500_Strobe(CC2500_SFSTXON); - delayMicroseconds(800); CC2500_Strobe(CC2500_SIDLE); CC2500_SetTxRxMode(RX_EN); CC2500_Strobe(CC2500_SRX); // Receive mode diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 8155f10..bdcd589 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -23,7 +23,7 @@ //If you know parameters you want for sure to be enabled or disabled which survives in future, you can use a file named "_MyConfig.h". //An example is given within the file named "_MyConfig.h.example" which needs to be renamed if you want to use it. //To enable this config file remove the // from the line below. -#define USE_MY_CONFIG +//#define USE_MY_CONFIG /*************************/ @@ -32,7 +32,7 @@ //Allow flashing multimodule directly with TX(erky9x or opentx maintenance mode) //Instructions:https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Flash_from_Tx.md //To disable this feature add "//" at the begining of the next line. Requires a compatible bootloader or upload method to be selected when you use the Multi 4-in-1 Boards Manager definitions. -//#define CHECK_FOR_BOOTLOADER +#define CHECK_FOR_BOOTLOADER /*******************/