From 8b05e55ebd7e037fa4bde300bf237aa74657aed5 Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Sun, 23 Jan 2022 17:56:00 +0100 Subject: [PATCH] MT99xx2/PA18: new protocol --- Lua_scripts/MultiChan.txt | 1 + Multiprotocol/MT99xx_ccnrf.ino | 133 ++++++++++++++++++++++++--------- Multiprotocol/Multi.txt | 3 +- Multiprotocol/Multi_Protos.ino | 5 ++ Multiprotocol/Multiprotocol.h | 7 +- Multiprotocol/_Config.h | 4 +- Protocols_Details.md | 14 +++- 7 files changed, 128 insertions(+), 39 deletions(-) diff --git a/Lua_scripts/MultiChan.txt b/Lua_scripts/MultiChan.txt index 63855ff..aeaa1f1 100644 --- a/Lua_scripts/MultiChan.txt +++ b/Lua_scripts/MultiChan.txt @@ -201,3 +201,4 @@ 90,0,MouldKg,Analog,0 90,1,MouldKg,Digit,0 91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA +92,0,MT99xx2,PA18,0,MODE,FLIP,RTH diff --git a/Multiprotocol/MT99xx_ccnrf.ino b/Multiprotocol/MT99xx_ccnrf.ino index 6efa899..6900651 100644 --- a/Multiprotocol/MT99xx_ccnrf.ino +++ b/Multiprotocol/MT99xx_ccnrf.ino @@ -27,12 +27,15 @@ #define MT99XX_PACKET_PERIOD_DRAGON 1038 // there is a pause of 2x1038 between two packets, no idea why and how since it is not even stable on a same dump... #define MT99XX_PACKET_PERIOD_DRAGON_TELEM 10265 // long pause to receive the telemetry packets, 3 are sent by the RX one after the other #define MT99XX_PACKET_PERIOD_F949G 3450 +#define MT99XX_PACKET_PERIOD_PA18 1160 +#define MT99XX_PA18_CRC 0x89 // Is it a constant??? #define MT99XX_INITIAL_WAIT 500 #define MT99XX_PACKET_SIZE 9 //#define FORCE_A180_ID //#define FORCE_DRAGON_ID //#define FORCE_F949G_ID +//#define FORCE_PA18_ID enum { MT99XX_DATA, @@ -82,6 +85,11 @@ enum{ FLAG_F949G_LIGHT = 0x01, FLAG_F949G_3D6G = 0x20, }; +enum{ + // flags going to packet[6] (PA18) + FLAG_PA18_RTH = 0x08, + FLAG_PA18_FLIP = 0x80, +}; const uint8_t h7_mys_byte[] = { 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, @@ -111,7 +119,7 @@ static void __attribute__((unused)) MT99XX_send_packet() else if(sub_protocol==FY805) XN297_RFChannel(0x4B); // FY805 always transmits on the same channel - else // MT99 & H7 & YZ & A180 & DRAGON & F949G + else // MT99 & H7 & YZ & A180 & DRAGON & F949G & PA18 XN297_Hopping(hopping_frequency_no); if(IS_BIND_IN_PROGRESS) @@ -121,7 +129,6 @@ static void __attribute__((unused)) MT99XX_send_packet() switch(sub_protocol) { case YZ: - packet_period = MT99XX_PACKET_PERIOD_YZ; packet[1] = 0x15; packet[2] = 0x05; packet[3] = 0x06; @@ -132,15 +139,11 @@ static void __attribute__((unused)) MT99XX_send_packet() packet[3] = 0x11; break; case FY805: - packet_period = MT99XX_PACKET_PERIOD_FY805; packet[1] = 0x15; packet[2] = 0x12; packet[3] = 0x17; break; - case F949G: - case A180: - packet_period = MT99XX_PACKET_PERIOD_A180; - default: // MT99 & H7 & A180 & DRAGON & F949G + default: // MT99 & H7 & A180 & DRAGON & F949G & PA18 packet[1] = 0x14; packet[2] = 0x03; packet[3] = 0x25; @@ -149,16 +152,24 @@ static void __attribute__((unused)) MT99XX_send_packet() packet[4] = rx_tx_addr[0]; packet[5] = rx_tx_addr[1]; packet[6] = rx_tx_addr[2]; - packet[7] = crc8; // checksum offset - if(sub_protocol != F949G) - packet[8] = 0xAA; // fixed + if(sub_protocol == PA18+8) + { + packet[7] = MT99XX_PA18_CRC; // checksum offset + packet[8] = 0x55; // fixed + } else - packet[8] = 0x00; + { // all others + packet[7] = crc8; // checksum offset + if(sub_protocol != F949G) + packet[8] = 0xAA; // fixed + else + packet[8] = 0x00; + } } else { if(sub_protocol != YZ) - { // MT99XX & H7 & LS & FY805 & A180 & DRAGON & F949G + { // MT99XX & H7 & LS & FY805 & A180 & DRAGON & F949G & PA18 packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron @@ -166,8 +177,10 @@ static void __attribute__((unused)) MT99XX_send_packet() packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00) packet[5] = 0x20; // roll trim (0x00-0x20-0x3f) packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP ); - packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ? - + if(sub_protocol != PA18+8) + packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ? + else + packet[7] = (packet[7]&0xBF)|0x20; switch(sub_protocol) { case MT99: @@ -198,16 +211,16 @@ static void __attribute__((unused)) MT99XX_send_packet() crc8=0; break; case A180: - packet[6] = GET_FLAG( !CH6_SW,FLAG_A180_RATE) // 0x02, A180=RATE, F949S=LED - |GET_FLAG( CH5_SW, FLAG_A180_3D6G ) // 0x01, A180=3D_6G, F949S=RATE - |GET_FLAG( CH7_SW, 0x20 ); // 0x20, F949S=3D_6G + packet[6] = GET_FLAG( !CH6_SW,FLAG_A180_RATE) // 0x02, A180=RATE, F949S=LED + |GET_FLAG( CH5_SW, FLAG_A180_3D6G ) // 0x01, A180=3D_6G, F949S=RATE + |GET_FLAG( CH7_SW, 0x20 ); // 0x20, F949S=3D_6G packet[7] = 0x00; break; case DRAGON: - if(CH5_SW) // Advanced mode + if(CH5_SW) // Advanced mode packet[5] |= 0x80; else - if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Beginner mode + if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Beginner mode packet[5] |= 0x40; packet[6] = FLAG_DRAGON_RATE | GET_FLAG( CH6_SW, FLAG_DRAGON_RTH ); @@ -222,12 +235,12 @@ static void __attribute__((unused)) MT99XX_send_packet() if(packet_count > 11) packet_count = 0; } - if(packet_count > 10) // Telemetry packet request every 10 or 11 packets + if(packet_count > 10) // Telemetry packet request every 10 or 11 packets { - packet[6] |= 0x04; // Request telemetry flag + packet[6] |= 0x04; // Request telemetry flag phase = MT99XX_RX; } - packet[7] = DRAGON_seq[seq_num]; // seq: 20 80 20 60 20 80 20 60... 80 changes to 80+batt from telem + packet[7] = DRAGON_seq[seq_num]; // seq: 20 80 20 60 20 80 20 60... 80 changes to 80+batt from telem if(seq_num==3) packet[7] |= v_lipo1; #else @@ -240,18 +253,31 @@ static void __attribute__((unused)) MT99XX_send_packet() | GET_FLAG( CH6_SW, FLAG_F949G_LIGHT ); packet[7] = 0x00; break; + case PA18+8: + if(Channel_data[CH5] > CHANNEL_MAX_COMMAND) // Expert mode + packet[5] += 0xA0; + else + if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Intermediate mode + packet[5] += 0x60; + packet[6] = GET_FLAG( CH6_SW, FLAG_PA18_FLIP ) // Flip + | GET_FLAG( CH7_SW, FLAG_PA18_RTH ); // RTH + if(hopping_frequency_no == 0) + packet[7] ^= 0x40; + break; } uint8_t result=crc8; for(uint8_t i=0; i<8; i++) result += packet[i]; + if(sub_protocol == PA18+8) + result += MT99XX_PA18_CRC; packet[8] = result; } else { // YZ - packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle - packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder - packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator - packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron + packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle + packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder + packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator + packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron if(packet_count++ >= 23) { seq_num ++; @@ -261,11 +287,11 @@ static void __attribute__((unused)) MT99XX_send_packet() } packet[4] = yz_p4_seq[seq_num]; packet[5] = 0x02 // expert ? (0=unarmed, 1=normal) - | GET_FLAG(CH8_SW, 0x10) //VIDEO - | GET_FLAG(CH5_SW, 0x80) //FLIP - | GET_FLAG(CH9_SW, 0x04) //HEADLESS - | GET_FLAG(CH7_SW, 0x20); //SNAPSHOT - packet[6] = GET_FLAG(CH6_SW, 0x80); //LED + | GET_FLAG(CH8_SW, 0x10) //VIDEO + | GET_FLAG(CH5_SW, 0x80) //FLIP + | GET_FLAG(CH9_SW, 0x04) //HEADLESS + | GET_FLAG(CH7_SW, 0x20); //SNAPSHOT + packet[6] = GET_FLAG(CH6_SW, 0x80); //LED packet[7] = packet[0]; for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++) packet[7] += packet[idx]; @@ -275,7 +301,7 @@ static void __attribute__((unused)) MT99XX_send_packet() //Hopp hopping_frequency_no++; - if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON || sub_protocol == F949G) + if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON || sub_protocol == F949G || sub_protocol == PA18+8) hopping_frequency_no++; // skip every other channel if(hopping_frequency_no > 15) hopping_frequency_no = 0; @@ -354,6 +380,17 @@ static void __attribute__((unused)) MT99XX_initialize_txid() //crc8 = 0xD6 //channel_offset = 0x03 break; + #endif + #ifdef FORCE_PA18_ID + case PA18: + rx_tx_addr[0] = 0xC9; // zebble ID + rx_tx_addr[1] = 0x02; + rx_tx_addr[2] = 0x13; + //crc8 = 0xDE + //channel_offset = 0x03 + //1Mb C=5 S=Y A= C9 02 13 CC CC P(9)= E1 70 70 70 20 20 00 20 1A + //bind S=Y A= CC CC CC CC CC P(9)= 20 14 03 25 C9 02 13 89 55 + break; #endif default: //MT99 & H7 & A180 & DRAGON & F949G rx_tx_addr[2] = 0x00; @@ -446,14 +483,40 @@ uint16_t MT99XX_callback() void MT99XX_init(void) { - if(sub_protocol != A180 && sub_protocol != DRAGON && sub_protocol != F949G) - BIND_IN_PROGRESS; // autobind protocol + if(protocol == PROTO_MT99XX2) + sub_protocol|=0x08; // Increase the number of sub_protocols for MT99XX + bind_counter = MT99XX_BIND_COUNT; + if(IS_BIND_DONE) + { + if(sub_protocol != A180 && sub_protocol != DRAGON && sub_protocol != F949G && sub_protocol != PA18+8) + BIND_IN_PROGRESS; // autobind protocol + else + bind_counter = 1; + } MT99XX_initialize_txid(); MT99XX_RF_init(); - packet_period = MT99XX_PACKET_PERIOD_MT; + switch(sub_protocol) + { + case YZ: + packet_period = MT99XX_PACKET_PERIOD_YZ; + break; + case FY805: + packet_period = MT99XX_PACKET_PERIOD_FY805; + break; + case F949G: + case A180: + packet_period = MT99XX_PACKET_PERIOD_A180; + break; + case PA18+8: + packet_period = MT99XX_PACKET_PERIOD_PA18; + break; + default: + packet_period = MT99XX_PACKET_PERIOD_MT; + break; + } packet_count=0; phase=MT99XX_DATA; diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 4979401..2c990cc 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -87,4 +87,5 @@ 88,WILLIFM 89,Losi 90,MouldKg,Analog,Digit -91,Xerall \ No newline at end of file +91,Xerall +92,MT99xx,PA18 \ No newline at end of file diff --git a/Multiprotocol/Multi_Protos.ino b/Multiprotocol/Multi_Protos.ino index 1f1678a..70c6d27 100644 --- a/Multiprotocol/Multi_Protos.ino +++ b/Multiprotocol/Multi_Protos.ino @@ -33,6 +33,7 @@ const char STR_FRSKYX[] ="FrSky X"; const char STR_FRSKYX2[] ="FrSkyX2"; const char STR_ESKY[] ="ESky"; const char STR_MT99XX[] ="MT99XX"; +const char STR_MT99XX2[] ="MT99XX2"; const char STR_MJXQ[] ="MJXq"; const char STR_SHENQI[] ="Shenqi"; const char STR_FY326[] ="FY326"; @@ -120,6 +121,7 @@ const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829"; const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 "; const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805\0""A180\0 ""Dragon""F949G\0"; +const char STR_SUBTYPE_MT992[] = "\x04""PA18"; const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix"; const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319"; const char STR_SUBTYPE_HONTAI[] = "\x07""Std\0 ""JJRC X1""X5C1\0 ""FQ_951"; @@ -374,6 +376,9 @@ const mm_protocol_definition multi_protocols[] = { #if defined(MT99XX_CCNRF_INO) {PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback }, #endif + #if defined(MT99XX_CCNRF_INO) + {PROTO_MT99XX2, STR_MT99XX2, STR_SUBTYPE_MT992, 1, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback }, + #endif #if defined(NCC1701_NRF24L01_INO) {PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback }, #endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 5debc48..94beaba 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 3 -#define VERSION_PATCH_LEVEL 7 +#define VERSION_PATCH_LEVEL 8 #define MODE_SERIAL 0 @@ -119,6 +119,7 @@ enum PROTOCOLS PROTO_LOSI = 89, // =>CYRF6936 PROTO_MOULDKG = 90, // =>NRF24L01 PROTO_XERALL = 91, // =>NRF24L01 + PROTO_MT99XX2 = 92, // =>NRF24L01, extension of MT99XX protocol PROTO_NANORF = 126, // =>NRF24L01 PROTO_TEST = 127, // =>CC2500 @@ -236,6 +237,10 @@ enum MT99XX DRAGON = 6, F949G = 7, }; +enum MT99XX2 +{ + PA18 = 0, +}; enum MJXQ { WLH08 = 0, diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 87b459e..f945a1d 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -256,7 +256,7 @@ #define GD00X_CCNRF_INO #define KF606_CCNRF_INO #define MJXQ_CCNRF_INO -#define MT99XX_CCNRF_INO +#define MT99XX_CCNRF_INO //Include MT99XX2 protocol #define OMP_CCNRF_INO #define Q303_CCNRF_INO #define Q90C_CCNRF_INO @@ -746,6 +746,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { A180 DRAGON F949G + PROTO_MT99XX2 + PA18 PROTO_NCC1701 NONE PROTO_OMP diff --git a/Protocols_Details.md b/Protocols_Details.md index 87763eb..a5fa0fd 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -119,6 +119,7 @@ CFlie|38|CFlie||||||||NRF24L01| [MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936| [MouldKg](Protocols_Details.md#mouldkg---90)|90|Analog|Digit|||||||NRF24L01|XN297 [MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805|A180|DRAGON|F949G|NRF24L01|XN297 +[MT99xx2](Protocols_Details.md#MT99XX2---92)|92|PA18||||||||NRF24L01|XN297 [NCC1701](Protocols_Details.md#NCC1701---44)|44|||||||||NRF24L01| [OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L [OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None| @@ -1145,6 +1146,17 @@ CH1|CH2|CH3|CH4|CH5|CH6 ---|---|---|---|---|--- A|E|T|R|6G3D|Light +## MT99XX2 - *92* + +### Sub_protocol PA18 - *92* +Model: PA18 mini + +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- +A|E|T|R|MODE|FLIP|RTH + +MODE: -100% beginner, 0% intermediate, +100% Expert + ## OMP - *77* Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider @@ -1903,7 +1915,7 @@ A|E|T|R|FLIP|LIGHT ## V761 - *48* -Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off +Gyro: -100%=Beginner mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off Calib: momentary switch, calib will happen one the channel goes from -100% to +100%