From 4a626eaf144b4b7834d104717e7430fd5b154883 Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Wed, 17 Mar 2021 17:05:42 +0100 Subject: [PATCH] Change XN297 emulation layer Loads of protocols have been touched by this change. Some testing has been done but please test on all your models. The XN297 emulation selects in this order: - the CC2500 if it is available and bitrate=250K. Configure the option field automatically for RF tune. - the NRF for all bitrates if it is available - if NRF is not available and bitrate=1M then an invalid protocol is sent automatically to the radio. CC2500 @250K can now receive normal and enhanced payloads. OMP protocol supports telemetry on CC2500 and is also for NRF only modules including telemetry. Separation of E016H (new protocol) from E01X due to different structure. MJXQ, MT99XX, Q303 and XK: some sub protocols available on CC2500 only. --- Lua_scripts/MultiChan.txt | 2 +- Multiprotocol/BUGSMINI_nrf24l01.ino | 90 ++-- Multiprotocol/Bayang_Rx_nrf24l01.ino | 177 +++---- Multiprotocol/Bayang_nrf24l01.ino | 52 +- Multiprotocol/CC2500_SPI.ino | 120 ++--- Multiprotocol/CG023_nrf24l01.ino | 30 +- Multiprotocol/CX10_nrf24l01.ino | 113 ++--- Multiprotocol/DM002_nrf24l01.ino | 20 +- Multiprotocol/E016H_nrf24l01.ino | 154 ++++++ Multiprotocol/E01X_nrf24l01.ino | 112 +---- Multiprotocol/ESky150v2_cc2500.ino | 12 +- Multiprotocol/FX816_nrf24l01.ino | 30 +- Multiprotocol/GD00X_ccnrf.ino | 21 +- Multiprotocol/GW008_nrf24l01.ino | 45 +- Multiprotocol/H8_3D_nrf24l01.ino | 22 +- Multiprotocol/Hontai_nrf24l01.ino | 51 +- Multiprotocol/JJRC345_nrf24l01.ino | 17 +- Multiprotocol/KF606_ccnrf.ino | 21 +- .../{MJXQ_nrf24l01.ino => MJXQ_ccnrf.ino} | 70 ++- .../{MT99xx_nrf24l01.ino => MT99xx_ccnrf.ino} | 34 +- Multiprotocol/Multi.txt | 5 +- Multiprotocol/Multi_Protos.ino | 18 +- Multiprotocol/Multiprotocol.h | 11 +- Multiprotocol/Multiprotocol.ino | 4 + Multiprotocol/NRF24l01_SPI.ino | 10 +- Multiprotocol/NRF250K_EMU.ino | 303 +++-------- .../{OMP_cc2500.ino => OMP_ccnrf.ino} | 64 +-- Multiprotocol/POTENSIC_nrf24l01.ino | 15 +- .../{Q303_nrf24l01.ino => Q303_ccnrf.ino} | 32 +- Multiprotocol/Q90C_ccnrf.ino | 22 +- Multiprotocol/REALACC_nrf24l01.ino | 13 +- Multiprotocol/Telemetry.ino | 33 +- Multiprotocol/Tiger_nrf24l01.ino | 16 +- Multiprotocol/V761_nrf24l01.ino | 16 +- Multiprotocol/V911S_ccnrf.ino | 24 +- Multiprotocol/Validate.h | 13 +- .../{XK_nrf24l01.ino => XK_ccnrf.ino} | 56 +-- Multiprotocol/XN297Dump_nrf24l01.ino | 116 ++--- Multiprotocol/XN297_EMU.ino | 469 ++++++++++++++---- Multiprotocol/ZSX_nrf24l01.ino | 15 +- Multiprotocol/_Config.h | 14 +- Multiprotocol/_MyConfig.h.example | 2 +- Multiprotocol/iface_nrf250k.h | 38 +- Multiprotocol/iface_xn297.h | 97 ++-- Protocols_Details.md | 385 +++++++------- 45 files changed, 1509 insertions(+), 1475 deletions(-) create mode 100644 Multiprotocol/E016H_nrf24l01.ino rename Multiprotocol/{MJXQ_nrf24l01.ino => MJXQ_ccnrf.ino} (88%) rename Multiprotocol/{MT99xx_nrf24l01.ino => MT99xx_ccnrf.ino} (93%) rename Multiprotocol/{OMP_cc2500.ino => OMP_ccnrf.ino} (80%) rename Multiprotocol/{Q303_nrf24l01.ino => Q303_ccnrf.ino} (94%) rename Multiprotocol/{XK_nrf24l01.ino => XK_ccnrf.ino} (83%) diff --git a/Lua_scripts/MultiChan.txt b/Lua_scripts/MultiChan.txt index 86445a6..3054514 100644 --- a/Lua_scripts/MultiChan.txt +++ b/Lua_scripts/MultiChan.txt @@ -38,7 +38,6 @@ 70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12 45,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH 45,1,E01X,E015,1,Arm,Flip,LED,HLess,RTH -45,2,E01X,E016H,1,Stop,Flip,n-a,HLess,RTH 16,0,ESKY,Std,0,Gyro,Pitch 16,1,ESKY,ET4,0,Gyro,Pitch 35,0,ESKY150,4CH,0 @@ -190,3 +189,4 @@ 82,0,LOLI,Std,0,CH5,CH6,CH7,CH8,1SwSePpPw,2SwSePw,3SwSe,4SwSe,5SwSeSb,6SwSe,7SwSePw,8SwSe 83,0,E129,E129,1,TakLan,EmStop,TrimA,TrimE,TrimR 84,0,JOYSWAY,Std,0 +85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH diff --git a/Multiprotocol/BUGSMINI_nrf24l01.ino b/Multiprotocol/BUGSMINI_nrf24l01.ino index 0e45c35..36d4a36 100644 --- a/Multiprotocol/BUGSMINI_nrf24l01.ino +++ b/Multiprotocol/BUGSMINI_nrf24l01.ino @@ -16,7 +16,7 @@ #if defined(BUGSMINI_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define BUGSMINI_INITIAL_WAIT 500 #define BUGSMINI_PACKET_INTERVAL 6840 @@ -59,9 +59,8 @@ enum { static void __attribute__((unused)) BUGSMINI_RF_init() { - NRF24L01_Initialize(); - - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BUGSMINI_RX_PAYLOAD_SIZE); // bytes of data payload for rx pipe 1 + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + //XN297_HoppingCalib(BUGSMINI_NUM_RF_CHANNELS*2); } static void __attribute__((unused)) BUGSMINI_check_arming() @@ -148,15 +147,14 @@ static void __attribute__((unused)) BUGSMINI_send_packet() hopping_frequency_no++; if(hopping_frequency_no >= BUGSMINI_NUM_RF_CHANNELS) hopping_frequency_no = 0; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? hopping_frequency[hopping_frequency_no+BUGSMINI_NUM_RF_CHANNELS] : hopping_frequency[hopping_frequency_no]); + XN297_Hopping(IS_BIND_IN_PROGRESS ? hopping_frequency[hopping_frequency_no+BUGSMINI_NUM_RF_CHANNELS] : hopping_frequency[hopping_frequency_no]); } - // Power on, TX mode, 2byte CRC - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, BUGSMINI_TX_PAYLOAD_SIZE); - NRF24L01_SetPower(); } // compute final address for the rxid received during bind @@ -220,37 +218,37 @@ static void __attribute__((unused)) BUGSMINI_make_address() // Something wrong happened if we arrive here.... } +#if defined(BUGS_HUB_TELEMETRY) static void __attribute__((unused)) BUGSMINI_update_telemetry() { -#if defined(BUGS_HUB_TELEMETRY) uint8_t checksum = 0x6d; for(uint8_t i=1; i<12; i++) - checksum += packet[i]; - if(packet[0] == checksum) + checksum += packet_in[i]; + if(packet_in[0] == checksum) { - RX_RSSI = packet[3]; + RX_RSSI = packet_in[3]; if(sub_protocol==BUGS3H) { - if(packet[11] & 0x40) + if(packet_in[11] & 0x40) v_lipo1 = 0x40; // Warning - else if(packet[11] & 0x80) + else if(packet_in[11] & 0x80) v_lipo1 = 0x20; // Critical else v_lipo1 = 0x80; // Ok } else { - if(packet[11] & 0x80) + if(packet_in[11] & 0x80) v_lipo1 = 0x80; // Ok - else if(packet[11] & 0x40) + else if(packet_in[11] & 0x40) v_lipo1 = 0x40; // Warning else v_lipo1 = 0x20; // Critical } telemetry_link=1; } -#endif } +#endif uint16_t BUGSMINI_callback() { @@ -258,58 +256,52 @@ uint16_t BUGSMINI_callback() switch(phase) { case BUGSMINI_BIND1: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( XN297_IsRX() ) { // RX fifo data ready - XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE); + XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE); // Not checking the CRC?? base_adr=BUGSMINI_EEPROM_OFFSET+(RX_num&0x0F)*2; - eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM - eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); + eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM + eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM BUGSMINI_make_address(); XN297_SetTXAddr(rx_tx_addr, 5); - XN297_SetRXAddr(rx_tx_addr, 5); + XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE); phase = BUGSMINI_DATA1; BIND_DONE; - return BUGSMINI_PACKET_INTERVAL; + break; } - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); BUGSMINI_send_packet(); phase = BUGSMINI_BIND2; return BUGSMINI_WRITE_WAIT; case BUGSMINI_BIND2: // switch to RX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) - | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); phase = BUGSMINI_BIND1; return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT; case BUGSMINI_DATA1: #ifdef MULTI_SYNC telemetry_set_input_sync(BUGSMINI_PACKET_INTERVAL); #endif - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) - { // RX fifo data ready => read only 12 bytes to not overwrite channel change flag - XN297_ReadPayload(packet, 12); - BUGSMINI_update_telemetry(); - } - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); + #if defined(BUGS_HUB_TELEMETRY) + if( XN297_IsRX() ) + { + XN297_ReadPayload(packet_in, BUGSMINI_RX_PAYLOAD_SIZE); // Not checking the CRC?? + BUGSMINI_update_telemetry(); + } + #endif BUGSMINI_send_packet(); + #if not defined(BUGS_HUB_TELEMETRY) + break; + #else phase = BUGSMINI_DATA2; return BUGSMINI_WRITE_WAIT; case BUGSMINI_DATA2: // switch to RX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushRx(); - NRF24L01_SetTxRxMode(RX_EN); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) - | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); phase = BUGSMINI_DATA1; return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT; + #endif } return BUGSMINI_PACKET_INTERVAL; } @@ -349,19 +341,19 @@ static void __attribute__((unused)) BUGSMINI_initialize_txid() void BUGSMINI_init() { BUGSMINI_initialize_txid(); - memset(packet, (uint8_t)0, BUGSMINI_TX_PAYLOAD_SIZE); BUGSMINI_RF_init(); + memset(packet, (uint8_t)0, BUGSMINI_TX_PAYLOAD_SIZE); if(IS_BIND_IN_PROGRESS) { XN297_SetTXAddr((const uint8_t*)"mjxRC", 5); - XN297_SetRXAddr((const uint8_t*)"mjxRC", 5); + XN297_SetRXAddr((const uint8_t*)"mjxRC", BUGSMINI_RX_PAYLOAD_SIZE); phase = BUGSMINI_BIND1; } else { BUGSMINI_make_address(); XN297_SetTXAddr(rx_tx_addr, 5); - XN297_SetRXAddr(rx_tx_addr, 5); + XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE); phase = BUGSMINI_DATA1; } armed = 0; diff --git a/Multiprotocol/Bayang_Rx_nrf24l01.ino b/Multiprotocol/Bayang_Rx_nrf24l01.ino index f2eb40e..f29b3fa 100644 --- a/Multiprotocol/Bayang_Rx_nrf24l01.ino +++ b/Multiprotocol/Bayang_Rx_nrf24l01.ino @@ -15,7 +15,7 @@ Multiprotocol is distributed in the hope that it will be useful, #if defined(BAYANG_RX_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define BAYANG_RX_PACKET_SIZE 15 #define BAYANG_RX_RF_NUM_CHANNELS 4 @@ -27,18 +27,15 @@ enum { BAYANG_RX_DATA }; -static void __attribute__((unused)) Bayang_Rx_init_nrf24l01() +static void __attribute__((unused)) Bayang_Rx_RF_init() { const uint8_t bind_address[BAYANG_RX_ADDRESS_LENGTH] = { 0,0,0,0,0 }; - NRF24L01_Initialize(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH); - XN297_SetRXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH); - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_RX_PACKET_SIZE + 2); // 2 extra bytes for xn297 crc - NRF24L01_WriteReg(NRF24L01_05_RF_CH, BAYANG_RX_RF_BIND_CHANNEL); - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushRx(); - NRF24L01_SetTxRxMode(RX_EN); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetRXAddr(bind_address, BAYANG_RX_PACKET_SIZE); + XN297_RFChannel(BAYANG_RX_RF_BIND_CHANNEL); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } static uint8_t __attribute__((unused)) Bayang_Rx_check_validity() { @@ -91,7 +88,7 @@ static void __attribute__((unused)) Bayang_Rx_build_telemetry_packet() void BAYANG_RX_init() { uint8_t i; - Bayang_Rx_init_nrf24l01(); + Bayang_Rx_RF_init(); hopping_frequency_no = 0; rx_data_started = false; rx_data_received = false; @@ -105,8 +102,9 @@ void BAYANG_RX_init() rx_tx_addr[i] = eeprom_read_byte((EE_ADDR)temp++); for (i = 0; i < BAYANG_RX_RF_NUM_CHANNELS; i++) hopping_frequency[i] = eeprom_read_byte((EE_ADDR)temp++); + //XN297_HoppingCalib(BAYANG_RX_RF_NUM_CHANNELS); XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); - XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_PACKET_SIZE); phase = BAYANG_RX_DATA; } } @@ -116,86 +114,89 @@ uint16_t BAYANG_RX_callback() uint8_t i; static int8_t read_retry; - switch (phase) { - case BAYANG_RX_BIND: - if(IS_BIND_DONE) - { - BAYANG_RX_init(); // Abort bind - break; - } - if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { - // data received from TX - if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && ( packet[0] == 0xA4 || packet[0] == 0xA2 ) && Bayang_Rx_check_validity()) { - // store tx info into eeprom - uint16_t temp = BAYANG_RX_EEPROM_OFFSET; - for (i = 0; i < 5; i++) { - rx_tx_addr[i] = packet[i + 1]; - eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[i]); - } - for (i = 0; i < 4; i++) { - hopping_frequency[i] = packet[i + 6]; - eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]); - } - XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); - XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); - BIND_DONE; - phase = BAYANG_RX_DATA; - } - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - } - break; - case BAYANG_RX_DATA: - if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { - if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA5 && Bayang_Rx_check_validity()) { - if ((telemetry_link & 0x7F) == 0) { - Bayang_Rx_build_telemetry_packet(); - telemetry_link = 1; - #ifdef SEND_CPPM - if(sub_protocol>0) - telemetry_link |= 0x80; // Disable telemetry output - #endif - } - rx_data_started = true; - rx_data_received = true; - read_retry = 8; - pps_counter++; - } - } - // packets per second - if (millis() - pps_timer >= 1000) { - pps_timer = millis(); - debugln("%d pps", pps_counter); - RX_LQI = pps_counter >> 1; - pps_counter = 0; - } - // frequency hopping - if (read_retry++ >= 8) { - hopping_frequency_no++; - if (hopping_frequency_no >= BAYANG_RX_RF_NUM_CHANNELS) - hopping_frequency_no = 0; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - if (rx_data_started) + switch (phase) + { + case BAYANG_RX_BIND: + if(IS_BIND_DONE) { - if(rx_data_received) - { // In sync - rx_data_received = false; - read_retry = 5; - return 1500; + BAYANG_RX_init(); // Abort bind + break; + } + if ( XN297_IsRX() ) + { + debugln("RX"); + // data received from TX + if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && ( packet[0] == 0xA4 || packet[0] == 0xA2 ) && Bayang_Rx_check_validity()) + { + // store tx info into eeprom + uint16_t temp = BAYANG_RX_EEPROM_OFFSET; + for (i = 0; i < 5; i++) { + rx_tx_addr[i] = packet[i + 1]; + eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[i]); + } + for (i = 0; i < 4; i++) { + hopping_frequency[i] = packet[i + 6]; + eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]); + } + //XN297_HoppingCalib(BAYANG_RX_RF_NUM_CHANNELS); + XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_PACKET_SIZE); + BIND_DONE; + phase = BAYANG_RX_DATA; + } + XN297_SetTxRxMode(RX_EN); + } + break; + case BAYANG_RX_DATA: + if ( XN297_IsRX() ) { + if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA5 && Bayang_Rx_check_validity()) { + if ((telemetry_link & 0x7F) == 0) { + Bayang_Rx_build_telemetry_packet(); + telemetry_link = 1; + #ifdef SEND_CPPM + if(sub_protocol>0) + telemetry_link |= 0x80; // Disable telemetry output + #endif + } + rx_data_started = true; + rx_data_received = true; + read_retry = 8; + pps_counter++; + } + } + // packets per second + if (millis() - pps_timer >= 1000) { + pps_timer = millis(); + debugln("%d pps", pps_counter); + RX_LQI = pps_counter >> 1; + pps_counter = 0; + } + // frequency hopping + if (read_retry++ >= 8) { + hopping_frequency_no++; + if (hopping_frequency_no >= BAYANG_RX_RF_NUM_CHANNELS) + hopping_frequency_no = 0; + XN297_Hopping(hopping_frequency_no); + XN297_SetTxRxMode(RX_EN); + if (rx_data_started) + { + if(rx_data_received) + { // In sync + rx_data_received = false; + read_retry = 5; + return 1500; + } + else + { // packet lost + read_retry = 0; + if(RX_LQI==0) // communication lost + rx_data_started=false; + } } else - { // packet lost - read_retry = 0; - if(RX_LQI==0) // communication lost - rx_data_started=false; - } + read_retry = -16; // retry longer until first packet is caught } - else - read_retry = -16; // retry longer until first packet is caught - } - return 250; + return 250; } return 1000; } diff --git a/Multiprotocol/Bayang_nrf24l01.ino b/Multiprotocol/Bayang_nrf24l01.ino index e5e4ae3..fa9dc4c 100644 --- a/Multiprotocol/Bayang_nrf24l01.ino +++ b/Multiprotocol/Bayang_nrf24l01.ino @@ -17,7 +17,7 @@ Multiprotocol is distributed in the hope that it will be useful, #if defined(BAYANG_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define BAYANG_BIND_COUNT 1000 #define BAYANG_PACKET_PERIOD 2000 @@ -97,6 +97,8 @@ static void __attribute__((unused)) BAYANG_send_packet() } else { + XN297_Hopping(hopping_frequency_no++); + hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS; uint16_t val; uint8_t dyntrim = 1; switch (sub_protocol) @@ -192,28 +194,18 @@ static void __attribute__((unused)) BAYANG_send_packet() for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++) packet[14] += packet[i]; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? rf_ch_num:hopping_frequency[hopping_frequency_no++]); - hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS; - - // Power on, TX mode, 2byte CRC - // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing - NRF24L01_FlushTx(); - NRF24L01_SetTxRxMode(TX_EN); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, BAYANG_PACKET_SIZE); - - NRF24L01_SetPower(); // Set tx_power } #ifdef BAYANG_HUB_TELEMETRY static void __attribute__((unused)) BAYANG_check_rx(void) { - if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( XN297_IsRX() ) { // data received from model - XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 255); - - NRF24L01_FlushRx(); + XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); // Strange can't test the CRC since it seems to be disabled on telemetry packets... uint8_t check = packet[0]; for (uint8_t i=1; i < BAYANG_PACKET_SIZE-1; i++) check += packet[i]; @@ -242,27 +234,21 @@ static void __attribute__((unused)) BAYANG_check_rx(void) telemetry_link=0; // Don't send anything yet } } - NRF24L01_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(TXRX_OFF); } #endif static void __attribute__((unused)) BAYANG_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t *)"\x00\x00\x00\x00\x00", BAYANG_ADDRESS_LENGTH); - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE); + //XN297_HoppingCalib(BAYANG_RF_NUM_CHANNELS); - switch (sub_protocol) - { - case X16_AH: - case IRDRONE: - rf_ch_num = BAYANG_RF_BIND_CHANNEL_X16_AH; - break; - default: - rf_ch_num = BAYANG_RF_BIND_CHANNEL; - break; - } + //Set bind channel + uint8_t ch = BAYANG_RF_BIND_CHANNEL; + if(sub_protocol == X16_AH || sub_protocol == IRDRONE) + ch = BAYANG_RF_BIND_CHANNEL_X16_AH; + XN297_RFChannel(ch); } enum { @@ -287,7 +273,7 @@ uint16_t BAYANG_callback() { XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); #ifdef BAYANG_HUB_TELEMETRY - XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_PACKET_SIZE); #endif BIND_DONE; phase++; //WRITE @@ -322,9 +308,9 @@ uint16_t BAYANG_callback() // switch radio to rx as soon as packet is sent start=(uint16_t)micros(); while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 1000) // Wait max 1ms - if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) + if(XN297_IsPacketSent()) break; - NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03); + XN297_SetTxRxMode(RX_EN); phase++; // READ return BAYANG_PACKET_TELEM_PERIOD - BAYANG_CHECK_DELAY - BAYANG_READ_DELAY; case BAYANG_READ: diff --git a/Multiprotocol/CC2500_SPI.ino b/Multiprotocol/CC2500_SPI.ino index 55a6317..4006e0e 100644 --- a/Multiprotocol/CC2500_SPI.ino +++ b/Multiprotocol/CC2500_SPI.ino @@ -195,6 +195,7 @@ void __attribute__((unused)) CC2500_250K_Init() // TX Power = 0 // Whitening = false // Fast Frequency Hopping - no PLL auto calibration +/* //Previous config CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x01); // Packet Automation Control CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control CC2500_WriteReg(CC2500_0C_FSCTRL0, option); // Frequency offset hack @@ -217,6 +218,42 @@ void __attribute__((unused)) CC2500_250K_Init() CC2500_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration +*/ + CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // Packet Automation Control, address check true auto append RSSI & LQI + CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x00); // Packet Automation Control, fixed packet len + CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control (IF Frequency) + 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, 0xC5); // Frequency Control Word, Low Byte + CC2500_WriteReg(CC2500_10_MDMCFG4, 0x3D); // Modem Configuration Set to 406kHz BW filter + CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration + CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration, GFSK, no preambule and no sync word -> TX by default + CC2500_WriteReg(CC2500_13_MDMCFG1, 0x03); // Modem Configuration, 2 bytes of preamble + 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_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration + CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration + CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration + + //Prep RX + // Set first 3 bytes of rx addr in [0]->SYNC1, [1]->SYNC0 and [2]->ADDR + // CC2500_WriteReg(CC2500_04_SYNC1, [0]); // Sync word, high byte + // CC2500_WriteReg(CC2500_05_SYNC0, [1]); // Sync word, low byte + // CC2500_WriteReg(CC2500_09_ADDR, [2]); // Set addr + //RX + // CC2500_WriteReg(CC2500_12_MDMCFG2, 0x12); // Modem Configuration, GFSK, 16/16 Sync Word TX&RX + //TX + // CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration, GFSK, no preambule and no sync word + // need to set packet length before sending/receiving + // CC2500_WriteReg(CC2500_06_PKTLEN, cc2500_packet_len); // Packet len, fix packet len CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(); @@ -250,87 +287,4 @@ void __attribute__((unused)) CC2500_250K_RFChannel(uint8_t number) CC2500_Strobe(CC2500_SCAL); delayMicroseconds(900); } - -//NRF emulation layer with CRC16 enabled -uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len; -void __attribute__((unused)) CC2500_250K_NRF_SetTXAddr(uint8_t* addr, uint8_t len) -{ - cc2500_nrf_addr_len = len; - memcpy(cc2500_nrf_tx_addr, addr, len); -} -void __attribute__((unused)) CC2500_250K_NRF_WritePayload(uint8_t* msg, uint8_t len) -{ - #if defined(ESKY150V2_CC2500_INO) - uint8_t buf[158]; - #else - uint8_t buf[35]; - #endif - uint8_t last = 0; - uint8_t i; - - //nrf preamble - if(cc2500_nrf_tx_addr[cc2500_nrf_addr_len - 1] & 0x80) - buf[0]=0xAA; - else - buf[0]=0x55; - last++; - // address - for (i = 0; i < cc2500_nrf_addr_len; ++i) - buf[last++] = cc2500_nrf_tx_addr[cc2500_nrf_addr_len - i - 1]; - // payload - for (i = 0; i < len; ++i) - buf[last++] = msg[i]; - - // crc - crc = 0xffff; - for (uint8_t i = 1; i < last; ++i) - crc16_update( buf[i], 8); - buf[last++] = crc >> 8; - buf[last++] = crc & 0xff; - buf[last++] = 0; - - //for(uint8_t i=0;i63) - { - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63); - CC2500_Strobe(CC2500_STX); - last-=63; - buff+=63; - while(last) - {//Loop until all the data is sent - do - {// Wait for the FIFO to become available - status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST); - } - while((status&0x7F)>31 && (status&0x80)==0); - if(last>31) - {//Send 31 bytes - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31); - last-=31; - buff+=31; - } - else - {//Send last bytes - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); - last=0; - } - } - } - else - {//Send packet - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); - CC2500_Strobe(CC2500_STX); - } -} #endif \ No newline at end of file diff --git a/Multiprotocol/CG023_nrf24l01.ino b/Multiprotocol/CG023_nrf24l01.ino index 9acb9b3..d0a422f 100644 --- a/Multiprotocol/CG023_nrf24l01.ino +++ b/Multiprotocol/CG023_nrf24l01.ino @@ -63,9 +63,15 @@ static void __attribute__((unused)) CG023_send_packet() aileron = convert_channel_16b_limit(AILERON, 0x43, 0xBB); if (IS_BIND_IN_PROGRESS) + { packet[0]= 0xaa; + XN297_RFChannel(CG023_RF_BIND_CHANNEL); + } else + { packet[0]= 0x55; + XN297_RFChannel(hopping_frequency_no); + } // transmitter id packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; @@ -85,7 +91,7 @@ static void __attribute__((unused)) CG023_send_packet() if(sub_protocol==CG023) { // rate - packet[13] = CG023_FLAG_RATE_HIGH + packet[13] = CG023_FLAG_RATE_HIGH | GET_FLAG(CH5_SW,CG023_FLAG_FLIP) | GET_FLAG(CH6_SW,CG023_FLAG_LED_OFF) | GET_FLAG(CH7_SW,CG023_FLAG_STILL) @@ -95,7 +101,7 @@ static void __attribute__((unused)) CG023_send_packet() else {// YD829 // rate - packet[13] = YD829_FLAG_RATE_HIGH + packet[13] = YD829_FLAG_RATE_HIGH | GET_FLAG(CH5_SW,YD829_FLAG_FLIP) | GET_FLAG(CH7_SW,YD829_FLAG_STILL) | GET_FLAG(CH8_SW,YD829_FLAG_VIDEO) @@ -103,25 +109,15 @@ static void __attribute__((unused)) CG023_send_packet() } packet[14] = 0; - // Power on, TX mode, 2byte CRC - // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - if (IS_BIND_IN_PROGRESS) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, CG023_RF_BIND_CHANNEL); - else - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); - - // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetTxRxMode(TX_EN); + XN297_SetPower(); XN297_WritePayload(packet, CG023_PACKET_SIZE); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) CG023_RF_init() { - NRF24L01_Initialize(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); } @@ -144,7 +140,7 @@ uint16_t CG023_callback() static void __attribute__((unused)) CG023_initialize_txid() { rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); - if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel + if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel rx_tx_addr[0] ++; hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets } diff --git a/Multiprotocol/CX10_nrf24l01.ino b/Multiprotocol/CX10_nrf24l01.ino index 692e581..d792c5f 100644 --- a/Multiprotocol/CX10_nrf24l01.ino +++ b/Multiprotocol/CX10_nrf24l01.ino @@ -17,7 +17,7 @@ #if defined(CX10_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define CX10_BIND_COUNT 4360 // 6 seconds #define CX10_PACKET_SIZE 15 @@ -46,12 +46,12 @@ enum { CX10_DATA }; -static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) +static void __attribute__((unused)) CX10_Write_Packet() { uint8_t offset = 0; if(sub_protocol == CX10_BLUE) offset = 4; - packet[0] = bind ? 0xAA : 0x55; + packet[0] = IS_BIND_IN_PROGRESS ? 0xAA : 0x55; packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; packet[3] = rx_tx_addr[2]; @@ -62,57 +62,57 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) uint16_t throttle=convert_channel_16b_limit(THROTTLE,1000,2000); uint16_t rudder= convert_channel_16b_limit(RUDDER ,2000,1000); // Channel 5 - flip flag - packet[12+offset] = GET_FLAG(CH5_SW,CX10_FLAG_FLIP); // flip flag applied on rudder + packet[12+offset] = GET_FLAG(CH5_SW,CX10_FLAG_FLIP); // flip flag applied on rudder // Channel 6 - rate mode is 2 lsb of packet 13 - if(CH6_SW) // rate 3 / headless on CX-10A + if(CH6_SW) // rate 3 / headless on CX-10A flags = 0x02; else if(Channel_data[CH6] < CHANNEL_MIN_COMMAND) - flags = 0x00; // rate 1 + flags = 0x00; // rate 1 else - flags = 0x01; // rate 2 - uint8_t flags2=0; // packet 14 + flags = 0x01; // rate 2 + uint8_t flags2=0; // packet 14 uint8_t video_state=packet[14] & 0x21; switch(sub_protocol) { case CX10_BLUE: - flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture - |GET_FLAG( CH8_SW, 0x08); // Channel 8 - video + flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture + |GET_FLAG( CH8_SW, 0x08); // Channel 8 - video break; case F_Q282: case F_Q242: case F_Q222: memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6); //FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL - flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP - |GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED - |GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS - |GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL - |GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509 + flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP + |GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED + |GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS + |GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL + |GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509 if(sub_protocol==F_Q242) { flags=2; - flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture - |GET_FLAG(CH8_SW,0x10); // Channel 8 - video + flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture + |GET_FLAG(CH8_SW,0x10); // Channel 8 - video packet[17]=0x00; packet[18]=0x00; } else { // F_Q282 & F_Q222 - flags=3; // expert - if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1 + flags=3; // expert + if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1 { if (!(video_state & 0x20)) video_state ^= 0x21; } else if (video_state & 0x20) video_state &= 0x01; flags2 |= video_state - |GET_FLAG(CH7_SW,0x10); // Channel 7 - F_Q282 picture / F_Q222 Module 2 + |GET_FLAG(CH7_SW,0x10); // Channel 7 - F_Q282 picture / F_Q222 Module 2 } - if(CH10_SW) flags |=0x80; // Channel 10 - RTH + if(CH10_SW) flags |=0x80; // Channel 10 - RTH break; case DM007: aileron = 3000 - aileron; @@ -128,16 +128,16 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) if(CH8_SW) packet[12] &= ~CX10_FLAG_FLIP; case JC3015_1: //FLIP|MODE|PICTURE|VIDEO - flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7 - |GET_FLAG(CH8_SW,_BV(4)); // Channel 8 + flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7 + |GET_FLAG(CH8_SW,_BV(4)); // Channel 8 break; case MK33041: elevator = 3000 - elevator; //FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH - flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture - |GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth - flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video - |GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless + flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture + |GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth + flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video + |GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless break; } packet[5+offset] = lowByte(aileron); @@ -151,32 +151,23 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) packet[13+offset]=flags; packet[14+offset]=flags2; - // Power on, TX mode, 2byte CRC - // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - if (bind) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL); - else + // Send + if(IS_BIND_DONE) { - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); + XN297_Hopping(hopping_frequency_no++); hopping_frequency_no %= CX10_NUM_RF_CHANNELS; } - // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, packet_length); - NRF24L01_SetPower(); } static void __attribute__((unused)) CX10_RF_init() { - NRF24L01_Initialize(); - - XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5); - XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5); - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // rx pipe 0 (used only for blue board) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5); + XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", packet_length); + XN297_RFChannel(CX10_RF_BIND_CHANNEL); } uint16_t CX10_callback() @@ -190,43 +181,39 @@ uint16_t CX10_callback() } else { - CX10_Write_Packet(1); + CX10_Write_Packet(); bind_counter--; } break; case CX10_BIND2: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + // switch to TX mode + if( XN297_IsRX() ) { // RX fifo data ready - XN297_ReadPayload(packet, packet_length); - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); - if(packet[9] == 1) + debugln("RX"); + if(XN297_ReadPayload(packet, packet_length) && packet[9] == 1) { BIND_DONE; + XN297_SetTxRxMode(TXRX_OFF); phase = CX10_DATA; + break; } } else { - // switch to TX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushTx(); - NRF24L01_SetTxRxMode(TX_EN); - CX10_Write_Packet(1); + XN297_SetTxRxMode(TXRX_OFF); + CX10_Write_Packet(); // wait for packet to be sent - while( (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) == 0); //delayMicroseconds(400); - // switch to RX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushRx(); - NRF24L01_SetTxRxMode(RX_EN); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + while( !XN297_IsPacketSent()); //delayMicroseconds(400); } + // switch to RX mode + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); break; case CX10_DATA: #ifdef MULTI_SYNC telemetry_set_input_sync(packet_period); #endif - CX10_Write_Packet(0); + CX10_Write_Packet(); break; } return packet_period; diff --git a/Multiprotocol/DM002_nrf24l01.ino b/Multiprotocol/DM002_nrf24l01.ino index 201e14a..868e759 100644 --- a/Multiprotocol/DM002_nrf24l01.ino +++ b/Multiprotocol/DM002_nrf24l01.ino @@ -16,7 +16,7 @@ #if defined(DM002_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define DM002_PACKET_PERIOD 6100 // Timeout for callback in uSec #define DM002_INITIAL_WAIT 500 @@ -24,7 +24,6 @@ #define DM002_RF_BIND_CHANNEL 0x27 #define DM002_BIND_COUNT 655 // 4 seconds - enum DM002_FLAGS { // flags going to packet[9] DM002_FLAG_FLIP = 0x01, @@ -75,28 +74,23 @@ static void __attribute__((unused)) DM002_send_packet() packet_count&=0x0F; packet[10] = packet_count; packet_count++; + XN297_Hopping(hopping_frequency_no); } //CRC for(uint8_t i=0;i. + */ +// compatible with E016H + +#if defined(E016H_NRF24L01_INO) + +#include "iface_xn297.h" + +//Protocols constants +#define E016H_BIND_COUNT 500 +#define E016H_ADDRESS_LENGTH 5 + +#define E016H_PACKET_PERIOD 4080 +#define E016H_PACKET_SIZE 10 +#define E016H_BIND_CHANNEL 80 +#define E016H_NUM_CHANNELS 4 + +//Channels +#define E016H_STOP_SW CH5_SW +#define E016H_FLIP_SW CH6_SW +#define E016H_HEADLESS_SW CH8_SW +#define E016H_RTH_SW CH9_SW + +// E016H flags packet[1] +#define E016H_FLAG_CALIBRATE 0x80 +#define E016H_FLAG_STOP 0x20 +#define E016H_FLAG_FLIP 0x04 +// E016H flags packet[3] +#define E016H_FLAG_HEADLESS 0x10 +#define E016H_FLAG_RTH 0x04 +// E016H flags packet[7] +#define E016H_FLAG_TAKEOFF 0x80 +#define E016H_FLAG_HIGHRATE 0x08 + +static void __attribute__((unused)) E016H_send_packet() +{ + uint8_t can_flip = 0, calibrate = 1; + + if(IS_BIND_IN_PROGRESS) + { + memcpy(packet, &rx_tx_addr[1], 4); + memcpy(&packet[4], hopping_frequency, 4); + packet[8] = 0x23; + } + else + { + // trim commands + packet[0] = 0; + // aileron + uint16_t val = convert_channel_16b_limit(AILERON, 0, 0x3ff); + can_flip |= (val < 0x100) || (val > 0x300); + packet[1] = val >> 8; + packet[2] = val & 0xff; + if(val < 0x300) calibrate = 0; + // elevator + val = convert_channel_16b_limit(ELEVATOR, 0x3ff, 0); + can_flip |= (val < 0x100) || (val > 0x300); + packet[3] = val >> 8; + packet[4] = val & 0xff; + if(val < 0x300) calibrate = 0; + // throttle + val = convert_channel_16b_limit(THROTTLE, 0, 0x3ff); + packet[5] = val >> 8; + packet[6] = val & 0xff; + if(val > 0x100) calibrate = 0; + // rudder + val = convert_channel_16b_limit(RUDDER, 0, 0x3ff); + packet[7] = val >> 8; + packet[8] = val & 0xff; + if(val > 0x100) calibrate = 0; + // flags + packet[1] |= GET_FLAG(E016H_STOP_SW, E016H_FLAG_STOP) + | (can_flip ? GET_FLAG(E016H_FLIP_SW, E016H_FLAG_FLIP) : 0) + | (calibrate ? E016H_FLAG_CALIBRATE : 0); + packet[3] |= GET_FLAG(E016H_HEADLESS_SW, E016H_FLAG_HEADLESS) + | GET_FLAG(E016H_RTH_SW, E016H_FLAG_RTH); + packet[7] |= E016H_FLAG_HIGHRATE; + // frequency hopping + XN297_Hopping(hopping_frequency_no++ & 0x03); + } + // checksum + packet[9] = packet[0]; + for (uint8_t i=1; i < E016H_PACKET_SIZE-1; i++) + packet[9] += packet[i]; + + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); + XN297_WritePayload(packet, E016H_PACKET_SIZE); +} + +static void __attribute__((unused)) E016H_RF_init() +{ + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + XN297_SetTXAddr((uint8_t *)"\x5a\x53\x46\x30\x31", 5); // bind address + //XN297_HoppingCalib(E016H_NUM_CHANNELS); + XN297_RFChannel(E016H_BIND_CHANNEL); +} + +uint16_t E016H_callback() +{ + #ifdef MULTI_SYNC + telemetry_set_input_sync(packet_period); + #endif + if(bind_counter) + { + bind_counter--; + if (bind_counter == 0) + { + XN297_SetTXAddr(rx_tx_addr, E016H_ADDRESS_LENGTH); + BIND_DONE; + } + } + E016H_send_packet(); + return E016H_PACKET_PERIOD; +} + +static void __attribute__((unused)) E016H_initialize_txid() +{ + // tx id + rx_tx_addr[0] = 0xa5; + rx_tx_addr[1] = 0x00; + + // rf channels + uint32_t lfsr=random(0xfefefefe); + for(uint8_t i=0; i>=8; + } +} + +void E016H_init() +{ + BIND_IN_PROGRESS; + E016H_initialize_txid(); + E016H_RF_init(); + bind_counter = E016H_BIND_COUNT; + hopping_frequency_no = 0; +} + +#endif diff --git a/Multiprotocol/E01X_nrf24l01.ino b/Multiprotocol/E01X_nrf24l01.ino index 690968f..b0b59b8 100644 --- a/Multiprotocol/E01X_nrf24l01.ino +++ b/Multiprotocol/E01X_nrf24l01.ino @@ -33,11 +33,6 @@ #define E015_PACKET_SIZE 10 #define E015_BIND_PACKET_SIZE 9 -#define E016H_PACKET_PERIOD 4080 -#define E016H_PACKET_SIZE 10 -#define E016H_BIND_CHANNEL 80 -#define E016H_NUM_CHANNELS 4 - //Channels #define E01X_ARM_SW CH5_SW #define E016H_STOP_SW CH5_SW @@ -64,17 +59,6 @@ #define E015_FLAG_EXPERT 0x02 #define E015_FLAG_INTERMEDIATE 0x01 -// E016H flags packet[1] -#define E016H_FLAG_CALIBRATE 0x80 -#define E016H_FLAG_STOP 0x20 -#define E016H_FLAG_FLIP 0x04 -// E016H flags packet[3] -#define E016H_FLAG_HEADLESS 0x10 -#define E016H_FLAG_RTH 0x04 -// E016H flags packet[7] -#define E016H_FLAG_TAKEOFF 0x80 -#define E016H_FLAG_HIGHRATE 0x08 - static void __attribute__((unused)) E015_check_arming() { uint8_t arm_channel = E01X_ARM_SW; @@ -97,7 +81,6 @@ static void __attribute__((unused)) E015_check_arming() static void __attribute__((unused)) E01X_send_packet() { - uint8_t can_flip = 0, calibrate = 1; if(sub_protocol==E012) { packet_length=E012_PACKET_SIZE; @@ -132,7 +115,7 @@ static void __attribute__((unused)) E01X_send_packet() packet[13] = 0x56; packet[14] = rx_tx_addr[2]; } - else if(sub_protocol==E015) + else { // E015 if(IS_BIND_IN_PROGRESS) { @@ -170,72 +153,14 @@ static void __attribute__((unused)) E01X_send_packet() packet_length=E015_PACKET_SIZE; } } - else - { // E016H - packet_length=E016H_PACKET_SIZE; - if(IS_BIND_IN_PROGRESS) - { - rf_ch_num=E016H_BIND_CHANNEL; - memcpy(packet, &rx_tx_addr[1], 4); - memcpy(&packet[4], hopping_frequency, 4); - packet[8] = 0x23; - } - else - { - // trim commands - packet[0] = 0; - // aileron - uint16_t val = convert_channel_16b_limit(AILERON, 0, 0x3ff); - can_flip |= (val < 0x100) || (val > 0x300); - packet[1] = val >> 8; - packet[2] = val & 0xff; - if(val < 0x300) calibrate = 0; - // elevator - val = convert_channel_16b_limit(ELEVATOR, 0x3ff, 0); - can_flip |= (val < 0x100) || (val > 0x300); - packet[3] = val >> 8; - packet[4] = val & 0xff; - if(val < 0x300) calibrate = 0; - // throttle - val = convert_channel_16b_limit(THROTTLE, 0, 0x3ff); - packet[5] = val >> 8; - packet[6] = val & 0xff; - if(val > 0x100) calibrate = 0; - // rudder - val = convert_channel_16b_limit(RUDDER, 0, 0x3ff); - packet[7] = val >> 8; - packet[8] = val & 0xff; - if(val > 0x100) calibrate = 0; - // flags - packet[1] |= GET_FLAG(E016H_STOP_SW, E016H_FLAG_STOP) - | (can_flip ? GET_FLAG(E01X_FLIP_SW, E016H_FLAG_FLIP) : 0) - | (calibrate ? E016H_FLAG_CALIBRATE : 0); - packet[3] |= GET_FLAG(E01X_HEADLESS_SW, E016H_FLAG_HEADLESS) - | GET_FLAG(E01X_RTH_SW, E016H_FLAG_RTH); - packet[7] |= E016H_FLAG_HIGHRATE; - // frequency hopping - rf_ch_num=hopping_frequency[hopping_frequency_no++ & 0x03]; - } - // checksum - packet[9] = packet[0]; - for (uint8_t i=1; i < E016H_PACKET_SIZE-1; i++) - packet[9] += packet[i]; - } - // Power on, TX mode, CRC enabled - if(sub_protocol==E016H) - XN297_Configure( _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - else //E012 & E015 - HS6200_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + HS6200_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); - if(sub_protocol==E016H) - XN297_WritePayload(packet, packet_length); - else - HS6200_WritePayload(packet, packet_length); + HS6200_WritePayload(packet, packet_length); // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power @@ -250,10 +175,8 @@ static void __attribute__((unused)) E01X_RF_init() if(sub_protocol==E012) HS6200_SetTXAddr((uint8_t *)"\x55\x42\x9C\x8F\xC9", E01X_ADDRESS_LENGTH); - else if(sub_protocol==E015) + else //E015 HS6200_SetTXAddr((uint8_t *)"\x62\x54\x79\x38\x53", E01X_ADDRESS_LENGTH); - else //E016H - XN297_SetTXAddr((uint8_t *)"\x5a\x53\x46\x30\x31", 5); // bind address } uint16_t E01X_callback() @@ -266,10 +189,7 @@ uint16_t E01X_callback() bind_counter--; if (bind_counter == 0) { - if(sub_protocol==E016H) - XN297_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH); - else - HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH); + HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH); BIND_DONE; } } @@ -288,21 +208,6 @@ static void __attribute__((unused)) E012_initialize_txid() } } -static void __attribute__((unused)) E016H_initialize_txid() -{ - // tx id - rx_tx_addr[0] = 0xa5; - rx_tx_addr[1] = 0x00; - - // rf channels - uint32_t lfsr=random(0xfefefefe); - for(uint8_t i=0; i>=8; - } -} - void E01X_init() { BIND_IN_PROGRESS; @@ -311,7 +216,7 @@ void E01X_init() E012_initialize_txid(); packet_period=E012_PACKET_PERIOD; } - else if(sub_protocol==E015) + else //E015 { packet_period=E015_PACKET_PERIOD; rf_ch_num=E015_RF_CHANNEL; @@ -319,11 +224,6 @@ void E01X_init() arm_flags = 0; arm_channel_previous = E01X_ARM_SW; } - else - { // E016H - E016H_initialize_txid(); - packet_period=E016H_PACKET_PERIOD; - } E01X_RF_init(); bind_counter = E01X_BIND_COUNT; hopping_frequency_no = 0; diff --git a/Multiprotocol/ESky150v2_cc2500.ino b/Multiprotocol/ESky150v2_cc2500.ino index 8c8f2c1..a978fe6 100644 --- a/Multiprotocol/ESky150v2_cc2500.ino +++ b/Multiprotocol/ESky150v2_cc2500.ino @@ -15,7 +15,7 @@ #if defined(ESKY150V2_CC2500_INO) -#include "iface_cc2500.h" +#include "iface_nrf250k.h" //#define ESKY150V2_FORCE_ID @@ -74,7 +74,7 @@ static void __attribute__((unused)) ESKY150V2_send_packet() packet[4+2*i] = channel; packet[5+2*i] = channel>>8; } - CC2500_250K_NRF_WritePayload(packet, ESKY150V2_PAYLOADSIZE); + NRF250K_WritePayload(packet, ESKY150V2_PAYLOADSIZE); } uint16_t ESKY150V2_callback() @@ -91,12 +91,12 @@ uint16_t ESKY150V2_callback() BIND_DONE; //Need full power for bind to work... CC2500_SetPower(); //Set power level BIND_IN_PROGRESS; - CC2500_250K_NRF_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE); + NRF250K_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE); if (--bind_counter == 0) { BIND_DONE; // Change TX address from bind to normal mode - CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); + NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); memset(packet,0x00,ESKY150V2_PAYLOADSIZE); } return 30000; //ESKY150V2_BINDING_PACKET_PERIOD; @@ -118,7 +118,7 @@ void ESKY150V2_init() if(IS_BIND_IN_PROGRESS) { - CC2500_250K_NRF_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address + NRF250K_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address CC2500_250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE); @@ -132,7 +132,7 @@ void ESKY150V2_init() bind_counter=100; } else - CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); + NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); } #endif diff --git a/Multiprotocol/FX816_nrf24l01.ino b/Multiprotocol/FX816_nrf24l01.ino index 9d1abae..eac739f 100644 --- a/Multiprotocol/FX816_nrf24l01.ino +++ b/Multiprotocol/FX816_nrf24l01.ino @@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful, #if defined(FX816_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define FX816_INITIAL_WAIT 500 #define FX816_PACKET_PERIOD 10000 @@ -27,7 +27,14 @@ Multiprotocol is distributed in the hope that it will be useful, static void __attribute__((unused)) FX816_send_packet() { - packet[0] = IS_BIND_IN_PROGRESS?0x55:0xAA; + if(IS_BIND_IN_PROGRESS) + packet[0] = 0x55; + else + { + XN297_Hopping(hopping_frequency_no++); + hopping_frequency_no%=FX816_RF_NUM_CHANNELS; + packet[0] = 0xAA; + } packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; uint8_t val=convert_channel_8b(AILERON); @@ -44,25 +51,18 @@ static void __attribute__((unused)) FX816_send_packet() val+=packet[i]; packet[5]=val; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? FX816_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]); - hopping_frequency_no%=FX816_RF_NUM_CHANNELS; - - // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, FX816_PAYLOAD_SIZE); - - // Power on, TX mode, 2byte CRC - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) FX816_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5); + //XN297_HoppingCalib(FX816_RF_NUM_CHANNELS); + XN297_RFChannel(FX816_RF_BIND_CHANNEL); } static void __attribute__((unused)) FX816_initialize_txid() diff --git a/Multiprotocol/GD00X_ccnrf.ino b/Multiprotocol/GD00X_ccnrf.ino index 092d0a7..b66f3d3 100644 --- a/Multiprotocol/GD00X_ccnrf.ino +++ b/Multiprotocol/GD00X_ccnrf.ino @@ -113,7 +113,7 @@ static void __attribute__((unused)) GD00X_send_packet() if(IS_BIND_DONE) { - XN297L_Hopping(hopping_frequency_no); + XN297_Hopping(hopping_frequency_no); if(sub_protocol==GD_V1) { hopping_frequency_no++; @@ -121,21 +121,22 @@ static void __attribute__((unused)) GD00X_send_packet() } } - XN297L_WritePayload(packet, packet_length); - - XN297L_SetPower(); // Set tx_power - XN297L_SetFreqOffset(); // Set frequency offset + // Send + XN297_SetFreqOffset(); + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); + XN297_WritePayload(packet, packet_length); } static void __attribute__((unused)) GD00X_RF_init() { - XN297L_Init(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); if(sub_protocol==GD_V1) - XN297L_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); + XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); else - XN297L_SetTXAddr((uint8_t*)"GDKNx", 5); - XN297L_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels - XN297L_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel + XN297_SetTXAddr((uint8_t*)"GDKNx", 5); + XN297_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels + XN297_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel } static void __attribute__((unused)) GD00X_initialize_txid() diff --git a/Multiprotocol/GW008_nrf24l01.ino b/Multiprotocol/GW008_nrf24l01.ino index f4c95e1..6eebf4f 100644 --- a/Multiprotocol/GW008_nrf24l01.ino +++ b/Multiprotocol/GW008_nrf24l01.ino @@ -19,7 +19,7 @@ Multiprotocol is distributed in the hope that it will be useful, #if defined(GW008_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define GW008_INITIAL_WAIT 500 #define GW008_PACKET_PERIOD 2400 @@ -47,6 +47,9 @@ static void __attribute__((unused)) GW008_send_packet() } else { + XN297_Hopping((hopping_frequency_no++)/2); + hopping_frequency_no %= 8; + packet[1] = 0x01 | GET_FLAG(CH5_SW, 0x40); // flip packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator @@ -63,25 +66,21 @@ static void __attribute__((unused)) GW008_send_packet() } packet[14] = rx_tx_addr[1]; - // Power on, TX mode, CRC enabled - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? GW008_RF_BIND_CHANNEL : hopping_frequency[(hopping_frequency_no++)/2]); - hopping_frequency_no %= 8; - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) GW008_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); - XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, GW008_PAYLOAD_SIZE+2); // payload + 2 bytes for pcf + XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", GW008_PAYLOAD_SIZE); + + //XN297_HoppingCalib(8); + XN297_RFChannel(GW008_RF_BIND_CHANNEL); } static void __attribute__((unused)) GW008_initialize_txid() @@ -96,20 +95,20 @@ uint16_t GW008_callback() switch(phase) { case GW008_BIND1: - if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) && // RX fifo data ready + if(XN297_IsRX() && // RX fifo data ready XN297_ReadEnhancedPayload(packet, GW008_PAYLOAD_SIZE) == GW008_PAYLOAD_SIZE && // check payload size packet[0] == rx_tx_addr[0] && packet[14] == rx_tx_addr[1]) // check tx id { - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(TX_EN); rx_tx_addr[2] = packet[13]; BIND_DONE; phase = GW008_DATA; } else { - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(TX_EN); GW008_send_packet(); phase = GW008_BIND2; return 850; // minimum value 750 for STM32 @@ -117,14 +116,10 @@ uint16_t GW008_callback() break; case GW008_BIND2: // switch to RX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushRx(); - NRF24L01_SetTxRxMode(RX_EN); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) - | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); phase = GW008_BIND1; return 5000; - break; case GW008_DATA: #ifdef MULTI_SYNC telemetry_set_input_sync(GW008_PACKET_PERIOD); diff --git a/Multiprotocol/H8_3D_nrf24l01.ino b/Multiprotocol/H8_3D_nrf24l01.ino index 71b8c1d..eb7a3b0 100644 --- a/Multiprotocol/H8_3D_nrf24l01.ino +++ b/Multiprotocol/H8_3D_nrf24l01.ino @@ -19,7 +19,7 @@ #if defined(H8_3D_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" #define H8_3D_PACKET_PERIOD 1800 #define H20H_PACKET_PERIOD 9340 @@ -122,17 +122,15 @@ static void __attribute__((unused)) H8_3D_send_packet() sum += packet[i]; packet[19] = sum; // data checksum - // Power on, TX mode, 2byte CRC - // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + // RF channel if(sub_protocol!=H20H) { // H8_3D, H20MINI, H30MINI - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? hopping_frequency[0] : hopping_frequency[hopping_frequency_no++]); + XN297_RFChannel(IS_BIND_IN_PROGRESS ? hopping_frequency[0] : hopping_frequency[hopping_frequency_no++]); hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS; } else - { //H20H - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? H20H_BIND_RF : hopping_frequency[packet_count>>3]); + { // H20H + XN297_RFChannel(IS_BIND_IN_PROGRESS ? H20H_BIND_RF : hopping_frequency[packet_count>>3]); if(IS_BIND_DONE) { packet_count++; @@ -147,17 +145,15 @@ static void __attribute__((unused)) H8_3D_send_packet() } } - // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, H8_3D_PACKET_SIZE); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) H8_3D_RF_init() { - NRF24L01_Initialize(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); if(sub_protocol==H20H) XN297_SetTXAddr((uint8_t *)"\xEE\xDD\xCC\xBB\x11", 5); diff --git a/Multiprotocol/Hontai_nrf24l01.ino b/Multiprotocol/Hontai_nrf24l01.ino index 033f8db..fc865a7 100644 --- a/Multiprotocol/Hontai_nrf24l01.ino +++ b/Multiprotocol/Hontai_nrf24l01.ino @@ -15,7 +15,7 @@ #if defined(HONTAI_NRF24L01_INO) -#include "iface_nrf24l01.h" +#include "iface_xn297.h" // mix of nrf and xn297 at 1Mb... #define HONTAI_BIND_COUNT 80 #define HONTAI_PACKET_PERIOD 13500 @@ -44,6 +44,11 @@ static void __attribute__((unused)) HONTAI_send_packet() } else { + /*if(sub_protocol == JJRCX1) + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); + else*/ + XN297_Hopping(hopping_frequency_no++); + hopping_frequency_no %= 3; memset(packet,0,HONTAI_PACKET_SIZE); packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle packet[4] = convert_channel_16b_limit(AILERON, 63, 0); // Aileron @@ -113,42 +118,44 @@ static void __attribute__((unused)) HONTAI_send_packet() packet[packet_length-1]=bit_reverse(crc); // Power on, TX mode, 2byte CRC - if(sub_protocol == JJRCX1) + /*if(sub_protocol == JJRCX1) + { + NRF24L01_SetPower(); NRF24L01_SetTxRxMode(TX_EN); - else - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]); - hopping_frequency_no %= 3; - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + } + else*/ + { + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); + } if(sub_protocol == JJRCX1) NRF24L01_WritePayload(packet, packet_length); else XN297_WritePayload(packet, packet_length); - - NRF24L01_SetPower(); } static void __attribute__((unused)) HONTAI_RF_init() { - NRF24L01_Initialize(); - - if(sub_protocol == JJRCX1) - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5); - else - XN297_SetTXAddr((const uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); // this will select the nrf and initialize it, therefore both sub protocols can use common instructions if(sub_protocol == JJRCX1) { + //NRF24L01_Initialize(); + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5); NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xff); // JJRC uses dynamic payload length NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // match other stock settings even though AA disabled... NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); + //NRF24L01_WriteReg(NRF24L01_05_RF_CH, HONTAI_RF_BIND_CHANNEL); } - - NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX + else + { + XN297_SetTXAddr((const uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5); + //XN297_HoppingCalib(3); + } + XN297_RFChannel(HONTAI_RF_BIND_CHANNEL); } const uint8_t PROGMEM HONTAI_hopping_frequency_nonels[][3] = { @@ -172,9 +179,9 @@ static void __attribute__((unused)) HONTAI_init2() data_tx_addr[3] = pgm_read_byte_near( &HONTAI_addr_vals[3][(rx_tx_addr[4] >> 4) & 0x0f]); data_tx_addr[4] = 0x24; if(sub_protocol == JJRCX1) - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, sizeof(data_tx_addr)); + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, 5); else - XN297_SetTXAddr(data_tx_addr, sizeof(data_tx_addr)); + XN297_SetTXAddr(data_tx_addr, 5); //Hopping frequency table for(uint8_t i=0;i<3;i++) diff --git a/Multiprotocol/JJRC345_nrf24l01.ino b/Multiprotocol/JJRC345_nrf24l01.ino index 59fa23e..96de2ff 100644 --- a/Multiprotocol/JJRC345_nrf24l01.ino +++ b/Multiprotocol/JJRC345_nrf24l01.ino @@ -71,7 +71,7 @@ static void __attribute__((unused)) JJRC345_send_packet() } else { //00 41 00 0A 00 80 80 80 00 00 40 46 00 49 F1 18 - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); + XN297_Hopping(hopping_frequency_no); hopping_frequency_no++; hopping_frequency_no %= JJRC345_NUM_CHANNELS; packet[1] = hopping_frequency[hopping_frequency_no]; // next packet will be sent on this channel @@ -121,21 +121,18 @@ static void __attribute__((unused)) JJRC345_send_packet() packet[14] = rx_tx_addr[2]; packet[15] = rx_tx_addr[3]; - // Power on, TX mode - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, JJRC345_PACKET_SIZE); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) JJRC345_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel + //XN297_HoppingCalib(JJRC345_NUM_CHANNELS); + XN297_RFChannel(sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel } uint16_t JJRC345_callback() diff --git a/Multiprotocol/KF606_ccnrf.ino b/Multiprotocol/KF606_ccnrf.ino index 81094eb..2447a19 100644 --- a/Multiprotocol/KF606_ccnrf.ino +++ b/Multiprotocol/KF606_ccnrf.ino @@ -45,14 +45,15 @@ static void __attribute__((unused)) KF606_send_packet() } if(IS_BIND_DONE) { - XN297L_Hopping(hopping_frequency_no); + XN297_Hopping(hopping_frequency_no); hopping_frequency_no ^= 1; // 2 RF channels } - XN297L_WritePayload(packet, KF606_PAYLOAD_SIZE); - - XN297L_SetPower(); // Set tx_power - XN297L_SetFreqOffset(); // Set frequency offset + // Send + XN297_SetPower(); + XN297_SetFreqOffset(); + XN297_SetTxRxMode(TX_EN); + XN297_WritePayload(packet, KF606_PAYLOAD_SIZE); } static void __attribute__((unused)) KF606_initialize_txid() @@ -78,10 +79,10 @@ static void __attribute__((unused)) KF606_initialize_txid() static void __attribute__((unused)) KF606_RF_init() { - XN297L_Init(); - XN297L_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5); - XN297L_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels - XN297L_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); + XN297_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5); + XN297_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels + XN297_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel } uint16_t KF606_callback() @@ -93,7 +94,7 @@ uint16_t KF606_callback() if(--bind_counter==0) { BIND_DONE; - XN297L_SetTXAddr(rx_tx_addr, 3); + XN297_SetTXAddr(rx_tx_addr, 3); } KF606_send_packet(); return KF606_PACKET_PERIOD; diff --git a/Multiprotocol/MJXQ_nrf24l01.ino b/Multiprotocol/MJXQ_ccnrf.ino similarity index 88% rename from Multiprotocol/MJXQ_nrf24l01.ino rename to Multiprotocol/MJXQ_ccnrf.ino index 87f3096..bbc41bd 100644 --- a/Multiprotocol/MJXQ_nrf24l01.ino +++ b/Multiprotocol/MJXQ_ccnrf.ino @@ -15,10 +15,9 @@ // compatible with MJX WLH08, X600, X800, H26D, Eachine E010 // Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17 -#if defined(MJXQ_NRF24L01_INO) +#if defined(MJXQ_CCNRF_INO) -#include "iface_nrf24l01.h" -#include "iface_nrf250k.h" +#include "iface_xn297.h" #define MJXQ_BIND_COUNT 150 #define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec @@ -103,6 +102,12 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value() #define MJXQ_CHAN2TRIM(X) (((X) & 0x80 ? (X) : 0x7f - (X)) >> 1) static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) { + //RF freq + hopping_frequency_no++; + XN297_Hopping(hopping_frequency_no / 2); + hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated + + //Build packet packet[0] = convert_channel_8b(THROTTLE); packet[1] = convert_channel_s8b(RUDDER); packet[4] = 0x40; // rudder does not work well with dyntrim @@ -192,35 +197,26 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) uint8_t sum = packet[0]; for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i]; packet[15] = sum; - hopping_frequency_no++; - if (sub_protocol == E010 || sub_protocol == PHOENIX) + + // Send + XN297_SetTxRxMode(TX_EN); + XN297_SetPower(); +#ifdef NRF24L01_INSTALLED + if (sub_protocol == H26D || sub_protocol == H26WH) { - XN297L_Hopping(hopping_frequency_no / 2); - XN297L_SetFreqOffset(); - XN297L_SetPower(); - XN297L_WritePayload(packet, MJXQ_PACKET_SIZE); + //NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]); + //NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + //NRF24L01_FlushTx(); + //NRF24L01_SetTxRxMode(TX_EN); + //NRF24L01_SetPower(); + NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE); } else - { - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]); - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - - // Power on, TX mode, 2byte CRC and send packet - if (sub_protocol == H26D || sub_protocol == H26WH) - { - NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE); - } - else - { - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - XN297_WritePayload(packet, MJXQ_PACKET_SIZE); - } - NRF24L01_SetPower(); +#endif + {//E010, PHOENIX, WLH08, X600, X800 + XN297_SetFreqOffset(); + XN297_WritePayload(packet, MJXQ_PACKET_SIZE); } - hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated } static void __attribute__((unused)) MJXQ_RF_init() @@ -239,22 +235,20 @@ static void __attribute__((unused)) MJXQ_RF_init() } if (sub_protocol == E010 || sub_protocol == PHOENIX) { - XN297L_Init(); - XN297L_SetTXAddr(addr, sizeof(addr)); - XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); + XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH); + XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS); } else { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); // this will select the nrf and initialize it, therefore both H26 sub protocols can use common instructions +#ifdef NRF24L01_INSTALLED if (sub_protocol == H26D || sub_protocol == H26WH) - { NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH); - } else +#endif XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH); - - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); + //NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // no RX??? } } @@ -275,7 +269,7 @@ static void __attribute__((unused)) MJXQ_init2() hopping_frequency[i]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]&0x0F][i] ); hopping_frequency[i+2]=hopping_frequency[i]+0x10; } - XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS); + XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS); break; case WLH08: // do nothing diff --git a/Multiprotocol/MT99xx_nrf24l01.ino b/Multiprotocol/MT99xx_ccnrf.ino similarity index 93% rename from Multiprotocol/MT99xx_nrf24l01.ino rename to Multiprotocol/MT99xx_ccnrf.ino index 836bf10..cd6e85c 100644 --- a/Multiprotocol/MT99xx_nrf24l01.ino +++ b/Multiprotocol/MT99xx_ccnrf.ino @@ -15,10 +15,9 @@ // compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124 // Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29 -#if defined(MT99XX_NRF24L01_INO) +#if defined(MT99XX_CCNRF_INO) -#include "iface_nrf24l01.h" -#include "iface_nrf250k.h" +#include "iface_xn297.h" #define MT99XX_BIND_COUNT 928 #define MT99XX_PACKET_PERIOD_FY805 2460 @@ -246,17 +245,14 @@ static void __attribute__((unused)) MT99XX_send_packet() } } + //RF freq if(sub_protocol == LS) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel + XN297_RFChannel(0x2D); // LS always transmits on the same channel else if(sub_protocol==FY805) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x4B); // FY805 always transmits on the same channel + XN297_RFChannel(0x4B); // FY805 always transmits on the same channel else // MT99 & H7 & YZ & A180 & DRAGON - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - XN297_WritePayload(packet, MT99XX_PACKET_SIZE); + XN297_Hopping(hopping_frequency_no); if(sub_protocol == DRAGON) { @@ -269,23 +265,24 @@ static void __attribute__((unused)) MT99XX_send_packet() hopping_frequency_no++; if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON ) hopping_frequency_no++; // skip every other channel - if(hopping_frequency_no > 15) hopping_frequency_no = 0; - NRF24L01_SetPower(); + // Send + XN297_SetPower(); + XN297_SetFreqOffset(); + XN297_SetTxRxMode(TX_EN); + XN297_WritePayload(packet, MT99XX_PACKET_SIZE); } static void __attribute__((unused)) MT99XX_RF_init() { - NRF24L01_Initialize(); - if(sub_protocol == YZ) - XN297_SetScrambledMode(XN297_UNSCRAMBLED); + XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K); + else + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5); - if(sub_protocol == YZ) - NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps (nRF24L01+ only) - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) ); + XN297_HoppingCalib(16); } static void __attribute__((unused)) MT99XX_initialize_txid() @@ -360,6 +357,7 @@ uint16_t MT99XX_callback() uint8_t channel_offset = ((crc8>>4) + (crc8 & 0x0f)) % 8; for(uint8_t i=0;i<16;i++) hopping_frequency[i] += channel_offset; + XN297_HoppingCalib(16); BIND_DONE; } } diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index bda7221..ad4a237 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -42,7 +42,7 @@ 42,BUGSMINI,BUGSMINI,BUGS3H 43,Traxxas,RX6519 44,NCC1701 -45,E01X,E012,E015,E016H +45,E01X,E012,E015 46,V911S,V911S,E119 47,GD00x,GD_V1,GD_V2 48,V761,3CH,4CH @@ -81,4 +81,5 @@ 81,E010r5 82,LOLI 83,E129 -84,JOYSWAY \ No newline at end of file +84,JOYSWAY +85,E016H \ No newline at end of file diff --git a/Multiprotocol/Multi_Protos.ino b/Multiprotocol/Multi_Protos.ino index 6bc85ec..3f83650 100644 --- a/Multiprotocol/Multi_Protos.ino +++ b/Multiprotocol/Multi_Protos.ino @@ -97,6 +97,7 @@ const char STR_E016HV2[] ="E016Hv2"; const char STR_E010R5[] ="E010r5"; const char STR_LOLI[] ="LOLI"; const char STR_E129[] ="E129"; +const char STR_E016H[] ="E016H"; const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20"; const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501"; @@ -233,6 +234,9 @@ const mm_protocol_definition multi_protocols[] = { #if defined(E010R5_CYRF6936_INO) {PROTO_E010R5, STR_E010R5, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E010R5_init, E010R5_callback }, #endif + #if defined(E016H_NRF24L01_INO) + {PROTO_E016H, STR_E016H, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, E016H_init, E016H_callback }, + #endif #if defined(E016HV2_CC2500_INO) {PROTO_E016HV2, STR_E016HV2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_CC2500, E016HV2_init, E016HV2_callback }, #endif @@ -345,20 +349,20 @@ const mm_protocol_definition multi_protocols[] = { #if defined(LOLI_NRF24L01_INO) {PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback }, #endif - #if defined(MJXQ_NRF24L01_INO) - {PROTO_MJXQ, STR_MJXQ, STR_SUBTYPE_MJXQ, 7, OPTION_RFTUNE, 0, 0, SW_NRF, MJXQ_init, MJXQ_callback }, + #if defined(MJXQ_CCNRF_INO) + {PROTO_MJXQ, STR_MJXQ, STR_SUBTYPE_MJXQ, 7, OPTION_NONE, 0, 0, SW_NRF, MJXQ_init, MJXQ_callback }, #endif #if defined(MLINK_CYRF6936_INO) {PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback }, #endif - #if defined(MT99XX_NRF24L01_INO) + #if defined(MT99XX_CCNRF_INO) {PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 7, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback }, #endif #if defined(NCC1701_NRF24L01_INO) {PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback }, #endif - #if defined(OMP_CC2500_INO) - {PROTO_OMP, STR_OMP, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, OMP_init, OMP_callback }, + #if defined(OMP_CCNRF_INO) + {PROTO_OMP, STR_OMP, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, OMP_init, OMP_callback }, #endif #if defined(PELIKAN_A7105_INO) {PROTO_PELIKAN, STR_PELIKAN, STR_SUBTYPE_PELIKAN, 2, OPTION_NONE, 0, 1, SW_A7105, PELIKAN_init, PELIKAN_callback }, @@ -372,7 +376,7 @@ const mm_protocol_definition multi_protocols[] = { #if defined(CX10_NRF24L01_INO) {PROTO_Q2X2, STR_Q2X2, STR_SUBTYPE_Q2X2, 3, OPTION_NONE, 0, 0, SW_NRF, CX10_init, CX10_callback }, #endif - #if defined(Q303_NRF24L01_INO) + #if defined(Q303_CCNRF_INO) {PROTO_Q303, STR_Q303, STR_SUBTYPE_Q303, 4, OPTION_NONE, 0, 0, SW_NRF, Q303_init, Q303_callback }, #endif #if defined(Q90C_CCNRF_INO) @@ -427,7 +431,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_OPTION, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback }, // {PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_WBUS, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },// crash OpenTX... #endif - #if defined(XK_NRF24L01_INO) + #if defined(XK_CCNRF_INO) {PROTO_XK, STR_XK, STR_SUBTYPE_XK, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback }, #endif #if defined(XN297DUMP_NRF24L01_INO) diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 9ba165f..372e1bc 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 2 -#define VERSION_PATCH_LEVEL 61 +#define VERSION_PATCH_LEVEL 62 #define MODE_SERIAL 0 @@ -112,6 +112,7 @@ enum PROTOCOLS PROTO_LOLI = 82, // =>NRF24L01 PROTO_E129 = 83, // =>CYRF6936 PROTO_JOYSWAY = 84, // =>A7105 + PROTO_E016H = 85, // =>NRF24L01 PROTO_NANORF = 126, // =>NRF24L01 PROTO_TEST = 127, // =>CC2500 @@ -587,6 +588,11 @@ enum MultiPacketTypes #define DISABLE_TELEM_on protocol_flags3 |= _BV(3) #define IS_DISABLE_TELEM_on ( ( protocol_flags3 & _BV(3) ) !=0 ) #define IS_DISABLE_TELEM_off ( ( protocol_flags3 & _BV(3) ) ==0 ) +//Valid/invalid sub_proto +#define SUB_PROTO_VALID protocol_flags3 &= ~_BV(6) +#define SUB_PROTO_INVALID protocol_flags3 |= _BV(6) +#define IS_SUB_PROTO_INVALID ( ( protocol_flags3 & _BV(6) ) !=0 ) +#define IS_SUB_PROTO_VALID ( ( protocol_flags3 & _BV(6) ) ==0 ) //LBT power #define LBT_POWER_off protocol_flags3 &= ~_BV(7) #define LBT_POWER_on protocol_flags3 |= _BV(7) @@ -890,6 +896,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- E010R5 81 LOLI 82 E129 83 + JOYSWAY 84 + E016H 85 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -1035,7 +1043,6 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- sub_protocol==E01X E012 0 E015 1 - E016H 2 sub_protocol==GD00X GD_V1 0 GD_V2 1 diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 73ea7d0..5c12a80 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -158,6 +158,7 @@ uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, CH5, CH6, CH7, CH8, CH9, // Mode_select variables uint8_t mode_select; uint8_t protocol_flags=0,protocol_flags2=0,protocol_flags3=0; +uint8_t option_override; #ifdef ENABLE_PPM // PPM variable @@ -1179,6 +1180,9 @@ static void protocol_init() FAILSAFE_VALUES_off; #endif DATA_BUFFER_LOW_off; + + SUB_PROTO_VALID; + option_override = 0xFF; blink=millis(); diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino index 9b0753a..22e0c2a 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -28,7 +28,6 @@ void NRF24L01_Initialize() { rf_setup = 0x09; prev_power = 0x00; // Make sure prev_power is inline with current power - XN297_SetScrambledMode(XN297_SCRAMBLED); //Load most likely default NRF config NRF24L01_FlushTx(); @@ -196,11 +195,11 @@ void NRF24L01_SetPower() void NRF24L01_SetTxRxMode(enum TXRX_State mode) { + NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) + | (1 << NRF24L01_07_TX_DS) + | (1 << NRF24L01_07_MAX_RT)); if(mode == TX_EN) { NRF_CE_off; - NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) - | (1 << NRF24L01_07_TX_DS) - | (1 << NRF24L01_07_MAX_RT)); NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to TX mode | (1 << NRF24L01_00_CRCO) | (1 << NRF24L01_00_PWR_UP)); @@ -211,9 +210,6 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode) if (mode == RX_EN) { NRF_CE_off; - NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) - | (1 << NRF24L01_07_TX_DS) - | (1 << NRF24L01_07_MAX_RT)); NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to RX mode | (1 << NRF24L01_00_CRCO) | (1 << NRF24L01_00_PWR_UP) diff --git a/Multiprotocol/NRF250K_EMU.ino b/Multiprotocol/NRF250K_EMU.ino index 27712b1..44da9b8 100644 --- a/Multiprotocol/NRF250K_EMU.ino +++ b/Multiprotocol/NRF250K_EMU.ino @@ -15,223 +15,16 @@ #if defined(CC2500_INSTALLED) || defined(NRF24L01_INSTALLED) #include "iface_nrf250k.h" -#include "iface_xn297.h" -static void __attribute__((unused)) XN297L_Init() -{ - //CC2500 - #if defined(CC2500_INSTALLED) - debugln("Using CC2500"); - xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default - rf_switch(SW_CC2500); - CC2500_250K_Init(); - #elif defined(NRF24L01_INSTALLED) - debugln("Using NRF"); - rf_switch(SW_NRF); - NRF24L01_Initialize(); - NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps - #endif -} - -static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len) -{ - #if defined(CC2500_INSTALLED) - if (len > 5) len = 5; - if (len < 3) len = 3; - xn297_addr_len = len; - memcpy(xn297_tx_addr, addr, len); - #elif defined(NRF24L01_INSTALLED) - XN297_SetTXAddr(addr,len); - #endif -} - -static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len) -{ - #if defined(CC2500_INSTALLED) - uint8_t buf[32]; - uint8_t last = 0; - uint8_t i; - - // address - for (i = 0; i < xn297_addr_len; ++i) - { - buf[last] = xn297_tx_addr[xn297_addr_len - i - 1]; - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[i]; - last++; - } - - // payload - for (i = 0; i < len; ++i) { - // bit-reverse bytes in packet - buf[last] = bit_reverse(msg[i]); - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[xn297_addr_len+i]; - last++; - } - - // crc - crc = 0xb5d2; - for (uint8_t i = 0; i < last; ++i) - crc16_update( buf[i], 8); - if(xn297_scramble_enabled) - crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]); - else - crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]); - buf[last++] = crc >> 8; - buf[last++] = crc & 0xff; - - // stop TX/RX - CC2500_Strobe(CC2500_SIDLE); - // flush tx FIFO - CC2500_Strobe(CC2500_SFTX); - // packet length - CC2500_WriteReg(CC2500_3F_TXFIFO, last + 3); - // xn297L preamble - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x71\x0f\x55", 3); - // xn297 packet - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last); - // transmit - CC2500_Strobe(CC2500_STX); - #elif defined(NRF24L01_INSTALLED) - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - XN297_WritePayload(msg, len); - #endif -} - -static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack) -{ - #if defined(CC2500_INSTALLED) - uint8_t buf[32]; - uint8_t scramble_index=0; - uint8_t last = 0; - static uint8_t pid=0; - - // address - for (uint8_t i = 0; i < xn297_addr_len; ++i) - { - buf[last] = xn297_tx_addr[xn297_addr_len-i-1]; - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[scramble_index++]; - last++; - } - - // pcf - buf[last] = (len << 1) | (pid>>1); - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[scramble_index++]; - last++; - buf[last] = (pid << 7) | (noack << 6); - - // payload - buf[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[scramble_index++]; - - for (uint8_t i = 0; i < len-1; ++i) - { - last++; - buf[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2); - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[scramble_index++]; - } - - last++; - buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload - if(xn297_scramble_enabled) - buf[last] ^= xn297_scramble[scramble_index++] & 0xc0; - - // crc - //if (xn297_crc) - { - crc = 0xb5d2; - for (uint8_t i = 0; i < last; ++i) - crc16_update( buf[i], 8); - crc16_update( buf[last] & 0xc0, 2); - if (xn297_scramble_enabled) - crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]); - //else - // crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]); - - buf[last++] |= (crc >> 8) >> 2; - buf[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2); - buf[last++] = (crc & 0xff) << 6; - } - - pid++; - pid &= 3; - - // stop TX/RX - CC2500_Strobe(CC2500_SIDLE); - // flush tx FIFO - CC2500_Strobe(CC2500_SFTX); - // packet length - CC2500_WriteReg(CC2500_3F_TXFIFO, last + 3); - // xn297L preamble - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x71\x0F\x55", 3); - // xn297 packet - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last); - // transmit - CC2500_Strobe(CC2500_STX); - #elif defined(NRF24L01_INSTALLED) - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - XN297_WriteEnhancedPayload(msg, len, noack); - #endif -} - -static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq) -{ //calibrate hopping frequencies - #if defined(CC2500_INSTALLED) - CC2500_250K_HoppingCalib(num_freq); - #elif defined(NRF24L01_INSTALLED) - (void)num_freq; - #endif -} - -static void __attribute__((unused)) XN297L_Hopping(uint8_t index) -{ - #if defined(CC2500_INSTALLED) - CC2500_250K_Hopping(index); - #elif defined(NRF24L01_INSTALLED) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]); - #endif -} - -static void __attribute__((unused)) XN297L_RFChannel(uint8_t number) -{ //change channel - #if defined(CC2500_INSTALLED) - CC2500_250K_RFChannel(number); - #elif defined(NRF24L01_INSTALLED) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, number); - #endif -} - -static void __attribute__((unused)) XN297L_SetPower() -{ - #if defined(CC2500_INSTALLED) - CC2500_SetPower(); - #elif defined(NRF24L01_INSTALLED) - NRF24L01_SetPower(); - #endif -} - -static void __attribute__((unused)) XN297L_SetFreqOffset() -{ // Frequency offset - #if defined(CC2500_INSTALLED) - CC2500_SetFreqOffset(); - #endif -} +uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len; static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len) { if (len > 5) len = 5; if (len < 3) len = 3; #if defined(CC2500_INSTALLED) - CC2500_250K_NRF_SetTXAddr(addr, len); + cc2500_nrf_addr_len = len; + memcpy(cc2500_nrf_tx_addr, addr, len); #elif defined(NRF24L01_INSTALLED) NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, len); @@ -241,20 +34,86 @@ static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t len) { #if defined(CC2500_INSTALLED) - CC2500_250K_NRF_WritePayload(msg, len); + #if defined(ESKY150V2_CC2500_INO) + uint8_t buf[158]; + #else + uint8_t buf[35]; + #endif + uint8_t last = 0; + uint8_t i; + + //nrf preamble + if(cc2500_nrf_tx_addr[cc2500_nrf_addr_len - 1] & 0x80) + buf[0]=0xAA; + else + buf[0]=0x55; + last++; + // address + for (i = 0; i < cc2500_nrf_addr_len; ++i) + buf[last++] = cc2500_nrf_tx_addr[cc2500_nrf_addr_len - i - 1]; + // payload + for (i = 0; i < len; ++i) + buf[last++] = msg[i]; + + // crc + crc = 0xffff; + for (uint8_t i = 1; i < last; ++i) + crc16_update( buf[i], 8); + buf[last++] = crc >> 8; + buf[last++] = crc & 0xff; + buf[last++] = 0; + + //for(uint8_t i=0;i63) + { + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63); + CC2500_Strobe(CC2500_STX); + last-=63; + buff+=63; + while(last) + {//Loop until all the data is sent + do + {// Wait for the FIFO to become available + status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST); + } + while((status&0x7F)>31 && (status&0x80)==0); + if(last>31) + {//Send 31 bytes + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31); + last-=31; + buff+=31; + } + else + {//Send last bytes + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); + last=0; + } + } + } + else + {//Send packet + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); + CC2500_Strobe(CC2500_STX); + } #elif defined(NRF24L01_INSTALLED) - NRF24L01_FlushTx(); - NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT)); - NRF24L01_WritePayload(msg, len); + if(len<=32) + { + NRF24L01_FlushTx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT)); + NRF24L01_WritePayload(msg, len); + } #endif } -static boolean __attribute__((unused)) NRF250K_IsPacketSent() -{ - #if defined(CC2500_INSTALLED) - return true; // don't know on the CC2500 how to detect if the packet has been transmitted... - #elif defined(NRF24L01_INSTALLED) - return NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS); - #endif -} #endif diff --git a/Multiprotocol/OMP_cc2500.ino b/Multiprotocol/OMP_ccnrf.ino similarity index 80% rename from Multiprotocol/OMP_cc2500.ino rename to Multiprotocol/OMP_ccnrf.ino index 5cb5630..a2900fc 100644 --- a/Multiprotocol/OMP_cc2500.ino +++ b/Multiprotocol/OMP_ccnrf.ino @@ -13,13 +13,9 @@ Multiprotocol is distributed in the hope that it will be useful, along with Multiprotocol. If not, see . */ -#if defined(OMP_CC2500_INO) +#if defined(OMP_CCNRF_INO) -#ifndef NRF24L01_INSTALLED - #undef OMP_HUB_TELEMETRY -#endif - -#include "iface_nrf250k.h" +#include "iface_xn297.h" //#define FORCE_OMP_ORIGINAL_ID //#define OMP_TELEM_DEBUG @@ -33,10 +29,6 @@ Multiprotocol is distributed in the hope that it will be useful, static void __attribute__((unused)) OMP_send_packet() { - #ifdef OMP_HUB_TELEMETRY - rf_switch(SW_CC2500); - #endif - if(IS_BIND_IN_PROGRESS) { memcpy(packet,"BND",3); @@ -52,15 +44,12 @@ static void __attribute__((unused)) OMP_send_packet() packet_sent++; packet_sent %= OMP_RF_NUM_CHANNELS-1; // Change telem RX channels every time if(packet_sent==0) - { packet[0] |= 0x40; // |0x40 to request RX telemetry - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); - } #endif //hopping frequency packet[0 ] |= hopping_frequency_no; - XN297L_Hopping(hopping_frequency_no); + XN297_Hopping(hopping_frequency_no); hopping_frequency_no++; hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels @@ -103,27 +92,22 @@ static void __attribute__((unused)) OMP_send_packet() packet[15] = 0x04; } - XN297L_SetPower(); // Set tx_power - XN297L_SetFreqOffset(); // Set frequency offset - XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0); + XN297_SetPower(); // Set tx_power + XN297_SetFreqOffset(); // Set frequency offset + XN297_SetTxRxMode(TX_EN); + XN297_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0); } static void __attribute__((unused)) OMP_RF_init() { //Config CC2500 - XN297L_Init(); - XN297L_SetTXAddr((uint8_t*)"FLPBD", 5); - XN297L_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels - XN297L_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); + XN297_SetTXAddr((uint8_t*)"FLPBD", 5); + XN297_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels + XN297_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel #ifdef OMP_HUB_TELEMETRY - //Config NRF - NRF24L01_Initialize(); - NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps - XN297_Configure(_BV(NRF24L01_00_EN_CRC)); - XN297_SetRXAddr(rx_tx_addr, 5); // Set the RX address - NRF24L01_SetTxRxMode(TXRX_OFF); // Turn it off for now - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, OMP_PAYLOAD_SIZE + 4); // packet length +4 bytes of PCF+CRC + XN297_SetRXAddr(rx_tx_addr, OMP_PAYLOAD_SIZE); #endif } @@ -167,6 +151,8 @@ enum { uint16_t OMP_callback() { + bool rx; + switch(phase) { case OMP_BIND: @@ -176,12 +162,15 @@ uint16_t OMP_callback() return OMP_PACKET_PERIOD; case OMP_PREPDATA: BIND_DONE; - XN297L_SetTXAddr(rx_tx_addr, 5); + XN297_SetTXAddr(rx_tx_addr, 5); phase++; // OMP_DATA case OMP_DATA: #ifdef MULTI_SYNC telemetry_set_input_sync(OMP_PACKET_PERIOD); #endif + #ifdef OMP_HUB_TELEMETRY + rx = XN297_IsRX(); // Needed for the NRF24L01 since otherwise the bit gets cleared + #endif OMP_send_packet(); #ifdef OMP_HUB_TELEMETRY if(packet_sent == 0) @@ -191,8 +180,11 @@ uint16_t OMP_callback() } else if(packet_sent == 1) { - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( rx ) { // a packet has been received + #ifdef OMP_TELEM_DEBUG + debug("RX :"); + #endif if(XN297_ReadEnhancedPayload(packet_in, OMP_PAYLOAD_SIZE) == OMP_PAYLOAD_SIZE) { // packet with good CRC and length #ifdef OMP_TELEM_DEBUG @@ -238,7 +230,7 @@ uint16_t OMP_callback() debugln(""); #endif } - NRF24L01_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(TXRX_OFF); packet_count++; if(packet_count>=100) {//LQI calculation @@ -254,21 +246,15 @@ uint16_t OMP_callback() return OMP_PACKET_PERIOD; #ifdef OMP_HUB_TELEMETRY case OMP_RX: - NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) - | (1 << NRF24L01_07_TX_DS) - | (1 << NRF24L01_07_MAX_RT)); - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP) | (1 << NRF24L01_00_PRIM_RX) ); // Start RX { uint16_t start=(uint16_t)micros(); while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500) { - if(CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13) + if(XN297_IsPacketSent()) break; } } - NRF_CE_on; - rf_switch(SW_NRF); + XN297_SetTxRxMode(RX_EN); phase = OMP_DATA; return OMP_PACKET_PERIOD-OMP_WRITE_TIME; #endif diff --git a/Multiprotocol/POTENSIC_nrf24l01.ino b/Multiprotocol/POTENSIC_nrf24l01.ino index 74fde10..77826e8 100644 --- a/Multiprotocol/POTENSIC_nrf24l01.ino +++ b/Multiprotocol/POTENSIC_nrf24l01.ino @@ -61,19 +61,20 @@ static void __attribute__((unused)) POTENSIC_send_packet() } POTENSIC_set_checksum(); packet[9] = hopping_frequency_no; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no&0x03]); + + //RF channel + XN297_Hopping(hopping_frequency_no&0x03); hopping_frequency_no++; - // Power on, TX mode, 2byte CRC - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, POTENSIC_PACKET_SIZE); - NRF24L01_SetPower(); } static void __attribute__((unused)) POTENSIC_RF_init() { - NRF24L01_Initialize(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); if(IS_BIND_IN_PROGRESS) XN297_SetTXAddr((uint8_t*)"\x01\x01\x01\x01\x06", 5); // Bind address diff --git a/Multiprotocol/Q303_nrf24l01.ino b/Multiprotocol/Q303_ccnrf.ino similarity index 94% rename from Multiprotocol/Q303_nrf24l01.ino rename to Multiprotocol/Q303_ccnrf.ino index 9544f60..f22f018 100644 --- a/Multiprotocol/Q303_nrf24l01.ino +++ b/Multiprotocol/Q303_ccnrf.ino @@ -13,7 +13,7 @@ along with Multiprotocol. If not, see . */ -#if defined(Q303_NRF24L01_INO) +#if defined(Q303_CCNRF_INO) #include "iface_nrf24l01.h" @@ -185,6 +185,11 @@ static void __attribute__((unused)) Q303_send_packet() } else { + //RF freq + XN297_Hopping(hopping_frequency_no++); + hopping_frequency_no %= rf_ch_num; + + //Build packet packet[0] = 0x55; // sticks switch(sub_protocol) @@ -267,32 +272,27 @@ static void __attribute__((unused)) Q303_send_packet() } } - // Power on, TX mode, CRC enabled - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - - NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? Q303_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]); - hopping_frequency_no %= rf_ch_num; - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - + // Send + XN297_SetPower(); + XN297_SetFreqOffset(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, packet_length); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) Q303_RF_init() { const uint8_t bind_address[] = {0xcc,0xcc,0xcc,0xcc,0xcc}; - NRF24L01_Initialize(); - if(sub_protocol==Q303) { - XN297_SetScrambledMode(XN297_UNSCRAMBLED); - NRF24L01_SetBitrate(NRF24L01_BR_250K); + XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K); + XN297_HoppingCalib(rf_ch_num); } + else + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + XN297_SetTXAddr(bind_address, 5); + XN297_RFChannel(Q303_RF_BIND_CHANNEL); } static void __attribute__((unused)) Q303_initialize_txid() diff --git a/Multiprotocol/Q90C_ccnrf.ino b/Multiprotocol/Q90C_ccnrf.ino index a6a9d17..078df73 100644 --- a/Multiprotocol/Q90C_ccnrf.ino +++ b/Multiprotocol/Q90C_ccnrf.ino @@ -51,7 +51,7 @@ static void __attribute__((unused)) Q90C_send_packet() } else { - XN297L_Hopping(hopping_frequency_no++); // RF Freq + XN297_Hopping(hopping_frequency_no++); // RF Freq hopping_frequency_no %= Q90C_RF_NUM_CHANNELS; packet[0]= convert_channel_8b(THROTTLE); // 0..255 // A,E,R have weird scaling, 0x00-0xff range (unsigned) but center isn't 7f or 80 @@ -108,9 +108,11 @@ static void __attribute__((unused)) Q90C_send_packet() packet[11] = sum ^ crc8; } - XN297L_SetFreqOffset(); // Set frequency offset - XN297L_SetPower(); // Set tx_power - XN297L_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0); + // Send + XN297_SetFreqOffset(); // Set frequency offset + XN297_SetPower(); // Set tx_power + XN297_SetTxRxMode(TX_EN); + XN297_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0); } static void __attribute__((unused)) Q90C_initialize_txid() @@ -133,13 +135,13 @@ static void __attribute__((unused)) Q90C_initialize_txid() static void __attribute__((unused)) Q90C_RF_init() { - XN297L_Init(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); if(IS_BIND_IN_PROGRESS) - XN297L_SetTXAddr((uint8_t*)"\x4F\x43\x54\x81\x81", Q90C_ADDRESS_LENGTH); + XN297_SetTXAddr((uint8_t*)"\x4F\x43\x54\x81\x81", Q90C_ADDRESS_LENGTH); else - XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); - XN297L_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels - XN297L_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel + XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); + XN297_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels + XN297_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel } uint16_t Q90C_callback() @@ -151,7 +153,7 @@ uint16_t Q90C_callback() if(--bind_counter==0) { BIND_DONE; - XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); + XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); } Q90C_send_packet(); return Q90C_PACKET_PERIOD; diff --git a/Multiprotocol/REALACC_nrf24l01.ino b/Multiprotocol/REALACC_nrf24l01.ino index 3d2fc51..d900791 100644 --- a/Multiprotocol/REALACC_nrf24l01.ino +++ b/Multiprotocol/REALACC_nrf24l01.ino @@ -51,7 +51,7 @@ static void __attribute__((unused)) REALACC_send_packet() | GET_FLAG(CH5_SW, 0x01) // Flip | GET_FLAG(CH6_SW, 0x80); // Light - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); + XN297_Hopping(hopping_frequency_no); hopping_frequency_no++; hopping_frequency_no %= REALACC_RF_NUM_CHANNELS; XN297_WriteEnhancedPayload(packet, REALACC_PAYLOAD_SIZE,0); @@ -88,10 +88,9 @@ static void __attribute__((unused)) REALACC_initialize_txid() static void __attribute__((unused)) REALACC_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t*)"MAIN", 4); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, REALACC_BIND_RF_CHANNEL); // Set bind channel + XN297_RFChannel(REALACC_BIND_RF_CHANNEL); // Set bind channel } uint16_t REALACC_callback() @@ -99,10 +98,8 @@ uint16_t REALACC_callback() #ifdef MULTI_SYNC telemetry_set_input_sync(REALACC_PACKET_PERIOD); #endif - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - NRF24L01_SetPower(); + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); if(IS_BIND_IN_PROGRESS) { REALACC_send_bind_packet(); diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index 322aa80..6813dfd 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -139,11 +139,15 @@ static void multi_send_status() if(protocol!=PROTO_SCANNER) flags &= ~0x04; //Invalid protocol } + else if(IS_SUB_PROTO_INVALID) + { + flags &= ~0x04; //Invalid sub protocol + } else if(sub_protocol&0x07) { uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto; //if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol - if((sub_protocol&0x07)>=nbr) + if((sub_protocol&0x07)>=nbr ) flags &= ~0x04; //Invalid sub protocol } if (IS_WAIT_BIND_on) @@ -174,12 +178,12 @@ static void multi_send_status() // Channel order Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON); - if(multi_protocols_index == 0xFF) // selection out of list... send first available protocol + if(multi_protocols_index == 0xFF) // selection out of list... send first available protocol { - Serial_write(multi_protocols[0].protocol); // begining of list - Serial_write(multi_protocols[0].protocol); // begining of list + Serial_write(multi_protocols[0].protocol); // begining of list + Serial_write(multi_protocols[0].protocol); // begining of list for(uint8_t i=0;i<16;i++) - Serial_write(0x00); // everything else is invalid + Serial_write(0x00); // everything else is invalid } else { @@ -191,13 +195,13 @@ static void multi_send_status() if(multi_protocols[multi_protocols_index+2].protocol != 0) Serial_write(multi_protocols[multi_protocols_index+2].protocol); // skip to next protocol number else - Serial_write(multi_protocols[multi_protocols_index].protocol); // or end of list + Serial_write(multi_protocols[multi_protocols_index].protocol); // or end of list } else - Serial_write(multi_protocols[multi_protocols_index+1].protocol); // next protocol number + Serial_write(multi_protocols[multi_protocols_index+1].protocol); // next protocol number } else - Serial_write(multi_protocols[multi_protocols_index].protocol); // end of list + Serial_write(multi_protocols[multi_protocols_index].protocol); // end of list if(multi_protocols_index>0) { if(multi_protocols[multi_protocols_index-1].protocol==PROTO_SCANNER) @@ -205,19 +209,22 @@ static void multi_send_status() if(multi_protocols_index > 1) Serial_write(multi_protocols[multi_protocols_index-2].protocol); // skip to prev protocol number else - Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list + Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list } else - Serial_write(multi_protocols[multi_protocols_index-1].protocol); // prev protocol number + Serial_write(multi_protocols[multi_protocols_index-1].protocol); // prev protocol number } else - Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list + Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list // Protocol for(uint8_t i=0;i<7;i++) - Serial_write(multi_protocols[multi_protocols_index].ProtoString[i]); // protocol name + Serial_write(multi_protocols[multi_protocols_index].ProtoString[i]); // protocol name // Sub-protocol uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto; - Serial_write(nbr | (multi_protocols[multi_protocols_index].optionType<<4)); // number of sub protocols && option type + if(option_override>0x0F) + Serial_write(nbr | (multi_protocols[multi_protocols_index].optionType<<4)); // number of sub protocols && option type + else + Serial_write(nbr | (option_override<<4)); // number of sub protocols && option_override type uint8_t j=0; if(nbr && (sub_protocol&0x07)>1]); + XN297_Hopping(hopping_frequency_no>>1); hopping_frequency_no++; if(IS_BIND_IN_PROGRESS) { @@ -79,22 +79,16 @@ static void __attribute__((unused)) TIGER_send_packet() hopping_frequency_no=2*TIGER_BIND_RF_NUM_CHANNELS; } - //Clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - //Send packet + //Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE); - //Set tx_power - NRF24L01_SetPower(); } static void __attribute__((unused)) TIGER_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t *)"\x68\x94\xA6\xD5\xC3", 5); - // Power on, TX mode, 2byte CRC - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); } static void __attribute__((unused)) TIGER_initialize_txid() diff --git a/Multiprotocol/V761_nrf24l01.ino b/Multiprotocol/V761_nrf24l01.ino index 30007c9..8bd17fe 100644 --- a/Multiprotocol/V761_nrf24l01.ino +++ b/Multiprotocol/V761_nrf24l01.ino @@ -115,18 +115,16 @@ static void __attribute__((unused)) V761_send_packet() hopping_frequency_no = 0; } V761_set_checksum(); - // Power on, TX mode, 2byte CRC - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, V761_PACKET_SIZE); - NRF24L01_SetPower(); } static void __attribute__((unused)) V761_RF_init() { - NRF24L01_Initialize(); - NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // set address length (4 bytes) + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); } static void __attribute__((unused)) V761_initialize_txid() @@ -175,7 +173,7 @@ uint16_t V761_callback() if(bind_counter) bind_counter--; packet_count ++; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, V761_BIND_FREQ); + XN297_RFChannel(V761_BIND_FREQ); XN297_SetTXAddr((uint8_t*)"\x34\x43\x10\x10", 4); V761_send_packet(); if(packet_count >= 20) @@ -188,7 +186,7 @@ uint16_t V761_callback() if(bind_counter) bind_counter--; packet_count ++; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[0]); + XN297_Hopping(0); XN297_SetTXAddr(rx_tx_addr, 4); V761_send_packet(); if(bind_counter == 0) diff --git a/Multiprotocol/V911S_ccnrf.ino b/Multiprotocol/V911S_ccnrf.ino index 8461cda..7eef1d9 100644 --- a/Multiprotocol/V911S_ccnrf.ino +++ b/Multiprotocol/V911S_ccnrf.ino @@ -58,7 +58,7 @@ static void __attribute__((unused)) V911S_send_packet() } if(rf_ch_num&2) channel=7-channel; - XN297L_Hopping(channel); + XN297_Hopping(channel); hopping_frequency_no++; hopping_frequency_no&=7; // 8 RF channels @@ -102,23 +102,23 @@ static void __attribute__((unused)) V911S_send_packet() } if(sub_protocol==V911S_STD) - XN297L_WritePayload(packet, V911S_PACKET_SIZE); + XN297_WritePayload(packet, V911S_PACKET_SIZE); else - XN297L_WriteEnhancedPayload(packet, V911S_PACKET_SIZE, IS_BIND_IN_PROGRESS?0:1); + XN297_WriteEnhancedPayload(packet, V911S_PACKET_SIZE, IS_BIND_IN_PROGRESS?0:1); - XN297L_SetPower(); // Set tx_power - XN297L_SetFreqOffset(); // Set frequency offset + XN297_SetPower(); // Set tx_power + XN297_SetFreqOffset(); // Set frequency offset } static void __attribute__((unused)) V911S_RF_init() { - XN297L_Init(); + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); if(sub_protocol==V911S_STD) - XN297L_SetTXAddr((uint8_t *)"KNBND",5); // V911S Bind address + XN297_SetTXAddr((uint8_t *)"KNBND",5); // V911S Bind address else - XN297L_SetTXAddr((uint8_t *)"XPBND",5); // E119 Bind address - XN297L_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels - XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel + XN297_SetTXAddr((uint8_t *)"XPBND",5); // E119 Bind address + XN297_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels + XN297_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel } static void __attribute__((unused)) V911S_initialize_txid() @@ -144,7 +144,7 @@ uint16_t V911S_callback() if (bind_counter == 0) { BIND_DONE; - XN297L_SetTXAddr(rx_tx_addr, 5); + XN297_SetTXAddr(rx_tx_addr, 5); packet_period=V911S_PACKET_PERIOD; } else if(bind_counter==100) // same as original TX... @@ -193,7 +193,7 @@ void V911S_init(void) } else { - XN297L_SetTXAddr(rx_tx_addr, 5); + XN297_SetTXAddr(rx_tx_addr, 5); packet_period= V911S_PACKET_PERIOD; } hopping_frequency_no=0; diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index dba0e2f..34f13c4 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -276,7 +276,6 @@ #undef FRSKY_RX_CC2500_INO #undef HITEC_CC2500_INO #undef HOTT_CC2500_INO - #undef OMP_CC2500_INO //CC2500 for control and NRF for telemetry #undef REDPINE_CC2500_INO #undef RLINK_CC2500_INO #undef SCANNER_CC2500_INO @@ -293,6 +292,7 @@ #undef CG023_NRF24L01_INO #undef CX10_NRF24L01_INO #undef DM002_NRF24L01_INO + #undef E016H_NRF24L01_INO #undef E01X_NRF24L01_INO #undef ESKY_NRF24L01_INO #undef ESKY150_NRF24L01_INO @@ -306,28 +306,29 @@ #undef JJRC345_NRF24L01_INO #undef KN_NRF24L01_INO #undef LOLI_NRF24L01_INO - #undef MJXQ_NRF24L01_INO - #undef MT99XX_NRF24L01_INO #undef NCC1701_NRF24L01_INO #undef POTENSIC_NRF24L01_INO #undef PROPEL_NRF24L01_INO - #undef Q303_NRF24L01_INO #undef REALACC_NRF24L01_INO #undef SHENQI_NRF24L01_INO #undef SYMAX_NRF24L01_INO #undef TIGER_NRF24L01_INO #undef V2X2_NRF24L01_INO #undef V761_NRF24L01_INO - #undef XK_NRF24L01_INO #undef YD717_NRF24L01_INO #undef ZSX_NRF24L01_INO #endif #if not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED) #undef GD00X_CCNRF_INO #undef KF606_CCNRF_INO + #undef MJXQ_CCNRF_INO + #undef MT99XX_CCNRF_INO + #undef OMP_CCNRF_INO + #undef Q303_CCNRF_INO #undef Q90C_CCNRF_INO #undef SLT_CCNRF_INO #undef V911S_CCNRF_INO + #undef XK_CCNRF_INO #endif #if not defined(STM32_BOARD) #undef SX1276_INSTALLED @@ -401,7 +402,7 @@ #if not defined(DEVO_CYRF6936_INO) #undef DEVO_HUB_TELEMETRY #endif - #if not defined(OMP_CC2500_INO) + #if not defined(OMP_CCNRF_INO) #undef OMP_HUB_TELEMETRY #endif #if not defined(PROPEL_NRF24L01_INO) diff --git a/Multiprotocol/XK_nrf24l01.ino b/Multiprotocol/XK_ccnrf.ino similarity index 83% rename from Multiprotocol/XK_nrf24l01.ino rename to Multiprotocol/XK_ccnrf.ino index fd4a8e8..0f44035 100644 --- a/Multiprotocol/XK_nrf24l01.ino +++ b/Multiprotocol/XK_ccnrf.ino @@ -14,7 +14,7 @@ Multiprotocol is distributed in the hope that it will be useful, */ // Compatible with X450 and X420/X520 plane. -#if defined(XK_NRF24L01_INO) +#if defined(XK_CCNRF_INO) #include "iface_nrf250k.h" @@ -56,6 +56,13 @@ static uint16_t __attribute__((unused)) XK_convert_channel(uint8_t num) static void __attribute__((unused)) XK_send_packet() { + // RF channel + XN297_Hopping((IS_BIND_IN_PROGRESS?0:XK_RF_BIND_NUM_CHANNELS)+(hopping_frequency_no>>1)); + hopping_frequency_no++; + if(hopping_frequency_no >= (IS_BIND_IN_PROGRESS?XK_RF_BIND_NUM_CHANNELS*2:XK_RF_NUM_CHANNELS*2)) + hopping_frequency_no=0; + + // Build packet memset(packet,0x00,7); memset(&packet[10],0x00,5); @@ -101,32 +108,16 @@ static void __attribute__((unused)) XK_send_packet() crc+=packet[i]; packet[15]=crc; - rf_ch_num = (IS_BIND_IN_PROGRESS?0:XK_RF_BIND_NUM_CHANNELS)+(hopping_frequency_no>>1); - hopping_frequency_no++; - if(hopping_frequency_no >= (IS_BIND_IN_PROGRESS?XK_RF_BIND_NUM_CHANNELS*2:XK_RF_NUM_CHANNELS*2)) - hopping_frequency_no=0; - // debug("C: %02X, P:",hopping_frequency[rf_ch_num]); // for(uint8_t i=0; iSR & TIMER_SR_UIF) {//timer just rolled over... @@ -412,29 +411,20 @@ static uint16_t XN297Dump_callback() timeL=0; } time=(timeH<<16)+timeL; - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC - | (1 << NRF24L01_00_CRCO) - | (1 << NRF24L01_00_PWR_UP) - | (1 << NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); XN297Dump_overflow(); break; } debug(",%d",hopping_frequency_no); - NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); + XN297_RFChannel(hopping_frequency_no); // switch to RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( XN297_IsRX() ) { // RX fifo data ready - if(NRF24L01_ReadReg(NRF24L01_09_CD)) + // if(NRF24L01_ReadReg(NRF24L01_09_CD)) { boolean res; if(enhanced) @@ -471,11 +461,8 @@ static uint16_t XN297Dump_callback() } } // restart RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } XN297Dump_overflow(); break; @@ -518,7 +505,7 @@ static uint16_t XN297Dump_callback() } debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]); time_rf[hopping_frequency_no]=-1; - NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); + XN297_RFChannel(hopping_frequency[0]); uint16_t timeL=TCNT1; if(TIMER2_BASE->SR & TIMER_SR_UIF) {//timer just rolled over... @@ -527,15 +514,12 @@ static uint16_t XN297Dump_callback() } time=(timeH<<16)+timeL; // switch to RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( XN297_IsRX() ) { // RX fifo data ready - if(NRF24L01_ReadReg(NRF24L01_09_CD)) + //if(NRF24L01_ReadReg(NRF24L01_09_CD)) { boolean res; if(enhanced) @@ -557,12 +541,12 @@ static uint16_t XN297Dump_callback() if(time_rf[hopping_frequency_no] > (time>>1)) time_rf[hopping_frequency_no]=time>>1; debugln("Time: %5luus", time>>1); - NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); + XN297_RFChannel(hopping_frequency[0]); } else { time=(timeH<<16)+timeL; - NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[hopping_frequency_no]); + XN297_RFChannel(hopping_frequency[hopping_frequency_no]); } packet_count++; if(packet_count>24) @@ -573,18 +557,15 @@ static uint16_t XN297Dump_callback() } } // restart RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } XN297Dump_overflow(); break; case 4: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + if( XN297_IsRX() ) { // RX fifo data ready - if(NRF24L01_ReadReg(NRF24L01_09_CD)) + //if(NRF24L01_ReadReg(NRF24L01_09_CD)) { boolean res; if(enhanced) @@ -604,11 +585,8 @@ static uint16_t XN297Dump_callback() } } // restart RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); } break; } @@ -618,10 +596,10 @@ static uint16_t XN297Dump_callback() if(phase==0) { address_length=4; - memcpy(rx_tx_addr, (uint8_t *)"\x5A\x20\x12\xAC", address_length); //"\xA3\x05\x22\xC1" - bitrate=XN297DUMP_1M; + memcpy(rx_tx_addr, (uint8_t *)"\x5A\xF6\xC1\x71", address_length); //"\xA3\x05\x22\xC1""\x5A\x20\x12\xAC" + bitrate=XN297DUMP_250K; packet_length=32; - hopping_frequency_no=60; //bind ?, normal 60 + hopping_frequency_no=58; //bind ?, normal 60 NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TXRX_OFF); @@ -658,12 +636,18 @@ static uint16_t XN297Dump_callback() if(NRF24L01_ReadReg(NRF24L01_09_CD)) { NRF24L01_ReadPayload(packet, packet_length); - bool ok=true; + //bool ok=true; uint8_t buffer[40]; memcpy(buffer,packet,packet_length); if(memcmp(&packet_in[0],&packet[0],packet_length)) { - //realign bits + debug("P:"); + for(uint8_t i=0;i 5) len = 5; - if (len < 3) len = 3; - uint8_t buf[] = { 0x55, 0x0F, 0x71, 0x0C, 0x00 }; // bytes for XN297 preamble 0xC710F55 (28 bit) - xn297_addr_len = len; - if (xn297_addr_len < 4) - for (uint8_t i = 0; i < 4; ++i) - buf[i] = buf[i+1]; - NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, buf, 5); - // Receive address is complicated. We need to use scrambled actual address as a receive address - // but the TX code now assumes fixed 4-byte transmit address for preamble. We need to adjust it - // first. Also, if the scrambled address begins with 1 nRF24 will look for preamble byte 0xAA - // instead of 0x55 to ensure enough 0-1 transitions to tune the receiver. Still need to experiment - // with receiving signals. - memcpy(xn297_tx_addr, addr, len); + xn297_crc = crc_en; + xn297_scramble_enabled = scramble_en; + xn297_bitrate = bitrate; + xn297_rf = XN297_NRF; + + #if defined(NRF24L01_INSTALLED) and defined(CC2500_INSTALLED) + if(bitrate == XN297_1M) + xn297_rf = XN297_NRF; // Use NRF24L01 + else + xn297_rf = XN297_CC2500; // Use CC2500 + #elif defined(NRF24L01_INSTALLED) and not defined(CC2500_INSTALLED) + xn297_rf = XN297_NRF; // Use NRF24L01 + #else //CC2500 only + xn297_rf = XN297_CC2500; // Use CC2500 + if(bitrate == XN297_1M) + { + xn297_rf = XN297_NRF; // Use NRF24L01 which does not exist, nothing will happen... + SUB_PROTO_INVALID; + return false; // Can't do... + } + #endif + + #if defined(NRF24L01_INSTALLED) + if(xn297_rf == XN297_NRF) + { + debugln("Using NRF"); + rf_switch(SW_NRF); + NRF24L01_Initialize(); + if(bitrate == XN297_250K) + NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps + } + #endif + #if defined(CC2500_INSTALLED) + if(xn297_rf == XN297_CC2500) + { + debugln("Using CC2500"); + rf_switch(SW_CC2500); + CC2500_250K_Init(); + option_override = 2; // OPTION_RFTUNE + } + #endif + return true; } -void XN297_SetRXAddr(const uint8_t* addr, uint8_t len) +static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t* addr, uint8_t len) { if (len > 5) len = 5; if (len < 3) len = 3; - uint8_t buf[] = { 0, 0, 0, 0, 0 }; - memcpy(buf, addr, len); - memcpy(xn297_rx_addr, addr, len); + xn297_addr_len = len; + memcpy(xn297_tx_addr, addr, len); + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + { + uint8_t buf[] = { 0x55, 0x0F, 0x71, 0x0C, 0x00 }; // bytes for XN297 preamble 0xC710F55 (28 bit) + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, xn297_addr_len == 3 ? buf+1 : buf, 5); + } + #endif +}; + +static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t* addr, uint8_t rx_packet_len) +{ + //Scramble address for (uint8_t i = 0; i < xn297_addr_len; ++i) { - buf[i] = xn297_rx_addr[i]; + xn297_rx_addr[i] = addr[i]; if(xn297_scramble_enabled) - buf[i] ^= xn297_scramble[xn297_addr_len-i-1]; + xn297_rx_addr[i] ^= xn297_scramble[xn297_addr_len-i-1]; } - NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5); + + if(xn297_crc) + rx_packet_len += 2; // Include CRC + rx_packet_len += 2; // Include pcf, will this be a problem timing wise even if not enhanced? + + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + { + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, xn297_rx_addr, xn297_addr_len); + if(rx_packet_len >= 32) + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 32); + else + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, rx_packet_len); + } + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + {// TX: Sync1, Sync0, Address + CC2500_WriteReg(CC2500_04_SYNC1, xn297_rx_addr[xn297_addr_len-1]); // Sync word, high byte + CC2500_WriteReg(CC2500_05_SYNC0, xn297_rx_addr[xn297_addr_len-2]); // Sync word, low byte + CC2500_WriteReg(CC2500_09_ADDR, xn297_rx_addr[xn297_addr_len-3]); // Address + rx_packet_len += 1 + xn297_addr_len - 3; // The Address field above will be in the payload then the end of the XN297 address + } + #endif + xn297_rx_packet_len = rx_packet_len; } -void XN297_Configure(uint8_t flags) +static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State mode) { - xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC)); - flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF); + static enum TXRX_State cur_mode=TXRX_OFF; + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + { + + NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) + | (1 << NRF24L01_07_TX_DS) + | (1 << NRF24L01_07_MAX_RT)); + if(mode==TXRX_OFF) + { + NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0); //PowerDown + NRF_CE_off; + return; + } + NRF_CE_off; + if(mode == TX_EN) + { + NRF24L01_FlushTx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, 1 << NRF24L01_00_PWR_UP); + } + else + { + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); // RX + } + if(mode != cur_mode) + { + //delayMicroseconds(130); + cur_mode=mode; + } + NRF_CE_on; + } + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + { + if(mode != cur_mode) + { + CC2500_SetTxRxMode(mode); + if(mode == RX_EN) + { + CC2500_WriteReg(CC2500_12_MDMCFG2, 0x12); // Modem Configuration, GFSK, 16/16 Sync Word TX&RX + CC2500_WriteReg(CC2500_06_PKTLEN, xn297_rx_packet_len); // Packet len + CC2500_Strobe(CC2500_SFRX); + CC2500_Strobe(CC2500_SRX); + } + else + CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration, GFSK, no preambule and no sync word + cur_mode=mode; + } + } + #endif } -void XN297_SetScrambledMode(const uint8_t mode) +static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len) { - xn297_scramble_enabled = mode; + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + { + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + NRF24L01_WritePayload(msg, len); + } + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + { + // stop TX/RX + CC2500_Strobe(CC2500_SIDLE); + // flush tx FIFO + CC2500_Strobe(CC2500_SFTX); + // packet length + CC2500_WriteReg(CC2500_06_PKTLEN, len + 4); // Packet len, fix packet len + // xn297L preamble + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4); + // xn297 packet + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, msg, len); + // transmit + CC2500_Strobe(CC2500_STX); + } + #endif } -void XN297_WritePayload(uint8_t* msg, uint8_t len) +static void __attribute__((unused)) XN297_WritePayload(uint8_t* msg, uint8_t len) { uint8_t buf[32]; uint8_t last = 0; - if (xn297_addr_len < 4) - { - // If address length (which is defined by receive address length) - // is less than 4 the TX address can't fit the preamble, so the last - // byte goes here + if (xn297_rf == XN297_NRF && xn297_addr_len < 4) + { // If address length (which is defined by receiver address length) is less than 4 the TX address can't fit the preamble, so the last byte goes here buf[last++] = 0x55; } + + // address for (uint8_t i = 0; i < xn297_addr_len; ++i) { buf[last] = xn297_tx_addr[xn297_addr_len-i-1]; @@ -72,6 +255,8 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len) buf[last] ^= xn297_scramble[i]; last++; } + + // payload for (uint8_t i = 0; i < len; ++i) { // bit-reverse bytes in packet @@ -80,6 +265,8 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len) buf[last] ^= xn297_scramble[xn297_addr_len+i]; last++; } + + // crc if (xn297_crc) { uint8_t offset = xn297_addr_len < 4 ? 1 : 0; @@ -93,56 +280,56 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len) buf[last++] = crc >> 8; buf[last++] = crc & 0xff; } - NRF24L01_WritePayload(buf, last); + + // send packet + XN297_SendPayload(buf, last); } -void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack) +static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack) { - uint8_t packet[32]; + uint8_t buf[32]; uint8_t scramble_index=0; uint8_t last = 0; static uint8_t pid=0; - // address - if (xn297_addr_len < 4) - { - // If address length (which is defined by receive address length) - // is less than 4 the TX address can't fit the preamble, so the last - // byte goes here - packet[last++] = 0x55; + if (xn297_rf == XN297_NRF && xn297_addr_len < 4) + { // If address length (which is defined by receiver address length) is less than 4 the TX address can't fit the preamble, so the last byte goes here + buf[last++] = 0x55; } + + // address for (uint8_t i = 0; i < xn297_addr_len; ++i) { - packet[last] = xn297_tx_addr[xn297_addr_len-i-1]; + buf[last] = xn297_tx_addr[xn297_addr_len-i-1]; if(xn297_scramble_enabled) - packet[last] ^= xn297_scramble[scramble_index++]; + buf[last] ^= xn297_scramble[scramble_index++]; last++; } // pcf - packet[last] = (len << 1) | (pid>>1); + buf[last] = (len << 1) | (pid>>1); if(xn297_scramble_enabled) - packet[last] ^= xn297_scramble[scramble_index++]; + buf[last] ^= xn297_scramble[scramble_index++]; last++; - packet[last] = (pid << 7) | (noack << 6); + buf[last] = (pid << 7) | (noack << 6); // payload - packet[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload + buf[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload if(xn297_scramble_enabled) - packet[last] ^= xn297_scramble[scramble_index++]; + buf[last] ^= xn297_scramble[scramble_index++]; for (uint8_t i = 0; i < len-1; ++i) { last++; - packet[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2); + buf[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2); if(xn297_scramble_enabled) - packet[last] ^= xn297_scramble[scramble_index++]; + buf[last] ^= xn297_scramble[scramble_index++]; } last++; - packet[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload + buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload if(xn297_scramble_enabled) - packet[last] ^= xn297_scramble[scramble_index++] & 0xc0; + buf[last] ^= xn297_scramble[scramble_index++] & 0xc0; // crc if (xn297_crc) @@ -150,31 +337,69 @@ void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack) uint8_t offset = xn297_addr_len < 4 ? 1 : 0; crc = 0xb5d2; for (uint8_t i = offset; i < last; ++i) - crc16_update( packet[i], 8); - crc16_update( packet[last] & 0xc0, 2); + crc16_update( buf[i], 8); + crc16_update( buf[last] & 0xc0, 2); if (xn297_scramble_enabled) crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]); //else // crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]); - packet[last++] |= (crc >> 8) >> 2; - packet[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2); - packet[last++] = (crc & 0xff) << 6; + buf[last++] |= (crc >> 8) >> 2; + buf[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2); + buf[last++] = (crc & 0xff) << 6; } - NRF24L01_WritePayload(packet, last); - pid++; if(pid>3) pid=0; + + // send packet + XN297_SendPayload(buf, last); } -boolean XN297_ReadPayload(uint8_t* msg, uint8_t len) -{ //!!! Don't forget if using CRC to do a +2 on any of the used NRF24L01_11_RX_PW_Px !!! - uint8_t buf[32]; +static bool __attribute__((unused)) XN297_IsRX() +{ + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + return (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)); + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + { + if((CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F) != xn297_rx_packet_len + 2) // 2 = RSSI + LQI + return false; // Buffer does not contain the expected number of bytes + // Check the address + uint8_t buf[3]; + CC2500_ReadData(buf, xn297_addr_len-3 + 1); + for(uint8_t i=0; i < xn297_addr_len-3 + 1; i++) + if(buf[i] != xn297_rx_addr[xn297_addr_len-3 - i]) + return false; // Bad address + return true; // Address is correct + } + #endif + return false; +} + +static void __attribute__((unused)) XN297_ReceivePayload(uint8_t* msg, uint8_t len) +{ if (xn297_crc) - NRF24L01_ReadPayload(buf, len+2); // Read payload + CRC - else - NRF24L01_ReadPayload(buf, len); + len += 2; // Include CRC + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + NRF24L01_ReadPayload(msg, len); // Read payload and CRC + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_ReadData(msg, len); + #endif +} + +static bool __attribute__((unused)) XN297_ReadPayload(uint8_t* msg, uint8_t len) +{ //!!! Don't forget if using CRC to do a +2 on the received packet length (NRF24L01_11_RX_PW_Px !!! or CC2500_06_PKTLEN) + uint8_t buf[32]; + + // Read payload + XN297_ReceivePayload(buf, len); + // Decode payload for(uint8_t i=0; i>6) ; if( crc == crcxored) - return pcf_size; // CRC OK - return 0; // CRC NOK + return pcf_size; // CRC OK + return 0; // CRC NOK } +static bool __attribute__((unused)) XN297_IsPacketSent() +{ + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + return (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)); + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + return (CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13); + #endif + return true; // packet sent to not block +} + +static void __attribute__((unused)) XN297_HoppingCalib(uint8_t num_freq) +{ //calibrate hopping frequencies + #ifdef NRF24L01_INSTALLED + (void)num_freq; + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_250K_HoppingCalib(num_freq); + #endif +} + +static void __attribute__((unused)) XN297_Hopping(uint8_t index) +{ + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]); + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_250K_Hopping(index); + #endif +} + +static void __attribute__((unused)) XN297_RFChannel(uint8_t number) +{ //change channel + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + NRF24L01_WriteReg(NRF24L01_05_RF_CH, number); + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_250K_RFChannel(number); + #endif +} + +static void __attribute__((unused)) XN297_SetPower() +{ + #ifdef NRF24L01_INSTALLED + if(xn297_rf == XN297_NRF) + NRF24L01_SetPower(); + #endif + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_SetPower(); + #endif +} + +static void __attribute__((unused)) XN297_SetFreqOffset() +{ // Frequency offset + #ifdef CC2500_INSTALLED + if(xn297_rf == XN297_CC2500) + CC2500_SetFreqOffset(); + #endif +} + // End of XN297 emulation #endif diff --git a/Multiprotocol/ZSX_nrf24l01.ino b/Multiprotocol/ZSX_nrf24l01.ino index f36a225..2e7fcd8 100644 --- a/Multiprotocol/ZSX_nrf24l01.ino +++ b/Multiprotocol/ZSX_nrf24l01.ino @@ -44,12 +44,10 @@ static void __attribute__((unused)) ZSX_send_packet() | GET_FLAG(CH5_SW, 0x80); // Light } - XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); XN297_WritePayload(packet, ZSX_PAYLOAD_SIZE); - - NRF24L01_SetPower(); // Set tx_power } static void __attribute__((unused)) ZSX_initialize_txid() @@ -65,10 +63,9 @@ static void __attribute__((unused)) ZSX_initialize_txid() static void __attribute__((unused)) ZSX_RF_init() { - NRF24L01_Initialize(); - + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_SetTXAddr((uint8_t*)"\xc1\xc2\xc3", 3); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, ZSX_RF_BIND_CHANNEL); // Set bind channel + XN297_RFChannel(ZSX_RF_BIND_CHANNEL); // Set bind channel } uint16_t ZSX_callback() @@ -81,7 +78,7 @@ uint16_t ZSX_callback() { BIND_DONE; XN297_SetTXAddr(rx_tx_addr, 3); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x00); + XN297_RFChannel(0x00); } ZSX_send_packet(); return ZSX_PACKET_PERIOD; diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 3d9245b..49a5b13 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -203,7 +203,6 @@ #define FRSKY_RX_CC2500_INO #define HITEC_CC2500_INO #define HOTT_CC2500_INO -#define OMP_CC2500_INO //CC2500 for control and NRF for telemetry #define SCANNER_CC2500_INO #define FUTABA_CC2500_INO #define SKYARTEC_CC2500_INO @@ -220,6 +219,7 @@ #define CG023_NRF24L01_INO #define CX10_NRF24L01_INO //Include Q2X2 protocol #define DM002_NRF24L01_INO +#define E016H_NRF24L01_INO #define E01X_NRF24L01_INO #define ESKY_NRF24L01_INO #define ESKY150_NRF24L01_INO @@ -233,28 +233,29 @@ #define JJRC345_NRF24L01_INO #define KN_NRF24L01_INO #define LOLI_NRF24L01_INO -#define MJXQ_NRF24L01_INO -#define MT99XX_NRF24L01_INO #define NCC1701_NRF24L01_INO #define POTENSIC_NRF24L01_INO #define PROPEL_NRF24L01_INO -#define Q303_NRF24L01_INO #define REALACC_NRF24L01_INO #define SHENQI_NRF24L01_INO #define SYMAX_NRF24L01_INO #define TIGER_NRF24L01_INO #define V2X2_NRF24L01_INO #define V761_NRF24L01_INO -#define XK_NRF24L01_INO #define YD717_NRF24L01_INO #define ZSX_NRF24L01_INO //The protocols below need either a CC2500 or NRF24L01 to be installed #define GD00X_CCNRF_INO #define KF606_CCNRF_INO +#define MJXQ_CCNRF_INO +#define MT99XX_CCNRF_INO +#define OMP_CCNRF_INO +#define Q303_CCNRF_INO #define Q90C_CCNRF_INO #define SLT_CCNRF_INO #define V911S_CCNRF_INO +#define XK_CCNRF_INO //The protocols below need a SX1276 to be installed #define FRSKYR9_SX1276_INO @@ -592,12 +593,13 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { NONE PROTO_E010R5 NONE + PROTO_E016H + NONE PROTO_E016HV2 NONE PROTO_E01X E012 E015 - E016H PROTO_E129 NONE PROTO_ESKY diff --git a/Multiprotocol/_MyConfig.h.example b/Multiprotocol/_MyConfig.h.example index 105f35c..bc0b07a 100644 --- a/Multiprotocol/_MyConfig.h.example +++ b/Multiprotocol/_MyConfig.h.example @@ -35,7 +35,7 @@ #undef FQ777_NRF24L01_INO #undef ASSAN_NRF24L01_INO #undef HONTAI_NRF24L01_INO - #undef Q303_NRF24L01_INO + #undef Q303_CCNRF_INO #undef GW008_NRF24L01_INO #undef DM002_NRF24L01_INO #undef CABELL_NRF24L01_INO diff --git a/Multiprotocol/iface_nrf250k.h b/Multiprotocol/iface_nrf250k.h index 854e167..15d0f8b 100644 --- a/Multiprotocol/iface_nrf250k.h +++ b/Multiprotocol/iface_nrf250k.h @@ -1,34 +1,28 @@ #ifndef _IFACE_NRF250K_H_ - #define _IFACE_NRF250K_H_ -#if defined (CC2500_INSTALLED) +#ifdef CC2500_INSTALLED #include "iface_cc2500.h" -#elif defined (NRF24L01_INSTALLED) +#endif +#ifdef NRF24L01_INSTALLED #include "iface_nrf24l01.h" #endif #include "iface_xn297.h" -//XN297L -static void __attribute__((unused)) XN297L_Init(); -static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t*, uint8_t); -static void __attribute__((unused)) XN297L_WritePayload(uint8_t*, uint8_t); -static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t); -static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t); -static void __attribute__((unused)) XN297L_Hopping(uint8_t); -static void __attribute__((unused)) XN297L_RFChannel(uint8_t); -static void __attribute__((unused)) XN297L_SetPower(); -static void __attribute__((unused)) XN297L_SetFreqOffset(); +#if defined (CC2500_INSTALLED) || defined (NRF24L01_INSTALLED) -//NRF250K -#define NRF250K_Init() XN297L_Init() -#define NRF250K_HoppingCalib(X) XN297L_HoppingCalib(X) -#define NRF250K_Hopping(X) XN297L_Hopping(X) -#define NRF250K_RFChannel(X) XN297L_RFChannel(X) -#define NRF250K_SetPower() XN297L_SetPower() -#define NRF250K_SetFreqOffset() XN297L_SetFreqOffset() +////////////// +// Functions +#define NRF250K_Init() XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K) +#define NRF250K_HoppingCalib(X) XN297_HoppingCalib(X) +#define NRF250K_Hopping(X) XN297_Hopping(X) +#define NRF250K_RFChannel(X) XN297_RFChannel(X) +#define NRF250K_SetPower() XN297_SetPower() +#define NRF250K_SetFreqOffset() XN297_SetFreqOffset() +#define NRF250K_IsPacketSent() XN297_IsPacketSent() static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t*, uint8_t); static void __attribute__((unused)) NRF250K_WritePayload(uint8_t*, uint8_t); -static boolean __attribute__((unused)) NRF250K_IsPacketSent(); -#endif \ No newline at end of file +#endif + +#endif diff --git a/Multiprotocol/iface_xn297.h b/Multiprotocol/iface_xn297.h index 9cd24ae..bd50122 100644 --- a/Multiprotocol/iface_xn297.h +++ b/Multiprotocol/iface_xn297.h @@ -8,76 +8,39 @@ #include "iface_nrf24l01.h" #endif -/////////////// -// XN297 emulation layer -// XN297 emulation layer -enum { - XN297_UNSCRAMBLED = 0, - XN297_SCRAMBLED -}; +#if defined (CC2500_INSTALLED) || defined (NRF24L01_INSTALLED) -uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default -uint8_t xn297_addr_len; -uint8_t xn297_tx_addr[5]; -uint8_t xn297_rx_addr[5]; -uint8_t xn297_crc = 0; +////////////////// +// Configuration +#define XN297_UNSCRAMBLED false +#define XN297_SCRAMBLED true +#define XN297_CRCDIS false +#define XN297_CRCEN true +#define XN297_1M false +#define XN297_250K true +#define XN297_NRF false +#define XN297_CC2500 true -// xn297 address / pcf / payload scramble table -const uint8_t xn297_scramble[] = { - 0xE3, 0xB1, 0x4B, 0xEA, 0x85, 0xBC, 0xE5, 0x66, - 0x0D, 0xAE, 0x8C, 0x88, 0x12, 0x69, 0xEE, 0x1F, - 0xC7, 0x62, 0x97, 0xD5, 0x0B, 0x79, 0xCA, 0xCC, - 0x1B, 0x5D, 0x19, 0x10, 0x24, 0xD3, 0xDC, 0x3F, - 0x8E, 0xC5, 0x2F, 0xAA, 0x16, 0xF3, 0x95 }; +////////////// +// Functions +static bool __attribute__((unused)) XN297_Configure(bool, bool, bool); +static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t*, uint8_t); +static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t*, uint8_t); +static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State); +static void __attribute__((unused)) XN297_SendPayload(uint8_t*, uint8_t); +static void __attribute__((unused)) XN297_WritePayload(uint8_t*, uint8_t); +static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t); +static bool __attribute__((unused)) XN297_IsRX(); +static void __attribute__((unused)) XN297_ReceivePayload(uint8_t*, uint8_t); +static bool __attribute__((unused)) XN297_ReadPayload(uint8_t*, uint8_t); +static uint8_t __attribute__((unused)) XN297_ReadEnhancedPayload(uint8_t*, uint8_t); +static void __attribute__((unused)) XN297_HoppingCalib(uint8_t); +static void __attribute__((unused)) XN297_Hopping(uint8_t); +static void __attribute__((unused)) XN297_RFChannel(uint8_t); +static void __attribute__((unused)) XN297_SetPower(); +static void __attribute__((unused)) XN297_SetFreqOffset(); +static bool __attribute__((unused)) XN297_IsPacketSent(); -// scrambled, standard mode crc xorout table -const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = { - 0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C, - 0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B, - 0xD461, 0xF494, 0x2503, 0x691D, 0xFE8B, 0x9BA7, - 0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401, - 0x2138, 0x129F, 0xB3A0, 0x2988, 0x23CA, 0xC0CB, - 0x0C6C, 0xB329, 0xA0A1, 0x0A16, 0xA9D0 }; - -// unscrambled, standard mode crc xorout table -const uint16_t PROGMEM xn297_crc_xorout[] = { - 0x0000, 0x3D5F, 0xA6F1, 0x3A23, 0xAA16, 0x1CAF, - 0x62B2, 0xE0EB, 0x0821, 0xBE07, 0x5F1A, 0xAF15, - 0x4F0A, 0xAD24, 0x5E48, 0xED34, 0x068C, 0xF2C9, - 0x1852, 0xDF36, 0x129D, 0xB17C, 0xD5F5, 0x70D7, - 0xB798, 0x5133, 0x67DB, 0xD94E, 0x0A5B, 0xE445, - 0xE6A5, 0x26E7, 0xBDAB, 0xC379, 0x8E20 }; - -// scrambled enhanced mode crc xorout table -const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[] = { - 0x0000, 0x7EBF, 0x3ECE, 0x07A4, 0xCA52, 0x343B, - 0x53F8, 0x8CD0, 0x9EAC, 0xD0C0, 0x150D, 0x5186, - 0xD251, 0xA46F, 0x8435, 0xFA2E, 0x7EBD, 0x3C7D, - 0x94E0, 0x3D5F, 0xA685, 0x4E47, 0xF045, 0xB483, - 0x7A1F, 0xDEA2, 0x9642, 0xBF4B, 0x032F, 0x01D2, - 0xDC86, 0x92A5, 0x183A, 0xB760, 0xA953 }; - -// unscrambled enhanced mode crc xorout table -// unused so far -#ifdef XN297DUMP_NRF24L01_INO -const uint16_t xn297_crc_xorout_enhanced[] = { - 0x0000, 0x8BE6, 0xD8EC, 0xB87A, 0x42DC, 0xAA89, - 0x83AF, 0x10E4, 0xE83E, 0x5C29, 0xAC76, 0x1C69, - 0xA4B2, 0x5961, 0xB4D3, 0x2A50, 0xCB27, 0x5128, - 0x7CDB, 0x7A14, 0xD5D2, 0x57D7, 0xE31D, 0xCE42, - 0x648D, 0xBF2D, 0x653B, 0x190C, 0x9117, 0x9A97, - 0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 }; -#endif - -#ifdef NRF24L01_INSTALLED -void XN297_SetTXAddr(const uint8_t*, uint8_t); -void XN297_SetRXAddr(const uint8_t*, uint8_t); -void XN297_Configure(uint8_t); -void XN297_SetScrambledMode(const uint8_t); -void XN297_WritePayload(uint8_t*, uint8_t); -void XN297_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t); -boolean XN297_ReadPayload(uint8_t*, uint8_t); -uint8_t XN297_ReadEnhancedPayload(uint8_t*, uint8_t); #endif #endif diff --git a/Protocols_Details.md b/Protocols_Details.md index d1d8938..c04535b 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -77,8 +77,9 @@ CFlie|38|CFlie||||||||NRF24L01| [DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO||||CYRF6936| [DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936| [E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936/NRF24L01|RF2500 +[E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297 [E016HV2](Protocols_Details.md#E016HV2---80)|80|||||||||CC2500/NRF24L01|unknown -[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200 +[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|||||||NRF24L01|HS6200 [E129](Protocols_Details.md#E129---83)|83|||||||||CYRF6936/NRF24L01|RF2500 [ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01| [ESky150](Protocols_Details.md#ESKY150---35)|35|||||||||NRF24L01| @@ -884,28 +885,6 @@ Recommended for best telemetry performance. Telemetry compatibility mode when Sync does not work due to an old firmware on the RX. You should definitively upgrade your receivers/sensors to the latest firmware versions: https://www.rcgroups.com/forums/showpost.php?p=44668015&postcount=18022 -## OMP - *77* -Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider - -Telemetry is supported only if a NRF24L01 RF component is installed: -- A1 = battery voltage including "recovered" battery voltage from corrupted telemetry packets -- A2 = battery voltage from only good telemetry packets -- How to calculate accurately the OpenTX Ratio and Offset: -Set the Ratio to 12.7 and Offset to 0, plug 2 batteries with extreme voltage values, write down the values Batt1=12.5V & Telem1=12.2V, Batt2=7V & Telem2=6.6V then calculate/set Ratio=12.7*[(12.5-7)/(12.2-6.6)]=12.47 => 12.5 and Offset=12.5-12.2*[(12.5-7)/(12.2-6.6)]=0.517 => 0.5 -- RX_RSSI = TQly = percentage of received telemetry packets (good and corrupted) from the model which has nothing to do with how well the RX is receiving the TX - -Option for this protocol corresponds to the CC2500 fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable. -Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it. - -CH1|CH2|CH3|CH4|CH5|CH6|CH7 ----|---|---|---|---|---|--- -A|E|T_PITCH|R|T_HOLD|IDLE|MODE - -IDLE= 3 pos switch: -100% Normal, 0% Idle1, +100% Idle2 - -From the TX manual: MODE= 3 pos switch -100% Attitude, 0% Attitude(?), +100% 3D -For M2: MODE= 3 pos switch -100% 6G, 0% 3D, +100% 3D - ## Scanner - *54* 2.4GHz scanner accessible using the OpenTX 2.3 Spectrum Analyser tool. @@ -968,7 +947,7 @@ A|E|T|R|CH5|CH6|CH7 If a CC2500 is installed it will be used for all the below protocols. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). -If only a NRF24L01 is installed then these protocols might be problematic because they are using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. +If only a NRF24L01 is installed then these protocols might be problematic because they are using the XN297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. ## GD00X - *47* Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50 @@ -994,6 +973,176 @@ CH1|CH2|CH3|CH4|CH5 ---|---|---|---|--- A||T||TRIM +## MJXQ - *18* +Autobind protocol + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14 +---|---|---|---|---|---|---|---|---|----|----|----|----|---- +A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT|RATE + +RATE: -100%(default)=>higher rates by enabling dynamic trims (except for Headless), 100%=>disable dynamic trims + +CC2500: only E010 and PHOENIX are supported. + +### Sub_protocol WLH08 - *0* + +### Sub_protocol X600 - *1* +Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them +### Sub_protocol X800 - *2* +Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them +### Sub_protocol H26D - *3* +Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them +### Sub_protocol E010 - *4* +15 TX IDs available, change RX_Num value 0..14 to cycle through them + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +### Sub_protocol H26WH - *5* +CH6| +---| +ARM| + +Only 1 TX ID available + +### Sub_protocol PHOENIX - *6* +CH6| +---| +ARM| + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +## MT99XX - *17* +Autobind protocol + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS + +CC2500: only YZ is supported. + +### Sub_protocol MT99 - *0* +Models: MT99xx +### Sub_protocol H7 - *1* +Models: Eachine H7, Cheerson CX023 +### Sub_protocol YZ - *2* +Model: Yi Zhan i6S + +Only one model can be flown at the same time since the ID is hardcoded. + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +### Sub_protocol LS - *3* +Models: LS114, 124, 215 + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS + +### Sub_protocol FY805 - *4* +Model: FY805 + +**Only 1 ID available** + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP||||HEADLESS + +### Sub_protocol A180 - *5* +Model: XK A180 + +CH1|CH2|CH3|CH4|CH5 +---|---|---|---|--- +A|E|T|R|3D6G + +### Sub_protocol DRAGON - *6* +Model: Eachine Mini Wing Dragon + +CH1|CH2|CH3|CH4|CH5|CH6 +---|---|---|---|---|--- +A|E|T|R|MODE|RTH + +MODE: -100%=Beginner, 0%=Intermediate, +100%=Advanced + +## OMP - *77* +Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +Telemetry is supported: +- A1 = battery voltage including "recovered" battery voltage from corrupted telemetry packets +- A2 = battery voltage from only good telemetry packets +- How to calculate accurately the OpenTX Ratio and Offset: +Set the Ratio to 12.7 and Offset to 0, plug 2 batteries with extreme voltage values, write down the values Batt1=12.5V & Telem1=12.2V, Batt2=7V & Telem2=6.6V then calculate/set Ratio=12.7*[(12.5-7)/(12.2-6.6)]=12.47 => 12.5 and Offset=12.5-12.2*[(12.5-7)/(12.2-6.6)]=0.517 => 0.5 +- RX_RSSI = TQly = percentage of received telemetry packets (good and corrupted) from the model which has nothing to do with how well the RX is receiving the TX + +Option for this protocol corresponds to the CC2500 fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable. +Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it. + +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- +A|E|T_PITCH|R|T_HOLD|IDLE|MODE + +IDLE= 3 pos switch: -100% Normal, 0% Idle1, +100% Idle2 + +From the TX manual: MODE= 3 pos switch -100% Attitude, 0% Attitude(?), +100% 3D +For M2: MODE= 3 pos switch -100% 6G, 0% 3D, +100% 3D + +## Q303 - *31* +Autobind protocol + +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +CC2500: only Q303 is supported. + +### Sub_protocol Q303 - *0* + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|--- +AHOLD|FLIP|PICTURE|VIDEO|HEADLESS|RTH|GIMBAL + +GIMBAL needs 3 position -100%/0%/100% + +### Sub_protocol CX35 - *1* +CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|--- +ARM|VTX|PICTURE|VIDEO||RTH|GIMBAL + +ARM is 2 positions: land / take off + +Each toggle of VTX will increment the channel. + +Gimbal is full range. + +### Sub_protocol CX10D - *2* +Models CX10D and CX33W + +CH5|CH6 +---|--- +ARM|FLIP + +ARM is 3 positions: -100%=land / 0%=manual / +100%=take off + +### Sub_protocol CX10WD - *3* +CH5|CH6 +---|--- +ARM|FLIP + +ARM is 3 positions: -100%=land / 0%=manual / +100%=take off + ## Q90C - *72* CH1|CH2|CH3|CH4|CH5|CH6 @@ -1087,6 +1236,26 @@ Models: WLtoys V911S, XK A110 ### Sub_protocol E119 - *1* Models: Eachine E119 +## XK - *62* + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 +---|---|---|---|---|---|---|---|---|---- +A|E|T|R|Flight_modes|Take_off|Emerg stop|3D/6G|Picture|Video + +Flight_modes: -100%=M-Mode, 0%=6G-Mode, +100%=V-Mode. CH6-CH10 are mementary switches. + +CC2500: only X450 is supported. + +### Sub_protocol X450 - *0* +Models: XK X450 (TX=X8) + +If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). + +If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. + +### Sub_protocol X420 - *1* +Models: XK X420/X520 (TX=X4) + *** # NRF24L01 RF Module @@ -1286,6 +1455,15 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 ---|---|---|---|---|---|---|---|---|----|---- A|E|T|R|FLIP|LED|CAMERA1|CAMERA2|HEADLESS|RTH|RATE_LOW +## E016H - *85* +Autobind protocol + +Model: Eachine E016H + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|STOP|FLIP|-|HEADLESS|RTH + ## E01X - *45* Autobind protocol @@ -1307,13 +1485,6 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ---|---|---|---|---|---|---|---|--- A|E|T|R|ARM|FLIP|LED|HEADLESS|RTH -### Sub_protocol E016H - *2* -Models: Eachine E016H - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ----|---|---|---|---|---|---|---|--- -A|E|T|R|STOP|FLIP|-|HEADLESS|RTH - ## ESKY - *16* CH1|CH2|CH3|CH4|CH5|CH6 @@ -1493,93 +1664,6 @@ CH14| CH6 | -100% | 0% | | - | - CH15| CH7 | -100% | 0% | - | - | +100% CH16| CH8 | -100% | 0% | - | - | - -## MJXQ - *18* -Autobind protocol - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14 ----|---|---|---|---|---|---|---|---|----|----|----|----|---- -A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT|RATE - -RATE: -100%(default)=>higher rates by enabling dynamic trims (except for Headless), 100%=>disable dynamic trims - -### Sub_protocol WLH08 - *0* -### Sub_protocol X600 - *1* -Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them -### Sub_protocol X800 - *2* -Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them -### Sub_protocol H26D - *3* -Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them -### Sub_protocol E010 - *4* -15 TX IDs available, change RX_Num value 0..14 to cycle through them - -If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). - -If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. - -### Sub_protocol H26WH - *5* -CH6| ----| -ARM| - -Only 1 TX ID available - -### Sub_protocol PHOENIX - *6* -CH6| ----| -ARM| - -## MT99XX - *17* -Autobind protocol - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ----|---|---|---|---|---|---|---|--- -A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS - -### Sub_protocol MT99 - *0* -Models: MT99xx -### Sub_protocol H7 - *1* -Models: Eachine H7, Cheerson CX023 -### Sub_protocol YZ - *2* -Model: Yi Zhan i6S - -Only one model can be flown at the same time since the ID is hardcoded. - -If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). - -If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. - -### Sub_protocol LS - *3* -Models: LS114, 124, 215 - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ----|---|---|---|---|---|---|---|--- -A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS - -### Sub_protocol FY805 - *4* -Model: FY805 - -**Only 1 ID available** - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ----|---|---|---|---|---|---|---|--- -A|E|T|R|FLIP||||HEADLESS - -### Sub_protocol A180 - *5* -Model: XK A180 - -CH1|CH2|CH3|CH4|CH5 ----|---|---|---|--- -A|E|T|R|3D6G - -### Sub_protocol DRAGON - *6* -Model: Eachine Mini Wing Dragon - -CH1|CH2|CH3|CH4|CH5|CH6 ----|---|---|---|---|--- -A|E|T|R|MODE|RTH - -MODE: -100%=Beginner, 0%=Intermediate, +100%=Advanced - ## NCC1701 - *44* Model: Air Hogs Star Trek USS Enterprise NCC-1701-A @@ -1635,52 +1719,6 @@ A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL Model: JXD 509 is using Q282 with CH12=Start/Stop motors -## Q303 - *31* -Autobind protocol - -CH1|CH2|CH3|CH4 ----|---|---|--- -A|E|T|R - -### Sub_protocol Q303 - *0* - -If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). - -If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. - -CH5|CH6|CH7|CH8|CH9|CH10|CH11 ----|---|---|---|---|---|--- -AHOLD|FLIP|PICTURE|VIDEO|HEADLESS|RTH|GIMBAL - -GIMBAL needs 3 position -100%/0%/100% - -### Sub_protocol CX35 - *1* -CH5|CH6|CH7|CH8|CH9|CH10|CH11 ----|---|---|---|---|---|--- -ARM|VTX|PICTURE|VIDEO||RTH|GIMBAL - -ARM is 2 positions: land / take off - -Each toggle of VTX will increment the channel. - -Gimbal is full range. - -### Sub_protocol CX10D - *2* -Models CX10D and CX33W - -CH5|CH6 ----|--- -ARM|FLIP - -ARM is 3 positions: -100%=land / 0%=manual / +100%=take off - -### Sub_protocol CX10WD - *3* -CH5|CH6 ----|--- -ARM|FLIP - -ARM is 3 positions: -100%=land / 0%=manual / +100%=take off - ## Realacc - *76* Model: Realacc R11 @@ -1792,25 +1830,6 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ---|---|---|---|---|---|---|---|--- A|E|T|R|GYRO|CALIB|FLIP|RTN_ACT|RTN - -## XK - *62* - -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 ----|---|---|---|---|---|---|---|---|---- -A|E|T|R|Flight_modes|Take_off|Emerg stop|3D/6G|Picture|Video - -Flight_modes: -100%=M-Mode, 0%=6G-Mode, +100%=V-Mode. CH6-CH10 are mementary switches. - -### Sub_protocol X450 - *0* -Models: XK X450 (TX=X8) - -If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). - -If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. - -### Sub_protocol X420 - *1* -Models: XK X420/X520 (TX=X4) - ## YD717 - *8* Autobind protocol