diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index f108385c0..076781df2 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -113,6 +113,7 @@ static const YamlLookupTable trainerModeLut = { { TRAINER_MODE_MASTER_BLUETOOTH, "MASTER_BT" }, { TRAINER_MODE_SLAVE_BLUETOOTH, "SLAVE_BT" }, { TRAINER_MODE_MULTI, "MASTER_MULTI" }, + { TRAINER_MODE_CRSF, "MASTER_CRSF" }, }; static const YamlLookupTable swashTypeLut = { diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index dd922fda6..5f8ee4fc2 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -1634,6 +1634,8 @@ QString ModelData::trainerModeToString(int value) return tr("Slave/Bluetooth"); case TRAINER_MODE_MULTI: return tr("Master/Multi"); + case TRAINER_MODE_CRSF: + return tr("Master/CRSF"); default: return CPN_STR_UNKNOWN_ITEM; } diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 4fe0b9706..ed586b521 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -83,7 +83,8 @@ enum TrainerMode { TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, TRAINER_MODE_MULTI, - TRAINER_MODE_LAST = TRAINER_MODE_MULTI + TRAINER_MODE_CRSF, + TRAINER_MODE_LAST = TRAINER_MODE_CRSF }; #define MODEL_NAME_LEN 15 diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index b36e54a17..30e5bf7ee 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -206,10 +206,11 @@ enum TrainerMode { TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, TRAINER_MODE_MULTI, + TRAINER_MODE_CRSF, }; #define TRAINER_MODE_MIN() TRAINER_MODE_OFF -#define TRAINER_MODE_MAX() TRAINER_MODE_MULTI +#define TRAINER_MODE_MAX() TRAINER_MODE_CRSF enum SerialPort { SP_AUX1=0, diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 07553d7ed..8d0b5b501 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -1101,6 +1101,18 @@ bool isTrainerModeAvailable(int mode) #endif } + if (mode == TRAINER_MODE_CRSF) { + +#if !defined(CROSSFIRE) + return false; +#else + if ((!IS_INTERNAL_MODULE_ENABLED() && !IS_EXTERNAL_MODULE_ENABLED()) || + (!(isModuleELRS(INTERNAL_MODULE) && CRSF_ELRS_MIN_VER(INTERNAL_MODULE, 4, 0)) && + !(isModuleELRS(EXTERNAL_MODULE) && CRSF_ELRS_MIN_VER(EXTERNAL_MODULE, 4, 0)))) + return false; +#endif + } + return true; } diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index f36a63a7f..37e704e7b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -1329,6 +1329,7 @@ static const struct YamlIdStr enum_TrainerMode[] = { { TRAINER_MODE_MASTER_BLUETOOTH, "MASTER_BT" }, { TRAINER_MODE_SLAVE_BLUETOOTH, "SLAVE_BT" }, { TRAINER_MODE_MULTI, "MASTER_MULTI" }, + { TRAINER_MODE_CRSF, "MASTER_CRSF" }, { 0, NULL } }; diff --git a/radio/src/telemetry/crossfire.cpp b/radio/src/telemetry/crossfire.cpp index b46c78733..b54f8bcd8 100644 --- a/radio/src/telemetry/crossfire.cpp +++ b/radio/src/telemetry/crossfire.cpp @@ -22,9 +22,15 @@ #include "crossfire.h" #include "edgetx.h" +#include "trainer.h" + // clang-format off #define CS(id,subId,name,unit,precision) {id,subId,unit,precision,name} +#define CROSSFIRE_CH_BITS 11 +#define CROSSFIRE_CH_MASK ((1 << CROSSFIRE_CH_BITS) - 1) +#define CROSSFIRE_CH_CENTER 0x3E0 + const CrossfireSensor crossfireSensors[] = { CS(LINK_ID, 0, STR_SENSOR_RX_RSSI1, UNIT_DB, 0), CS(LINK_ID, 1, STR_SENSOR_RX_RSSI2, UNIT_DB, 0), @@ -194,6 +200,27 @@ void processCrossfireTelemetryFrame(uint8_t module, uint8_t* rxBuffer, } break; + case CHANNELS_ID: + if (g_model.trainerData.mode == TRAINER_MODE_CRSF) { + uint8_t inputbitsavailable = 0; + uint32_t inputbits = 0; + uint8_t byteIdx = 3; + int16_t *pulses = trainerInput; + + for (int i = 0; i < min(CROSSFIRE_CHANNELS_COUNT, MAX_TRAINER_CHANNELS); i++) { + while (inputbitsavailable < CROSSFIRE_CH_BITS) { + inputbits |= (uint32_t)(rxBuffer[byteIdx++]) << inputbitsavailable; + inputbitsavailable += 8; + } + *pulses++ = ((int32_t)(inputbits & CROSSFIRE_CH_MASK) - CROSSFIRE_CH_CENTER) * 5 / 8; + inputbitsavailable -= CROSSFIRE_CH_BITS; + inputbits >>= CROSSFIRE_CH_BITS; + } + + trainerResetTimer(); + } + break; + case LINK_RX_ID: if (getCrossfireTelemetryValue<1>(4, value, rxBuffer)) processCrossfireTelemetryValue(RX_RSSI_PERC_INDEX, value); diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index d45c75616..347ea2e6d 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -158,8 +158,9 @@ const uint8_t CROSSFIRE_FRAME_PERIODS[] = { #define CRSF_ELRS_MIN_VER(moduleIdx, maj, min) \ (crossfireModuleStatus[moduleIdx].isELRS \ - && crossfireModuleStatus[moduleIdx].major >= maj \ - && crossfireModuleStatus[moduleIdx].minor >= min) + && (crossfireModuleStatus[moduleIdx].major > maj \ + || (crossfireModuleStatus[moduleIdx].major == maj \ + && crossfireModuleStatus[moduleIdx].minor >= min))) #if defined(HARDWARE_INTERNAL_MODULE) #define INT_CROSSFIRE_BR_IDX CROSSFIRE_STORE_TO_INDEX(g_eeGeneral.internalModuleBaudrate) diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index ef42183a8..d29c78d2c 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -211,6 +211,7 @@ #define TR_VTRAINER_MASTER_BATTERY "教练主机/串口" #define TR_VTRAINER_BLUETOOTH "教练主机/蓝牙","教练从机/蓝牙" #define TR_VTRAINER_MULTI "教练主机/多协议" +#define TR_VTRAINER_CRSF "教练主机/CRSF" #define TR_VFAILSAFE "未设置","失控保持","自定义","无脉冲","接收机" #define TR_VSENSORTYPES "自定义","运算" #define TR_VFORMULAS "加","平均值","最小值","最大值","乘","总计值","单节电池","消耗量","距离" diff --git a/radio/src/translations/cz.h b/radio/src/translations/cz.h index 8ea3ec97b..d7ac16416 100644 --- a/radio/src/translations/cz.h +++ b/radio/src/translations/cz.h @@ -221,6 +221,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Učitel/Serial" #define TR_VTRAINER_BLUETOOTH TR("Učitel/BT","Učitel/Bluetooth"),TR("Žák/BT","Žák/Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Nenastaven","Držet","Vlastní","Bez pulzů","Přijímač" #define TR_VSENSORTYPES "Vlastní","Vypočtený" #define TR_VFORMULAS "Součet","Průměr","Min","Max","Násobení","Celkem","Článek","Spotřeba","Vzdálenost" diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index 046113931..64bcdb2ed 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -217,6 +217,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Træner/Seriel" #define TR_VTRAINER_BLUETOOTH "Træner/" TR("BT","Bluetooth"), "Elev/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Træner/Multi" +#define TR_VTRAINER_CRSF "Træner/CRSF" #define TR_VFAILSAFE "Ikke sat","Hold","Tilpasset","Ingen puls","Modtager" #define TR_VSENSORTYPES "Tilpasset","Beregnet" #define TR_VFORMULAS "Tillæg","Gennems.","Min","Max","Gange","Sum","Cell","Forbrug","Afstand" diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index 51414239e..b038e71e0 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -212,6 +212,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Lehrer/Serial" #define TR_VTRAINER_BLUETOOTH TR("Lehrer/BT","Lehrer/Bluetooth"),TR("Schüler/BT","Schüler/Bluetooth") #define TR_VTRAINER_MULTI "Lehrer/Multi" +#define TR_VTRAINER_CRSF "Lehrer/CRSF" #define TR_VFAILSAFE "Kein Failsafe","Halte Pos.","Kanäle","Kein Signal","Empfänger" #define TR_VSENSORTYPES "Sensor","Berechnung" #define TR_VFORMULAS "Addieren","Mittelwert","Min","Max","Multiplizier","Gesamt","Zelle","Verbrauch","Distanz" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index 968faa75b..6618d5c76 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -214,6 +214,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Serial" #define TR_VTRAINER_BLUETOOTH "Master/" TR("BT","Bluetooth"), "Slave/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Not set","Hold","Custom","No pulses","Receiver" #define TR_VSENSORTYPES "Custom","Calculated" #define TR_VFORMULAS "Add","Average","Min","Max","Multiply","Totalize","Cell","Consumpt","Distance" diff --git a/radio/src/translations/es.h b/radio/src/translations/es.h index 60e3ca21b..523c6485b 100644 --- a/radio/src/translations/es.h +++ b/radio/src/translations/es.h @@ -210,6 +210,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Serie" #define TR_VTRAINER_BLUETOOTH TR("Master/BT","Master/Bluetooth"),TR("Esclavo/BT","Esclavo/Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "No","Hold","Custom","No pulsos","Receptor" #define TR_VSENSORTYPES "Custom","Calculado" #define TR_VFORMULAS "Suma","Media","Min","Máx","Multipl.","Total","Cell","Consumo","Distancia" diff --git a/radio/src/translations/fi.h b/radio/src/translations/fi.h index 2a8e25be1..97b7564a5 100644 --- a/radio/src/translations/fi.h +++ b/radio/src/translations/fi.h @@ -219,6 +219,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Serial" #define TR_VTRAINER_BLUETOOTH TR("Master/BT","Master/Bluetooth"),TR("Slave/BT","Slave/Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Not set","Hold","Custom","No pulses","Receiver" #define TR_VSENSORTYPES "Custom","Calculated" #define TR_VFORMULAS "Add","Average","Min","Max","Multiply","Totalize","Cell","Kulutus","Etäisyys" diff --git a/radio/src/translations/fr.h b/radio/src/translations/fr.h index 74fb39571..b0b407eed 100644 --- a/radio/src/translations/fr.h +++ b/radio/src/translations/fr.h @@ -217,6 +217,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Maître/Série" #define TR_VTRAINER_BLUETOOTH TR("Maître/BT","Maître/Bluetooth"),TR("Élève/BT","Élève/Bluetooth") #define TR_VTRAINER_MULTI "Maître/Multi" +#define TR_VTRAINER_CRSF "Maître/CRSF" #define TR_VFAILSAFE "Pas déf.","Maintien",TR("Prédéf.","Prédéfini"),"Pas d'imp","Récepteur" #define TR_VSENSORTYPES "Perso","Calculé" #define TR_VFORMULAS "Addition","Moyenne","Min","Max","Multipl.","Totalise","Élém.","Consomm.","Distance" diff --git a/radio/src/translations/he.h b/radio/src/translations/he.h index fc8674d83..633e5bc7f 100644 --- a/radio/src/translations/he.h +++ b/radio/src/translations/he.h @@ -218,6 +218,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Serial" #define TR_VTRAINER_BLUETOOTH "Master/" TR("BT","Bluetooth"), "Slave/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "לא מוגדר","מוחזק","הגדרה ידנית - מומלץ!","ללא שינוי","מקלט" #define TR_VSENSORTYPES "Custom","Calculated" #define TR_VFORMULAS "Add","Average","Min","Max","Multiply","Totalize","Cell","Consumpt","Distance" diff --git a/radio/src/translations/it.h b/radio/src/translations/it.h index 3171375c3..9476941a5 100644 --- a/radio/src/translations/it.h +++ b/radio/src/translations/it.h @@ -214,6 +214,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Seriale" #define TR_VTRAINER_BLUETOOTH "Master/" TR("BT","Bluetooth"), "Slave/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Non settato","Mantieni","Personali","No impulsi","Ricevente" #define TR_VSENSORTYPES "Person.","Calcolato" #define TR_VFORMULAS "Somma","Media","Min","Max","Moltipl","Totalizza","Cella","Consumo","Distanza" diff --git a/radio/src/translations/jp.h b/radio/src/translations/jp.h index c6aa7d39c..c71f67208 100644 --- a/radio/src/translations/jp.h +++ b/radio/src/translations/jp.h @@ -213,6 +213,7 @@ #define TR_VTRAINER_MASTER_BATTERY "マスター/シリアル" #define TR_VTRAINER_BLUETOOTH "マスター/" TR("BT","Bluetooth"), "スレーブ/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "マスター/Multi" +#define TR_VTRAINER_CRSF "マスター/CRSF" #define TR_VFAILSAFE "設定なし","ホールド","カスタム","信号なし","受信機" #define TR_VSENSORTYPES "カスタム","演算" #define TR_VFORMULAS "加算値","平均値","最小値","最大値","乗算値","合計値","セル","消費量","距離" diff --git a/radio/src/translations/nl.h b/radio/src/translations/nl.h index 7e8a4f23d..f9644277f 100644 --- a/radio/src/translations/nl.h +++ b/radio/src/translations/nl.h @@ -211,6 +211,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Master/Serial" #define TR_VTRAINER_BLUETOOTH "Master/" TR("BT","Bluetooth"), "Slave/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Niet Gezet","Vasthouden","Custom","Geen Pulsen","Ontvanger" #define TR_VSENSORTYPES "Custom","Berekend" #define TR_VFORMULAS "Optellen","Gemiddeld","Min","Max","Vermenigvuld","Totaal","Cellen","Verbruik","Afstand" diff --git a/radio/src/translations/pl.h b/radio/src/translations/pl.h index 1e151d4ae..bbc0c15bc 100644 --- a/radio/src/translations/pl.h +++ b/radio/src/translations/pl.h @@ -210,6 +210,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Trener/Serial" #define TR_VTRAINER_BLUETOOTH "Master/" TR("BT","Bluetooth"), "Slave/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Master/Multi" +#define TR_VTRAINER_CRSF "Master/CRSF" #define TR_VFAILSAFE "Brak","Utrzymuj","Własne","0 sygnału","Odbiornik" #define TR_VSENSORTYPES "Użytkownik","Obliczone" #define TR_VFORMULAS "Dodaj","Średnie","Min","Max","Mnóż","Zliczani","Komórka","Zużycie","Zasięg" diff --git a/radio/src/translations/pt.h b/radio/src/translations/pt.h index fcd0ef5af..376207e13 100644 --- a/radio/src/translations/pt.h +++ b/radio/src/translations/pt.h @@ -217,6 +217,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Mestre/Serial" #define TR_VTRAINER_BLUETOOTH "Mestre/" TR("BT","Bluetooth"), "Escrv/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Mestre/Multi" +#define TR_VTRAINER_CRSF "Mestre/CRSF" #define TR_VFAILSAFE "Nao def","Manter","Custom","Sem Pulsos","Receptor" #define TR_VSENSORTYPES "Custom","Calculado" #define TR_VFORMULAS "Soma","Média","Min","Max","Multipl","Totalizar","Cell","Consumido","Distâcia" diff --git a/radio/src/translations/ru.h b/radio/src/translations/ru.h index 1b1542c37..4673472c8 100644 --- a/radio/src/translations/ru.h +++ b/radio/src/translations/ru.h @@ -216,6 +216,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Мастер/Серийный" #define TR_VTRAINER_BLUETOOTH "Мастер/" TR("BT","Bluetooth"), "Раб/" TR("BT","Bluetooth") #define TR_VTRAINER_MULTI "Мастер/Мульти" +#define TR_VTRAINER_CRSF "Мастер/CRSF" #define TR_VFAILSAFE "Не устан","Удерж","Настр","Нет импул","Прием" #define TR_VSENSORTYPES "Настроен","Рассчитан" #define TR_VFORMULAS "Добав","Средн","Мин","Макс","Умнож","Суммир","Ячейка","Расх","Дист" diff --git a/radio/src/translations/se.h b/radio/src/translations/se.h index 875497f2c..c75f6351c 100644 --- a/radio/src/translations/se.h +++ b/radio/src/translations/se.h @@ -224,6 +224,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Lärare/Seriell" #define TR_VTRAINER_BLUETOOTH TR("Lärare/BT","Lärare/Bluetooth"),TR("Elev/BT","Elev/Bluetooth") #define TR_VTRAINER_MULTI "Lärare/Multi" +#define TR_VTRAINER_CRSF "Lärare/CRSF" #define TR_VFAILSAFE "Ej inställt","Lås senaste",TR("Eget","Egna värden"),"Inga pulser","Mottagare" #define TR_VSENSORTYPES "Anpassad","Beräknad" diff --git a/radio/src/translations/tw.h b/radio/src/translations/tw.h index 6b6a63a4a..d42ee4d93 100644 --- a/radio/src/translations/tw.h +++ b/radio/src/translations/tw.h @@ -216,6 +216,7 @@ #define TR_VTRAINER_MASTER_BATTERY "教練主機/端口" #define TR_VTRAINER_BLUETOOTH "教練主機/藍牙","教練從機/藍牙" #define TR_VTRAINER_MULTI "教練主機/多協議" +#define TR_VTRAINER_CRSF "教練主機/CRSF" #define TR_VFAILSAFE "未設置","失控保持","自定義","無脈衝", "接收機" #define TR_VSENSORTYPES "自定義","運算" #define TR_VFORMULAS "加","平均值","最小值","最大值","乘","總計值","單節電池","消耗量","距離" diff --git a/radio/src/translations/ua.h b/radio/src/translations/ua.h index 30bdc1bd4..0cfe90f96 100644 --- a/radio/src/translations/ua.h +++ b/radio/src/translations/ua.h @@ -216,6 +216,7 @@ #define TR_VTRAINER_MASTER_BATTERY "Майстер/Послід." #define TR_VTRAINER_BLUETOOTH "Майстер/" TR("BT","Bluetooth"), "Слейв/" TR("BT","Bluetooth") /* for untranslated - use english */ #define TR_VTRAINER_MULTI "Майстер/Мульти" +#define TR_VTRAINER_CRSF "Майстер/CRSF" #define TR_VFAILSAFE "Не встан.","Тримай","Корист.","Немає імпульсу","Приймач" #define TR_VSENSORTYPES "Корист.","Обчислено" #define TR_VFORMULAS "Дод.","Середн.","Min","Max","Множ.","Сума","Комірка","Витрата","Дистанц." diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index b915382dc..0ca0711e4 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -35,7 +35,7 @@ #define TR_VTRAINERMODES \ TR_VTRAINER_MASTER_OFF, 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 + TR_VTRAINER_MASTER_BATTERY, TR_VTRAINER_BLUETOOTH, TR_VTRAINER_MULTI, TR_VTRAINER_CRSF #if defined(PCBHORUS) #define TR_SM_VSRCRAW "smA","smB","smC","smD","smE","smF",