From 6d77932f89b3c4d7726169fb284a204f6e659cf0 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Tue, 22 Oct 2019 15:53:12 +0200 Subject: [PATCH] Add support for multi-protocol trainer (#6896) * Add support for multi-protocol trainer * Fix telemetry condition * Trainer mode not supported on Sky9X * fixed radio trainer screen - convert values properly. - apply the weights as setup. * Fix T16 with BT * String fixes * Cosmetics --- radio/src/dataconstants.h | 5 +- radio/src/gui/480x272/radio_trainer.cpp | 7 ++- radio/src/gui/common/stdlcd/radio_trainer.cpp | 7 ++- radio/src/telemetry/multi.cpp | 55 ++++++++++++++++++- radio/src/telemetry/telemetry.h | 34 +++++------- radio/src/translations/cz.h.txt | 3 +- radio/src/translations/de.h.txt | 3 +- radio/src/translations/en.h.txt | 3 +- radio/src/translations/es.h.txt | 3 +- radio/src/translations/fi.h.txt | 3 +- radio/src/translations/fr.h.txt | 3 +- radio/src/translations/it.h.txt | 3 +- radio/src/translations/nl.h.txt | 3 +- radio/src/translations/pl.h.txt | 1 + radio/src/translations/pt.h.txt | 1 + radio/src/translations/se.h.txt | 1 + radio/src/translations/untranslated.h | 12 ++-- 17 files changed, 107 insertions(+), 40 deletions(-) diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index a4bef6c77..d433541dc 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -197,6 +197,7 @@ enum TrainerMode { TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, #endif + TRAINER_MODE_MULTI, }; #elif defined(PCBSKY9X) enum ModuleIndex { @@ -206,7 +207,9 @@ enum TrainerMode { }; #endif -#if defined(BLUETOOTH) +#if defined(MULTIMODULE) + #define TRAINER_MODE_MAX() TRAINER_MODE_MULTI +#elif defined(BLUETOOTH) #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH #elif defined(RADIO_T16) #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE diff --git a/radio/src/gui/480x272/radio_trainer.cpp b/radio/src/gui/480x272/radio_trainer.cpp index 48c6305ef..71b1adfd8 100644 --- a/radio/src/gui/480x272/radio_trainer.cpp +++ b/radio/src/gui/480x272/radio_trainer.cpp @@ -86,10 +86,13 @@ bool menuRadioTrainer(event_t event) if (attr) s_editMode = 0; lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + 6*FH, STR_CAL, attr); for (int i=0; i<4; i++) { + int32_t chVal = ppmInput[i] - g_eeGeneral.trainer.calib[i]; + chVal *= g_eeGeneral.trainer.mix[i].studWeight * 10; + chVal /= 512; #if defined (PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(TRAINER_COLUMN_1+i*TRAINER_COLUMN_WIDTH, MENU_CONTENT_TOP + 6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])*2, LEFT|PREC1); + lcdDrawNumber(TRAINER_COLUMN_1+i*TRAINER_COLUMN_WIDTH, MENU_CONTENT_TOP + 6*FH, chVal, LEFT|PREC1); #else - lcdDrawNumber(TRAINER_COLUMN_1+i*TRAINER_COLUMN_WIDTH, MENU_CONTENT_TOP + 6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, LEFT); + lcdDrawNumber(TRAINER_COLUMN_1+i*TRAINER_COLUMN_WIDTH, MENU_CONTENT_TOP + 6*FH, chVal / 10, LEFT); #endif } diff --git a/radio/src/gui/common/stdlcd/radio_trainer.cpp b/radio/src/gui/common/stdlcd/radio_trainer.cpp index a4d6f5e56..58c338a8d 100644 --- a/radio/src/gui/common/stdlcd/radio_trainer.cpp +++ b/radio/src/gui/common/stdlcd/radio_trainer.cpp @@ -88,10 +88,13 @@ void menuRadioTrainer(event_t event) lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr); for (uint8_t i=0; i<4; i++) { uint8_t x = (i*TRAINER_CALIB_COLUMN_WIDTH + 16) * FW/2; + int32_t chVal = ppmInput[i] - g_eeGeneral.trainer.calib[i]; + chVal *= g_eeGeneral.trainer.mix[i].studWeight * 10; + chVal /= 512; #if defined (PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])*2, PREC1|RIGHT); + lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, chVal, PREC1|RIGHT); #else - lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, RIGHT); + lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, chVal / 10, RIGHT); #endif } diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index 7c24ac48c..ec6bdef8d 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -21,6 +21,8 @@ #include "telemetry.h" #include "multi.h" +#define MULTI_CHAN_BITS 11 + extern uint8_t g_moduleIdx; enum MultiPacketTypes : uint8_t @@ -36,7 +38,8 @@ enum MultiPacketTypes : uint8_t FrskySportPolling, HitecTelemetry, SpectrumScannerPacket, - FlyskyIBusTelemetryAC + FlyskyIBusTelemetryAC, + MultiRxChannels }; enum MultiBufferState : uint8_t @@ -239,6 +242,43 @@ static void processMultiSyncPacket(const uint8_t * data, uint8_t module) #endif } +#if defined(PCBTARANIS) || defined(PCBHORUS) +static void processMultiRxChannels(const uint8_t * data, uint8_t len) +{ + if (g_model.trainerData.mode != TRAINER_MODE_MULTI) + return; + + //uint8_t pps = data[0]; + //uint8_t rssi = data[1]; + int ch = max(data[2], (uint8_t)0); + int maxCh = min(ch + data[3], MAX_TRAINER_CHANNELS); + + uint32_t bits = 0; + uint8_t bitsavailable = 0; + uint8_t byteIdx = 4; + + while(ch < maxCh) { + + while((bitsavailable < MULTI_CHAN_BITS) && byteIdx < len) { + bits |= (uint32_t)(data[byteIdx++]) << (uint32_t)bitsavailable; + bitsavailable += 8; + } + + int value = bits & ((1 << MULTI_CHAN_BITS) - 1); + bitsavailable -= MULTI_CHAN_BITS; + bits >>= MULTI_CHAN_BITS; + + ppmInput[ch] = (value - 1024) * 500 / 800; + ch++; + + if (byteIdx >= len) + break; + } + + if (ch == maxCh) + ppmInputValidityTimer = PPM_IN_VALID_TIMEOUT; +} +#endif static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) { @@ -328,6 +368,15 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) TRACE("[MP] Received spectrum scanner len %d != 6", len); break; +#if defined(PCBTARANIS) || defined(PCBHORUS) + case MultiRxChannels: + if (len >= 4) + processMultiRxChannels(data, len); + else + TRACE("[MP] Received RX channels len %d < 4", len); + break; +#endif + default: TRACE("[MP] Unkown multi packet type 0x%02X, len %d", type, len); break; @@ -458,7 +507,7 @@ void MultiModuleStatus::getStatusString(char * statusText) if (!isValid()) { #if defined(PCBTARANIS) || defined(PCBHORUS) #if !defined(INTERNAL_MODULE_MULTI) - if (IS_INTERNAL_MODULE_ENABLED()) + if (isSportLineUsedByInternalModule()) strcpy(statusText, STR_DISABLE_INTERNAL); else #endif @@ -552,7 +601,7 @@ void processMultiTelemetryData(uint8_t data, uint8_t module) uint8_t * rxBuffer = getRxBuffer(module); uint8_t &rxBufferCount = getRxBufferCount(module); - debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", multiTelemetryBufferState, data, rxBufferCount); + //debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", multiTelemetryBufferState, data, rxBufferCount); switch (getMultiTelemetryBufferState(module)) { case NoProtocolDetected: if (data == 'M') { diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 35964e893..442ec7e43 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -111,13 +111,21 @@ extern uint8_t telemetryProtocol; #endif #define IS_SPEKTRUM_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_SPEKTRUM) +#if defined(PCBTARANIS) || defined(PCBHORUS) +inline bool isSportLineUsedByInternalModule() +{ + return g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT_PXX1; +} +#else +inline bool isSportLineUsedByInternalModule() +{ + return false; +} +#endif + inline uint8_t modelTelemetryProtocol() { - bool internalModuleInUse = IS_INTERNAL_MODULE_ENABLED(); -#if defined(INTERNAL_MODULE_MULTI) - //internal muli module is not conflicting with external one - internalModuleInUse = false; -#endif + bool sportUsed = isSportLineUsedByInternalModule(); #if defined(CROSSFIRE) if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_CROSSFIRE) { @@ -125,12 +133,12 @@ inline uint8_t modelTelemetryProtocol() } #endif - if (!internalModuleInUse && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) { + if (!sportUsed && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) { return g_model.telemetryProtocol; } #if defined(MULTIMODULE) - if (!internalModuleInUse && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { + if (!sportUsed && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { return PROTOCOL_TELEMETRY_MULTIMODULE; } #endif @@ -236,18 +244,6 @@ extern OutputTelemetryBuffer outputTelemetryBuffer __DMA; extern Fifo * luaInputTelemetryFifo; #endif -#if defined(PCBTARANIS) || defined(PCBHORUS) -inline bool isSportLineUsedByInternalModule() -{ - return g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT_PXX1; -} -#else -inline bool isSportLineUsedByInternalModule() -{ - return false; -} -#endif - void processPXX2Frame(uint8_t module, uint8_t *frame); #endif // _TELEMETRY_H_ diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index bb1916f94..638af0653 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -353,7 +353,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Učitel/SBUS Modul\0" #define TR_VTRAINER_MASTER_CPPM_MODULE "Učitel/CPPM Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Učitel/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\012" #define TR_VFAILSAFE "Nenastaven""Držet\0 ""Vlastní\0 ""Bez pulzů\0""Přijímač\0" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 9ca6518ae..5538e33b6 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -356,7 +356,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Lehrer/SBUS Modul\0" #define TR_VTRAINER_MASTER_CPPM_MODULE "Lehrer/CPPM Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Lehrer/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\015" // "\013" original #define TR_VFAILSAFE "Kein Failsafe""Halte Pos.\0 ""Kanäle\0 ""Kein Signal\0 ""Empfänger\0 " diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 1e1f9f2e0..4fa537891 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -356,7 +356,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index f68de52c7..44d2fed5c 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -371,7 +371,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Guardar\0 ""Adaptar\0 ""Sin pulso""Receiver\0" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 490dfc35b..4350b43a5 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -371,7 +371,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index be2e60f4b..8a54e8592 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -373,7 +373,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Maître/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Maître/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Maître/Série\0 " -#define TR_VTRAINER_BLUETOOTH TR("Maître/BT\0 ""Elève/BT\0", "Maître/Bluetooth\0 ""Elève/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Maître/BT\0 ""Elève/BT\0 ", "Maître/Bluetooth\0 ""Elève/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE TR("Pas déf.\0""Maintien\0""Prédéf.\0 ""Pas d'imp""Récepteur", "Pas déf.\0""Maintien\0""Prédéfini""Pas d'imp""Récepteur") diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 167f8240d..2804358c5 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -374,7 +374,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/Modulo SBUS" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/Modulo CPPM" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\013" #define TR_VFAILSAFE "Non settato""Mantieni\0 ""Personali\0 ""No impulsi\0""Ricevente\0 " diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index f57f1eb75..36c4189cb 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -353,7 +353,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE TR("\013","\011") #define TR_VFAILSAFE TR("Niet Gezet\0""Vasthouden\0""Custom\0 ""Geen Pulsen""Ontvanger\0 ","Not Set\0 ""Hold\0 ""Custom\0 ""No Pulses""Receiver\0") diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 45c2d3807..66ecb032b 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -375,6 +375,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Trener/CPPM Moduł " #define TR_VTRAINER_MASTER_BATTERY "Trener/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" /*9 decimal*/ #define TR_VFAILSAFE "Brak \0 ""Utrzymuj\0""Własne \0""0 sygnału""Odbiornik" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 217590c1f..669c4c4c4 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -357,6 +357,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 7e6aa1499..7164ba97c 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -370,6 +370,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Lärare/CPPM-Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Lärare/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Ej givet\0""Lås Servo""Anpassat\0""Pulsfritt""Mottagare" diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index dc72f9f58..5c55aad6d 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -68,14 +68,16 @@ #define TR_VSWITCHES "---" "ID0""ID1""ID2" "THR""RUD""ELE""AIL""GEA""TRN" TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_ON_ONE_SWITCHES #endif -#if defined(PCBHORUS) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH +#if defined(PCBHORUS) && !defined(BLUETOOTH) + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MULTI +#elif defined(PCBHORUS) + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBX9E) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) && defined(BLUETOOTH) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_MULTI #else #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY #endif