XN297EMU: option=0->nrf24L01, option!=0 -> CC2500

XN297L@250kbps is emulated by default with the NRF24L01. If option (freq tune) is diffrent from 0, the CC2500 module (if installed) will be used instead with option being the freq usual tuning.
This commit is contained in:
pascallanger 2020-01-12 14:06:27 +01:00
parent 953a97dae4
commit 6a9b6ed4be
12 changed files with 408 additions and 426 deletions

View File

@ -114,6 +114,7 @@ const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410";
const char STR_SUBTYPE_FX816[] = "\x03""P38"; const char STR_SUBTYPE_FX816[] = "\x03""P38";
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 "; 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_ESKY150[] = "\x03""4CH""7CH";
const char STR_SUBTYPE_V911S[] = "\x04""Std\0""E119";
enum enum
{ {
@ -265,7 +266,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION }, {PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
#endif #endif
#if defined(V911S_NRF24L01_INO) #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 #endif
#if defined(GD00X_NRF24L01_INO) #if defined(GD00X_NRF24L01_INO)
{PROTO_GD00X, STR_GD00X, 2, STR_SUBTYPE_GD00X, OPTION_RFTUNE }, {PROTO_GD00X, STR_GD00X, 2, STR_SUBTYPE_GD00X, OPTION_RFTUNE },

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_REVISION 0 #define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 52 #define VERSION_PATCH_LEVEL 53
//****************** //******************
// Protocols // Protocols
@ -300,6 +300,11 @@ enum ESKY150
ESKY150_4CH = 0, ESKY150_4CH = 0,
ESKY150_7CH = 1, ESKY150_7CH = 1,
}; };
enum V911S
{
V911S_STD = 0,
V911S_E119 = 1,
};
enum XN297DUMP enum XN297DUMP
{ {
XN297DUMP_250K = 0, XN297DUMP_250K = 0,
@ -351,7 +356,7 @@ enum MultiPacketTypes
//*** Tests *** //*** 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_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 *** //*** Flags ***
@ -842,6 +847,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
sub_protocol==ESKY150 sub_protocol==ESKY150
ESKY150_4CH 0 ESKY150_4CH 0
ESKY150_7CH 1 ESKY150_7CH 1
sub_protocol==V911S
V911S_STD 0
V911S_E119 1
Power value => 0x80 0=High/1=Low Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol; Stream[3] = option_protocol;

View File

@ -346,6 +346,7 @@ void setup()
pinMode(DI4_PIN,INPUT_PULLUP); pinMode(DI4_PIN,INPUT_PULLUP);
#endif #endif
#endif #endif
//Random pins //Random pins
pinMode(PB0, INPUT_ANALOG); // set up pin for analog input pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
@ -724,7 +725,6 @@ bool Update_All()
else else
Channel_data[i]=val; Channel_data[i]=val;
} }
PPM_FLAG_off; // wait for next frame before update PPM_FLAG_off; // wait for next frame before update
#ifdef FAILSAFE_ENABLE #ifdef FAILSAFE_ENABLE
PPM_failsafe(); PPM_failsafe();

View File

@ -128,7 +128,7 @@ static void multi_send_status()
#ifdef MULTI_TELEMETRY #ifdef MULTI_TELEMETRY
multi_send_header(MULTI_TELEMETRY_STATUS, 6); multi_send_header(MULTI_TELEMETRY_STATUS, 6);
#else #else
multi_send_header(MULTI_TELEMETRY_STATUS, 5); multi_send_header(MULTI_TELEMETRY_STATUS, 6);
#endif #endif
// Build flags // Build flags
@ -170,8 +170,8 @@ static void multi_send_status()
Serial_write(VERSION_REVISION); Serial_write(VERSION_REVISION);
Serial_write(VERSION_PATCH_LEVEL); Serial_write(VERSION_PATCH_LEVEL);
// Channel order
#ifdef MULTI_TELEMETRY #ifdef MULTI_TELEMETRY
// Channel order
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON); Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
#endif #endif

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
// 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<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency[i]=0x10+i*5+offset;
if(!offset) hopping_frequency[0]++;
// channels order
rf_ch_num=random(0xfefefefe)&0x03; // 0-3
}
uint16_t V911S_callback()
{
if(IS_BIND_DONE)
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(V911S_PACKET_PERIOD);
#endif
V911S_send_packet(0);
}
else
{
if (bind_counter == 0)
{
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 5);
packet_period=V911S_PACKET_PERIOD;
}
else
{
V911S_send_packet(1);
bind_counter--;
if(bind_counter==100) // same as original TX...
packet_period=V911S_BIND_PACKET_PERIOD*3;
}
}
return packet_period;
}
uint16_t initV911S(void)
{
V911S_initialize_txid();
#ifdef V911S_ORIGINAL_ID
rx_tx_addr[0]=0xA5;
rx_tx_addr[1]=0xFF;
rx_tx_addr[2]=0x70;
rx_tx_addr[3]=0x8D;
rx_tx_addr[4]=0x76;
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency[i]=0x10+i*5;
hopping_frequency[0]++;
rf_ch_num=0;
#endif
V911S_init();
if(IS_BIND_IN_PROGRESS)
{
bind_counter = V911S_BIND_COUNT;
packet_period= V911S_BIND_PACKET_PERIOD;
}
else
{
XN297_SetTXAddr(rx_tx_addr, 5);
packet_period= V911S_PACKET_PERIOD;
}
hopping_frequency_no=0;
return V911S_INITIAL_WAIT;
}
#endif

View File

@ -14,11 +14,11 @@
*/ */
// compatible with V911S // compatible with V911S
#if defined(V911S_XN297L_INO) #if defined(V911S_NRF24L01_INO)
#include "iface_xn297l.h" #include "iface_xn297l.h"
//#define V911S_ORIGINAL_ID #define V911S_ORIGINAL_ID
#define V911S_PACKET_PERIOD 5000 #define V911S_PACKET_PERIOD 5000
#define V911S_BIND_PACKET_PERIOD 3300 #define V911S_BIND_PACKET_PERIOD 3300
@ -82,7 +82,10 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
hopping_frequency_no&=7; // 8 RF channels hopping_frequency_no&=7; // 8 RF channels
} }
if(sub_protocol==V911S_STD)
XN297L_WritePayload(packet, V911S_PACKET_SIZE); XN297L_WritePayload(packet, V911S_PACKET_SIZE);
else
XN297L_WriteEnhancedPayload(packet, V911S_PACKET_SIZE, bind);
XN297L_SetPower(); // Set tx_power XN297L_SetPower(); // Set tx_power
XN297L_SetFreqOffset(); // Set frequency offset XN297L_SetFreqOffset(); // Set frequency offset
@ -91,7 +94,10 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
static void __attribute__((unused)) V911S_init() static void __attribute__((unused)) V911S_init()
{ {
XN297L_Init(); XN297L_Init();
XN297L_SetTXAddr((uint8_t *)"KNBND",5); // Bind address if(sub_protocol==V911S_STD)
XN297L_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_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels
XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
} }
@ -140,6 +146,8 @@ uint16_t initV911S(void)
{ {
V911S_initialize_txid(); V911S_initialize_txid();
#ifdef V911S_ORIGINAL_ID #ifdef V911S_ORIGINAL_ID
if(sub_protocol==V911S_STD)
{//V911S
rx_tx_addr[0]=0xA5; rx_tx_addr[0]=0xA5;
rx_tx_addr[1]=0xFF; rx_tx_addr[1]=0xFF;
rx_tx_addr[2]=0x70; rx_tx_addr[2]=0x70;
@ -149,6 +157,19 @@ uint16_t initV911S(void)
hopping_frequency[i]=0x10+i*5; hopping_frequency[i]=0x10+i*5;
hopping_frequency[0]++; hopping_frequency[0]++;
rf_ch_num=0; rf_ch_num=0;
}
else
{
//E119
rx_tx_addr[0]=0x30;
rx_tx_addr[1]=0xFF;
rx_tx_addr[2]=0xD1;
rx_tx_addr[3]=0x2C;
rx_tx_addr[4]=0x2A;
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency[i]=0x0E + i*5;
rf_ch_num=0;
}
#endif #endif
V911S_init(); V911S_init();

View File

@ -207,7 +207,6 @@
#undef CORONA_CC2500_INO #undef CORONA_CC2500_INO
#undef REDPINE_CC2500_INO #undef REDPINE_CC2500_INO
#undef HITEC_CC2500_INO #undef HITEC_CC2500_INO
#undef XN297L_CC2500_EMU
#undef SCANNER_CC2500_INO #undef SCANNER_CC2500_INO
#undef FRSKY_RX_CC2500_INO #undef FRSKY_RX_CC2500_INO
#undef HOTT_CC2500_INO #undef HOTT_CC2500_INO
@ -245,7 +244,6 @@
#undef E01X_NRF24L01_INO #undef E01X_NRF24L01_INO
#undef V761_NRF24L01_INO #undef V761_NRF24L01_INO
#undef V911S_NRF24L01_INO #undef V911S_NRF24L01_INO
#undef XN297L_CC2500_EMU
#undef POTENSIC_NRF24L01_INO #undef POTENSIC_NRF24L01_INO
#undef ZSX_NRF24L01_INO #undef ZSX_NRF24L01_INO
#undef BAYANG_RX_NRF24L01_INO #undef BAYANG_RX_NRF24L01_INO
@ -357,9 +355,7 @@
#if not defined(MULTI_TELEMETRY) #if not defined(MULTI_TELEMETRY)
#undef MULTI_SYNC #undef MULTI_SYNC
#undef MULTI_NAMES #undef MULTI_NAMES
#endif #else
#if defined(MULTI_TELEMETRY)
#define MULTI_NAMES #define MULTI_NAMES
#endif #endif

View File

@ -12,11 +12,32 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifdef NRF24L01_INSTALLED
#include "iface_xn297l.h" #include "iface_xn297l.h"
#if defined (XN297L_CC2500_EMU)
static void __attribute__((unused)) XN297L_Init() static void __attribute__((unused)) XN297L_Init()
{ {
#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 PE1_off; // antenna RF2
PE2_on; PE2_on;
CC2500_Reset(); CC2500_Reset();
@ -67,18 +88,41 @@ static void __attribute__((unused)) XN297L_Init()
CC2500_SetTxRxMode(TX_EN); CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower(); CC2500_SetPower();
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
#endif
} }
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len) static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t 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 > 5) len = 5;
if (len < 3) len = 3; if (len < 3) len = 3;
xn297_addr_len = len; xn297_addr_len = len;
memcpy(xn297_tx_addr, addr, len); memcpy(xn297_tx_addr, addr, len);
#endif
} }
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len) static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
{ {
#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 buf[32];
uint8_t last = 0; uint8_t last = 0;
uint8_t i; uint8_t i;
@ -125,10 +169,114 @@ static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t le
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last); CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last);
// transmit // transmit
CC2500_Strobe(CC2500_STX); 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;
// 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++;
}
// 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) static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
{ //calibrate hopping frequencies { //calibrate hopping frequencies
#ifdef CC2500_INSTALLED
if(option==0)
#endif
return; //NRF
#ifdef CC2500_INSTALLED
for (uint8_t i = 0; i < num_freq; i++) for (uint8_t i = 0; i < num_freq; i++)
{ {
CC2500_Strobe(CC2500_SIDLE); CC2500_Strobe(CC2500_SIDLE);
@ -137,87 +285,71 @@ static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
delayMicroseconds(900); delayMicroseconds(900);
calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1); calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
} }
#endif
} }
static void __attribute__((unused)) XN297L_Hopping(uint8_t index) 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 // spacing is 333.25 kHz, must multiply xn297 channel by 3
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3); CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
// set PLL calibration // set PLL calibration
CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]); CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
#endif
} }
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number) static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
{ //change channel { //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_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_0A_CHANNR, number*3); CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
CC2500_Strobe(CC2500_SCAL); CC2500_Strobe(CC2500_SCAL);
delayMicroseconds(900); delayMicroseconds(900);
#endif
} }
static void __attribute__((unused)) XN297L_SetPower() static void __attribute__((unused)) XN297L_SetPower()
{ {
#ifdef CC2500_INSTALLED
if(option==0)
#endif
{//NRF
NRF24L01_SetPower();
return;
}
#ifdef CC2500_INSTALLED
CC2500_SetPower(); CC2500_SetPower();
#endif
} }
static void __attribute__((unused)) XN297L_SetFreqOffset() static void __attribute__((unused)) XN297L_SetFreqOffset()
{ // Frequency offset { // Frequency offset
#ifdef CC2500_INSTALLED
if(option==0 && prev_option==0)
#endif
return; //NRF
#ifdef CC2500_INSTALLED
if (prev_option != option) if (prev_option != option)
{ {
if(prev_option==0 || option==0)
CHANGE_PROTOCOL_FLAG_on;
prev_option = option; prev_option = option;
CC2500_WriteReg(CC2500_0C_FSCTRL0, option); CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
} }
#endif
} }
#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();
}
static void __attribute__((unused)) XN297L_SetFreqOffset()
{ // Frequency offset
}
#endif #endif

View File

@ -78,9 +78,6 @@
#define CC2500_INSTALLED #define CC2500_INSTALLED
#define NRF24L01_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 **/ /** OrangeRX TX **/
//If you compile for the OrangeRX TX module you need to select the correct board type. //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 "//" //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. // - 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. // - 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) /* Available protocols and associated sub protocols to pick and choose from (Listed in alphabetical order)
PROTO_AFHDS2A PROTO_AFHDS2A
PWM_IBUS PWM_IBUS
@ -695,7 +665,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_V761 PROTO_V761
NONE NONE
PROTO_V911S PROTO_V911S
NONE V911S_STD
V911S_E119
PROTO_WFLY PROTO_WFLY
NONE NONE
PROTO_WK2x01 PROTO_WK2x01
@ -714,3 +685,29 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_ZSX PROTO_ZSX
NONE 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)
*/

View File

@ -2,15 +2,17 @@
#define _IFACE_XN297L_H_ #define _IFACE_XN297L_H_
#if defined (XN297L_CC2500_EMU) #if defined (CC2500_INSTALLED)
#include "iface_cc2500.h" #include "iface_cc2500.h"
#elif defined (NRF24L01_INSTALLED) #endif
#if defined (NRF24L01_INSTALLED)
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
#endif #endif
static void __attribute__((unused)) XN297L_Init(); static void __attribute__((unused)) XN297L_Init();
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t*, uint8_t); 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_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_HoppingCalib(__attribute__((unused)) uint8_t);
static void __attribute__((unused)) XN297L_Hopping(uint8_t); static void __attribute__((unused)) XN297L_Hopping(uint8_t);
static void __attribute__((unused)) XN297L_RFChannel(uint8_t); static void __attribute__((unused)) XN297L_RFChannel(uint8_t);

View File

@ -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| [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| [YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297 [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 # A7105 RF Module
@ -262,7 +262,7 @@ Models: TX: CADET PRO V4, RX: RX-602 V4
Extended limits supported Extended limits supported
**Only 1 ID for now** **Only 1 set of frequencies for now**
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---
@ -898,9 +898,9 @@ A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
## GD00X - *47* ## GD00X - *47*
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50 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 CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|--- ---|---|---|---|---|---|---
@ -1001,9 +1001,9 @@ ARM|
## KF606 - *49* ## KF606 - *49*
Model: KF606 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 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* ### Sub_protocol E010 - *4*
15 TX IDs available, change RX_Num value 0..14 to cycle through them 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* ### Sub_protocol H26WH - *5*
CH6| CH6|
@ -1060,7 +1060,9 @@ Model: Yi Zhan i6S
Only one model can be flown at the same time since the ID is hardcoded. 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* ### Sub_protocol LS - *3*
Models: LS114, 124, 215 Models: LS114, 124, 215
@ -1130,7 +1132,10 @@ CH1|CH2|CH3|CH4
A|E|T|R A|E|T|R
### Sub_protocol Q303 - *0* ### 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 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* ## V911S - *46*
Models: WLtoys V911S, XK A110 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 CH1|CH2|CH3|CH4|CH5
---|---|---|---|--- ---|---|---|---|---