diff --git a/Multiprotocol/A7105_SPI.ino b/Multiprotocol/A7105_SPI.ino index ad8f7be..1698725 100644 --- a/Multiprotocol/A7105_SPI.ino +++ b/Multiprotocol/A7105_SPI.ino @@ -191,16 +191,10 @@ const uint8_t PROGMEM HUBSAN_A7105_regs[] = { 0xFF, 0xFF, 0xFF }; const uint8_t PROGMEM FLYSKY_A7105_regs[] = { -/* 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, 0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, 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_PLUS 0xAA201041 diff --git a/Multiprotocol/A7105_joysway.ino b/Multiprotocol/A7105_joysway.ino index b153c79..1aed90d 100644 --- a/Multiprotocol/A7105_joysway.ino +++ b/Multiprotocol/A7105_joysway.ino @@ -35,7 +35,7 @@ static int joysway_init() //uint8_t vco_calibration0; //uint8_t vco_calibration1; - counter = 0; + phase = 0; next_ch = 0x30; for (i = 0; i < 0x33; i++) @@ -100,7 +100,7 @@ static void joysway_build_packet() //Calculate: //Center = 0x5d9 //1 % = 5 - packet[0] = counter == 0 ? 0xdd : 0xff; + packet[0] = phase == 0 ? 0xdd : 0xff; packet[1] = (MProtocol_id_master >> 24) & 0xff; packet[2] = (MProtocol_id_master >> 16) & 0xff; packet[3] = (MProtocol_id_master >> 8) & 0xff; @@ -118,7 +118,7 @@ static void joysway_build_packet() packet[9] = 0x64; packet[12] = 0x64; packet[13] = 0x64; - packet[14] = counter == 0 ? 0x30 : 0xaa; + packet[14] = phase == 0 ? 0x30 : 0xaa; uint8_t value = 0; for (int i = 0; i < 15; i++) { value += packet[i]; } packet[15] = value; @@ -127,21 +127,21 @@ static void joysway_build_packet() static uint16_t joysway_cb() { uint8_t ch; - if (counter == 254) { - counter = 0; + if (phase == 254) { + phase = 0; A7105_WriteID(0x5475c52a); ch = 0x0a; - } else if (counter == 2) { + } else if (phase == 2) { A7105_WriteID(MProtocol_id_master); ch = 0x30; } else { - if ((counter & 0x01) ^ EVEN_ODD) { + if ((phase & 0x01) ^ EVEN_ODD) { ch = 0x30; } else { ch = next_ch; } } - if (! ((counter & 0x01) ^ EVEN_ODD)) { + if (! ((phase & 0x01) ^ EVEN_ODD)) { next_ch++; if (next_ch == 0x45) next_ch = 0x30; @@ -149,7 +149,7 @@ static uint16_t joysway_cb() joysway_build_packet(); A7105_Strobe(A7105_STANDBY); A7105_WriteData(16, ch); - counter++; + phase++; return 6000; } diff --git a/Multiprotocol/Cc2500_skyartec.ino b/Multiprotocol/Cc2500_skyartec.ino new file mode 100644 index 0000000..7f3a932 --- /dev/null +++ b/Multiprotocol/Cc2500_skyartec.ino @@ -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 . + */ + +#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 \ No newline at end of file diff --git a/Multiprotocol/DSM2_cyrf6936.ino b/Multiprotocol/DSM2_cyrf6936.ino index 0882d77..19a969e 100644 --- a/Multiprotocol/DSM2_cyrf6936.ino +++ b/Multiprotocol/DSM2_cyrf6936.ino @@ -17,7 +17,6 @@ #include "iface_cyrf6936.h" -#define DSM2_NUM_CHANNELS 7 #define RANDOM_CHANNELS 0 // disabled //#define RANDOM_CHANNELS 1 // enabled #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[9] = sum & 0xff; packet[10] = 0x01; //??? - packet[11] = DSM2_NUM_CHANNELS; + packet[11] = option>3?option:option+4; 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; else -#if DSM2_NUM_CHANNELS < 8 - packet[12] = 0x01; -#else - packet[12] = 0x02; -#endif + packet[12] = option<8?0x01:0x02; packet[13] = 0x00; //??? for(i = 8; i < 14; 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)// { -#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 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) ) - { - //BIND_DONE; binding = 0; - } if (sub_protocol==DSMX) { packet[0] = cyrfmfg_id[2]; @@ -463,12 +462,16 @@ uint16_t ReadDsm2() set_sop_data_crc(); if (cyrf_state == DSM2_CH2_CHECK_A) { - #if DSM2_NUM_CHANNELS < 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 - #else - cyrf_state = DSM2_CH1_WRITE_B; // change from CH2_CHECK_A to CH1_WRITE_A (to transmit upper) - #endif + if(option < 8) + { + cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) + if(option>3) + return 11000 - CH1_CH2_DELAY - WRITE_DELAY ; // force 11ms if option>3 ie 4,5,6,7 channels @11ms + 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 cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) diff --git a/Multiprotocol/Nrf24l01_fy326.ino b/Multiprotocol/FY326_nrf24l01.ino similarity index 51% rename from Multiprotocol/Nrf24l01_fy326.ino rename to Multiprotocol/FY326_nrf24l01.ino index 68234db..6417bfb 100644 --- a/Multiprotocol/Nrf24l01_fy326.ino +++ b/Multiprotocol/FY326_nrf24l01.ino @@ -4,38 +4,26 @@ 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, + 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 Deviation. If not, see . + along with Multiprotocol. If not, see . */ - +// Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29 #if defined(FY326_NRF24L01_INO) #include "iface_nrf24l01.h" -#define INITIAL_WAIT 500 -#define FY326_PERIOD 1500 // Timeout for callback in uSec -#define FY326_CHKTIME 300 // Time to wait if packet not yet received or sent -#define FY326_SIZE 15 +#define FY326_INITIAL_WAIT 500 +#define FY326_PACKET_PERIOD 1500 +#define FY326_PACKET_CHKTIME 300 +#define FY326_PACKET_SIZE 15 #define FY326_BIND_COUNT 16 - -#define CHANNEL_FLIP AUX1 -#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; +#define FY326_RF_BIND_CHANNEL 0x17 +#define FY326_NUM_RF_CHANNELS 5 enum { FY326_INIT1 = 0, @@ -47,97 +35,86 @@ enum { FY319_BIND2, }; -// Bit vector from bit position -#define BV(bit) (1 << bit) +#define rxid channel -#define CHAN_RANGE (PPM_MAX - PPM_MIN) -static uint8_t scale_channel(uint8_t ch, uint8_t destMin, uint8_t destMax) +#define CHAN_TO_TRIM(chanval) ((chanval/10)-10) +static void __attribute__((unused)) FY326_send_packet(uint8_t bind) { - uint32_t chanval = Servo_data[ch]; - uint32_t range = destMax - destMin; - - 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[0] = rx_tx_addr[3]; + if(bind) packet[1] = 0x55; - } else { - packet[1] = GET_FLAG(CHANNEL_HEADLESS, 0x80) - | GET_FLAG(CHANNEL_RTH, 0x40) - | GET_FLAG(CHANNEL_FLIP, 0x02) - | GET_FLAG(CHANNEL_CALIBRATE, 0x01) - | GET_FLAG(CHANNEL_EXPERT, 4); - } - packet[2] = 200 - scale_channel(AILERON, 0, 200); // aileron 1 - packet[3] = scale_channel(ELEVATOR, 0, 200); // elevator 2 - packet[4] = 200 - scale_channel(RUDDER, 0, 200); // rudder 4 - packet[5] = scale_channel(THROTTLE, 0, 200); // throttle 3 + else + packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless + | GET_FLAG(Servo_AUX2, 0x40) // RTH + | GET_FLAG(Servo_AUX1, 0x02) // Flip + | GET_FLAG(Servo_AUX5, 0x01) // Calibrate + | GET_FLAG(Servo_AUX4, 0x04); // Expert + packet[2] = 200 - convert_channel_8b_scale(AILERON, 0, 200); // aileron + packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator + packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder + packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle if(sub_protocol == FY319) { packet[6] = 255 - scale_channel(AILERON, 0, 255); packet[7] = scale_channel(ELEVATOR, 0, 255); packet[8] = 255 - scale_channel(RUDDER, 0, 255); } else { - packet[6] = txid[0]; - packet[7] = txid[1]; - packet[8] = txid[2]; - } + packet[6] = rx_tx_addr[0]; + packet[7] = rx_tx_addr[1]; + packet[8] = rx_tx_addr[2]; + } packet[9] = CHAN_TO_TRIM(packet[2]); // aileron_trim; packet[10] = CHAN_TO_TRIM(packet[3]); // elevator_trim; packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim; packet[12] = 0; // throttle_trim; 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 NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); 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_SetTxRxMode(TX_EN); if(sub_protocol == FY319) NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address else 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_0A_RX_ADDR_P0, 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, (uint8_t *)"\x15\x59\x23\xc6\x29", 5); NRF24L01_FlushTx(); NRF24L01_FlushRx(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes + NRF24L01_WriteReg(NRF24L01_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_11_RX_PW_P0, FY326_SIZE); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL); + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, FY326_PACKET_SIZE); + NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL); NRF24L01_SetBitrate(NRF24L01_BR_250K); NRF24L01_SetPower(); NRF24L01_Activate(0x73); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); + NRF24L01_Activate(0x73); } -static uint16_t fy326_callback() +uint16_t fy326_callback() { uint8_t i; switch (phase) { @@ -191,77 +168,76 @@ static uint16_t fy326_callback() break; case FY326_BIND1: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) { // RX fifo data ready - NRF24L01_ReadPayload(packet, FY326_SIZE); + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE); rxid = packet[13]; - txid[0] = 0xaa; + rx_tx_addr[0] = 0xAA; NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); BIND_DONE; phase = FY326_DATA; - } else if (bind_counter-- == 0) { + } + else + if (bind_counter-- == 0) + { bind_counter = FY326_BIND_COUNT; NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); - send_packet(1); + FY326_send_packet(1); phase = FY326_BIND2; - return FY326_CHKTIME; + return FY326_PACKET_CHKTIME; } break; case FY326_BIND2: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS)) { // TX data sent - // switch to RX mode + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS)) + { // TX data sent -> switch to RX mode NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_FlushRx(); NRF24L01_SetTxRxMode(RX_EN); phase = FY326_BIND1; - } else { - return FY326_CHKTIME; } + else + return FY326_PACKET_CHKTIME; break; case FY326_DATA: - send_packet(0); + FY326_send_packet(0); break; } - return FY326_PERIOD; + return FY326_PACKET_PERIOD; } -// Generate address to use from TX id and manufacturer id (STM32 unique id) -static void fy_txid() +static void __attribute__((unused)) FY326_initialize_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) { - for(uint8_t i=0; i<5; i++) - rf_chans[i] = txid[0] & ~0x80; + hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~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; + bind_counter = 0; + FY326_initialize_txid(); + fy326_init(); if(sub_protocol == FY319) phase = FY319_INIT1; else phase = FY326_INIT1; - bind_counter = FY326_BIND_COUNT; - fy_txid(); - fy326_init(); - return INITIAL_WAIT; + return FY326_INITIAL_WAIT; } -#endif +#endif diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 109586c..77036de 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -140,6 +140,9 @@ void setup() Servo_data[THROTTLE]=PPM_MIN_100; memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data)); + //Wait for every component to start + delay(100); + // Read status of bind button if( (PINB & _BV(5)) == 0x00 ) 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} 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 @@ -352,12 +355,6 @@ static void protocol_init() remote_callback = wk_cb; break; #endif -#if defined(FY326_NRF24L01_INO) - case MODE_FY326: - next_callback=FY326_setup(); - remote_callback = fy326_callback; - break; -#endif #if defined(ESKY150_NRF24L01_INO) case MODE_ESKY150: next_callback=esky150_setup(); @@ -371,7 +368,7 @@ static void protocol_init() break; #endif #if defined(HonTai_NRF24L01_INO) - case MODE_BlueFly: + case MODE_HonTai: next_callback=ht_setup(); remote_callback = ht_callback; break; @@ -388,6 +385,18 @@ static void protocol_init() remote_callback = ne260_cb; break; #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) case MODE_FLYSKY: @@ -512,6 +521,12 @@ static void protocol_init() next_callback=initSHENQI(); remote_callback = SHENQI_callback; break; +#endif +#if defined(FY326_NRF24L01_INO) + case MODE_FY326: + next_callback=initFY326(); + remote_callback = FY326_callback; + break; #endif } @@ -594,7 +609,7 @@ static void module_reset() case MODE_DEVO: CYRF_Reset(); 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(); break; } @@ -669,12 +684,13 @@ static void Mprotocol_serial_init() #include UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; + UCSR0A = 0 ; // Clear X2 bit //Set frame format to 8 data bits, even parity, 2 stop bits - UCSR0C |= (1<0) { - counter--; - if (! counter) { BIND_DONE; } + if (bind_phase>0) { + bind_phase--; + if (! bind_phase) { BIND_DONE; } NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bluefly_binding_adr_rf, 5); NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); NRF24L01_FlushTx(); @@ -141,42 +139,11 @@ static uint16_t bluefly_cb() { 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() { - initialize_tx_id(); - + hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2; + bluefly_binding_packet(); bluefly_init(); - - if(IS_AUTOBIND_FLAG_on) { - counter = BIND_BlueFly_COUNT; -// PROTOCOL_SetBindState(BIND_BlueFly_COUNT * 10); //8 seconds binding time - } else { - counter = 0; - } + if(IS_AUTOBIND_FLAG_on) { bind_phase = BIND_BlueFly_COUNT; } else { bind_phase = 0; } return 1000; } diff --git a/Multiprotocol/Nrf24l01_fbl100.ino b/Multiprotocol/Nrf24l01_fbl100.ino new file mode 100644 index 0000000..f25e368 --- /dev/null +++ b/Multiprotocol/Nrf24l01_fbl100.ino @@ -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 . + + 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 \ No newline at end of file diff --git a/Multiprotocol/Nrf24l01_h377.ino b/Multiprotocol/Nrf24l01_h377.ino index e8feaf3..439178d 100644 --- a/Multiprotocol/Nrf24l01_h377.ino +++ b/Multiprotocol/Nrf24l01_h377.ino @@ -133,19 +133,19 @@ static uint16_t h377_cb() { if(counter1ms==1) { NRF24L01_FlushTx(); } //------------------------- else if(counter1ms==2) { - if (counter>0) { + if (bind_phase>0) { NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)binding_adr_rf, 5); NRF24L01_WriteReg(NRF24L01_05_RF_CH, binding_ch); } } else if(counter1ms==3) { - if (counter >0) { - counter--; - if (! counter) { BIND_DONE; } // binding finished, change tx add + if (bind_phase >0) { + bind_phase--; + if (! bind_phase) { BIND_DONE; } // binding finished, change tx add 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(); } //------------------------- @@ -200,10 +200,10 @@ static uint16_t h377_setup() { h377_init(); if(IS_AUTOBIND_FLAG_on) { - counter = BIND_COUNT; + bind_phase = BIND_COUNT; BIND_IN_PROGRESS; } - else { counter = 0; } + else { bind_phase = 0; } return 1000; } diff --git a/Multiprotocol/Nrf24l01_ne260.ino b/Multiprotocol/Nrf24l01_ne260.ino index 32b5345..598c15b 100644 --- a/Multiprotocol/Nrf24l01_ne260.ino +++ b/Multiprotocol/Nrf24l01_ne260.ino @@ -162,7 +162,6 @@ uint8_t neChannel = 10; uint8_t neChannelOffset = 0; #define PACKET_NE_LENGTH 7 -static u32 bind_count; static uint16_t model_id = 0xA04A; uint8_t NE_ch[]={THROTTLE, RUDDER, ELEVATOR, AILERON, AUX1}; @@ -266,7 +265,6 @@ static uint16_t ne260_cb() { static uint16_t NE260_setup() { ne260_init(); - bind_count = 10000; state = NE260_BINDTX; return 10000; diff --git a/Multiprotocol/Nrf24l01_udi.ino b/Multiprotocol/Nrf24l01_udi.ino index ab8afa8..a8eac63 100644 --- a/Multiprotocol/Nrf24l01_udi.ino +++ b/Multiprotocol/Nrf24l01_udi.ino @@ -573,8 +573,7 @@ static uint16_t UDI_setup() packet_counter = 0; UDI_init(); phase = UDI_INIT2; - counter = BIND_UDI_COUNT; - + // observed on U839 TX set_tx_id(0x457C27); diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 5df7e3b..e0d4da0 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -46,6 +46,8 @@ #define DSM2_CYRF6936_INO #endif #ifdef CC2500_INSTALLED + #define SKYARTEC_CC2500_INO + #define FRSKY_CC2500_INO #define FRSKYX_CC2500_INO #endif @@ -53,12 +55,12 @@ #define HM830_NRF24L01_INO #define CFlie_NRF24L01_INO #define H377_NRF24L01_INO - #define FY326_NRF24L01_INO #define ESKY150_NRF24L01_INO -// #define BlueFly_NRF24L01_INO //probleme gene id #define HonTai_NRF24L01_INO #define UDI_NRF24L01_INO #define NE260_NRF24L01_INO + #define BlueFly_NRF24L01_INO //probleme gene id + #define FBL100_NRF24L01_INO // finir id #define BAYANG_NRF24L01_INO #define CG023_NRF24L01_INO @@ -72,7 +74,8 @@ #define YD717_NRF24L01_INO #define MT99XX_NRF24L01_INO #define MJXQ_NRF24L01_INO -// #define SHENQI_NRF24L01_INO + #define SHENQI_NRF24L01_INO + #define FY326_NRF24L01_INO #endif //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 /* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , 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 }, /* 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 }, /* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 9 */ {MODE_KN , FEILUN , 0 , P_HIGH , AUTOBIND , 0 }, @@ -158,6 +161,9 @@ const PPM_Parameters PPM_prot[15]= { H26D MODE_SHENQI NONE + MODE_FY326 + FY326 + FY319 RX_Num value between 0 and 15 diff --git a/Multiprotocol/multiprotocol.h b/Multiprotocol/multiprotocol.h index b2b9e81..12883c3 100644 --- a/Multiprotocol/multiprotocol.h +++ b/Multiprotocol/multiprotocol.h @@ -29,12 +29,13 @@ enum PROTOCOLS MODE_J6PRO = 43, // =>CYRF6936 MODE_H377=44, // =>NRF24L01 MODE_WK2x01 = 45, // =>CYRF6936 - MODE_FY326=46, // =>NRF24L01 - MODE_ESKY150=47, // =>NRF24L01 - MODE_BlueFly=48, // =>NRF24L01 - MODE_HonTai=49, // =>NRF24L01 - MODE_UDI=50, // =>NRF24L01 - MODE_NE260=51, // =>NRF24L01 + MODE_ESKY150=46, // =>NRF24L01 + MODE_BlueFly=47, // =>NRF24L01 + MODE_HonTai=48, // =>NRF24L01 + MODE_UDI=49, // =>NRF24L01 + MODE_NE260=50, // =>NRF24L01 + MODE_FBL100=51, // =>NRF24L01 + MODE_SKYARTEC=52, // =>CC2500 MODE_SERIAL = 0, // Serial commands MODE_FLYSKY = 1, // =>A7105 @@ -55,7 +56,8 @@ enum PROTOCOLS MODE_ESKY = 16, // =>NRF24L01 MODE_MT99XX=17, // =>NRF24L01 MODE_MJXQ=18, // =>NRF24L01 - MODE_SHENQI=19 // =>NRF24L01 + MODE_SHENQI=19, // =>NRF24L01 + MODE_FY326=20 // =>NRF24L01 }; enum Flysky { @@ -133,12 +135,22 @@ enum FY326 FY326 = 0, FY319 = 1 }; +enum HONTAI +{ + HONTAI = 0, + JJRCX1 = 1 +}; enum UDI { U816_V1 = 0, U816_V2, U839_2014 }; +enum FBL100 +{ + FBL100 = 0, + HP100 +}; #define NONE 0 #define P_HIGH 1 @@ -332,7 +344,8 @@ enum NRF_POWER // 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_2 = 0x6E, // -8dbm CC2500_POWER_3 = 0x7F, // -6dbm @@ -449,6 +462,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- MT99XX 17 MJXQ 18 SHENQI 19 + FY326 20 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -500,6 +514,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- X600 1 X800 2 H26D 3 + sub_protocol==FY326 + FY326 0 + FY319 1 Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; option_protocol value is -127..127 diff --git a/README.md b/README.md index 3c27e54..d223102 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,12 @@ CH1|CH2|CH3|CH4 ---|---|---|--- A|E|T|R +##CC2500 RF Module +###SKYARTEC +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- + ? | ? | ? | ? | ? | ? | ? + ##NRF24L01 RF Module ###BLUEFLY Autobind @@ -101,6 +107,16 @@ CH1|CH2|CH3|CH4 ---|---|---|--- A|E|T|R +###FBL100 +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- + ? | ? | ? | ? | ? | ? | ? | ? + +####Sub_protocol HP100 +Same channels assignement as above. + ###Fy326 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 -####Sub_protocol U816 V1 (orange) -####Sub_protocol U816 V2 (red) -####Sub_protocol U816 (2014) +####Sub_protocol U816_V1 (orange) +####Sub_protocol U816_V2 (red) +####Sub_protocol U839_2014 Same channels assignement as above. diff --git a/sync.ffs_db b/sync.ffs_db index 357e3b1..e2cbf55 100644 Binary files a/sync.ffs_db and b/sync.ffs_db differ