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 }