diff --git a/Multiprotocol/FrSkyR9_sx1276.ino b/Multiprotocol/FrSkyR9_sx1276.ino index 1f2f752..057e303 100644 --- a/Multiprotocol/FrSkyR9_sx1276.ino +++ b/Multiprotocol/FrSkyR9_sx1276.ino @@ -102,6 +102,61 @@ static void __attribute__((unused)) FrSkyR9_build_packet() packet[25] = crc >> 8; // high byte } +static uint8_t __attribute__((unused)) FrSkyR9_CRC8(uint8_t *p, uint8_t l) +{ + uint8_t crc = 0xFF; + for (uint8_t i = 0; i < l; i++) + { + crc = crc ^ p[i]; + for ( uint8_t j = 0; j < 8; j++ ) + if ( crc & 0x80 ) + { + crc <<= 1; + crc ^= 0x07; + } + else + crc <<= 1; + } + return crc; +} + +static void __attribute__((unused)) FrSkyR9_build_EU_packet() +{ + //ID + packet[0] = rx_tx_addr[1]; + packet[1] = rx_tx_addr[2]; + packet[2] = rx_tx_addr[3]; + + //Hopping + packet[3] = FrSkyX_chanskip; // step size and last 2 channels start index + + //RX number + packet[4] = RX_num; // receiver number from OpenTX + + //Channels + //TODO FrSkyX_channels(5,4); // Set packet[5]=failsafe and packet[6..11]=4 channels data + + //Bind + if(IS_BIND_IN_PROGRESS) + { + packet[5] = 0x01; // bind indicator + if((sub_protocol & 2) == 0) + packet[5] |= 0x10; // 16CH + // if(sub_protocol & 1) + // packet[5] |= 0x20; // 868 + if(binding_idx&0x01) + packet[5] |= 0x40; // telem OFF + if(binding_idx&0x02) + packet[5] |= 0x80; // ch9-16 + } + + //Sequence and send SPort + packet[12] = (FrSkyX_RX_Seq << 4)|0x08; //TX=8 at startup + + //CRC + packet[13] = FrSkyR9_CRC8(packet, 13); +} + uint16_t initFrSkyR9() { //Check frequencies @@ -127,6 +182,12 @@ uint16_t initFrSkyR9() FrSkyFormat=1; // 8 channels debugln("%dCH", FrSkyFormat&1 ? 8:16); + //EU packet length + if( (sub_protocol & 0xFD) == R9_EU ) + packet_length=14; + else + packet_length=26; + //SX1276 Init SX1276_SetMode(true, false, SX1276_OPMODE_SLEEP); SX1276_SetMode(true, false, SX1276_OPMODE_STDBY); @@ -168,14 +229,17 @@ uint16_t FrSkyR9_callback() // output_power: 2 dBm (17-(15-OutputPower) (if pa_boost_pin == true)) SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18 //Build packet - FrSkyR9_build_packet(); + if( packet_length == 26 ) + FrSkyR9_build_packet(); + else + FrSkyR9_build_EU_packet(); phase++; return 460; // Frequency settle time case FRSKYR9_DATA: //Set RF switch to TX SX1276_SetTxRxMode(TX_EN); //Send packet - SX1276_WritePayloadToFifo(packet, 26); + SX1276_WritePayloadToFifo(packet, packet_length); SX1276_SetMode(true, false, SX1276_OPMODE_TX); #if not defined TELEMETRY phase=FRSKYR9_FREQ; diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino index f549c2f..8bb3847 100644 --- a/Multiprotocol/Multi_Names.ino +++ b/Multiprotocol/Multi_Names.ino @@ -125,7 +125,7 @@ const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2"; const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow"; const char STR_SUBTYPE_POTENSIC[] = "\x03""A20"; const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC"; -const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410"; +const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410""FZ8xx"; const char STR_SUBTYPE_FX816[] = "\x03""P38"; const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 "; const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch"; @@ -141,7 +141,7 @@ const char STR_SUBTYPE_WFLY[] = "\x06""WFR0xS"; const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync"; const char STR_SUBTYPE_PELIKAN[] = "\x04""Pro\0""Lite"; const char STR_SUBTYPE_V761[] = "\x03""3CH""4CH"; -const char STR_SUBTYPE_RLINK[] = "\x07""Surface"; +const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 "; enum { @@ -225,7 +225,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE }, #endif #if defined(FLYZONE_A7105_INO) - {PROTO_FLYZONE, STR_FLYZONE, 1, STR_SUBTYPE_FLYZONE, OPTION_NONE }, + {PROTO_FLYZONE, STR_FLYZONE, 2, STR_SUBTYPE_FLYZONE, OPTION_NONE }, #endif #if defined(FQ777_NRF24L01_INO) {PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE }, @@ -327,7 +327,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE }, #endif #if defined(RLINK_CC2500_INO) - {PROTO_RLINK, STR_RLINK, 1, STR_SUBTYPE_RLINK, OPTION_RFTUNE }, + {PROTO_RLINK, STR_RLINK, 2, STR_SUBTYPE_RLINK, OPTION_RFTUNE }, #endif #if defined(SCANNER_CC2500_INO) // {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE }, diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index f6040ce..a95f791 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 1 -#define VERSION_PATCH_LEVEL 45 +#define VERSION_PATCH_LEVEL 46 //****************** // Protocols diff --git a/Multiprotocol/RadioLink_cc2500.ino b/Multiprotocol/RadioLink_cc2500.ino index 6f3ad5e..45ca8a6 100644 --- a/Multiprotocol/RadioLink_cc2500.ino +++ b/Multiprotocol/RadioLink_cc2500.ino @@ -23,6 +23,7 @@ #define RLINK_TX_PACKET_LEN 33 #define RLINK_RX_PACKET_LEN 15 #define RLINK_TX_ID_LEN 4 +#define RLINK_HOP 16 enum { RLINK_DATA = 0x00, @@ -40,15 +41,32 @@ const PROGMEM uint8_t RLINK_init_values[] = { static void __attribute__((unused)) RLINK_init() { + hopping_frequency[RLINK_HOP]=16; + // channels order depend on ID and currently unknown... #ifdef RLINK_FORCE_ID + //surface memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN); + memcpy(hopping_frequency,"\x1\xF\x8\x9\x2\x5\x0\x6\x4\xE\xB\xD\x3\xA\xC\x7",RLINK_HOP); //end value is value*12+6 + //air + memcpy(rx_tx_addr,"\xFC\x11\x0D\x20",RLINK_TX_ID_LEN); + memcpy(hopping_frequency,"\xB\xC\xF\xE\x5\x9\x8\x4\x3\x7\xA\x1\xD\x0\x6\x2",RLINK_HOP); //end value is value*12 #endif - // channels order depend on ID and currently unknown... - memcpy(hopping_frequency,"\x12\xBA\x66\x72\x1E\x42\x06\x4E\x36\xAE\x8A\xA2\x2A\x7E\x96\x5A",16); // 1,15,8,9,2,5,0,6,4,14,11,13,3,10,12,7 : end value is value*12+6 + // set channels value based on ID + for(uint8_t i=0;i<=RLINK_HOP;i++) + hopping_frequency[i]=3*(4*hopping_frequency[i]+(rx_tx_addr[0]&3)); - rf_ch_num=(random(0xfefefefe)&0x0F)+1; // 0x01..0x10 - hopping_frequency[rf_ch_num]=0xC6; + // replace one of the channel randomely + rf_ch_num=random(0xfefefefe)&0x0F; // 0x00..0x0F + if(hopping_frequency[RLINK_HOP]==0xC9) + hopping_frequency[rf_ch_num]=0xC6; + else + hopping_frequency[rf_ch_num]=hopping_frequency[RLINK_HOP]; + + debug("Hop(%d):", rf_ch_num); + for(uint8_t i=0;i3?0x03:0x01; // packet type: 0x01 normal, 0x03 request telemetry - //if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard + if(sub_protocol) + packet[1] = 0x21; //air 0x21 on dump but it looks to support telemetry + else + {//surface + packet[1] = 0x00; + //radiolink additionnal ID which is working only on a small set of RXs + //if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard + } + packet[1] |= packet_count>3?0x03:0x01; // packet type: 0x01 normal, 0x03 request telemetry // ID memcpy(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN); @@ -132,7 +157,7 @@ static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet() packet_count++; if(packet_count>5) packet_count=0; - //debug("P:"); + //debug("P(%02X):",hopping_frequency[pseudo & 0x0F]); //for(uint8_t i=0;i= 2000) - {//1 packet every 20ms + {//1 telemetry packet every 100ms pps_timer = millis(); + pps_counter*=5; debugln("%d pps", pps_counter); TX_LQI = pps_counter; //Max=100% pps_counter = 0;