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.
This commit is contained in:
Pascal Langer 2021-03-17 17:05:42 +01:00
parent 47de19c8a5
commit 4a626eaf14
45 changed files with 1509 additions and 1475 deletions

View File

@ -38,7 +38,6 @@
70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12 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,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH
45,1,E01X,E015,1,Arm,Flip,LED,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,0,ESKY,Std,0,Gyro,Pitch
16,1,ESKY,ET4,0,Gyro,Pitch 16,1,ESKY,ET4,0,Gyro,Pitch
35,0,ESKY150,4CH,0 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 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 83,0,E129,E129,1,TakLan,EmStop,TrimA,TrimE,TrimR
84,0,JOYSWAY,Std,0 84,0,JOYSWAY,Std,0
85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH

View File

@ -16,7 +16,7 @@
#if defined(BUGSMINI_NRF24L01_INO) #if defined(BUGSMINI_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define BUGSMINI_INITIAL_WAIT 500 #define BUGSMINI_INITIAL_WAIT 500
#define BUGSMINI_PACKET_INTERVAL 6840 #define BUGSMINI_PACKET_INTERVAL 6840
@ -59,9 +59,8 @@ enum {
static void __attribute__((unused)) BUGSMINI_RF_init() static void __attribute__((unused)) BUGSMINI_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//XN297_HoppingCalib(BUGSMINI_NUM_RF_CHANNELS*2);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BUGSMINI_RX_PAYLOAD_SIZE); // bytes of data payload for rx pipe 1
} }
static void __attribute__((unused)) BUGSMINI_check_arming() static void __attribute__((unused)) BUGSMINI_check_arming()
@ -148,15 +147,14 @@ static void __attribute__((unused)) BUGSMINI_send_packet()
hopping_frequency_no++; hopping_frequency_no++;
if(hopping_frequency_no >= BUGSMINI_NUM_RF_CHANNELS) if(hopping_frequency_no >= BUGSMINI_NUM_RF_CHANNELS)
hopping_frequency_no = 0; 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 // Send
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, BUGSMINI_TX_PAYLOAD_SIZE); XN297_WritePayload(packet, BUGSMINI_TX_PAYLOAD_SIZE);
NRF24L01_SetPower();
} }
// compute final address for the rxid received during bind // 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.... // Something wrong happened if we arrive here....
} }
#if defined(BUGS_HUB_TELEMETRY)
static void __attribute__((unused)) BUGSMINI_update_telemetry() static void __attribute__((unused)) BUGSMINI_update_telemetry()
{ {
#if defined(BUGS_HUB_TELEMETRY)
uint8_t checksum = 0x6d; uint8_t checksum = 0x6d;
for(uint8_t i=1; i<12; i++) for(uint8_t i=1; i<12; i++)
checksum += packet[i]; checksum += packet_in[i];
if(packet[0] == checksum) if(packet_in[0] == checksum)
{ {
RX_RSSI = packet[3]; RX_RSSI = packet_in[3];
if(sub_protocol==BUGS3H) if(sub_protocol==BUGS3H)
{ {
if(packet[11] & 0x40) if(packet_in[11] & 0x40)
v_lipo1 = 0x40; // Warning v_lipo1 = 0x40; // Warning
else if(packet[11] & 0x80) else if(packet_in[11] & 0x80)
v_lipo1 = 0x20; // Critical v_lipo1 = 0x20; // Critical
else else
v_lipo1 = 0x80; // Ok v_lipo1 = 0x80; // Ok
} }
else else
{ {
if(packet[11] & 0x80) if(packet_in[11] & 0x80)
v_lipo1 = 0x80; // Ok v_lipo1 = 0x80; // Ok
else if(packet[11] & 0x40) else if(packet_in[11] & 0x40)
v_lipo1 = 0x40; // Warning v_lipo1 = 0x40; // Warning
else else
v_lipo1 = 0x20; // Critical v_lipo1 = 0x20; // Critical
} }
telemetry_link=1; telemetry_link=1;
} }
#endif
} }
#endif
uint16_t BUGSMINI_callback() uint16_t BUGSMINI_callback()
{ {
@ -258,58 +256,52 @@ uint16_t BUGSMINI_callback()
switch(phase) switch(phase)
{ {
case BUGSMINI_BIND1: case BUGSMINI_BIND1:
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( XN297_IsRX() )
{ // RX fifo data ready { // 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; 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+0),packet[1]); // Save rxid in EEPROM
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // 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);
BUGSMINI_make_address(); BUGSMINI_make_address();
XN297_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, 5); XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE);
phase = BUGSMINI_DATA1; phase = BUGSMINI_DATA1;
BIND_DONE; BIND_DONE;
return BUGSMINI_PACKET_INTERVAL; break;
} }
NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN);
BUGSMINI_send_packet(); BUGSMINI_send_packet();
phase = BUGSMINI_BIND2; phase = BUGSMINI_BIND2;
return BUGSMINI_WRITE_WAIT; return BUGSMINI_WRITE_WAIT;
case BUGSMINI_BIND2: case BUGSMINI_BIND2:
// switch to RX mode // switch to RX mode
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(RX_EN); XN297_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));
phase = BUGSMINI_BIND1; phase = BUGSMINI_BIND1;
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT; return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
case BUGSMINI_DATA1: case BUGSMINI_DATA1:
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(BUGSMINI_PACKET_INTERVAL); telemetry_set_input_sync(BUGSMINI_PACKET_INTERVAL);
#endif #endif
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) #if defined(BUGS_HUB_TELEMETRY)
{ // RX fifo data ready => read only 12 bytes to not overwrite channel change flag if( XN297_IsRX() )
XN297_ReadPayload(packet, 12); {
BUGSMINI_update_telemetry(); XN297_ReadPayload(packet_in, BUGSMINI_RX_PAYLOAD_SIZE); // Not checking the CRC??
} BUGSMINI_update_telemetry();
NRF24L01_SetTxRxMode(TXRX_OFF); }
NRF24L01_SetTxRxMode(TX_EN); #endif
BUGSMINI_send_packet(); BUGSMINI_send_packet();
#if not defined(BUGS_HUB_TELEMETRY)
break;
#else
phase = BUGSMINI_DATA2; phase = BUGSMINI_DATA2;
return BUGSMINI_WRITE_WAIT; return BUGSMINI_WRITE_WAIT;
case BUGSMINI_DATA2: case BUGSMINI_DATA2:
// switch to RX mode // switch to RX mode
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_FlushRx(); XN297_SetTxRxMode(RX_EN);
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));
phase = BUGSMINI_DATA1; phase = BUGSMINI_DATA1;
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT; return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
#endif
} }
return BUGSMINI_PACKET_INTERVAL; return BUGSMINI_PACKET_INTERVAL;
} }
@ -349,19 +341,19 @@ static void __attribute__((unused)) BUGSMINI_initialize_txid()
void BUGSMINI_init() void BUGSMINI_init()
{ {
BUGSMINI_initialize_txid(); BUGSMINI_initialize_txid();
memset(packet, (uint8_t)0, BUGSMINI_TX_PAYLOAD_SIZE);
BUGSMINI_RF_init(); BUGSMINI_RF_init();
memset(packet, (uint8_t)0, BUGSMINI_TX_PAYLOAD_SIZE);
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
XN297_SetTXAddr((const uint8_t*)"mjxRC", 5); 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; phase = BUGSMINI_BIND1;
} }
else else
{ {
BUGSMINI_make_address(); BUGSMINI_make_address();
XN297_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, 5); XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE);
phase = BUGSMINI_DATA1; phase = BUGSMINI_DATA1;
} }
armed = 0; armed = 0;

View File

@ -15,7 +15,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#if defined(BAYANG_RX_NRF24L01_INO) #if defined(BAYANG_RX_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define BAYANG_RX_PACKET_SIZE 15 #define BAYANG_RX_PACKET_SIZE 15
#define BAYANG_RX_RF_NUM_CHANNELS 4 #define BAYANG_RX_RF_NUM_CHANNELS 4
@ -27,18 +27,15 @@ enum {
BAYANG_RX_DATA 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 }; 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_SetTXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH);
XN297_SetRXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH); XN297_SetRXAddr(bind_address, BAYANG_RX_PACKET_SIZE);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_RX_PACKET_SIZE + 2); // 2 extra bytes for xn297 crc XN297_RFChannel(BAYANG_RX_RF_BIND_CHANNEL);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, BAYANG_RX_RF_BIND_CHANNEL); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
static uint8_t __attribute__((unused)) Bayang_Rx_check_validity() { 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() void BAYANG_RX_init()
{ {
uint8_t i; uint8_t i;
Bayang_Rx_init_nrf24l01(); Bayang_Rx_RF_init();
hopping_frequency_no = 0; hopping_frequency_no = 0;
rx_data_started = false; rx_data_started = false;
rx_data_received = false; rx_data_received = false;
@ -105,8 +102,9 @@ void BAYANG_RX_init()
rx_tx_addr[i] = eeprom_read_byte((EE_ADDR)temp++); rx_tx_addr[i] = eeprom_read_byte((EE_ADDR)temp++);
for (i = 0; i < BAYANG_RX_RF_NUM_CHANNELS; i++) for (i = 0; i < BAYANG_RX_RF_NUM_CHANNELS; i++)
hopping_frequency[i] = eeprom_read_byte((EE_ADDR)temp++); 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_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; phase = BAYANG_RX_DATA;
} }
} }
@ -116,86 +114,89 @@ uint16_t BAYANG_RX_callback()
uint8_t i; uint8_t i;
static int8_t read_retry; static int8_t read_retry;
switch (phase) { switch (phase)
case BAYANG_RX_BIND: {
if(IS_BIND_DONE) 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)
{ {
if(rx_data_received) BAYANG_RX_init(); // Abort bind
{ // In sync break;
rx_data_received = false; }
read_retry = 5; if ( XN297_IsRX() )
return 1500; {
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 else
{ // packet lost read_retry = -16; // retry longer until first packet is caught
read_retry = 0;
if(RX_LQI==0) // communication lost
rx_data_started=false;
}
} }
else return 250;
read_retry = -16; // retry longer until first packet is caught
}
return 250;
} }
return 1000; return 1000;
} }

View File

@ -17,7 +17,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#if defined(BAYANG_NRF24L01_INO) #if defined(BAYANG_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define BAYANG_BIND_COUNT 1000 #define BAYANG_BIND_COUNT 1000
#define BAYANG_PACKET_PERIOD 2000 #define BAYANG_PACKET_PERIOD 2000
@ -97,6 +97,8 @@ static void __attribute__((unused)) BAYANG_send_packet()
} }
else else
{ {
XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
uint16_t val; uint16_t val;
uint8_t dyntrim = 1; uint8_t dyntrim = 1;
switch (sub_protocol) 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++) for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
packet[14] += packet[i]; packet[14] += packet[i];
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? rf_ch_num:hopping_frequency[hopping_frequency_no++]); // Send
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS; XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
// 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));
XN297_WritePayload(packet, BAYANG_PACKET_SIZE); XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
#ifdef BAYANG_HUB_TELEMETRY #ifdef BAYANG_HUB_TELEMETRY
static void __attribute__((unused)) BAYANG_check_rx(void) 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 { // data received from model
XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); // Strange can't test the CRC since it seems to be disabled on telemetry packets...
NRF24L01_WriteReg(NRF24L01_07_STATUS, 255);
NRF24L01_FlushRx();
uint8_t check = packet[0]; uint8_t check = packet[0];
for (uint8_t i=1; i < BAYANG_PACKET_SIZE-1; i++) for (uint8_t i=1; i < BAYANG_PACKET_SIZE-1; i++)
check += packet[i]; check += packet[i];
@ -242,27 +234,21 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
telemetry_link=0; // Don't send anything yet telemetry_link=0; // Don't send anything yet
} }
} }
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
} }
#endif #endif
static void __attribute__((unused)) BAYANG_RF_init() 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); 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) //Set bind channel
{ uint8_t ch = BAYANG_RF_BIND_CHANNEL;
case X16_AH: if(sub_protocol == X16_AH || sub_protocol == IRDRONE)
case IRDRONE: ch = BAYANG_RF_BIND_CHANNEL_X16_AH;
rf_ch_num = BAYANG_RF_BIND_CHANNEL_X16_AH; XN297_RFChannel(ch);
break;
default:
rf_ch_num = BAYANG_RF_BIND_CHANNEL;
break;
}
} }
enum { enum {
@ -287,7 +273,7 @@ uint16_t BAYANG_callback()
{ {
XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
#ifdef BAYANG_HUB_TELEMETRY #ifdef BAYANG_HUB_TELEMETRY
XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); XN297_SetRXAddr(rx_tx_addr, BAYANG_PACKET_SIZE);
#endif #endif
BIND_DONE; BIND_DONE;
phase++; //WRITE phase++; //WRITE
@ -322,9 +308,9 @@ uint16_t BAYANG_callback()
// switch radio to rx as soon as packet is sent // switch radio to rx as soon as packet is sent
start=(uint16_t)micros(); start=(uint16_t)micros();
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 1000) // Wait max 1ms 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; break;
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03); XN297_SetTxRxMode(RX_EN);
phase++; // READ phase++; // READ
return BAYANG_PACKET_TELEM_PERIOD - BAYANG_CHECK_DELAY - BAYANG_READ_DELAY; return BAYANG_PACKET_TELEM_PERIOD - BAYANG_CHECK_DELAY - BAYANG_READ_DELAY;
case BAYANG_READ: case BAYANG_READ:

View File

@ -195,6 +195,7 @@ void __attribute__((unused)) CC2500_250K_Init()
// TX Power = 0 // TX Power = 0
// Whitening = false // Whitening = false
// Fast Frequency Hopping - no PLL auto calibration // Fast Frequency Hopping - no PLL auto calibration
/* //Previous config
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x01); // Packet Automation Control CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x01); // Packet Automation Control
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control
CC2500_WriteReg(CC2500_0C_FSCTRL0, option); // Frequency offset hack 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_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // 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_SetTxRxMode(TX_EN);
CC2500_SetPower(); CC2500_SetPower();
@ -250,87 +287,4 @@ void __attribute__((unused)) CC2500_250K_RFChannel(uint8_t number)
CC2500_Strobe(CC2500_SCAL); CC2500_Strobe(CC2500_SCAL);
delayMicroseconds(900); 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;i<last;i++)
// debug("%02X ",buf[i]);
//debugln("");
// stop TX/RX
CC2500_Strobe(CC2500_SIDLE);
// flush tx FIFO
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_3F_TXFIFO, last);
// transmit nrf packet
uint8_t *buff=buf;
uint8_t status;
if(last>63)
{
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 #endif

View File

@ -63,9 +63,15 @@ static void __attribute__((unused)) CG023_send_packet()
aileron = convert_channel_16b_limit(AILERON, 0x43, 0xBB); aileron = convert_channel_16b_limit(AILERON, 0x43, 0xBB);
if (IS_BIND_IN_PROGRESS) if (IS_BIND_IN_PROGRESS)
{
packet[0]= 0xaa; packet[0]= 0xaa;
XN297_RFChannel(CG023_RF_BIND_CHANNEL);
}
else else
{
packet[0]= 0x55; packet[0]= 0x55;
XN297_RFChannel(hopping_frequency_no);
}
// transmitter id // transmitter id
packet[1] = rx_tx_addr[0]; packet[1] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1]; packet[2] = rx_tx_addr[1];
@ -85,7 +91,7 @@ static void __attribute__((unused)) CG023_send_packet()
if(sub_protocol==CG023) if(sub_protocol==CG023)
{ {
// rate // rate
packet[13] = CG023_FLAG_RATE_HIGH packet[13] = CG023_FLAG_RATE_HIGH
| GET_FLAG(CH5_SW,CG023_FLAG_FLIP) | GET_FLAG(CH5_SW,CG023_FLAG_FLIP)
| GET_FLAG(CH6_SW,CG023_FLAG_LED_OFF) | GET_FLAG(CH6_SW,CG023_FLAG_LED_OFF)
| GET_FLAG(CH7_SW,CG023_FLAG_STILL) | GET_FLAG(CH7_SW,CG023_FLAG_STILL)
@ -95,7 +101,7 @@ static void __attribute__((unused)) CG023_send_packet()
else else
{// YD829 {// YD829
// rate // rate
packet[13] = YD829_FLAG_RATE_HIGH packet[13] = YD829_FLAG_RATE_HIGH
| GET_FLAG(CH5_SW,YD829_FLAG_FLIP) | GET_FLAG(CH5_SW,YD829_FLAG_FLIP)
| GET_FLAG(CH7_SW,YD829_FLAG_STILL) | GET_FLAG(CH7_SW,YD829_FLAG_STILL)
| GET_FLAG(CH8_SW,YD829_FLAG_VIDEO) | GET_FLAG(CH8_SW,YD829_FLAG_VIDEO)
@ -103,25 +109,15 @@ static void __attribute__((unused)) CG023_send_packet()
} }
packet[14] = 0; packet[14] = 0;
// Power on, TX mode, 2byte CRC // Send
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing XN297_SetTxRxMode(TX_EN);
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
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();
XN297_WritePayload(packet, CG023_PACKET_SIZE); XN297_WritePayload(packet, CG023_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) CG023_RF_init() 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); 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() static void __attribute__((unused)) CG023_initialize_txid()
{ {
rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); 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] ++; rx_tx_addr[0] ++;
hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets
} }

View File

@ -17,7 +17,7 @@
#if defined(CX10_NRF24L01_INO) #if defined(CX10_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define CX10_BIND_COUNT 4360 // 6 seconds #define CX10_BIND_COUNT 4360 // 6 seconds
#define CX10_PACKET_SIZE 15 #define CX10_PACKET_SIZE 15
@ -46,12 +46,12 @@ enum {
CX10_DATA CX10_DATA
}; };
static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) static void __attribute__((unused)) CX10_Write_Packet()
{ {
uint8_t offset = 0; uint8_t offset = 0;
if(sub_protocol == CX10_BLUE) if(sub_protocol == CX10_BLUE)
offset = 4; offset = 4;
packet[0] = bind ? 0xAA : 0x55; packet[0] = IS_BIND_IN_PROGRESS ? 0xAA : 0x55;
packet[1] = rx_tx_addr[0]; packet[1] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1]; packet[2] = rx_tx_addr[1];
packet[3] = rx_tx_addr[2]; 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 throttle=convert_channel_16b_limit(THROTTLE,1000,2000);
uint16_t rudder= convert_channel_16b_limit(RUDDER ,2000,1000); uint16_t rudder= convert_channel_16b_limit(RUDDER ,2000,1000);
// Channel 5 - flip flag // 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 // 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; flags = 0x02;
else else
if(Channel_data[CH6] < CHANNEL_MIN_COMMAND) if(Channel_data[CH6] < CHANNEL_MIN_COMMAND)
flags = 0x00; // rate 1 flags = 0x00; // rate 1
else else
flags = 0x01; // rate 2 flags = 0x01; // rate 2
uint8_t flags2=0; // packet 14 uint8_t flags2=0; // packet 14
uint8_t video_state=packet[14] & 0x21; uint8_t video_state=packet[14] & 0x21;
switch(sub_protocol) switch(sub_protocol)
{ {
case CX10_BLUE: case CX10_BLUE:
flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture
|GET_FLAG( CH8_SW, 0x08); // Channel 8 - video |GET_FLAG( CH8_SW, 0x08); // Channel 8 - video
break; break;
case F_Q282: case F_Q282:
case F_Q242: case F_Q242:
case F_Q222: case F_Q222:
memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6); memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6);
//FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL //FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP
|GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED |GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED
|GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS |GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS
|GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL |GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL
|GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509 |GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
if(sub_protocol==F_Q242) if(sub_protocol==F_Q242)
{ {
flags=2; flags=2;
flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture
|GET_FLAG(CH8_SW,0x10); // Channel 8 - video |GET_FLAG(CH8_SW,0x10); // Channel 8 - video
packet[17]=0x00; packet[17]=0x00;
packet[18]=0x00; packet[18]=0x00;
} }
else else
{ // F_Q282 & F_Q222 { // F_Q282 & F_Q222
flags=3; // expert flags=3; // expert
if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1 if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1
{ {
if (!(video_state & 0x20)) video_state ^= 0x21; if (!(video_state & 0x20)) video_state ^= 0x21;
} }
else else
if (video_state & 0x20) video_state &= 0x01; if (video_state & 0x20) video_state &= 0x01;
flags2 |= video_state 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; break;
case DM007: case DM007:
aileron = 3000 - aileron; 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; if(CH8_SW) packet[12] &= ~CX10_FLAG_FLIP;
case JC3015_1: case JC3015_1:
//FLIP|MODE|PICTURE|VIDEO //FLIP|MODE|PICTURE|VIDEO
flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7 flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7
|GET_FLAG(CH8_SW,_BV(4)); // Channel 8 |GET_FLAG(CH8_SW,_BV(4)); // Channel 8
break; break;
case MK33041: case MK33041:
elevator = 3000 - elevator; elevator = 3000 - elevator;
//FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH //FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture
|GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth |GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth
flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video
|GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless |GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless
break; break;
} }
packet[5+offset] = lowByte(aileron); packet[5+offset] = lowByte(aileron);
@ -151,32 +151,23 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
packet[13+offset]=flags; packet[13+offset]=flags;
packet[14+offset]=flags2; packet[14+offset]=flags2;
// Power on, TX mode, 2byte CRC // Send
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing if(IS_BIND_DONE)
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
{ {
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no %= CX10_NUM_RF_CHANNELS; hopping_frequency_no %= CX10_NUM_RF_CHANNELS;
} }
// clear packet status bits and TX FIFO XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
XN297_WritePayload(packet, packet_length); XN297_WritePayload(packet, packet_length);
NRF24L01_SetPower();
} }
static void __attribute__((unused)) CX10_RF_init() static void __attribute__((unused)) CX10_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5); XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", packet_length);
XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5); XN297_RFChannel(CX10_RF_BIND_CHANNEL);
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);
} }
uint16_t CX10_callback() uint16_t CX10_callback()
@ -190,43 +181,39 @@ uint16_t CX10_callback()
} }
else else
{ {
CX10_Write_Packet(1); CX10_Write_Packet();
bind_counter--; bind_counter--;
} }
break; break;
case CX10_BIND2: 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 { // RX fifo data ready
XN297_ReadPayload(packet, packet_length); debugln("RX");
NRF24L01_SetTxRxMode(TXRX_OFF); if(XN297_ReadPayload(packet, packet_length) && packet[9] == 1)
NRF24L01_SetTxRxMode(TX_EN);
if(packet[9] == 1)
{ {
BIND_DONE; BIND_DONE;
XN297_SetTxRxMode(TXRX_OFF);
phase = CX10_DATA; phase = CX10_DATA;
break;
} }
} }
else else
{ {
// switch to TX mode XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); CX10_Write_Packet();
NRF24L01_FlushTx();
NRF24L01_SetTxRxMode(TX_EN);
CX10_Write_Packet(1);
// wait for packet to be sent // wait for packet to be sent
while( (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) == 0); //delayMicroseconds(400); while( !XN297_IsPacketSent()); //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));
} }
// switch to RX mode
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
break; break;
case CX10_DATA: case CX10_DATA:
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(packet_period); telemetry_set_input_sync(packet_period);
#endif #endif
CX10_Write_Packet(0); CX10_Write_Packet();
break; break;
} }
return packet_period; return packet_period;

View File

@ -16,7 +16,7 @@
#if defined(DM002_NRF24L01_INO) #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_PACKET_PERIOD 6100 // Timeout for callback in uSec
#define DM002_INITIAL_WAIT 500 #define DM002_INITIAL_WAIT 500
@ -24,7 +24,6 @@
#define DM002_RF_BIND_CHANNEL 0x27 #define DM002_RF_BIND_CHANNEL 0x27
#define DM002_BIND_COUNT 655 // 4 seconds #define DM002_BIND_COUNT 655 // 4 seconds
enum DM002_FLAGS { enum DM002_FLAGS {
// flags going to packet[9] // flags going to packet[9]
DM002_FLAG_FLIP = 0x01, DM002_FLAG_FLIP = 0x01,
@ -75,28 +74,23 @@ static void __attribute__((unused)) DM002_send_packet()
packet_count&=0x0F; packet_count&=0x0F;
packet[10] = packet_count; packet[10] = packet_count;
packet_count++; packet_count++;
XN297_Hopping(hopping_frequency_no);
} }
//CRC //CRC
for(uint8_t i=0;i<DM002_PACKET_SIZE-1;i++) for(uint8_t i=0;i<DM002_PACKET_SIZE-1;i++)
packet[11]+=packet[i]; packet[11]+=packet[i];
// Power on, TX mode, 2byte CRC //Send
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing XN297_SetPower();
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetTxRxMode(TX_EN);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? DM002_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no]);
// clear packet status bits and TX FIFO
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, DM002_PACKET_SIZE); XN297_WritePayload(packet, DM002_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) DM002_RF_init() static void __attribute__((unused)) DM002_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5);
XN297_RFChannel(DM002_RF_BIND_CHANNEL);
} }
uint16_t DM002_callback() uint16_t DM002_callback()

View File

@ -0,0 +1,154 @@
/*
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 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<E016H_NUM_CHANNELS; i++)
{
hopping_frequency[i] = (lfsr & 0xFF) % 80;
lfsr>>=8;
}
}
void E016H_init()
{
BIND_IN_PROGRESS;
E016H_initialize_txid();
E016H_RF_init();
bind_counter = E016H_BIND_COUNT;
hopping_frequency_no = 0;
}
#endif

View File

@ -33,11 +33,6 @@
#define E015_PACKET_SIZE 10 #define E015_PACKET_SIZE 10
#define E015_BIND_PACKET_SIZE 9 #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 //Channels
#define E01X_ARM_SW CH5_SW #define E01X_ARM_SW CH5_SW
#define E016H_STOP_SW CH5_SW #define E016H_STOP_SW CH5_SW
@ -64,17 +59,6 @@
#define E015_FLAG_EXPERT 0x02 #define E015_FLAG_EXPERT 0x02
#define E015_FLAG_INTERMEDIATE 0x01 #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() static void __attribute__((unused)) E015_check_arming()
{ {
uint8_t arm_channel = E01X_ARM_SW; 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() static void __attribute__((unused)) E01X_send_packet()
{ {
uint8_t can_flip = 0, calibrate = 1;
if(sub_protocol==E012) if(sub_protocol==E012)
{ {
packet_length=E012_PACKET_SIZE; packet_length=E012_PACKET_SIZE;
@ -132,7 +115,7 @@ static void __attribute__((unused)) E01X_send_packet()
packet[13] = 0x56; packet[13] = 0x56;
packet[14] = rx_tx_addr[2]; packet[14] = rx_tx_addr[2];
} }
else if(sub_protocol==E015) else
{ // E015 { // E015
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
@ -170,72 +153,14 @@ static void __attribute__((unused)) E01X_send_packet()
packet_length=E015_PACKET_SIZE; 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 HS6200_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
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));
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num); NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx(); NRF24L01_FlushTx();
if(sub_protocol==E016H) HS6200_WritePayload(packet, packet_length);
XN297_WritePayload(packet, packet_length);
else
HS6200_WritePayload(packet, packet_length);
// Check and adjust transmission power. We do this after // Check and adjust transmission power. We do this after
// transmission to not bother with timeout after power // transmission to not bother with timeout after power
@ -250,10 +175,8 @@ static void __attribute__((unused)) E01X_RF_init()
if(sub_protocol==E012) if(sub_protocol==E012)
HS6200_SetTXAddr((uint8_t *)"\x55\x42\x9C\x8F\xC9", E01X_ADDRESS_LENGTH); 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); 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() uint16_t E01X_callback()
@ -266,10 +189,7 @@ uint16_t E01X_callback()
bind_counter--; bind_counter--;
if (bind_counter == 0) if (bind_counter == 0)
{ {
if(sub_protocol==E016H) HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
XN297_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
else
HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
BIND_DONE; 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<E016H_NUM_CHANNELS; i++)
{
hopping_frequency[i] = (lfsr & 0xFF) % 80;
lfsr>>=8;
}
}
void E01X_init() void E01X_init()
{ {
BIND_IN_PROGRESS; BIND_IN_PROGRESS;
@ -311,7 +216,7 @@ void E01X_init()
E012_initialize_txid(); E012_initialize_txid();
packet_period=E012_PACKET_PERIOD; packet_period=E012_PACKET_PERIOD;
} }
else if(sub_protocol==E015) else //E015
{ {
packet_period=E015_PACKET_PERIOD; packet_period=E015_PACKET_PERIOD;
rf_ch_num=E015_RF_CHANNEL; rf_ch_num=E015_RF_CHANNEL;
@ -319,11 +224,6 @@ void E01X_init()
arm_flags = 0; arm_flags = 0;
arm_channel_previous = E01X_ARM_SW; arm_channel_previous = E01X_ARM_SW;
} }
else
{ // E016H
E016H_initialize_txid();
packet_period=E016H_PACKET_PERIOD;
}
E01X_RF_init(); E01X_RF_init();
bind_counter = E01X_BIND_COUNT; bind_counter = E01X_BIND_COUNT;
hopping_frequency_no = 0; hopping_frequency_no = 0;

View File

@ -15,7 +15,7 @@
#if defined(ESKY150V2_CC2500_INO) #if defined(ESKY150V2_CC2500_INO)
#include "iface_cc2500.h" #include "iface_nrf250k.h"
//#define ESKY150V2_FORCE_ID //#define ESKY150V2_FORCE_ID
@ -74,7 +74,7 @@ static void __attribute__((unused)) ESKY150V2_send_packet()
packet[4+2*i] = channel; packet[4+2*i] = channel;
packet[5+2*i] = channel>>8; packet[5+2*i] = channel>>8;
} }
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_PAYLOADSIZE); NRF250K_WritePayload(packet, ESKY150V2_PAYLOADSIZE);
} }
uint16_t ESKY150V2_callback() uint16_t ESKY150V2_callback()
@ -91,12 +91,12 @@ uint16_t ESKY150V2_callback()
BIND_DONE; //Need full power for bind to work... BIND_DONE; //Need full power for bind to work...
CC2500_SetPower(); //Set power level CC2500_SetPower(); //Set power level
BIND_IN_PROGRESS; BIND_IN_PROGRESS;
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE); NRF250K_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE);
if (--bind_counter == 0) if (--bind_counter == 0)
{ {
BIND_DONE; BIND_DONE;
// Change TX address from bind to normal mode // 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); memset(packet,0x00,ESKY150V2_PAYLOADSIZE);
} }
return 30000; //ESKY150V2_BINDING_PACKET_PERIOD; return 30000; //ESKY150V2_BINDING_PACKET_PERIOD;
@ -118,7 +118,7 @@ void ESKY150V2_init()
if(IS_BIND_IN_PROGRESS) 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 CC2500_250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel
memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE);
memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE); memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE);
@ -132,7 +132,7 @@ void ESKY150V2_init()
bind_counter=100; bind_counter=100;
} }
else else
CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
} }
#endif #endif

View File

@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#if defined(FX816_NRF24L01_INO) #if defined(FX816_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define FX816_INITIAL_WAIT 500 #define FX816_INITIAL_WAIT 500
#define FX816_PACKET_PERIOD 10000 #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() 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[1] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1]; packet[2] = rx_tx_addr[1];
uint8_t val=convert_channel_8b(AILERON); uint8_t val=convert_channel_8b(AILERON);
@ -44,25 +51,18 @@ static void __attribute__((unused)) FX816_send_packet()
val+=packet[i]; val+=packet[i];
packet[5]=val; packet[5]=val;
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? FX816_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]); // Send
hopping_frequency_no%=FX816_RF_NUM_CHANNELS; XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
// clear packet status bits and TX FIFO
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, FX816_PAYLOAD_SIZE); 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() 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_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() static void __attribute__((unused)) FX816_initialize_txid()

View File

@ -113,7 +113,7 @@ static void __attribute__((unused)) GD00X_send_packet()
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {
XN297L_Hopping(hopping_frequency_no); XN297_Hopping(hopping_frequency_no);
if(sub_protocol==GD_V1) if(sub_protocol==GD_V1)
{ {
hopping_frequency_no++; hopping_frequency_no++;
@ -121,21 +121,22 @@ static void __attribute__((unused)) GD00X_send_packet()
} }
} }
XN297L_WritePayload(packet, packet_length); // Send
XN297_SetFreqOffset();
XN297L_SetPower(); // Set tx_power XN297_SetPower();
XN297L_SetFreqOffset(); // Set frequency offset XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, packet_length);
} }
static void __attribute__((unused)) GD00X_RF_init() static void __attribute__((unused)) GD00X_RF_init()
{ {
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
if(sub_protocol==GD_V1) 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 else
XN297L_SetTXAddr((uint8_t*)"GDKNx", 5); XN297_SetTXAddr((uint8_t*)"GDKNx", 5);
XN297L_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels XN297_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_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel
} }
static void __attribute__((unused)) GD00X_initialize_txid() static void __attribute__((unused)) GD00X_initialize_txid()

View File

@ -19,7 +19,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#if defined(GW008_NRF24L01_INO) #if defined(GW008_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define GW008_INITIAL_WAIT 500 #define GW008_INITIAL_WAIT 500
#define GW008_PACKET_PERIOD 2400 #define GW008_PACKET_PERIOD 2400
@ -47,6 +47,9 @@ static void __attribute__((unused)) GW008_send_packet()
} }
else else
{ {
XN297_Hopping((hopping_frequency_no++)/2);
hopping_frequency_no %= 8;
packet[1] = 0x01 | GET_FLAG(CH5_SW, 0x40); // flip packet[1] = 0x01 | GET_FLAG(CH5_SW, 0x40); // flip
packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator 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]; packet[14] = rx_tx_addr[1];
// Power on, TX mode, CRC enabled // Send
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? GW008_RF_BIND_CHANNEL : hopping_frequency[(hopping_frequency_no++)/2]); XN297_SetTxRxMode(TX_EN);
hopping_frequency_no %= 8;
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0); XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) GW008_RF_init() 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_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5); XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", GW008_PAYLOAD_SIZE);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, GW008_PAYLOAD_SIZE+2); // payload + 2 bytes for pcf
//XN297_HoppingCalib(8);
XN297_RFChannel(GW008_RF_BIND_CHANNEL);
} }
static void __attribute__((unused)) GW008_initialize_txid() static void __attribute__((unused)) GW008_initialize_txid()
@ -96,20 +95,20 @@ uint16_t GW008_callback()
switch(phase) switch(phase)
{ {
case GW008_BIND1: 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 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 packet[0] == rx_tx_addr[0] && packet[14] == rx_tx_addr[1]) // check tx id
{ {
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN); XN297_SetTxRxMode(TX_EN);
rx_tx_addr[2] = packet[13]; rx_tx_addr[2] = packet[13];
BIND_DONE; BIND_DONE;
phase = GW008_DATA; phase = GW008_DATA;
} }
else else
{ {
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN); XN297_SetTxRxMode(TX_EN);
GW008_send_packet(); GW008_send_packet();
phase = GW008_BIND2; phase = GW008_BIND2;
return 850; // minimum value 750 for STM32 return 850; // minimum value 750 for STM32
@ -117,14 +116,10 @@ uint16_t GW008_callback()
break; break;
case GW008_BIND2: case GW008_BIND2:
// switch to RX mode // switch to RX mode
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_FlushRx(); XN297_SetTxRxMode(RX_EN);
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));
phase = GW008_BIND1; phase = GW008_BIND1;
return 5000; return 5000;
break;
case GW008_DATA: case GW008_DATA:
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(GW008_PACKET_PERIOD); telemetry_set_input_sync(GW008_PACKET_PERIOD);

View File

@ -19,7 +19,7 @@
#if defined(H8_3D_NRF24L01_INO) #if defined(H8_3D_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_xn297.h"
#define H8_3D_PACKET_PERIOD 1800 #define H8_3D_PACKET_PERIOD 1800
#define H20H_PACKET_PERIOD 9340 #define H20H_PACKET_PERIOD 9340
@ -122,17 +122,15 @@ static void __attribute__((unused)) H8_3D_send_packet()
sum += packet[i]; sum += packet[i];
packet[19] = sum; // data checksum packet[19] = sum; // data checksum
// Power on, TX mode, 2byte CRC // RF channel
// 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(sub_protocol!=H20H) if(sub_protocol!=H20H)
{ // H8_3D, H20MINI, H30MINI { // 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; hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS;
} }
else else
{ //H20H { // H20H
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? H20H_BIND_RF : hopping_frequency[packet_count>>3]); XN297_RFChannel(IS_BIND_IN_PROGRESS ? H20H_BIND_RF : hopping_frequency[packet_count>>3]);
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {
packet_count++; packet_count++;
@ -147,17 +145,15 @@ static void __attribute__((unused)) H8_3D_send_packet()
} }
} }
// clear packet status bits and TX FIFO // Send
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetPower();
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, H8_3D_PACKET_SIZE); XN297_WritePayload(packet, H8_3D_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) H8_3D_RF_init() static void __attribute__((unused)) H8_3D_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
if(sub_protocol==H20H) if(sub_protocol==H20H)
XN297_SetTXAddr((uint8_t *)"\xEE\xDD\xCC\xBB\x11", 5); XN297_SetTXAddr((uint8_t *)"\xEE\xDD\xCC\xBB\x11", 5);

View File

@ -15,7 +15,7 @@
#if defined(HONTAI_NRF24L01_INO) #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_BIND_COUNT 80
#define HONTAI_PACKET_PERIOD 13500 #define HONTAI_PACKET_PERIOD 13500
@ -44,6 +44,11 @@ static void __attribute__((unused)) HONTAI_send_packet()
} }
else 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); memset(packet,0,HONTAI_PACKET_SIZE);
packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle
packet[4] = convert_channel_16b_limit(AILERON, 63, 0); // Aileron 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); packet[packet_length-1]=bit_reverse(crc);
// Power on, TX mode, 2byte CRC // Power on, TX mode, 2byte CRC
if(sub_protocol == JJRCX1) /*if(sub_protocol == JJRCX1)
{
NRF24L01_SetPower();
NRF24L01_SetTxRxMode(TX_EN); NRF24L01_SetTxRxMode(TX_EN);
else NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_FlushTx();
}
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]); else*/
hopping_frequency_no %= 3; {
XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetTxRxMode(TX_EN);
NRF24L01_FlushTx(); }
if(sub_protocol == JJRCX1) if(sub_protocol == JJRCX1)
NRF24L01_WritePayload(packet, packet_length); NRF24L01_WritePayload(packet, packet_length);
else else
XN297_WritePayload(packet, packet_length); XN297_WritePayload(packet, packet_length);
NRF24L01_SetPower();
} }
static void __attribute__((unused)) HONTAI_RF_init() 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) 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_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_1C_DYNPD, 0x3f); // match other stock settings even though AA disabled...
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
//NRF24L01_WriteReg(NRF24L01_05_RF_CH, HONTAI_RF_BIND_CHANNEL);
} }
else
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX {
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] = { 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[3] = pgm_read_byte_near( &HONTAI_addr_vals[3][(rx_tx_addr[4] >> 4) & 0x0f]);
data_tx_addr[4] = 0x24; data_tx_addr[4] = 0x24;
if(sub_protocol == JJRCX1) 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 else
XN297_SetTXAddr(data_tx_addr, sizeof(data_tx_addr)); XN297_SetTXAddr(data_tx_addr, 5);
//Hopping frequency table //Hopping frequency table
for(uint8_t i=0;i<3;i++) for(uint8_t i=0;i<3;i++)

View File

@ -71,7 +71,7 @@ static void __attribute__((unused)) JJRC345_send_packet()
} }
else else
{ //00 41 00 0A 00 80 80 80 00 00 40 46 00 49 F1 18 { //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++;
hopping_frequency_no %= JJRC345_NUM_CHANNELS; hopping_frequency_no %= JJRC345_NUM_CHANNELS;
packet[1] = hopping_frequency[hopping_frequency_no]; // next packet will be sent on this channel 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[14] = rx_tx_addr[2];
packet[15] = rx_tx_addr[3]; packet[15] = rx_tx_addr[3];
// Power on, TX mode // Send
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
XN297_WritePayload(packet, JJRC345_PACKET_SIZE); XN297_WritePayload(packet, JJRC345_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) JJRC345_RF_init() 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); 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() uint16_t JJRC345_callback()

View File

@ -45,14 +45,15 @@ static void __attribute__((unused)) KF606_send_packet()
} }
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {
XN297L_Hopping(hopping_frequency_no); XN297_Hopping(hopping_frequency_no);
hopping_frequency_no ^= 1; // 2 RF channels hopping_frequency_no ^= 1; // 2 RF channels
} }
XN297L_WritePayload(packet, KF606_PAYLOAD_SIZE); // Send
XN297_SetPower();
XN297L_SetPower(); // Set tx_power XN297_SetFreqOffset();
XN297L_SetFreqOffset(); // Set frequency offset XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, KF606_PAYLOAD_SIZE);
} }
static void __attribute__((unused)) KF606_initialize_txid() 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() static void __attribute__((unused)) KF606_RF_init()
{ {
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
XN297L_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5); XN297_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5);
XN297L_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels XN297_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels
XN297L_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel XN297_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel
} }
uint16_t KF606_callback() uint16_t KF606_callback()
@ -93,7 +94,7 @@ uint16_t KF606_callback()
if(--bind_counter==0) if(--bind_counter==0)
{ {
BIND_DONE; BIND_DONE;
XN297L_SetTXAddr(rx_tx_addr, 3); XN297_SetTXAddr(rx_tx_addr, 3);
} }
KF606_send_packet(); KF606_send_packet();
return KF606_PACKET_PERIOD; return KF606_PACKET_PERIOD;

View File

@ -15,10 +15,9 @@
// compatible with MJX WLH08, X600, X800, H26D, Eachine E010 // compatible with MJX WLH08, X600, X800, H26D, Eachine E010
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17 // 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_xn297.h"
#include "iface_nrf250k.h"
#define MJXQ_BIND_COUNT 150 #define MJXQ_BIND_COUNT 150
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec #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) #define MJXQ_CHAN2TRIM(X) (((X) & 0x80 ? (X) : 0x7f - (X)) >> 1)
static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) 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[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_s8b(RUDDER); packet[1] = convert_channel_s8b(RUDDER);
packet[4] = 0x40; // rudder does not work well with dyntrim 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]; uint8_t sum = packet[0];
for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i]; for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i];
packet[15] = sum; 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); //NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]);
XN297L_SetFreqOffset(); //NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
XN297L_SetPower(); //NRF24L01_FlushTx();
XN297L_WritePayload(packet, MJXQ_PACKET_SIZE); //NRF24L01_SetTxRxMode(TX_EN);
//NRF24L01_SetPower();
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
} }
else else
{ #endif
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]); {//E010, PHOENIX, WLH08, X600, X800
XN297_SetFreqOffset();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
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();
} }
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
} }
static void __attribute__((unused)) MJXQ_RF_init() 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) if (sub_protocol == E010 || sub_protocol == PHOENIX)
{ {
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
XN297L_SetTXAddr(addr, sizeof(addr)); XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS); XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
} }
else 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) if (sub_protocol == H26D || sub_protocol == H26WH)
{
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
}
else else
#endif
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH); XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
//NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // no RX???
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE);
} }
} }
@ -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]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]&0x0F][i] );
hopping_frequency[i+2]=hopping_frequency[i]+0x10; hopping_frequency[i+2]=hopping_frequency[i]+0x10;
} }
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS); XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
break; break;
case WLH08: case WLH08:
// do nothing // do nothing

View File

@ -15,10 +15,9 @@
// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124 // compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29 // 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_xn297.h"
#include "iface_nrf250k.h"
#define MT99XX_BIND_COUNT 928 #define MT99XX_BIND_COUNT 928
#define MT99XX_PACKET_PERIOD_FY805 2460 #define MT99XX_PACKET_PERIOD_FY805 2460
@ -246,17 +245,14 @@ static void __attribute__((unused)) MT99XX_send_packet()
} }
} }
//RF freq
if(sub_protocol == LS) 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 else
if(sub_protocol==FY805) 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 else // MT99 & H7 & YZ & A180 & DRAGON
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); XN297_Hopping(hopping_frequency_no);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
if(sub_protocol == DRAGON) if(sub_protocol == DRAGON)
{ {
@ -269,23 +265,24 @@ static void __attribute__((unused)) MT99XX_send_packet()
hopping_frequency_no++; hopping_frequency_no++;
if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON ) if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON )
hopping_frequency_no++; // skip every other channel hopping_frequency_no++; // skip every other channel
if(hopping_frequency_no > 15) if(hopping_frequency_no > 15)
hopping_frequency_no = 0; 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() static void __attribute__((unused)) MT99XX_RF_init()
{ {
NRF24L01_Initialize();
if(sub_protocol == YZ) 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); XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
if(sub_protocol == YZ) XN297_HoppingCalib(16);
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps (nRF24L01+ only)
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) );
} }
static void __attribute__((unused)) MT99XX_initialize_txid() static void __attribute__((unused)) MT99XX_initialize_txid()
@ -360,6 +357,7 @@ uint16_t MT99XX_callback()
uint8_t channel_offset = ((crc8>>4) + (crc8 & 0x0f)) % 8; uint8_t channel_offset = ((crc8>>4) + (crc8 & 0x0f)) % 8;
for(uint8_t i=0;i<16;i++) for(uint8_t i=0;i<16;i++)
hopping_frequency[i] += channel_offset; hopping_frequency[i] += channel_offset;
XN297_HoppingCalib(16);
BIND_DONE; BIND_DONE;
} }
} }

View File

@ -42,7 +42,7 @@
42,BUGSMINI,BUGSMINI,BUGS3H 42,BUGSMINI,BUGSMINI,BUGS3H
43,Traxxas,RX6519 43,Traxxas,RX6519
44,NCC1701 44,NCC1701
45,E01X,E012,E015,E016H 45,E01X,E012,E015
46,V911S,V911S,E119 46,V911S,V911S,E119
47,GD00x,GD_V1,GD_V2 47,GD00x,GD_V1,GD_V2
48,V761,3CH,4CH 48,V761,3CH,4CH
@ -81,4 +81,5 @@
81,E010r5 81,E010r5
82,LOLI 82,LOLI
83,E129 83,E129
84,JOYSWAY 84,JOYSWAY
85,E016H

View File

@ -97,6 +97,7 @@ const char STR_E016HV2[] ="E016Hv2";
const char STR_E010R5[] ="E010r5"; const char STR_E010R5[] ="E010r5";
const char STR_LOLI[] ="LOLI"; const char STR_LOLI[] ="LOLI";
const char STR_E129[] ="E129"; 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_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501"; const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@ -233,6 +234,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(E010R5_CYRF6936_INO) #if defined(E010R5_CYRF6936_INO)
{PROTO_E010R5, STR_E010R5, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E010R5_init, E010R5_callback }, {PROTO_E010R5, STR_E010R5, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E010R5_init, E010R5_callback },
#endif #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) #if defined(E016HV2_CC2500_INO)
{PROTO_E016HV2, STR_E016HV2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_CC2500, E016HV2_init, E016HV2_callback }, {PROTO_E016HV2, STR_E016HV2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_CC2500, E016HV2_init, E016HV2_callback },
#endif #endif
@ -345,20 +349,20 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(LOLI_NRF24L01_INO) #if defined(LOLI_NRF24L01_INO)
{PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback }, {PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback },
#endif #endif
#if defined(MJXQ_NRF24L01_INO) #if defined(MJXQ_CCNRF_INO)
{PROTO_MJXQ, STR_MJXQ, STR_SUBTYPE_MJXQ, 7, OPTION_RFTUNE, 0, 0, SW_NRF, MJXQ_init, MJXQ_callback }, {PROTO_MJXQ, STR_MJXQ, STR_SUBTYPE_MJXQ, 7, OPTION_NONE, 0, 0, SW_NRF, MJXQ_init, MJXQ_callback },
#endif #endif
#if defined(MLINK_CYRF6936_INO) #if defined(MLINK_CYRF6936_INO)
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback }, {PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
#endif #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 }, {PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 7, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
#endif #endif
#if defined(NCC1701_NRF24L01_INO) #if defined(NCC1701_NRF24L01_INO)
{PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback }, {PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback },
#endif #endif
#if defined(OMP_CC2500_INO) #if defined(OMP_CCNRF_INO)
{PROTO_OMP, STR_OMP, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, OMP_init, OMP_callback }, {PROTO_OMP, STR_OMP, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, OMP_init, OMP_callback },
#endif #endif
#if defined(PELIKAN_A7105_INO) #if defined(PELIKAN_A7105_INO)
{PROTO_PELIKAN, STR_PELIKAN, STR_SUBTYPE_PELIKAN, 2, OPTION_NONE, 0, 1, SW_A7105, PELIKAN_init, PELIKAN_callback }, {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) #if defined(CX10_NRF24L01_INO)
{PROTO_Q2X2, STR_Q2X2, STR_SUBTYPE_Q2X2, 3, OPTION_NONE, 0, 0, SW_NRF, CX10_init, CX10_callback }, {PROTO_Q2X2, STR_Q2X2, STR_SUBTYPE_Q2X2, 3, OPTION_NONE, 0, 0, SW_NRF, CX10_init, CX10_callback },
#endif #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 }, {PROTO_Q303, STR_Q303, STR_SUBTYPE_Q303, 4, OPTION_NONE, 0, 0, SW_NRF, Q303_init, Q303_callback },
#endif #endif
#if defined(Q90C_CCNRF_INO) #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_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... // {PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_WBUS, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },// crash OpenTX...
#endif #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 }, {PROTO_XK, STR_XK, STR_SUBTYPE_XK, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
#endif #endif
#if defined(XN297DUMP_NRF24L01_INO) #if defined(XN297DUMP_NRF24L01_INO)

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 2 #define VERSION_REVISION 2
#define VERSION_PATCH_LEVEL 61 #define VERSION_PATCH_LEVEL 62
#define MODE_SERIAL 0 #define MODE_SERIAL 0
@ -112,6 +112,7 @@ enum PROTOCOLS
PROTO_LOLI = 82, // =>NRF24L01 PROTO_LOLI = 82, // =>NRF24L01
PROTO_E129 = 83, // =>CYRF6936 PROTO_E129 = 83, // =>CYRF6936
PROTO_JOYSWAY = 84, // =>A7105 PROTO_JOYSWAY = 84, // =>A7105
PROTO_E016H = 85, // =>NRF24L01
PROTO_NANORF = 126, // =>NRF24L01 PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500 PROTO_TEST = 127, // =>CC2500
@ -587,6 +588,11 @@ enum MultiPacketTypes
#define DISABLE_TELEM_on protocol_flags3 |= _BV(3) #define DISABLE_TELEM_on protocol_flags3 |= _BV(3)
#define IS_DISABLE_TELEM_on ( ( protocol_flags3 & _BV(3) ) !=0 ) #define IS_DISABLE_TELEM_on ( ( protocol_flags3 & _BV(3) ) !=0 )
#define IS_DISABLE_TELEM_off ( ( 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 //LBT power
#define LBT_POWER_off protocol_flags3 &= ~_BV(7) #define LBT_POWER_off protocol_flags3 &= ~_BV(7)
#define LBT_POWER_on 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 E010R5 81
LOLI 82 LOLI 82
E129 83 E129 83
JOYSWAY 84
E016H 85
BindBit=> 0x80 1=Bind/0=No BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No
@ -1035,7 +1043,6 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
sub_protocol==E01X sub_protocol==E01X
E012 0 E012 0
E015 1 E015 1
E016H 2
sub_protocol==GD00X sub_protocol==GD00X
GD_V1 0 GD_V1 0
GD_V2 1 GD_V2 1

View File

@ -158,6 +158,7 @@ uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, CH5, CH6, CH7, CH8, CH9,
// Mode_select variables // Mode_select variables
uint8_t mode_select; uint8_t mode_select;
uint8_t protocol_flags=0,protocol_flags2=0,protocol_flags3=0; uint8_t protocol_flags=0,protocol_flags2=0,protocol_flags3=0;
uint8_t option_override;
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
// PPM variable // PPM variable
@ -1179,6 +1180,9 @@ static void protocol_init()
FAILSAFE_VALUES_off; FAILSAFE_VALUES_off;
#endif #endif
DATA_BUFFER_LOW_off; DATA_BUFFER_LOW_off;
SUB_PROTO_VALID;
option_override = 0xFF;
blink=millis(); blink=millis();

View File

@ -28,7 +28,6 @@ void NRF24L01_Initialize()
{ {
rf_setup = 0x09; rf_setup = 0x09;
prev_power = 0x00; // Make sure prev_power is inline with current power prev_power = 0x00; // Make sure prev_power is inline with current power
XN297_SetScrambledMode(XN297_SCRAMBLED);
//Load most likely default NRF config //Load most likely default NRF config
NRF24L01_FlushTx(); NRF24L01_FlushTx();
@ -196,11 +195,11 @@ void NRF24L01_SetPower()
void NRF24L01_SetTxRxMode(enum TXRX_State mode) 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) { if(mode == TX_EN) {
NRF_CE_off; 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 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to TX mode
| (1 << NRF24L01_00_CRCO) | (1 << NRF24L01_00_CRCO)
| (1 << NRF24L01_00_PWR_UP)); | (1 << NRF24L01_00_PWR_UP));
@ -211,9 +210,6 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
if (mode == RX_EN) if (mode == RX_EN)
{ {
NRF_CE_off; 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 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to RX mode
| (1 << NRF24L01_00_CRCO) | (1 << NRF24L01_00_CRCO)
| (1 << NRF24L01_00_PWR_UP) | (1 << NRF24L01_00_PWR_UP)

View File

@ -15,223 +15,16 @@
#if defined(CC2500_INSTALLED) || defined(NRF24L01_INSTALLED) #if defined(CC2500_INSTALLED) || defined(NRF24L01_INSTALLED)
#include "iface_nrf250k.h" #include "iface_nrf250k.h"
#include "iface_xn297.h"
static void __attribute__((unused)) XN297L_Init() uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len;
{
//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
}
static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len) static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len)
{ {
if (len > 5) len = 5; if (len > 5) len = 5;
if (len < 3) len = 3; if (len < 3) len = 3;
#if defined(CC2500_INSTALLED) #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) #elif defined(NRF24L01_INSTALLED)
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, len); 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) static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t len)
{ {
#if defined(CC2500_INSTALLED) #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;i<last;i++)
// debug("%02X ",buf[i]);
//debugln("");
// stop TX/RX
CC2500_Strobe(CC2500_SIDLE);
// flush tx FIFO
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_3F_TXFIFO, last);
// transmit nrf packet
uint8_t *buff=buf;
uint8_t status;
if(last>63)
{
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) #elif defined(NRF24L01_INSTALLED)
NRF24L01_FlushTx(); if(len<=32)
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT)); {
NRF24L01_WritePayload(msg, len); 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 #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 #endif

View File

@ -13,13 +13,9 @@ Multiprotocol is distributed in the hope that it will be useful,
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if defined(OMP_CC2500_INO) #if defined(OMP_CCNRF_INO)
#ifndef NRF24L01_INSTALLED #include "iface_xn297.h"
#undef OMP_HUB_TELEMETRY
#endif
#include "iface_nrf250k.h"
//#define FORCE_OMP_ORIGINAL_ID //#define FORCE_OMP_ORIGINAL_ID
//#define OMP_TELEM_DEBUG //#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() static void __attribute__((unused)) OMP_send_packet()
{ {
#ifdef OMP_HUB_TELEMETRY
rf_switch(SW_CC2500);
#endif
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
memcpy(packet,"BND",3); memcpy(packet,"BND",3);
@ -52,15 +44,12 @@ static void __attribute__((unused)) OMP_send_packet()
packet_sent++; packet_sent++;
packet_sent %= OMP_RF_NUM_CHANNELS-1; // Change telem RX channels every time packet_sent %= OMP_RF_NUM_CHANNELS-1; // Change telem RX channels every time
if(packet_sent==0) if(packet_sent==0)
{
packet[0] |= 0x40; // |0x40 to request RX telemetry packet[0] |= 0x40; // |0x40 to request RX telemetry
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
}
#endif #endif
//hopping frequency //hopping frequency
packet[0 ] |= hopping_frequency_no; packet[0 ] |= hopping_frequency_no;
XN297L_Hopping(hopping_frequency_no); XN297_Hopping(hopping_frequency_no);
hopping_frequency_no++; hopping_frequency_no++;
hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels 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; packet[15] = 0x04;
} }
XN297L_SetPower(); // Set tx_power XN297_SetPower(); // Set tx_power
XN297L_SetFreqOffset(); // Set frequency offset XN297_SetFreqOffset(); // Set frequency offset
XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0); XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0);
} }
static void __attribute__((unused)) OMP_RF_init() static void __attribute__((unused)) OMP_RF_init()
{ {
//Config CC2500 //Config CC2500
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
XN297L_SetTXAddr((uint8_t*)"FLPBD", 5); XN297_SetTXAddr((uint8_t*)"FLPBD", 5);
XN297L_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels XN297_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels
XN297L_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel XN297_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel
#ifdef OMP_HUB_TELEMETRY #ifdef OMP_HUB_TELEMETRY
//Config NRF XN297_SetRXAddr(rx_tx_addr, OMP_PAYLOAD_SIZE);
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
#endif #endif
} }
@ -167,6 +151,8 @@ enum {
uint16_t OMP_callback() uint16_t OMP_callback()
{ {
bool rx;
switch(phase) switch(phase)
{ {
case OMP_BIND: case OMP_BIND:
@ -176,12 +162,15 @@ uint16_t OMP_callback()
return OMP_PACKET_PERIOD; return OMP_PACKET_PERIOD;
case OMP_PREPDATA: case OMP_PREPDATA:
BIND_DONE; BIND_DONE;
XN297L_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
phase++; // OMP_DATA phase++; // OMP_DATA
case OMP_DATA: case OMP_DATA:
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(OMP_PACKET_PERIOD); telemetry_set_input_sync(OMP_PACKET_PERIOD);
#endif #endif
#ifdef OMP_HUB_TELEMETRY
rx = XN297_IsRX(); // Needed for the NRF24L01 since otherwise the bit gets cleared
#endif
OMP_send_packet(); OMP_send_packet();
#ifdef OMP_HUB_TELEMETRY #ifdef OMP_HUB_TELEMETRY
if(packet_sent == 0) if(packet_sent == 0)
@ -191,8 +180,11 @@ uint16_t OMP_callback()
} }
else if(packet_sent == 1) else if(packet_sent == 1)
{ {
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( rx )
{ // a packet has been received { // a packet has been received
#ifdef OMP_TELEM_DEBUG
debug("RX :");
#endif
if(XN297_ReadEnhancedPayload(packet_in, OMP_PAYLOAD_SIZE) == OMP_PAYLOAD_SIZE) if(XN297_ReadEnhancedPayload(packet_in, OMP_PAYLOAD_SIZE) == OMP_PAYLOAD_SIZE)
{ // packet with good CRC and length { // packet with good CRC and length
#ifdef OMP_TELEM_DEBUG #ifdef OMP_TELEM_DEBUG
@ -238,7 +230,7 @@ uint16_t OMP_callback()
debugln(""); debugln("");
#endif #endif
} }
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(TXRX_OFF);
packet_count++; packet_count++;
if(packet_count>=100) if(packet_count>=100)
{//LQI calculation {//LQI calculation
@ -254,21 +246,15 @@ uint16_t OMP_callback()
return OMP_PACKET_PERIOD; return OMP_PACKET_PERIOD;
#ifdef OMP_HUB_TELEMETRY #ifdef OMP_HUB_TELEMETRY
case OMP_RX: 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(); uint16_t start=(uint16_t)micros();
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500) while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
{ {
if(CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13) if(XN297_IsPacketSent())
break; break;
} }
} }
NRF_CE_on; XN297_SetTxRxMode(RX_EN);
rf_switch(SW_NRF);
phase = OMP_DATA; phase = OMP_DATA;
return OMP_PACKET_PERIOD-OMP_WRITE_TIME; return OMP_PACKET_PERIOD-OMP_WRITE_TIME;
#endif #endif

View File

@ -61,19 +61,20 @@ static void __attribute__((unused)) POTENSIC_send_packet()
} }
POTENSIC_set_checksum(); POTENSIC_set_checksum();
packet[9] = hopping_frequency_no; 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++; 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)); // Send
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetPower();
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, POTENSIC_PACKET_SIZE); XN297_WritePayload(packet, POTENSIC_PACKET_SIZE);
NRF24L01_SetPower();
} }
static void __attribute__((unused)) POTENSIC_RF_init() static void __attribute__((unused)) POTENSIC_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
XN297_SetTXAddr((uint8_t*)"\x01\x01\x01\x01\x06", 5); // Bind address XN297_SetTXAddr((uint8_t*)"\x01\x01\x01\x01\x06", 5); // Bind address

View File

@ -13,7 +13,7 @@
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if defined(Q303_NRF24L01_INO) #if defined(Q303_CCNRF_INO)
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
@ -185,6 +185,11 @@ static void __attribute__((unused)) Q303_send_packet()
} }
else else
{ {
//RF freq
XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no %= rf_ch_num;
//Build packet
packet[0] = 0x55; packet[0] = 0x55;
// sticks // sticks
switch(sub_protocol) switch(sub_protocol)
@ -267,32 +272,27 @@ static void __attribute__((unused)) Q303_send_packet()
} }
} }
// Power on, TX mode, CRC enabled // Send
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
XN297_SetFreqOffset();
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? Q303_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]); XN297_SetTxRxMode(TX_EN);
hopping_frequency_no %= rf_ch_num;
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, packet_length); XN297_WritePayload(packet, packet_length);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) Q303_RF_init() static void __attribute__((unused)) Q303_RF_init()
{ {
const uint8_t bind_address[] = {0xcc,0xcc,0xcc,0xcc,0xcc}; const uint8_t bind_address[] = {0xcc,0xcc,0xcc,0xcc,0xcc};
NRF24L01_Initialize();
if(sub_protocol==Q303) if(sub_protocol==Q303)
{ {
XN297_SetScrambledMode(XN297_UNSCRAMBLED); XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K);
NRF24L01_SetBitrate(NRF24L01_BR_250K); XN297_HoppingCalib(rf_ch_num);
} }
else
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr(bind_address, 5); XN297_SetTXAddr(bind_address, 5);
XN297_RFChannel(Q303_RF_BIND_CHANNEL);
} }
static void __attribute__((unused)) Q303_initialize_txid() static void __attribute__((unused)) Q303_initialize_txid()

View File

@ -51,7 +51,7 @@ static void __attribute__((unused)) Q90C_send_packet()
} }
else else
{ {
XN297L_Hopping(hopping_frequency_no++); // RF Freq XN297_Hopping(hopping_frequency_no++); // RF Freq
hopping_frequency_no %= Q90C_RF_NUM_CHANNELS; hopping_frequency_no %= Q90C_RF_NUM_CHANNELS;
packet[0]= convert_channel_8b(THROTTLE); // 0..255 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 // 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; packet[11] = sum ^ crc8;
} }
XN297L_SetFreqOffset(); // Set frequency offset // Send
XN297L_SetPower(); // Set tx_power XN297_SetFreqOffset(); // Set frequency offset
XN297L_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0); XN297_SetPower(); // Set tx_power
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0);
} }
static void __attribute__((unused)) Q90C_initialize_txid() 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() static void __attribute__((unused)) Q90C_RF_init()
{ {
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
if(IS_BIND_IN_PROGRESS) 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 else
XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
XN297L_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels XN297_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels
XN297L_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel XN297_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel
} }
uint16_t Q90C_callback() uint16_t Q90C_callback()
@ -151,7 +153,7 @@ uint16_t Q90C_callback()
if(--bind_counter==0) if(--bind_counter==0)
{ {
BIND_DONE; BIND_DONE;
XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH); XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
} }
Q90C_send_packet(); Q90C_send_packet();
return Q90C_PACKET_PERIOD; return Q90C_PACKET_PERIOD;

View File

@ -51,7 +51,7 @@ static void __attribute__((unused)) REALACC_send_packet()
| GET_FLAG(CH5_SW, 0x01) // Flip | GET_FLAG(CH5_SW, 0x01) // Flip
| GET_FLAG(CH6_SW, 0x80); // Light | 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++;
hopping_frequency_no %= REALACC_RF_NUM_CHANNELS; hopping_frequency_no %= REALACC_RF_NUM_CHANNELS;
XN297_WriteEnhancedPayload(packet, REALACC_PAYLOAD_SIZE,0); 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() static void __attribute__((unused)) REALACC_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t*)"MAIN", 4); 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() uint16_t REALACC_callback()
@ -99,10 +98,8 @@ uint16_t REALACC_callback()
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(REALACC_PACKET_PERIOD); telemetry_set_input_sync(REALACC_PACKET_PERIOD);
#endif #endif
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetPower();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
NRF24L01_SetPower();
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
REALACC_send_bind_packet(); REALACC_send_bind_packet();

View File

@ -139,11 +139,15 @@ static void multi_send_status()
if(protocol!=PROTO_SCANNER) if(protocol!=PROTO_SCANNER)
flags &= ~0x04; //Invalid protocol flags &= ~0x04; //Invalid protocol
} }
else if(IS_SUB_PROTO_INVALID)
{
flags &= ~0x04; //Invalid sub protocol
}
else if(sub_protocol&0x07) else if(sub_protocol&0x07)
{ {
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto; uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
//if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol //if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol
if((sub_protocol&0x07)>=nbr) if((sub_protocol&0x07)>=nbr )
flags &= ~0x04; //Invalid sub protocol flags &= ~0x04; //Invalid sub protocol
} }
if (IS_WAIT_BIND_on) if (IS_WAIT_BIND_on)
@ -174,12 +178,12 @@ static void multi_send_status()
// Channel order // Channel order
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON); 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++) for(uint8_t i=0;i<16;i++)
Serial_write(0x00); // everything else is invalid Serial_write(0x00); // everything else is invalid
} }
else else
{ {
@ -191,13 +195,13 @@ static void multi_send_status()
if(multi_protocols[multi_protocols_index+2].protocol != 0) if(multi_protocols[multi_protocols_index+2].protocol != 0)
Serial_write(multi_protocols[multi_protocols_index+2].protocol); // skip to next protocol number Serial_write(multi_protocols[multi_protocols_index+2].protocol); // skip to next protocol number
else 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 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 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_index>0)
{ {
if(multi_protocols[multi_protocols_index-1].protocol==PROTO_SCANNER) if(multi_protocols[multi_protocols_index-1].protocol==PROTO_SCANNER)
@ -205,19 +209,22 @@ static void multi_send_status()
if(multi_protocols_index > 1) if(multi_protocols_index > 1)
Serial_write(multi_protocols[multi_protocols_index-2].protocol); // skip to prev protocol number Serial_write(multi_protocols[multi_protocols_index-2].protocol); // skip to prev protocol number
else else
Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list
} }
else 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 else
Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list
// Protocol // Protocol
for(uint8_t i=0;i<7;i++) 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 // Sub-protocol
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto; 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; uint8_t j=0;
if(nbr && (sub_protocol&0x07)<nbr) if(nbr && (sub_protocol&0x07)<nbr)
{ {

View File

@ -66,7 +66,7 @@ static void __attribute__((unused)) TIGER_send_packet()
packet[TIGER_PAYLOAD_SIZE-1]=crc8; packet[TIGER_PAYLOAD_SIZE-1]=crc8;
//Hopping frequency //Hopping frequency
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no>>1]); XN297_Hopping(hopping_frequency_no>>1);
hopping_frequency_no++; hopping_frequency_no++;
if(IS_BIND_IN_PROGRESS) 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; hopping_frequency_no=2*TIGER_BIND_RF_NUM_CHANNELS;
} }
//Clear packet status bits and TX FIFO //Send
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetPower();
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
//Send packet
XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE); XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE);
//Set tx_power
NRF24L01_SetPower();
} }
static void __attribute__((unused)) TIGER_RF_init() 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); 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() static void __attribute__((unused)) TIGER_initialize_txid()

View File

@ -115,18 +115,16 @@ static void __attribute__((unused)) V761_send_packet()
hopping_frequency_no = 0; hopping_frequency_no = 0;
} }
V761_set_checksum(); 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)); // Send
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetPower();
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, V761_PACKET_SIZE); XN297_WritePayload(packet, V761_PACKET_SIZE);
NRF24L01_SetPower();
} }
static void __attribute__((unused)) V761_RF_init() static void __attribute__((unused)) V761_RF_init()
{ {
NRF24L01_Initialize(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // set address length (4 bytes)
} }
static void __attribute__((unused)) V761_initialize_txid() static void __attribute__((unused)) V761_initialize_txid()
@ -175,7 +173,7 @@ uint16_t V761_callback()
if(bind_counter) if(bind_counter)
bind_counter--; bind_counter--;
packet_count ++; 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); XN297_SetTXAddr((uint8_t*)"\x34\x43\x10\x10", 4);
V761_send_packet(); V761_send_packet();
if(packet_count >= 20) if(packet_count >= 20)
@ -188,7 +186,7 @@ uint16_t V761_callback()
if(bind_counter) if(bind_counter)
bind_counter--; bind_counter--;
packet_count ++; packet_count ++;
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[0]); XN297_Hopping(0);
XN297_SetTXAddr(rx_tx_addr, 4); XN297_SetTXAddr(rx_tx_addr, 4);
V761_send_packet(); V761_send_packet();
if(bind_counter == 0) if(bind_counter == 0)

View File

@ -58,7 +58,7 @@ static void __attribute__((unused)) V911S_send_packet()
} }
if(rf_ch_num&2) if(rf_ch_num&2)
channel=7-channel; channel=7-channel;
XN297L_Hopping(channel); XN297_Hopping(channel);
hopping_frequency_no++; hopping_frequency_no++;
hopping_frequency_no&=7; // 8 RF channels hopping_frequency_no&=7; // 8 RF channels
@ -102,23 +102,23 @@ static void __attribute__((unused)) V911S_send_packet()
} }
if(sub_protocol==V911S_STD) if(sub_protocol==V911S_STD)
XN297L_WritePayload(packet, V911S_PACKET_SIZE); XN297_WritePayload(packet, V911S_PACKET_SIZE);
else 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 XN297_SetPower(); // Set tx_power
XN297L_SetFreqOffset(); // Set frequency offset XN297_SetFreqOffset(); // Set frequency offset
} }
static void __attribute__((unused)) V911S_RF_init() static void __attribute__((unused)) V911S_RF_init()
{ {
XN297L_Init(); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
if(sub_protocol==V911S_STD) if(sub_protocol==V911S_STD)
XN297L_SetTXAddr((uint8_t *)"KNBND",5); // V911S Bind address XN297_SetTXAddr((uint8_t *)"KNBND",5); // V911S Bind address
else else
XN297L_SetTXAddr((uint8_t *)"XPBND",5); // E119 Bind address XN297_SetTXAddr((uint8_t *)"XPBND",5); // E119 Bind address
XN297L_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels XN297_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels
XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel XN297_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
} }
static void __attribute__((unused)) V911S_initialize_txid() static void __attribute__((unused)) V911S_initialize_txid()
@ -144,7 +144,7 @@ uint16_t V911S_callback()
if (bind_counter == 0) if (bind_counter == 0)
{ {
BIND_DONE; BIND_DONE;
XN297L_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
packet_period=V911S_PACKET_PERIOD; packet_period=V911S_PACKET_PERIOD;
} }
else if(bind_counter==100) // same as original TX... else if(bind_counter==100) // same as original TX...
@ -193,7 +193,7 @@ void V911S_init(void)
} }
else else
{ {
XN297L_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
packet_period= V911S_PACKET_PERIOD; packet_period= V911S_PACKET_PERIOD;
} }
hopping_frequency_no=0; hopping_frequency_no=0;

View File

@ -276,7 +276,6 @@
#undef FRSKY_RX_CC2500_INO #undef FRSKY_RX_CC2500_INO
#undef HITEC_CC2500_INO #undef HITEC_CC2500_INO
#undef HOTT_CC2500_INO #undef HOTT_CC2500_INO
#undef OMP_CC2500_INO //CC2500 for control and NRF for telemetry
#undef REDPINE_CC2500_INO #undef REDPINE_CC2500_INO
#undef RLINK_CC2500_INO #undef RLINK_CC2500_INO
#undef SCANNER_CC2500_INO #undef SCANNER_CC2500_INO
@ -293,6 +292,7 @@
#undef CG023_NRF24L01_INO #undef CG023_NRF24L01_INO
#undef CX10_NRF24L01_INO #undef CX10_NRF24L01_INO
#undef DM002_NRF24L01_INO #undef DM002_NRF24L01_INO
#undef E016H_NRF24L01_INO
#undef E01X_NRF24L01_INO #undef E01X_NRF24L01_INO
#undef ESKY_NRF24L01_INO #undef ESKY_NRF24L01_INO
#undef ESKY150_NRF24L01_INO #undef ESKY150_NRF24L01_INO
@ -306,28 +306,29 @@
#undef JJRC345_NRF24L01_INO #undef JJRC345_NRF24L01_INO
#undef KN_NRF24L01_INO #undef KN_NRF24L01_INO
#undef LOLI_NRF24L01_INO #undef LOLI_NRF24L01_INO
#undef MJXQ_NRF24L01_INO
#undef MT99XX_NRF24L01_INO
#undef NCC1701_NRF24L01_INO #undef NCC1701_NRF24L01_INO
#undef POTENSIC_NRF24L01_INO #undef POTENSIC_NRF24L01_INO
#undef PROPEL_NRF24L01_INO #undef PROPEL_NRF24L01_INO
#undef Q303_NRF24L01_INO
#undef REALACC_NRF24L01_INO #undef REALACC_NRF24L01_INO
#undef SHENQI_NRF24L01_INO #undef SHENQI_NRF24L01_INO
#undef SYMAX_NRF24L01_INO #undef SYMAX_NRF24L01_INO
#undef TIGER_NRF24L01_INO #undef TIGER_NRF24L01_INO
#undef V2X2_NRF24L01_INO #undef V2X2_NRF24L01_INO
#undef V761_NRF24L01_INO #undef V761_NRF24L01_INO
#undef XK_NRF24L01_INO
#undef YD717_NRF24L01_INO #undef YD717_NRF24L01_INO
#undef ZSX_NRF24L01_INO #undef ZSX_NRF24L01_INO
#endif #endif
#if not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED) #if not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED)
#undef GD00X_CCNRF_INO #undef GD00X_CCNRF_INO
#undef KF606_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 Q90C_CCNRF_INO
#undef SLT_CCNRF_INO #undef SLT_CCNRF_INO
#undef V911S_CCNRF_INO #undef V911S_CCNRF_INO
#undef XK_CCNRF_INO
#endif #endif
#if not defined(STM32_BOARD) #if not defined(STM32_BOARD)
#undef SX1276_INSTALLED #undef SX1276_INSTALLED
@ -401,7 +402,7 @@
#if not defined(DEVO_CYRF6936_INO) #if not defined(DEVO_CYRF6936_INO)
#undef DEVO_HUB_TELEMETRY #undef DEVO_HUB_TELEMETRY
#endif #endif
#if not defined(OMP_CC2500_INO) #if not defined(OMP_CCNRF_INO)
#undef OMP_HUB_TELEMETRY #undef OMP_HUB_TELEMETRY
#endif #endif
#if not defined(PROPEL_NRF24L01_INO) #if not defined(PROPEL_NRF24L01_INO)

View File

@ -14,7 +14,7 @@ Multiprotocol is distributed in the hope that it will be useful,
*/ */
// Compatible with X450 and X420/X520 plane. // Compatible with X450 and X420/X520 plane.
#if defined(XK_NRF24L01_INO) #if defined(XK_CCNRF_INO)
#include "iface_nrf250k.h" #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() 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,0x00,7);
memset(&packet[10],0x00,5); memset(&packet[10],0x00,5);
@ -101,32 +108,16 @@ static void __attribute__((unused)) XK_send_packet()
crc+=packet[i]; crc+=packet[i];
packet[15]=crc; 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]); // debug("C: %02X, P:",hopping_frequency[rf_ch_num]);
// for(uint8_t i=0; i<XK_PAYLOAD_SIZE; i++) // for(uint8_t i=0; i<XK_PAYLOAD_SIZE; i++)
// debug(" %02X",packet[i]); // debug(" %02X",packet[i]);
// debugln(""); // debugln("");
if(sub_protocol==X420) // Send
{ XN297_SetPower(); // Set tx_power
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[rf_ch_num]); XN297_SetTxRxMode(TX_EN);
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); XN297_SetFreqOffset(); // Set frequency offset
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_WritePayload(packet, XK_PAYLOAD_SIZE);
NRF24L01_FlushTx();
XN297_WritePayload(packet, XK_PAYLOAD_SIZE);
NRF24L01_SetPower();
}
else
{
XN297L_Hopping(rf_ch_num);
XN297L_WritePayload(packet, XK_PAYLOAD_SIZE);
XN297L_SetPower(); // Set tx_power
XN297L_SetFreqOffset(); // Set frequency offset
}
} }
const uint8_t PROGMEM XK_bind_hop[XK_RF_BIND_NUM_CHANNELS]= { 0x07, 0x24, 0x3E, 0x2B, 0x47, 0x0E, 0x39, 0x1C }; // Bind const uint8_t PROGMEM XK_bind_hop[XK_RF_BIND_NUM_CHANNELS]= { 0x07, 0x24, 0x3E, 0x2B, 0x47, 0x0E, 0x39, 0x1C }; // Bind
@ -201,17 +192,9 @@ static void __attribute__((unused)) XK_initialize_txid()
static void __attribute__((unused)) XK_RF_init() static void __attribute__((unused)) XK_RF_init()
{ {
if(sub_protocol==X420) XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, sub_protocol==X420 ? XN297_1M : XN297_250K);
{ XN297_SetTXAddr((uint8_t*)"\x68\x94\xA6\xD5\xC3", 5); // Bind address
NRF24L01_Initialize(); XN297_HoppingCalib(XK_RF_BIND_NUM_CHANNELS+XK_RF_NUM_CHANNELS); // Calibrate all channels
XN297_SetTXAddr((uint8_t*)"\x68\x94\xA6\xD5\xC3", 5); // Bind address
}
else
{
XN297L_Init();
XN297L_SetTXAddr((uint8_t*)"\x68\x94\xA6\xD5\xC3", 5); // Bind address
XN297L_HoppingCalib(XK_RF_BIND_NUM_CHANNELS+XK_RF_NUM_CHANNELS); // Calibrate all channels
}
} }
uint16_t XK_callback() uint16_t XK_callback()
@ -223,10 +206,7 @@ uint16_t XK_callback()
if(--bind_counter==0) if(--bind_counter==0)
{ {
BIND_DONE; BIND_DONE;
if(sub_protocol==X420) XN297_SetTXAddr(rx_tx_addr, 5); // Normal packets address
XN297_SetTXAddr(rx_tx_addr, 5); // Normal packets address
else
XN297L_SetTXAddr(rx_tx_addr, 5); // Normal packets address
} }
XK_send_packet(); XK_send_packet();
return XK_PACKET_PERIOD; return XK_PACKET_PERIOD;
@ -234,7 +214,7 @@ uint16_t XK_callback()
void XK_init() void XK_init()
{ {
BIND_IN_PROGRESS; // Autobind protocol BIND_IN_PROGRESS; // Autobind protocol
XK_initialize_txid(); XK_initialize_txid();
XK_RF_init(); XK_RF_init();
hopping_frequency_no = 0; hopping_frequency_no = 0;

View File

@ -19,7 +19,7 @@
#ifdef XN297DUMP_NRF24L01_INO #ifdef XN297DUMP_NRF24L01_INO
#include "iface_nrf24l01.h" #include "iface_xn297.h"
// Parameters which can be modified // Parameters which can be modified
#define XN297DUMP_PERIOD_SCAN 50000 // 25000 #define XN297DUMP_PERIOD_SCAN 50000 // 25000
@ -66,6 +66,12 @@ static void __attribute__((unused)) XN297Dump_RF_init()
} }
} }
extern const uint8_t xn297_scramble[];
extern const uint16_t PROGMEM xn297_crc_xorout_scrambled[];
extern const uint16_t PROGMEM xn297_crc_xorout[];
extern const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[];
extern const uint16_t xn297_crc_xorout_enhanced[];
static boolean __attribute__((unused)) XN297Dump_process_packet(void) static boolean __attribute__((unused)) XN297Dump_process_packet(void)
{ {
uint16_t crcxored; uint16_t crcxored;
@ -318,15 +324,16 @@ static uint16_t XN297Dump_callback()
switch(bitrate) switch(bitrate)
{ {
case XN297DUMP_250K: case XN297DUMP_250K:
NRF24L01_SetBitrate(NRF24L01_BR_250K); XN297_Configure(XN297_CRCEN, scramble?XN297_SCRAMBLED:XN297_UNSCRAMBLED, XN297_250K);
debug("250K"); debug("250K");
break; break;
case XN297DUMP_2M: case XN297DUMP_2M:
XN297_Configure(XN297_CRCEN, scramble?XN297_SCRAMBLED:XN297_UNSCRAMBLED, XN297_1M);
NRF24L01_SetBitrate(NRF24L01_BR_2M); NRF24L01_SetBitrate(NRF24L01_BR_2M);
debug("2M"); debug("2M");
break; break;
default: default:
NRF24L01_SetBitrate(NRF24L01_BR_1M); XN297_Configure(XN297_CRCEN, scramble?XN297_SCRAMBLED:XN297_UNSCRAMBLED, XN297_1M);
debug("1M"); debug("1M");
break; break;
@ -358,20 +365,12 @@ static uint16_t XN297Dump_callback()
rf_ch_num=0; rf_ch_num=0;
packet_count=0; packet_count=0;
debug("Trying RF channel: 0"); debug("Trying RF channel: 0");
NRF24L01_Initialize();
XN297_SetScrambledMode(scramble?XN297_SCRAMBLED:XN297_UNSCRAMBLED);
XN297_SetTXAddr(rx_tx_addr,address_length); XN297_SetTXAddr(rx_tx_addr,address_length);
XN297_SetRXAddr(rx_tx_addr,address_length); XN297_SetRXAddr(rx_tx_addr,packet_length);
NRF24L01_FlushRx(); XN297_RFChannel(0);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes XN297_SetTxRxMode(RX_EN);
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length + 2 + (enhanced?2:0) ); // 2 extra bytes for xn297 crc
NRF24L01_WriteReg(NRF24L01_05_RF_CH,0);
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));
} }
} }
} }
@ -404,7 +403,7 @@ static uint16_t XN297Dump_callback()
bind_counter=0; bind_counter=0;
debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]); debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]);
time_rf[hopping_frequency_no]=0xFFFFFFFF; time_rf[hopping_frequency_no]=0xFFFFFFFF;
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); XN297_RFChannel(hopping_frequency[0]);
uint16_t timeL=TCNT1; uint16_t timeL=TCNT1;
if(TIMER2_BASE->SR & TIMER_SR_UIF) if(TIMER2_BASE->SR & TIMER_SR_UIF)
{//timer just rolled over... {//timer just rolled over...
@ -412,29 +411,20 @@ static uint16_t XN297Dump_callback()
timeL=0; timeL=0;
} }
time=(timeH<<16)+timeL; time=(timeH<<16)+timeL;
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
XN297Dump_overflow(); XN297Dump_overflow();
break; break;
} }
debug(",%d",hopping_frequency_no); debug(",%d",hopping_frequency_no);
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); XN297_RFChannel(hopping_frequency_no);
// switch to RX mode // switch to RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( XN297_IsRX() )
{ // RX fifo data ready { // RX fifo data ready
if(NRF24L01_ReadReg(NRF24L01_09_CD)) // if(NRF24L01_ReadReg(NRF24L01_09_CD))
{ {
boolean res; boolean res;
if(enhanced) if(enhanced)
@ -471,11 +461,8 @@ static uint16_t XN297Dump_callback()
} }
} }
// restart RX mode // restart RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
XN297Dump_overflow(); XN297Dump_overflow();
break; 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]); debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]);
time_rf[hopping_frequency_no]=-1; time_rf[hopping_frequency_no]=-1;
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); XN297_RFChannel(hopping_frequency[0]);
uint16_t timeL=TCNT1; uint16_t timeL=TCNT1;
if(TIMER2_BASE->SR & TIMER_SR_UIF) if(TIMER2_BASE->SR & TIMER_SR_UIF)
{//timer just rolled over... {//timer just rolled over...
@ -527,15 +514,12 @@ static uint16_t XN297Dump_callback()
} }
time=(timeH<<16)+timeL; time=(timeH<<16)+timeL;
// switch to RX mode // switch to RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( XN297_IsRX() )
{ // RX fifo data ready { // RX fifo data ready
if(NRF24L01_ReadReg(NRF24L01_09_CD)) //if(NRF24L01_ReadReg(NRF24L01_09_CD))
{ {
boolean res; boolean res;
if(enhanced) if(enhanced)
@ -557,12 +541,12 @@ static uint16_t XN297Dump_callback()
if(time_rf[hopping_frequency_no] > (time>>1)) if(time_rf[hopping_frequency_no] > (time>>1))
time_rf[hopping_frequency_no]=time>>1; time_rf[hopping_frequency_no]=time>>1;
debugln("Time: %5luus", time>>1); debugln("Time: %5luus", time>>1);
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); XN297_RFChannel(hopping_frequency[0]);
} }
else else
{ {
time=(timeH<<16)+timeL; time=(timeH<<16)+timeL;
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[hopping_frequency_no]); XN297_RFChannel(hopping_frequency[hopping_frequency_no]);
} }
packet_count++; packet_count++;
if(packet_count>24) if(packet_count>24)
@ -573,18 +557,15 @@ static uint16_t XN297Dump_callback()
} }
} }
// restart RX mode // restart RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
XN297Dump_overflow(); XN297Dump_overflow();
break; break;
case 4: case 4:
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( XN297_IsRX() )
{ // RX fifo data ready { // RX fifo data ready
if(NRF24L01_ReadReg(NRF24L01_09_CD)) //if(NRF24L01_ReadReg(NRF24L01_09_CD))
{ {
boolean res; boolean res;
if(enhanced) if(enhanced)
@ -604,11 +585,8 @@ static uint16_t XN297Dump_callback()
} }
} }
// restart RX mode // restart RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit XN297_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TXRX_OFF); XN297_SetTxRxMode(RX_EN);
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));
} }
break; break;
} }
@ -618,10 +596,10 @@ static uint16_t XN297Dump_callback()
if(phase==0) if(phase==0)
{ {
address_length=4; address_length=4;
memcpy(rx_tx_addr, (uint8_t *)"\x5A\x20\x12\xAC", address_length); //"\xA3\x05\x22\xC1" memcpy(rx_tx_addr, (uint8_t *)"\x5A\xF6\xC1\x71", address_length); //"\xA3\x05\x22\xC1""\x5A\x20\x12\xAC"
bitrate=XN297DUMP_1M; bitrate=XN297DUMP_250K;
packet_length=32; packet_length=32;
hopping_frequency_no=60; //bind ?, normal 60 hopping_frequency_no=58; //bind ?, normal 60
NRF24L01_Initialize(); NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
@ -658,12 +636,18 @@ static uint16_t XN297Dump_callback()
if(NRF24L01_ReadReg(NRF24L01_09_CD)) if(NRF24L01_ReadReg(NRF24L01_09_CD))
{ {
NRF24L01_ReadPayload(packet, packet_length); NRF24L01_ReadPayload(packet, packet_length);
bool ok=true; //bool ok=true;
uint8_t buffer[40]; uint8_t buffer[40];
memcpy(buffer,packet,packet_length); memcpy(buffer,packet,packet_length);
if(memcmp(&packet_in[0],&packet[0],packet_length)) if(memcmp(&packet_in[0],&packet[0],packet_length))
{ {
//realign bits debug("P:");
for(uint8_t i=0;i<packet_length;i++)
debug(" %02X",packet[i]);
debugln("");
memcpy(packet_in,packet,packet_length);
}
/*//realign bits
for(uint8_t i=0; i<packet_length; i++) for(uint8_t i=0; i<packet_length; i++)
buffer[i]=buffer[i+2]; buffer[i]=buffer[i+2];
//for(uint8_t i=0; i<packet_length; i++) //for(uint8_t i=0; i<packet_length; i++)
@ -693,7 +677,7 @@ static uint16_t XN297Dump_callback()
debugln(""); debugln("");
memcpy(packet_in,packet,packet_length); memcpy(packet_in,packet,packet_length);
} }
} }*/
/*crc=0; /*crc=0;
for (uint8_t i = 1; i < 12; ++i) for (uint8_t i = 1; i < 12; ++i)
crc16_update( packet[i], 8); crc16_update( packet[i], 8);

View File

@ -2,69 +2,252 @@
#include "iface_xn297.h" #include "iface_xn297.h"
bool xn297_scramble_enabled, xn297_crc, xn297_bitrate, xn297_rf;
uint8_t xn297_addr_len, xn297_rx_packet_len;
uint8_t xn297_tx_addr[5], xn297_rx_addr[5];
// 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 };
// 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 #endif
#ifdef NRF24L01_INSTALLED static bool __attribute__((unused)) XN297_Configure(bool crc_en, bool scramble_en, bool bitrate)
void XN297_SetTXAddr(const uint8_t* addr, uint8_t len)
{ {
if (len > 5) len = 5; xn297_crc = crc_en;
if (len < 3) len = 3; xn297_scramble_enabled = scramble_en;
uint8_t buf[] = { 0x55, 0x0F, 0x71, 0x0C, 0x00 }; // bytes for XN297 preamble 0xC710F55 (28 bit) xn297_bitrate = bitrate;
xn297_addr_len = len; xn297_rf = XN297_NRF;
if (xn297_addr_len < 4)
for (uint8_t i = 0; i < 4; ++i) #if defined(NRF24L01_INSTALLED) and defined(CC2500_INSTALLED)
buf[i] = buf[i+1]; if(bitrate == XN297_1M)
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2); xn297_rf = XN297_NRF; // Use NRF24L01
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, buf, 5); else
// Receive address is complicated. We need to use scrambled actual address as a receive address xn297_rf = XN297_CC2500; // Use CC2500
// but the TX code now assumes fixed 4-byte transmit address for preamble. We need to adjust it #elif defined(NRF24L01_INSTALLED) and not defined(CC2500_INSTALLED)
// first. Also, if the scrambled address begins with 1 nRF24 will look for preamble byte 0xAA xn297_rf = XN297_NRF; // Use NRF24L01
// instead of 0x55 to ensure enough 0-1 transitions to tune the receiver. Still need to experiment #else //CC2500 only
// with receiving signals. xn297_rf = XN297_CC2500; // Use CC2500
memcpy(xn297_tx_addr, addr, len); 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 > 5) len = 5;
if (len < 3) len = 3; if (len < 3) len = 3;
uint8_t buf[] = { 0, 0, 0, 0, 0 }; xn297_addr_len = len;
memcpy(buf, addr, len); memcpy(xn297_tx_addr, addr, len);
memcpy(xn297_rx_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) 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) 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)); static enum TXRX_State cur_mode=TXRX_OFF;
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); #ifdef NRF24L01_INSTALLED
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF); 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 buf[32];
uint8_t last = 0; uint8_t last = 0;
if (xn297_addr_len < 4) 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
// 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; buf[last++] = 0x55;
} }
// address
for (uint8_t i = 0; i < xn297_addr_len; ++i) for (uint8_t i = 0; i < xn297_addr_len; ++i)
{ {
buf[last] = xn297_tx_addr[xn297_addr_len-i-1]; 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]; buf[last] ^= xn297_scramble[i];
last++; last++;
} }
// payload
for (uint8_t i = 0; i < len; ++i) for (uint8_t i = 0; i < len; ++i)
{ {
// bit-reverse bytes in packet // 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]; buf[last] ^= xn297_scramble[xn297_addr_len+i];
last++; last++;
} }
// crc
if (xn297_crc) if (xn297_crc)
{ {
uint8_t offset = xn297_addr_len < 4 ? 1 : 0; 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 >> 8;
buf[last++] = crc & 0xff; 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 scramble_index=0;
uint8_t last = 0; uint8_t last = 0;
static uint8_t pid=0; static uint8_t pid=0;
// address if (xn297_rf == XN297_NRF && xn297_addr_len < 4)
if (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;
// 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;
} }
// address
for (uint8_t i = 0; i < xn297_addr_len; ++i) 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) if(xn297_scramble_enabled)
packet[last] ^= xn297_scramble[scramble_index++]; buf[last] ^= xn297_scramble[scramble_index++];
last++; last++;
} }
// pcf // pcf
packet[last] = (len << 1) | (pid>>1); buf[last] = (len << 1) | (pid>>1);
if(xn297_scramble_enabled) if(xn297_scramble_enabled)
packet[last] ^= xn297_scramble[scramble_index++]; buf[last] ^= xn297_scramble[scramble_index++];
last++; last++;
packet[last] = (pid << 7) | (noack << 6); buf[last] = (pid << 7) | (noack << 6);
// payload // 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) 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) for (uint8_t i = 0; i < len-1; ++i)
{ {
last++; 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) if(xn297_scramble_enabled)
packet[last] ^= xn297_scramble[scramble_index++]; buf[last] ^= xn297_scramble[scramble_index++];
} }
last++; 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) if(xn297_scramble_enabled)
packet[last] ^= xn297_scramble[scramble_index++] & 0xc0; buf[last] ^= xn297_scramble[scramble_index++] & 0xc0;
// crc // crc
if (xn297_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; uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
crc = 0xb5d2; crc = 0xb5d2;
for (uint8_t i = offset; i < last; ++i) for (uint8_t i = offset; i < last; ++i)
crc16_update( packet[i], 8); crc16_update( buf[i], 8);
crc16_update( packet[last] & 0xc0, 2); crc16_update( buf[last] & 0xc0, 2);
if (xn297_scramble_enabled) if (xn297_scramble_enabled)
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]); crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
//else //else
// crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]); // crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
packet[last++] |= (crc >> 8) >> 2; buf[last++] |= (crc >> 8) >> 2;
packet[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2); buf[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
packet[last++] = (crc & 0xff) << 6; buf[last++] = (crc & 0xff) << 6;
} }
NRF24L01_WritePayload(packet, last);
pid++; pid++;
if(pid>3) if(pid>3)
pid=0; pid=0;
// send packet
XN297_SendPayload(buf, last);
} }
boolean XN297_ReadPayload(uint8_t* msg, uint8_t len) static bool __attribute__((unused)) XN297_IsRX()
{ //!!! Don't forget if using CRC to do a +2 on any of the used NRF24L01_11_RX_PW_Px !!! {
uint8_t buf[32]; #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) if (xn297_crc)
NRF24L01_ReadPayload(buf, len+2); // Read payload + CRC len += 2; // Include CRC
else #ifdef NRF24L01_INSTALLED
NRF24L01_ReadPayload(buf, len); 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 // Decode payload
for(uint8_t i=0; i<len; i++) for(uint8_t i=0; i<len; i++)
{ {
@ -183,6 +408,7 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
b_in ^= xn297_scramble[i+xn297_addr_len]; b_in ^= xn297_scramble[i+xn297_addr_len];
msg[i] = bit_reverse(b_in); msg[i] = bit_reverse(b_in);
} }
if (!xn297_crc) if (!xn297_crc)
return true; // No CRC so OK by default... return true; // No CRC so OK by default...
@ -190,12 +416,7 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
crc = 0xb5d2; crc = 0xb5d2;
//process address //process address
for (uint8_t i = 0; i < xn297_addr_len; ++i) for (uint8_t i = 0; i < xn297_addr_len; ++i)
{ crc16_update( xn297_rx_addr[xn297_addr_len-i-1], 8);
uint8_t b_in=xn297_rx_addr[xn297_addr_len-i-1];
if(xn297_scramble_enabled)
b_in ^= xn297_scramble[i];
crc16_update( b_in, 8);
}
//process payload //process payload
for (uint8_t i = 0; i < len; ++i) for (uint8_t i = 0; i < len; ++i)
crc16_update( buf[i], 8); crc16_update( buf[i], 8);
@ -210,14 +431,15 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
return false; // CRC NOK return false; // CRC NOK
} }
uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len) static uint8_t __attribute__((unused)) XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
{ //!!! Don't forget do a +2 and if using CRC add +4 on any of the used NRF24L01_11_RX_PW_Px !!! { //!!! Don't forget do a +2 and if using CRC add +4 on any of the used NRF24L01_11_RX_PW_Px !!!
uint8_t buffer[32]; uint8_t buffer[32];
uint8_t pcf_size; // pcf payload size uint8_t pcf_size; // pcf payload size
if (xn297_crc)
NRF24L01_ReadPayload(buffer, len+4); // Read pcf + payload + CRC // Read payload
else XN297_ReceivePayload(buffer, len+2); // Read pcf + payload + CRC
NRF24L01_ReadPayload(buffer, len+2); // Read pcf + payload
// Decode payload
pcf_size = buffer[0]; pcf_size = buffer[0];
if(xn297_scramble_enabled) if(xn297_scramble_enabled)
pcf_size ^= xn297_scramble[xn297_addr_len]; pcf_size ^= xn297_scramble[xn297_addr_len];
@ -231,18 +453,13 @@ uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
} }
if (!xn297_crc) if (!xn297_crc)
return pcf_size; // No CRC so OK by default... return pcf_size; // No CRC so OK by default...
// Calculate CRC // Calculate CRC
crc = 0xb5d2; crc = 0xb5d2;
//process address //process address
for (uint8_t i = 0; i < xn297_addr_len; ++i) for (uint8_t i = 0; i < xn297_addr_len; ++i)
{ crc16_update( xn297_rx_addr[xn297_addr_len-i-1], 8);
uint8_t b_in=xn297_rx_addr[xn297_addr_len-i-1];
if(xn297_scramble_enabled)
b_in ^= xn297_scramble[i];
crc16_update( b_in, 8);
}
//process payload //process payload
for (uint8_t i = 0; i < len+1; ++i) for (uint8_t i = 0; i < len+1; ++i)
crc16_update( buffer[i], 8); crc16_update( buffer[i], 8);
@ -256,10 +473,78 @@ uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
#endif #endif
uint16_t crcxored=(buffer[len+1]<<10)|(buffer[len+2]<<2)|(buffer[len+3]>>6) ; uint16_t crcxored=(buffer[len+1]<<10)|(buffer[len+2]<<2)|(buffer[len+3]>>6) ;
if( crc == crcxored) if( crc == crcxored)
return pcf_size; // CRC OK return pcf_size; // CRC OK
return 0; // CRC NOK 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 // End of XN297 emulation
#endif #endif

View File

@ -44,12 +44,10 @@ static void __attribute__((unused)) ZSX_send_packet()
| GET_FLAG(CH5_SW, 0x80); // Light | GET_FLAG(CH5_SW, 0x80); // Light
} }
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); // Send
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); XN297_SetPower();
NRF24L01_FlushTx(); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, ZSX_PAYLOAD_SIZE); XN297_WritePayload(packet, ZSX_PAYLOAD_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void __attribute__((unused)) ZSX_initialize_txid() 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() 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); 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() uint16_t ZSX_callback()
@ -81,7 +78,7 @@ uint16_t ZSX_callback()
{ {
BIND_DONE; BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 3); XN297_SetTXAddr(rx_tx_addr, 3);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x00); XN297_RFChannel(0x00);
} }
ZSX_send_packet(); ZSX_send_packet();
return ZSX_PACKET_PERIOD; return ZSX_PACKET_PERIOD;

View File

@ -203,7 +203,6 @@
#define FRSKY_RX_CC2500_INO #define FRSKY_RX_CC2500_INO
#define HITEC_CC2500_INO #define HITEC_CC2500_INO
#define HOTT_CC2500_INO #define HOTT_CC2500_INO
#define OMP_CC2500_INO //CC2500 for control and NRF for telemetry
#define SCANNER_CC2500_INO #define SCANNER_CC2500_INO
#define FUTABA_CC2500_INO #define FUTABA_CC2500_INO
#define SKYARTEC_CC2500_INO #define SKYARTEC_CC2500_INO
@ -220,6 +219,7 @@
#define CG023_NRF24L01_INO #define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO //Include Q2X2 protocol #define CX10_NRF24L01_INO //Include Q2X2 protocol
#define DM002_NRF24L01_INO #define DM002_NRF24L01_INO
#define E016H_NRF24L01_INO
#define E01X_NRF24L01_INO #define E01X_NRF24L01_INO
#define ESKY_NRF24L01_INO #define ESKY_NRF24L01_INO
#define ESKY150_NRF24L01_INO #define ESKY150_NRF24L01_INO
@ -233,28 +233,29 @@
#define JJRC345_NRF24L01_INO #define JJRC345_NRF24L01_INO
#define KN_NRF24L01_INO #define KN_NRF24L01_INO
#define LOLI_NRF24L01_INO #define LOLI_NRF24L01_INO
#define MJXQ_NRF24L01_INO
#define MT99XX_NRF24L01_INO
#define NCC1701_NRF24L01_INO #define NCC1701_NRF24L01_INO
#define POTENSIC_NRF24L01_INO #define POTENSIC_NRF24L01_INO
#define PROPEL_NRF24L01_INO #define PROPEL_NRF24L01_INO
#define Q303_NRF24L01_INO
#define REALACC_NRF24L01_INO #define REALACC_NRF24L01_INO
#define SHENQI_NRF24L01_INO #define SHENQI_NRF24L01_INO
#define SYMAX_NRF24L01_INO #define SYMAX_NRF24L01_INO
#define TIGER_NRF24L01_INO #define TIGER_NRF24L01_INO
#define V2X2_NRF24L01_INO #define V2X2_NRF24L01_INO
#define V761_NRF24L01_INO #define V761_NRF24L01_INO
#define XK_NRF24L01_INO
#define YD717_NRF24L01_INO #define YD717_NRF24L01_INO
#define ZSX_NRF24L01_INO #define ZSX_NRF24L01_INO
//The protocols below need either a CC2500 or NRF24L01 to be installed //The protocols below need either a CC2500 or NRF24L01 to be installed
#define GD00X_CCNRF_INO #define GD00X_CCNRF_INO
#define KF606_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 Q90C_CCNRF_INO
#define SLT_CCNRF_INO #define SLT_CCNRF_INO
#define V911S_CCNRF_INO #define V911S_CCNRF_INO
#define XK_CCNRF_INO
//The protocols below need a SX1276 to be installed //The protocols below need a SX1276 to be installed
#define FRSKYR9_SX1276_INO #define FRSKYR9_SX1276_INO
@ -592,12 +593,13 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
NONE NONE
PROTO_E010R5 PROTO_E010R5
NONE NONE
PROTO_E016H
NONE
PROTO_E016HV2 PROTO_E016HV2
NONE NONE
PROTO_E01X PROTO_E01X
E012 E012
E015 E015
E016H
PROTO_E129 PROTO_E129
NONE NONE
PROTO_ESKY PROTO_ESKY

View File

@ -35,7 +35,7 @@
#undef FQ777_NRF24L01_INO #undef FQ777_NRF24L01_INO
#undef ASSAN_NRF24L01_INO #undef ASSAN_NRF24L01_INO
#undef HONTAI_NRF24L01_INO #undef HONTAI_NRF24L01_INO
#undef Q303_NRF24L01_INO #undef Q303_CCNRF_INO
#undef GW008_NRF24L01_INO #undef GW008_NRF24L01_INO
#undef DM002_NRF24L01_INO #undef DM002_NRF24L01_INO
#undef CABELL_NRF24L01_INO #undef CABELL_NRF24L01_INO

View File

@ -1,34 +1,28 @@
#ifndef _IFACE_NRF250K_H_ #ifndef _IFACE_NRF250K_H_
#define _IFACE_NRF250K_H_ #define _IFACE_NRF250K_H_
#if defined (CC2500_INSTALLED) #ifdef CC2500_INSTALLED
#include "iface_cc2500.h" #include "iface_cc2500.h"
#elif defined (NRF24L01_INSTALLED) #endif
#ifdef NRF24L01_INSTALLED
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
#endif #endif
#include "iface_xn297.h" #include "iface_xn297.h"
//XN297L #if defined (CC2500_INSTALLED) || defined (NRF24L01_INSTALLED)
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();
//NRF250K //////////////
#define NRF250K_Init() XN297L_Init() // Functions
#define NRF250K_HoppingCalib(X) XN297L_HoppingCalib(X) #define NRF250K_Init() XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K)
#define NRF250K_Hopping(X) XN297L_Hopping(X) #define NRF250K_HoppingCalib(X) XN297_HoppingCalib(X)
#define NRF250K_RFChannel(X) XN297L_RFChannel(X) #define NRF250K_Hopping(X) XN297_Hopping(X)
#define NRF250K_SetPower() XN297L_SetPower() #define NRF250K_RFChannel(X) XN297_RFChannel(X)
#define NRF250K_SetFreqOffset() XN297L_SetFreqOffset() #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_SetTXAddr(uint8_t*, uint8_t);
static void __attribute__((unused)) NRF250K_WritePayload(uint8_t*, uint8_t); static void __attribute__((unused)) NRF250K_WritePayload(uint8_t*, uint8_t);
static boolean __attribute__((unused)) NRF250K_IsPacketSent();
#endif #endif
#endif

View File

@ -8,76 +8,39 @@
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
#endif #endif
/////////////// #if defined (CC2500_INSTALLED) || defined (NRF24L01_INSTALLED)
// XN297 emulation layer
// XN297 emulation layer
enum {
XN297_UNSCRAMBLED = 0,
XN297_SCRAMBLED
};
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default //////////////////
uint8_t xn297_addr_len; // Configuration
uint8_t xn297_tx_addr[5]; #define XN297_UNSCRAMBLED false
uint8_t xn297_rx_addr[5]; #define XN297_SCRAMBLED true
uint8_t xn297_crc = 0; #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[] = { // Functions
0xE3, 0xB1, 0x4B, 0xEA, 0x85, 0xBC, 0xE5, 0x66, static bool __attribute__((unused)) XN297_Configure(bool, bool, bool);
0x0D, 0xAE, 0x8C, 0x88, 0x12, 0x69, 0xEE, 0x1F, static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t*, uint8_t);
0xC7, 0x62, 0x97, 0xD5, 0x0B, 0x79, 0xCA, 0xCC, static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t*, uint8_t);
0x1B, 0x5D, 0x19, 0x10, 0x24, 0xD3, 0xDC, 0x3F, static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State);
0x8E, 0xC5, 0x2F, 0xAA, 0x16, 0xF3, 0x95 }; 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
#endif #endif

View File

@ -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](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| [DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936|
[E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936/NRF24L01|RF2500 [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 [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 [E129](Protocols_Details.md#E129---83)|83|||||||||CYRF6936/NRF24L01|RF2500
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01| [ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01|
[ESky150](Protocols_Details.md#ESKY150---35)|35|||||||||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. 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 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* ## Scanner - *54*
2.4GHz scanner accessible using the OpenTX 2.3 Spectrum Analyser tool. 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 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* ## GD00X - *47*
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50 Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
@ -994,6 +973,176 @@ CH1|CH2|CH3|CH4|CH5
---|---|---|---|--- ---|---|---|---|---
A||T||TRIM 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* ## Q90C - *72*
CH1|CH2|CH3|CH4|CH5|CH6 CH1|CH2|CH3|CH4|CH5|CH6
@ -1087,6 +1236,26 @@ Models: WLtoys V911S, XK A110
### Sub_protocol E119 - *1* ### Sub_protocol E119 - *1*
Models: Eachine E119 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 # 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 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* ## E01X - *45*
Autobind protocol Autobind protocol
@ -1307,13 +1485,6 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---
A|E|T|R|ARM|FLIP|LED|HEADLESS|RTH 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* ## ESKY - *16*
CH1|CH2|CH3|CH4|CH5|CH6 CH1|CH2|CH3|CH4|CH5|CH6
@ -1493,93 +1664,6 @@ CH14| CH6 | -100% | 0% | | - | -
CH15| CH7 | -100% | 0% | - | - | +100% CH15| CH7 | -100% | 0% | - | - | +100%
CH16| CH8 | -100% | 0% | - | - | - 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* ## NCC1701 - *44*
Model: Air Hogs Star Trek USS Enterprise NCC-1701-A 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 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* ## Realacc - *76*
Model: Realacc R11 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 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* ## YD717 - *8*
Autobind protocol Autobind protocol