Mis à jours protocole FY326

This commit is contained in:
tipouic 2016-03-19 11:03:24 +01:00
parent f6b4db1618
commit 8da823e9fc
15 changed files with 698 additions and 240 deletions

View File

@ -191,16 +191,10 @@ const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
0xFF, 0xFF, 0xFF 0xFF, 0xFF, 0xFF
}; };
const uint8_t PROGMEM FLYSKY_A7105_regs[] = { const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
/*
0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, 0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50,
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f,
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, 0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
0x01, 0x0f, 0xff 0x01, 0x0f, 0xff
*/
-1, 0x42, 0x00, 0x14, 0x00, -1 , -1 , 0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50,
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f,
0x13, 0xc3, 0x00, -1, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
0x01, 0x0f, -1
}; };
#define ID_NORMAL 0x55201041 #define ID_NORMAL 0x55201041
#define ID_PLUS 0xAA201041 #define ID_PLUS 0xAA201041

View File

@ -35,7 +35,7 @@ static int joysway_init()
//uint8_t vco_calibration0; //uint8_t vco_calibration0;
//uint8_t vco_calibration1; //uint8_t vco_calibration1;
counter = 0; phase = 0;
next_ch = 0x30; next_ch = 0x30;
for (i = 0; i < 0x33; i++) for (i = 0; i < 0x33; i++)
@ -100,7 +100,7 @@ static void joysway_build_packet()
//Calculate: //Calculate:
//Center = 0x5d9 //Center = 0x5d9
//1 % = 5 //1 % = 5
packet[0] = counter == 0 ? 0xdd : 0xff; packet[0] = phase == 0 ? 0xdd : 0xff;
packet[1] = (MProtocol_id_master >> 24) & 0xff; packet[1] = (MProtocol_id_master >> 24) & 0xff;
packet[2] = (MProtocol_id_master >> 16) & 0xff; packet[2] = (MProtocol_id_master >> 16) & 0xff;
packet[3] = (MProtocol_id_master >> 8) & 0xff; packet[3] = (MProtocol_id_master >> 8) & 0xff;
@ -118,7 +118,7 @@ static void joysway_build_packet()
packet[9] = 0x64; packet[9] = 0x64;
packet[12] = 0x64; packet[12] = 0x64;
packet[13] = 0x64; packet[13] = 0x64;
packet[14] = counter == 0 ? 0x30 : 0xaa; packet[14] = phase == 0 ? 0x30 : 0xaa;
uint8_t value = 0; uint8_t value = 0;
for (int i = 0; i < 15; i++) { value += packet[i]; } for (int i = 0; i < 15; i++) { value += packet[i]; }
packet[15] = value; packet[15] = value;
@ -127,21 +127,21 @@ static void joysway_build_packet()
static uint16_t joysway_cb() static uint16_t joysway_cb()
{ {
uint8_t ch; uint8_t ch;
if (counter == 254) { if (phase == 254) {
counter = 0; phase = 0;
A7105_WriteID(0x5475c52a); A7105_WriteID(0x5475c52a);
ch = 0x0a; ch = 0x0a;
} else if (counter == 2) { } else if (phase == 2) {
A7105_WriteID(MProtocol_id_master); A7105_WriteID(MProtocol_id_master);
ch = 0x30; ch = 0x30;
} else { } else {
if ((counter & 0x01) ^ EVEN_ODD) { if ((phase & 0x01) ^ EVEN_ODD) {
ch = 0x30; ch = 0x30;
} else { } else {
ch = next_ch; ch = next_ch;
} }
} }
if (! ((counter & 0x01) ^ EVEN_ODD)) { if (! ((phase & 0x01) ^ EVEN_ODD)) {
next_ch++; next_ch++;
if (next_ch == 0x45) if (next_ch == 0x45)
next_ch = 0x30; next_ch = 0x30;
@ -149,7 +149,7 @@ static uint16_t joysway_cb()
joysway_build_packet(); joysway_build_packet();
A7105_Strobe(A7105_STANDBY); A7105_Strobe(A7105_STANDBY);
A7105_WriteData(16, ch); A7105_WriteData(16, ch);
counter++; phase++;
return 6000; return 6000;
} }

View File

@ -0,0 +1,183 @@
/*
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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(SKYARTEC_CC2500_INO)
#include "iface_cc2500.h"
#define TX_ADDR ((binding_idx >> 16) & 0xff)
#define TX_CHANNEL ((binding_idx >> 24) & 0xff)
enum {
SKYARTEC_PKT1 = 0,
SKYARTEC_SLEEP1,
SKYARTEC_PKT2,
SKYARTEC_SLEEP2,
SKYARTEC_PKT3,
SKYARTEC_SLEEP3,
SKYARTEC_PKT4,
SKYARTEC_SLEEP4,
SKYARTEC_PKT5,
SKYARTEC_SLEEP5,
SKYARTEC_PKT6,
SKYARTEC_LAST,
};
static void skyartec_init() {
CC2500_Reset();
cc2500_writeReg(CC2500_16_MCSM2, 0x07);
cc2500_writeReg(CC2500_17_MCSM1, 0x30);
cc2500_writeReg(CC2500_1E_WOREVT1, 0x87);
cc2500_writeReg(CC2500_1F_WOREVT0, 0x6b);
cc2500_writeReg(CC2500_20_WORCTRL, 0xf8);
cc2500_writeReg(CC2500_2A_PTEST, 0x7f);
cc2500_writeReg(CC2500_2B_AGCTEST, 0x3f);
cc2500_writeReg(CC2500_0B_FSCTRL1, 0x09);
cc2500_writeReg(CC2500_0C_FSCTRL0, 0x00);
cc2500_writeReg(CC2500_0D_FREQ2, 0x5d);
cc2500_writeReg(CC2500_0E_FREQ1, 0x93);
cc2500_writeReg(CC2500_0F_FREQ0, 0xb1);
cc2500_writeReg(CC2500_10_MDMCFG4, 0x2d);
cc2500_writeReg(CC2500_11_MDMCFG3, 0x20);
cc2500_writeReg(CC2500_12_MDMCFG2, 0x73);
cc2500_writeReg(CC2500_13_MDMCFG1, 0x22);
cc2500_writeReg(CC2500_14_MDMCFG0, 0xf8);
cc2500_writeReg(CC2500_0A_CHANNR, 0xcd);
cc2500_writeReg(CC2500_15_DEVIATN, 0x50);
cc2500_writeReg(CC2500_21_FREND1, 0xb6);
cc2500_writeReg(CC2500_22_FREND0, 0x10);
cc2500_writeReg(CC2500_18_MCSM0, 0x18);
cc2500_writeReg(CC2500_19_FOCCFG, 0x1d);
cc2500_writeReg(CC2500_1A_BSCFG, 0x1c);
cc2500_writeReg(CC2500_1B_AGCCTRL2, 0xc7);
cc2500_writeReg(CC2500_1C_AGCCTRL1, 0x00);
cc2500_writeReg(CC2500_1D_AGCCTRL0, 0xb2);
cc2500_writeReg(CC2500_23_FSCAL3, 0xea);
cc2500_writeReg(CC2500_24_FSCAL2, 0x0a);
cc2500_writeReg(CC2500_25_FSCAL1, 0x00);
cc2500_writeReg(CC2500_26_FSCAL0, 0x11);
cc2500_writeReg(CC2500_29_FSTEST, 0x59);
cc2500_writeReg(CC2500_2C_TEST2, 0x88);
cc2500_writeReg(CC2500_2D_TEST1, 0x31);
cc2500_writeReg(CC2500_2E_TEST0, 0x0b);
cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05);
cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05);
cc2500_writeReg(CC2500_09_ADDR, 0x43);
cc2500_writeReg(CC2500_06_PKTLEN, 0xff);
cc2500_writeReg(CC2500_04_SYNC1, 0x13);
cc2500_writeReg(CC2500_05_SYNC0, 0x18);
CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower();
cc2500_strobe(CC2500_SFTX);
cc2500_strobe(CC2500_SFRX);
cc2500_strobe(CC2500_SXOFF);
cc2500_strobe(CC2500_SIDLE);
}
static void add_pkt_suffix() {
int xor1 = 0;
int xor2 = 0;
for(int i = 3; i <= 16; i++) { xor1 ^= packet[i]; }
for(int i = 3; i <= 14; i++) { xor2 ^= packet[i]; }
int sum = packet[3] + packet[5] + packet[7] + packet[9] + packet[11] + packet[13];
packet[17] = xor1;
packet[18] = xor2;
packet[19] = sum & 0xff;
}
static void send_data_packet() {
//13 c5 01 0259 0168 0000 0259 030c 021a 0489 f3 7e 0a
packet[0] = 0x13; //Length
packet[1] = TX_ADDR; //Tx Addr?
packet[2] = 0x01; //???
for(int i = 0; i < 7; i++) {
uint32_t value = (uint32_t)Servo_data[i] * 0x280 / PPM_MAX + 0x280;
if(value < 0) { value = 0; }
if(value > 0x500) { value = 0x500; }
packet[3+2*i] = value >> 8;
packet[4+2*i] = value & 0xff;
}
add_pkt_suffix();
//for(int i = 0; i < 20; i++) printf("%02x ", packet[i]); printf("\n");
cc2500_writeReg(CC2500_04_SYNC1, ((binding_idx >> 0) & 0xff));
cc2500_writeReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff));
cc2500_writeReg(CC2500_09_ADDR, TX_ADDR);
cc2500_writeReg(CC2500_0A_CHANNR, TX_CHANNEL);
cc2500_writeFifo(packet, 20);
}
static void send_bind_packet() {
//0b 7d 01 01 b2 c5 4a 2f 00 00 c5 d6
packet[0] = 0x0b; //Length
packet[1] = 0x7d;
packet[2] = 0x01;
packet[3] = 0x01;
packet[4] = (binding_idx >> 24) & 0xff;
packet[5] = (binding_idx >> 16) & 0xff;
packet[6] = (binding_idx >> 8) & 0xff;
packet[7] = (binding_idx >> 0) & 0xff;
packet[8] = 0x00;
packet[9] = 0x00;
packet[10] = TX_ADDR;
uint8_t xore = 0;
for(int i = 3; i < 11; i++) { xore ^= packet[i]; }
packet[11] = xore;
cc2500_writeReg(CC2500_04_SYNC1, 0x7d);
cc2500_writeReg(CC2500_05_SYNC0, 0x7d);
cc2500_writeReg(CC2500_09_ADDR, 0x7d);
cc2500_writeReg(CC2500_0A_CHANNR, 0x7d);
cc2500_writeFifo(packet, 12);
}
static uint16_t skyartec_cb() {
if (state & 0x01) {
cc2500_strobe(CC2500_SIDLE);
if (state == SKYARTEC_LAST) { CC2500_SetPower(); state = SKYARTEC_PKT1; }
else { state++; }
return 3000;
}
if (state == SKYARTEC_PKT1 && bind_phase) {
send_bind_packet();
bind_phase--;
if(bind_phase == 0) { printf("Done binding\n"); }
} else { send_data_packet(); }
state++;
return 3000;
}
static uint8_t skyartec_setup() {
skyartec_init();
/* binding_idx = 0xb2c54a2f;
if (Model.fixed_id) {
binding_idx ^= Model.binding_idx + (Model.fixed_id << 16);
} else {
int partnum = CC2500_ReadReg(0xF0);
int vernum = CC2500_ReadReg(0xF1);
binding_idx ^= partnum << 24;
binding_idx ^= vernum << 16;
binding_idx ^= (vernum << 4 | partnum >> 4) << 8;
binding_idx ^= (partnum << 4 | vernum >> 4) << 8;
}
*/
binding_idx = MProtocol_id;
if (0 == (binding_idx & 0xff000000)) { binding_idx |= 0xb2; }
if (0 == (binding_idx & 0x00ff0000)) { binding_idx |= 0xc5; }
if (0 == (binding_idx & 0x0000ff00)) { binding_idx |= 0x4a; }
if (0 == (binding_idx & 0x000000ff)) { binding_idx |= 0x2f; }
bind_phase = 10000;
state = SKYARTEC_PKT1;
}
#endif

View File

@ -17,7 +17,6 @@
#include "iface_cyrf6936.h" #include "iface_cyrf6936.h"
#define DSM2_NUM_CHANNELS 7
#define RANDOM_CHANNELS 0 // disabled #define RANDOM_CHANNELS 0 // disabled
//#define RANDOM_CHANNELS 1 // enabled //#define RANDOM_CHANNELS 1 // enabled
#define BIND_CHANNEL 0x0d //13 This can be any odd channel #define BIND_CHANNEL 0x0d //13 This can be any odd channel
@ -132,15 +131,11 @@ static void __attribute__((unused)) build_bind_packet()
packet[8] = sum >> 8; packet[8] = sum >> 8;
packet[9] = sum & 0xff; packet[9] = sum & 0xff;
packet[10] = 0x01; //??? packet[10] = 0x01; //???
packet[11] = DSM2_NUM_CHANNELS; packet[11] = option>3?option:option+4;
if(sub_protocol==DSMX) //DSMX type if(sub_protocol==DSMX) //DSMX type
packet[12] = 0xb2; // Telemetry off: packet[12] = num_channels < 8 && Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_OFF ? 0xa2 : 0xb2; packet[12] = 0xb2; // Telemetry off: packet[12] = num_channels < 8 && Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_OFF ? 0xa2 : 0xb2;
else else
#if DSM2_NUM_CHANNELS < 8 packet[12] = option<8?0x01:0x02;
packet[12] = 0x01;
#else
packet[12] = 0x02;
#endif
packet[13] = 0x00; //??? packet[13] = 0x00; //???
for(i = 8; i < 14; i++) for(i = 8; i < 14; i++)
sum += packet[i]; sum += packet[i];
@ -166,34 +161,38 @@ static uint8_t __attribute__((unused)) PROTOCOL_SticksMoved(uint8_t init)
static void __attribute__((unused)) build_data_packet(uint8_t upper)// static void __attribute__((unused)) build_data_packet(uint8_t upper)//
{ {
#if DSM2_NUM_CHANNELS==4
const uint8_t ch_map[] = {0, 1, 2, 3, 0xff, 0xff, 0xff}; //Guess
#elif DSM2_NUM_CHANNELS==5
const uint8_t ch_map[] = {0, 1, 2, 3, 4, 0xff, 0xff}; //Guess
#elif DSM2_NUM_CHANNELS==6
const uint8_t ch_map[] = {1, 5, 2, 3, 0, 4, 0xff}; //HP6DSM
#elif DSM2_NUM_CHANNELS==7
const uint8_t ch_map[] = {1, 5, 2, 4, 3, 6, 0}; //DX6i
#elif DSM2_NUM_CHANNELS==8
const uint8_t ch_map[] = {1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 0xff, 0xff, 0xff, 0xff}; //DX8
#elif DSM2_NUM_CHANNELS==9
const uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 0xff, 0xff, 0xff, 0xff, 0xff}; //DM9
#elif DSM2_NUM_CHANNELS==10
const uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff};
#elif DSM2_NUM_CHANNELS==11
const uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 0xff, 0xff, 0xff};
#elif DSM2_NUM_CHANNELS==12
const uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 11, 0xff, 0xff};
#endif
uint8_t i; uint8_t i;
uint8_t bits; uint8_t bits;
uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //9 Channels - DM9 TX
switch(option>3?option:option+4) // Create channel map based on number of channels
{
case 12:
ch_map[11]=11; // 12 channels
case 11:
ch_map[10]=10; // 11 channels
case 10:
ch_map[9]=9; // 10 channels
break;
case 8:
memcpy(ch_map,"\x01\x05\x02\x03\x06\xFF\xFF\x04\x00\x07",10); // 8 channels - DX8 TX
break;
case 7:
memcpy(ch_map,"\x01\x05\x02\x04\x03\x06\x00",7); // 7 channels - DX6i TX
break;
case 6:
memcpy(ch_map,"\x01\x05\x02\x03\x00\x04\xFF",7); // 6 channels - HP6DSM TX
break;
case 4:
case 5:
memcpy(ch_map,"\x00\x01\x02\x03\xFF\xFF\xFF",7); // 4 channels - Guess
if(option&0x01)
ch_map[4]=4; // 5 channels - Guess
break;
}
// //
if( binding && PROTOCOL_SticksMoved(0) ) if( binding && PROTOCOL_SticksMoved(0) )
{
//BIND_DONE;
binding = 0; binding = 0;
}
if (sub_protocol==DSMX) if (sub_protocol==DSMX)
{ {
packet[0] = cyrfmfg_id[2]; packet[0] = cyrfmfg_id[2];
@ -463,12 +462,16 @@ uint16_t ReadDsm2()
set_sop_data_crc(); set_sop_data_crc();
if (cyrf_state == DSM2_CH2_CHECK_A) if (cyrf_state == DSM2_CH2_CHECK_A)
{ {
#if DSM2_NUM_CHANNELS < 8 if(option < 8)
cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) {
return 11000 - CH1_CH2_DELAY - WRITE_DELAY ; // Original is 22000 from deviation but it works better this way cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
#else if(option>3)
cyrf_state = DSM2_CH1_WRITE_B; // change from CH2_CHECK_A to CH1_WRITE_A (to transmit upper) return 11000 - CH1_CH2_DELAY - WRITE_DELAY ; // force 11ms if option>3 ie 4,5,6,7 channels @11ms
#endif else
return 22000 - CH1_CH2_DELAY - WRITE_DELAY ; // normal 22ms mode if option<=3 ie 4,5,6,7 channels @22ms
}
else
cyrf_state = DSM2_CH1_WRITE_B; // change from CH2_CHECK_A to CH1_WRITE_A (to transmit upper)
} }
else else
cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)

View File

@ -4,38 +4,26 @@
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Deviation is distributed in the hope that it will be useful, Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Deviation. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
// Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29
#if defined(FY326_NRF24L01_INO) #if defined(FY326_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
#define INITIAL_WAIT 500 #define FY326_INITIAL_WAIT 500
#define FY326_PERIOD 1500 // Timeout for callback in uSec #define FY326_PACKET_PERIOD 1500
#define FY326_CHKTIME 300 // Time to wait if packet not yet received or sent #define FY326_PACKET_CHKTIME 300
#define FY326_SIZE 15 #define FY326_PACKET_SIZE 15
#define FY326_BIND_COUNT 16 #define FY326_BIND_COUNT 16
#define FY326_RF_BIND_CHANNEL 0x17
#define CHANNEL_FLIP AUX1 #define FY326_NUM_RF_CHANNELS 5
#define CHANNEL_HEADLESS AUX2
#define CHANNEL_RTH AUX3
#define CHANNEL_CALIBRATE AUX4
#define CHANNEL_EXPERT AUX5
// frequency channel management
#define RF_BIND_CHANNEL 0x17
#define NUM_RF_CHANNELS 5
static uint8_t current_chan;
static uint8_t rf_chans[NUM_RF_CHANNELS];
static uint8_t txid[5];
static uint8_t rxid;
enum { enum {
FY326_INIT1 = 0, FY326_INIT1 = 0,
@ -47,97 +35,86 @@ enum {
FY319_BIND2, FY319_BIND2,
}; };
// Bit vector from bit position #define rxid channel
#define BV(bit) (1 << bit)
#define CHAN_RANGE (PPM_MAX - PPM_MIN) #define CHAN_TO_TRIM(chanval) ((chanval/10)-10)
static uint8_t scale_channel(uint8_t ch, uint8_t destMin, uint8_t destMax) static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
{ {
uint32_t chanval = Servo_data[ch]; packet[0] = rx_tx_addr[3];
uint32_t range = destMax - destMin; if(bind)
if (chanval < PPM_MIN) chanval = PPM_MIN;
else if (chanval > PPM_MAX) chanval = PPM_MAX;
return (range * (chanval - PPM_MIN)) / CHAN_RANGE + destMin;
}
#define GET_FLAG(ch, mask) (Servo_data[ch] > PPM_MIN_COMMAND ? mask : 0)
#define CHAN_TO_TRIM(chanval) ((uint8_t)(((uint16_t)chanval/10)-10)) // scale to [-10,10]. [-20,20] caused problems.
static void send_packet(uint8_t bind)
{
packet[0] = txid[3];
if (bind) {
packet[1] = 0x55; packet[1] = 0x55;
} else { else
packet[1] = GET_FLAG(CHANNEL_HEADLESS, 0x80) packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless
| GET_FLAG(CHANNEL_RTH, 0x40) | GET_FLAG(Servo_AUX2, 0x40) // RTH
| GET_FLAG(CHANNEL_FLIP, 0x02) | GET_FLAG(Servo_AUX1, 0x02) // Flip
| GET_FLAG(CHANNEL_CALIBRATE, 0x01) | GET_FLAG(Servo_AUX5, 0x01) // Calibrate
| GET_FLAG(CHANNEL_EXPERT, 4); | GET_FLAG(Servo_AUX4, 0x04); // Expert
} packet[2] = 200 - convert_channel_8b_scale(AILERON, 0, 200); // aileron
packet[2] = 200 - scale_channel(AILERON, 0, 200); // aileron 1 packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
packet[3] = scale_channel(ELEVATOR, 0, 200); // elevator 2 packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder
packet[4] = 200 - scale_channel(RUDDER, 0, 200); // rudder 4 packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
packet[5] = scale_channel(THROTTLE, 0, 200); // throttle 3
if(sub_protocol == FY319) { if(sub_protocol == FY319) {
packet[6] = 255 - scale_channel(AILERON, 0, 255); packet[6] = 255 - scale_channel(AILERON, 0, 255);
packet[7] = scale_channel(ELEVATOR, 0, 255); packet[7] = scale_channel(ELEVATOR, 0, 255);
packet[8] = 255 - scale_channel(RUDDER, 0, 255); packet[8] = 255 - scale_channel(RUDDER, 0, 255);
} }
else { else {
packet[6] = txid[0]; packet[6] = rx_tx_addr[0];
packet[7] = txid[1]; packet[7] = rx_tx_addr[1];
packet[8] = txid[2]; packet[8] = rx_tx_addr[2];
} }
packet[9] = CHAN_TO_TRIM(packet[2]); // aileron_trim; packet[9] = CHAN_TO_TRIM(packet[2]); // aileron_trim;
packet[10] = CHAN_TO_TRIM(packet[3]); // elevator_trim; packet[10] = CHAN_TO_TRIM(packet[3]); // elevator_trim;
packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim; packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim;
packet[12] = 0; // throttle_trim; packet[12] = 0; // throttle_trim;
packet[13] = rxid; packet[13] = rxid;
packet[14] = txid[4]; packet[14] = rx_tx_addr[4];
if (bind)
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
else
{
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
hopping_frequency_no %= FY326_NUM_RF_CHANNELS;
if (bind) {
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL);
} else {
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_chans[current_chan++]);
current_chan %= NUM_RF_CHANNELS;
} }
// clear packet status bits and TX FIFO // clear packet status bits and TX FIFO
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx(); NRF24L01_FlushTx();
NRF24L01_WritePayload(packet, FY326_SIZE); NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
NRF24L01_SetPower(); // Set tx_power
} }
static void fy326_init() static void __attribute__((unused)) FY326_init()
{ {
uint8_t rx_tx_addr[] = {0x15, 0x59, 0x23, 0xc6, 0x29};
NRF24L01_Initialize(); NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN); NRF24L01_SetTxRxMode(TX_EN);
if(sub_protocol == FY319) if(sub_protocol == FY319)
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address
else else
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, sizeof(rx_tx_addr)); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, sizeof(rx_tx_addr)); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
NRF24L01_FlushTx(); NRF24L01_FlushTx();
NRF24L01_FlushRx(); NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement on all data pipes
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, FY326_SIZE); NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, FY326_PACKET_SIZE);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL); NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
NRF24L01_SetBitrate(NRF24L01_BR_250K); NRF24L01_SetBitrate(NRF24L01_BR_250K);
NRF24L01_SetPower(); NRF24L01_SetPower();
NRF24L01_Activate(0x73); NRF24L01_Activate(0x73);
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
NRF24L01_Activate(0x73);
} }
static uint16_t fy326_callback() uint16_t fy326_callback()
{ {
uint8_t i; uint8_t i;
switch (phase) { switch (phase) {
@ -191,77 +168,76 @@ static uint16_t fy326_callback()
break; break;
case FY326_BIND1: case FY326_BIND1:
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) { // RX fifo data ready if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
NRF24L01_ReadPayload(packet, FY326_SIZE); { // RX fifo data ready
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
rxid = packet[13]; rxid = packet[13];
txid[0] = 0xaa; rx_tx_addr[0] = 0xAA;
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN); NRF24L01_SetTxRxMode(TX_EN);
BIND_DONE; BIND_DONE;
phase = FY326_DATA; phase = FY326_DATA;
} else if (bind_counter-- == 0) { }
else
if (bind_counter-- == 0)
{
bind_counter = FY326_BIND_COUNT; bind_counter = FY326_BIND_COUNT;
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN); NRF24L01_SetTxRxMode(TX_EN);
send_packet(1); FY326_send_packet(1);
phase = FY326_BIND2; phase = FY326_BIND2;
return FY326_CHKTIME; return FY326_PACKET_CHKTIME;
} }
break; break;
case FY326_BIND2: case FY326_BIND2:
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS)) { // TX data sent if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS))
// switch to RX mode { // TX data sent -> switch to RX mode
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_FlushRx(); NRF24L01_FlushRx();
NRF24L01_SetTxRxMode(RX_EN); NRF24L01_SetTxRxMode(RX_EN);
phase = FY326_BIND1; phase = FY326_BIND1;
} else {
return FY326_CHKTIME;
} }
else
return FY326_PACKET_CHKTIME;
break; break;
case FY326_DATA: case FY326_DATA:
send_packet(0); FY326_send_packet(0);
break; break;
} }
return FY326_PERIOD; return FY326_PACKET_PERIOD;
} }
// Generate address to use from TX id and manufacturer id (STM32 unique id) static void __attribute__((unused)) FY326_initialize_txid()
static void fy_txid()
{ {
txid[0] = (MProtocol_id_master >> 24) & 0xFF;
txid[1] = ((MProtocol_id_master >> 16) & 0xFF);
txid[2] = (MProtocol_id_master >> 8) & 0xFF;
txid[3] = MProtocol_id_master & 0xFF;
// for (uint8_t i = 0; i < sizeof(MProtocol_id_master); ++i) rand32_r(&MProtocol_id_master, 0);
txid[4] = MProtocol_id_master & 0xFF;
rf_chans[0] = txid[0] & 0x0F;
rf_chans[1] = 0x10 + (txid[0] >> 4);
rf_chans[2] = 0x20 + (txid[1] & 0x0F);
rf_chans[3] = 0x30 + (txid[1] >> 4);
rf_chans[4] = 0x40 + (txid[2] >> 4);
if(sub_protocol == FY319) { if(sub_protocol == FY319) {
for(uint8_t i=0; i<5; i++) hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~0x80;
rf_chans[i] = txid[0] & ~0x80; hopping_frequency[1] = (rx_tx_addr[0] >> 4) & ~0x80;
hopping_frequency[2] = (rx_tx_addr[1]&0x0f) & ~0x80;
hopping_frequency[3] = (rx_tx_addr[1] >> 4) & ~0x80;
hopping_frequency[4] = (rx_tx_addr[2] >> 4) & ~0x80;
} else {
hopping_frequency[0] = (rx_tx_addr[0]&0x0f);
hopping_frequency[1] = 0x10 + (rx_tx_addr[0] >> 4);
hopping_frequency[2] = 0x20 + (rx_tx_addr[1]&0x0f);
hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4);
hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4);
} }
} }
static uint16_t FY326_setup() uint16_t initFY326(void)
{ {
BIND_IN_PROGRESS; BIND_IN_PROGRESS; // autobind protocol
rxid = 0xaa; rxid = 0xaa;
bind_counter = 0;
FY326_initialize_txid();
fy326_init();
if(sub_protocol == FY319) if(sub_protocol == FY319)
phase = FY319_INIT1; phase = FY319_INIT1;
else else
phase = FY326_INIT1; phase = FY326_INIT1;
bind_counter = FY326_BIND_COUNT; return FY326_INITIAL_WAIT;
fy_txid();
fy326_init();
return INITIAL_WAIT;
} }
#endif
#endif

View File

@ -140,6 +140,9 @@ void setup()
Servo_data[THROTTLE]=PPM_MIN_100; Servo_data[THROTTLE]=PPM_MIN_100;
memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data)); memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data));
//Wait for every component to start
delay(100);
// Read status of bind button // Read status of bind button
if( (PINB & _BV(5)) == 0x00 ) if( (PINB & _BV(5)) == 0x00 )
BIND_BUTTON_FLAG_on; // If bind button pressed save the status for protocol id reset under hubsan BIND_BUTTON_FLAG_on; // If bind button pressed save the status for protocol id reset under hubsan
@ -148,7 +151,7 @@ void setup()
// after this mode_select will be one of {0000, 0001, ..., 1111} // after this mode_select will be one of {0000, 0001, ..., 1111}
mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0 mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0
//********************************** //**********************************
//mode_select=14; // here to test PPM //mode_select=1; // here to test PPM
//********************************** //**********************************
// Update LED // Update LED
@ -352,12 +355,6 @@ static void protocol_init()
remote_callback = wk_cb; remote_callback = wk_cb;
break; break;
#endif #endif
#if defined(FY326_NRF24L01_INO)
case MODE_FY326:
next_callback=FY326_setup();
remote_callback = fy326_callback;
break;
#endif
#if defined(ESKY150_NRF24L01_INO) #if defined(ESKY150_NRF24L01_INO)
case MODE_ESKY150: case MODE_ESKY150:
next_callback=esky150_setup(); next_callback=esky150_setup();
@ -371,7 +368,7 @@ static void protocol_init()
break; break;
#endif #endif
#if defined(HonTai_NRF24L01_INO) #if defined(HonTai_NRF24L01_INO)
case MODE_BlueFly: case MODE_HonTai:
next_callback=ht_setup(); next_callback=ht_setup();
remote_callback = ht_callback; remote_callback = ht_callback;
break; break;
@ -388,6 +385,18 @@ static void protocol_init()
remote_callback = ne260_cb; remote_callback = ne260_cb;
break; break;
#endif #endif
#if defined(SKYARTEC_CC2500_INO)
case MODE_SKYARTEC:
next_callback=skyartec_setup();
remote_callback = skyartec_cb;
break;
#endif
#if defined(FBL100_NRF24L01_INO)
case MODE_FBL100:
next_callback=fbl_setup();
remote_callback = ne260_cb;
break;
#endif
#if defined(FLYSKY_A7105_INO) #if defined(FLYSKY_A7105_INO)
case MODE_FLYSKY: case MODE_FLYSKY:
@ -512,6 +521,12 @@ static void protocol_init()
next_callback=initSHENQI(); next_callback=initSHENQI();
remote_callback = SHENQI_callback; remote_callback = SHENQI_callback;
break; break;
#endif
#if defined(FY326_NRF24L01_INO)
case MODE_FY326:
next_callback=initFY326();
remote_callback = FY326_callback;
break;
#endif #endif
} }
@ -594,7 +609,7 @@ static void module_reset()
case MODE_DEVO: case MODE_DEVO:
CYRF_Reset(); CYRF_Reset();
break; break;
default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY, MODE_MT99XX, MODE_MJXQ, MODE_SHENQI default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY, MODE_MT99XX, MODE_MJXQ, MODE_SHENQI, MODE_FY326
NRF24L01_Reset(); NRF24L01_Reset();
break; break;
} }
@ -669,12 +684,13 @@ static void Mprotocol_serial_init()
#include <util/setbaud.h> #include <util/setbaud.h>
UBRR0H = UBRRH_VALUE; UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE; UBRR0L = UBRRL_VALUE;
UCSR0A = 0 ; // Clear X2 bit
//Set frame format to 8 data bits, even parity, 2 stop bits //Set frame format to 8 data bits, even parity, 2 stop bits
UCSR0C |= (1<<UPM01)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); UCSR0C = (1<<UPM01)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
while ( UCSR0A & (1 << RXC0) )//flush receive buffer while ( UCSR0A & (1 << RXC0) )//flush receive buffer
UDR0; UDR0;
//enable reception and RC complete interrupt //enable reception and RC complete interrupt
UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);//rx enable and interrupt UCSR0B = (1<<RXEN0)|(1<<RXCIE0);//rx enable and interrupt
UCSR0B |= (1<<TXEN0);//tx enable UCSR0B |= (1<<TXEN0);//tx enable
} }
@ -684,9 +700,10 @@ static void PPM_Telemetry_serial_init()
//9600 bauds //9600 bauds
UBRR0H = 0x00; UBRR0H = 0x00;
UBRR0L = 0x67; UBRR0L = 0x67;
UCSR0A = 0 ; // Clear X2 bit
//Set frame format to 8 data bits, none, 1 stop bit //Set frame format to 8 data bits, none, 1 stop bit
UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00); UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
UCSR0B |= (1<<TXEN0);//tx enable UCSR0B = (1<<TXEN0);//tx enable
} }
#endif #endif

View File

@ -25,8 +25,6 @@
static uint8_t hopping_frequency_start; static uint8_t hopping_frequency_start;
static uint8_t bluefly_binding_adr_rf[TXID_BlueFly_SIZE]={0x32,0xaa,0x45,0x45,0x78}; // fixed binding ids for all planes static uint8_t bluefly_binding_adr_rf[TXID_BlueFly_SIZE]={0x32,0xaa,0x45,0x45,0x78}; // fixed binding ids for all planes
// bluefly_rf_adr_buf can be used for fixed id
static uint8_t bluefly_rf_adr_buf[TXID_BlueFly_SIZE]; // ={0x13,0x88,0x46,0x57,0x76};
static uint8_t bind_payload[PAYLOAD_BlueFly_SIZE]; static uint8_t bind_payload[PAYLOAD_BlueFly_SIZE];
@ -37,7 +35,7 @@ static void bluefly_binding_packet(void)
{ {
int i; int i;
for (i = 0; i < TXID_BlueFly_SIZE; ++i) for (i = 0; i < TXID_BlueFly_SIZE; ++i)
bind_payload[i] = bluefly_rf_adr_buf[i]; bind_payload[i] = rx_tx_addr[i];
bind_payload[i++] = hopping_frequency_start; bind_payload[i++] = hopping_frequency_start;
for (; i < PAYLOAD_BlueFly_SIZE; ++i) bind_payload[i] = 0x55; for (; i < PAYLOAD_BlueFly_SIZE; ++i) bind_payload[i] = 0x55;
} }
@ -47,8 +45,8 @@ static void bluefly_init() {
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable p0 rx NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable p0 rx
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bluefly_rf_adr_buf, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bluefly_rf_adr_buf, 5); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOAD_BlueFly_SIZE); // payload size = 12 NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOAD_BlueFly_SIZE); // payload size = 12
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81 NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81
@ -110,7 +108,7 @@ static uint16_t bluefly_cb() {
bluefly_ch_data(); bluefly_ch_data();
break; break;
case 1: case 1:
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bluefly_rf_adr_buf, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_start + hopping_frequency_no*2); NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_start + hopping_frequency_no*2);
hopping_frequency_no++; hopping_frequency_no++;
hopping_frequency_no %= 15; hopping_frequency_no %= 15;
@ -120,9 +118,9 @@ static uint16_t bluefly_cb() {
case 2: case 2:
break; break;
case 3: case 3:
if (counter>0) { if (bind_phase>0) {
counter--; bind_phase--;
if (! counter) { BIND_DONE; } if (! bind_phase) { BIND_DONE; }
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bluefly_binding_adr_rf, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bluefly_binding_adr_rf, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81);
NRF24L01_FlushTx(); NRF24L01_FlushTx();
@ -141,42 +139,11 @@ static uint16_t bluefly_cb() {
return 1000; // send 1 binding packet and 1 data packet per 9ms return 1000; // send 1 binding packet and 1 data packet per 9ms
} }
// Generate internal id from TX id and manufacturer id (STM32 unique id)
static void initialize_tx_id() {
uint32_t lfsr = 0x7649eca9ul;
if (Model.fixed_id) {
for (uint8_t i = 0, j = 0; i < sizeof(Model.fixed_id); ++i, j += 8)
rand32_r(&lfsr, (Model.fixed_id >> j) & 0xff);
}
// Pump zero bytes for LFSR to diverge more
for (int i = 0; i < TXID_BlueFly_SIZE; ++i) rand32_r(&lfsr, 0);
for (uint8_t i = 0; i < TXID_BlueFly_SIZE; ++i) {
bluefly_rf_adr_buf[i] = lfsr & 0xff;
rand32_r(&lfsr, i);
}
printf("Effective id: %02X%02X%02X%02X%02X\r\n", bluefly_rf_adr_buf[0], bluefly_rf_adr_buf[1], bluefly_rf_adr_buf[2], bluefly_rf_adr_buf[3], bluefly_rf_adr_buf[4]);
// Use LFSR to seed frequency hopping sequence after another
// divergence round
for (uint8_t i = 0; i < sizeof(lfsr); ++i) rand32_r(&lfsr, 0);
hopping_frequency_start = ((lfsr >> 8) % 47) + 2;
bluefly_binding_packet();
}
static uint16_t BlueFly_setup() { static uint16_t BlueFly_setup() {
initialize_tx_id(); hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2;
bluefly_binding_packet();
bluefly_init(); bluefly_init();
if(IS_AUTOBIND_FLAG_on) { bind_phase = BIND_BlueFly_COUNT; } else { bind_phase = 0; }
if(IS_AUTOBIND_FLAG_on) {
counter = BIND_BlueFly_COUNT;
// PROTOCOL_SetBindState(BIND_BlueFly_COUNT * 10); //8 seconds binding time
} else {
counter = 0;
}
return 1000; return 1000;
} }

View File

@ -0,0 +1,282 @@
/*
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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
rewrite v977/v966 protocol to improve reliability
*/
#if defined(FBL100_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define BIND_FBL_COUNT 800
#define FBL_SIZE 5
#define FREQUENCE_FBL_NUM 20
static uint8_t binding_fbl_adr_rf[5]; // fixed binding ids for all planes
static uint8_t bind_fbl_buf_array[4][10];
static unsigned int fbl_data[8];
// HiSky protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence
// which does not depend on this id and is passed explicitly in binding sequence. So we are free
// to generate this sequence as we wish. It should be in the range [02..77]
static void calc_fbl_channels() {
int idx = 0;
uint32_t rnd = MProtocol_id;
while (idx < FREQUENCE_FBL_NUM) {
int i;
int count_2_26 = 0, count_27_50 = 0, count_51_74 = 0;
rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization
// Use least-significant byte. 73 is prime, so channels 76..77 are unused
uint8_t next_ch = ((rnd >> 8) % 73) + 2;
// Keep the distance 2 between the channels - either odd or even
if (((next_ch ^ MProtocol_id) & 0x01 )== 0) { continue; }
// Check that it's not duplicate and spread uniformly
for (i = 0; i < idx; i++) {
if(hopping_frequency[i] == next_ch) { break; }
if(hopping_frequency[i] <= 26) { count_2_26++; }
else if (hopping_frequency[i] <= 50) { count_27_50++; }
else { count_51_74++; }
}
if (i != idx) { continue; }
if ((next_ch <= 26 && count_2_26 < 8) ||(next_ch >= 27 && next_ch <= 50 && count_27_50 < 8) ||(next_ch >= 51 && count_51_74 < 8)) {
hopping_frequency[idx++] = next_ch;
}
}
}
static void fbl100_build_binding_packet(void) {
uint8_t i;
unsigned int sum;
uint8_t sum_l,sum_h;
sum = 0;
for(i=0;i<5;i++) { sum += rx_tx_addr[i]; }
sum_l = (uint8_t)sum;
sum >>= 8;
sum_h = (uint8_t)sum;
bind_fbl_buf_array[0][0] = 0xff;
bind_fbl_buf_array[0][1] = 0xaa;
bind_fbl_buf_array[0][2] = 0x55;
for(i=3;i<8;i++) { bind_fbl_buf_array[0][i] = rx_tx_addr[i-3]; }
for(i=1;i<4;i++) {
bind_fbl_buf_array[i][0] = sum_l;
bind_fbl_buf_array[i][1] = sum_h;
bind_fbl_buf_array[i][2] = i-1;
}
for(i=0;i<7;i++) { bind_fbl_buf_array[1][i+3] = hopping_frequency[i]; }
for(i=0;i<7;i++) { bind_fbl_buf_array[2][i+3] = hopping_frequency[i+7]; }
for(i=0;i<6;i++) { bind_fbl_buf_array[3][i+3] = hopping_frequency[i+14]; }
binding_idx = 0;
}
static void hp100_build_binding_packet(void) {
memcpy(packet, rx_tx_addr, 5);
packet[5] = hopping_frequency[0]; // start address
for (uint8_t i = 6; i < 12; i++) { packet[i] = 0x55; }
}
static void config_nrf24l01() {
NRF24L01_Initialize();
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable p0 rx
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // 0:No Auto Acknoledgement; 1:Auto Acknoledgement
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // fbl100/v922's packet size = 10, hp100 = 12
// 2-bytes CRC, radio off
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
NRF24L01_SetBitrate(sub_protocol == HP100? NRF24L01_BR_250K:NRF24L01_BR_1M); //hp100:250kbps; fbl100: 1Mbps
NRF24L01_SetPower();
NRF24L01_FlushTx();
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
}
// FBL100 channel sequence: AILE ELEV THRO RUDD GEAR PITH, channel data value is from 0 to 1000
static void fbl100_build_ch_data() {
uint32_t temp;
uint8_t i;
for (i = 0; i< 8; i++) {
temp = (uint32_t)Servo_data[i] * 500/PPM_MAX + 500;
if (i == 2) { temp = 1000 -temp; } // It is clear that fbl100's thro stick is made reversely,so I adjust it here on purposely
if (temp < 0) { fbl_data[i] = 0; }
else if (temp > 1000) { fbl_data[i] = 1000; }
else { fbl_data[i] = (unsigned int)temp; }
packet[i] = (uint8_t)fbl_data[i];
}
packet[8] = (uint8_t)((fbl_data[0]>>8)&0x0003);
packet[8] |= (uint8_t)((fbl_data[1]>>6)&0x000c);
packet[8] |= (uint8_t)((fbl_data[2]>>4)&0x0030);
packet[8] |= (uint8_t)((fbl_data[3]>>2)&0x00c0);
packet[9] = (uint8_t)((fbl_data[4]>>8)&0x0003);
packet[9] |= (uint8_t)((fbl_data[5]>>6)&0x000c);
packet[9] |= (uint8_t)((fbl_data[6]>>4)&0x0030);
packet[9] |= (uint8_t)((fbl_data[7]>>2)&0x00c0);
}
static void hp100_build_ch_data() {
uint32_t temp;
uint8_t i;
for (i = 0; i< 8; i++) {
temp = (uint32_t)Servo_data[i] * 300/PPM_MAX + 500;
if (temp < 0) { temp = 0; }
else if (temp > 1000) { temp = 1000; }
if (i == 3 || i == 5) { temp = 1000 -temp; } // hp100's rudd and pit channel are made reversely,so I adjust them on purposely
fbl_data[i] = (unsigned int)temp;
packet[i] = (uint8_t)fbl_data[i];
}
packet[8] = (uint8_t)((fbl_data[0]>>8)&0x0003);
packet[8] |= (uint8_t)((fbl_data[1]>>6)&0x000c);
packet[8] |= (uint8_t)((fbl_data[2]>>4)&0x0030);
packet[8] |= (uint8_t)((fbl_data[3]>>2)&0x00c0);
packet[9] = (uint8_t)((fbl_data[4]>>8)&0x0003);
packet[9] |= (uint8_t)((fbl_data[5]>>6)&0x000c);
packet[9] |= (uint8_t)((fbl_data[6]>>4)&0x0030);
packet[9] |= (uint8_t)((fbl_data[7]>>2)&0x00c0);
unsigned char l, h, t;
l=h=0xff;
for(i=0; i<10; i++ ) {
h ^= packet[i];
h ^= h>>4;
t = h;
h = l;
l = t;
t = (l<<4) | (l>>4);
h^=((t<<2) | (t>>6)) & 0x1f;
h^=t&0xf0;
l^=((t<<1) | (t>>7)) & 0xe0;
}
packet[10] = h;
packet[11] = l;
}
static uint16_t fbl100_cb() {
switch(phase) {
case 0:
fbl100_build_ch_data();
break;
case 1:
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
hopping_frequency_no++;
if (hopping_frequency_no >= FREQUENCE_FBL_NUM) { hopping_frequency_no = 0; }
break;
case 2:
NRF24L01_FlushTx();
NRF24L01_WritePayload(packet, packet_length);
break;
case 3:
break;
case 4:
if (bind_phase>0) {
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, binding_fbl_adr_rf, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81);
}
break;
case 5:
if (bind_phase >0) {
bind_phase--;
if (! bind_phase) { BIND_DONE; } // binding finished, change tx add
NRF24L01_FlushTx(); // must be invoked before NRF24L01_WritePayload()
NRF24L01_WritePayload(bind_fbl_buf_array[binding_idx], packet_length);
binding_idx++;
if (binding_idx >= 4)
binding_idx = 0;
}
break;
case 6:
break;
case 7:
NRF24L01_SetPower();
break;
default:
break;
}
phase++;
if (phase >=9) { phase = 0; } // send 1 binding packet and 1 data packet per 9ms
return 1000;
}
static uint16_t hp100_cb() {
switch(phase) {
case 0:
hp100_build_ch_data();
break;
case 1:
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[0] + hopping_frequency_no*2);
hopping_frequency_no++;
hopping_frequency_no %= 15;
NRF24L01_FlushTx();
NRF24L01_WritePayload(packet, packet_length);
break;
case 2:
if(bind_phase>0) { hp100_build_binding_packet(); }
break;
case 3:
if (bind_phase>0) {
bind_phase--;
if (! bind_phase) { BIND_DONE; }
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, binding_fbl_adr_rf, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81);
NRF24L01_FlushTx();
NRF24L01_WritePayload(packet, packet_length);
}
break;
case 4:
break;
case 5:
NRF24L01_SetPower();
break;
default:
break;
}
phase++;
if (phase >= 6) { phase = 0; } // send 1 binding packet and 1 data packet per 10ms
return 1000;
}
static uint8_t fbl_setup() {
calc_fbl_channels();
printf("FH Seq: ");
for (int i = 0; i < FREQUENCE_FBL_NUM; ++i) { printf("%d, ", hopping_frequency[i]); }
printf("\r\n");
// debut init
if (sub_protocol == HP100) {
packet_length = 12;
binding_fbl_adr_rf[0] = 0x32; binding_fbl_adr_rf[1] = 0xaa; binding_fbl_adr_rf[2] = 0x45;
binding_fbl_adr_rf[3] = 0x45; binding_fbl_adr_rf[4] = 0x78;
} else {
packet_length = 10;
binding_fbl_adr_rf[0] = 0x12; binding_fbl_adr_rf[1] = 0x23; binding_fbl_adr_rf[2] = 0x23;
binding_fbl_adr_rf[3] = 0x45; binding_fbl_adr_rf[4] = 0x78;
fbl100_build_binding_packet();
}
config_nrf24l01();
if(IS_AUTOBIND_FLAG_on) { bind_phase = BIND_FBL_COUNT; }
else { bind_phase = 0; }
// CLOCK_StartTimer(1000, sub_protocol == HP100?hp100_cb:fbl100_cb);
}
#endif

View File

@ -133,19 +133,19 @@ static uint16_t h377_cb() {
if(counter1ms==1) { NRF24L01_FlushTx(); } if(counter1ms==1) { NRF24L01_FlushTx(); }
//------------------------- //-------------------------
else if(counter1ms==2) { else if(counter1ms==2) {
if (counter>0) { if (bind_phase>0) {
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)binding_adr_rf, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)binding_adr_rf, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, binding_ch); NRF24L01_WriteReg(NRF24L01_05_RF_CH, binding_ch);
} }
} }
else if(counter1ms==3) { else if(counter1ms==3) {
if (counter >0) { if (bind_phase >0) {
counter--; bind_phase--;
if (! counter) { BIND_DONE; } // binding finished, change tx add if (! bind_phase) { BIND_DONE; } // binding finished, change tx add
NRF24L01_WritePayload(bind_buf_array,10); NRF24L01_WritePayload(bind_buf_array,10);
} }
} }
else if (counter1ms==4) { if (counter > 0) { NRF24L01_FlushTx(); }} else if (counter1ms==4) { if (bind_phase > 0) { NRF24L01_FlushTx(); }}
//------------------------- //-------------------------
else if(counter1ms==5) { NRF24L01_SetPower(); } else if(counter1ms==5) { NRF24L01_SetPower(); }
//------------------------- //-------------------------
@ -200,10 +200,10 @@ static uint16_t h377_setup() {
h377_init(); h377_init();
if(IS_AUTOBIND_FLAG_on) { if(IS_AUTOBIND_FLAG_on) {
counter = BIND_COUNT; bind_phase = BIND_COUNT;
BIND_IN_PROGRESS; BIND_IN_PROGRESS;
} }
else { counter = 0; } else { bind_phase = 0; }
return 1000; return 1000;
} }

View File

@ -162,7 +162,6 @@ uint8_t neChannel = 10;
uint8_t neChannelOffset = 0; uint8_t neChannelOffset = 0;
#define PACKET_NE_LENGTH 7 #define PACKET_NE_LENGTH 7
static u32 bind_count;
static uint16_t model_id = 0xA04A; static uint16_t model_id = 0xA04A;
uint8_t NE_ch[]={THROTTLE, RUDDER, ELEVATOR, AILERON, AUX1}; uint8_t NE_ch[]={THROTTLE, RUDDER, ELEVATOR, AILERON, AUX1};
@ -266,7 +265,6 @@ static uint16_t ne260_cb() {
static uint16_t NE260_setup() { static uint16_t NE260_setup() {
ne260_init(); ne260_init();
bind_count = 10000;
state = NE260_BINDTX; state = NE260_BINDTX;
return 10000; return 10000;

View File

@ -573,7 +573,6 @@ static uint16_t UDI_setup()
packet_counter = 0; packet_counter = 0;
UDI_init(); UDI_init();
phase = UDI_INIT2; phase = UDI_INIT2;
counter = BIND_UDI_COUNT;
// observed on U839 TX // observed on U839 TX
set_tx_id(0x457C27); set_tx_id(0x457C27);

View File

@ -46,6 +46,8 @@
#define DSM2_CYRF6936_INO #define DSM2_CYRF6936_INO
#endif #endif
#ifdef CC2500_INSTALLED #ifdef CC2500_INSTALLED
#define SKYARTEC_CC2500_INO
#define FRSKY_CC2500_INO #define FRSKY_CC2500_INO
#define FRSKYX_CC2500_INO #define FRSKYX_CC2500_INO
#endif #endif
@ -53,12 +55,12 @@
#define HM830_NRF24L01_INO #define HM830_NRF24L01_INO
#define CFlie_NRF24L01_INO #define CFlie_NRF24L01_INO
#define H377_NRF24L01_INO #define H377_NRF24L01_INO
#define FY326_NRF24L01_INO
#define ESKY150_NRF24L01_INO #define ESKY150_NRF24L01_INO
// #define BlueFly_NRF24L01_INO //probleme gene id
#define HonTai_NRF24L01_INO #define HonTai_NRF24L01_INO
#define UDI_NRF24L01_INO #define UDI_NRF24L01_INO
#define NE260_NRF24L01_INO #define NE260_NRF24L01_INO
#define BlueFly_NRF24L01_INO //probleme gene id
#define FBL100_NRF24L01_INO // finir id
#define BAYANG_NRF24L01_INO #define BAYANG_NRF24L01_INO
#define CG023_NRF24L01_INO #define CG023_NRF24L01_INO
@ -72,7 +74,8 @@
#define YD717_NRF24L01_INO #define YD717_NRF24L01_INO
#define MT99XX_NRF24L01_INO #define MT99XX_NRF24L01_INO
#define MJXQ_NRF24L01_INO #define MJXQ_NRF24L01_INO
// #define SHENQI_NRF24L01_INO #define SHENQI_NRF24L01_INO
#define FY326_NRF24L01_INO
#endif #endif
//Update this table to set which protocol and all associated settings are called for the corresponding dial number //Update this table to set which protocol and all associated settings are called for the corresponding dial number
@ -80,10 +83,10 @@ const PPM_Parameters PPM_prot[15]= {
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option // Dial Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 }, /* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 },
/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
/* 3 */ {MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, /* 3 */ {MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, // D7 fine tuning
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
/* 6 */ {MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 6 */ {MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // 6 channels @ 11ms
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
/* 9 */ {MODE_KN , FEILUN , 0 , P_HIGH , AUTOBIND , 0 }, /* 9 */ {MODE_KN , FEILUN , 0 , P_HIGH , AUTOBIND , 0 },
@ -158,6 +161,9 @@ const PPM_Parameters PPM_prot[15]= {
H26D H26D
MODE_SHENQI MODE_SHENQI
NONE NONE
MODE_FY326
FY326
FY319
RX_Num value between 0 and 15 RX_Num value between 0 and 15

View File

@ -29,12 +29,13 @@ enum PROTOCOLS
MODE_J6PRO = 43, // =>CYRF6936 MODE_J6PRO = 43, // =>CYRF6936
MODE_H377=44, // =>NRF24L01 MODE_H377=44, // =>NRF24L01
MODE_WK2x01 = 45, // =>CYRF6936 MODE_WK2x01 = 45, // =>CYRF6936
MODE_FY326=46, // =>NRF24L01 MODE_ESKY150=46, // =>NRF24L01
MODE_ESKY150=47, // =>NRF24L01 MODE_BlueFly=47, // =>NRF24L01
MODE_BlueFly=48, // =>NRF24L01 MODE_HonTai=48, // =>NRF24L01
MODE_HonTai=49, // =>NRF24L01 MODE_UDI=49, // =>NRF24L01
MODE_UDI=50, // =>NRF24L01 MODE_NE260=50, // =>NRF24L01
MODE_NE260=51, // =>NRF24L01 MODE_FBL100=51, // =>NRF24L01
MODE_SKYARTEC=52, // =>CC2500
MODE_SERIAL = 0, // Serial commands MODE_SERIAL = 0, // Serial commands
MODE_FLYSKY = 1, // =>A7105 MODE_FLYSKY = 1, // =>A7105
@ -55,7 +56,8 @@ enum PROTOCOLS
MODE_ESKY = 16, // =>NRF24L01 MODE_ESKY = 16, // =>NRF24L01
MODE_MT99XX=17, // =>NRF24L01 MODE_MT99XX=17, // =>NRF24L01
MODE_MJXQ=18, // =>NRF24L01 MODE_MJXQ=18, // =>NRF24L01
MODE_SHENQI=19 // =>NRF24L01 MODE_SHENQI=19, // =>NRF24L01
MODE_FY326=20 // =>NRF24L01
}; };
enum Flysky enum Flysky
{ {
@ -133,12 +135,22 @@ enum FY326
FY326 = 0, FY326 = 0,
FY319 = 1 FY319 = 1
}; };
enum HONTAI
{
HONTAI = 0,
JJRCX1 = 1
};
enum UDI enum UDI
{ {
U816_V1 = 0, U816_V1 = 0,
U816_V2, U816_V2,
U839_2014 U839_2014
}; };
enum FBL100
{
FBL100 = 0,
HP100
};
#define NONE 0 #define NONE 0
#define P_HIGH 1 #define P_HIGH 1
@ -332,7 +344,8 @@ enum NRF_POWER
// CC2500 power // CC2500 power
enum CC2500_POWER enum CC2500_POWER
{ {
CC2500_POWER_0 = 0xC5, // -12dbm CC2500_POWER_0 = 0x50, // -30dbm
//CC2500_POWER_0 = 0xC5, // -12dbm
CC2500_POWER_1 = 0x97, // -10dbm CC2500_POWER_1 = 0x97, // -10dbm
CC2500_POWER_2 = 0x6E, // -8dbm CC2500_POWER_2 = 0x6E, // -8dbm
CC2500_POWER_3 = 0x7F, // -6dbm CC2500_POWER_3 = 0x7F, // -6dbm
@ -449,6 +462,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
MT99XX 17 MT99XX 17
MJXQ 18 MJXQ 18
SHENQI 19 SHENQI 19
FY326 20
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
@ -500,6 +514,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
X600 1 X600 1
X800 2 X800 2
H26D 3 H26D 3
sub_protocol==FY326
FY326 0
FY319 1
Power value => 0x80 0=High/1=Low Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol; Stream[3] = option_protocol;
option_protocol value is -127..127 option_protocol value is -127..127

View File

@ -76,6 +76,12 @@ CH1|CH2|CH3|CH4
---|---|---|--- ---|---|---|---
A|E|T|R A|E|T|R
##CC2500 RF Module
###SKYARTEC
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
? | ? | ? | ? | ? | ? | ?
##NRF24L01 RF Module ##NRF24L01 RF Module
###BLUEFLY ###BLUEFLY
Autobind Autobind
@ -101,6 +107,16 @@ CH1|CH2|CH3|CH4
---|---|---|--- ---|---|---|---
A|E|T|R A|E|T|R
###FBL100
Autobind
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
? | ? | ? | ? | ? | ? | ? | ?
####Sub_protocol HP100
Same channels assignement as above.
###Fy326 ###Fy326
Autobind Autobind
@ -164,9 +180,9 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP 360|FLIP|VIDEO|LED|MODE 2 A|E|T|R|FLIP 360|FLIP|VIDEO|LED|MODE 2
####Sub_protocol U816 V1 (orange) ####Sub_protocol U816_V1 (orange)
####Sub_protocol U816 V2 (red) ####Sub_protocol U816_V2 (red)
####Sub_protocol U816 (2014) ####Sub_protocol U839_2014
Same channels assignement as above. Same channels assignement as above.

Binary file not shown.