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
3740enum {
3841 MT99XX_DATA,
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
8694const 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
447484void 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;
0 commit comments