Skip to content

Commit 8b05e55

Browse files
committed
MT99xx2/PA18: new protocol
1 parent af71a20 commit 8b05e55

File tree

7 files changed

+128
-39
lines changed

7 files changed

+128
-39
lines changed

Lua_scripts/MultiChan.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,4 @@
201201
90,0,MouldKg,Analog,0
202202
90,1,MouldKg,Digit,0
203203
91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA
204+
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH

Multiprotocol/MT99xx_ccnrf.ino

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@
2727
#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...
2828
#define MT99XX_PACKET_PERIOD_DRAGON_TELEM 10265 // long pause to receive the telemetry packets, 3 are sent by the RX one after the other
2929
#define MT99XX_PACKET_PERIOD_F949G 3450
30+
#define MT99XX_PACKET_PERIOD_PA18 1160
31+
#define MT99XX_PA18_CRC 0x89 // Is it a constant???
3032
#define MT99XX_INITIAL_WAIT 500
3133
#define MT99XX_PACKET_SIZE 9
3234

3335
//#define FORCE_A180_ID
3436
//#define FORCE_DRAGON_ID
3537
//#define FORCE_F949G_ID
38+
//#define FORCE_PA18_ID
3639

3740
enum {
3841
MT99XX_DATA,
@@ -82,6 +85,11 @@ enum{
8285
FLAG_F949G_LIGHT = 0x01,
8386
FLAG_F949G_3D6G = 0x20,
8487
};
88+
enum{
89+
// flags going to packet[6] (PA18)
90+
FLAG_PA18_RTH = 0x08,
91+
FLAG_PA18_FLIP = 0x80,
92+
};
8593

8694
const uint8_t h7_mys_byte[] = {
8795
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
@@ -111,7 +119,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
111119
else
112120
if(sub_protocol==FY805)
113121
XN297_RFChannel(0x4B); // FY805 always transmits on the same channel
114-
else // MT99 & H7 & YZ & A180 & DRAGON & F949G
122+
else // MT99 & H7 & YZ & A180 & DRAGON & F949G & PA18
115123
XN297_Hopping(hopping_frequency_no);
116124

117125
if(IS_BIND_IN_PROGRESS)
@@ -121,7 +129,6 @@ static void __attribute__((unused)) MT99XX_send_packet()
121129
switch(sub_protocol)
122130
{
123131
case YZ:
124-
packet_period = MT99XX_PACKET_PERIOD_YZ;
125132
packet[1] = 0x15;
126133
packet[2] = 0x05;
127134
packet[3] = 0x06;
@@ -132,15 +139,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
132139
packet[3] = 0x11;
133140
break;
134141
case FY805:
135-
packet_period = MT99XX_PACKET_PERIOD_FY805;
136142
packet[1] = 0x15;
137143
packet[2] = 0x12;
138144
packet[3] = 0x17;
139145
break;
140-
case F949G:
141-
case A180:
142-
packet_period = MT99XX_PACKET_PERIOD_A180;
143-
default: // MT99 & H7 & A180 & DRAGON & F949G
146+
default: // MT99 & H7 & A180 & DRAGON & F949G & PA18
144147
packet[1] = 0x14;
145148
packet[2] = 0x03;
146149
packet[3] = 0x25;
@@ -149,25 +152,35 @@ static void __attribute__((unused)) MT99XX_send_packet()
149152
packet[4] = rx_tx_addr[0];
150153
packet[5] = rx_tx_addr[1];
151154
packet[6] = rx_tx_addr[2];
152-
packet[7] = crc8; // checksum offset
153-
if(sub_protocol != F949G)
154-
packet[8] = 0xAA; // fixed
155+
if(sub_protocol == PA18+8)
156+
{
157+
packet[7] = MT99XX_PA18_CRC; // checksum offset
158+
packet[8] = 0x55; // fixed
159+
}
155160
else
156-
packet[8] = 0x00;
161+
{ // all others
162+
packet[7] = crc8; // checksum offset
163+
if(sub_protocol != F949G)
164+
packet[8] = 0xAA; // fixed
165+
else
166+
packet[8] = 0x00;
167+
}
157168
}
158169
else
159170
{
160171
if(sub_protocol != YZ)
161-
{ // MT99XX & H7 & LS & FY805 & A180 & DRAGON & F949G
172+
{ // MT99XX & H7 & LS & FY805 & A180 & DRAGON & F949G & PA18
162173
packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle
163174
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
164175
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
165176
packet[3] = convert_channel_16b_limit(ELEVATOR,0x00,0xE1); // elevator
166177
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
167178
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
168179
packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP );
169-
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
170-
180+
if(sub_protocol != PA18+8)
181+
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
182+
else
183+
packet[7] = (packet[7]&0xBF)|0x20;
171184
switch(sub_protocol)
172185
{
173186
case MT99:
@@ -198,16 +211,16 @@ static void __attribute__((unused)) MT99XX_send_packet()
198211
crc8=0;
199212
break;
200213
case A180:
201-
packet[6] = GET_FLAG( !CH6_SW,FLAG_A180_RATE) // 0x02, A180=RATE, F949S=LED
202-
|GET_FLAG( CH5_SW, FLAG_A180_3D6G ) // 0x01, A180=3D_6G, F949S=RATE
203-
|GET_FLAG( CH7_SW, 0x20 ); // 0x20, F949S=3D_6G
214+
packet[6] = GET_FLAG( !CH6_SW,FLAG_A180_RATE) // 0x02, A180=RATE, F949S=LED
215+
|GET_FLAG( CH5_SW, FLAG_A180_3D6G ) // 0x01, A180=3D_6G, F949S=RATE
216+
|GET_FLAG( CH7_SW, 0x20 ); // 0x20, F949S=3D_6G
204217
packet[7] = 0x00;
205218
break;
206219
case DRAGON:
207-
if(CH5_SW) // Advanced mode
220+
if(CH5_SW) // Advanced mode
208221
packet[5] |= 0x80;
209222
else
210-
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Beginner mode
223+
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Beginner mode
211224
packet[5] |= 0x40;
212225
packet[6] = FLAG_DRAGON_RATE
213226
| GET_FLAG( CH6_SW, FLAG_DRAGON_RTH );
@@ -222,12 +235,12 @@ static void __attribute__((unused)) MT99XX_send_packet()
222235
if(packet_count > 11)
223236
packet_count = 0;
224237
}
225-
if(packet_count > 10) // Telemetry packet request every 10 or 11 packets
238+
if(packet_count > 10) // Telemetry packet request every 10 or 11 packets
226239
{
227-
packet[6] |= 0x04; // Request telemetry flag
240+
packet[6] |= 0x04; // Request telemetry flag
228241
phase = MT99XX_RX;
229242
}
230-
packet[7] = DRAGON_seq[seq_num]; // seq: 20 80 20 60 20 80 20 60... 80 changes to 80+batt from telem
243+
packet[7] = DRAGON_seq[seq_num]; // seq: 20 80 20 60 20 80 20 60... 80 changes to 80+batt from telem
231244
if(seq_num==3)
232245
packet[7] |= v_lipo1;
233246
#else
@@ -240,18 +253,31 @@ static void __attribute__((unused)) MT99XX_send_packet()
240253
| GET_FLAG( CH6_SW, FLAG_F949G_LIGHT );
241254
packet[7] = 0x00;
242255
break;
256+
case PA18+8:
257+
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND) // Expert mode
258+
packet[5] += 0xA0;
259+
else
260+
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Intermediate mode
261+
packet[5] += 0x60;
262+
packet[6] = GET_FLAG( CH6_SW, FLAG_PA18_FLIP ) // Flip
263+
| GET_FLAG( CH7_SW, FLAG_PA18_RTH ); // RTH
264+
if(hopping_frequency_no == 0)
265+
packet[7] ^= 0x40;
266+
break;
243267
}
244268
uint8_t result=crc8;
245269
for(uint8_t i=0; i<8; i++)
246270
result += packet[i];
271+
if(sub_protocol == PA18+8)
272+
result += MT99XX_PA18_CRC;
247273
packet[8] = result;
248274
}
249275
else
250276
{ // YZ
251-
packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle
252-
packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder
253-
packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator
254-
packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron
277+
packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle
278+
packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder
279+
packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator
280+
packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron
255281
if(packet_count++ >= 23)
256282
{
257283
seq_num ++;
@@ -261,11 +287,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
261287
}
262288
packet[4] = yz_p4_seq[seq_num];
263289
packet[5] = 0x02 // expert ? (0=unarmed, 1=normal)
264-
| GET_FLAG(CH8_SW, 0x10) //VIDEO
265-
| GET_FLAG(CH5_SW, 0x80) //FLIP
266-
| GET_FLAG(CH9_SW, 0x04) //HEADLESS
267-
| GET_FLAG(CH7_SW, 0x20); //SNAPSHOT
268-
packet[6] = GET_FLAG(CH6_SW, 0x80); //LED
290+
| GET_FLAG(CH8_SW, 0x10) //VIDEO
291+
| GET_FLAG(CH5_SW, 0x80) //FLIP
292+
| GET_FLAG(CH9_SW, 0x04) //HEADLESS
293+
| GET_FLAG(CH7_SW, 0x20); //SNAPSHOT
294+
packet[6] = GET_FLAG(CH6_SW, 0x80); //LED
269295
packet[7] = packet[0];
270296
for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++)
271297
packet[7] += packet[idx];
@@ -275,7 +301,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
275301

276302
//Hopp
277303
hopping_frequency_no++;
278-
if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON || sub_protocol == F949G)
304+
if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON || sub_protocol == F949G || sub_protocol == PA18+8)
279305
hopping_frequency_no++; // skip every other channel
280306
if(hopping_frequency_no > 15)
281307
hopping_frequency_no = 0;
@@ -354,6 +380,17 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
354380
//crc8 = 0xD6
355381
//channel_offset = 0x03
356382
break;
383+
#endif
384+
#ifdef FORCE_PA18_ID
385+
case PA18:
386+
rx_tx_addr[0] = 0xC9; // zebble ID
387+
rx_tx_addr[1] = 0x02;
388+
rx_tx_addr[2] = 0x13;
389+
//crc8 = 0xDE
390+
//channel_offset = 0x03
391+
//1Mb C=5 S=Y A= C9 02 13 CC CC P(9)= E1 70 70 70 20 20 00 20 1A
392+
//bind S=Y A= CC CC CC CC CC P(9)= 20 14 03 25 C9 02 13 89 55
393+
break;
357394
#endif
358395
default: //MT99 & H7 & A180 & DRAGON & F949G
359396
rx_tx_addr[2] = 0x00;
@@ -446,14 +483,40 @@ uint16_t MT99XX_callback()
446483

447484
void MT99XX_init(void)
448485
{
449-
if(sub_protocol != A180 && sub_protocol != DRAGON && sub_protocol != F949G)
450-
BIND_IN_PROGRESS; // autobind protocol
486+
if(protocol == PROTO_MT99XX2)
487+
sub_protocol|=0x08; // Increase the number of sub_protocols for MT99XX
488+
451489
bind_counter = MT99XX_BIND_COUNT;
490+
if(IS_BIND_DONE)
491+
{
492+
if(sub_protocol != A180 && sub_protocol != DRAGON && sub_protocol != F949G && sub_protocol != PA18+8)
493+
BIND_IN_PROGRESS; // autobind protocol
494+
else
495+
bind_counter = 1;
496+
}
452497

453498
MT99XX_initialize_txid();
454499
MT99XX_RF_init();
455500

456-
packet_period = MT99XX_PACKET_PERIOD_MT;
501+
switch(sub_protocol)
502+
{
503+
case YZ:
504+
packet_period = MT99XX_PACKET_PERIOD_YZ;
505+
break;
506+
case FY805:
507+
packet_period = MT99XX_PACKET_PERIOD_FY805;
508+
break;
509+
case F949G:
510+
case A180:
511+
packet_period = MT99XX_PACKET_PERIOD_A180;
512+
break;
513+
case PA18+8:
514+
packet_period = MT99XX_PACKET_PERIOD_PA18;
515+
break;
516+
default:
517+
packet_period = MT99XX_PACKET_PERIOD_MT;
518+
break;
519+
}
457520

458521
packet_count=0;
459522
phase=MT99XX_DATA;

Multiprotocol/Multi.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,5 @@
8787
88,WILLIFM
8888
89,Losi
8989
90,MouldKg,Analog,Digit
90-
91,Xerall
90+
91,Xerall
91+
92,MT99xx,PA18

Multiprotocol/Multi_Protos.ino

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const char STR_FRSKYX[] ="FrSky X";
3333
const char STR_FRSKYX2[] ="FrSkyX2";
3434
const char STR_ESKY[] ="ESky";
3535
const char STR_MT99XX[] ="MT99XX";
36+
const char STR_MT99XX2[] ="MT99XX2";
3637
const char STR_MJXQ[] ="MJXq";
3738
const char STR_SHENQI[] ="Shenqi";
3839
const char STR_FY326[] ="FY326";
@@ -120,6 +121,7 @@ const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0
120121
const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829";
121122
const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
122123
const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805\0""A180\0 ""Dragon""F949G\0";
124+
const char STR_SUBTYPE_MT992[] = "\x04""PA18";
123125
const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
124126
const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319";
125127
const char STR_SUBTYPE_HONTAI[] = "\x07""Std\0 ""JJRC X1""X5C1\0 ""FQ_951";
@@ -374,6 +376,9 @@ const mm_protocol_definition multi_protocols[] = {
374376
#if defined(MT99XX_CCNRF_INO)
375377
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
376378
#endif
379+
#if defined(MT99XX_CCNRF_INO)
380+
{PROTO_MT99XX2, STR_MT99XX2, STR_SUBTYPE_MT992, 1, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
381+
#endif
377382
#if defined(NCC1701_NRF24L01_INO)
378383
{PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback },
379384
#endif

Multiprotocol/Multiprotocol.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#define VERSION_MAJOR 1
2020
#define VERSION_MINOR 3
2121
#define VERSION_REVISION 3
22-
#define VERSION_PATCH_LEVEL 7
22+
#define VERSION_PATCH_LEVEL 8
2323

2424
#define MODE_SERIAL 0
2525

@@ -119,6 +119,7 @@ enum PROTOCOLS
119119
PROTO_LOSI = 89, // =>CYRF6936
120120
PROTO_MOULDKG = 90, // =>NRF24L01
121121
PROTO_XERALL = 91, // =>NRF24L01
122+
PROTO_MT99XX2 = 92, // =>NRF24L01, extension of MT99XX protocol
122123

123124
PROTO_NANORF = 126, // =>NRF24L01
124125
PROTO_TEST = 127, // =>CC2500
@@ -236,6 +237,10 @@ enum MT99XX
236237
DRAGON = 6,
237238
F949G = 7,
238239
};
240+
enum MT99XX2
241+
{
242+
PA18 = 0,
243+
};
239244
enum MJXQ
240245
{
241246
WLH08 = 0,

Multiprotocol/_Config.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@
256256
#define GD00X_CCNRF_INO
257257
#define KF606_CCNRF_INO
258258
#define MJXQ_CCNRF_INO
259-
#define MT99XX_CCNRF_INO
259+
#define MT99XX_CCNRF_INO //Include MT99XX2 protocol
260260
#define OMP_CCNRF_INO
261261
#define Q303_CCNRF_INO
262262
#define Q90C_CCNRF_INO
@@ -746,6 +746,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
746746
A180
747747
DRAGON
748748
F949G
749+
PROTO_MT99XX2
750+
PA18
749751
PROTO_NCC1701
750752
NONE
751753
PROTO_OMP

Protocols_Details.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ CFlie|38|CFlie||||||||NRF24L01|
119119
[MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936|
120120
[MouldKg](Protocols_Details.md#mouldkg---90)|90|Analog|Digit|||||||NRF24L01|XN297
121121
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805|A180|DRAGON|F949G|NRF24L01|XN297
122+
[MT99xx2](Protocols_Details.md#MT99XX2---92)|92|PA18||||||||NRF24L01|XN297
122123
[NCC1701](Protocols_Details.md#NCC1701---44)|44|||||||||NRF24L01|
123124
[OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L
124125
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
@@ -1145,6 +1146,17 @@ CH1|CH2|CH3|CH4|CH5|CH6
11451146
---|---|---|---|---|---
11461147
A|E|T|R|6G3D|Light
11471148

1149+
## MT99XX2 - *92*
1150+
1151+
### Sub_protocol PA18 - *92*
1152+
Model: PA18 mini
1153+
1154+
CH1|CH2|CH3|CH4|CH5|CH6|CH7
1155+
---|---|---|---|---|---|---
1156+
A|E|T|R|MODE|FLIP|RTH
1157+
1158+
MODE: -100% beginner, 0% intermediate, +100% Expert
1159+
11481160
## OMP - *77*
11491161
Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider
11501162

@@ -1903,7 +1915,7 @@ A|E|T|R|FLIP|LIGHT
19031915

19041916
## V761 - *48*
19051917

1906-
Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
1918+
Gyro: -100%=Beginner mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
19071919

19081920
Calib: momentary switch, calib will happen one the channel goes from -100% to +100%
19091921

0 commit comments

Comments
 (0)