From e4f4d278a832723e2cf8988253fb073509cad452 Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Thu, 30 Nov 2017 20:12:23 +0100 Subject: [PATCH 1/6] Hubsan protocol Added subprotocol H107 (0) Added subprotocol H301 (1) Added subprotocol H501 (2) --- Multiprotocol/A7105_SPI.ino | 2 + Multiprotocol/Hubsan_a7105.ino | 210 +++++++++++++++++++++--------- Multiprotocol/Multi.txt | 2 +- Multiprotocol/Multiprotocol.h | 12 +- Multiprotocol/_Config.h | 10 +- Multiprotocol/_MyConfig.h.example | 14 +- Protocols_Details.md | 22 +++- 7 files changed, 204 insertions(+), 68 deletions(-) diff --git a/Multiprotocol/A7105_SPI.ino b/Multiprotocol/A7105_SPI.ino index 7db0bbf..a8da2ad 100644 --- a/Multiprotocol/A7105_SPI.ino +++ b/Multiprotocol/A7105_SPI.ino @@ -294,6 +294,8 @@ void A7105_Init(void) A7105_SetTxRxMode(TX_EN); A7105_SetPower(); + A7105_AdjustLOBaseFreq(A7105_FREQ_OFFSET); + A7105_Strobe(A7105_STANDBY); } #endif \ No newline at end of file diff --git a/Multiprotocol/Hubsan_a7105.ino b/Multiprotocol/Hubsan_a7105.ino index 755e817..0a1cfda 100644 --- a/Multiprotocol/Hubsan_a7105.ino +++ b/Multiprotocol/Hubsan_a7105.ino @@ -20,24 +20,48 @@ #include "iface_a7105.h" enum{ - // flags going to packet[9] (Normal) - HUBSAN_FLAG_VIDEO= 0x01, // record video - HUBSAN_FLAG_FLIP = 0x08, // enable flips - HUBSAN_FLAG_LED = 0x04 // enable LEDs + // flags going to packet[9] (H107) + HUBSAN_FLAG_VIDEO= 0x01, // record video + HUBSAN_FLAG_FLIP = 0x08, // enable flips + HUBSAN_FLAG_LED = 0x04 // enable LEDs }; enum{ - // flags going to packet[9] (Plus series) - HUBSAN_FLAG_HEADLESS = 0x08, // headless mode + // flags going to packet[9] (H107 Plus series) + HUBSAN_FLAG_HEADLESS = 0x08, // headless mode }; enum{ - // flags going to packet[13] (Plus series) - HUBSAN_FLAG_SNAPSHOT = 0x01, - HUBSAN_FLAG_FLIP_PLUS = 0x80, + // flags going to packet[9] (H301) + FLAG_H301_VIDEO = 0x01, + FLAG_H301_STAB = 0x02, + FLAG_H301_LED = 0x10, + FLAG_H301_RTH = 0x40, }; -uint32_t sessionid,id_data; +enum{ + // flags going to packet[13] (H107 Plus series) + HUBSAN_FLAG_SNAPSHOT = 0x01, + HUBSAN_FLAG_FLIP_PLUS = 0x80, +}; + +enum{ + // flags going to packet[9] (H501S) + FLAG_H501_VIDEO = 0x01, + FLAG_H501_LED = 0x04, + FLAG_H501_RTH = 0x20, + FLAG_H501_HEADLESS1 = 0x40, + FLAG_H501_GPS_HOLD = 0x80, + }; + + enum{ + // flags going to packet[13] (H501S) + FLAG_H501_SNAPSHOT = 0x01, + FLAG_H501_HEADLESS2 = 0x02, + FLAG_H501_ALT_HOLD = 0x08, +}; + +uint32_t hubsan_id_data; enum { BIND_1, @@ -54,7 +78,7 @@ enum { DATA_4, DATA_5, }; -#define WAIT_WRITE 0x80 +#define HUBSAN_WAIT_WRITE 0x80 static void __attribute__((unused)) hubsan_update_crc() { @@ -72,11 +96,11 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state) memset(packet, 0, 16); packet[0] = bind_state; packet[1] = channel; - packet[2] = (sessionid >> 24) & 0xFF; - packet[3] = (sessionid >> 16) & 0xFF; - packet[4] = (sessionid >> 8) & 0xFF; - packet[5] = (sessionid >> 0) & 0xFF; - if(id_data == ID_NORMAL) + packet[2] = (MProtocol_id >> 24) & 0xFF; + packet[3] = (MProtocol_id >> 16) & 0xFF; + packet[4] = (MProtocol_id >> 8) & 0xFF; + packet[5] = (MProtocol_id >> 0) & 0xFF; + if(hubsan_id_data == ID_NORMAL && sub_protocol != H501) { packet[6] = 0x08; packet[7] = 0xe4; @@ -108,7 +132,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state) //ii : aileron observed range: 0x45 - 0xc3 (smaller is right)69-195-50% static void __attribute__((unused)) hubsan_build_packet() { - static uint8_t vtx_freq = 0; + static uint8_t vtx_freq = 0, h501_packet = 0; memset(packet, 0, 16); if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D) { @@ -127,8 +151,8 @@ static void __attribute__((unused)) hubsan_build_packet() packet[4] = 0xFF - convert_channel_8b(RUDDER); //Rudder is reversed packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed packet[8] = convert_channel_8b(AILERON); //Aileron - if(id_data == ID_NORMAL) - { + if(hubsan_id_data == ID_NORMAL && sub_protocol==H107) + {// H107/L/C/D, H102D if( packet_count < 100) { packet[9] = 0x02 | HUBSAN_FLAG_LED | HUBSAN_FLAG_FLIP; // sends default value for the 100 first packets @@ -150,22 +174,56 @@ static void __attribute__((unused)) hubsan_build_packet() packet[12] = 0x04; packet[13] = 0x26; packet[14] = 0x79; + } else if(sub_protocol==H301) + {// H301 + if( packet_count < 100) + { + packet[9] = FLAG_H301_STAB; // sends default value for the 100 first packets + packet_count++; + } + else + { + packet[9] = GET_FLAG(Servo_AUX2, FLAG_H301_LED) + | GET_FLAG(Servo_AUX3, FLAG_H301_STAB) + | GET_FLAG(Servo_AUX4, FLAG_H301_VIDEO) + | GET_FLAG(Servo_AUX1, FLAG_H301_RTH); + } + packet[10] = 0x18; // ? + packet[12] = 0x5c; // ? + packet[14] = 0xf6; // ? } else - { //ID_PLUS - packet[3] = 0x64; - packet[5] = 0x64; - packet[7] = 0x64; - packet[9] = 0x06; - //FLIP|LIGHT|PICTURE|VIDEO|HEADLESS - if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; - if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS; - packet[10]= 0x19; - packet[12]= 0x5C; // ghost channel ? - packet[13] = 0; - if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT; - if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS; - packet[14]= 0x49; // ghost channel ? + { //ID_PLUS && H501 + packet[3] = sub_protocol==H501 ? 0x00:0x64; + packet[5] = sub_protocol==H501 ? 0x00:0x64; + packet[7] = sub_protocol==H501 ? 0x00:0x64; + + if(sub_protocol==H501) + { // H501S + packet[9] = 0x02 + | GET_FLAG(Servo_AUX2, FLAG_H501_LED) + | GET_FLAG(Servo_AUX4, FLAG_H501_VIDEO) + | GET_FLAG(Servo_AUX1, FLAG_H501_RTH) + | GET_FLAG(Servo_AUX7, FLAG_H501_GPS_HOLD) + | GET_FLAG(Servo_AUX5, FLAG_H501_HEADLESS1); + //packet[10]= 0x1A; + packet[13] = GET_FLAG(Servo_AUX6, FLAG_H501_HEADLESS2) + | GET_FLAG(Servo_AUX8, FLAG_H501_ALT_HOLD) + | GET_FLAG(Servo_AUX3, FLAG_H501_SNAPSHOT); + } + else + { // H107P/C+/D+ + packet[9] = 0x06; + //FLIP|LIGHT|PICTURE|VIDEO|HEADLESS + if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; + if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS; + packet[10]= 0x19; + packet[12]= 0x5C; // ghost channel ? + packet[13] = 0; + if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT; + if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS; + packet[14]= 0x49; // ghost channel ? + } if(packet_count < 100) { // set channels to neutral for first 100 packets packet[2] = 0x80; // throttle neutral is at mid stick on plus series @@ -176,6 +234,21 @@ static void __attribute__((unused)) hubsan_build_packet() packet[13]= 0x00; packet_count++; } + if(sub_protocol==H501) + { // H501S + h501_packet++; + if(h501_packet == 10) + { + memset(packet, 0, 16); + packet[0] = 0xe8; + } + else if(h501_packet == 20) + { + memset(packet, 0, 16); + packet[0] = 0xe9; + } + if(h501_packet >= 20) h501_packet = 0; + } } hubsan_update_crc(); } @@ -198,41 +271,42 @@ uint16_t ReadHubsan() static uint8_t rfMode=0; #endif static uint8_t txState=0; - static uint8_t bind_count=0; uint16_t delay; uint8_t i; - switch(phase) { + switch(phase) + { case BIND_1: - bind_count++; - if(bind_count >= 20) + bind_phase++; + if(bind_phase >= 20 && sub_protocol != H501) { - if(id_data == ID_NORMAL) - id_data = ID_PLUS; + if(hubsan_id_data == ID_NORMAL) + hubsan_id_data = ID_PLUS; else - id_data = ID_NORMAL; - A7105_WriteID(id_data); - bind_count = 0; + hubsan_id_data = ID_NORMAL; + A7105_WriteID(hubsan_id_data); + bind_phase = 0; } case BIND_3: case BIND_5: case BIND_7: hubsan_build_bind_packet(phase == BIND_7 ? 9 : (phase == BIND_5 ? 1 : phase + 1 - BIND_1)); + A7105_Strobe(A7105_STANDBY); A7105_WriteData(16, channel); - phase |= WAIT_WRITE; + phase |= HUBSAN_WAIT_WRITE; return 3000; - case BIND_1 | WAIT_WRITE: - case BIND_3 | WAIT_WRITE: - case BIND_5 | WAIT_WRITE: - case BIND_7 | WAIT_WRITE: + case BIND_1 | HUBSAN_WAIT_WRITE: + case BIND_3 | HUBSAN_WAIT_WRITE: + case BIND_5 | HUBSAN_WAIT_WRITE: + case BIND_7 | HUBSAN_WAIT_WRITE: //wait for completion for(i = 0; i< 20; i++) if(! (A7105_ReadReg(A7105_00_MODE) & 0x01)) break; A7105_SetTxRxMode(RX_EN); A7105_Strobe(A7105_RX); - phase &= ~WAIT_WRITE; - if(id_data == ID_PLUS) + phase &= ~HUBSAN_WAIT_WRITE; + if(hubsan_id_data == ID_PLUS) { if(phase == BIND_7 && packet[2] == 9) { @@ -264,7 +338,7 @@ uint16_t ReadHubsan() return 15000; //22.5msec elapsed since last write } A7105_ReadData(16); - if(packet[1] == 9 && id_data == ID_NORMAL) { + if(packet[1] == 9 && hubsan_id_data == ID_NORMAL) { phase = DATA_1; A7105_WriteReg(A7105_1F_CODE_I, 0x0F); BIND_DONE; @@ -285,7 +359,13 @@ uint16_t ReadHubsan() if( phase == DATA_1) A7105_SetPower(); //Keep transmit power in sync hubsan_build_packet(); - A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel); + A7105_Strobe(A7105_STANDBY); + uint8_t ch; + if((phase == DATA_5 && hubsan_id_data == ID_NORMAL) && sub_protocol == H107) + ch = channel + 0x23; + else + ch = channel; + A7105_WriteData(16, ch); if (phase == DATA_5) phase = DATA_1; else @@ -340,20 +420,30 @@ uint16_t ReadHubsan() return 0; } -uint16_t initHubsan() { +uint16_t initHubsan() +{ const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82}; A7105_Init(); - sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); - channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)]; + channel = allowed_ch[MProtocol_id % sizeof(allowed_ch)]; + hubsan_id_data=ID_NORMAL; - BIND_IN_PROGRESS; // autobind protocol - phase = BIND_1; + if(IS_AUTOBIND_FLAG_on || sub_protocol==H107) + { + BIND_IN_PROGRESS; // autobind protocol + phase = BIND_1; + } + else + { + phase = DATA_1; + A7105_WriteID(MProtocol_id); + A7105_WriteReg(A7105_1F_CODE_I, 0x0F); + } packet_count=0; - id_data=ID_NORMAL; -#ifdef HUBSAN_HUB_TELEMETRY - init_frskyd_link_telemetry(); -#endif + bind_phase=0; + #ifdef HUBSAN_HUB_TELEMETRY + init_frskyd_link_telemetry(); + #endif return 10000; } diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index e8cec95..46e03fd 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -1,5 +1,5 @@ 1,Flysky,Flysky,V9x9,V6x6,V912,CX20 -2,Hubsan +2,Hubsan,H107,H301,H501 3,FrskyD 4,Hisky,Hisky,HK310 5,V2x2,V2x2,JXD506 diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index e5d2572..a16757c 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 1 #define VERSION_REVISION 6 -#define VERSION_PATCH_LEVEL 35 +#define VERSION_PATCH_LEVEL 36 //****************** // Protocols //****************** @@ -72,6 +72,12 @@ enum Flysky V912 = 3, CX20 = 4 }; +enum Hubsan +{ + H107 = 0, + H301 = 1, + H501 = 2, +}; enum AFHDS2A { PWM_IBUS = 0, @@ -555,6 +561,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- V6x6 2 V912 3 CX20 4 + sub_protocol==Hubsan + H107 0 + H301 1 + H501 2 sub_protocol==Hisky Hisky 0 HK310 1 diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index f59474e..08506a7 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -77,6 +77,10 @@ //#define CC2500_ENABLE_LOW_POWER //#define NRF24L01_ENABLE_LOW_POWER +//Fine tune of the A7105 LO base frequency +// This is required for some A7105 modules and/or RXs with inaccurate crystal oscillator. +// The offset is in +/-kHz. Default value is 0. +#define A7105_FREQ_OFFSET 0 /*****************/ /*** GLOBAL ID ***/ @@ -272,7 +276,7 @@ const int8_t AFHDS2AFailsafe[14]= { const PPM_Parameters PPM_prot[15]= { // Dial Protocol Sub protocol RX_Num Power Auto Bind Option /* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, +/* 2 */ {MODE_HUBSAN, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning /* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, @@ -295,7 +299,9 @@ const PPM_Parameters PPM_prot[15]= { V912 CX20 MODE_HUBSAN - NONE + H107 + H301 + H501 MODE_FRSKYV NONE MODE_FRSKYD diff --git a/Multiprotocol/_MyConfig.h.example b/Multiprotocol/_MyConfig.h.example index 80ac6af..f14a2e4 100644 --- a/Multiprotocol/_MyConfig.h.example +++ b/Multiprotocol/_MyConfig.h.example @@ -1,7 +1,19 @@ +/* + This file is meant to keep your settings after an upgrade of the multi source. + If you know parameters you want for sure to be enabled or disabled in future + then just force their values here. + To enable a setting use #define + To disable a setting use #undef +*/ + //#define FORCE_GLOBAL_ID 0x12345678 +//Force bootloader +#define CHECK_FOR_BOOTLOADER + #if not defined STM32_BOARD -// Atmega328p board list of unwanted protocols to fit in flash +// Everything here will only apply to Multi Atmega328p boards +// Add or remove unwanted protocols to fit in flash #undef AFHDS2A_A7105_INO #undef DEVO_CYRF6936_INO diff --git a/Protocols_Details.md b/Protocols_Details.md index 16471b3..4638474 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -106,18 +106,34 @@ Note that the RX ouput will be AETR. ### Sub_protocol PPM_SBUS - *3* ## HUBSAN - *2* -Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+ - -Autobind protocol Telemetry enabled for battery voltage and TX RSSI Option=vTX frequency (H107D) 5645 - 5900 MHz +### Sub_protocol H107 - *0* +Autobind protocol + +Models: Hubsan H102D, H107/L/C/D and H107P/C+/D+ + CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 ---|---|---|---|---|---|---|---|--- A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS +### Sub_protocol H301 - *1* +Models: Hubsan H301 + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- +A|E|T|R|RTH|LIGHT|STAB|VIDEO + +### Sub_protocol H501 - *1* +Models: Hubsan H501S + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 +---|---|---|---|---|---|---|---|---|---|---|--- +A|E|T|R|RTH|LIGHT|PICTURE|VIDEO|HEADLESS1|HEADLESS2|GPS_HOLD|ALT_HOLD + *** # CC2500 RF Module From cec654a75be8a9477c0c0263d8fa0c878328fac8 Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 1 Dec 2017 08:13:06 -0500 Subject: [PATCH 2/6] Update Protocol Details for CABELL protocol (#117) * Added CABELL Protocol * Added additional disclaimer to license. * Revert "Added additional disclaimer to license." This reverts commit a00bc9956a155a1a73dbbcd21fd19633d6d121ff. * Added additional disclaimer * Added CABELL_NRF24L01_INO define to config * Updated available protocol list Added CABELL protocol * Removed unused variables * Changed changel range to 45 channels that comply with USA FCC part 97 rules. This change allows licenced HAMs to operate under part 97 rules instead of part 15. These channels are still in the ISM band, but overlap with the part 97 amateur portion of the band. * Changed protocol number to 33 Was previously 30, but the main branch has now allocated up to 32, so changing to 33 * Corrected permutation calculation * Added sub-protocol for setting failsafe values * Opened up a free bit in the option byte for future use * Fixed packet errors when trying to unbind when in bind mode This use case didn't really make any sense, but it should not cause packet errors, so fixed it. * RSSI Telemetry for CABELL protocol * Pins back to stock configuration * Split checksum into MSB and LSB fields to avoid endian issue * struct change for checksum * Added analog values to telemetry packet that could be used for LIPO voltage * Added MODE_CABELL to frsk_link_frame * Updated packet layout comments * Fixed telemetry conditional compiles in CABELL protocol * Telemetry working; moved power override bit * Changed telemetry to 250 kbps and adjustable packet period - imporves reliability/range * Changed CABELL protocol number to 34 * Fixed typos in comments * Fix ATMEGA BASH_SERIAL buffer overrun Changed the compare to TXBUFFER_SIZE to >= If next wasn't set to zero until > TXBUFFER_SIZE then the next time the routines get called the the array index references outside the buffer (e.g tail+1) * Revert "Fix ATMEGA BASH_SERIAL buffer overrun" This reverts commit ba4526ee89c2b5a946a659eea2c9581c36254809. * Updated documentation for CABELL V3 Protocol * Updated Documentation for the CABELL V3 Protocol --- Multiprotocol/CABELL_nrf224l01.ino | 2 +- Multiprotocol/Multiprotocol.h | 2 +- Multiprotocol/Multiprotocol.ino | 2 +- Multiprotocol/Pins.h | 4 +--- Multiprotocol/Validate.h | 2 +- Protocols_Details.md | 14 ++++++++++---- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index e272eb2..6c50ba8 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -439,4 +439,4 @@ uint16_t initCABELL(void) return packet_period; } -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index a16757c..6e486e3 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -803,4 +803,4 @@ Commands from TX to module use values > 127 for command type data[1-22] Failsafe data, encoded like normal channel data, with the expection that 0 means hold for that channel and 2047 means no pulses -*/ +*/ \ No newline at end of file diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index a433319..99a90e1 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -1589,4 +1589,4 @@ static uint32_t random_id(uint16_t address, uint8_t create_new) WDTCSR = 0; // Disable Watchdog interrupt } } -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index e455326..e760180 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -3,12 +3,10 @@ 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 . */ @@ -338,4 +336,4 @@ #define eeprom_read_byte EEPROM.read #else #define EE_ADDR uint8_t* -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index 42efac6..02ba70b 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -165,4 +165,4 @@ #endif #if MAX_PPM_CHANNELS>16 #error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16. -#endif +#endif \ No newline at end of file diff --git a/Protocols_Details.md b/Protocols_Details.md index 4638474..034ef6e 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -410,19 +410,25 @@ TAKE_OFF|EMG_STOP ## Cabell - *34* Homegrown protocol with variable number of channels (4-16) and telemetry (RSSI, V1, V2). -RXs details are located here: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS +It is a FHSS protocol developed by Dennis Cabell (KE8FZX) using the NRF24L01+ 2.4 GHz transceiver. 45 channels are used frequency hop from 2.403 through 2.447 GHz. The reason for using 45 channels is to keep operation within the overlap area between the 2.4 GHz ISM band (governed in the USA by FCC part 15) and the HAM portion of the band (governed in the USA by FCC part 97). This allows part 15 compliant use of the protocol, while allowing licensed amateur radio operators to operate under the less restrictive part 97 rules if desired. -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16 ----|---|---|---|---|---|---|---|---|----|----|----|----|----|----|---- -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16 +Additional details about configuring and using the protocol are available at the RX project at: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS + +CH1|CH2|CH3|CH4|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14 |CH15 |CH16 +---|---|---|---|----|----|----|----|----|----|----|----|----|-----|-----|----- + A | E | T | R |AUX1|AUX2|AUX3|AUX4|AUX5|AUX6|AUX7|AUX8|AUX9|AUX10|AUX11|AUX12 ### Sub_protocol CABELL_V3 - *0* +4 to 16 channels without telemetry ### Sub_protocol CABELL_V3_TELEMETRY - *1* +4 to 16 channels with telemetry (RSSI, V1, V2). V1 & V2 can be used to return any analog voltage between 0 and 5 volts, so can be used for battery voltage or any other sensor that provides an analog voltage. ### Sub_protocol CABELL_SET_FAIL_SAFE - *6* +Stores failsafe values in the RX. The channel values are set when the sub-protocol is changed to 6, so hold sticks in place as the sub-protocol is changed. ### Sub_protocol CABELL_UNBIND - *7* +The receiver bound to the model is un-bound. This happens immediately when the sub-protocol is set to 7. ## CG023 - *13* Autobind protocol From 937601919843513305041022079fea76240fba7f Mon Sep 17 00:00:00 2001 From: pascallanger Date: Fri, 1 Dec 2017 14:19:19 +0100 Subject: [PATCH 3/6] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 706f367..46e839c 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,9 @@ For example, if you have no interest in binding your Tx to an model with and FrS ## **Choice 3:** Which protocols to upload to the MULTI-Module -Of course there is always a catch. In this case it is the 32KB memory limit on the ATmega328 processor. Due to the amazing work done by devs on this project, the memory required by all the possible protocols exceeds this limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page. -Also, the lead dev Pascal Langer (rcgroups:hpnuts) makes this process even easier for many users by making compiled binaries available for three popular combinations of RF modules. These are always “fresh” (based on the latest stable firmware) and available on the [Releases](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) page. +In the case of the ATmega328, the memory required by all the possible protocols exceeds the 32KB flash limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page. -An alternatice is to use a STM32 ARM microcontroller based module. If you go the route of building this version of the DIY MULTI-Module then the memory limits do not apply anymore. +An alternative is to use a STM32 ARM microcontroller based module which can hold all the protocols. ## **Choice 4:** Choosing the type of interface between the MULTI-Module and your radio (PPM or Serial) From 7ff482dafe1cab47808527f591e3901ea911d530 Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Fri, 1 Dec 2017 15:02:24 +0100 Subject: [PATCH 4/6] Rates in Bayang and MJXQ --- Multiprotocol/Bayang_nrf24l01.ino | 17 ++++++++++++----- Multiprotocol/MJXQ_nrf24l01.ino | 5 +++-- Multiprotocol/Multiprotocol.h | 4 +++- Protocols_Details.md | 20 ++++++++++++-------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Multiprotocol/Bayang_nrf24l01.ino b/Multiprotocol/Bayang_nrf24l01.ino index 08a3d0f..0661625 100644 --- a/Multiprotocol/Bayang_nrf24l01.ino +++ b/Multiprotocol/Bayang_nrf24l01.ino @@ -75,7 +75,9 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) else { uint16_t val; - switch (sub_protocol) { + uint8_t dyntrim = 1; + switch (sub_protocol) + { case X16_AH: case IRDRONE: packet[0] = 0xA6; @@ -97,22 +99,27 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) if(Servo_AUX4) packet[2] |= BAYANG_FLAG_VIDEO; if(Servo_AUX5) + { packet[2] |= BAYANG_FLAG_HEADLESS; + dyntrim = 0; + } //Flags packet[3] packet[3] = 0x00; if(Servo_AUX6) packet[3] = BAYANG_FLAG_INVERTED; if(Servo_AUX7) - packet[3] |= BAYANG_FLAG_TAKE_OFF; + dyntrim = 0; if(Servo_AUX8) + packet[3] |= BAYANG_FLAG_TAKE_OFF; + if(Servo_AUX9) packet[3] |= BAYANG_FLAG_EMG_STOP; //Aileron val = convert_channel_10b(AILERON); - packet[4] = (val>>8) + ((val>>2) & 0xFC); + packet[4] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C); packet[5] = val & 0xFF; //Elevator val = convert_channel_10b(ELEVATOR); - packet[6] = (val>>8) + ((val>>2) & 0xFC); + packet[6] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C); packet[7] = val & 0xFF; //Throttle val = convert_channel_10b(THROTTLE); @@ -120,7 +127,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) packet[9] = val & 0xFF; //Rudder val = convert_channel_10b(RUDDER); - packet[10] = (val>>8) + (val>>2 & 0xFC); + packet[10] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C); packet[11] = val & 0xFF; } switch (sub_protocol) diff --git a/Multiprotocol/MJXQ_nrf24l01.ino b/Multiprotocol/MJXQ_nrf24l01.ino index 71a23cf..bb21678 100644 --- a/Multiprotocol/MJXQ_nrf24l01.ino +++ b/Multiprotocol/MJXQ_nrf24l01.ino @@ -105,9 +105,9 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) packet[1] = convert_channel_s8b(RUDDER); packet[4] = 0x40; // rudder does not work well with dyntrim packet[2] = 0x80 ^ convert_channel_s8b(ELEVATOR); - packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator + packet[5] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator packet[3] = convert_channel_s8b(AILERON); - packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron + packet[6] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron packet[7] = rx_tx_addr[0]; packet[8] = rx_tx_addr[1]; packet[9] = rx_tx_addr[2]; @@ -128,6 +128,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) // Servo_AUX7 AUTOFLIP // X800, X600 // Servo_AUX8 PAN // Servo_AUX9 TILT +// Servo_AUX10 XTRM // Dyntrim, don't use if high. switch(sub_protocol) { case H26WH: diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index a16757c..78d3636 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 1 #define VERSION_REVISION 6 -#define VERSION_PATCH_LEVEL 36 +#define VERSION_PATCH_LEVEL 37 //****************** // Protocols //****************** @@ -378,6 +378,8 @@ enum FailSafeMode { #define Servo_AUX6 (Servo_AUX & _BV(5)) #define Servo_AUX7 (Servo_AUX & _BV(6)) #define Servo_AUX8 (Servo_AUX & _BV(7)) +#define Servo_AUX9 (Servo_data[AUX9 ]>PPM_SWITCH) +#define Servo_AUX10 (Servo_data[AUX10]>PPM_SWITCH) //************************ //*** Power settings *** diff --git a/Protocols_Details.md b/Protocols_Details.md index 4638474..f1070b1 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -379,9 +379,11 @@ Models: EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ... Autobind protocol -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 ----|---|---|---|---|---|---|---|---|---- -A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|---|---|---|----|---- +A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED|RATE + +RATE: -100%(default)=>higher rates by enabling dynamic trims (except for Headless), 100%=>disable dynamic trims ### Sub_protocol BAYANG - *0* Option=0 -> normal Bayang protocol @@ -396,14 +398,14 @@ Same channels assignement as above. ### Sub_protocol X16_AH - *2* Model: X16 AH -CH11 +CH12 ---- TAKE_OFF ### Sub_protocol IRDRONE - *3* Model: IRDRONE -CH11|CH12 +CH12|CH13 ----|---- TAKE_OFF|EMG_STOP @@ -610,9 +612,11 @@ ARM| ## MJXQ - *18* Autobind protocol -CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13 ----|---|---|---|---|---|---|---|---|---|---|---|--- -A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14 +---|---|---|---|---|---|---|---|---|----|----|----|----|---- +A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT|RATE + +RATE: -100%(default)=>higher rates by enabling dynamic trims (except for Headless), 100%=>disable dynamic trims ### Sub_protocol WLH08 - *0* ### Sub_protocol X600 - *1* From dc9b84ea8b85e81cb274ba9f85257b73a3432f7e Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Fri, 1 Dec 2017 16:46:42 +0100 Subject: [PATCH 5/6] _MyConfig.h --- Multiprotocol/Multiprotocol.h | 2 +- Multiprotocol/Multiprotocol.ino | 6 +++--- Multiprotocol/_Config.h | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index b0f884b..78d3636 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -805,4 +805,4 @@ Commands from TX to module use values > 127 for command type data[1-22] Failsafe data, encoded like normal channel data, with the expection that 0 means hold for that channel and 2047 means no pulses -*/ \ No newline at end of file +*/ diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 99a90e1..b768b15 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -38,8 +38,8 @@ #include "_Config.h" //Personal config file -#if __has_include("_MyConfig.h") - #include "_MyConfig.h" +#if __has_include("_MyConfig.h") || defined(USE_MY_CONFIG) +#include "_MyConfig.h" #endif #include "Pins.h" @@ -1589,4 +1589,4 @@ static uint32_t random_id(uint16_t address, uint8_t create_new) WDTCSR = 0; // Disable Watchdog interrupt } } -#endif \ No newline at end of file +#endif diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 08506a7..b9695fd 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -17,6 +17,14 @@ /** Multiprotocol module configuration file ***/ /**********************************************/ +/********************/ +/*** LOCAL CONFIG ***/ +/********************/ +//If you know parameters you want for sure to be enabled or disabled which survives in future, you can use a file named "_MyConfig.h". +//An example is given within the file named "_MyConfig.h.example" which needs to be renamed if you want to use it. +//To enable this config file remove the // from the line below. It's automatically loaded if the file exists for the AVR platform but not STM32... +//#define USE_MY_CONFIG + /*******************/ /*** TX SETTINGS ***/ /*******************/ From 7debad6c673061e1c6957315ac0c9ca9efbfddae Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Fri, 1 Dec 2017 17:55:24 +0100 Subject: [PATCH 6/6] SPORT polling --- Multiprotocol/FrSkyX_cc2500.ino | 25 +++- Multiprotocol/Multiprotocol.h | 2 +- Multiprotocol/Multiprotocol.ino | 14 +- Multiprotocol/Telemetry.ino | 237 +++++++++++++++++++++++++++++--- Multiprotocol/Validate.h | 4 + Multiprotocol/_Config.h | 6 + 6 files changed, 265 insertions(+), 23 deletions(-) diff --git a/Multiprotocol/FrSkyX_cc2500.ino b/Multiprotocol/FrSkyX_cc2500.ino index 08fc29b..aa124f5 100644 --- a/Multiprotocol/FrSkyX_cc2500.ino +++ b/Multiprotocol/FrSkyX_cc2500.ino @@ -1,4 +1,3 @@ - /* ************************** * By Midelic on RCGroups * ************************** @@ -164,6 +163,30 @@ static void __attribute__((unused)) frskyX_data_frame() uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ; for (uint8_t i=22;i>8;//high byte diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 78d3636..cbcd780 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 1 #define VERSION_REVISION 6 -#define VERSION_PATCH_LEVEL 37 +#define VERSION_PATCH_LEVEL 38 //****************** // Protocols //****************** diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index b768b15..22486e1 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -194,6 +194,13 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets uint8_t telemetry_link=0; uint8_t telemetry_counter=0; uint8_t telemetry_lost; + #ifdef SPORT_POLLING + #define MAX_SPORT_BUFFER 64 + uint8_t SportData[MAX_SPORT_BUFFER]; + bool ok_to_send = false; + uint8_t sport_idx = 0; + uint8_t sport_index = 0; + #endif #endif // TELEMETRY // Callback @@ -670,7 +677,9 @@ inline void tx_resume() { #ifdef TELEMETRY // Resume telemetry by enabling transmitter interrupt + #ifndef SPORT_POLLING if(!IS_TX_PAUSE_on) + #endif { #ifdef ORANGE_TX cli() ; @@ -1195,8 +1204,9 @@ void modules_reset() USART2_BASE->CR1 |= USART_CR1_PCE_BIT; } usart3_begin(100000,SERIAL_8E2); - - USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable + #ifndef SPORT_POLLING + USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable + #endif USART2_BASE->CR1 &= ~ USART_CR1_TE; //disable transmit #else //ATMEGA328p diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index 04f0af0..3889450 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -48,6 +48,18 @@ uint8_t RetrySequence ; // Store for FrskyX telemetry struct t_fx_rx_frame FrskyxRxFrames[4] ; uint8_t NextFxFrameToForward ; + #ifdef SPORT_POLLING + uint8_t sport_rx_index[28] ; + uint8_t ukindex ; + uint8_t kindex ; + uint8_t TxData[2]; + uint8_t SportIndexPolling; + uint8_t RxData[16] ; + volatile uint8_t RxIndex=0 ; + uint8_t sport_bytes=0; + uint8_t skipped_id; + uint8_t rx_counter=0; + #endif #endif // SPORT_TELEMETRY #if defined HUB_TELEMETRY @@ -433,13 +445,15 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09 0x34 0x0A 0xC3 0x56 0xF3 */ +#if defined SPORT_POLLING || defined MULTI_TELEMETRY +const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45, + 0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB, + 0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71, + 0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7, + 0x98, 0x39, 0xBA, 0x1B } ; +#endif #ifdef MULTI_TELEMETRY - const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45, - 0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB, - 0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71, - 0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7, - 0x98, 0x39, 0xBA, 0x1B } ; void sportSend(uint8_t *p) { multi_send_header(MULTI_TELEMETRY_SPORT, 9); @@ -489,8 +503,158 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09 } } } + #endif +#if defined SPORT_POLLING +uint8_t nextID() +{ + uint8_t i ; + uint8_t poll_idx ; + if (phase) + { + poll_idx = 99 ; + for ( i = 0 ; i < 28 ; i++ ) + { + if ( sport_rx_index[kindex] ) + { + poll_idx = kindex ; + } + kindex++ ; + if ( kindex>= 28 ) + { + kindex = 0 ; + phase = 0 ; + break ; + } + if ( poll_idx != 99 ) + { + break ; + } + } + if ( poll_idx != 99 ) + { + return poll_idx ; + } + } + if ( phase == 0 ) + { + for ( i = 0 ; i < 28 ; i++ ) + { + if ( sport_rx_index[ukindex] == 0 ) + { + poll_idx = ukindex ; + phase = 1 ; + } + ukindex++; + if (ukindex >= 28 ) + { + ukindex = 0 ; + } + if ( poll_idx != 99 ) + { + return poll_idx ; + } + } + if ( poll_idx == 99 ) + { + phase = 1 ; + return 0 ; + } + } + return poll_idx ; +} + +void pollSport() +{ + uint8_t pindex = nextID() ; + TxData[0] = START_STOP; + TxData[1] = pgm_read_byte_near(&Indices[pindex]) ; + if(!telemetry_lost && ((TxData[1] &0x1F)== skipped_id ||TxData[1]==0x98)) + {//98 ID(RSSI/RxBat and SWR ) and ID's from sport telemetry + pindex = nextID() ; + TxData[1] = pgm_read_byte_near(&Indices[pindex]); + } + SportIndexPolling = pindex ; + RxIndex = 0; + Serial_write(TxData[0]); + Serial_write(TxData[1]); +} + +bool checkSportPacket() +{ + uint8_t *packet = RxData ; + uint16_t crc = 0 ; + if ( RxIndex < 8 ) + return 0 ; + for ( uint8_t i = 0 ; i<8 ; i += 1 ) + { + crc += packet[i]; + crc += crc >> 8; + crc &= 0x00ff; + } + return (crc == 0x00ff) ; +} + +uint8_t unstuff() +{ + uint8_t i ; + uint8_t j ; + j = 0 ; + for ( i = 0 ; i < RxIndex ; i += 1 ) + { + if ( RxData[i] == BYTESTUFF ) + { + i += 1 ; + RxData[j] = RxData[i] ^ STUFF_MASK ; ; + } + else + RxData[j] = RxData[i] ; + j += 1 ; + } + return j ; +} + +void processSportData(uint8_t *p) +{ + + RxIndex = unstuff() ; + uint8_t x=checkSportPacket() ; + if (x) + { + SportData[sport_idx]=0x7E; + sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1); + SportData[sport_idx]=TxData[1]&0x1F; + sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1); + + for(uint8_t i=0;i<(RxIndex-1);i++) + {//no crc + if(p[i]==START_STOP || p[i]==BYTESTUFF) + {//stuff back + SportData[sport_idx]=BYTESTUFF; + sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1); + SportData[sport_idx]=p[i]^STUFF_MASK; + } + else + SportData[sport_idx]=p[i]; + sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1); + } + sport_rx_index[SportIndexPolling] = 1 ; + ok_to_send=true; + RxIndex =0 ; + } +} + +inline void rx_pause() +{ + USART3_BASE->CR1 &= ~ USART_CR1_RXNEIE; //disable rx interrupt on USART3 +} +inline void rx_resume() +{ + USART3_BASE->CR1 |= USART_CR1_RXNEIE; //enable rx interrupt on USART3 +} +#endif//end SPORT_POLLING + void sportIdle() { #if !defined MULTI_TELEMETRY @@ -500,11 +664,18 @@ void sportIdle() void sportSendFrame() { + #if defined SPORT_POLLING + rx_pause(); + #endif uint8_t i; sport_counter = (sport_counter + 1) %36; if(telemetry_lost) { - sportIdle(); + #ifdef SPORT_POLLING + pollSport(); + #else + sportIdle(); + #endif return; } if(sport_counter<6) @@ -542,6 +713,9 @@ void sportSendFrame() for (i=0;i SPORT_TIME) { + #if defined SPORT_POLLING + processSportData(RxData); //process arrived data before polling + #endif sportSendFrame(); #ifdef STM32_BOARD last=now; @@ -831,21 +1012,39 @@ void TelemetryUpdate() #endif { // Transmit interrupt #ifdef STM32_BOARD + #ifdef SPORT_POLLING + if(USART3_BASE->SR & USART_SR_RXNE) + { + USART3_BASE->SR &= ~USART_SR_RXNE; + if (RxIndex < 16 ) + { + if(RxData[0]==TxData[0] && RxData[1]==TxData[1]) + RxIndex=0; + RxData[RxIndex++] = USART3_BASE->DR & 0xFF ; + } + } + #endif if(USART3_BASE->SR & USART_SR_TXE) { + USART3_BASE->SR &= ~USART_SR_TXE; #endif - if(tx_head!=tx_tail) - { - if(++tx_tail>=TXBUFFER_SIZE)//head - tx_tail=0; - #ifdef STM32_BOARD - USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit - #else - UDR0=tx_buff[tx_tail]; - #endif - } - if (tx_tail == tx_head) - tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt + if(tx_head!=tx_tail) + { + if(++tx_tail>=TXBUFFER_SIZE)//head + tx_tail=0; + #ifdef STM32_BOARD + USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit + #else + UDR0=tx_buff[tx_tail]; + #endif + } + if (tx_tail == tx_head) + { + tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt + #ifdef SPORT_POLLING + rx_resume(); + #endif + } #ifdef STM32_BOARD } #endif diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index 02ba70b..b618d10 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -137,6 +137,10 @@ #endif #endif +#if not defined (SPORT_TELEMETRY) || not defined (STM32_BOARD) + #undef SPORT_POLLING +#endif + //Make sure TX is defined correctly #ifndef AILERON #error You must select a correct channel order. diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index b9695fd..782d62f 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -229,6 +229,12 @@ const int8_t AFHDS2AFailsafe[14]= { #define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX #define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX +//SPORT_POLLING is an implementation of the same polling routine as XJT module for sport telemetry bidirectional communication. +//This is useful for passing sport control frames from Tx to rx(ex: changing Betaflight PID or VTX channels on the fly using LUA scripts with OpentX). +//Using this feature on turnigy 9XR_PRO requires uncomment INVERT_TELEMETRY as this TX output on telemetry pin only inverted signal. +//!This is a work in progress! +//#define SPORT_POLLING + /****************************/ /*** SERIAL MODE SETTINGS ***/ /****************************/