diff --git a/Multiprotocol/Binary_Signature.ino b/Multiprotocol/Binary_Signature.ino
new file mode 100644
index 0000000..af2f343
--- /dev/null
+++ b/Multiprotocol/Binary_Signature.ino
@@ -0,0 +1,181 @@
+/*
+ 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 .
+ */
+
+/************************/
+/** Firmware Signature **/
+/************************/
+
+/*
+The firmware signature is appended to the compiled binary image in order to provide information
+about the options used to compile the firmware file. This information is then used by Multi-module
+flashing tools to verify that the image is correct / valid.
+
+In order for the build process to determine the options used to build the firmware this file conditionally
+declares 'flag' variables for the options we are interested in.
+
+When the pre-compiler parses the source code these variables are either present or not in the parsed cpp file,
+typically '$build_dir$/preproc/ctags_target_for_gcc_minus_e.cpp'.
+
+Once the .bin file is compiled an additional command-line tool scans the parsed cpp file, detects the flags,
+assembles the signature, and finally appends to the end of the binary file.
+
+The signature is 24 bytes long:
+multi-x[8-byte hex code]-[8-byte version number]
+
+For example:
+multi-x1234abcd-01020199
+
+The 8-byte hex code is a 32-bit bitmask value indicating the configuration options, currently:
+
+Bit(s) Option Comment
+1-2 Module type Read as a two-bit value indicating a number from 0-3 which maps to a module type (AVR, STM32, OrangeRX)
+3-7 Channel order Read as a five-bit value indicating a number from 0-23 which maps to as channel order (AETR, TAER, RETA, etc)
+8 Bootloader support Indicates whether or not the firmware was built with support for the bootloader
+9 CHECK_FOR_BOOTLOADER
+10 INVERT_TELEMETRY
+11 MULTI_STATUS
+12 MULTI_TELEMETRY
+13 DEBUG_SERIAL
+
+The 8-byte version number is the version number zero-padded to a fixed width of two-bytes per segment and no separator.
+E.g. 1.2.3.45 becomes 01020345.
+
+Module types are mapped to the following decimal / binary values:
+
+Module Type Decimal Value Binary Valsue
+AVR 0 00
+STM32 1 01
+OrangeRX 2 10
+
+Channel orders are mapped to the following decimal / binary values:
+
+Channel Order Decimal Value Binary Value
+AETR 0 00000
+AERT 1 00001
+ARET 2 00010
+ARTE 3 00011
+ATRE 4 00100
+ATER 5 00101
+EATR 6 00110
+EART 7 00111
+ERAT 8 01000
+ERTA 9 01001
+ETRA 10 01010
+ETAR 11 01011
+TEAR 12 01100
+TERA 13 01101
+TREA 14 01110
+TRAE 15 01111
+TARE 16 10000
+TAER 17 10001
+RETA 18 10010
+REAT 19 10011
+RAET 20 10100
+RATE 21 10101
+RTAE 22 10110
+RTEA 23 10111
+
+*/
+
+// Set the flags for detecting and writing the firmware signature
+#if defined (CHECK_FOR_BOOTLOADER)
+ bool firmwareFlag_CHECK_FOR_BOOTLOADER = true;
+#endif
+#if defined (INVERT_TELEMETRY)
+ bool firmwareFlag_INVERT_TELEMETRY = true;
+#endif
+#if defined (MULTI_STATUS)
+ bool firmwareFlag_MULTI_STATUS = true;
+#endif
+#if defined (MULTI_TELEMETRY)
+ bool firmwareFlag_MULTI_TELEMETRY = true;
+#endif
+#if defined (DEBUG_SERIAL)
+ bool firmwareFlag_DEBUG_SERIAL = true;
+#endif
+
+// Channel order flags
+#if defined (AETR)
+ bool firmwareFlag_ChannelOrder_AETR = true;
+#endif
+#if defined (AERT)
+ bool firmwareFlag_ChannelOrder_AERT = true;
+#endif
+#if defined (ARET)
+ bool firmwareFlag_ChannelOrder_ARET = true;
+#endif
+#if defined (ARTE)
+ bool firmwareFlag_ChannelOrder_ARTE = true;
+#endif
+#if defined (ATRE)
+ bool firmwareFlag_ChannelOrder_ATRE = true;
+#endif
+#if defined (ATER)
+ bool firmwareFlag_ChannelOrder_ATER = true;
+#endif
+#if defined (EATR)
+ bool firmwareFlag_ChannelOrder_EATR = true;
+#endif
+#if defined (EART)
+ bool firmwareFlag_ChannelOrder_EART = true;
+#endif
+#if defined (ERAT)
+ bool firmwareFlag_ChannelOrder_ERAT = true;
+#endif
+#if defined (ERTA)
+ bool firmwareFlag_ChannelOrder_ERTA = true;
+#endif
+#if defined (ETRA)
+ bool firmwareFlag_ChannelOrder_ETRA = true;
+#endif
+#if defined (ETAR)
+ bool firmwareFlag_ChannelOrder_ETAR = true;
+#endif
+#if defined (TEAR)
+ bool firmwareFlag_ChannelOrder_TEAR = true;
+#endif
+#if defined (TERA)
+ bool firmwareFlag_ChannelOrder_TERA = true;
+#endif
+#if defined (TREA)
+ bool firmwareFlag_ChannelOrder_TREA = true;
+#endif
+#if defined (TRAE)
+ bool firmwareFlag_ChannelOrder_TRAE = true;
+#endif
+#if defined (TARE)
+ bool firmwareFlag_ChannelOrder_TARE = true;
+#endif
+#if defined (TAER)
+ bool firmwareFlag_ChannelOrder_TAER = true;
+#endif
+#if defined (RETA)
+ bool firmwareFlag_ChannelOrder_RETA = true;
+#endif
+#if defined (REAT)
+ bool firmwareFlag_ChannelOrder_REAT = true;
+#endif
+#if defined (RAET)
+ bool firmwareFlag_ChannelOrder_RAET = true;
+#endif
+#if defined (RATE)
+ bool firmwareFlag_ChannelOrder_RATE = true;
+#endif
+#if defined (RTAE)
+ bool firmwareFlag_ChannelOrder_RTAE = true;
+#endif
+#if defined (RTEA)
+ bool firmwareFlag_ChannelOrder_RTEA = true;
+#endif
\ No newline at end of file
diff --git a/Multiprotocol/FrSkyX_cc2500.ino b/Multiprotocol/FrSkyX_cc2500.ino
index 2092c38..b2a8ef5 100644
--- a/Multiprotocol/FrSkyX_cc2500.ino
+++ b/Multiprotocol/FrSkyX_cc2500.ino
@@ -20,9 +20,19 @@
#include "iface_cc2500.h"
uint8_t FrSkyX_chanskip;
-uint8_t FrSkyX_TX_Seq ;
+uint8_t FrSkyX_TX_Seq, FrSkyX_TX_IN_Seq;
uint8_t FrSkyX_RX_Seq ;
+#ifdef SPORT_SEND
+ struct t_FrSkyX_TX_Frame
+ {
+ uint8_t count;
+ uint8_t payload[6];
+ } ;
+ // Store FrskyX telemetry
+ struct t_FrSkyX_TX_Frame FrSkyX_TX_Frames[4] ;
+#endif
+
#define FrSkyX_FAILSAFE_TIMEOUT 1032
static void __attribute__((unused)) FrSkyX_set_start(uint8_t ch )
@@ -178,30 +188,70 @@ static void __attribute__((unused)) FrSkyX_build_packet()
else
chan_offset^=0x08;
- //sequence
- packet[21] = (FrSkyX_RX_Seq << 4) | FrSkyX_TX_Seq ;//=8 at startup
-
+ //sequence and send SPort
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
for (uint8_t i=22;i100)
{//~1sec
- FrSkyX_TX_Seq = 0x08 ;
- //FrSkyX_RX_Seq = 0 ;
+ FrSkyX_TX_Seq = 0x08 ; // Request init
+ FrSkyX_TX_IN_Seq = 0xFF ; // No sequence received yet
+ #ifdef SPORT_SEND
+ for(uint8_t i=0;i<4;i++)
+ FrSkyX_TX_Frames[i].count=0; // discard frames in current output buffer
+ #endif
packet_count=0;
#if defined TELEMETRY
telemetry_lost=1;
@@ -284,8 +338,6 @@ uint16_t ReadFrSkyX()
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
}
FrSkyX_build_packet();
- if ( FrSkyX_TX_Seq != 0x08 )
- FrSkyX_TX_Seq = ( FrSkyX_TX_Seq + 1 ) & 0x03 ;
state = FRSKY_DATA1;
return 500;
}
@@ -316,8 +368,13 @@ uint16_t initFrSkyX()
state = FRSKY_DATA1;
FrSkyX_initialize_data(0);
}
- FrSkyX_TX_Seq = 0x08 ;
- FrSkyX_RX_Seq = 0 ;
+ FrSkyX_TX_Seq = 0x08 ; // Request init
+ FrSkyX_TX_IN_Seq = 0xFF ; // No sequence received yet
+ #ifdef SPORT_SEND
+ for(uint8_t i=0;i<4;i++)
+ FrSkyX_TX_Frames[i].count=0; // discard frames in current output buffer
+ #endif
+ FrSkyX_RX_Seq = 0 ; // Seq 0 to start with
return 10000;
}
#endif
\ No newline at end of file
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index a73367c..1377e01 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 2
+#define VERSION_PATCH_LEVEL 4
//******************
// Protocols
@@ -303,7 +303,7 @@ enum FRSKYX_RX
struct PPM_Parameters
{
- uint8_t protocol : 6;
+ uint8_t protocol : 7;
uint8_t sub_proto : 3;
uint8_t rx_num : 4;
uint8_t power : 1;
@@ -589,8 +589,12 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Total of 26 bytes
Stream[0] = 0x55 sub_protocol values are 0..31 Stream contains channels
Stream[0] = 0x54 sub_protocol values are 32..63 Stream contains channels
+ Stream[0] = 0x51 sub_protocol values are 64..95 Stream contains channels
+ Stream[0] = 0x50 sub_protocol values are 96..127 Stream contains channels
Stream[0] = 0x57 sub_protocol values are 0..31 Stream contains failsafe
Stream[0] = 0x56 sub_protocol values are 32..63 Stream contains failsafe
+ Stream[0] = 0x53 sub_protocol values are 64..95 Stream contains failsafe
+ Stream[0] = 0x52 sub_protocol values are 96..127 Stream contains failsafe
Stream[0] |= 0x20 any of the above + 8 additional bytes at the end of the stream available for the current sub_protocol
header
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index bf54b5b..2c5a05e 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -1416,40 +1416,40 @@ void update_serial_data()
//Forced frequency tuning values for CC2500 protocols
#if defined(FORCE_FRSKYD_TUNING) && defined(FRSKYD_CC2500_INO)
if(protocol==PROTO_FRSKYD)
- option=FORCE_FRSKYD_TUNING; // Use config-defined tuning value for FrSkyD
+ option=FORCE_FRSKYD_TUNING; // Use config-defined tuning value for FrSkyD
else
#endif
#if defined(FORCE_FRSKYV_TUNING) && defined(FRSKYV_CC2500_INO)
if(protocol==PROTO_FRSKYV)
- option=FORCE_FRSKYV_TUNING; // Use config-defined tuning value for FrSkyV
+ option=FORCE_FRSKYV_TUNING; // Use config-defined tuning value for FrSkyV
else
#endif
#if defined(FORCE_FRSKYX_TUNING) && defined(FRSKYX_CC2500_INO)
if(protocol==PROTO_FRSKYX)
- option=FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
+ option=FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
else
#endif
#if defined(FORCE_SFHSS_TUNING) && defined(SFHSS_CC2500_INO)
if (protocol==PROTO_SFHSS)
- option=FORCE_SFHSS_TUNING; // Use config-defined tuning value for SFHSS
+ option=FORCE_SFHSS_TUNING; // Use config-defined tuning value for SFHSS
else
#endif
#if defined(FORCE_CORONA_TUNING) && defined(CORONA_CC2500_INO)
if (protocol==PROTO_CORONA)
- option=FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
+ option=FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
else
#endif
#if defined(FORCE_REDPINE_TUNING) && defined(REDPINE_CC2500_INO)
if (protocol==PROTO_REDPINE)
- option=FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
+ option=FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
else
#endif
#if defined(FORCE_HITEC_TUNING) && defined(HITEC_CC2500_INO)
if (protocol==PROTO_HITEC)
- option=FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC
+ option=FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC
else
#endif
- option=rx_ok_buff[3]; // Use radio-defined option value
+ option=rx_ok_buff[3]; // Use radio-defined option value
#ifdef FAILSAFE_ENABLE
bool failsafe=false;
@@ -1483,9 +1483,13 @@ void update_serial_data()
BIND_IN_PROGRESS; //launch bind right away if in autobind mode or bind is set
else
BIND_DONE;
- protocol=(rx_ok_buff[0]==0x55?0:32) + (rx_ok_buff[1]&0x1F); //protocol no (0-63) bits 4-6 of buff[1] and bit 0 of buf[0]
+ protocol=rx_ok_buff[1]&0x1F; //protocol no (0-31)
+ if(!(rx_ok_buff[0]&1))
+ protocol+=32; //protocol no (0-63)
+ if(!(rx_ok_buff[0]&4))
+ protocol+=64; //protocol no (0-127)
sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6
- RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0---3
+ RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0-3
}
else
if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set
@@ -1920,55 +1924,48 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{ // RX interrupt
static uint8_t idx=0,len=26;
#ifdef ORANGE_TX
- if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
+ if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
#elif defined STM32_BOARD
if((USART2_BASE->SR & USART_SR_RXNE) && (USART2_BASE->SR &0x0F)==0)
#else
- UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable
+ UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable
sei() ;
- if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
+ if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
#endif
{ // received byte is ok to process
if(idx==0||discard_frame==1)
{ // Let's try to sync at this point
idx=0;discard_frame=0;
- RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore...
+ RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore...
rx_buff[0]=UDR0;
#ifdef SERIAL_DATA_ENABLE
#ifdef FAILSAFE_ENABLE
- if((rx_buff[0]&0xDC)==0x54) // If 1st byte is 0x74, 0x75, 0x76, 0x77, 0x54, 0x55, 0x56 or 0x57 it looks ok
+ if((rx_buff[0]&0xD8)==0x50) // If 1st byte is 0x74, 0x75, 0x76, 0x77, 0x54, 0x55, 0x56 or 0x57 it looks ok
#else
- if((rx_buff[0]&0xDE)==0x54) // If 1st byte is 0x74, 0x75, 0x54 or 0x55 it looks ok
+ if((rx_buff[0]&0xDA)==0x50) // If 1st byte is 0x74, 0x75, 0x54 or 0x55 it looks ok
#endif
#else
#ifdef FAILSAFE_ENABLE
- if((rx_buff[0]&0xFC)==0x54) // If 1st byte is 0x58, 0x54, 0x55, 0x56 or 0x57 it looks ok
+ if((rx_buff[0]&0xF8)==0x50) // If 1st byte is 0x58, 0x54, 0x55, 0x56 or 0x57 it looks ok
#else
- if((rx_buff[0]&0xFE)==0x54) // If 1st byte is 0x58, 0x54 or 0x55 it looks ok
+ if((rx_buff[0]&0xFA)==0x50) // If 1st byte is 0x54 or 0x55 it looks ok
#endif
#endif
{
- uint16_t max_time;
#ifdef SERIAL_DATA_ENABLE
if(rx_buff[0]&0x20)
- {
- max_time=8500;
len=34;
- }
else
#endif
- {
- max_time=6500;
len=26;
- }
TX_RX_PAUSE_on;
tx_pause();
#if defined STM32_BOARD
- TIMER2_BASE->CCR2=TIMER2_BASE->CNT+max_time;// Full message should be received within timer of 3250us
+ TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15??s=1.5 byte
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC2IF; // Clear Timer2/Comp2 interrupt flag
TIMER2_BASE->DIER |= TIMER_DIER_CC2IE; // Enable Timer2/Comp2 interrupt
#else
- OCR1B = TCNT1+max_time; // Full message should be received within timer of 3250us
+ OCR1B = TCNT1 + 300; // Next byte should show up within 15??s=1.5 byte
TIFR1 = OCF1B_bm ; // clear OCR1B match flag
SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match
#endif
@@ -1977,39 +1974,44 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
}
else
{
- rx_buff[idx++]=UDR0; // Store received byte
+ rx_buff[idx++]=UDR0; // Store received byte
+ #if defined STM32_BOARD
+ TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15??s=1.5 byte
+ #else
+ OCR1B = TCNT1 + 300; // Next byte should show up within 15??s=1.5 byte
+ #endif
if(idx>=len)
{ // A full frame has been received
if(!IS_RX_DONOTUPDATE_on)
{ //Good frame received and main is not working on the buffer
memcpy((void*)rx_ok_buff,(const void*)rx_buff,len);// Duplicate the buffer
- RX_FLAG_on; // flag for main to process servo data
+ RX_FLAG_on; // Flag for main to process servo data
}
else
- RX_MISSED_BUFF_on; // notify that rx_buff is good
- discard_frame=1; // start again
+ RX_MISSED_BUFF_on; // Notify that rx_buff is good
+ discard_frame=1; // Start again
}
}
}
else
{
- idx=UDR0; // Dummy read
- discard_frame=1; // Error encountered discard full frame...
+ idx=UDR0; // Dummy read
+ discard_frame=1; // Error encountered discard full frame...
debugln("Bad frame RX");
}
if(discard_frame==1)
{
#ifdef STM32_BOARD
- TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
+ TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
#else
- CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
+ CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
#endif
TX_RX_PAUSE_off;
tx_resume();
}
#if not defined (ORANGE_TX) && not defined (STM32_BOARD)
cli() ;
- UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable
+ UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable
#endif
}
@@ -2024,10 +2026,10 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{ // Timer1 compare B interrupt
discard_frame=1;
#ifdef STM32_BOARD
- TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
+ TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
debugln("Bad frame timer");
#else
- CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
+ CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
#endif
tx_resume();
}
@@ -2074,20 +2076,3 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
}
}
#endif
-
-// Set the flags for detecting and writing the firmware signature
-#if defined (CHECK_FOR_BOOTLOADER)
- bool firmwareFlag_CHECK_FOR_BOOTLOADER = true;
-#endif
-#if defined (MULTI_STATUS)
- bool firmwareFlag_MULTI_STATUS = true;
-#endif
-#if defined (MULTI_TELEMETRY)
- bool firmwareFlag_MULTI_TELEMETRY = true;
-#endif
-#if defined (INVERT_TELEMETRY)
- bool firmwareFlag_INVERT_TELEMETRY = true;
-#endif
-#if defined (DEBUG_SERIAL)
- bool firmwareFlag_DEBUG_SERIAL = true;
-#endif
diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino
index 197e84e..ac94009 100644
--- a/Multiprotocol/Telemetry.ino
+++ b/Multiprotocol/Telemetry.ino
@@ -303,9 +303,12 @@ void frsky_check_telemetry(uint8_t *packet_in,uint8_t len)
else
RxBt = (packet_in[4]<<1) + 1 ;
+ //Save outgoing telemetry sequence
+ FrSkyX_TX_IN_Seq=packet_in[5] >> 4;
+
//Check incoming telemetry sequence
uint8_t packet_seq=packet_in[5] & 0x03;
- if ( (packet_in[5] & 0x0F) == 0x08 )
+ if ( packet_in[5] & 0x08 )
{//Request init
FrSkyX_RX_Seq = 0x08 ;
FrSkyX_RX_NextFrame = 0x00 ;
@@ -345,6 +348,7 @@ void frsky_check_telemetry(uint8_t *packet_in,uint8_t len)
}
else
{//Not in sequence
+ debugln("NS");
struct t_FrSkyX_RX_Frame *q ;
uint8_t count ;
// packet_in[4] RSSI
@@ -369,11 +373,6 @@ void frsky_check_telemetry(uint8_t *packet_in,uint8_t len)
}
FrSkyX_RX_Seq = ( FrSkyX_RX_Seq & 0x03 ) | 0x04 ; // Request re-transmission of original sequence
}
-
- //Check outgoing telemetry sequence
- if (((packet_in[5] >> 4) & 0x08) == 0x08)
- FrSkyX_TX_Seq = 0 ; //Request init
- //debugln("s:%02X,p:%02X",FrSkyX_TX_Seq,packet_in[5] >> 4);
}
#endif
}