diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino
index a557a96..eb4eda8 100644
--- a/Multiprotocol/Multi_Names.ino
+++ b/Multiprotocol/Multi_Names.ino
@@ -114,6 +114,7 @@ const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410";
const char STR_SUBTYPE_FX816[] = "\x03""P38";
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ";
const char STR_SUBTYPE_ESKY150[] = "\x03""4CH""7CH";
+const char STR_SUBTYPE_V911S[] = "\x04""Std\0""E119";
enum
{
@@ -265,7 +266,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
#endif
#if defined(V911S_NRF24L01_INO)
- {PROTO_V911S, STR_V911S, 0, NO_SUBTYPE, OPTION_NONE },
+ {PROTO_V911S, STR_V911S, 1, STR_SUBTYPE_V911S, OPTION_RFTUNE },
#endif
#if defined(GD00X_NRF24L01_INO)
{PROTO_GD00X, STR_GD00X, 2, STR_SUBTYPE_GD00X, OPTION_RFTUNE },
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index 30afc70..6aed893 100644
--- a/Multiprotocol/Multiprotocol.h
+++ b/Multiprotocol/Multiprotocol.h
@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 0
-#define VERSION_PATCH_LEVEL 52
+#define VERSION_PATCH_LEVEL 53
//******************
// Protocols
@@ -300,6 +300,11 @@ enum ESKY150
ESKY150_4CH = 0,
ESKY150_7CH = 1,
};
+enum V911S
+{
+ V911S_STD = 0,
+ V911S_E119 = 1,
+};
enum XN297DUMP
{
XN297DUMP_250K = 0,
@@ -351,7 +356,7 @@ enum MultiPacketTypes
//*** Tests ***
//***************
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX )
-#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO )
+#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN )
//***************
//*** Flags ***
@@ -842,6 +847,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
sub_protocol==ESKY150
ESKY150_4CH 0
ESKY150_7CH 1
+ sub_protocol==V911S
+ V911S_STD 0
+ V911S_E119 1
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index de9ceb5..1a5b461 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -331,7 +331,7 @@ void setup()
pinMode(S2_pin,INPUT_PULLUP);
pinMode(S3_pin,INPUT_PULLUP);
pinMode(S4_pin,INPUT_PULLUP);
-
+
#if defined ENABLE_DIRECT_INPUTS
#if defined (DI1_PIN)
pinMode(DI1_PIN,INPUT_PULLUP);
@@ -346,6 +346,7 @@ void setup()
pinMode(DI4_PIN,INPUT_PULLUP);
#endif
#endif
+
//Random pins
pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
@@ -724,7 +725,6 @@ bool Update_All()
else
Channel_data[i]=val;
}
-
PPM_FLAG_off; // wait for next frame before update
#ifdef FAILSAFE_ENABLE
PPM_failsafe();
diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h
index 5950cd9..075b5a8 100644
--- a/Multiprotocol/Pins.h
+++ b/Multiprotocol/Pins.h
@@ -312,7 +312,7 @@
#define DEBUG_PIN_off
#define DEBUG_PIN_toggle
#endif
-
+
#define cli() noInterrupts()
#define sei() interrupts()
#define delayMilliseconds(x) delay(x)
diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino
index 165f8d1..361dda6 100644
--- a/Multiprotocol/Telemetry.ino
+++ b/Multiprotocol/Telemetry.ino
@@ -125,11 +125,11 @@ static void multi_send_status()
multi_send_header(MULTI_TELEMETRY_STATUS, 24);
else
#endif
- #ifdef MULTI_TELEMETRY
+ #ifdef MULTI_TELEMETRY
multi_send_header(MULTI_TELEMETRY_STATUS, 6);
- #else
- multi_send_header(MULTI_TELEMETRY_STATUS, 5);
- #endif
+ #else
+ multi_send_header(MULTI_TELEMETRY_STATUS, 6);
+ #endif
// Build flags
uint8_t flags=0;
@@ -170,9 +170,9 @@ static void multi_send_status()
Serial_write(VERSION_REVISION);
Serial_write(VERSION_PATCH_LEVEL);
- // Channel order
#ifdef MULTI_TELEMETRY
- Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
+ // Channel order
+ Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
#endif
#ifdef MULTI_NAMES
diff --git a/Multiprotocol/V911S_nrf24l01.ino b/Multiprotocol/V911S_nrf24l01.ino
deleted file mode 100644
index ead0e2d..0000000
--- a/Multiprotocol/V911S_nrf24l01.ino
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- This project is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Multiprotocol is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Multiprotocol. If not, see .
- */
-// compatible with V911S
-
-#if defined(V911S_NRF24L01_INO)
-
-#include "iface_nrf24l01.h"
-
-//#define V911S_ORIGINAL_ID
-
-#define V911S_PACKET_PERIOD 5000
-#define V911S_BIND_PACKET_PERIOD 3300
-#define V911S_INITIAL_WAIT 500
-#define V911S_PACKET_SIZE 16
-#define V911S_RF_BIND_CHANNEL 35
-#define V911S_NUM_RF_CHANNELS 8
-#define V911S_BIND_COUNT 200
-
-// flags going to packet[1]
-#define V911S_FLAG_EXPERT 0x04
-// flags going to packet[2]
-#define V911S_FLAG_CALIB 0x01
-
-static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
-{
- if(bind)
- {
- packet[0] = 0x42;
- packet[1] = 0x4E;
- packet[2] = 0x44;
- for(uint8_t i=0;i<5;i++)
- packet[i+3] = rx_tx_addr[i];
- for(uint8_t i=0;i<8;i++)
- packet[i+8] = hopping_frequency[i];
- }
- else
- {
- uint8_t channel=hopping_frequency_no;
- if(rf_ch_num&1)
- {
- if((hopping_frequency_no&1)==0)
- channel+=8;
- channel>>=1;
- }
- if(rf_ch_num&2)
- channel=7-channel;
- packet[ 0]=(rf_ch_num<<3)|channel;
- packet[ 1]=V911S_FLAG_EXPERT; // short press on left button
- packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button
- memset(packet+3, 0x00, V911S_PACKET_SIZE - 3);
- //packet[3..6]=trims TAER signed
- uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF);
- packet[ 7] = ch;
- packet[ 8] = ch>>8;
- ch=convert_channel_16b_limit(AILERON ,0x7FF,0);
- packet[ 8]|= ch<<3;
- packet[ 9] = ch>>5;
- ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF);
- packet[10] = ch;
- packet[11] = ch>>8;
- ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
- packet[11]|= ch<<3;
- packet[12] = ch>>5;
- }
-
- // Power on, TX mode, 2byte CRC
- XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
- if (!bind)
- {
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[channel]);
- hopping_frequency_no++;
- hopping_frequency_no&=7; // 8 RF channels
- }
- // clear packet status bits and TX FIFO
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
- NRF24L01_FlushTx();
- XN297_WritePayload(packet, V911S_PACKET_SIZE);
-
- NRF24L01_SetPower(); // Set tx_power
-}
-
-static void __attribute__((unused)) V911S_init()
-{
- NRF24L01_Initialize();
- NRF24L01_SetTxRxMode(TX_EN);
- XN297_SetTXAddr((uint8_t *)"\x4B\x4E\x42\x4E\x44", 5); // Bind address
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, V911S_RF_BIND_CHANNEL); // Bind channel
- NRF24L01_FlushTx();
- NRF24L01_FlushRx();
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
- NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
- NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
- NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
- NRF24L01_SetPower();
-}
-
-static void __attribute__((unused)) V911S_initialize_txid()
-{
- //channels
- uint8_t offset=rx_tx_addr[3]%5; // 0-4
- for(uint8_t i=0;i.
*/
+#ifdef NRF24L01_INSTALLED
#include "iface_xn297l.h"
-#if defined (XN297L_CC2500_EMU)
static void __attribute__((unused)) XN297L_Init()
{
- PE1_off; // antenna RF2
- PE2_on;
- CC2500_Reset();
- CC2500_Strobe(CC2500_SIDLE);
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ debugln("Using NRF");
+ PE1_on; //NRF24L01 antenna RF3 by default
+ PE2_off; //NRF24L01 antenna RF3 by default
+ NRF24L01_Initialize();
+ NRF24L01_SetTxRxMode(TX_EN);
+ NRF24L01_FlushTx();
+ NRF24L01_FlushRx();
+ NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
+ NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
+ NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
+ NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
+ NRF24L01_SetPower();
+ return;
+ }
+ //CC2500
+ #ifdef CC2500_INSTALLED
+ debugln("Using CC2500");
+ PE1_off; // antenna RF2
+ PE2_on;
+ CC2500_Reset();
+ CC2500_Strobe(CC2500_SIDLE);
- // Address Config = No address check
- // Base Frequency = 2400
- // CRC Autoflush = false
- // CRC Enable = false
- // Channel Spacing = 333.251953
- // Data Format = Normal mode
- // Data Rate = 249.939
- // Deviation = 126.953125
- // Device Address = 0
- // Manchester Enable = false
- // Modulated = true
- // Modulation Format = GFSK
- // Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
- // RX Filter BW = 203.125000
- // Sync Word Qualifier Mode = No preamble/sync
- // TX Power = 0
- // Whitening = false
- // Fast Frequency Hopping - no PLL auto calibration
+ // Address Config = No address check
+ // Base Frequency = 2400
+ // CRC Autoflush = false
+ // CRC Enable = false
+ // Channel Spacing = 333.251953
+ // Data Format = Normal mode
+ // Data Rate = 249.939
+ // Deviation = 126.953125
+ // Device Address = 0
+ // Manchester Enable = false
+ // Modulated = true
+ // Modulation Format = GFSK
+ // Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
+ // RX Filter BW = 203.125000
+ // Sync Word Qualifier Mode = No preamble/sync
+ // TX Power = 0
+ // Whitening = false
+ // Fast Frequency Hopping - no PLL auto calibration
- 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
- CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency Control Word, High Byte
- CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency Control Word, Middle Byte
- CC2500_WriteReg(CC2500_0F_FREQ0, 0xC3); // Frequency Control Word, Low Byte
- CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration
- CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
- CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration
- CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration
- CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // Modem Configuration
- CC2500_WriteReg(CC2500_15_DEVIATN, 0x62); // Modem Deviation Setting
- CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration
- CC2500_WriteReg(CC2500_19_FOCCFG, 0x1D); // Frequency Offset Compensation Configuration
- CC2500_WriteReg(CC2500_1A_BSCFG, 0x1C); // Bit Synchronization Configuration
- CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7); // AGC Control
- CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control
- CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0); // AGC Control
- CC2500_WriteReg(CC2500_21_FREND1, 0xB6); // Front End RX Configuration
- CC2500_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_08_PKTCTRL0, 0x01); // Packet Automation Control
+ CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control
+ CC2500_WriteReg(CC2500_0C_FSCTRL0, option); // Frequency offset hack
+ CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency Control Word, High Byte
+ CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency Control Word, Middle Byte
+ CC2500_WriteReg(CC2500_0F_FREQ0, 0xC3); // Frequency Control Word, Low Byte
+ CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration
+ CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
+ CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration
+ CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration
+ CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // Modem Configuration
+ CC2500_WriteReg(CC2500_15_DEVIATN, 0x62); // Modem Deviation Setting
+ CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration
+ CC2500_WriteReg(CC2500_19_FOCCFG, 0x1D); // Frequency Offset Compensation Configuration
+ CC2500_WriteReg(CC2500_1A_BSCFG, 0x1C); // Bit Synchronization Configuration
+ CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7); // AGC Control
+ CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control
+ CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0); // AGC Control
+ CC2500_WriteReg(CC2500_21_FREND1, 0xB6); // Front End RX Configuration
+ CC2500_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_SetTxRxMode(TX_EN);
- CC2500_SetPower();
- xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
+ CC2500_SetTxRxMode(TX_EN);
+ CC2500_SetPower();
+ xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
+ #endif
}
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
{
- if (len > 5) len = 5;
- if (len < 3) len = 3;
- xn297_addr_len = len;
- memcpy(xn297_tx_addr, addr, len);
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ XN297_SetTXAddr(addr,len);
+ return;
+ }
+ //CC2500
+ #ifdef CC2500_INSTALLED
+ if (len > 5) len = 5;
+ if (len < 3) len = 3;
+ xn297_addr_len = len;
+ memcpy(xn297_tx_addr, addr, len);
+ #endif
}
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
{
- uint8_t buf[32];
- uint8_t last = 0;
- uint8_t i;
- static const uint16_t initial = 0xb5d2;
-
- // 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++;
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ 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);
+ return;
}
+ //CC2500
+ #ifdef CC2500_INSTALLED
+ uint8_t buf[32];
+ uint8_t last = 0;
+ uint8_t i;
+ static const uint16_t initial = 0xb5d2;
- // payload
- for (i = 0; i < len; ++i) {
- // bit-reverse bytes in packet
- buf[last] = bit_reverse(msg[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
+ uint16_t crc = initial;
+ for (uint8_t i = 0; i < last; ++i)
+ crc = crc16_update(crc, buf[i], 8);
if(xn297_scramble_enabled)
- buf[last] ^= xn297_scramble[xn297_addr_len+i];
- last++;
+ 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);
+ #endif
+}
+
+static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
+{
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ 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);
+ return;
}
+ //CC2500
+ #ifdef CC2500_INSTALLED
+ uint8_t buf[32];
+ uint8_t scramble_index=0;
+ uint8_t last = 0;
+ static uint8_t pid=0;
- // crc
- uint16_t crc = initial;
- for (uint8_t i = 0; i < last; ++i)
- crc = crc16_update(crc, 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;
+ // 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
+ buf[last++] = 0x55;
+ }
+ 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++;
+ }
- // 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);
+ // 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)
+ {
+ uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
+ uint16_t crc = 0xb5d2;
+ for (uint8_t i = offset; i < last; ++i)
+ crc = crc16_update(crc, buf[i], 8);
+ crc = crc16_update(crc, 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;
+ }
+ NRF24L01_WritePayload(packet, last);
+
+ pid++;
+ if(pid>3)
+ pid=0;
+
+ // 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);
+ #endif
}
static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
{ //calibrate hopping frequencies
- for (uint8_t i = 0; i < num_freq; i++)
- {
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ return; //NRF
+ #ifdef CC2500_INSTALLED
+ for (uint8_t i = 0; i < num_freq; i++)
+ {
+ CC2500_Strobe(CC2500_SIDLE);
+ CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
+ CC2500_Strobe(CC2500_SCAL);
+ delayMicroseconds(900);
+ calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
+ }
+ #endif
+}
+
+static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
+{
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
+ return;
+ }
+ #ifdef CC2500_INSTALLED
+ // spacing is 333.25 kHz, must multiply xn297 channel by 3
+ CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
+ // set PLL calibration
+ CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
+ #endif
+}
+
+static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
+{ //change channel
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
+ return;
+ }
+ #ifdef CC2500_INSTALLED
CC2500_Strobe(CC2500_SIDLE);
- CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
+ CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
CC2500_Strobe(CC2500_SCAL);
delayMicroseconds(900);
- calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
- }
-}
-
-static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
-{
- // spacing is 333.25 kHz, must multiply xn297 channel by 3
- CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
- // set PLL calibration
- CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
-}
-
-static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
-{ //change channel
- CC2500_Strobe(CC2500_SIDLE);
- CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
- CC2500_Strobe(CC2500_SCAL);
- delayMicroseconds(900);
+ #endif
}
static void __attribute__((unused)) XN297L_SetPower()
{
- CC2500_SetPower();
-}
-
-static void __attribute__((unused)) XN297L_SetFreqOffset()
-{ // Frequency offset
- if (prev_option != option)
- {
- prev_option = option;
- CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
+ #ifdef CC2500_INSTALLED
+ if(option==0)
+ #endif
+ {//NRF
+ NRF24L01_SetPower();
+ return;
}
-}
-
-#elif defined (NRF24L01_INSTALLED)
-
-static void __attribute__((unused)) XN297L_Init()
-{
- NRF24L01_Initialize();
- NRF24L01_SetTxRxMode(TX_EN);
- NRF24L01_FlushTx();
- NRF24L01_FlushRx();
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
- NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
- NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
- NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
- NRF24L01_SetPower();
-}
-
-static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
-{
- XN297_SetTXAddr(addr,len);
-}
-
-static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
-{
- 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);
-}
-
-static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t num_freq)
-{ //calibrate hopping frequencies
-}
-
-static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
-{
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
-}
-
-static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
-{ //change channel
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
-}
-
-static void __attribute__((unused)) XN297L_SetPower()
-{
- NRF24L01_SetPower();
+ #ifdef CC2500_INSTALLED
+ CC2500_SetPower();
+ #endif
}
static void __attribute__((unused)) XN297L_SetFreqOffset()
{ // Frequency offset
+ #ifdef CC2500_INSTALLED
+ if(option==0 && prev_option==0)
+ #endif
+ return; //NRF
+ #ifdef CC2500_INSTALLED
+ if (prev_option != option)
+ {
+ if(prev_option==0 || option==0)
+ CHANGE_PROTOCOL_FLAG_on;
+ prev_option = option;
+ CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
+ }
+ #endif
}
-
#endif
\ No newline at end of file
diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h
index 69dc5f8..746f47a 100644
--- a/Multiprotocol/_Config.h
+++ b/Multiprotocol/_Config.h
@@ -78,9 +78,6 @@
#define CC2500_INSTALLED
#define NRF24L01_INSTALLED
-//If available use the CC2500 to emulate the XN297L @250Kbps instead of the NRF24L01. Comment to disable.
-#define XN297L_CC2500_EMU
-
/** OrangeRX TX **/
//If you compile for the OrangeRX TX module you need to select the correct board type.
//By default the compilation is done for the GREEN board, to switch to a BLUE board uncomment the line below by removing the "//"
@@ -488,33 +485,6 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
// - 0x40010000 will give to the protocol the channels in the order 4,2,3,1,5,6,7,8 swapping channel 1 and 4. Note: 0 means leave the channel where it is.
// - 0x0000ABCD will give to the protocol the channels in the order 1,2,3,4,10,11,12,13 which potentially enables acces to channels not available on your TX. Note A=10,B=11,C=12,D=13,E=14,F=15.
-
-/**********************************/
-/*** DIRECT INPUTS SETTINGS ***/
-/**********************************/
-//In this section you can configure the direct inputs.
-//It enables switches wired directly to the board
-//Direct inputs works only in ppm mode and only for stm_32 boards
-//Uncomment following lines to enable derect inputs or define your own configuration in _MyConfig.h
-/*
-#define ENABLE_DIRECT_INPUTS
-
-#define DI1_PIN PC13
-#define IS_DI1_on (digitalRead(DI1_PIN)==LOW)
-
-#define DI2_PIN PC14
-#define IS_DI2_on (digitalRead(DI2_PIN)==LOW)
-
-#define DI3_PIN PC15
-#define IS_DI3_on (digitalRead(DI3_PIN)==LOW)
-
-//Define up to 4 direct input channels
-//CHANNEL1 - 2pos switch
-#define DI_CH1_read IS_DI1_on ? PPM_MAX_100*2 : PPM_MIN_100*2
-//CHANNEL2 - 3pos switch
-#define DI_CH2_read IS_DI2_on ? PPM_MAX_100*2 : (IS_DI2_on ? PPM_MAX_100 + PPM_MIN_100 : PPM_MIN_100*2)
-*/
-
/* Available protocols and associated sub protocols to pick and choose from (Listed in alphabetical order)
PROTO_AFHDS2A
PWM_IBUS
@@ -695,7 +665,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_V761
NONE
PROTO_V911S
- NONE
+ V911S_STD
+ V911S_E119
PROTO_WFLY
NONE
PROTO_WK2x01
@@ -714,3 +685,29 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_ZSX
NONE
*/
+
+/**********************************/
+/*** DIRECT INPUTS SETTINGS ***/
+/**********************************/
+//In this section you can configure the direct inputs.
+//It enables switches wired directly to the board
+//Direct inputs works only in ppm mode and only for stm_32 boards
+//Uncomment following lines to enable derect inputs or define your own configuration in _MyConfig.h
+/*
+#define ENABLE_DIRECT_INPUTS
+
+#define DI1_PIN PC13
+#define IS_DI1_on (digitalRead(DI1_PIN)==LOW)
+
+#define DI2_PIN PC14
+#define IS_DI2_on (digitalRead(DI2_PIN)==LOW)
+
+#define DI3_PIN PC15
+#define IS_DI3_on (digitalRead(DI3_PIN)==LOW)
+
+//Define up to 4 direct input channels
+//CHANNEL1 - 2pos switch
+#define DI_CH1_read IS_DI1_on ? PPM_MAX_100*2 : PPM_MIN_100*2
+//CHANNEL2 - 3pos switch
+#define DI_CH2_read IS_DI2_on ? PPM_MAX_100*2 : (IS_DI2_on ? PPM_MAX_100 + PPM_MIN_100 : PPM_MIN_100*2)
+*/
diff --git a/Multiprotocol/iface_xn297l.h b/Multiprotocol/iface_xn297l.h
index 29bf09b..8943a29 100644
--- a/Multiprotocol/iface_xn297l.h
+++ b/Multiprotocol/iface_xn297l.h
@@ -2,15 +2,17 @@
#define _IFACE_XN297L_H_
-#if defined (XN297L_CC2500_EMU)
+#if defined (CC2500_INSTALLED)
#include "iface_cc2500.h"
-#elif defined (NRF24L01_INSTALLED)
+#endif
+#if defined (NRF24L01_INSTALLED)
#include "iface_nrf24l01.h"
#endif
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);
diff --git a/Protocols_Details.md b/Protocols_Details.md
index e60aa88..697f55b 100644
--- a/Protocols_Details.md
+++ b/Protocols_Details.md
@@ -127,7 +127,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
-* "*" Sub Protocols designated by * suffix will use the NRF24L01 module by default to emulate the XN297L RF chip. If a CC2500 module is installed it will be used instead as it is proving to be a better option for the XN297L@250kbps. Each specific sub protocol has a more detailed explanation.
+* "*" Sub Protocols designated by * suffix are using a XN297L@250kbps which will be emulated by default with the NRF24L01. If option (freq tune) is diffrent from 0, the CC2500 module (if installed) will be used instead. Each specific sub protocol has a more detailed explanation.
# A7105 RF Module
@@ -262,7 +262,7 @@ Models: TX: CADET PRO V4, RX: RX-602 V4
Extended limits supported
-**Only 1 ID for now**
+**Only 1 set of frequencies for now**
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
@@ -898,9 +898,9 @@ A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
## GD00X - *47*
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
-If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
-If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
@@ -1001,9 +1001,9 @@ ARM|
## KF606 - *49*
Model: KF606
-If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
-If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
CH1|CH2|CH3|CH4|CH5
---|---|---|---|---
@@ -1028,9 +1028,9 @@ 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 the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
-If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
### Sub_protocol H26WH - *5*
CH6|
@@ -1060,7 +1060,9 @@ Model: Yi Zhan i6S
Only one model can be flown at the same time since the ID is hardcoded.
-If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
+
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
### Sub_protocol LS - *3*
Models: LS114, 124, 215
@@ -1130,7 +1132,10 @@ CH1|CH2|CH3|CH4
A|E|T|R
### Sub_protocol Q303 - *0*
-If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
+
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---
@@ -1302,9 +1307,9 @@ Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gy
## V911S - *46*
Models: WLtoys V911S, XK A110
-If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
+This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
-If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
+If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
CH1|CH2|CH3|CH4|CH5
---|---|---|---|---