diff --git a/Multiprotocol/ESky150v2_cc2500.ino b/Multiprotocol/ESky150v2_cc2500.ino new file mode 100644 index 0000000..5a69838 --- /dev/null +++ b/Multiprotocol/ESky150v2_cc2500.ino @@ -0,0 +1,141 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Multiprotocol is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Multiprotocol. If not, see . + */ + +#if defined(ESKY150V2_CC2500_INO) + +#include "iface_nrf250k.h" + +//#define ESKY150V2_FORCE_ID + +#define ESKY150V2_PAYLOADSIZE 40 +#define ESKY150V2_BINDPAYLOADSIZE 150 +#define ESKY150V2_NFREQCHANNELS 70 +#define ESKY150V2_TXID_SIZE 4 +#define ESKY150V2_BIND_CHANNEL 0x00 +#define ESKY150V2_PACKET_PERIOD 10000 +#define ESKY150V2_BINDING_PACKET_PERIOD 57000 + +#ifdef ESKY150V2_FORCE_ID +const uint8_t PROGMEM ESKY150V2_hop[ESKY150V2_NFREQCHANNELS]= { + 0x07, 0x47, 0x09, 0x27, 0x0B, 0x42, 0x0D, 0x35, 0x17, 0x40, 0x26, 0x3D, 0x16, 0x43, 0x06, 0x2A, 0x24, 0x44, + 0x0E, 0x38, 0x20, 0x48, 0x22, 0x2D, 0x2B, 0x39, 0x0F, 0x36, 0x23, 0x46, 0x14, 0x3B, 0x1A, 0x41, 0x10, 0x2E, + 0x1E, 0x28, 0x0C, 0x49, 0x1D, 0x3E, 0x29, 0x2C, 0x25, 0x30, 0x1C, 0x2F, 0x1B, 0x33, 0x13, 0x31, 0x0A, 0x37, + 0x12, 0x3C, 0x18, 0x4B, 0x11, 0x45, 0x21, 0x4A, 0x1F, 0x3F, 0x15, 0x32, 0x08, 0x3A, 0x19, 0x34 }; +/*const uint8_t PROGMEM ESKY150V2_hop2[40]= { + 0x19, 0x23, 0x13, 0x1B, 0x09, 0x22, 0x14, 0x27, 0x06, 0x26, 0x16, 0x24, 0x0B, 0x2A, 0x0E, 0x1C, 0x11, 0x1E, + 0x08, 0x29, 0x0D, 0x28, 0x18, 0x2D, 0x12, 0x20, 0x0C, 0x1A, 0x10, 0x1D, 0x07, 0x2C, 0x0A, 0x2B, 0x0F, 0x25, + 0x15, 0x1F, 0x17, 0x21 };*/ +#endif + +static void __attribute__((unused)) ESKY150V2_set_freq(void) +{ + calc_fh_channels(ESKY150V2_NFREQCHANNELS); + + #ifdef ESKY150V2_FORCE_ID + for(uint8_t i=0; i= ESKY150V2_NFREQCHANNELS) + hopping_frequency_no = 0; + NRF250K_SetPower(); //Set power level + + packet[0] = 0xFA; // Unknown + packet[1] = 0x41; // Unknown + packet[2] = 0x08; // Unknown + packet[3] = 0x00; // Unknown + for(uint8_t i=0;i<16;i++) + { + uint16_t channel=convert_channel_16b_limit(CH_TAER[i],200,1000); + packet[4+2*i] = channel; + packet[5+2*i] = channel>>8; + } + NRF250K_WritePayload(packet, ESKY150V2_PAYLOADSIZE); +} + +uint16_t ESKY150V2_callback() +{ + if(option==0) option=1; //Trick the RF component auto select system + if(IS_BIND_DONE) + { + #ifdef MULTI_SYNC + telemetry_set_input_sync(ESKY150V2_PACKET_PERIOD); + #endif + ESKY150V2_send_packet(); + } + else + { + BIND_DONE; //Need full power for bind to work... + NRF250K_SetPower(); //Set power level + BIND_IN_PROGRESS; + NRF250K_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE); + if (--bind_counter == 0) + { + BIND_DONE; + // Change TX address from bind to normal mode + NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); + memset(packet,0x00,ESKY150V2_PAYLOADSIZE); + } + return 30000; //ESKY150V2_BINDING_PACKET_PERIOD; + } + return ESKY150V2_PACKET_PERIOD; +} + +uint16_t initESKY150V2() +{ + if(option==0) option=1; // Trick the RF component auto select system + NRF250K_Init(); + ESKY150V2_set_freq(); + hopping_frequency_no = 0; + + #ifdef ESKY150V2_FORCE_ID // ID taken from TX dump + rx_tx_addr[0]=0x87;rx_tx_addr[1]=0x5B;rx_tx_addr[2]=0x2C;rx_tx_addr[3]=0x5D; + #endif + + memset(packet,0x00,ESKY150V2_BINDPAYLOADSIZE); + + if(IS_BIND_IN_PROGRESS) + { + NRF250K_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address + NRF250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel + memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); + memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE); + packet[8]=0x41; //Unknown + packet[9]=0x88; //Unknown + packet[10]=0x41; //Unknown + memset(&packet[11],0xAA,4); //Unknown + memcpy(&packet[15],hopping_frequency,ESKY150V2_NFREQCHANNELS); // hop table + //for(uint8_t i=0; i<40; i++) // Does not seem to be needed + // packet[i+85]=pgm_read_byte_near( &ESKY150V2_hop2[i] ); + bind_counter=100; + } + else + NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE); + return 50000; +} + +#endif diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 9b62074..ea7834a 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -66,3 +66,4 @@ 66,PROPEL,74-Z 67,LR12,LR12,LR12_6ch 68,Skyartec +69,ESKYv2,150V2 diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino index 2b13173..64f3e70 100644 --- a/Multiprotocol/Multi_Names.ino +++ b/Multiprotocol/Multi_Names.ino @@ -51,6 +51,7 @@ const char STR_GW008[] ="GW008"; const char STR_DM002[] ="DM002"; const char STR_CABELL[] ="Cabell"; const char STR_ESKY150[] ="Esky150"; +const char STR_ESKY150V2[] ="EskyV2"; const char STR_H8_3D[] ="H8 3D"; const char STR_CORONA[] ="Corona"; const char STR_CFLIE[] ="CFlie"; @@ -121,6 +122,7 @@ const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410"; const char STR_SUBTYPE_FX816[] = "\x03""P38"; const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 "; const char STR_SUBTYPE_ESKY150[] = "\x03""4CH""7CH"; +const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2"; const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0"; const char STR_SUBTYPE_XK[] = "\x04""X450""X420"; const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch"; @@ -195,6 +197,9 @@ const mm_protocol_definition multi_protocols[] = { #if defined(ESKY150_NRF24L01_INO) {PROTO_ESKY150, STR_ESKY150, 2, STR_SUBTYPE_ESKY150, OPTION_NONE }, #endif + #if defined(ESKY150V2_CC2500_INO) + {PROTO_ESKY150V2, STR_ESKY150V2, 1, STR_SUBTYPE_ESKY150V2, OPTION_RFTUNE }, + #endif #if defined(FLYSKY_A7105_INO) {PROTO_FLYSKY, STR_FLYSKY, 5, STR_SUBTYPE_FLYSKY, OPTION_NONE }, #endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 50f2c74..a35f5d7 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 0 -#define VERSION_PATCH_LEVEL 94 +#define VERSION_PATCH_LEVEL 95 //****************** // Protocols @@ -95,6 +95,7 @@ enum PROTOCOLS PROTO_PROPEL = 66, // =>NRF24L01 PROTO_FRSKYL = 67, // =>CC2500 PROTO_SKYARTEC = 68, // =>CC2500 + PROTO_ESKY150V2 = 69, // =>CC2500+NRF24L01 }; enum Flysky @@ -397,7 +398,7 @@ enum MultiPacketTypes //*** Tests *** //*************** #define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 ) -#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC ) +#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC || protocol==ESKY150V2 ) //*************** //*** Flags *** @@ -760,6 +761,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- PROPEL 66 FRSKYL 67 SKYARTEC 68 + ESKY150V2 69 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 03a91bf..15e3695 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -75,7 +75,11 @@ uint32_t blink=0,last_signal=0; // uint16_t counter; uint8_t channel; -uint8_t packet[50]; +#ifdef ESKY150V2_CC2500_INO + uint8_t packet[150]; +#else + uint8_t packet[50]; +#endif #define NUM_CHN 16 // Servo data @@ -97,7 +101,7 @@ uint16_t packet_period; uint8_t packet_count; uint8_t packet_sent; uint8_t packet_length; -#ifdef HOTT_CC2500_INO +#if defined(HOTT_CC2500_INO) || defined(ESKY150V2_CC2500_INO) uint8_t hopping_frequency[75]; #else uint8_t hopping_frequency[50]; @@ -1211,6 +1215,14 @@ static void protocol_init() remote_callback = FrSky_Rx_callback; break; #endif + #if defined(ESKY150V2_CC2500_INO) + case PROTO_ESKY150V2: + PE1_off; + PE2_on; //antenna RF2 + next_callback = initESKY150V2(); + remote_callback = ESKY150V2_callback; + break; + #endif #endif #ifdef CYRF6936_INSTALLED #if defined(DSM_CYRF6936_INO) @@ -2183,6 +2195,51 @@ static uint32_t random_id(uint16_t address, uint8_t create_new) #endif } +// Generate frequency hopping sequence in the range [02..77] +static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch) +{ + uint8_t idx = 0; + uint32_t rnd = MProtocol_id; + uint8_t max=(num_ch/3)+2; + + while (idx < num_ch) + { + uint8_t i; + uint8_t 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 a distance of 5 between consecutive channels + if (idx !=0) + { + if(hopping_frequency[idx-1]>next_ch) + { + if(hopping_frequency[idx-1]-next_ch<5) + continue; + } + else + if(next_ch-hopping_frequency[idx-1]<5) + continue; + } + // Check that it's not duplicated 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 < max) || (next_ch >= 27 && next_ch <= 50 && count_27_50 < max) || (next_ch >= 51 && count_51_74 < max) ) + hopping_frequency[idx++] = next_ch;//find hopping frequency + } +} + /**************************/ /**************************/ /** Interrupt routines **/ diff --git a/Multiprotocol/NRF250K_EMU.ino b/Multiprotocol/NRF250K_EMU.ino index daf959a..cb57672 100644 --- a/Multiprotocol/NRF250K_EMU.ino +++ b/Multiprotocol/NRF250K_EMU.ino @@ -383,7 +383,11 @@ static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t l } //CC2500 #ifdef CC2500_INSTALLED - uint8_t buf[35]; + #if defined(ESKY150V2_CC2500_INO) + uint8_t buf[158]; + #else + uint8_t buf[35]; + #endif uint8_t last = 0; uint8_t i; @@ -417,10 +421,40 @@ static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t l CC2500_Strobe(CC2500_SFTX); // packet length CC2500_WriteReg(CC2500_3F_TXFIFO, last); - // nrf packet - CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last); - // transmit - CC2500_Strobe(CC2500_STX); + // transmit nrf packet + uint8_t *buff=buf; + uint8_t status; + if(last>63) + { + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63); + CC2500_Strobe(CC2500_STX); + last-=63; + buff+=63; + while(last) + {//Loop until all the data is sent + do + {// Wait for the FIFO to become available + status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST); + } + while((status&0x7F)>31 && (status&0x80)==0); + if(last>31) + {//Send 31 bytes + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31); + last-=31; + buff+=31; + } + else + {//Send last bytes + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); + last=0; + } + } + } + else + {//Send packet + CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last); + CC2500_Strobe(CC2500_STX); + } #endif } diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index f249354..85f5f6a 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -212,6 +212,7 @@ #endif #ifndef CC2500_INSTALLED #undef CORONA_CC2500_INO + #undef ESKY150V2_CC2500_INO #undef FRSKYD_CC2500_INO #undef FRSKYL_CC2500_INO #undef FRSKYV_CC2500_INO @@ -237,6 +238,7 @@ #undef E01X_NRF24L01_INO #undef ESKY_NRF24L01_INO #undef ESKY150_NRF24L01_INO + #undef ESKY150V2_CC2500_INO // Use both CC2500 and NRF code #undef FQ777_NRF24L01_INO #undef FX816_NRF24L01_INO #undef FY326_NRF24L01_INO diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index f65ead2..616c4aa 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -177,6 +177,7 @@ //The protocols below need a CC2500 to be installed #define CORONA_CC2500_INO +#define ESKY150V2_CC2500_INO //Need both CC2500 and NRF #define FRSKYL_CC2500_INO #define FRSKYD_CC2500_INO #define FRSKYV_CC2500_INO @@ -552,6 +553,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { PROTO_ESKY150 ESKY150_4CH ESKY150_7CH + PROTO_ESKY150V2 + NONE PROTO_FLYSKY Flysky V9X9 diff --git a/Protocols_Details.md b/Protocols_Details.md index c232209..98eac0a 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -82,6 +82,7 @@ CFlie|38|CFlie||||||||NRF24L01| [E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200 [ESky](Protocols_Details.md#ESKY---16)|16|ESky|Std|ET4||||||NRF24L01| [ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01| +[ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|||||||||CC2500|NRF24L01 [Flysky](Protocols_Details.md#FLYSKY---1)|1|Flysky|V9x9|V6x6|V912|CX20||||A7105| [Flysky AFHDS2A](Protocols_Details.md#FLYSKY-AFHDS2A---28)|28|PWM_IBUS|PPM_IBUS|PWM_SBUS|PPM_SBUS|||||A7105| [Flysky AFHDS2A RX](Protocols_Details.md#FLYSKY-AFHDS2A-RX---56)|56|||||||||A7105| @@ -936,6 +937,17 @@ A|E|T|R|FMODE|AUX6|AUX7 FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..100%=>3 +## ESKY150V2 - *69* +ESky protocol for small models: 150 V2, F150 V2, Blade 70s(?) + +Notes: + - RX output will match the eSky standard TAER independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI. + - To run this protocol you need both CC2500 and NRF24L01 to be enabled for code reasons, only the CC2500 is really used. + +CH1|CH2|CH3|CH4|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14|CH15 |CH16 +---|---|---|---|----||----|----|----|----|----|----|----|----|----|----|---- +A|E|T|R|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14 |CH15 |CH16 + ## FX816 - *58* Model: FEI XIONG FX816 P38