diff --git a/.gitmodules b/.gitmodules index 61bd2368d..7458ffe95 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,5 +4,5 @@ branch = master [submodule "libACCESS"] path = radio/src/thirdparty/libACCESS - url = https://github.com/FrSky-OS/libACCESS.git + url = https://github.com/FrSkyRC/libACCESS.git branch = master diff --git a/.travis.yml b/.travis.yml index 442466067..6a8432377 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,65 +1,50 @@ sudo: required -dist: trusty +dist: xenial language: cpp compiler: gcc +addons: + apt: + sources: + - sourceline: 'ppa:ubuntu-sdk-team/ppa' + - sourceline: 'ppa:ubuntu-toolchain-r/test' + - sourceline: 'ppa:beineri/opt-qt571-xenial' + update: true + packages: + - curl + - libmpfr4 + - libmpc3 + - libfox-1.6-dev + - libgtest-dev + - clang-6.0 + - python3-pip + env: global: - # - QT_BASE=53 - # - QT_BASE=54 - # - QT_BASE=55 - # - QT_BASE=56 - QT_BASE=57 - # - GCC_ARM=/opt/gcc-arm-none-eabi/bin - - PYTHONPATH=${PYTHONPATH}:/usr/lib/python3/dist-packages + - GCC_ARM_VERSION=4_7-2013q3 matrix: - # - # ALL will build every individual board & DEFAULT, sequentially. - # DEFAULT is "make all" (including Companion & Simulator), with default settings - # - # - FLAVOR=ALL - - FLAVOR=DEFAULT + - FLAVOR=COMPANION - FLAVOR=ARM9X - # - FLAVOR=AR9X - # - FLAVOR=SKY9X - # - FLAVOR=9XRPRO - FLAVOR=X9LITE - - FLAVOR=X9LITES - FLAVOR=X7 - - FLAVOR=T12 - FLAVOR=XLITE - - FLAVOR=XLITES - FLAVOR=X9 - # - FLAVOR=X9D - # - FLAVOR=X9D+ - # - FLAVOR=X9E - - FLAVOR=T16 - - FLAVOR=HORUS - # - FLAVOR=X10 - # - FLAVOR=X12Sr10 - # - FLAVOR=X12S + - FLAVOR=COLORLCD before_install: - - sudo add-apt-repository ppa:ubuntu-sdk-team/ppa --yes - - sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded --yes - - sudo add-apt-repository ppa:ubuntu-toolchain-r/test --yes - - if [ "$QT_BASE" = "53" ]; then sudo add-apt-repository ppa:beineri/opt-qt532-trusty -y; fi - - if [ "$QT_BASE" = "54" ]; then sudo add-apt-repository ppa:beineri/opt-qt542-trusty -y; fi - - if [ "$QT_BASE" = "55" ]; then sudo add-apt-repository ppa:beineri/opt-qt551-trusty -y; fi - - if [ "$QT_BASE" = "56" ]; then sudo add-apt-repository ppa:beineri/opt-qt562-trusty -y; fi - - if [ "$QT_BASE" = "57" ]; then sudo add-apt-repository ppa:beineri/opt-qt571-trusty -y; fi - - sudo apt-get update -qq - - pyenv uninstall -f 2.7.6 && pyenv install 3.5.4 && pyenv global 3.5.4 - - pip install pillow - -install: - - sudo apt-get --yes --force-yes install curl libmpfr4 libmpc3 libfox-1.6-dev libgtest-dev - - sudo apt-get --yes --force-yes install gcc-arm-none-eabi - # Trying to build with gcc-arm 4.7 isn't working because it can't find the compiler, despite adding to PATH (in commit-tests.sh) by defining GCC_ARM above - # - wget --quiet https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q3-update/+download/gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2 - # - tar xjf gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2 - # - mv gcc-arm-none-eabi-4_7-2013q3 /opt/gcc-arm-none-eabi + - wget --quiet https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q3-update/+download/gcc-arm-none-eabi-${GCC_ARM_VERSION}-20130916-linux.tar.bz2 + - tar xjf gcc-arm-none-eabi-${GCC_ARM_VERSION}-20130916-linux.tar.bz2 + - sudo mv gcc-arm-none-eabi-${GCC_ARM_VERSION} /opt/gcc-arm-none-eabi + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-gcc /usr/bin/arm-none-eabi-gcc + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-g++ /usr/bin/arm-none-eabi-g++ + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-as /usr/bin/arm-none-eabi-as + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-objcopy /usr/bin/arm-none-eabi-objcopy + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-objdump /usr/bin/arm-none-eabi-objdump + - sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-size /usr/bin/arm-none-eabi-size - sudo apt-get install --yes --force-yes -qq qt${QT_BASE}base qt${QT_BASE}multimedia qt${QT_BASE}svg qt${QT_BASE}tools; source /opt/qt${QT_BASE}/bin/qt${QT_BASE}-env.sh + - sudo ln -sf /usr/bin/python3 /usr/bin/python + - python3 -m pip install pillow clang script: - ./tools/commit-tests.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 97782efcf..89f912977 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(VERSION_REVISION "0") set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) -set(SDCARD_REVISION "0000") +set(SDCARD_REVISION "0024") set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION}) cmake_minimum_required(VERSION 2.8) @@ -235,15 +235,21 @@ add_custom_target(tests-radio if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) add_subdirectory(${COMPANION_SRC_DIRECTORY}) - add_custom_target(gtests DEPENDS gtests-radio gtests-companion) + add_custom_target(tests-companion + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion + DEPENDS gtests-companion + ) + add_custom_target(gtests + DEPENDS gtests-radio gtests-companion + ) add_custom_target(tests - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio && ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion - DEPENDS gtests + DEPENDS tests-radio tests-companion ) else() - add_custom_target(gtests DEPENDS gtests-radio) + add_custom_target(gtests + DEPENDS gtests-radio + ) add_custom_target(tests - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio - DEPENDS gtests + DEPENDS tests-radio ) endif() diff --git a/CREDITS.txt b/CREDITS.txt index 62e673034..b654164b9 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1633,3 +1633,31 @@ Siegfried Preißler Bernard Mohamedaly John North Thomas Wormsley +Michael Schreiber +DTg Privat +Frédéric Devillard +Lauland Bourg +Jurij Peternel +Murray King +Horia Adrian Bucovanu +Freddy Prousteau +Wojciech Winiarski +James A Davey +James Donelson +David Jolly +Domingos S. Fonseca M. +Kenneth Frehafer +Christian Epple +David Williams +Michael Bernard +Michael Wagner +Carl Pennington +LTR Consulting +Norman Brisson +Darko Perković +Andreas Fischer +Pablo Peinado Abad +NthWave Web Works +Simon Brenner +Joseph Litko +Bradley Murchie diff --git a/companion/src/firmwares/io_data.cpp b/companion/src/firmwares/io_data.cpp index f7df7ddf6..b0201d3d5 100644 --- a/companion/src/firmwares/io_data.cpp +++ b/companion/src/firmwares/io_data.cpp @@ -85,6 +85,11 @@ void LimitData::clear() max = +1000; } +bool LimitData::isEmpty() const +{ + return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0'); +} + /* * CurveData diff --git a/companion/src/firmwares/io_data.h b/companion/src/firmwares/io_data.h index b501d4944..7f22b045a 100644 --- a/companion/src/firmwares/io_data.h +++ b/companion/src/firmwares/io_data.h @@ -111,6 +111,7 @@ class LimitData { QString revertToString() const; QString nameToString(int index) const; void clear(); + bool isEmpty() const; }; class CurvePoint { diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 2d384415f..c4959d456 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -123,6 +123,9 @@ enum TrainerMode { TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, + TRAINER_MODE_MASTER_BLUETOOTH, + TRAINER_MODE_SLAVE_BLUETOOTH, + TRAINER_MODE_MULTI }; class ModelData { diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index b4457345a..a227dd5b8 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -86,7 +86,7 @@ QString ModuleData::rfProtocolToString() const { switch (protocol) { case PULSES_MULTIMODULE: - return Multiprotocols::protocolToString((int)multi.rfProtocol, multi.customProto); + return Multiprotocols::protocolToString((int)multi.rfProtocol); default: return CPN_STR_UNKNOWN_ITEM; @@ -107,7 +107,7 @@ QString ModuleData::subTypeToString(int type) const switch (protocol) { case PULSES_MULTIMODULE: - return Multiprotocols::subTypeToString(multi.customProto ? MM_RF_CUSTOM_SELECTED : (int)multi.rfProtocol, (unsigned)type); + return Multiprotocols::subTypeToString((int)multi.rfProtocol, (unsigned)type); case PULSES_PXX_R9M: return CHECK_IN_ARRAY(strings, type); diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index 8f3f8cd53..6d6795c58 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -164,9 +164,10 @@ class ModuleData { struct Multi { unsigned int rfProtocol; + bool disableTelemetry; + bool disableMapping; bool autoBindMode; bool lowPowerMode; - bool customProto; int optionValue; } multi; diff --git a/companion/src/firmwares/multiprotocols.cpp b/companion/src/firmwares/multiprotocols.cpp index 73f9ea69f..f1b37bae0 100644 --- a/companion/src/firmwares/multiprotocols.cpp +++ b/companion/src/firmwares/multiprotocols.cpp @@ -172,5 +172,8 @@ QString Multiprotocols::protocolToString(int protocol, bool custom) // static QString Multiprotocols::subTypeToString(int protocol, unsigned subType) { - return tr(qPrintable(multiProtocols.getProtocol(protocol).subTypeStrings.value(subType, CPN_STR_UNKNOWN_ITEM))); + if (protocol > MODULE_SUBTYPE_MULTI_LAST) + return tr(qPrintable(QString::number(subType))); + else + return tr(qPrintable(multiProtocols.getProtocol(protocol).subTypeStrings.value(subType, CPN_STR_UNKNOWN_ITEM))); } diff --git a/companion/src/firmwares/multiprotocols.h b/companion/src/firmwares/multiprotocols.h index 9eded65b6..42a6cfc9c 100644 --- a/companion/src/firmwares/multiprotocols.h +++ b/companion/src/firmwares/multiprotocols.h @@ -23,6 +23,7 @@ #include #include +#include "moduledata.h" #define MM_RF_CUSTOM_SELECTED 0xff @@ -48,7 +49,7 @@ class Multiprotocols unsigned int numSubTypes() const { - return (unsigned int) subTypeStrings.length(); + return protocol > MODULE_SUBTYPE_MULTI_LAST ? 8 : (unsigned int) subTypeStrings.length(); } int getOptionMin() const; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 80b56f16f..10df6d7a3 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -2037,9 +2037,10 @@ class ModuleUnionField: public UnionField { rfProtExtra(0) { ModuleData::Multi& multi = module.multi; - internalField.Append(new UnsignedField<2>(this, rfProtExtra)); - internalField.Append(new SpareBitsField<3>(this)); - internalField.Append(new BoolField<1>(this, multi.customProto)); + internalField.Append(new UnsignedField<3>(this, rfProtExtra)); + internalField.Append(new BoolField<1>(this, multi.disableTelemetry)); + internalField.Append(new BoolField<1>(this, multi.disableMapping)); + internalField.Append(new SpareBitsField<1>(this)); internalField.Append(new BoolField<1>(this, multi.autoBindMode)); internalField.Append(new BoolField<1>(this, multi.lowPowerMode)); internalField.Append(new SignedField<8>(this, multi.optionValue)); @@ -2052,12 +2053,17 @@ class ModuleUnionField: public UnionField { void beforeExport() override { - rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03; + if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST) + module.multi.rfProtocol += 3; + rfProtExtra = (module.multi.rfProtocol & 0x70) >> 4; + module.multi.rfProtocol &= 0x0f; } void afterImport() override { - module.multi.rfProtocol = (rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf); + module.multi.rfProtocol = (rfProtExtra << 4) + (module.rfProtocol & 0xf); + if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST) + module.multi.rfProtocol -= 3; } private: diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 3b4413a3c..9509c3c28 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -1222,7 +1222,6 @@ void registerOpenTxFirmwares() /* FrSky Taranis X9D+ 2019 board */ firmware = new OpenTxFirmware("opentx-x9d+2019", Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019); addOpenTxTaranisOptions(firmware); - firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky Taranis X9D board */ @@ -1243,13 +1242,11 @@ void registerOpenTxFirmwares() /* FrSky X9-Lite board */ firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE); addOpenTxTaranisOptions(firmware); - firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky X9-LiteS board */ firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES); addOpenTxTaranisOptions(firmware); - firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky X7 board */ @@ -1260,7 +1257,6 @@ void registerOpenTxFirmwares() /* FrSky X-Lite S/PRO board */ firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES); addOpenTxTaranisOptions(firmware); - firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky X-Lite board */ @@ -1276,9 +1272,8 @@ void registerOpenTxFirmwares() registerOpenTxFirmware(firmware); /* FrSky X10 Express board */ - firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 / X10S Express"), BOARD_X10_EXPRESS); + firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express / X10S Express"), BOARD_X10_EXPRESS); addOpenTxFrskyOptions(firmware); - firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky X12 (Horus) board */ @@ -1289,17 +1284,18 @@ void registerOpenTxFirmwares() registerOpenTxFirmware(firmware); /* Jumper T12 board */ - firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12"), BOARD_JUMPER_T12); + firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12 / T12 Pro"), BOARD_JUMPER_T12); addOpenTxCommonOptions(firmware); firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support")); firmware->addOption("nogvars", Firmware::tr("Disable Global variables")); firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); firmware->addOption("flexr9m", Firmware::tr("Enable non certified R9M firmwares")); + firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); /* Jumper T16 board */ - firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+"), BOARD_JUMPER_T16); + firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); addOpenTxFrskyOptions(firmware); firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module")); diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 8868e7766..737882d78 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -40,6 +40,12 @@ void HardwarePanel::setupSwitchType(int index, QLabel * label, AutoLineEdit * na else if (index == 5) { label->setText("SH"); } + if (index == 6) { + label->setText("SI"); + } + else if (index == 7) { + label->setText("SJ"); + } } if (IS_JUMPER_T12(board)) { if (index == 4) { @@ -166,7 +172,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings ui->txCurrentCalibrationLabel->hide(); } - if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_HORUS(board) || IS_JUMPER_T12(board)) { + if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_HORUS(board)) { ui->bluetoothMode->addItem(tr("OFF"), 0); if (IS_TARANIS_X9E(board)) { ui->bluetoothMode->addItem(tr("Enabled"), 1); diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 358f85817..a5f25d1ca 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -701,6 +701,10 @@ void MdiChild::updateTitle() if (availableEEpromSize >= 0) { title += QString(" - %1 ").arg(availableEEpromSize) + tr("free bytes"); } + QFileInfo fi(curFile); + if (!isUntitled && !fi.isWritable()) { + title += QString(" (%1)").arg(tr("read only")); + } setWindowTitle(title); } @@ -1355,7 +1359,8 @@ bool MdiChild::loadFile(const QString & filename, bool resetCurrentFile) bool MdiChild::save() { - if (isUntitled) { + QFileInfo fi(curFile); + if (isUntitled || !fi.isWritable()) { return saveAs(true); } else { diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 4fbe64a9a..593121d83 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -101,6 +101,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera { Stopwatch s1("Channels"); + chnCapability = firmware->getCapability(Outputs); int channelNameMaxLen = firmware->getCapability(ChannelsName); QStringList headerLabels; @@ -115,11 +116,11 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera headerLabels << tr("PPM Center"); if (firmware->getCapability(SYMLimits)) headerLabels << tr("Linear Subtrim"); - TableLayout *tableLayout = new TableLayout(this, firmware->getCapability(LogicalSwitches), headerLabels); + TableLayout *tableLayout = new TableLayout(this, chnCapability, headerLabels); s1.report("header"); - for (int i=0; igetCapability(Outputs); i++) { + for (int i=0; iresizeColumnsToContents(); - tableLayout->pushRowsUp(firmware->getCapability(Outputs)+1); + tableLayout->pushRowsUp(chnCapability+1); s1.report("end"); } @@ -279,7 +280,7 @@ void Channels::ppmcenterEdited() void Channels::update() { - for (int i=0; igetCapability(Outputs); i++) { + for (int i=0; imimeData(); - if (mimeData->hasFormat("application/x-companion-chn")) { - QByteArray chnData = mimeData->data("application/x-companion-chn"); + if (mimeData->hasFormat(MIMETYPE_CHN)) { + QByteArray chnData = mimeData->data(MIMETYPE_CHN); LimitData *chn = &model->limitData[selectedChannel]; memcpy(chn, chnData.constData(), sizeof(LimitData)); updateLine(selectedChannel); @@ -326,8 +327,17 @@ void Channels::chnPaste() void Channels::chnDelete() { - model->limitData[selectedChannel].clear(); - updateLine(selectedChannel); + int maxidx = chnCapability - 1; + for (int i=selectedChannel; ilimitData[i].isEmpty() || !model->limitData[i+1].isEmpty()) { + LimitData *chn1 = &model->limitData[i]; + LimitData *chn2 = &model->limitData[i+1]; + memcpy(chn1, chn2, sizeof(LimitData)); + updateLine(i); + } + } + model->limitData[maxidx].clear(); + updateLine(maxidx); emit modified(); } @@ -336,32 +346,93 @@ void Channels::chnCopy() QByteArray chnData; chnData.append((char*)&model->limitData[selectedChannel],sizeof(LimitData)); QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-companion-chn", chnData); + mimeData->setData(MIMETYPE_CHN, chnData); QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } void Channels::chnCut() { chnCopy(); - chnDelete(); + chnClear(); } void Channels::chn_customContextMenuRequested(QPoint pos) { - QLabel *label = (QLabel *)sender(); - selectedChannel = label->property("index").toInt(); + QLabel *label = (QLabel *)sender(); + selectedChannel = label->property("index").toInt(); - QPoint globalPos = label->mapToGlobal(pos); + QPoint globalPos = label->mapToGlobal(pos); - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat("application/x-companion-chn"); + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); + bool hasData = mimeData->hasFormat(MIMETYPE_CHN); + bool moveUpAllowed = (selectedChannel > 0); + bool moveDownAllowed = (selectedChannel < (chnCapability - 1)); + bool insertAllowed = (selectedChannel < (chnCapability - 1)) && (model->limitData[chnCapability - 1].isEmpty()); - QMenu contextMenu; - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(chnCopy())); - contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(chnCut())); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(chnPaste()))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(chnDelete())); + QMenu contextMenu; + contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(chnCopy())); + contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(chnCut())); + contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(chnPaste()))->setEnabled(hasData); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(chnClear())); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(chnInsert()))->setEnabled(insertAllowed); + contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(chnDelete())); + contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(chnMoveUp()))->setEnabled(moveUpAllowed); + contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(chnMoveDown()))->setEnabled(moveDownAllowed); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(chnClearAll())); - contextMenu.exec(globalPos); + contextMenu.exec(globalPos); +} + +void Channels::chnMoveUp() +{ + swapChnData(selectedChannel, selectedChannel - 1); +} + +void Channels::chnMoveDown() +{ + swapChnData(selectedChannel, selectedChannel + 1); +} + +void Channels::chnClear() +{ + model->limitData[selectedChannel].clear(); + updateLine(selectedChannel); + emit modified(); +} + +void Channels::chnClearAll() +{ + for (int i=0; ilimitData[i].clear(); + updateLine(i); + } + emit modified(); +} + +void Channels::chnInsert() +{ + for (int i=(chnCapability - 1); i>selectedChannel; i--) { + if (!model->limitData[i].isEmpty() || !model->limitData[i-1].isEmpty()) { + memcpy(&model->limitData[i], &model->limitData[i-1], sizeof(LimitData)); + updateLine(i); + } + } + chnClear(); +} + +void Channels::swapChnData(int idx1, int idx2) +{ + if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) { + LimitData chntmp = model->limitData[idx2]; + LimitData *chn1 = &model->limitData[idx1]; + LimitData *chn2 = &model->limitData[idx2]; + memcpy(chn2, chn1, sizeof(LimitData)); + memcpy(chn1, &chntmp, sizeof(LimitData)); + updateLine(idx1); + updateLine(idx2); + emit modified(); + } } diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index a13fa84a6..f50c72b89 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -26,6 +26,8 @@ #include +constexpr char MIMETYPE_CHN[] = "application/x-companion-chn"; + class GVarGroup; class LimitsGroup @@ -70,9 +72,15 @@ class Channels : public ModelPanel void chnCopy(); void chnPaste(); void chnCut(); + void chnMoveUp(); + void chnMoveDown(); + void chnInsert(); + void chnClear(); + void chnClearAll(); void chn_customContextMenuRequested(QPoint pos); private: + void swapChnData(int idx1, int idx2); QLineEdit *name[CPN_MAX_CHNOUT]; LimitsGroup *chnOffset[CPN_MAX_CHNOUT]; LimitsGroup *chnMin[CPN_MAX_CHNOUT]; @@ -82,6 +90,7 @@ class Channels : public ModelPanel QSpinBox *centerSB[CPN_MAX_CHNOUT]; QCheckBox *symlimitsChk[CPN_MAX_CHNOUT]; int selectedChannel; + int chnCapability; }; #endif // _CHANNELS_H_ diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index dfcc1809e..c30454bdc 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -74,7 +74,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, { Stopwatch s1("CustomFunctionsPanel - populate"); lock = true; - int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); + fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this); @@ -83,7 +83,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, if (!firmware->getCapability(VoicesAsNumbers)) { tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength)); - for (int i=0; igetBoard())) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); - for (int i=0; isetContextMenuPolicy(Qt::CustomContextMenu); @@ -244,7 +244,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, tableLayout->resizeColumnsToContents(); s1.report("resizeColumnsToContents"); tableLayout->setColumnWidth(3, 300); - tableLayout->pushRowsUp(num_fsw+1); + tableLayout->pushRowsUp(fswCapability+1); s1.report("end"); } @@ -579,7 +579,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) widgetsMask |= CUSTOM_FUNCTION_ENABLE; } } - } fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); @@ -603,8 +602,7 @@ void CustomFunctionsPanel::update() { updateDataModels(); lock = true; - int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); - for (int i=0; imimeData(); - if (mimeData->hasFormat("application/x-companion-fsw")) { - QByteArray fswData = mimeData->data("application/x-companion-fsw"); + if (mimeData->hasFormat(MIMETYPE_FSW)) { + QByteArray fswData = mimeData->data(MIMETYPE_FSW); CustomFunctionData *fsw = &functions[selectedFunction]; memcpy(fsw, fswData.constData(), sizeof(CustomFunctionData)); - lock = true; - fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue())); - fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func)); - populateGVmodeCB(fswtchGVmode[selectedFunction], functions[selectedFunction].adjustMode); - populateFuncParamCB(fswtchParamT[selectedFunction], functions[selectedFunction].func, functions[selectedFunction].param, functions[selectedFunction].adjustMode); - refreshCustomFunction(selectedFunction); - lock = false; + resetCBsAndRefresh(selectedFunction); emit modified(); } } void CustomFunctionsPanel::fswDelete() { - functions[selectedFunction].clear(); - // TODO update switch and func - lock = true; - fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue())); - fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func)); - refreshCustomFunction(selectedFunction); - lock = false; + int maxidx = fswCapability - 1; + for (int i=selectedFunction; isetData("application/x-companion-fsw", fswData); + mimeData->setData(MIMETYPE_FSW, fswData); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void CustomFunctionsPanel::fswCut() { fswCopy(); - fswDelete(); + fswClear(); } void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos) { - QLabel *label = (QLabel *)sender(); - selectedFunction = label->property("index").toInt(); + QLabel *label = (QLabel *)sender(); + selectedFunction = label->property("index").toInt(); - QPoint globalPos = label->mapToGlobal(pos); + QPoint globalPos = label->mapToGlobal(pos); - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat("application/x-companion-fsw"); + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); + bool hasData = mimeData->hasFormat(MIMETYPE_FSW); + bool moveUpAllowed = (selectedFunction > 0); + bool moveDownAllowed = (selectedFunction < (fswCapability - 1)); + bool insertAllowed = (selectedFunction < (fswCapability - 1)) && (functions[fswCapability - 1].isEmpty()); - QMenu contextMenu; - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy())); - contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut())); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete())); + QMenu contextMenu; + contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(fswCopy())); + contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(fswCut())); + contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(fswPaste()))->setEnabled(hasData); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(fswClear())); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(fswInsert()))->setEnabled(insertAllowed); + contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(fswDelete())); + contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(fswMoveUp()))->setEnabled(moveUpAllowed); + contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(fswMoveDown()))->setEnabled(moveDownAllowed); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(fswClearAll())); - contextMenu.exec(globalPos); + contextMenu.exec(globalPos); } void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) @@ -755,3 +761,65 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi b->hide(); } } + +void CustomFunctionsPanel::fswMoveUp() +{ + swapFuncData(selectedFunction, selectedFunction - 1); +} + +void CustomFunctionsPanel::fswMoveDown() +{ + swapFuncData(selectedFunction, selectedFunction + 1); +} + +void CustomFunctionsPanel::fswClear() +{ + functions[selectedFunction].clear(); + resetCBsAndRefresh(selectedFunction); + emit modified(); +} + +void CustomFunctionsPanel::fswClearAll() +{ + for (int i=0; iselectedFunction; i--) { + if (!functions[i].isEmpty() || !functions[i-1].isEmpty()) { + memcpy(&functions[i], &functions[i-1], sizeof(CustomFunctionData)); + resetCBsAndRefresh(i); + } + } + fswClear(); +} + +void CustomFunctionsPanel::swapFuncData(int idx1, int idx2) +{ + if ((idx1 != idx2) && (!functions[idx1].isEmpty() || !functions[idx2].isEmpty())) { + CustomFunctionData fswtmp = functions[idx2]; + CustomFunctionData *fsw1 = &functions[idx1]; + CustomFunctionData *fsw2 = &functions[idx2]; + memcpy(fsw2, fsw1, sizeof(CustomFunctionData)); + memcpy(fsw1, &fswtmp, sizeof(CustomFunctionData)); + resetCBsAndRefresh(idx1); + resetCBsAndRefresh(idx2); + emit modified(); + } +} + +void CustomFunctionsPanel::resetCBsAndRefresh(int idx) +{ + lock = true; + fswtchSwtch[idx]->setCurrentIndex(fswtchSwtch[idx]->findData(functions[idx].swtch.toValue())); + fswtchFunc[idx]->setCurrentIndex(fswtchFunc[idx]->findData(functions[idx].func)); + fswtchGVmode[idx]->setCurrentIndex(functions[idx].adjustMode); + populateFuncParamCB(fswtchParamT[idx], functions[idx].func, functions[idx].param, functions[idx].adjustMode); + refreshCustomFunction(idx); + lock = false; +} diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index 26cb4b273..fd257ce98 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -30,6 +30,8 @@ class RawSourceFilterItemModel; class RawSwitchFilterItemModel; class TimerEdit; +constexpr char MIMETYPE_FSW[] = "application/x-companion-fsw"; + class RepeatComboBox: public QComboBox { Q_OBJECT @@ -53,7 +55,7 @@ class CustomFunctionsPanel : public GenericPanel Q_OBJECT public: - CustomFunctionsPanel(QWidget *parent, ModelData * mode, GeneralSettings & generalSettings, Firmware * firmware); + CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware); ~CustomFunctionsPanel(); virtual void update(); @@ -77,11 +79,18 @@ class CustomFunctionsPanel : public GenericPanel void fswCopy(); void fswPaste(); void fswCut(); + void fswMoveUp(); + void fswMoveDown(); + void fswInsert(); + void fswClear(); + void fswClearAll(); private: void populateFuncCB(QComboBox *b, unsigned int value); void populateGVmodeCB(QComboBox *b, unsigned int value); void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0); + void swapFuncData(int idx1, int idx2); + void resetCBsAndRefresh(int idx); RawSwitchFilterItemModel * rawSwitchItemModel; RawSourceFilterItemModel * rawSrcAllItemModel; RawSourceFilterItemModel * rawSrcInputsItemModel; @@ -105,6 +114,7 @@ class CustomFunctionsPanel : public GenericPanel QMediaPlayer * mediaPlayer; int selectedFunction; + int fswCapability; }; diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index aa2081fd1..81f2f52e7 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -527,8 +527,8 @@ void LogicalSwitchesPanel::cswPaste() QByteArray cswData = mimeData->data("application/x-companion-csw"); LogicalSwitchData *csw = &model->logicalSw[selectedSwitch]; memcpy(csw, cswData.constData(), sizeof(LogicalSwitchData)); + update(); emit modified(); - updateLine(selectedSwitch); } } diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index c996bc374..77988a2e7 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -195,13 +195,24 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->label_module->setText(ModuleData::indexToString(moduleIdx, firmware)); if (moduleIdx < 0) { - if (IS_HORUS(firmware->getBoard())) { + if (!IS_TARANIS(firmware->getBoard())) { ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1); ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1); - } - if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER) { ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1); } + else if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER) { + ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1); + } + + if (generalSettings.bluetoothMode != 2) { + ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BLUETOOTH, 0, Qt::UserRole - 1); + ui->trainerMode->setItemData(TRAINER_MODE_SLAVE_BLUETOOTH, 0, Qt::UserRole - 1); + } + + if (!IS_JUMPER_T16(firmware->getBoard())) { + ui->trainerMode->setItemData(TRAINER_MODE_MULTI, 0, Qt::UserRole - 1); + } + ui->trainerMode->setCurrentIndex(model.trainerMode); if (!IS_HORUS_OR_TARANIS(firmware->getBoard())) { ui->label_trainerMode->hide(); @@ -227,6 +238,9 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul continue; ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i); } + for (int i=MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) { + ui->multiProtocol->addItem(QString::number(i + 3), i); + } ui->btnGrpValueType->setId(ui->optPercent, FAILSAFE_DISPLAY_PERCENT); ui->btnGrpValueType->setId(ui->optUs, FAILSAFE_DISPLAY_USEC); @@ -269,7 +283,9 @@ bool ModulePanel::moduleHasFailsafes() (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M || (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE || (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE_PRO || - (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_XJT_LITE_X16); + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_XJT_LITE_X16 || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_MULTIMODULE + ); } void ModulePanel::setupFailsafes() @@ -469,14 +485,14 @@ void ModulePanel::update() break; case PULSES_MULTIMODULE: mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE | MASK_SUBTYPES; - max_rx_num = 15; + max_rx_num = 63; if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2) mask |= MASK_CHANNELS_COUNT; else module.channelsCount = 16; if (pdef.optionsstr != nullptr) mask |= MASK_MULTIOPTION; - if (pdef.hasFailsafe) + if (pdef.hasFailsafe || (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_FRSKY && (module.subType == 0 || module.subType == 2 || module.subType > 3 ))) mask |= MASK_FAILSAFES; break; case PULSES_OFF: @@ -565,7 +581,7 @@ void ModulePanel::update() unsigned i = 0; switch(protocol){ case PULSES_MULTIMODULE: - numEntries = (module.multi.customProto ? 8 : pdef.numSubTypes()); + numEntries = (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST ? 8 : pdef.numSubTypes()); break; case PULSES_PXX_R9M: if (firmware->getCapability(HasModuleR9MFlex)) @@ -587,11 +603,19 @@ void ModulePanel::update() ui->multiProtocol->setVisible(mask & MASK_MULTIMODULE); ui->label_option->setVisible(mask & MASK_MULTIOPTION); ui->optionValue->setVisible(mask & MASK_MULTIOPTION); - ui->autoBind->setVisible(mask & MASK_MULTIMODULE); + ui->disableTelem->setVisible(mask & MASK_MULTIMODULE); + ui->disableChMap->setVisible(mask & MASK_MULTIMODULE); ui->lowPower->setVisible(mask & MASK_MULTIMODULE); + ui->autoBind->setVisible(mask & MASK_MULTIMODULE); + if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2) + ui->autoBind->setText(tr("Autodetect Format")); + else + ui->autoBind->setText(tr("Bind on channel")); if (mask & MASK_MULTIMODULE) { ui->multiProtocol->setCurrentIndex(ui->multiProtocol->findData(module.multi.rfProtocol)); + ui->disableTelem->setChecked(module.multi.disableTelemetry); + ui->disableChMap->setChecked(module.multi.disableMapping); ui->autoBind->setChecked(module.multi.autoBindMode); ui->lowPower->setChecked(module.multi.lowPowerMode); } @@ -763,7 +787,7 @@ void ModulePanel::onMultiProtocolChanged(int index) lock=true; module.multi.rfProtocol = (unsigned int)rfProtocol; unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes(); - if (module.multi.customProto) + if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST) maxSubTypes=8; module.subType = std::min(module.subType, maxSubTypes -1); module.channelsCount = getMaxChannelCount(); @@ -793,10 +817,21 @@ void ModulePanel::onSubTypeChanged() } } +void ModulePanel::on_disableTelem_stateChanged(int state) +{ + module.multi.disableTelemetry = (state == Qt::Checked); +} + +void ModulePanel::on_disableChMap_stateChanged(int state) +{ + module.multi.disableMapping = (state == Qt::Checked); +} + void ModulePanel::on_autoBind_stateChanged(int state) { module.multi.autoBindMode = (state == Qt::Checked); } + void ModulePanel::on_lowPower_stateChanged(int state) { module.multi.lowPowerMode = (state == Qt::Checked); diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 3edb1efd8..586cba07d 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -86,6 +86,8 @@ class ModulePanel : public ModelPanel void onMultiProtocolChanged(int index); void onSubTypeChanged(); void on_autoBind_stateChanged(int state); + void on_disableChMap_stateChanged(int state); + void on_disableTelem_stateChanged(int state); void on_lowPower_stateChanged(int state); void on_r9mPower_currentIndexChanged(int index); void setChannelFailsafeValue(const int channel, const int value, quint8 updtSb = 0); diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui index 5ed3f9e11..c0a54d024 100644 --- a/companion/src/modeledit/setup_module.ui +++ b/companion/src/modeledit/setup_module.ui @@ -7,7 +7,7 @@ 0 0 1075 - 434 + 438 @@ -417,7 +417,6 @@ - Bind on startup @@ -935,9 +934,24 @@ Master/SBUS in battery compartment + + + Master/Bluetooth + + + + + Slave/Bluetooth + + + + + Master/Multi + + - + Qt::Horizontal @@ -950,6 +964,20 @@ + + + + Disable Telemetry + + + + + + + Disable Ch. Map + + + diff --git a/companion/src/translations/companion_de.ts b/companion/src/translations/companion_de.ts index 63d302d40..009eff99e 100644 --- a/companion/src/translations/companion_de.ts +++ b/companion/src/translations/companion_de.ts @@ -2417,7 +2417,7 @@ If you have a settings backup file, you may import that instead. Popup menu available - Popoup-Menü verfügbar + Popup-Menü verfügbar @@ -2482,7 +2482,7 @@ If you have a settings backup file, you may import that instead. Not enough free points in EEPROM to store the curve. - Es sind nicht genügend freie Stützstellen im EEPROM vorhanden, um diese Kurve zu abzuspeichern. + Es sind nicht genügend freie Stützpunkte im EEPROM vorhanden, um diese Kurve zu abzuspeichern. diff --git a/companion/src/translations/companion_fr.ts b/companion/src/translations/companion_fr.ts index 355c77914..8f69bf1bb 100644 --- a/companion/src/translations/companion_fr.ts +++ b/companion/src/translations/companion_fr.ts @@ -828,84 +828,109 @@ Manche Droit: Profondeur, Direction Channels - + Name Nom - + Min - + Max - + Subtrim - + Direction - + Curve Courbe - + PPM Center Neutre PPM - + Linear Subtrim Subtrim linéaire - + CH%1 VOIE%1 - + Popup menu available Menu contextuel disponible - + --- - + INV - - &Copy - &Copier + + Copy + Copier - - &Cut - &Couper + + Cut + Couper - - &Paste - &Coller + + Paste + Coller - - &Delete - &Supprimer + + Clear + Effacer + + + + Insert + Insérer + + + + Delete + Supprimer + + + + Move Up + Monter + + + + Move Down + Descendre + + + + Clear All + Effacer Tout @@ -1321,7 +1346,7 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import CurveData - + CV CB @@ -1826,45 +1851,70 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import %1 - + + Copy + Copier + + + + Cut + Couper + + + + Paste + Coller + + + + Clear + Effacer + + + + Insert + Insérer + + + + Delete + Supprimer + + + + Move Up + Monter + + + + Move Down + Descendre + + + + Clear All + Effacer Tout + + + Value Valeur - + Source Source - + GVAR VG - + Increment Incrément - - - &Delete - &Supprimer - - - - &Copy - &Copier - - - - &Cut - &Couper - - - - &Paste - &Coller - CustomizeSplashDialog @@ -2070,7 +2120,7 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import OpenTX ne supporte pas cette fonction sur cette carte - + OpenTX doesn't accept this radio protocol OpenTX ne supporte pas ce protocole radio @@ -2833,19 +2883,19 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont - + Disable HELI menu and cyclic mix support Supprimer le menu HELICO et les mixages cycliques - + Disable Global variables Supprimer le support des variables globales - + Enable Lua custom scripts screen Activer l'écran des scripts Lua personnalisés @@ -2880,107 +2930,99 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont - + FrSky Taranis X9D - + Haptic module installed Module vibreur installé - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmation avant l'arrêt de la radio - + Horus gimbals installed (Hall sensors) Manches Horus à effet HALL installés - + FrSky Taranis X9-Lite - - - - - - Support for auto update on boot - Prise en charge de la mise à jour automatique au démarrage - - - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S - + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - - + + Support for ACCESS internal module replacement Prise en charge du module de remplacement interne ACCESS - + + FrSky Horus X10 Express / X10S Express + + + + FrSky Horus X12S - + Use ONLY with first DEV pcb version Exclusivement pour les Horus DEV - Jumper T12 - - - - Enable non certified R9M firmwares Activer les firmwares R9M non certifiés - - Jumper T16 / T16+ - - - - + + Support for MULTI internal module Prise en charge du module MULTI interne - + + Support for bluetooth module + Prise en charge du module Bluetooth + + + Turnigy 9XR-PRO @@ -3025,22 +3067,17 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Ne pas mettre les lignes actives en gras - - FrSky Horus X10 / X10S Express - - - - + Turnigy 9XR with m128 chip Turnigy 9XR avec une puce m128 - + Turnigy 9XR - + 9X with stock board 9X avec carte mère d'origine @@ -3050,27 +3087,37 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Permet la remise à zéro des valeurs en pressant haut-bas en même temps, valeur min avec gauche/bas, valeur max avec haut/droite, inversion avec gauche/droite - + 9X with stock board and m128 chip Carte 9x avec un chip m128 - + 9X with AR9X board 9X avec carte AR9X - + + Jumper T12 / T12 Pro + + + + + Jumper T16 / T16+ / T16 Pro + + + + 9X with Sky9x board 9X avec carte Sky9x - + 9X with Gruvin9x board 9X avec carte Gruvin9x - + DIY MEGA2560 radio Radio DIY à base de MEGA2560 @@ -3549,7 +3596,7 @@ Vous utilisez actuellement: FlightModeData - + FM PV @@ -5290,8 +5337,8 @@ Cette fonction ne peut pas être désactivée sur la radio. HardwarePanel - - + + None Aucun @@ -5311,67 +5358,67 @@ Cette fonction ne peut pas être désactivée sur la radio. 3 Positions - + Pot with detent Potentiomètre avec centre - + Multipos switch Inter multiposition - + Pot without detent Potentiomètre sans centre - + Slider with detent Curseur avec centre - + OFF - + Enabled Activé - + Telemetry Télémétrie - + Trainer Écolage - + Internal Interne - + Ask Demander - + Per model Par modèle - + Internal + External Interne + Externe - + External Externe @@ -6992,12 +7039,12 @@ Do you wish to continue? MdiChild - + Unable to find file %1! Fichier %1 introuvable ! - + Save As Enregister Sous @@ -7194,49 +7241,54 @@ Do you wish to continue? Afficher la barre d'outils "Modèle" - + + read only + lecture seule + + + Category index out of range. Index de catégorie hors limite. - + Cannot delete the last category. Impossible d'effacer la dernière catégorie. - + This category is not empty! Catégorie non vide ! - + Cannot insert model, last model in list would be deleted. Impossible d'insérer le modèle, le dernier modèle dans la liste serait supprimé. - + Cannot add model, could not find an available model slot. Impossible d'ajouter un modèle, aucun emplacement libre n’est disponible. - + New model Translators: do NOT use accents here, this is a default model name. No accent, but no more than 15 characters!! Nve modele - + Cannot paste model, out of available model slots. Impossible de coller le modèle, aucun emplacement libre n’est disponible. - + You are replacing an existing model, are you sure? Vous allez écraser un modèle existant, êtes-vous sûr ? - + Delete %n selected model(s)? Supprimer le modèle sélectionné ? @@ -7244,7 +7296,7 @@ Do you wish to continue? - + Delete %n selected category(ies)? Supprimer la catégorie sélectionnée ? @@ -7252,59 +7304,59 @@ Do you wish to continue? - + Cannot duplicate model, could not find an available model slot. Impossible de dupliquer le modèle, aucun emplacement libre n’est disponible. - + Do you wish to continue with the conversion? Souhaitez-vous vraiment lancer la conversion ? - + Choose <i>Apply</i> to convert the file, or <i>Close</i> to close it without conversion. Choisissez <i>Appliquer</i> pour convertir le fichier ou <i>Annuler</i> pour le fermer sans conversion. - + <b>The conversion generated some important messages, please review them below.</b> <b>La conversion a généré des messages importants, veuillez les consulter ci-dessous.</b> - + Companion :: Conversion Result for %1 Companion :: Résultat de conversion de %1 - + Unable to find Horus radio SD card! Impossible de trouver la carte SD de la Horus ! - + Models and Settings written Modèle et paramètres écrit - + Cannot write temporary file! Ecriture de fichier temporaire impossible ! - + Editing model %1: Édition du modèle %1 : - + Error reading file %1: %2. Fichier %1 corrompu: %2. - + Error opening file %1: %2. Erreur à l'ouverture du fichier %1: @@ -7326,7 +7378,7 @@ Do you wish to continue? - + Do you want to overwrite radio general settings? Voulez-vous vraiment écraser les paramètres généraux ? @@ -7336,29 +7388,29 @@ Do you wish to continue? octets libres - + New category Translators do NOT use accent for this, this is the default category name on Horus. No accent, but no more than 15 characters!! Nlle categorie - + <p><b>Currently selected radio type (%1) is not compatible with file %3 (from %2), models and settings need to be converted.</b></p> <p><b>Le type de radio actuellement sélectionné (%1) n'est pas compatible avec le fichier %3 (à partir de %2), les modèles et les paramètres doivent être convertis.</b></p> - + Open backup Models and Settings file Ouvrir la sauvegarde de paramètres et modèles - + Invalid binary backup File %1 Fichier de sauvegarde %1 invalide - + %1 has been modified. Do you want to save your changes? %1 a été modifié. @@ -8657,7 +8709,7 @@ Mixage actif par défaut si non-renseigné. Module - + Failsafe Mode Mode Failsafe @@ -8667,7 +8719,7 @@ Mixage actif par défaut si non-renseigné. 1ère voie - + PPM delay Impulsion @@ -8687,12 +8739,12 @@ Mixage actif par défaut si non-renseigné. Polarité - + Trainer Mode Mode écolage - + PPM Frame Length Longueur de trame PPM @@ -8702,42 +8754,42 @@ Mixage actif par défaut si non-renseigné. VOIE - + Antenna Antenne - + Option value - + us µs - + Master/Jack Maître/Jack - + Slave/Jack Elève/Jack - + Master/SBUS Module Maître/SBUS module - + Master/CPPM Module Maître/CPPM Module - + Master/SBUS in battery compartment Maître/SBUS dans compartiment batterie @@ -8747,29 +8799,54 @@ Mixage actif par défaut si non-renseigné. Puissance RF - + Sub Type Sous-Type - + + Master/Bluetooth + Maître/Bluetooth + + + + Slave/Bluetooth + Elève/Bluetooth + + + + Master/Multi + Maître/Multi + + + + Disable Telemetry + Désactiver la télémétrie + + + + Disable Ch. Map + Désactiver "Mapping" des VOIES + + + Show values in: Afficher les valeurs en: - + % abbreviation for percent - + μs abbreviation for microseconds - + ms @@ -8801,57 +8878,57 @@ Mixage actif par défaut si non-renseigné. ATTENTION: RE-BIND nécessaire pour tout changement de puissance RF - + Channels Nb de voies - + Not set Non défini - + Hold Maintien - + Custom Prédéfini - + No Pulses Pas d'impulsions - + Receiver Récepteur - + WARNING: Requires non-certified firmware! ATTENTION: Nécessite un firmware non certifié! - + Registration ID ID d'enregistrement - + Failsafe Positions Positions Failsafe - + Protocol Protocole - + Multi Radio Protocol Protocole Multi @@ -8861,27 +8938,22 @@ Mixage actif par défaut si non-renseigné. Récepteur No. - + Output type Type de sortie - + Open Drain - + Push Pull - - Bind on startup - Bind au démarage - - - + Low Power Puissance Réduite @@ -8889,12 +8961,12 @@ Mixage actif par défaut si non-renseigné. ModuleData - + Positive - + Negative Négative @@ -8975,40 +9047,50 @@ Mixage actif par défaut si non-renseigné. ModulePanel - + Value Valeur - + Hold Maintien - + No Pulse Pas d'impulsion - + Ask Demander - + Internal Interne - + Internal + External Interne + Externe - + External Externe + + + Autodetect Format + Format Détection auto + + + + Bind on channel + Bind avec VOIE + MultiModelPrinter @@ -10943,22 +11025,22 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo SetupPanel - + Timer %1 Chrono %1 - + THR GAZ - + Profile Settings Paramètres du profil - + SD structure path not specified or invalid Chemin de la structure SD non spécifié ou invalide @@ -11682,62 +11764,62 @@ La valeur par défaut est configurée dans le profil radio sélectionné.Simulateur Radio (%1) - + Could not determine startup data source. Impossible de déterminer les données source. - + Could not load data, possibly wrong format. Impossible de charger les données, mauvais format. - + Data Load Error Erreur de lecture des données - + Invalid startup data provided. Plese specify a proper file/path. Données de démarrage fournies non valides. Veuillez spécifier un fichier/chemin approprié. - + Simulator Startup Error Erreur de démarrage du simulateur - + Error saving data: could open file for writing: '%1' Erreur de sauvegarde des données: impossible d'écrire le fichier '%1' - + Error saving data: could not get data from simulator interface. Erreur de sauvegarde des données: impossible de récupérer les données depuis l'interface de simulation. - + An unexpected error occurred while attempting to save radio data to file '%1'. Une erreur inattendue s'est produite lors de l'enregistrement des données radio dans le fichier '%1'. - + Data Save Error Erreur de sauvegarde des données - + Cannot open joystick, joystick disabled Impossible d'accéder au Joystick, Joystick désactivé - + Radio firmware error: %1 Erreur firmware radio: %1 - + - Flight Mode %1 (#%2) - Phase de Vol %1 (#%2) diff --git a/companion/src/translations/companion_ja.ts b/companion/src/translations/companion_ja.ts index 0db7a42a8..ddc8b2c37 100644 --- a/companion/src/translations/companion_ja.ts +++ b/companion/src/translations/companion_ja.ts @@ -97,26 +97,12 @@ AppPreferencesDialog - - - - - - - Edit Settings このダイアログはメインメニュー->設定 設定 - - - - - - - Radio Profile 様々な操作に対応する複数のうろファイルが存在する場合があります。 送信機プロファイル @@ -128,256 +114,88 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select Folder フォルダの選択 - - - - - - - - - - - - - - The profile specific folder, if set, will override general Backup folder プロファイル保存フォルダが指定される場合は、バックアップフォルダを上書き保存します - - - - - - - Splash Screen 起動イメージ - - - - - - - Select Image イメージの選択 - - - - - - - Clear Image イメージの消去 - - - - - - - Profile Name プロファイル名 - - - - - - - Radio Type 送信機タイプ - - - - - - - Menu Language メニュー言語 - - - - - - - Build Options ビルドオプション - - - - - - - SD Structure path SDカード保存先パス - - - - - - - Backup folder バックアップフォルダ - - - - - - - If set it will override the application general setting 設定されている場合はアプリケーション設定を上書き保存します - - - - - - - if set, will override general backup enable 設定されている場合は有効なバックアップを上書き保存します - - - - - - - - - - - - - - Enable automatic backup before writing firmware 設定した場合は自動バックアップを有効にします - - - - - - - General Settings 一般設定 - - - - - - - Default Stick Mode 初期スティックモード - - - - - - - Mode selection: Mode 1: @@ -401,913 +219,386 @@ Mode 4: - - - - - - - Mode 1 (RUD ELE THR AIL) - モード1 (左:エレベーター・ラダー 右:スロットル・エルロン) + モード1 (左:エレベーター・ラダー 右:スロットル・エルロン) - - - - - - - Mode 2 (RUD THR ELE AIL) - モード2 (左:スロットル・ラダー 右:エレベーター・エルロン) + モード2 (左:スロットル・ラダー 右:エレベーター・エルロン) - - - - - - - Mode 3 (AIL ELE THR RUD) - モード3 (左:エレベーター・エルロン 右:スロットル・ラダー) + モード3 (左:エレベーター・エルロン 右:スロットル・ラダー) - - - - - - - Mode 4 (AIL THR ELE RUD) - モード4 (左:スロットル・エルロン 右:エレベーター・ラダー) + モード4 (左:スロットル・エルロン 右:エレベーター・ラダー) - - - - - - - Default Channel Order 初期チャンネルマップ - - - - - - - <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>チャンネルマップ</p><p><br/></p><p>モデル作成された際の初期チャンネルマップを定義します</p></body></html> - - - - - - - R E T A - ↔RUD ↕ELE ↕THR ↔AIL [R E T A] + ↔RUD ↕ELE ↕THR ↔AIL [R E T A] - - - - - - - R E A T - ↔RUD ↕ELE ↔AIL ↕THR [R E A T] + ↔RUD ↕ELE ↔AIL ↕THR [R E A T] - - - - - - - R T E A - ↔RUD ↕THR ↕ELE ↔AIL [R T E A] + ↔RUD ↕THR ↕ELE ↔AIL [R T E A] - - - - - - - R T A E - ↔RUD ↕THR ↔AIL ↕ELE [R T A E] + ↔RUD ↕THR ↔AIL ↕ELE [R T A E] - - - - - - - R A E T - ↔RUD ↔AIL ↕ELE ↕THR [R A E T] + ↔RUD ↔AIL ↕ELE ↕THR [R A E T] - - - - - - - R A T E - ↔RUD ↔AIL ↕THR ↕ELE [R A T E] + ↔RUD ↔AIL ↕THR ↕ELE [R A T E] - - - - - - - E R T A - ↕ELE ↔RUD ↕THR ↔AIL [E R T A] + ↕ELE ↔RUD ↕THR ↔AIL [E R T A] - - - - - - - E R A T - ↕ELE ↔RUD ↔AIL ↕THR [E R A T] + ↕ELE ↔RUD ↔AIL ↕THR [E R A T] - - - - - - - E T R A - ↕ELE ↕THR ↔RUD ↔AIL [E T R A] + ↕ELE ↕THR ↔RUD ↔AIL [E T R A] - - - - - - - E T A R - ↕ELE ↕THR ↔AIL ↔RUD [E T A R] + ↕ELE ↕THR ↔AIL ↔RUD [E T A R] - - - - - - - E A R T - ↕ELE ↔AIL ↔RUD ↕THR [E A R T] + ↕ELE ↔AIL ↔RUD ↕THR [E A R T] - - - - - - - E A T R - ↕ELE ↔AIL ↕THR ↔RUD [E A T R] + ↕ELE ↔AIL ↕THR ↔RUD [E A T R] - - - - - - - T R E A - ↕THR ↔RUD ↕ELE ↔AIL [T R E A] + ↕THR ↔RUD ↕ELE ↔AIL [T R E A] - - - - - - - T R A E - ↕THR ↔RUD ↔AIL ↕ELE [T R A E] + ↕THR ↔RUD ↔AIL ↕ELE [T R A E] - - - - - - - T E R A - ↕THR ↕ELE ↔RUD ↔AIL [T E R A] + ↕THR ↕ELE ↔RUD ↔AIL [T E R A] - - - - - - - T E A R - ↕THR ↕ELE ↔AIL ↔RUD [T E A R] + ↕THR ↕ELE ↔AIL ↔RUD [T E A R] - - - - - - - T A R E - ↕THR ↔AIL ↔RUD ↕ELE [T A R E] + ↕THR ↔AIL ↔RUD ↕ELE [T A R E] - - - - - - - T A E R - ↕THR ↔AIL ↕ELE ↔RUD [T A E R] + ↕THR ↔AIL ↕ELE ↔RUD [T A E R] - - - - - - - A R E T - ↔AIL ↔RUD ↕ELE ↕THR [A R E T] + ↔AIL ↔RUD ↕ELE ↕THR [A R E T] - - - - - - - A R T E - ↔AIL ↔RUD ↕THR ↕ELE [A R T E] + ↔AIL ↔RUD ↕THR ↕ELE [A R T E] - - - - - - - A E R T - ↔AIL ↕ELE ↔RUD ↕THR [A E R T] + ↔AIL ↕ELE ↔RUD ↕THR [A E R T] - - - - - - - A E T R - ↔AIL ↕ELE ↕THR ↔RUD [A E T R] + ↔AIL ↕ELE ↕THR ↔RUD [A E T R] - - - - - - - A T R E - ↔AIL ↕THR ↔RUD ↕ELE [A T R E] + ↔AIL ↕THR ↔RUD ↕ELE [A T R E] - - - - - - - A T E R - ↔AIL ↕THR ↕ELE ↔RUD [A T E R] + ↔AIL ↕THR ↕ELE ↔RUD [A T E R] - - - - - - - Append version number to FW file name ファームウェア ファイル名にバージョン番号を追加 - - - - - - - Offer to write FW to Tx after download ダウンロード後、送信機にFWを適用可能な事を通知 - - - - - - - Other Settings その他の設定 - - - - - - - Application Settings アプリケーション設定 - - - - - - - Automatic check for OpenTX firmware updates OpenTXファームアップデートの自動チェック - - - - - - - Automatic check for Companion updates Companionアップデートの自動チェック - - - - - - - most recently used files 最近使用したファイル - - - - - - - Startup Settings スタートアップ設定 - - - - - - - Google Earth Executable Google Earthの実行 - - - - - - - Automatic Backup Folder 自動バックアップフォルダ - - - - - - - Remember ファイル履歴 - - - - - - - Show splash screen when Companion starts Companion起動時に起動イメージを表示 - - - - - - - Output Logs Folder ログ出力フォルダ - - - - - - - <html><head/><body><p>This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. </p><p>When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.</p></body></html> <html><head/><body><p>このオプションは、機体モデルが削除または移動した際、そのモデルスロットが保持される旧版のOpenTxバージョンの挙動を維持します。</p><p>このオプションが選択されない場合は、他の機体モデルは削除により残された差異を埋めるために並べ替えるかもしれません。</p></body></html> - - - - - - - Remove empty model slots when deleting models (only applies for radios w/out categories) モデルを削除するとき同時に空モデルスロットを削除 (カテゴリなしの機体モデルにのみ適用) - - - - - - - Use model wizard 機体モデルウィザードを使用 - - - - - - - Open model editor 機体モデルエディタを開く - - - - - - - Just create the model 機体モデルの作成のみ - - - - - - - Debug Output Logging 出力したログのデバッグ - - - - - - - Only show user splash images オリジナルの起動イメージのみを表示 - - - - - - - Show user and companion splash images オリジナルとCompanion標準イメージを表示 - - - - - - - Select Executable 実行ファイル選択 - - - - - - - <html><head/><body><p>Keep a log of all debugging messages generated by the desktop Companion/Simulator applications. An OpenTX developer may request this to help diagnose an issue.</p></body></html> <html><head/><body><p>デスクトップのCompanion / シミュレータ アプリケーションにより生成された、すべてのデバッグメッセージのログを保存します。OpenTX開発者は問題を診断・解析するため、ログを要求するかもしれません。</p></body></html> - - - - - - - Application (Companion/Simulator) アプリケーション (Companion / シミュレータ) - - - - - - - <html><head/><body><p>Keep a log of all messages generated by the radio firmware when running in Simulator. This is the same information one would also see in the Simulator <span style=" font-style:italic;">Debug Output</span> window.</p></body></html> <html><head/><body><p>シミュレータで実行しているときは、送信機ファームウェアによって生成されたすべてのメッセージのログを保存してください。これはシミュレータの<span style = "font-style:italic;">デバッグ出力</span>ウィンドウにも同じ情報が表示されます。</p></body></html> - - - - - - - Radio Firmware (in Simulator) 送信機ファームウェア (シミュレータ内) - - - - - - - Splash Screen Library 起動イメージライブラリ - - - - - - - User Splash Screens オリジナル起動イメージ - - - - - - - Action on New Model 機体モデル新規作成 - - - - Release channel リリース状態 選択 - - - - Releases (stable) リリース版 (Stable) - - - - Release candidates (testing) Release candidates RC版 (Testing) - - - - Nightly builds (unstable) ナイトリービルド版 (Unstable) - - - - - - - Simulator Settings シミュレータ設定 - - - - - - - Calibrate キャリブレート - - - - - - - Blue 青色 - - - - - - - Green 緑色 - - - - - - - Red 赤色 - - - - - - - Orange オレンジ - - - - - - - Yellow 黄色 - - - - - - - Screenshot capture folder 画面キャプチャフォルダ - - - - - - - Only capture to clipboard キャプチャをクリップボードのみにコピー - - - - - - - Enable 有効 - - - - - - - Joystick スティック - - - - - - - Simulator BackLight バックライト - - - - - - - Remember simulator switch values シミュレータで設定した各スイッチの値を記憶 - - - - - - - Simulator Volume Gain シミュレータ 音量幅 @@ -1319,7 +610,7 @@ Mode 4: <p><b>You cannot switch Radio Type or change Build Options while there are unsaved file changes. What do you wish to do?</b></p> <ul><li><i>Save All</i> - Save any open file(s) before saving Settings.<li><li><i>Reset</i> - Revert to the previous Radio Type and Build Options before saving Settings.</li><li><i>Cancel</i> - Return to the Settings editor dialog.</li></ul> - <p><b>ファイル変更後で保存されていない間は、送信機タイプの切り替えやビルドオプションの変更はできません。保存しますか?</b></p> <ul><li><i>すべて保存</i> - 設定を保存する前に、開いているファイルをすべて保存します  <li><li><i>リセット</i> - 設定を保存する前に、以前の送信機タイプとビルドオプションに戻します </li><li><i>キャンセル</i> - 設定エディタダイアログに戻ります </li></ul> + <p><b>ファイル変更後で保存されていない間は、送信機タイプの切り替えやビルドオプションの変更はできません。保存しますか?</b></p> <ul><li><i>すべて保存</i> - 設定を保存する前に、開いているファイルをすべて保存します  <li><li><i>リセット</i> - 設定を保存する前に、以前の送信機タイプとビルドオプションに戻します </li><li><i>キャンセル</i> - 設定エディタダイアログに戻ります </li></ul> @@ -1388,31 +679,6 @@ Mode 4: Images (%1) イメージ (%1) - - - - - Use releases (stable) - - - - - Use release candidates (testing) - - - - - - - Use nightly builds (unstable) - - - - - - Use releases and release candidates (testing) - - BinEepromFormat @@ -1449,58 +715,58 @@ Mode 4: Boards - + Left Horizontal 左・横 - + Left Vertical 左・縦 - + Right Vertical 右・縦 - + Right Horizontal 右・横 - + Aux. 1 AUX. 1 - + Aux. 2 AUX. 2 - - + + Unknown 不明 - + Rud ラダー - + Ele エレベーター - + Thr スロットル - + Ail エルロン @@ -1633,85 +899,36 @@ Mode 4: ChecklistDialog - - - - - - - Edit Checklist チェックリスト編集 - - - - - - - Line nn, Col nn 行 nn, カラー nn - - - - - - - &Import... &インポート... - - - - - - - &Cancel &キャンセル - - - - - - - &OK &OK - - - - - - - Please note, the maximum width displayable is radio model limited. Also, renaming the model will break the link to this checklist file. 注: 表示可能な最大幅は送信機モデルによって異なります。また、モデル名称を変更すると、このチェックリストファイルへのリンクが解除されます。 - - - - - - - File: unknown ファイル: 不明 @@ -1813,37 +1030,37 @@ Mode 4: 送信機と機体モデルの設定 - + Select or create a file for exported Settings: エクスポートした設定ファイルを選択または作成します: - + Press the 'Retry' button to choose another file. 別のファイルを選択するには『再試行』ボタンを押してください。 - + Simulator for this firmware is not yet available このファームウェアのシミュレータはまだ利用できません - + Uknown error during Simulator startup. シミュレータ起動中に不明なエラーが発生しました。 - + Simulator Error シミュレータ エラー - + Data Load Error データロード エラー - + Error occurred while starting simulator. シミュレータ起動中にエラーが発生しました。 @@ -1967,73 +1184,31 @@ If you have a settings backup file, you may import that instead. CompareDialog - - - - - - - Compare Models 機体モデルの比較 - - - - - - - To compare models, drag and drop them anywhere in this window. 機体モデルを比較するには、モデルをこのウィンドウ内の任意の場所にドラッグ&ドロップしてください。 - - - - - - - Close 閉じる - - - - - - - Style スタイル - - - - - - - Print 出力 - - - - - - - Print to file ファイルへ出力 @@ -2190,213 +1365,87 @@ If you have a settings backup file, you may import that instead. Curves - - - - - - - Curve name カーブ名 - - - - - - - Fixed X 等間隔 - - - - - - - Custom X カスタム - - - - - - - Lines 直線 - - - - - - - Smooth なめらか - - - - - - - - - - - - - - Curve type カーブタイプ - - - - - - - Curve Creator カーブ クリエイター - - - - - - - Coefficient カーブ係数 - - - - - - - Side 片側カーブ - - - - - - - Y at X=-100 カーブ左端の高さ - - - - - - - Both 両カーブ - - - - - - - x>0 右カーブ - - - - - - - x<0 左カーブ - - - - - - - Y at X=100 カーブ右端の高さ - - - - - - - Apply 適用 - - - - - - - Y at X=0 カーブ中心の高さ - - - - - - - Point size 点のサイズ @@ -2810,53 +1859,18 @@ If you have a settings backup file, you may import that instead. CustomizeSplashDialog - - - - - - - Transmitter Splash Screen Editor 送信機 起動イメージ エディタ - - - - - - - - - - - - - - Invert 反転 - - - - - - - - - - - - - - Open Splash Library イメージライブラリを開く @@ -2865,114 +1879,30 @@ If you have a settings backup file, you may import that instead. - - - - - - - - - - - - - - - - - - - - - - - - - - - - ... ... - - - - - - - - - - - - - - Load Profile プロファイル ロード - - - - - - - - - - - - - - Load FW FW ロード - - - - - - - - - - - - - - Load Pict 画像 ロード - - - - - - - - - - - - - - Save 保存 @@ -3088,48 +2018,48 @@ If you have a settings backup file, you may import that instead. フィールド %1 変換エラー - + Switch スイッチ - + Switch スイッチ - + cannot be exported on this board! このボードにエクスポートできません! - + Source 選択元 - + Source %1 cannot be exported on this board! このボードでは選択元 %1 をエクスポートできません! - + OpenTX only accepts %1 points in all curves OpenTXはすべてのカーブで %1 点のみを許容します - + OpenTx only accepts %1 points in all curves OpenTxはすべてのカーブで %1 点のみを許容します - + OpenTX on this board doesn't accept this function このボード上のOpenTXはこの機能を受け付けません - + OpenTX doesn't accept this radio protocol OpenTXはこの送信機プロトコルを受け付けません @@ -3138,57 +2068,21 @@ If you have a settings backup file, you may import that instead. DebugOutput - - - - - - - - - Debug Output デバッグ出力 - - - - - - - - - <html><head/><body><p>Enable or disable the filter. If the button won't stay enabled, it is likely there is a syntax error in the Regular Expression entered.</p></body></html> <html><head/><body><p>フィルタを有効または無効にします。ボタンが有効にならない場合は、入力した正規表現に構文エラーがある可能性があります。</p></body></html> - - - - - - - - - Filter: フィルタ: - - - - - - - - - <html><head/><body><p>Enter filter text here. Click the help/info button for details about using the filter. </p><p> To <b>remove a remembered entry</b> from the filter list, first choose it, and then press <code>Shift-Delete</code> (or <code>Shift-Backspace</code>) key combination.</p></body></html> <html><head/><body><p>ここにフィルタテキストを入力してください。フィルタの使用方法の詳細は、help / info ボタンをクリックしてください。</p><p> @@ -3196,141 +2090,51 @@ To <b>remove a remembered entry</b> from the filter list, first cho - - - - - - - - - Buffer: バッファ: - - - - - - - - - Number of lines to keep in display. 画面へ表示し続ける行数を示します。 - - - - - - - - - Filter &Help フィルタ &ヘルプ - - - - - - - - - Show information about using the filter. フィルタの使用に関する情報を表示します。 - - - - - - - - - Word &Wrap 単語 &重複 - - - - - - - - - Toggle word wrapping on/off. 単語の重複チェックのON / OFFを切り替えます。 - - - - - - - - - &Clear &消去 - - - - - - - - - Clear the output window of all text. すべてのテキストの出力ウィンドウを消去します。 - - - - - - - - - Enable &Filter 有効 &フィルタ - - - - - - - - - Turn the filter on/off. フィルタをON / OFFします。 @@ -3349,13 +2153,6 @@ To <b>remove a remembered entry</b> from the filter list, first cho DownloadDialog - - - - - - - Downloading: ダウンロード中: @@ -3501,25 +2298,11 @@ To <b>remove a remembered entry</b> from the filter list, first cho ExpoDialog - - - - - - - Flight modes フライトモード - - - - - - - Input name 入力名 @@ -3527,75 +2310,26 @@ To <b>remove a remembered entry</b> from the filter list, first cho - - - - - - - - - - - - - - - - - - - - - GV GV - - - - - - - Source for the mixer. ミキサー選択元. - - - - - - - Weight ウェイト - - - - - - - Switch スイッチ - - - - - - - Switch used to enable the line. If blank then the input is considered to be "ON" all the time. この設定を有効にするために使用されるスイッチです。 @@ -3603,169 +2337,71 @@ If blank then the input is considered to be "ON" all the time. - - - - - - - Stick Side スティック端 - - - - - - - NEG リバース - - - - - - - POS ノーマル - - - - - - - ALL すべて - - - - - - - Scale スケール - - - - - - - Include Trim トリム含 - - - - - - - No いいえ - - - - - - - Yes はい - - - - - - - Curve カーブ - - - - - - - Curve applied to the source. 選択元に適用されたカーブ. - - - - - - - Source 選択元 - - - - - - - Line name Expoライン名 - - - - - - - Offset オフセット - - - - - - - The source for the mixer ミキサー選択元 @@ -4159,252 +2795,275 @@ Blank means include all. ?, *, and [...] wildcards accepted. Firmware - + Channel values displayed in us 表示されるチャンネル値 - + No OverrideCH functions available 使用可能な上書きチャンネル機能はありません - + Possibility to enable FAI MODE (no telemetry) at field フィールドでFAIモード (テレメトリーなし) を有効にする可能性 - + FAI MODE (no telemetry) always enabled FAIモード (テレメトリーなし) を常に有効 - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 2015/01/01以降に販売された送信機に対し、EUでの使用に適さないD8 FrSkyプロトコルサポートを削除 - + Enable non certified firmwares 認定されていないファームウェアを有効にする - - + + Disable HELI menu and cyclic mix support HELIメニューとサイクリックミックスサポートを無効にする - - + + Disable Global variables グローバル変数を無効にする - - + + Enable Lua custom scripts screen Luaカスタムスクリプト画面を有効にする - + Use alternative SQT5 font SQT5 代替フォントを使用する - + Pots use in menus navigation メニューナビゲーションでダイヤルを使用 - + FrSky Taranis X9D+ FrSky Taranis X9D+ - + Support for PPM internal module hack PPM内部モジュールハックのサポート - + Disable RAS (SWR) RAS (SWR)を無効にする - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D FrSky Taranis X9D - + Haptic module installed タッチパネル対応モジュールをインストール - + FrSky Taranis X9E FrSky Taranis X9E - + Confirmation before radio shutdown 送信機シャットダウン前の確認 - + Horus gimbals installed (Hall sensors) Horusジンバル (ホールセンサー) をインストール - + FrSky Taranis X9-Lite FrSky Taranis X9-Lite - - + + + + + Support for auto update on boot 起動時の自動更新サポート - + + FrSky Taranis X9-Lite S + + + + FrSky Taranis X7 / X7S FrSky Taranis X7 / X7S - + FrSky Taranis X-Lite S/PRO FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite FrSky Taranis X-Lite - + FrSky Horus X10 / X10S FrSky Horus X10 / X10S - + + FrSky Horus X10 / X10S Express + + + + FrSky Horus X12S FrSky Horus X12S - + Use ONLY with first DEV pcb version 初期DEV pcbバージョンでのみ使用 - + + Jumper T16 / T16+ + + + + + Support for MULTI internal module + MULTI内部モジュールのサポート + + + + Support for bluetooth module + Bluetoothモジュールのサポート + + + Turnigy 9XR-PRO Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support HELIメニューとサイクリックミックスのサポートを有効にする - + Global variables グローバル変数 - + In model setup menus automatically set source by moving the control モデル設定メニューでは、コントローラーを動かし自動的に選択元を設定します - + In model setup menus automatically set switch by moving the control モデル設定メニューでは、コントローラーを動かし自動的にスイッチを設定します - + No graphical check boxes and sliders グラフィカルなチェックボックスとスライダーはありません - + Battery graph バッテリーグラフ - + Don't use bold font for highlighting active items 有効なアイテムを強調表示するために太字フォントを使用しない - - + + Support for ACCESS internal module replacement ACCESS内部モジュール変更のサポート - - FrSky Horus X10 Express - - - - + Jumper T12 - + Enable non certified R9M firmwares 非認定 R9Mファームウェアを有効 - + Turnigy 9XR with m128 chip Turnigy 9XR m128チップ搭載 - + Turnigy 9XR Turnigy 9XR - + 9X with stock board 9X ストックボード - + Enable resetting values by pressing up and down at the same time 上下に同時に押し、値のリセットを有効にする - + 9X with stock board and m128 chip 9X ストックボード+m128 chip - + 9X with AR9X board 9X AR9Xボード - + 9X with Sky9x board 9X Sky9Xボード - + 9X with Gruvin9x board 9X Gruvin9X - + DIY MEGA2560 radio DIY MEGA2560 送信機 @@ -4413,73 +3072,31 @@ Blank means include all. ?, *, and [...] wildcards accepted. FirmwarePreferencesDialog - - - - - - - Downloads ダウンロード - - - - - - - Check for updates アップデートのチェック - - - - - - - Firmware ファームウェア - - - - - - - Download firmware ダウンロード ファームウェア - - - - - - - Download SD contents ダウンロード SDカード - - - - - - - Latest Download 最新版のダウンロード @@ -4521,158 +3138,67 @@ Blank means include all. ?, *, and [...] wildcards accepted. FlashEEpromDialog - - - - - - - Write Models and Settings to Radio モデル・設定を書き込み - - - - - - - Load... ロード... - - - - - - - Current Profile 現在のプロファイル - - - - - - - Allows Companion to write to older version of the firmware Companionが古いバージョンのファームウェアでの書き込みを許可します - - - - - - - Check Firmware compatibility ファームウェアの互換性を確認 - - - - - - - <html><head/><body><p>Saves a dated copy of your eeprom to the backup folder you specified in the Companion settings before writing the current model to the radio.</p></body></html> <html><head/><body><p>現在のモデルを送信機に書き込む前に、EEPROM情報のコピー(日付)をCompanion設定指定したバックアップフォルダに保存します<p></body></html> - - - - - - - Backup before Write 書き込み前にバックアップを取る - - - - - - - <html><head/><body><p>Modify calibration parameters using settings from current profile</p></body></html> 現在のプロファイルの設定を使用して校正情報を修正します - - - - - - - Patch calibration setting from profile プロファイルからパッチ適用の有無を設定 - - - - - - - <html><head/><body><p>Modify HW parameters using settings from current profile</p></body></html> <html><head/><body><p>現在のプロファイルの設定を使用してハードウェアパラメータを変更します</p></body></html> - - - - - - - Patch HW settings from profile プロファイルからHWパラメータを変更 - - - - - - - Cancel キャンセル - - - - - - - Write to TX 書き込み @@ -4730,169 +3256,71 @@ Blank means include all. ?, *, and [...] wildcards accepted. FlashFirmwareDialog - - - - - - - Flash Firmware ファームウェアの書き込み - - - - - - - Load... ロード... - - - - - - - Date & Time 日付・時間 - - - - - - - Variant リビジョン - - - - - - - Version バージョン - - - - - - - Use profile start screen profile起動画面を使用 - - - - - - - Use firmware start screen firmware起動画面を使用 - - - - - - - Use library start screen library起動画面を使用 - - - - - - - Use another start screen 別の起動画面を使用 - - - - - - - Allows Companion to write to older version of the firmware Companionが古いバージョンのファームウェアを適用することを許可します - - - - - - - Check Hardware compatibility ハードウェア互換性を確認する - - - - - - - Backup and restore Models and Settings バックアップとモデル復元と設定 - - - - - - - Cancel キャンセル - - - - - - - Write to TX 書き込み @@ -5092,49 +3520,21 @@ You are currently using: FlightMode - - - - - - - Fade In フェードイン - - - - - - - Fade Out フェードアウト - - - - - - - Name 名称 - - - - - - - Switch スイッチ @@ -5324,25 +3724,11 @@ You are currently using: FusesDialog - - - - - - - Fuses フューズ - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5372,25 +3758,11 @@ p, li { white-space: pre-wrap; } - - - - - - - Read Fuses ヒューズの読み込み - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5424,13 +3796,6 @@ p, li { white-space: pre-wrap; } - - - - - - - Reset Fuses EEPROM - PROTECT リセット フューズ @@ -5438,13 +3803,6 @@ EEPROM - 保護 - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5478,13 +3836,6 @@ p, li { white-space: pre-wrap; } - - - - - - - Reset Fuses EEPROM - DELETE リセット フューズ @@ -5492,13 +3843,6 @@ EEPROM - 削除 - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5575,49 +3919,21 @@ p, li { white-space: pre-wrap; } GeneralEdit - - - - - - - Radio settings 送信機設定 - - - - - - - Retrieve calib. and hw settings from profile 校正情報を取得し、ProfileからHWを設定 - - - - - - - Store calib. and hw settings in selected profile 校正情報を保存し、選択したProfileのHWを設定 - - - - - - - General settings used throught the transmitter. These will be relevant for all models in the same EEPROM. 送信機全体で使用される一般設定。 @@ -5686,297 +4002,122 @@ These will be relevant for all models in the same EEPROM. GeneralSetup - - - - - - - Form フォーム - - - - - - - Readonly Unlock 読取専用 解除 - - - - - - - SC SC - - - - - - - SE SE - - - - - - - SA SA - - - - - - - SF SF - - - - - - - SH SH - - - - - - - SD SD - - - - - - - SB SB - - - - - - - SG SG - - - - - - - Stick reverse スティック リバース - - - - - - - Country Code 地域 - - - - - - - If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. FAIを有効にすると、RSSIとRxBtセンサーのみが機能し続けます。この機能を送信機側で無効にすることはできません。 - - - - - - - FAI Mode FAIモード - - - - - - - Automatically adjust the radio's clock if a GPS is connected to telemetry. GPSがテレメトリーに接続されている場合、自動的に送信機側の内蔵時計を調整します。 - - - - - - - Adjust RTC 時計調整 - - - - - - - Speaker Volume スピーカー音量 - - - - - - - - - - - - - - Hz Hz - - - - - - - Vario pitch at max バリオピッチ 最大 - - - - - - - Backlight Switch バックライトスイッチ - - - - - - - Color 1 カラー 1 - - - - - - - Color 2 カラー 2 - - - - - - - Sound Mode サウンドモード - - - - - - - If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds. この値が0以外の場合、キーを押すとバックライトが点灯し、指定秒数を経過すると消灯します。 @@ -5984,221 +4125,87 @@ These will be relevant for all models in the same EEPROM. - - - - - - - - - - - - - - - sec - - - - - - - Backlight color バックライトカラー - - - - - - - Speaker Pitch (spkr only) 再生ピッチ (対応機のみ) - - - - - - - Beeper ビープ - - - - - - - Speaker スピーカー - - - - - - - BeeperVoice ビープ音声 - - - - - - - SpeakerVoice スピーカー音声 - - - - - - - Beep volume ビープ音量 - - - - - - - Wav volume WAV音量 - - - - - - - Vario volume バリオVOL - - - - - - - Background volume バックグランドVOL - - - - - - - - - - - - - - ms ms - - - - - - - Backlight flash on alarm アラーム時ライト点滅 - - - - - - - Vario pitch at zero バリオピッチ ゼロ - - - - - - - Vario repeat at zero バリオリピート ゼロ - - - - - - - Backlight Auto OFF after バックライト 自動消灯 - - - - - - - This is the switch selectrion for turning on the backlight (if installed). @@ -6209,20 +4216,6 @@ These will be relevant for all models in the same EEPROM. - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -6238,97 +4231,41 @@ p, li { white-space: pre-wrap; } - - - - - - - RotEnc Navigation Rot Enc ナビゲーション - - - - - - - Backlight Brightness バックライト 明るさ - - - - - - - America アメリカ - - - - - - - Japan 日本 - - - - - - - Europe ヨーロッパ - - - - - - - Voice Language 音声言語 - - - - - - - Timeshift from UTC UTC 時差 - - - - - - - Backlight OFF Brightness バックライトOFF 明るさ @@ -6336,27 +4273,6 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -6382,25 +4298,11 @@ p, li { white-space: pre-wrap; } - - - - - - - RSSI Poweroff Warning RSSI 信号切断 警告 - - - - - - - Beeper volume 0 - Quiet. No beeps at all. @@ -6419,561 +4321,214 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - - - - - Quiet 消音 - - - - - - - Alarms Only アラームのみ - - - - - - - - - - - - - - No Keys キーなし - - - - - - - - - - - - - - All すべて - - - - - - - Beeper Mode ビープ モード - - - - - - - Jack Mode Jackモード - - - - - - - Audio 音声 - - - - - - - Trainer トレーナー - - - - - - - - - - - - - - X-Short より短い - - - - - - - - - - - - - - Short 短い - - - - - - - - - - - - - - Normal 通常 - - - - - - - - - - - - - - Long 長い - - - - - - - - - - - - - - X-Long より長い - - - - - - - Beeper Length ビープ音の長さ - - - - - - - Haptic Mode タッチパネルモード - - - - - - - Measurement Units 計量単位 - - - - - - - Play Delay (switch mid position) 遅延動作 (スイッチ中央) - - - - - - - NMEA - - - - - - - 4800 Baud - - - - - - - 9600 Baud - - - - - - - 14400 Baud - - - - - - - 19200 Baud - - - - - - - 38400 Baud - - - - - - - 57600 Baud - - - - - - - 76800 Baud - - - - - - - 115200 Baud - - - - - - - - - - - - - - Show splash screen on startup 起動時、起動イメージ表示 - - - - Power On Delay 起動時間 - - - - - - - --- --- - - - - - - - 2s 2秒 - - - - - - - 3s 3秒 - - - - - - - 4s 4秒 - - - - - - - 6s 6秒 - - - - - - - 8s 8秒 - - - - - - - 10s 10秒 - - - - - - - 15s 15秒 - - - - - - - If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. 指定された時間(分)入力がないまま送信機が放置されると、ゼロでない場合はビープ音が鳴ります。 - - - - - - - min - - - - - - - Standard 標準 - - - - - - - Optrex オプトレックス(京セラ) - - - - - - - Battery warning voltage. This is the threashhold where the battery warning sounds. @@ -6984,588 +4539,247 @@ Acceptable values are 5v..10v - - - - - - - Only Alarms アラームのみ - - - - - - - MAVLink Baud Rate MAVLink ボーレート - - - - - - - Haptic Length タッチパネル長押し - - - - - - - Battery Warning バッテリー警告 - - - - - - - "No Sound" Warning 【無音】警告 - - - - - - - LCD Display Type 液晶ディスプレイタイプ - - - - - - - Haptic Strength タッチパネル感度 - - - - - - - Battery Meter Range バッテリーメーター範囲 - - - - - - - Contrast コントラスト - - - - - - - Show Splash Screen on Startup 起動時、起動イメージ表示 - - - - - - - Low EEPROM Warning EEPROM残量警告 - - - - - - - Inactivity Timer 非アクティブタイマー - - - - - - - Min 最小 - - - - - - - - - - - - - - v v - - - - - - - Max 最大 - - - - - - - GPS Coordinates GPS座標 - - - - - - - Default Channel Order 初期チャンネルマップ - - - - - - - Metric メートル法 - - - - - - - Imperial ヤード・ポンド法 - - - - - - - Stick Mode スティックモード - - - - - - - <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>チャンネルマップ</p><p><br/></p><p>モデル作成された際の初期チャンネルマッピングを定義します</p></body></html> - - - - Owner Registration ID オーナー登録ID - - - - aaaaaaAA - - - - - - - R E T A - ↔RUD ↕ELE ↕THR ↔AIL [R E T A] + ↔RUD ↕ELE ↕THR ↔AIL [R E T A] - - - - - - - R E A T - ↔RUD ↕ELE ↔AIL ↕THR [R E A T] + ↔RUD ↕ELE ↔AIL ↕THR [R E A T] - - - - - - - R T E A - ↔RUD ↕THR ↕ELE ↔AIL [R T E A] + ↔RUD ↕THR ↕ELE ↔AIL [R T E A] - - - - - - - R T A E - ↔RUD ↕THR ↔AIL ↕ELE [R T A E] + ↔RUD ↕THR ↔AIL ↕ELE [R T A E] - - - - - - - R A E T - ↔RUD ↔AIL ↕ELE ↕THR [R A E T] + ↔RUD ↔AIL ↕ELE ↕THR [R A E T] - - - - - - - R A T E - ↔RUD ↔AIL ↕THR ↕ELE [R A T E] + ↔RUD ↔AIL ↕THR ↕ELE [R A T E] - - - - - - - E R T A - ↕ELE ↔RUD ↕THR ↔AIL [E R T A] + ↕ELE ↔RUD ↕THR ↔AIL [E R T A] - - - - - - - E R A T - ↕ELE ↔RUD ↔AIL ↕THR [E R A T] + ↕ELE ↔RUD ↔AIL ↕THR [E R A T] - - - - - - - E T R A - ↕ELE ↕THR ↔RUD ↔AIL [E T R A] + ↕ELE ↕THR ↔RUD ↔AIL [E T R A] - - - - - - - E T A R - ↕ELE ↕THR ↔AIL ↔RUD [E T A R] + ↕ELE ↕THR ↔AIL ↔RUD [E T A R] - - - - - - - E A R T - ↕ELE ↔AIL ↔RUD ↕THR [E A R T] + ↕ELE ↔AIL ↔RUD ↕THR [E A R T] - - - - - - - E A T R - ↕ELE ↔AIL ↕THR ↔RUD [E A T R] + ↕ELE ↔AIL ↕THR ↔RUD [E A T R] - - - - - - - T R E A - ↕THR ↔RUD ↕ELE ↔AIL [T R E A] + ↕THR ↔RUD ↕ELE ↔AIL [T R E A] - - - - - - - T R A E - ↕THR ↔RUD ↔AIL ↕ELE [T R A E] + ↕THR ↔RUD ↔AIL ↕ELE [T R A E] - - - - - - - T E R A - ↕THR ↕ELE ↔RUD ↔AIL [T E R A] + ↕THR ↕ELE ↔RUD ↔AIL [T E R A] - - - - - - - T E A R - ↕THR ↕ELE ↔AIL ↔RUD [T E A R] + ↕THR ↕ELE ↔AIL ↔RUD [T E A R] - - - - - - - T A R E - ↕THR ↔AIL ↔RUD ↕ELE [T A R E] + ↕THR ↔AIL ↔RUD ↕ELE [T A R E] - - - - - - - T A E R - ↕THR ↔AIL ↕ELE ↔RUD [T A E R] + ↕THR ↔AIL ↕ELE ↔RUD [T A E R] - - - - - - - A R E T - ↔AIL ↔RUD ↕ELE ↕THR [A R E T] + ↔AIL ↔RUD ↕ELE ↕THR [A R E T] - - - - - - - A R T E - ↔AIL ↔RUD ↕THR ↕ELE [A R T E] + ↔AIL ↔RUD ↕THR ↕ELE [A R T E] - - - - - - - A E R T - ↔AIL ↕ELE ↔RUD ↕THR [A E R T] + ↔AIL ↕ELE ↔RUD ↕THR [A E R T] - - - - - - - A E T R - ↔AIL ↕ELE ↕THR ↔RUD [A E T R] + ↔AIL ↕ELE ↕THR ↔RUD [A E T R] - - - - - - - A T R E - ↔AIL ↕THR ↔RUD ↕ELE [A T R E] + ↔AIL ↕THR ↔RUD ↕ELE [A T R E] - - - - - - - A T E R - ↔AIL ↕THR ↕ELE ↔RUD [A T E R] + ↔AIL ↕THR ↕ELE ↔RUD [A T E R] - - - - Power Off Delay 終了時間 - - - - - - - Mode selection: Mode 1: @@ -7607,142 +4821,55 @@ Mode 4: - - - - - - - Mode 1 (RUD ELE THR AIL) - モード1 (左:エレベーター・ラダー 右:スロットル・エルロン) + モード1 (左:エレベーター・ラダー 右:スロットル・エルロン) - - - - - - - Mode 2 (RUD THR ELE AIL) - モード2 (左:スロットル・ラダー 右:エレベーター・エルロン) + モード2 (左:スロットル・ラダー 右:エレベーター・エルロン) - - - - - - - Mode 3 (AIL ELE THR RUD) - モード3 (左:エレベーター・エルロン 右:スロットル・ラダー) + モード3 (左:エレベーター・エルロン 右:スロットル・ラダー) - - - - - - - Mode 4 (AIL THR ELE RUD) - モード4 (左:スロットル・エルロン 右:エレベーター・ラダー) + モード4 (左:スロットル・エルロン 右:エレベーター・ラダー) - - - - - - - DMS - - - - - - - USB Mode USBモード - - - - - - - - - - - - - - Ask on Connect 接続毎に確認 - - - - - - - Joystick (HID) ジョイスティック (HID) - - - - - - - USB Mass Storage USBストレージ - - - - - - - USB Serial (CDC) USBシリアル (CDC) - - - Power On Speed - - - - - Power Off Speed - - GeneralSetupPanel @@ -7898,595 +5025,256 @@ Are you sure ? Hardware - - - - - - - Form フォーム - - - - - - - - + SQ SQ - - - - - - - SR SR - - - - - - - LS2 LS2 - - - - - - - - + SP SP - - - - - - - SO SO - - - - - - - S4 S4 - - - - - - - RS RS - - - - - - - - + SB SB - - - - - - - PPM 2 PPM 2 - - - - + Antenna アンテナ - - - - - - + S5 S5 - - - - - - - - + OFF OFF - - - - - - - - + S-Port Mirror S-Port ミラー - - - - - - - - + Telemetry テレメトリー - - - - - - - - + SBUS Trainer SBUS トレーナー - - - - - - - - + Debug デバッグ + + + RTC Batt Check + RTC Battチェック + - - - - - - - Rud ラダー - - - - - - - PPM 3 PPM 3 - - - - - - - - + S1 S1 - - - - - - - - + S2 S2 - - - - - - - - + S3 S3 - - - - - - - PPM 1 PPM 1 - - - - - - - - + Serial Port シリアルポート - - - - - - - - + v v - - - - - - - PPM Multiplier PPM 乗算 - - - - - - - Current Offset 現在のオフセット - - - - - - - PPM 4 PPM 4 - - - - - - - - + SA SA - - - - - - - Ele エレベーター - - - - - - - Ail エルロン - - - - - - - Thr スロットル - - - - - - - SC SC - - - - - - - - + LS LS - - - - - - - SD SD - - - - - - - - + Battery Offset バッテリーオフセット - - - - - - - SE SE - - - - - - - - + SF SF - - - - - - - - + SG SG - - - - - - - SH SH - - - - - - - - + SI SI - - - - - - - - + SJ SJ - - - - - - - SK SK - - - - - - - - + SL SL - - - - - - - SM SM - - - - - - - SN SN - - - - - - - - + RS2 RS2 - - - - - - - Bluetooth Bluetooth - - - - - - - ADC Filter ADCフィルタ - - - - - - - Device Name: デバイス名: @@ -8585,169 +5373,71 @@ Are you sure ? Heli - - - - - - - Off OFF - - - - - - - 120 120 - - - - - - - 120X 120X - - - - - - - 140 140 - - - - - - - 90 90 - - - - - - - Invert Elevator ELE リバース - - - - - - - Invert Aileron AIL リバース - - - - - - - Invert Collective COL リバース - - - - - - - Long. cyc 長周期 - - - - - - - Invert リバース - - - - - - - Swash Ring Swashリング - - - - - - - Swash Type Swashタイプ - - - - - - - Lateral cyc 側面周期 - - - - - - - Collective コレクティブ @@ -9140,109 +5830,46 @@ Are you sure ? LogsDialog - - - - - - - Companion Log Viewer Companion ログビューワ - - - - - - - Fly sessions 飛行時間 - - - - - - - Save session CSV CSVで保存 - - - - - - - Zoom 拡大 - - - - - - - X X軸 - - - - - - - Y Y軸 - - - - - - - Reset リセット - - - - - - - Filename ファイル名 - - - - - - - Open LogFile ログファイルを開く @@ -10655,71 +7282,71 @@ Do you want to save your changes? 変更を保存しますか? - + <p><b>Currently selected radio type (%1) is not compatible with file %3 (from %2), models and settings need to be converted.</b></p> <p><b>現在選択されている送信機タイプ (%1) はファイル %3 (from %2) と互換性がありません。機体モデルと設定を変換する必要があります。</b></p> - + Do you wish to continue with the conversion? 変換を続けますか? - + Choose <i>Apply</i> to convert the file, or <i>Close</i> to close it without conversion. ファイルを変換するには<i>適用</i>を、変換せずに閉じるには<i>閉じる</i>を選択します。 - + <b>The conversion generated some important messages, please review them below.</b> <b>変換によっていくつかの重要なメッセージが出力されました。下記の内容を確認してください。</b> - + Companion :: Conversion Result for %1 Companion :: %1 の変換結果 - + Unable to find Horus radio SD card! Horus送信機のSDカードが見つかりません! - + Models and Settings written 機体モデルと設定が書かれました - + Cannot write temporary file! 一時ファイルを書き込めません! - + Open backup Models and Settings file バックアップ機体モデルと設定ファイルを開く - + Unable to find file %1! ファイル %1 が見つかりません! - + Error opening file %1: %2. ファイル %1 を開くときにエラーが発生しました: %2. - + Error reading file %1: %2. ファイル %1 の読み取りエラーです: %2. - + Invalid binary backup File %1 無効なバイナリバックアップファイルです %1 @@ -10741,59 +7368,26 @@ Do you want to save your changes? MixerDialog - - - - - Dialog ダイアログ - - - - - - - Delay Delay: 遅延 - - - - - - - Slow Slow: ゆっくり - - - - - - - Up - - - - - - - Down @@ -10802,34 +7396,6 @@ Do you want to save your changes? - - - - - - - - - - - - - - - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -10855,145 +7421,61 @@ p, li { white-space: pre-wrap; } - - - - - - - Include Trim トリム含 - - - - - - - Offset オフセット - - - - - - - Weight ウェイト - - - - - - - Name 名称 - - - - - - - Source 選択元 - - - - - - - Multiplex 複数ミキサー - - - - - - - Warning 警告 - - - - - - - The curve used by the mix ミックスで使用するカーブ - - - - - - - Include DR/Expo DR/Expo含 - - - - - - - Flight modes フライトモード - - - - - - - Switch スイッチ - - - - - - - Mixer warning. Setting this value will cause a beep to be emmitted when this value is active. ミキサー警告 @@ -11001,73 +7483,31 @@ Setting this value will cause a beep to be emmitted when this value is active. - - - - - - - OFF - - - - - - - 1 Beep 1 ビープ - - - - - - - 2 Beep 2 ビープ - - - - - - - 3 Beep 3 ビープ - - - - - - - No いいえ - - - - - - - Yes はい @@ -11075,27 +7515,6 @@ Setting this value will cause a beep to be emmitted when this value is active. - - - - - - - - - - - - - - - - - - - - - GV @@ -11104,46 +7523,11 @@ Setting this value will cause a beep to be emmitted when this value is active. - - - - - - - - - - - - - - - - - - - - - - - - - - - - The source for the mixer ミキサー選択元 - - - - - - - Multiplexer This determines how mixer values are added. @@ -11161,61 +7545,26 @@ This determines how mixer values are added. - - - - - - - ADD 加算 - - - - - - - MULTIPLY 乗算 - - - - - - - REPLACE 置換 - - - - - - - Curve カーブ - - - - - - - Switch used by the mix. If blank then the mix is considered to be "ON" all the time. ミックスで使用されるスイッチ @@ -11246,12 +7595,6 @@ If blank then the mix is considered to be "ON" all the time. Invert All すべてリバース - - - - FullScreenDialog - - MixersListWidget @@ -11425,23 +7768,11 @@ If blank then the mix is considered to be "ON" all the time. ModelEdit - - - - - Dialog ダイアログ - - - - - - - Simulate シミュレート @@ -11495,12 +7826,6 @@ If blank then the mix is considered to be "ON" all the time. Telemetry テレメトリー - - - - FullScreenDialog - - ModelPrinter @@ -12319,94 +8644,41 @@ If blank then the mix is considered to be "ON" all the time. Module - - - - - - - Start スタート - - - - - - - CH - - - - - - - Receiver No. 受信機 No. - - - - - - - Polarity 極性 - - - - - - - Negative リバース - - - - - - - Positive ノーマル - - - - - - - RF Output Power 送信出力 - - - - Receiver 1 受信機 1 @@ -12414,545 +8686,274 @@ If blank then the mix is considered to be "ON" all the time. - - - - - - - - - - - - X X - - - - Receiver 2 受信機 2 - - - - Receiver 3 受信機 3 - - - - - - - Bind on startup 起動時バインド - - - - - - - Low Power 低パワー - - - - - - - WARNING: changing RF Output Power needs RE-BIND 警告: 送信出力を変更するには再バインドが必要です - - - - - - - Channels チャンネル - - - - - - - PPM delay PPM 遅延 - - - - - - - us - - - - - - - PPM Frame Length PPM フレーム長 - - - - - - - ms ms - - - - - - - Antenna アンテナ - - - - - - - Output type 出力タイプ - - - - - - - Open Drain オープン ドレン - - - - - - - Push Pull プッシュ プル - - - - - - - Option value オプション値 - - - - - - - Protocol プロトコル - - - - Registration ID 登録ID - - - - - - - Multi Radio Protocol マルチプロトコル - - - - - - - Sub Type サブタイプ - - - - - - - Failsafe Mode フェイルセーフモード - - - - - - - Not set 設定なし - - - - - - - Hold ホールド - - - - - - - Custom カスタム - - - - - - - No Pulses パルスなし - - - - - - - Receiver 受信機 - - - - - - - Trainer Mode トレーナーモード - - - - - - - Master/Jack マスター/Jack - - - - - - - Slave/Jack スレーブ/Jack - - - - - - - Master/SBUS Module マスター/SBUSモジュール - - - - - - - Master/CPPM Module マスター/CPPMモジュール - - - - - - - Master/SBUS in battery compartment マスター/バッテリーカバー内SBUB - - - - - - - WARNING: Requires non-certified firmware! 警告: 未認定のR9Mファームウェアが必要です! - - - - - - - Failsafe Positions フェイルセーフポジション - - - - - - - Show values in: 値の表示: - - - - - - - % abbreviation for percent - - - - - - - μs abbreviation for microseconds - - - - - - Internal - 内部 - - - - - - - Ext. + Int. - - ModuleData - + Trainer Port トレーナーポート - + Internal Radio System 内部送信システム - + External Radio Module 外部送信モジュール - + Extra Radio System 追加送信システム - + Radio System 送信システム - + 10mW - 16CH - - + + 100mW - 16CH - + 500mW - 16CH - + Auto <= 1W - 16CH - - + + 25mW - 8CH - - + + 25mW - 16CH - + 200mW - 16CH (no telemetry) 200mW - 16CH (テレメトリーなし) - + 500mW - 16CH (no telemetry) 500mW - 16CH (テレメトリーなし) - + 100mW - 16CH (no telemetry) 100mW - 16CH (テレメトリーなし) - + Positive ノーマル - + Negative リバース @@ -12960,37 +8961,37 @@ If blank then the mix is considered to be "ON" all the time. ModulePanel - + Value - + Hold ホールド - + No Pulse パルスなし - + Ask 確認 - + Internal 内部 - + Internal + External 内部 + 外部 - + External 外部 @@ -13492,7 +9493,7 @@ If blank then the mix is considered to be "ON" all the time. 初期値 - + Custom - proto %1) カスタム - プロトコル%1) @@ -13523,22 +9524,22 @@ If blank then the mix is considered to be "ON" all the time. OpenTxEepromInterface - + Unknown error 不明のエラー - + ... plus %1 errors ...追加 %1 エラー - + Cannot write radio settings 送信機設定を書き込めません - + Cannot write model %1 機体モデル %1 を書き込めません @@ -13609,49 +9610,21 @@ If blank then the mix is considered to be "ON" all the time. PrintDialog - - - - - - - Close 閉じる - - - - - - - Style スタイル - - - - - - - Print 出力 - - - - - - - Print to file ファイルへ出力 @@ -13675,25 +9648,11 @@ If blank then the mix is considered to be "ON" all the time. ProgressDialog - - - - - - - Flash Firmware ファームウェアの書き込み - - - - - - - Close 閉じる @@ -13708,17 +9667,23 @@ If blank then the mix is considered to be "ON" all the time. ProgressWidget - - - - - - - Show Details 詳細を表示 + + QObject + + + WARNING + 警告 + + + + <p>Importing JumperTX data into OpenTX 2.3 is <b>not supported and dangerous.</b></p> <p>It is unfortunately not possible for us to differentiate JumperTX data from legitimate FrSky X10 data, but <b>You should only continue here if the file you opened comes from a real FrSky X10.</b></p> <p>Do you really want to continue?</p> + <p>JumperTXデータをOpenTX 2.3にインポートすることは<b>サポート対象外となり危険な行為です。</b></p> <p>残念ながら、JumperTXデータを正当なFrSky X10データと区別することができませんが、<b>開いたファイルが実際のFrSky X10で生成されたものである場合にのみ、続行する事ができます。</b></p> <p>本当に続行しますか?</p> + + RadioData @@ -13868,38 +9833,17 @@ If blank then the mix is considered to be "ON" all the time. RadioNotFoundDialog - - - - - - - No Radio Found 送信機が見つかりません - - - - - - - <html><head/><body><p>No Radio was found!</p><p>Make sure that you hold the lower trim buttons towards the center while you turn it on.</p><p>Then connect the USB wire.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Note: if you have a Taranis that has not had the firmware upgraded to 2.0 then this version of Companion will not work.</span></p></body></html> <html><head/><body><p>送信機が見つかりませんでした!</p><p>電源を入れるときは、下部トリムボタンを中央に押し上げてください。</p><p>次に、USBケーブルを接続します。</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">注: ファームウェアが2.0にアップグレードされていないTaranisを使用している場合、このバージョンのCompanionは動作しません。</span></p></body></html> - - - - - - - OK OK @@ -13908,99 +9852,36 @@ If blank then the mix is considered to be "ON" all the time. RadioOutputsWidget - - - - - - - - - Form フォーム - - - - - - - - - View: ビュー: - - - - - - - - - Logical Switches 論理スイッチ - - - - - - - - - Global Variables グローバル変数 - - - - - - - - - Channel Outputs チャンネルオプション - - - - - - - - - Mix Outputs ミキサー出力 - - - - - - - - - L o g @@ -14013,15 +9894,6 @@ W - - - - - - - - - G l o @@ -14034,15 +9906,6 @@ l - - - - - - - - - C h a @@ -14058,15 +9921,6 @@ H - - - - - - - - - M i x @@ -14081,12 +9935,12 @@ X FM%1 - + FM%1 GV%1 - GV%1 + GV%1 @@ -14678,7 +10532,7 @@ X - + ??? @@ -14688,17 +10542,22 @@ X - + + Act + Act + + + ---- - + Telemetry テレメトリー - + SW @@ -14895,304 +10754,126 @@ X TELE - - - Internal - 内部 - - - - External - 外部 - Setup - - - - - - - Timer 1 タイマー 1 - - - - - - - Top LCD Timer 液晶タイマー - - - - - - - Model Image モデルイメージ - - - - - - - Warnings 警告 - - - - - - - Switch Warnings スイッチ警告 - - - - - - - Pot Warnings ダイヤル警告 - - - - - - - OFF OFF - - - - - - - Manual 手動 - - - - - - - Auto 自動 - - - - - - - Model 機体モデル - - - - - - - Center beep センター ビープ - - - - - - - Display Checklist チェックリスト表示 - - - - - - - Never なし - - - - - - - On change 変更 - - - - - - - Always 常に - - - - - - - Throttle Trim Idle Only THRトリムアイドル - - - - - - - Global Functions グローバルファンクション - - - - - - - Throttle Warning スロットル警告 - - - - - - - Exponential エクスポ - - - - - - - Extra Fine 極細 - - - - - - - Fine 細かめ - - - - - - - Medium 中間 - - - - - - - Coarse 粗め - - - - - - - Reverse throttle operation. If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. @@ -15202,109 +10883,46 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi - - - - - - - Reverse Throttle スロットル リバース - - - - - - - Edit Checklist... チェックリストの編集... - - - - - - - Extended Trims 拡張トリム - - - - - - - Extended Limits 拡張制限 - - - - - - - Throttle Source スロットル値 - - - - - - - Trim Step トリム間隔 - - - - - - - Trims Display トリム表示 - - - - - - - Timer 2 タイマー 2 - - - - - - - Timer 3 タイマー 3 @@ -15312,22 +10930,22 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi SetupPanel - + Timer %1 タイマー %1 - + THR - + Profile Settings プロファイル設定 - + SD structure path not specified or invalid SDカード保存先パスが指定されていないか無効です @@ -15677,421 +11295,151 @@ Profile ID: [%1]; Radio ID: [%2] SimulatorMainWindow - - - - - - - - - OpenTx Simulator OpenTX シミュレータ - - - - - - - - - View ビュー - - - - - - - - - Radio Window 送信機ウィンドウ - - - - - - - - - Reload... 再読み込み... - - - - - - - - - Tools ツール - - - - - - - - - Toolbar ツールバー - - - - - - - - - Reload Lua Scripts Luaスクリプトを再読み込み - - - - - - - - - Reload the Lua environment on the simulated radio. 送信機シミュレータでLua環境を再読み込みします。 - - - - - - - - - F7 - - - - - - - - - Reload Radio Data 送信機データを再読み込み - - - - - - - - - Reload all radio data without restarting the simulator. シミュレータを再起動せずにすべての送信機データを再読み込みします。 - - - - - - - - - F9 - - - - - - - - - Key Mapping キーマッピング - - - - - - - - - Show keyboard maping reference. 参照するキーマッピングを表示します。 - - - - - - - - - F1 - - - - - - - - - Joystick Settings スティック設定 - - - - - - - - - Open joystick configuration settings dialog. スティック設定ダイアログを開きます。 - - - - - - - - - F3 - - - - - - - - - LCD Screenshot 液晶 画面キャプチャ - - - - - - - - - Save a screenshot of the current simulated LCD screen. 現在シミュレートされている液晶画面のキャプチャを保存します。 - - - - - - - - - F8 - - - - - - - - - Dock In Main Window メインウィンドウに結合 - - - - - - - - - Show the radio in the main window or as a separate "floating" window. メインウィンドウまたは別の『フローティング』ウィンドウとして送信機を表示します。 - - - - - - - - - Menu Bar メニューバー - - - - - - - - - Show or hide the top menu bar. トップメニューバーを表示または非表示にします。 - - - - - - - - - Alt+M - - - - - - - - - Constrain Width 幅の制限 - - - - - - - - - Set radio widget width to be a fixed size. 送信機ウィジェットの幅を固定サイズに設定します。 - - - - - - - - - Constrain Height 高さ制限 - - - - - - - - - Set radio widget height to be a fixed size. 送信機ウィジェットの高さを固定サイズに設定します。 @@ -16174,57 +11522,21 @@ Profile ID: [%1]; Radio ID: [%2] SimulatorStartupDialog - - - - - - - - - OpenTX Simulator - Startup Options OpenTX シミュレータ - スタートアップオプション - - - - - - - - - Simulator Startup Options: シミュレータ スタートアップオプション: - - - - - - - - - Radio Profile: 送信機プロファイル: - - - - - - - - - Existing radio profiles are shown here.<br /> Create or edit profiles using the Companion application. 既存の送信機プロファイルはこちらに表示されます。<br /> @@ -16232,29 +11544,11 @@ Companionアプリケーションを使用してプロファイルを作成ま - - - - - - - - - Radio Type: 送信機タイプ: - - - - - - - - - Existing radio simulators are shown here.<br /> The radio type specified in the selected profile is used by default. 既存の送信機シミュレータをここに示します。<br /> @@ -16262,71 +11556,26 @@ The radio type specified in the selected profile is used by default. - - - - - - - - - Data Source: データ元: - - - - - - - - - Data File: データファイル: - - - - - - - - - Data Folder: データフォルダ: - - - - - - - - - SD Image Path: SDイメージパス: - - - - - - - - - Radio data (.bin/.eeprom/.otx) image file to use. A new file with a default image will be created if necessary.<br /> <b>NOTE</b>: any existing EEPROM data incompatible with the selected radio type may be overwritten! 使用する送信機データ(.bin / .eeprom / .otx)画像ファイルです。必要に応じて、デフォルト画像を含む新しいファイルが作成されます。<br /> @@ -16334,15 +11583,6 @@ The radio type specified in the selected profile is used by default. - - - - - - - - - Select data file... データファイル選択... @@ -16350,47 +11590,11 @@ The radio type specified in the selected profile is used by default. - - - - - - - - - - - - - - - - - - - - - - - - - - - ... ... - - - - - - - - - Directory containing RADIO and MODELS folders to use.<br /> New folder(s) with default radio/model will be created here if necessary. 使用する送信機および機体モデルフォルダを含むディレクトリです。<br /> @@ -16398,29 +11602,11 @@ New folder(s) with default radio/model will be created here if necessary. - - - - - - - - - Select data folder... データフォルダ選択... - - - - - - - - - Directory containing the SD card image to use.<br/> The default is configured in the chosen Radio Profile. 使用するSDカードイメージを含むディレクトリです。<br/> @@ -16428,71 +11614,26 @@ The default is configured in the chosen Radio Profile. - - - - - - - - - Select SD card image folder... SDカードイメージフォルダ選択... - - - - - - - - - Select which of the data sources (File/Folder/SD Card) you would like to start the simulator with. シミュレータを起動するデータ元 (ファイル/フォルダ/ SDカード) を選択します。 - - - - - - - - - File ファイル - - - - - - - - - Folder フォルダ - - - - - - - - - SD Path SDパス @@ -16521,15 +11662,6 @@ The default is configured in the chosen Radio Profile. SimulatorWidget - - - - - - - - - Companion Simulator Companion シミュレータ @@ -16539,62 +11671,62 @@ The default is configured in the chosen Radio Profile. 送信機シミュレータ (%1) - + Could not determine startup data source. 起動データ元を特定できませんでした。 - + Could not load data, possibly wrong format. データをロードできません、フォーマットが間違っている可能性があります。 - + Data Load Error データロード エラー - + Invalid startup data provided. Plese specify a proper file/path. 無効なスタートアップデータが提供されました。正しいファイル/パスを指定してください。 - + Simulator Startup Error シミュレータ スタートアップ エラー - + Error saving data: could open file for writing: '%1' データ保存エラー: 書き込み用にファイルを開くことができました: 「%1」 - + Error saving data: could not get data from simulator interface. データ保存エラー: シミュレータのインターフェイスからデータを取得できませんでした。 - + An unexpected error occurred while attempting to save radio data to file '%1'. 送信機データをファイル「%1」に保存しようとしたときに予期せぬエラーが発生しました。 - + Data Save Error データ保存 エラー - + Cannot open joystick, joystick disabled スティックが接続不可、もしくはスティックが無効です - + Radio firmware error: %1 送信機 ファームウェア エラー: %1 - + - Flight Mode %1 (#%2) - フライトモード %1 (#%2) @@ -16617,20 +11749,6 @@ The default is configured in the chosen Radio Profile. - - - - - - - - - - - - - - ... ... @@ -16670,13 +11788,6 @@ The default is configured in the chosen Radio Profile. StyleEditDialog - - - - - - - @@ -16685,49 +11796,21 @@ The default is configured in the chosen Radio Profile. - - - - - - - &Reset to default &初期値へリセット - - - - - - - &Cancel &キャンセル - - - - - - - &OK &OK - - - - - - - This feature does not validate your changes and assumes you are familiar with CSS syntax for QT. この機能は変更を検証するものではなく、QTのCSS構文に精通していることを前提としています。 @@ -16991,475 +12074,190 @@ Too many errors, giving up. Telemetry - - - - - - - Protocol プロトコル - - - - - - - - - - - - - - ---- - - - - - - - - - - - - - - Yellow 黄色 - - - - - - - - - - - - - - Orange オレンジ - - - - - - - - - - - - - - Red 赤色 - - - - - - - Alarm 1 アラーム 1 - - - - - - - Alarm 2 アラーム 2 - - - - - - - RSSI RSSI - - - - - - - Disable telemetry audio warnings テレメトリー音声警告を無効 - - - - - Source 信号元 - - - - - - - A1 - - - - - - - A2 - - - - - - - Sink Max Sink 最大 - - - - - - - Climb Max クライム 最大 - - - - - - - Sink Min Sink 最小 - - - - - - - Climb Min クライム 最小 - - - - - - - Center Silent センター サイレント - - - - - - - Vario limits バリオ リミット値 - - - - - - - Vario source バリオ 元値 - - - - - - - Altimetry 高度計 - - - - - - - Altitude source 高度 元値 - - - - - - - Volts source ボルト 元値 - - - - - - - Top Bar トップバー - - - - - - - Volt source ボルト 元値 - - - - - - - Current source 現在の元値 - - - - - - - Blades ブレード - - - - - - - mAh count mAh カウント - - - - - - - mAh - - - - - - - A - - - - - - - FAS Offset FAS オフセット - - - - - - - Persistent mAh 持続 mAh - - - - - - - Various その他の設定 - - - - - - - Serial Protocol シリアルプロトコル - - - - - - - None なし - - - - - - - FrSky Sensor Hub FrSky センサーハブ - - - - - - - Sensors センサー - - - - - - - Disable multi sensor handling マルチセンサーハンドリング無効 @@ -17468,289 +12266,107 @@ Too many errors, giving up. TelemetryAnalog - - - - - - - Unit ユニット - - - - - - - Max Value 最大値 - - - - - - - Alarm 1 アラーム 1 - - - - - - - - - - - - - - ---- - - - - - - - - - - - - - - Yellow 黄色 - - - - - - - - - - - - - - Orange オレンジ - - - - - - - - - - - - - - Red 赤色 - - - - - - - - - - - - - - < - - - - - - - - - - - - - - > - - - - - - - Alarm 2 アラーム 2 - - - - - - - Offset オフセット - - - - - - - Volts (V) ボルト (V) - - - - - - - Amps (A) アンペア (A) - - - - - - - Speed (m/s or ft/s) 速度 (m/s or ft/s) - - - - - - - Raw (-) - - - - - - - Speed (km/h or miles/h) 速度 (km/h or miles/h) - - - - - - - Meters (m or ft) メートル (m or ft) - - - - - - - Temp (°) 温度 (°) - - - - - - - Fuel (%) 燃料 (%) - - - - - - - mAmps (mA) ミリアンペア (mA) @@ -17764,61 +12380,26 @@ Too many errors, giving up. TelemetryCustomScreen - - - - - - - Custom Screen Type カスタム画面タイプ - - - - - - - Min 最小 - - - - - - - Source 選択元 - - - - - - - Gauge ゲージ - - - - - - - Max 最大 @@ -17846,104 +12427,104 @@ Too many errors, giving up. TelemetryPanel - + Telemetry screen %1 テレメトリースクリーン %1 - + FrSky S.PORT - + FrSky D - + FrSky D (cable) - + Source 信号元 - + Low Alarm 低アラーム - + Critical Alarm クリティカルアラーム - + Winged Shadow How High Winged Shadow How High - + Winged Shadow How High (not supported) Winged Shadow How High (サポートなし) - + Alti - + Alti+ - + VSpeed - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells セル - + --- --- @@ -17952,711 +12533,278 @@ Too many errors, giving up. TelemetrySensor - - - - - - - Form フォーム - - - - - - - Custom カスタム - - - - - - - Calculated 計算値 - - - - - - - Id ID - - - - - - - Instance インスタンス - - - - Rx 受信 - - - - - - Mod. - モジュール. - - - - - - - - - - + Add 追加 - - - - - - - - + Average 平均 - - - - - - - - + Min 最小 - - - - - - - - + Max 最大 - - - - - - - - + Multiply 乗算 - - - - - - - - + Totalize 合計 - - - - - - - - + Cell セル - - - - - - - - + Consumption 消費 - - - - - - - - + Dist 距離 - - - - - - - - + Cells Sensor : セル センサー : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + --- --- - - - - - - - - + GPS Sensor : GPS センサー : - - - - - - - - + Alt. Sensor : 高度 センサー : - - - - - - - - + Sensor : センサー : - - - - - - - - + Raw (-) Raw (-) - - - - - - - - + V V - - - - - - - - + A - - - - - - - - + mA - - - - - - - - + kt - - - - - - - - + m/s - - - - - - - - + ft/s - - - - - - - - + km/h - - - - - - - - + mph - - - - - - - - + m - - - - - - - - + ft - - - - - - - - + °C - - - - - - - - + °F - - - - - - - - + % - - - - - - - - + mAh - - - - - - - - + W - - - - - - - - + mW - - - - - - - - + dBm - - - - - - - - + RPM - - - - - - - - + g - - - - - - - - + ° - - - - - - - - + Rad - - - - - - - - + mL - - - - - - - - + US fl.Oz. - - - - - - - - + Precision 精度 - - - - - - - - + Ratio レシオ - - - - - - - - + Blades ブレード - - - - - - - - + Offset オフセット - - - - - - - - + Multiplier 乗算 - - - - - - - - + Auto Offset 自動オフセット - - - - - - - - + Filter フィルタ - - - - - - - - + Persistent 持続 - - - - - - - - + Positive ノーマル - - - - - - - - + Logs ログ @@ -18688,169 +12836,61 @@ Too many errors, giving up. TelemetrySimulator - - - - - - - - - Telemetry Simulator テレメトリー シミュレータ - - - - - - - - - When enabled, sends any non-blank values as simulated telemetry data. 有効にすると、空白以外の値をテレメトリーデータとしてシミュレートします。 - - - - - - - - - Simulate シミュレート - - - - - - - - - Replay SD Log File SDログファイルを再生 - - - - - - - - - Replay rate 再生レート - - - - - - - - - Load ロード - - - - - - - - - |> - - - - - - - - - <| - - - - - - - - - > - - - - - - - - - <- - - - - - - - - - X - - - - - - - - - Row # Timestamp Row # @@ -18858,71 +12898,26 @@ Timestamp - - - - - - - - - 1/5x 1/5x - - - - - - - - - 5x 5x - - - - - - - - - No Log File Currently Loaded 現在ロードされているログファイルなし - - - - - - - - - RAS 相対アンテナ - - - - - - - - - A2 @@ -18930,75 +12925,21 @@ Timestamp - - - - - - - - - - - - - - - - - - - - - - - - - - - V / ratio V/レシオ - - - - - - - - - Db - - - - - - - - - RxBt 受信機Batt - - - - - - - - - A1 @@ -19016,429 +12957,105 @@ Timestamp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <html><head/><body><p><br/></p></body></html> - - - - - - - - - Tmp1 温度1 - - - - - - - - - A3 - - - - - - - - - A4 - - - - - - - - - RSSI RSSI - - - - - - - - - Tmp2 温度2 - - - - - - - - - - - - - - - - - - RPM RPM - - - - - - - - - Fuel 燃料 - - - - - - - - - - - - - - - - - - °C - - - - - - - - - ml - - - - - - - - - % - - - - - - - - - - - - - - - - - - Meters メートル - - - - - - - - - Alt 高度 - - - - - - - - - VSpd 昇降計 - - - - - - - - - m/s - - - - - - - - - Fuel Qty 燃料油量 - - - - - - - - - - - - - - - - - - km/h - - - - - - - - - VFAS - - - - - - - - - Hdg ヘッディング - - - - - - - - - ASpd 対気速度 @@ -19446,297 +13063,99 @@ Timestamp - - - - - - - - - - - - - - - - - - - - - - - - - - - G - - - - - - - - - GPS GPS - - - - - - - - - Lat,Lon (dec.deg.) - - - - - - - - - AccX 加速度X - - - - - - - - - dd-MM-yyyy hh:mm:ss - - - - - - - - - Date 日時 - - - - - - - - - Amps アンペア - - - - - - - - - AccZ 加速度Z - - - - - - - - - GAlt GPS高度 - - - - - - - - - - - - - - - - - - Volts ボルト - - - - - - - - - Cels セル - - - - - - - - - Curr 電流計 - - - - - - - - - AccY 加速度Y - - - - - - - - - GSpd GPS速度 - - - - - - - - - Degrees 角度(°) - - - - - - - - - Setting RSSI to zero simulates telemetry and radio link loss. RSSIをゼロに設定すると、テレメトリーと送信機リンク損失がシミュレートされます。 - - - - - - - - - Set RSSI to zero when paused. 一時停止したらRSSIをゼロに設定します。 - - - - - - - - - Stop sending telemetry data when the Telemetry Simulator window is hidden. テレメトリーシミュレータ ウィンドウが非表示になったらテレメトリーデータの送信を停止します。 - - - - - - - - - Pause simulation when hidden. 非表示になったらシミュレーションを一時停止します。 @@ -19778,25 +13197,11 @@ hh:mm:ss Timer - - - - - - - Countdown カウントダウン - - - - - - - Minute Call 音声時報 @@ -19881,61 +13286,26 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ Trainer - - - - - - - Form フォーム - - - - - - - Mode モード - - - - - - - Input 入力 - - - - - - - Weight ウェイト - - - - - - - Rud ラダー @@ -19948,62 +13318,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Beeper volume 0 - Quiet. No beeps at all. @@ -20024,34 +13338,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Off OFF @@ -20060,34 +13346,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - += (Sum) += (合計) @@ -20096,34 +13354,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - := (Replace) := (置換) @@ -20132,34 +13362,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn1 @@ -20168,34 +13370,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn2 @@ -20204,34 +13378,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn3 @@ -20240,70 +13386,21 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn4 - - - - - - - Ele エレベーター - - - - - - - Thr スロットル - - - - - - - Ail エルロン @@ -20312,15 +13409,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ TrainerSimulator - - - - - - - - - Trainer simulator トレーナー シミュレータ @@ -20747,33 +13835,12 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ burnConfigDialog - - - - - - - Programmer Configuration プログラムの設定 - - - - - - - - - - - - - - Location of sam-ba executable sam-ba実行ファイル場所 @@ -20782,58 +13849,16 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - - - - - - - - The location of the AVRDUDE executable. AVRDUDE実行ファイル場所. - - - - - - - DFU-Util Location DFU-Utiltyの場所 - - - - - - - Location of AVRDUDE executable AVRDUDE実行ファイル場所 @@ -20841,27 +13866,6 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - Use this button to browse and look for the AVRDUDE executable file. AVRDUDE実行ファイルを参照・検索するには、このボタンを押してください。 @@ -20869,51 +13873,16 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ - - - - - - - - - - - - - - - - - - - - - Browse... 参照... - - - - - - - Programmer プログラム - - - - - - - Programmer used for communicating with the controller. Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer. コントローラとの通信に使用されるプログラムです。 @@ -20921,65 +13890,23 @@ Please consult the programmer's documentation and the AVRDUDE documentation - - - - - - - List all available programmers. 利用可能なプログラムを一覧表示します。 - - - - - - - List Available 一覧表示 - - - - - - - - - - - - - - Extra arguments that will be passed to AVRDUDE on every call すべての呼び出しでAVRDUDEに渡される追加引数 - - - - - - - - - - - - - - Extra arguments used in AVRDUDE. This can be used for providing extra information to AVRDUDE. @@ -20991,49 +13918,21 @@ Please only use this if you know what you are doing. There are no error checks - - - - - - - Extra Arguments 追加引数 - - - - - - - Show AVRDUDE help AVRDUDEのヘルプを表示します - - - - - - - Show Help ヘルプを表示 - - - - - - - Communication port to the programmer. プログラムへの通信ポートです。 @@ -21041,84 +13940,28 @@ Please only use this if you know what you are doing. There are no error checks - - - - - - - - - - - - - - Port ポート - - - - - - - AVRDUDE Location AVRDUDEの場所 - - - - - - - MCU MCU - - - - - - - - - - - - - - CPU of your TX 送信機のCPU - - - - - - - - - - - - - - CPU present on your 9x radio Should be m64 for stock radios m2560 for v4.1 boards @@ -21128,73 +13971,31 @@ v4.1ボード用m2560 - - - - - - - at91sam3s8-9xr at91sam3s8-9xr - - - - - - - SAM-BA Location SAM-BAの場所 - - - - - - - ARM MCU ARM MCU - - - - - - - sam-ba serial port sam-ba シリアルポート - - - - - - - Alternate device 代替デバイス - - - - - - - Use advanced controls 詳細設定を使用 @@ -21240,211 +14041,76 @@ v4.1ボード用m2560 joystickDialog - - - - - - - - - Configure Joystick スティックの設定 - - - - - - - - - Ch2 - - - - - - - - - Ch1 - - - - - - - - - Ch4 - - - - - - - - - Ch6 - - - - - - - - - Ch3 - - - - - - - - - Ch5 - - - - - - - - - Ch7 - - - - - - - - - Ch8 - - - - - - - - - Instructions インストラクション - - - - - - - - - Enable 有効 - - - - - - - - - Cancel キャンセル - - - - - - - - - Back 戻る - - - - - - - - - Start スタート - - - - - - - - - Ok OK diff --git a/radio/sdcard/.gitignore b/radio/sdcard/.gitignore new file mode 100644 index 000000000..c1b29b53e --- /dev/null +++ b/radio/sdcard/.gitignore @@ -0,0 +1 @@ +*/opentx.sdcard.version diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/Graupner HoTT.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/Graupner HoTT.lua new file mode 100644 index 000000000..ff6a3254c --- /dev/null +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/Graupner HoTT.lua @@ -0,0 +1,132 @@ +---- ######################################################################### +---- # # +---- # Copyright (C) OpenTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program 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. # +---- # # +---- ######################################################################### + + +--############################################################################### +-- Multi buffer for HoTT description +-- To start operation: +-- Write "HoTT" at address 0..3 +-- Write 0xFF at address 4 will request the buffer to be cleared +-- Write 0xDF at address 5 +-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters +-- by 8 lines +-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page, +-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev +-- Write at address 4 the value 0xFF will request the buffer to be cleared +-- !! Before exiting the script must write 0 at address 0 for normal operation !! +--############################################################################### + +local function HoTT_Release() + multiBuffer( 0, 0 ) +end + +local function HoTT_Draw_LCD() + local i + local value + local line + local result + local offset=0 + + lcd.clear() + + if LCD_W == 480 then + --Draw title + lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) + lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR) + --Draw RX Menu + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(10,50,"No HoTT telemetry...", BLINK) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS) + else + lcd.drawText(10+i*16,32+16*line,string.char(value)) + end + end + end + end + else + --Draw RX Menu on LCD_W=128 + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS) + else + lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE) + end + end + end + end + end +end + +-- Init +local function HoTT_Init() + --Set protocol to talk to + multiBuffer( 0, string.byte('H') ) + --test if value has been written + if multiBuffer( 0 ) ~= string.byte('H') then + error("Not enough memory!") + return 2 + end + multiBuffer( 1, string.byte('o') ) + multiBuffer( 2, string.byte('T') ) + multiBuffer( 3, string.byte('T') ) + --Request init of the RX buffer + multiBuffer( 4, 0xFF ) + --Request RX to send the config menu + multiBuffer( 5, 0xDF ) +end + +-- Main +local function HoTT_Run(event) + if event == nil then + error("Cannot be run as a model script!") + return 2 + elseif event == EVT_VIRTUAL_EXIT then + HoTT_Release() + return 2 + else + if event == EVT_VIRTUAL_PREV_PAGE then + killEvents(event); + multiBuffer( 5, 0xD7 ) + elseif event == EVT_VIRTUAL_NEXT_PAGE then + multiBuffer( 5, 0xDE ) + elseif event == EVT_VIRTUAL_ENTER then + multiBuffer( 5, 0xD9 ) + elseif event == EVT_VIRTUAL_NEXT then + multiBuffer( 5, 0xDD ) + elseif event == EVT_VIRTUAL_PREV then + multiBuffer( 5, 0xDB ) + else + multiBuffer( 5, 0xDF ) + end + HoTT_Draw_LCD() + return 0 + end +end + +return { init=HoTT_Init, run=HoTT_Run } diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/Graupner HoTT.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/Graupner HoTT.lua new file mode 100644 index 000000000..ff6a3254c --- /dev/null +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/Graupner HoTT.lua @@ -0,0 +1,132 @@ +---- ######################################################################### +---- # # +---- # Copyright (C) OpenTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program 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. # +---- # # +---- ######################################################################### + + +--############################################################################### +-- Multi buffer for HoTT description +-- To start operation: +-- Write "HoTT" at address 0..3 +-- Write 0xFF at address 4 will request the buffer to be cleared +-- Write 0xDF at address 5 +-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters +-- by 8 lines +-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page, +-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev +-- Write at address 4 the value 0xFF will request the buffer to be cleared +-- !! Before exiting the script must write 0 at address 0 for normal operation !! +--############################################################################### + +local function HoTT_Release() + multiBuffer( 0, 0 ) +end + +local function HoTT_Draw_LCD() + local i + local value + local line + local result + local offset=0 + + lcd.clear() + + if LCD_W == 480 then + --Draw title + lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) + lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR) + --Draw RX Menu + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(10,50,"No HoTT telemetry...", BLINK) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS) + else + lcd.drawText(10+i*16,32+16*line,string.char(value)) + end + end + end + end + else + --Draw RX Menu on LCD_W=128 + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS) + else + lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE) + end + end + end + end + end +end + +-- Init +local function HoTT_Init() + --Set protocol to talk to + multiBuffer( 0, string.byte('H') ) + --test if value has been written + if multiBuffer( 0 ) ~= string.byte('H') then + error("Not enough memory!") + return 2 + end + multiBuffer( 1, string.byte('o') ) + multiBuffer( 2, string.byte('T') ) + multiBuffer( 3, string.byte('T') ) + --Request init of the RX buffer + multiBuffer( 4, 0xFF ) + --Request RX to send the config menu + multiBuffer( 5, 0xDF ) +end + +-- Main +local function HoTT_Run(event) + if event == nil then + error("Cannot be run as a model script!") + return 2 + elseif event == EVT_VIRTUAL_EXIT then + HoTT_Release() + return 2 + else + if event == EVT_VIRTUAL_PREV_PAGE then + killEvents(event); + multiBuffer( 5, 0xD7 ) + elseif event == EVT_VIRTUAL_NEXT_PAGE then + multiBuffer( 5, 0xDE ) + elseif event == EVT_VIRTUAL_ENTER then + multiBuffer( 5, 0xD9 ) + elseif event == EVT_VIRTUAL_NEXT then + multiBuffer( 5, 0xDD ) + elseif event == EVT_VIRTUAL_PREV then + multiBuffer( 5, 0xDB ) + else + multiBuffer( 5, 0xDF ) + end + HoTT_Draw_LCD() + return 0 + end +end + +return { init=HoTT_Init, run=HoTT_Run } diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/Graupner HoTT.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/Graupner HoTT.lua new file mode 100644 index 000000000..ff6a3254c --- /dev/null +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/Graupner HoTT.lua @@ -0,0 +1,132 @@ +---- ######################################################################### +---- # # +---- # Copyright (C) OpenTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program 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. # +---- # # +---- ######################################################################### + + +--############################################################################### +-- Multi buffer for HoTT description +-- To start operation: +-- Write "HoTT" at address 0..3 +-- Write 0xFF at address 4 will request the buffer to be cleared +-- Write 0xDF at address 5 +-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters +-- by 8 lines +-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page, +-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev +-- Write at address 4 the value 0xFF will request the buffer to be cleared +-- !! Before exiting the script must write 0 at address 0 for normal operation !! +--############################################################################### + +local function HoTT_Release() + multiBuffer( 0, 0 ) +end + +local function HoTT_Draw_LCD() + local i + local value + local line + local result + local offset=0 + + lcd.clear() + + if LCD_W == 480 then + --Draw title + lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) + lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR) + --Draw RX Menu + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(10,50,"No HoTT telemetry...", BLINK) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS) + else + lcd.drawText(10+i*16,32+16*line,string.char(value)) + end + end + end + end + else + --Draw RX Menu on LCD_W=128 + if multiBuffer( 4 ) == 0xFF then + lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE) + else + for line = 0, 7, 1 do + for i = 0, 21-1, 1 do + value=multiBuffer( line*21+6+i ) + if value > 0x80 then + value = value - 0x80 + lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS) + else + lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE) + end + end + end + end + end +end + +-- Init +local function HoTT_Init() + --Set protocol to talk to + multiBuffer( 0, string.byte('H') ) + --test if value has been written + if multiBuffer( 0 ) ~= string.byte('H') then + error("Not enough memory!") + return 2 + end + multiBuffer( 1, string.byte('o') ) + multiBuffer( 2, string.byte('T') ) + multiBuffer( 3, string.byte('T') ) + --Request init of the RX buffer + multiBuffer( 4, 0xFF ) + --Request RX to send the config menu + multiBuffer( 5, 0xDF ) +end + +-- Main +local function HoTT_Run(event) + if event == nil then + error("Cannot be run as a model script!") + return 2 + elseif event == EVT_VIRTUAL_EXIT then + HoTT_Release() + return 2 + else + if event == EVT_VIRTUAL_PREV_PAGE then + killEvents(event); + multiBuffer( 5, 0xD7 ) + elseif event == EVT_VIRTUAL_NEXT_PAGE then + multiBuffer( 5, 0xDE ) + elseif event == EVT_VIRTUAL_ENTER then + multiBuffer( 5, 0xD9 ) + elseif event == EVT_VIRTUAL_NEXT then + multiBuffer( 5, 0xDD ) + elseif event == EVT_VIRTUAL_PREV then + multiBuffer( 5, 0xDB ) + else + multiBuffer( 5, 0xDF ) + end + HoTT_Draw_LCD() + return 0 + end +end + +return { init=HoTT_Init, run=HoTT_Run } diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 8b8239460..06368660c 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -31,6 +31,7 @@ option(AUTOSWITCH "Automatic switch detection in menus" ON) option(SEMIHOSTING "Enable debugger semihosting" OFF) option(JITTER_MEASURE "Enable ADC jitter measurement" OFF) option(WATCHDOG "Enable hardware Watchdog" ON) +option(ASTERISK "Enable asterisk icon (test only firmware)" OFF) if(SDL_FOUND) option(SIMU_AUDIO "Enable simulator audio." ON) endif() @@ -72,7 +73,7 @@ set(GVARS_VARIANT 1) set(FRSKY_VARIANT 2) set(3POS_VARIANT 4) -set(RADIO_DEPENDENCIES radio_translations) +set(RADIO_DEPENDENCIES firmware_translations) set(FATFS_SRC ${FATFS_DIR}/ff.c @@ -168,9 +169,11 @@ include(storage/conversions/CMakeLists.txt) add_subdirectory(lua) -if(RAMBACKUP) - add_definitions(-DRAMBACKUP) - set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp) +if(RTC_BACKUP_RAM) + add_definitions(-DRTC_BACKUP_RAM) + set(SRC ${SRC} storage/rlc.cpp) + set(FIRMWARE_SRC ${FIRMWARE_SRC} storage/rtc_backup.cpp) + set(GTEST_SRC ${GTEST_SRC} ${RADIO_SRC_DIRECTORY}/storage/rtc_backup.cpp) endif() if(NOT LUA STREQUAL NO) @@ -248,6 +251,10 @@ if(JITTER_MEASURE) add_definitions(-DJITTER_MEASURE) endif() +if(ASTERISK) + add_definitions(-DASTERISK) +endif() + if(WATCHDOG) add_definitions(-DWATCHDOG) endif() @@ -523,7 +530,8 @@ if(NOT MSVC) add_executable(firmware ${SRC} ${FIRMWARE_HEADERS}) link_libraries(firmware -lstdc++) - add_dependencies(firmware ${RADIO_DEPENDENCIES}) + add_dependencies(firmware ${RADIO_DEPENDENCIES} ${FIRMWARE_DEPENDENCIES}) + set_target_properties(firmware PROPERTIES EXCLUDE_FROM_ALL TRUE) add_custom_command( TARGET firmware POST_BUILD diff --git a/radio/src/bluetooth.cpp b/radio/src/bluetooth.cpp index 40af04537..e51d8656b 100644 --- a/radio/src/bluetooth.cpp +++ b/radio/src/bluetooth.cpp @@ -180,7 +180,7 @@ void Bluetooth::processTrainerByte(uint8_t data) break; case STATE_DATA_IN_FRAME: - if (data == BYTESTUFF) { + if (data == BYTE_STUFF) { dataState = STATE_DATA_XOR; // XOR next byte } else if (data == START_STOP) { @@ -225,8 +225,8 @@ void Bluetooth::processTrainerByte(uint8_t data) void Bluetooth::pushByte(uint8_t byte) { crc ^= byte; - if (byte == START_STOP || byte == BYTESTUFF) { - buffer[bufferIndex++] = 0x7d; + if (byte == START_STOP || byte == BYTE_STUFF) { + buffer[bufferIndex++] = BYTE_STUFF; byte ^= STUFF_MASK; } buffer[bufferIndex++] = byte; @@ -762,11 +762,11 @@ const char * Bluetooth::flashFirmware(const char * filename, ProgressHandler pro pausePulses(); bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, true); // normal mode - watchdogSuspend(1000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(1000); bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, false); // bootloader mode - watchdogSuspend(1000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(1000); const char * result = doFlashFirmware(filename, progressHandler); @@ -785,7 +785,7 @@ const char * Bluetooth::flashFirmware(const char * filename, ProgressHandler pro progressHandler(getBasename(filename), STR_MODULE_RESET, 0, 0); /* wait 1s off */ - watchdogSuspend(1000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(1000); state = BLUETOOTH_STATE_OFF; diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 1f245c9c4..81a0d2576 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -194,10 +194,8 @@ enum TrainerMode { TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, #endif -#if defined(BLUETOOTH) TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, -#endif TRAINER_MODE_MULTI, }; #elif defined(PCBSKY9X) @@ -208,12 +206,10 @@ enum TrainerMode { }; #endif -#if defined(MULTIMODULE) +#if defined(RADIO_T16) #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 #elif defined(PCBX7) || defined(PCBXLITE) #define TRAINER_MODE_MAX() TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE #else @@ -269,6 +265,7 @@ enum TelemetryProtocol PROTOCOL_TELEMETRY_SPEKTRUM, PROTOCOL_TELEMETRY_FLYSKY_IBUS, PROTOCOL_TELEMETRY_HITEC, + PROTOCOL_TELEMETRY_HOTT, PROTOCOL_TELEMETRY_MULTIMODULE, PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_MULTIMODULE, PROTOCOL_TELEMETRY_LUA diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 1fa188c78..172351770 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -421,6 +421,7 @@ PACK(struct TrainerModuleData { // Only used in case switch and if statements as "virtual" protocol #define MM_RF_CUSTOM_SELECTED 0xff +#define MULTI_MAX_PROTOCOLS 127 // rfProtocol:4 + rfProtocolExtra:3 PACK(struct ModuleData { uint8_t type:4 ENUM(ModuleType); // TODO some refactoring is needed, rfProtocol is only used by DSM2 and MULTI, it could be merged with subType @@ -440,8 +441,9 @@ PACK(struct ModuleData { int8_t frameLength; } ppm); NOBACKUP(struct { - uint8_t rfProtocolExtra:2; - uint8_t spare1:3 SKIP; + uint8_t rfProtocolExtra:3; + uint8_t disableTelemetry:1; + uint8_t disableMapping:1; uint8_t customProto:1; uint8_t autoBindMode:1; uint8_t lowPowerMode:1; @@ -475,15 +477,13 @@ PACK(struct ModuleData { } NAME(mod) FUNC(select_mod_type); // Helper functions to set both of the rfProto protocol at the same time - NOBACKUP(inline uint8_t getMultiProtocol(bool returnCustom) { - if (returnCustom && multi.customProto) - return MM_RF_CUSTOM_SELECTED; + NOBACKUP(inline uint8_t getMultiProtocol() { return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4); }) NOBACKUP(inline void setMultiProtocol(uint8_t proto) { rfProtocol = (uint8_t) (proto & 0x0f); - multi.rfProtocolExtra = (proto & 0x30) >> 4; + multi.rfProtocolExtra = (proto & 0x70) >> 4; }) }); diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index 60eff9536..5b1fb2dae 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -169,14 +169,14 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext if (param == 0) newActiveFunctions |= 0x0F; else if (param <= NUM_STICKS) - newActiveFunctions |= (1 << (param-1)); + newActiveFunctions |= (1 << (param - 1)); else if (param == NUM_STICKS + 1) - newActiveFunctions |= (1 << FUNCTION_TRAINER_CHANNELS); + newActiveFunctions |= (1u << FUNCTION_TRAINER_CHANNELS); break; } case FUNC_INSTANT_TRIM: - newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM); + newActiveFunctions |= (1u << FUNCTION_INSTANT_TRIM); if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) { #if defined(COLORLCD) #warning IS_INSTANT_TRIM_ALLOWED() is always false diff --git a/radio/src/gui/128x64/lcd.cpp b/radio/src/gui/128x64/lcd.cpp index 31038f07f..99a2bd43c 100644 --- a/radio/src/gui/128x64/lcd.cpp +++ b/radio/src/gui/128x64/lcd.cpp @@ -864,6 +864,44 @@ void drawDate(coord_t x, coord_t y, TelemetryItem & telemetryItem, LcdFlags att) } } +void drawTimerWithMode(coord_t x, coord_t y, uint8_t index, LcdFlags att) +{ + const TimerData &timer = g_model.timers[index]; + + if (timer.mode) { + const TimerState &timerState = timersStates[index]; + const uint8_t negative = (timerState.val < 0 ? BLINK | INVERS : 0); + if (timerState.val < 60 * 60) { // display MM:SS + div_t qr = div((int) abs(timerState.val), 60); + lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0 | negative, 2); + lcdDrawText(lcdLastLeftPos, y, ":", att | BLINK | negative); + lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att | negative); + if (negative) + lcdDrawText(lcdLastLeftPos, y, "-", att | negative); + } + else if (timerState.val < (99 * 60 * 60) + (59 * 60)) { // display HHhMM + div_t qr = div((int) (abs(timerState.val) / 60), 60); + lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0, 2); + lcdDrawText(lcdLastLeftPos, y, "h", att); + lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att); + if (negative) + lcdDrawText(lcdLastLeftPos, y, "-", att); + } + else { //display HHHH for crazy large persistent timers + lcdDrawText(x - 5, y, "h", att); + lcdDrawNumber(lcdLastLeftPos, y, timerState.val / 3600, att); + } + uint8_t xLabel = (negative ? x - 56 : x - 49); + uint8_t len = zlen(timer.name, LEN_TIMER_NAME); + if (len > 0) { + lcdDrawSizedText(xLabel, y + FH, timer.name, len, RIGHT | ZCHAR); + } + else { + drawTimerMode(xLabel, y + FH, timer.mode, RIGHT); + } + } +} + void drawTelemScreenDate(coord_t x, coord_t y, source_t sensor, LcdFlags att) { y+=3; diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h index 1161e78d5..9539606fd 100644 --- a/radio/src/gui/128x64/lcd.h +++ b/radio/src/gui/128x64/lcd.h @@ -107,6 +107,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, L void lcdDrawText(coord_t x, coord_t y, const char * s); void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len); void lcdDrawTextAlignedLeft(coord_t y, const char * s); +void drawTimerWithMode(coord_t x, coord_t y, uint8_t index, LcdFlags att); #define lcdDrawTextAlignedCenter(y, s) lcdDrawText((LCD_W-sizeof(s)*FW+FW+1)/2, y, s) @@ -178,6 +179,7 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, ui #define BLINK_ON_PHASE (0) #else #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) + #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7)) #endif inline pixel_t getPixel(uint8_t x, uint8_t y) diff --git a/radio/src/gui/128x64/model_inputs_mixes.cpp b/radio/src/gui/128x64/model_inputs_mixes.cpp index 5e6bd1d02..1fa163858 100644 --- a/radio/src/gui/128x64/model_inputs_mixes.cpp +++ b/radio/src/gui/128x64/model_inputs_mixes.cpp @@ -378,7 +378,7 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) void menuModelMixOne(event_t event) { - title(STR_MIXER); + title(STR_MIXES); MixData * md2 = mixAddress(s_currIdx) ; putsChn(lcdLastRightPos+1*FW, 0, md2->destCh+1,0); @@ -731,10 +731,10 @@ void menuModelExpoMix(uint8_t expo, event_t event) break; } - lcdDrawNumber(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, getExpoMixCount(expo)); - lcdDrawText(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, expo ? STR_MAX(MAX_EXPOS) : STR_MAX(MAX_MIXERS)); + lcdDrawNumber(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXES))+FW+FW/2, 0, getExpoMixCount(expo)); + lcdDrawText(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXES))+FW+FW/2, 0, expo ? STR_MAX(MAX_EXPOS) : STR_MAX(MAX_MIXERS)); - SIMPLE_MENU(expo ? STR_MENUINPUTS : STR_MIXER, menuTabModel, expo ? MENU_MODEL_INPUTS : MENU_MODEL_MIXES, s_maxLines); + SIMPLE_MENU(expo ? STR_MENUINPUTS : STR_MIXES, menuTabModel, expo ? MENU_MODEL_INPUTS : MENU_MODEL_MIXES, s_maxLines); sub = menuVerticalPosition; s_currCh = 0; diff --git a/radio/src/gui/128x64/model_mix_edit.cpp b/radio/src/gui/128x64/model_mix_edit.cpp index a1329d8b3..f880c1618 100644 --- a/radio/src/gui/128x64/model_mix_edit.cpp +++ b/radio/src/gui/128x64/model_mix_edit.cpp @@ -86,9 +86,9 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) void menuModelMixOne(event_t event) { MixData * md2 = mixAddress(s_currIdx) ; - putsChn(PSIZE(TR_MIXER)*FW+FW, 0, md2->destCh+1,0); + putsChn(PSIZE(TR_MIXES)*FW+FW, 0, md2->destCh+1,0); - SUBMENU(STR_MIXER, MIX_FIELD_COUNT, {0, 0, 0, 0, 0, 1, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); + SUBMENU(STR_MIXES, MIX_FIELD_COUNT, {0, 0, 0, 0, 0, 1, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); int8_t sub = menuVerticalPosition; int8_t editMode = s_editMode; diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index e1d9d26a9..00771538a 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -87,12 +87,24 @@ enum MenuModelSetupItems { #if defined(HARDWARE_INTERNAL_MODULE) ITEM_MODEL_SETUP_INTERNAL_MODULE_LABEL, ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE, +#if defined(MULTIMODULE) + ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE, + ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS, + ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS, +#endif ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS, - ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND, + ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE, ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM, + ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS, +#if defined(MULTIMODULE) + ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND, + ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM, + ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING, +#endif #if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA, #endif + ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER, ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE, ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE, ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS, @@ -106,20 +118,22 @@ enum MenuModelSetupItems { #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE, #endif - ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS, #endif ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS, - ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE, ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM, #if defined(PCBSKY9X) && defined(REVX) ITEM_MODEL_SETUP_EXTERNAL_MODULE_OUTPUT_TYPE, #endif + ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS, #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING, #endif ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE, ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE, @@ -191,12 +205,12 @@ enum MenuModelSetupItems { #define OUTPUT_TYPE_ROW #endif -inline uint8_t EXTERNAL_MODULE_TYPE_ROW() +inline uint8_t MODULE_TYPE_ROWS(int moduleIdx) { - if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) + if (isModuleXJT(moduleIdx) || isModuleR9MNonAccess(moduleIdx) || isModuleDSM2(moduleIdx)) return 1; #if defined(MULTIMODULE) - else if (isModuleMultimodule(EXTERNAL_MODULE)) { + else if (isModuleMultimodule(moduleIdx)) { return 1; } #endif @@ -204,6 +218,17 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW() return 0; } +inline uint8_t MODULE_SUBTYPE_ROWS(int moduleIdx) +{ +#if defined(MULTIMODULE) + if (isModuleMultimodule(moduleIdx)) { + return MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? 1 : HIDDEN_ROW; + } +#endif + + return HIDDEN_ROW; +} + #define POT_WARN_ROWS ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) #define TIMER_ROWS 1, 0, 1, 0, 0, 0 @@ -280,17 +305,22 @@ void onBluetoothConnectMenu(const char * result) #if defined(HARDWARE_INTERNAL_MODULE) #define INTERNAL_MODULE_ROWS \ LABEL(InternalModule), \ - INTERNAL_MODULE_TYPE_ROWS, \ - MODULE_CHANNELS_ROWS(INTERNAL_MODULE), \ - IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1)), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* RxNum */ \ - EXTERNAL_ANTENNA_ROW \ - IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* Failsafe */ \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* Range check and Register buttons */ \ - IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* Module options */ \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 1 */ \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 2 */ \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */ + MODULE_TYPE_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE*/ \ + MULTIMODULE_SUBTYPE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE*/ \ + MULTIMODULE_STATUS_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS */ \ + MODULE_CHANNELS_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS*/ \ + IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1))), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM*/ \ + MODULE_OPTION_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS */ \ + MULTIMODULE_MODULE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND */ \ + EXTERNAL_ANTENNA_ROW /* ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA */ \ + MODULE_POWER_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER */ \ + IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE */ \ + IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS*/ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1 */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2 */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3 */ #else #define INTERNAL_MODULE_ROWS #endif @@ -330,13 +360,13 @@ void menuModelSetup(event_t event) INTERNAL_MODULE_ROWS LABEL(ExternalModule), - EXTERNAL_MODULE_TYPE_ROW(), + MODULE_TYPE_ROWS(EXTERNAL_MODULE), MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) - MODULE_POWER_ROW(EXTERNAL_MODULE), MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum + MODULE_POWER_ROW(EXTERNAL_MODULE), IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) FAILSAFE_ROWS(EXTERNAL_MODULE), @@ -371,19 +401,18 @@ void menuModelSetup(event_t event) NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, // Center beeps 0, // Global functions - LABEL(ExternalModule), - EXTERNAL_MODULE_TYPE_ROW(), + LABEL(ExternalModule), + MODULE_TYPE_ROWS(EXTERNAL_MODULE), MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) - MODULE_POWER_ROW(EXTERNAL_MODULE), MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings - OUTPUT_TYPE_ROW - IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum + MODULE_POWER_ROW(EXTERNAL_MODULE), IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) FAILSAFE_ROWS(EXTERNAL_MODULE), - IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1 IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2 @@ -429,6 +458,7 @@ void menuModelSetup(event_t event) } } + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags attr = (sub == k ? blink : 0); @@ -800,6 +830,7 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, STR_INTERNALRF); break; +#if !defined(INTERNAL_MODULE_MULTI) case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE: { lcdDrawTextAlignedLeft(y, INDENT TR_MODE); @@ -849,6 +880,7 @@ void menuModelSetup(event_t event) break; } #endif +#endif #if defined(PCBSKY9X) case ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL: @@ -860,101 +892,103 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, STR_EXTERNALRF); break; +#if defined(INTERNAL_MODULE_MULTI) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE: lcdDrawTextAlignedLeft(y, INDENT TR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, reusableBuffer.moduleSetup.newType, menuHorizontalPosition==0 ? attr : 0); - if (isModuleXJT(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); - else if (isModuleDSM2(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); - else if (isModuleR9MNonAccess(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, moduleIdx == EXTERNAL_MODULE ? reusableBuffer.moduleSetup.newType : g_model.moduleData[moduleIdx].type, menuHorizontalPosition==0 ? attr : 0); + if (isModuleXJT(moduleIdx)) + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[moduleIdx].subType, menuHorizontalPosition==1 ? attr : 0); + else if (isModuleDSM2(moduleIdx)) + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_DSM_PROTOCOLS, g_model.moduleData[moduleIdx].rfProtocol, menuHorizontalPosition==1 ? attr : 0); + else if (isModuleR9MNonAccess(moduleIdx)) + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_R9M_REGION, g_model.moduleData[moduleIdx].subType, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) - else if (isModuleMultimodule(EXTERNAL_MODULE)) { - int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) - lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition==1 ? attr : 0); - else - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); + else if (isModuleMultimodule(moduleIdx)) { + int multi_rfProto = g_model.moduleData[moduleIdx].getMultiProtocol(); + lcdDrawMultiProtocolString(lcdNextPos + 3, y, moduleIdx, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0); } #endif - if (attr && menuHorizontalPosition == 0) { + if (attr && menuHorizontalPosition == 0 && moduleIdx == EXTERNAL_MODULE) { if (s_editMode > 0) { - g_model.moduleData[EXTERNAL_MODULE].type = MODULE_TYPE_NONE; + g_model.moduleData[moduleIdx].type = MODULE_TYPE_NONE; } else if (reusableBuffer.moduleSetup.newType != reusableBuffer.moduleSetup.previousType) { - g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + g_model.moduleData[moduleIdx].type = reusableBuffer.moduleSetup.newType; reusableBuffer.moduleSetup.previousType = reusableBuffer.moduleSetup.newType; - setModuleType(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type); + setModuleType(moduleIdx, g_model.moduleData[moduleIdx].type); } - else if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE) { - g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + else if (g_model.moduleData[moduleIdx].type == MODULE_TYPE_NONE) { + g_model.moduleData[moduleIdx].type = reusableBuffer.moduleSetup.newType; } } if (attr) { if (s_editMode > 0) { switch (menuHorizontalPosition) { case 0: - reusableBuffer.moduleSetup.newType = checkIncDec(event, reusableBuffer.moduleSetup.newType, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); +#if defined(HARDWARE_INTERNAL_MODULE) + if (moduleIdx == INTERNAL_MODULE) { + uint8_t moduleType = checkIncDec(event, g_model.moduleData[moduleIdx].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, + isInternalModuleAvailable); + if (checkIncDec_Ret) { + setModuleType(moduleIdx, moduleType); + } + } + else +#endif + reusableBuffer.moduleSetup.newType = checkIncDec(event, reusableBuffer.moduleSetup.newType, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, + isExternalModuleAvailable); break; case 1: - if (isModuleDSM2(EXTERNAL_MODULE)) { - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); + if (isModuleDSM2(moduleIdx)) { + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); } - else if (isModuleR9MNonAccess(EXTERNAL_MODULE)) { - g_model.moduleData[EXTERNAL_MODULE].subType = checkIncDec(event, - g_model.moduleData[EXTERNAL_MODULE].subType, - MODULE_SUBTYPE_R9M_FCC, - MODULE_SUBTYPE_R9M_LAST, - EE_MODEL, - isR9MModeAvailable); + else if (isModuleR9MNonAccess(moduleIdx)) { + g_model.moduleData[moduleIdx].subType = checkIncDec(event, + g_model.moduleData[moduleIdx].subType, + MODULE_SUBTYPE_R9M_FCC, + MODULE_SUBTYPE_R9M_LAST, + EE_MODEL, + isR9MModeAvailable); if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].pxx.power = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); + g_model.moduleData[moduleIdx].pxx.power = 0; + g_model.moduleData[moduleIdx].channelsStart = 0; + g_model.moduleData[moduleIdx].channelsCount = defaultModuleChannels_M8(moduleIdx); } } #if defined(MULTIMODULE) - else if (isModuleMultimodule(EXTERNAL_MODULE)) { - int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable); + else if (isModuleMultimodule(moduleIdx)) { + int multiRfProto = g_model.moduleData[moduleIdx].getMultiProtocol(); + CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MULTI_MAX_PROTOCOLS, isMultiProtocolSelectable); if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM); - if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto) - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto); - g_model.moduleData[EXTERNAL_MODULE].subType = 0; - // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1; - } - else { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0; - } - g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0; + g_model.moduleData[moduleIdx].setMultiProtocol(multiRfProto); + g_model.moduleData[moduleIdx].subType = 0; + resetMultiProtocolsOptions(moduleIdx); } } #endif else { - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_PXX1_LAST); + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, MODULE_SUBTYPE_PXX1_LAST); } if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); + g_model.moduleData[moduleIdx].channelsStart = 0; + g_model.moduleData[moduleIdx].channelsCount = defaultModuleChannels_M8(moduleIdx); } } } #if POPUP_LEVEL > 1 else if (old_editMode > 0) { - if (isModuleR9MNonAccess(EXTERNAL_MODULE)) { - if (g_model.moduleData[EXTERNAL_MODULE].subType > MODULE_SUBTYPE_R9M_EU) { + if (isModuleR9MNonAccess(moduleIdx)) { + if (g_model.moduleData[moduleIdx].subType > MODULE_SUBTYPE_R9M_EU) { POPUP_WARNING(STR_MODULE_PROTOCOL_FLEX_WARN_LINE1); SET_WARNING_INFO(STR_MODULE_PROTOCOL_WARN_LINE2, sizeof(TR_MODULE_PROTOCOL_WARN_LINE2) - 1, 0); } #if POPUP_LEVEL >= 3 - else if (g_model.moduleData[EXTERNAL_MODULE].subType == MODULE_SUBTYPE_R9M_EU) { + else if (g_model.moduleData[moduleIdx].subType == MODULE_SUBTYPE_R9M_EU) { POPUP_WARNING(STR_MODULE_PROTOCOL_EU_WARN_LINE1); SET_WARNING_INFO(STR_MODULE_PROTOCOL_WARN_LINE2, sizeof(TR_MODULE_PROTOCOL_WARN_LINE2) - 1, 0); } @@ -970,32 +1004,22 @@ void menuModelSetup(event_t event) break; #if defined(MULTIMODULE) +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE: { lcdDrawTextAlignedLeft(y, STR_SUBTYPE); - uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true); - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto); - - if (multi_rfProto == MM_RF_CUSTOM_SELECTED) { - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), (menuHorizontalPosition == 0 ? attr : 0), 2); - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition == 1 ? attr : 0), 2); - } - else { - if (pdef->subTypeString != nullptr) - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - } + lcdDrawMultiSubProtocolString(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, g_model.moduleData[moduleIdx].subType, attr); if (attr && s_editMode > 0) { switch (menuHorizontalPosition) { - case 0: - if (multi_rfProto == MM_RF_CUSTOM_SELECTED) - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); - else if (pdef->maxSubtype > 0) - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype); - break; - case 1: - // Custom protocol, third column is subtype - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); + case 0:{ + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, getMaxMultiSubtype(moduleIdx)); + if (checkIncDec_Ret) { + resetMultiProtocolsOptions(moduleIdx); + } break; + } } } } @@ -1100,7 +1124,6 @@ void menuModelSetup(event_t event) #endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; lcdDrawTextAlignedLeft(y, STR_CHANNELRANGE); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); @@ -1162,7 +1185,6 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM: case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER_NUM); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], attr | LEADING0 | LEFT, 2); if (attr) { @@ -1177,7 +1199,6 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE: case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); lcdDrawTextAlignedLeft(y, INDENT TR_MODULE); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, BUTTON(TR_REGISTER), (menuHorizontalPosition == 0 ? attr : 0)); lcdDrawText(lcdLastRightPos + 3, y, STR_MODULE_RANGE, (menuHorizontalPosition == 1 ? attr : 0)); @@ -1225,11 +1246,10 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_EXTRA_MODULE_BIND: #endif #if defined(HARDWARE_INTERNAL_MODULE) - case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE: #endif - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; if (isModulePPM(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_PPMFRAME); @@ -1366,7 +1386,6 @@ void menuModelSetup(event_t event) #if defined(PCBSKY9X) && defined(REVX) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OUTPUT_TYPE: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; moduleData.ppm.outputType = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_OUTPUT_TYPE, STR_VOUTPUT_TYPE, moduleData.ppm.outputType, 0, 1, attr, event); break; @@ -1377,7 +1396,6 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE: #endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData &moduleData = g_model.moduleData[moduleIdx]; lcdDrawTextAlignedLeft(y, STR_FAILSAFE); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition == 0 ? attr : 0); @@ -1434,18 +1452,36 @@ void menuModelSetup(event_t event) } break; #endif - +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); #if defined(MULTIMODULE) - if (isModuleMultimodule(moduleIdx)) { + if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true); - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); - if (pdef->optionsstr) - lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); + const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); + if (multi_proto < MODULE_SUBTYPE_MULTI_LAST) { + const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); + if (pdef->optionsstr) { + lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); + if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + } + } + else { + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]); + if (attr && status.optionDisp == 2) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + } if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) optionValue = 50 + 5 * optionValue; @@ -1460,11 +1496,6 @@ void menuModelSetup(event_t event) } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); - if (pdef->optionsstr == STR_MULTI_RFTUNE) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } } } } @@ -1483,13 +1514,15 @@ void menuModelSetup(event_t event) break; } +#if defined(INTERNAL_MODULE_MULTI) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER: { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); auto & module = g_model.moduleData[moduleIdx]; // Lite FCC / Lite FLEX / Lite Pro Flex if (isModuleTypeR9MNonAccess(module.type)) { - lcdDrawTextAlignedLeft(y, STR_RF_POWER); + lcdDrawText(INDENT_WIDTH, y, STR_RF_POWER); if (isModuleR9M_FCC_VARIANT(moduleIdx)) { // FCC and FLEX modes ... if (isModuleTypeR9MLiteNonPro(module.type)) { // R9M lite FCC has only one power value, so displayed for info only @@ -1558,27 +1591,47 @@ void menuModelSetup(event_t event) break; #if defined(MULTIMODULE) +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND: - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, event); + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) + g_model.moduleData[moduleIdx].multi.autoBindMode = editCheckBox(g_model.moduleData[moduleIdx].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, event); else - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event); + g_model.moduleData[moduleIdx].multi.autoBindMode = editCheckBox(g_model.moduleData[moduleIdx].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event); + break; +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM: +#endif + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM: + g_model.moduleData[moduleIdx].multi.disableTelemetry = editCheckBox(g_model.moduleData[moduleIdx].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event); + break; +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING: +#endif + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING: + g_model.moduleData[moduleIdx].multi.disableMapping = editCheckBox(g_model.moduleData[moduleIdx].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event); break; +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: { lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); char statusText[64]; - getMultiModuleStatus(EXTERNAL_MODULE).getStatusString(statusText); + getMultiModuleStatus(moduleIdx).getStatusString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } - +#if defined(HARDWARE_INTERNAL_MODULE) + case ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS: +#endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS: { lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC); char statusText[64]; - getMultiSyncStatus(EXTERNAL_MODULE).getRefreshString(statusText); + getMultiSyncStatus(moduleIdx).getRefreshString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } @@ -1643,7 +1696,7 @@ void menuModelSetup(event_t event) if (old_editMode > 0 && s_editMode == 0) { switch(menuVerticalPosition) { #if defined(HARDWARE_INTERNAL_MODULE) - case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE: case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, INTERNAL_MODULE); @@ -1655,7 +1708,7 @@ void menuModelSetup(event_t event) checkModelIdUnique(g_eeGeneral.currModel, EXTRA_MODULE); break; #endif - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE: case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE); diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index a0472d681..bfcee26c3 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -224,15 +224,17 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF if (func == FUNC_TRAINER) { maxParam = NUM_STICKS + 1; uint8_t param = CFN_CH_INDEX(cfn); - if (param == NUM_STICKS + 1) - lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "Chans", attr); + if (param == 0) + lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_STICKS, attr); + else if (param == NUM_STICKS + 1) + lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_CHANS, attr); else - drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, CFN_CH_INDEX(cfn) == 0 ? 0 : MIXSRC_Rud + CFN_CH_INDEX(cfn) - 1, attr); + drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_Rud + param - 1, attr); } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { maxParam = MAX_GVARS-1; - drawStringWithIndex(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); + drawStringWithIndex(lcdNextPos + 2, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags); break; } diff --git a/radio/src/gui/128x64/model_telemetry.cpp b/radio/src/gui/128x64/model_telemetry.cpp index 96f5401a3..23f1e6230 100644 --- a/radio/src/gui/128x64/model_telemetry.cpp +++ b/radio/src/gui/128x64/model_telemetry.cpp @@ -237,8 +237,8 @@ void menuModelTelemetry(event_t event) case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) - if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) - lcdDrawTextAlignedLeft(y, "RSNR"); + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A || g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT)) + lcdDrawTextAlignedLeft(y, "RQly"); else lcdDrawTextAlignedLeft(y, "RSSI"); #else diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 0fdfa9b43..a423adf83 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -177,43 +177,6 @@ void displayTrims(uint8_t phase) } } -void drawTimerWithMode(coord_t x, coord_t y, uint8_t index) -{ - const TimerData & timer = g_model.timers[index]; - - if (timer.mode) { - const TimerState & timerState = timersStates[index]; - const uint8_t negative = (timerState.val<0 ? BLINK | INVERS : 0); - LcdFlags att = RIGHT | DBLSIZE; - if (timerState.val < 60 * 60) { // display MM:SS - div_t qr = div(abs(timerState.val), 60); - lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0 | negative, 2); - lcdDrawText(lcdLastLeftPos, y, ":", att|BLINK | negative); - lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att | negative); - if (negative) - lcdDrawText(lcdLastLeftPos, y, "-", att | negative); - } - else if (timerState.val < (99 * 60 * 60) + (59 * 60)) { // display HHhMM - div_t qr = div(abs(timerState.val) / 60, 60); - lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0, 2); - lcdDrawText(lcdLastLeftPos, y, "h", att); - lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att); - if (negative) - lcdDrawText(lcdLastLeftPos, y, "-", att); - } - else { //display HHHH for crazy large persistent timers - lcdDrawText(x - 5, y, "h", att); - lcdDrawNumber(lcdLastLeftPos, y, timerState.val / 3600, att); - } - uint8_t xLabel = (negative ? x-56 : x-49); - uint8_t len = zlen(timer.name, LEN_TIMER_NAME); - if (len > 0) - lcdDrawSizedText(xLabel, y+FH, timer.name, len, RIGHT | ZCHAR); - else - lcdDrawTextAtIndex(xLabel, y+FH, STR_VTMRMODES, timer.mode, RIGHT); - } -} - void displayBattVoltage() { #if defined(BATTGRAPH) @@ -459,7 +422,7 @@ void menuMainView(event_t event) displayVoltageOrAlarm(); // Timer 1 - drawTimerWithMode(125, 2*FH, 0); + drawTimerWithMode(125, 2*FH, 0, RIGHT | DBLSIZE); // Trims sliders displayTrims(mode); @@ -597,7 +560,7 @@ void menuMainView(event_t event) } else { // Timer2 - drawTimerWithMode(87, 5*FH, 1); + drawTimerWithMode(87, 5*FH, 1, RIGHT | DBLSIZE); } // And ! in case of unexpected shutdown diff --git a/radio/src/gui/128x64/view_telemetry.cpp b/radio/src/gui/128x64/view_telemetry.cpp index b840a622e..84a0cbf77 100644 --- a/radio/src/gui/128x64/view_telemetry.cpp +++ b/radio/src/gui/128x64/view_telemetry.cpp @@ -45,8 +45,6 @@ void displayRssiLine() } } - - uint8_t barCoord(int16_t value, int16_t min, int16_t max) { if (value <= min) @@ -57,7 +55,6 @@ uint8_t barCoord(int16_t value, int16_t min, int16_t max) return ((int32_t)(BAR_WIDTH-1) * (value - min)) / (max - min); } - bool displayGaugesTelemetryScreen(TelemetryScreenData & screen) { // Custom Screen with gauges @@ -125,9 +122,11 @@ bool displayNumbersTelemetryScreen(TelemetryScreenData & screen) if (field) { LcdFlags att = (i==3 ? RIGHT|NO_UNIT : RIGHT|MIDSIZE|NO_UNIT); coord_t pos[] = {0, 65, 130}; - if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER && i!=3) { + if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER && i != 3) { // there is not enough space on LCD for displaying "Tmr1" or "Tmr2" and still see the - sign, we write "T1" or "T2" instead drawStringWithIndex(pos[j], 1+FH+2*FH*i, "T", field-MIXSRC_FIRST_TIMER+1, 0); + drawTimerWithMode(pos[j+1] + 2, 1+FH+2*FH*i, field - MIXSRC_FIRST_TIMER, RIGHT | DBLSIZE); + continue; } else if (field >= MIXSRC_FIRST_TELEM && isGPSSensor(1+(field-MIXSRC_FIRST_TELEM)/3) && telemetryItems[(field-MIXSRC_FIRST_TELEM)/3].isAvailable()) { // we don't display GPS name, no space for it @@ -146,7 +145,8 @@ bool displayNumbersTelemetryScreen(TelemetryScreenData & screen) att |= INVERS|BLINK; } } - if(isSensorUnit(1+(field-MIXSRC_FIRST_TELEM)/3, UNIT_DATETIME) && field >= MIXSRC_FIRST_TELEM) { + + if (isSensorUnit(1+(field-MIXSRC_FIRST_TELEM)/3, UNIT_DATETIME) && field >= MIXSRC_FIRST_TELEM) { drawTelemScreenDate(pos[j+1]-36, 6+FH+2*FH*i, field, SMLSIZE|NO_UNIT); } else { diff --git a/radio/src/gui/212x64/lcd.h b/radio/src/gui/212x64/lcd.h index 82c6a1339..270d25959 100644 --- a/radio/src/gui/212x64/lcd.h +++ b/radio/src/gui/212x64/lcd.h @@ -173,6 +173,7 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, u #define BLINK_ON_PHASE (0) #else #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) + #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7)) #endif inline pixel_t getPixel(unsigned int x, unsigned int y) diff --git a/radio/src/gui/212x64/model_mix_edit.cpp b/radio/src/gui/212x64/model_mix_edit.cpp index 8cc35395f..0007d91ee 100644 --- a/radio/src/gui/212x64/model_mix_edit.cpp +++ b/radio/src/gui/212x64/model_mix_edit.cpp @@ -91,10 +91,10 @@ void menuModelMixOne(event_t event) } MixData * md2 = mixAddress(s_currIdx) ; - putsChn(PSIZE(TR_MIXER)*FW+FW, 0, md2->destCh+1,0); + putsChn(PSIZE(TR_MIXES)*FW+FW, 0, md2->destCh+1,0); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); - SUBMENU(STR_MIXER, MIX_FIELD_COUNT, {0, 0, 0, 0, 0, 1, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); + SUBMENU(STR_MIXES, MIX_FIELD_COUNT, {0, 0, 0, 0, 0, 1, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); int8_t sub = menuVerticalPosition; int8_t editMode = s_editMode; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index d25a54fc7..923adc9a9 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -107,6 +107,8 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS, #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING, #endif ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE, @@ -815,21 +817,11 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { - uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - + uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); // Do not use MODEL_SETUP_3RD_COLUMN here since some the protocol string are so long that we cannot afford the 2 spaces (+6) here - if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { - lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0); - lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2); - lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2); - } - else { - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto); - if (pdef->subTypeString) { - lcdDrawTextAtIndex(lcdNextPos + 3, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - } - } + lcdDrawMultiProtocolString(lcdNextPos + 3, y, EXTERNAL_MODULE, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0); + if (MULTIMODULE_HAS_SUBTYPE(EXTERNAL_MODULE)) + lcdDrawMultiSubProtocolString(lcdNextPos + 3, y, EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); } #endif if (attr && menuHorizontalPosition == 0) { @@ -858,21 +850,12 @@ void menuModelSetup(event_t event) } #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { - int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable); + int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); + CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MULTI_MAX_PROTOCOLS, isMultiProtocolSelectable); if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM); - if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto) - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto); + g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto); g_model.moduleData[EXTERNAL_MODULE].subType = 0; - // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1; - } - else { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0; - } - g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0; + resetMultiProtocolsOptions(EXTERNAL_MODULE); } } #endif @@ -894,20 +877,10 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) case 2: - if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); - break; + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, getMaxMultiSubtype(EXTERNAL_MODULE)); + if (checkIncDec_Ret) { + resetMultiProtocolsOptions(EXTERNAL_MODULE); } - else { - const mm_protocol_definition * pdef = getMultiProtocolDefinition(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false)); - if (pdef->maxSubtype > 0) - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype); - } - break; - - case 3: - // Custom protocol, third column is subtype - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); break; #endif } @@ -1240,14 +1213,29 @@ void menuModelSetup(event_t event) uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); #if defined(MULTIMODULE) - if (isModuleMultimodule(moduleIdx)) { + if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true); - const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_proto); - if (pdef->optionsstr) - lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); - + const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); + if (multi_proto < MODULE_SUBTYPE_MULTI_LAST) { + const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); + if (pdef->optionsstr) + lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); + if (pdef->optionsstr == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + } + else { + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]); + if (attr && status.optionDisp == 2) { + lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + } if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) optionValue = 50 + 5 * optionValue; @@ -1261,11 +1249,6 @@ void menuModelSetup(event_t event) } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); - if (pdef->optionsstr == STR_MULTI_RFTUNE) { - lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } } } } @@ -1290,7 +1273,7 @@ void menuModelSetup(event_t event) { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); if (isModuleR9MNonAccess(moduleIdx)) { - lcdDrawTextAlignedLeft(y, TR_RF_POWER); + lcdDrawText(INDENT_WIDTH, y, STR_RFPOWER); if (isModuleR9M_FCC_VARIANT(moduleIdx)) { lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr); if (attr) @@ -1317,12 +1300,20 @@ void menuModelSetup(event_t event) #if defined (MULTIMODULE) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND: - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) + if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, event); else g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event); break; + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM: + g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event); + break; + + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING: + g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event); + break; + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: { lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index eb1bcb58d..7c2d1e139 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -216,15 +216,17 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF if (func == FUNC_TRAINER) { maxParam = NUM_STICKS + 1; uint8_t param = CFN_CH_INDEX(cfn); - if (param == NUM_STICKS + 1) - lcdDrawText(lcdNextPos, y, "Chans", attr); + if (param == 0) + lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_STICKS, attr); + else if (param == NUM_STICKS + 1) + lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_CHANS, attr); else - drawSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); + drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_Rud + param - 1, attr); } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { maxParam = MAX_GVARS-1; - drawStringWithIndex(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); + drawStringWithIndex(lcdNextPos + 2, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags); break; } diff --git a/radio/src/gui/212x64/model_telemetry.cpp b/radio/src/gui/212x64/model_telemetry.cpp index ea1aa7dcc..fc35f0024 100644 --- a/radio/src/gui/212x64/model_telemetry.cpp +++ b/radio/src/gui/212x64/model_telemetry.cpp @@ -228,8 +228,8 @@ void menuModelTelemetry(event_t event) case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) - if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) - lcdDrawTextAlignedLeft(y, "RSNR"); + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A || g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT)) + lcdDrawTextAlignedLeft(y, "RQly"); else lcdDrawTextAlignedLeft(y, "RSSI"); #else diff --git a/radio/src/gui/common/stdlcd/draw_functions.cpp b/radio/src/gui/common/stdlcd/draw_functions.cpp index 906e61c62..64c60448a 100644 --- a/radio/src/gui/common/stdlcd/draw_functions.cpp +++ b/radio/src/gui/common/stdlcd/draw_functions.cpp @@ -21,6 +21,39 @@ #include "opentx.h" #include +#if defined(MULTIMODULE) +void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags) +{ + if (protocol <= MODULE_SUBTYPE_MULTI_LAST) { + lcdDrawTextAtIndex(x, y, STR_MULTI_PROTOCOLS, protocol, flags); + return; + } + else { + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.protocolName[0] && status.isValid()) + lcdDrawText(x, y, status.protocolName, flags); + else + lcdDrawNumber(x, y, protocol + 3, flags); // Convert because of OpenTX FrSky fidling (OpenTX protocol tables and Multiprotocol tables don't match) + } +} + +void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags) +{ + const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol()); + if (subType <= pdef->maxSubtype && pdef->subTypeString != nullptr) { + lcdDrawTextAtIndex(x, y, pdef->subTypeString, subType, flags); + return; + } + else { + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.protocolName[0] && status.isValid()) + lcdDrawText(x, y, status.protocolSubName, flags); + else + lcdDrawNumber(x, y, subType, flags); + } +} +#endif + void drawStringWithIndex(coord_t x, coord_t y, const char * str, uint8_t idx, LcdFlags flags) { if (flags & RIGHT) { diff --git a/radio/src/gui/common/stdlcd/draw_functions.h b/radio/src/gui/common/stdlcd/draw_functions.h index 1c2cffb8e..a3b237126 100644 --- a/radio/src/gui/common/stdlcd/draw_functions.h +++ b/radio/src/gui/common/stdlcd/draw_functions.h @@ -22,7 +22,8 @@ #define _STDLCD_DRAW_FUNCTIONS_H_ #include "lcd.h" - +void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags = 0); +void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags = 0); void drawStringWithIndex(coord_t x, coord_t y, const char * str, uint8_t idx, LcdFlags att=0); void drawValueWithUnit(coord_t x, coord_t y, int val, uint8_t unit, LcdFlags att=0); diff --git a/radio/src/gui/common/stdlcd/model_mixes.cpp b/radio/src/gui/common/stdlcd/model_mixes.cpp index 2a4849d6f..c2714a3b0 100644 --- a/radio/src/gui/common/stdlcd/model_mixes.cpp +++ b/radio/src/gui/common/stdlcd/model_mixes.cpp @@ -231,7 +231,7 @@ void displayMixInfos(coord_t y, MixData * md) void displayMixLine(coord_t y, MixData * md, bool active) { if(active && md->name[0]) { - lcdDrawSizedText(FW*sizeof(TR_MIXER)+FW/2, 0, md->name, sizeof(md->name), ZCHAR); + lcdDrawSizedText(FW*sizeof(TR_MIXES)+FW/2, 0, md->name, sizeof(md->name), ZCHAR); if (!md->flightModes || ((md->curve.value || md->swtch) && ((get_tmr10ms() / 200) & 1))) displayMixInfos(y, md); else @@ -385,7 +385,7 @@ void menuModelMixAll(event_t event) break; } - lcdDrawNumber(FW*sizeof(TR_MIXER)+FW/2, 0, getMixesCount(), 0); + lcdDrawNumber(FW*sizeof(TR_MIXES)+FW/2, 0, getMixesCount(), 0); lcdDrawText(lcdNextPos, 0, STR_MAX(MAX_MIXERS)); // Value @@ -397,7 +397,7 @@ void menuModelMixAll(event_t event) #endif } - SIMPLE_MENU(STR_MIXER, menuTabModel, MENU_MODEL_MIXES, HEADER_LINE + s_maxLines); + SIMPLE_MENU(STR_MIXES, menuTabModel, MENU_MODEL_MIXES, HEADER_LINE + s_maxLines); #if LCD_W >= 212 // Gauge diff --git a/radio/src/gui/common/stdlcd/radio_power_meter.cpp b/radio/src/gui/common/stdlcd/radio_power_meter.cpp index 589da52f0..b30de2b1f 100644 --- a/radio/src/gui/common/stdlcd/radio_power_meter.cpp +++ b/radio/src/gui/common/stdlcd/radio_power_meter.cpp @@ -50,7 +50,7 @@ void menuRadioPowerMeter(event_t event) lcdRefresh(); moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); /* wait 1s to resume normal operation before leaving */ - watchdogSuspend(1000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(1000); return; } diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index ad663f7c1..efe9b62ca 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -568,13 +568,15 @@ void menuRadioSdManager(event_t _event) if (moduleState[EXTERNAL_MODULE].mode == MODULE_MODE_BIND) { if (reusableBuffer.sdManager.otaUpdateInformation.step == BIND_INIT) { if (reusableBuffer.sdManager.otaUpdateInformation.candidateReceiversCount > 0) { - popupMenuItemsCount = min(reusableBuffer.sdManager.otaUpdateInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); - for (uint8_t i=0; i(reusableBuffer.sdManager.otaUpdateInformation.candidateReceiversCount,PXX2_MAX_RECEIVERS_PER_MODULE); + for (auto rx = 0; rx < popupMenuItemsCount; rx++) { + popupMenuItems[rx] = reusableBuffer.sdManager.otaUpdateInformation.candidateReceiversNames[rx]; + } + popupMenuTitle = STR_PXX2_SELECT_RX; + POPUP_MENU_START(onUpdateReceiverSelection); } - popupMenuTitle = STR_PXX2_SELECT_RX; - CLEAR_POPUP(); - POPUP_MENU_START(onUpdateReceiverSelection); } else { POPUP_WAIT(STR_WAITING_FOR_RX); diff --git a/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp index ab96c52d5..32a79b8c5 100644 --- a/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp +++ b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp @@ -44,7 +44,7 @@ void menuRadioSpectrumAnalyser(event_t event) lcdRefresh(); moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); /* wait 1s to resume normal operation before leaving */ - watchdogSuspend(1000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(1000); return; } diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index 0a298b282..8c12c4201 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -44,7 +44,7 @@ void readModelNotes() menuTextView(event); event = getEvent(); lcdRefresh(); - wdt_reset(); + WDG_RESET(); } LED_ERROR_END(); diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index bec40cfaf..12319d870 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -665,7 +665,7 @@ bool isExternalModuleAvailable(int moduleType) #endif #if defined(HARDWARE_INTERNAL_MODULE) - if ((isModuleUsingSport(EXTERNAL_MODULE, moduleType) || isTrainerUsingModuleBay()) && isModuleUsingSport(INTERNAL_MODULE, g_model.moduleData[INTERNAL_MODULE].type)) + if (isTrainerUsingModuleBay() || (isModuleUsingSport(EXTERNAL_MODULE, moduleType) && isModuleUsingSport(INTERNAL_MODULE, g_model.moduleData[INTERNAL_MODULE].type))) return false; #endif @@ -791,6 +791,37 @@ int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable) return retval; } #if defined(MULTIMODULE) + +// This maps OpenTX multi type with Pascal's Multi type +uint8_t convertMultiProtocol(uint8_t moduleIdx, uint8_t type) +{ + + // 15 for Multimodule is FrskyX or D16 which we map as a subprotocol of 3 (FrSky) + // all protos > frskyx are therefore also off by one + if (type >= 15) + type = type + 1; + + // 25 is again a FrSky protocol (FrskyV) so shift again + if (type >= 25) + type = type + 1; + + if (type == MODULE_SUBTYPE_MULTI_FRSKY) { + int subtype = g_model.moduleData[moduleIdx].subType; + if (subtype == MM_RF_FRSKY_SUBTYPE_D8) { + //D8 + type = 3; + } + else if (subtype == MM_RF_FRSKY_SUBTYPE_V8) { + //V8 + type = 25; + } + else { + type = 15; + } + } + return type; +} + // Third row is number of subtypes -1 (max valid subtype) #define NO_SUBTYPE nullptr @@ -815,7 +846,7 @@ const char STR_SUBTYPE_SYMAX[] = "\003""Std""X5C"; const char STR_SUBTYPE_SLT[] = "\006""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0"; const char STR_SUBTYPE_CX10[] = "\007""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041"; const char STR_SUBTYPE_CG023[] = "\005""Std\0 ""YD829"; -const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0 ""IRDrone""DHD D4"; +const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4"; const char STR_SUBTYPE_MT99[] = "\006""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805"; const char STR_SUBTYPE_MJXQ[] = "\007""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix"; const char STR_SUBTYPE_FY326[] = "\005""Std\0 ""FY319"; @@ -836,53 +867,70 @@ const char STR_SUBTYPE_REDPINE[] = "\004""Fast""Slow"; const char STR_SUBTYPE_POTENSIC[] = "\003""A20"; const char STR_SUBTYPE_ZSX[] = "\007""280JJRC"; const char STR_SUBTYPE_FLYZONE[] = "\005""FZ410"; -const char STR_SUBTYPE_FRSKYX_RX[] = "\003""FCC""LBT"; +const char STR_SUBTYPE_FX816[] = "\003""P38"; +const char STR_SUBTYPE_ESKY150[] = "\003""4CH""7CH"; + +const char* mm_options_strings::options[] = { + nullptr, + STR_MULTI_OPTION, + STR_MULTI_RFTUNE, + STR_MULTI_VIDFREQ, + STR_MULTI_FIXEDID, + STR_MULTI_TELEMETRY, + STR_MULTI_SERVOFREQ, + STR_MULTI_MAX_THROW, + STR_MULTI_RFCHAN +}; const mm_protocol_definition multi_protocols[] = { - - {MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, STR_SUBTYPE_FLYSKY, nullptr}, - {MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ}, - {MODULE_SUBTYPE_MULTI_FRSKY, 5, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr}, - {MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr}, - {MODULE_SUBTYPE_MULTI_DSM2, 3, false, STR_SUBTYPE_DSM, nullptr}, - {MODULE_SUBTYPE_MULTI_DEVO, 4, false, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID}, - {MODULE_SUBTYPE_MULTI_YD717, 4, false, STR_SUBTYPE_YD717, nullptr}, - {MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr}, - {MODULE_SUBTYPE_MULTI_SYMAX, 1, false, STR_SUBTYPE_SYMAX, nullptr}, - {MODULE_SUBTYPE_MULTI_SLT, 4, false, STR_SUBTYPE_SLT, nullptr}, - {MODULE_SUBTYPE_MULTI_CX10, 6, false, STR_SUBTYPE_CX10, nullptr}, - {MODULE_SUBTYPE_MULTI_CG023, 1, false, STR_SUBTYPE_CG023, nullptr}, - {MODULE_SUBTYPE_MULTI_BAYANG, 4, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY}, - {MODULE_SUBTYPE_MULTI_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr}, - {MODULE_SUBTYPE_MULTI_MJXQ, 6, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_FY326, 1, false, STR_SUBTYPE_FY326, nullptr}, - {MODULE_SUBTYPE_MULTI_SFHSS, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_HONTAI, 3, false, STR_SUBTYPE_HONTAI, nullptr}, - {MODULE_SUBTYPE_MULTI_OLRS, 0, false, NO_SUBTYPE, STR_RF_POWER}, - {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, - {MODULE_SUBTYPE_MULTI_Q2X2, 2, false, STR_SUBTYPE_Q2X2, nullptr}, - {MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr}, - {MODULE_SUBTYPE_MULTI_Q303, 3, false, STR_SUBTYPE_Q303, nullptr}, - {MODULE_SUBTYPE_MULTI_CABELL, 7, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION}, - {MODULE_SUBTYPE_MULTI_H83D, 3, false, STR_SUBTYPE_H83D, nullptr}, - {MODULE_SUBTYPE_MULTI_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr}, - {MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr}, - {MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION}, - {MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr}, - {MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr}, - {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr}, - {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE}, - {MM_RF_CUSTOM_SELECTED, 7, true, NO_SUBTYPE, STR_MULTI_OPTION}, +// Protocol as defined in pulses\modules_constants.h, number of sub_protocols - 1, Failsafe supported, Disable channel mapping supported, Subtype string, Option type + {MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr}, + {MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ}, + {MODULE_SUBTYPE_MULTI_FRSKY, 5, false, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_HISKY, 1, false, true, STR_SUBTYPE_HISKY, nullptr}, + {MODULE_SUBTYPE_MULTI_V2X2, 1, false, false, STR_SUBTYPE_V2X2, nullptr}, + {MODULE_SUBTYPE_MULTI_DSM2, 3, false, true, STR_SUBTYPE_DSM, STR_MULTI_MAX_THROW}, + {MODULE_SUBTYPE_MULTI_DEVO, 4, false, true, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID}, + {MODULE_SUBTYPE_MULTI_YD717, 4, false, false, STR_SUBTYPE_YD717, nullptr}, + {MODULE_SUBTYPE_MULTI_KN, 1, false, false, STR_SUBTYPE_KN, nullptr}, + {MODULE_SUBTYPE_MULTI_SYMAX, 1, false, false, STR_SUBTYPE_SYMAX, nullptr}, + {MODULE_SUBTYPE_MULTI_SLT, 4, false, true, STR_SUBTYPE_SLT, nullptr}, + {MODULE_SUBTYPE_MULTI_CX10, 6, false, false, STR_SUBTYPE_CX10, nullptr}, + {MODULE_SUBTYPE_MULTI_CG023, 1, false, false, STR_SUBTYPE_CG023, nullptr}, + {MODULE_SUBTYPE_MULTI_BAYANG, 4, false, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY}, + {MODULE_SUBTYPE_MULTI_MT99XX, 4, false, false, STR_SUBTYPE_MT99, nullptr}, + {MODULE_SUBTYPE_MULTI_MJXQ, 6, false, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_FY326, 1, false, false, STR_SUBTYPE_FY326, nullptr}, + {MODULE_SUBTYPE_MULTI_SFHSS, 0, true, true, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_HONTAI, 3, false, false, STR_SUBTYPE_HONTAI, nullptr}, + {MODULE_SUBTYPE_MULTI_OLRS, 0, false, false, NO_SUBTYPE, STR_RF_POWER}, + {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, + {MODULE_SUBTYPE_MULTI_Q2X2, 2, false, false, STR_SUBTYPE_Q2X2, nullptr}, + {MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, true, STR_SUBTYPE_WK2x01, nullptr}, + {MODULE_SUBTYPE_MULTI_Q303, 3, false, false, STR_SUBTYPE_Q303, nullptr}, + {MODULE_SUBTYPE_MULTI_CABELL, 7, false, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION}, + {MODULE_SUBTYPE_MULTI_H83D, 3, false, false, STR_SUBTYPE_H83D, nullptr}, + {MODULE_SUBTYPE_MULTI_CORONA, 2, false, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_HITEC, 2, false, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, false, STR_SUBTYPE_BUGS_MINI, nullptr}, + {MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, false, STR_SUBTYPE_TRAXXAS, nullptr}, + {MODULE_SUBTYPE_MULTI_E01X, 2, false, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION}, + {MODULE_SUBTYPE_MULTI_GD00X, 1, false, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_KF606, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_REDPINE, 1, false, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, false, STR_SUBTYPE_POTENSIC, nullptr}, + {MODULE_SUBTYPE_MULTI_ZSX, 0, false, false, STR_SUBTYPE_ZSX, nullptr}, + {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, false, STR_SUBTYPE_FLYZONE, nullptr}, + {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_ESky, 0, false, true, NO_SUBTYPE, nullptr}, + {MODULE_SUBTYPE_MULTI_J6PRO, 0, false, true, NO_SUBTYPE, nullptr}, + {MODULE_SUBTYPE_MULTI_ESKY150, 1, false, false, STR_SUBTYPE_ESKY150, nullptr}, + {MODULE_SUBTYPE_MULTI_FX816, 0, false, false, STR_SUBTYPE_FX816, nullptr}, + {MODULE_SUBTYPE_MULTI_HOTT, 0, true, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MM_RF_CUSTOM_SELECTED, 7, true, true, NO_SUBTYPE, STR_MULTI_OPTION}, // Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff) - {0xfe, 0, false, NO_SUBTYPE, nullptr} + {0xfe, 0, false, true, NO_SUBTYPE, nullptr} }; #undef NO_SUBTYPE diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 7845fe8d6..cdcbd9419 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -159,7 +159,7 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx) if (!IS_MODULE_ENABLED(moduleIdx)) return HIDDEN_ROW; - if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2)) + if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol() != MODULE_SUBTYPE_MULTI_DSM2)) return 0; else return 1; @@ -167,40 +167,97 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx) #if defined(MULTIMODULE) -// When using packed, the pointer in here end up not being aligned, which clang and gcc complain about -// Keep the order of the fields that the so that the size stays small -struct mm_protocol_definition { - uint8_t protocol; - uint8_t maxSubtype; - bool failsafe; - const char *subTypeString; - const char *optionsstr; -}; -const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); -#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW, -#define MULTIMODULE_MODULE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, -#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t)2 : (uint8_t)1 +inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) + return HIDDEN_ROW; + + uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol(); + if (protocol < MODULE_SUBTYPE_MULTI_LAST) { + const mm_protocol_definition * pdef = getMultiProtocolDefinition(protocol); + if (pdef->disable_ch_mapping) + return 0; + } + + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.supportsDisableMapping() && status.isValid()) { + return 0; + } + + return HIDDEN_ROW; +} inline bool isMultiProtocolSelectable(int protocol) { return protocol != MODULE_SUBTYPE_MULTI_SCANNER; } +inline bool MULTIMODULE_PROTOCOL_KNOWN(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) { + return false; + } + + if (g_model.moduleData[moduleIdx].getMultiProtocol() < MODULE_SUBTYPE_MULTI_LAST) { + return true; + } + + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.isValid()) { + return status.protocolValid(); + } + + return false; +} + inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx) { - return getMultiProtocolDefinition(moduleIdx)->maxSubtype > 0; + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) { + return true; + } + + if (status.isValid()) { + return status.protocolSubNbr > 0; + } + else + { + if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) + return true; + else + return getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol())->maxSubtype > 0; + } } + inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx) { #if LCD_W < 212 - return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 1 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 0 : HIDDEN_ROW); + return (MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW); #else - return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 2 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 1 : 0); + return (MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t) 1 : 0); #endif } + +inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) + return false; + + uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol(); + if (protocol < MODULE_SUBTYPE_MULTI_LAST) { + return getMultiProtocolDefinition(protocol)->optionsstr != nullptr; + } + + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + return status.optionDisp; +} + +#define MULTIMODULE_MODULE_ROWS(moduleIdx) MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP +#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW, +#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 : MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t)2 : (uint8_t)1 #define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW, -#define MULTIMODULE_HASOPTIONS(moduleIdx) (getMultiProtocolDefinition(moduleIdx)->optionsstr != nullptr) -#define MULTIMODULE_OPTIONS_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) && MULTIMODULE_HASOPTIONS(g_model.moduleData[moduleIdx].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW +#define MULTIMODULE_OPTIONS_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) && MULTIMODULE_HASOPTIONS(moduleIdx)) ? (uint8_t) 0: HIDDEN_ROW #else #define MULTIMODULE_STATUS_ROWS(moduleIdx) @@ -212,7 +269,7 @@ inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx) #define FAILSAFE_ROWS(moduleIdx) isModuleFailsafeAvailable(moduleIdx) ? (g_model.moduleData[moduleIdx].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW #define MODULE_OPTION_ROW(moduleIdx) (isModuleR9MNonAccess(moduleIdx) || isModuleSBUS(moduleIdx) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW(moduleIdx)) -#define MODULE_POWER_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) || isModuleR9MNonAccess(moduleIdx)) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW +#define MODULE_POWER_ROW(moduleIdx) (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) || isModuleR9MNonAccess(moduleIdx)) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); diff --git a/radio/src/io/bootloader_flash.cpp b/radio/src/io/bootloader_flash.cpp index 15e7aec99..0bbe87b42 100644 --- a/radio/src/io/bootloader_flash.cpp +++ b/radio/src/io/bootloader_flash.cpp @@ -27,7 +27,7 @@ bool isBootloader(const char * filename) uint8_t buffer[1024]; UINT count; - if (f_read(&file, buffer, 1024, &count) != FR_OK || count != 1024) { + if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK || count != sizeof(buffer)) { return false; } @@ -47,18 +47,18 @@ void bootloaderFlash(const char * filename) unlockFlash(); } - for (int i=0; i { public: bool getFrame(uint8_t * frame) { - while (1) { + while (true) { if (isEmpty()) { return false; } diff --git a/radio/src/io/multi_firmware_update.cpp b/radio/src/io/multi_firmware_update.cpp index 22a3b42fb..bd8020cef 100644 --- a/radio/src/io/multi_firmware_update.cpp +++ b/radio/src/io/multi_firmware_update.cpp @@ -33,20 +33,21 @@ class MultiFirmwareUpdateDriver const char* flashFirmware(FIL* file, const char* label) const; protected: - virtual void init() const = 0; + virtual void moduleOn() const = 0; + virtual void init(bool inverted) const = 0; virtual bool getByte(uint8_t& byte) const = 0; virtual void sendByte(uint8_t byte) const = 0; virtual void clear() const = 0; - virtual void deinit() const {} + virtual void deinit(bool inverted) const {} private: bool getRxByte(uint8_t& byte) const; bool checkRxByte(uint8_t byte) const; - const char * waitForInitialSync() const; + const char * waitForInitialSync(bool& inverted) const; const char * getDeviceSignature(uint8_t* signature) const; const char * loadAddress(uint32_t offset) const; const char * progPage(uint8_t* buffer, uint16_t size) const; - void leaveProgMode() const; + void leaveProgMode(bool inverted) const; }; #if defined(INTERNAL_MODULE_MULTI) @@ -57,9 +58,13 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver MultiInternalUpdateDriver() {} protected: - void init() const override + void moduleOn() const override { INTERNAL_MODULE_ON(); + } + + void init(bool inverted) const override + { intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); } @@ -78,7 +83,7 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver intmoduleFifo.clear(); } - void deinit() const override + void deinit(bool inverted) const override { clear(); } @@ -88,13 +93,18 @@ static const MultiInternalUpdateDriver multiInternalUpdateDriver; #endif -class MultiExternalSoftSerialUpdateDriver: public MultiFirmwareUpdateDriver +class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver { public: - MultiExternalSoftSerialUpdateDriver() {} + MultiExternalUpdateDriver() {} protected: - void init() const override + void moduleOn() const override + { + EXTERNAL_MODULE_ON(); + } + + void init(bool inverted) const override { #if !defined(EXTMODULE_USART) GPIO_InitTypeDef GPIO_InitStructure; @@ -106,8 +116,10 @@ class MultiExternalSoftSerialUpdateDriver: public MultiFirmwareUpdateDriver GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); #endif - EXTERNAL_MODULE_ON(); - telemetryPortInvertedInit(57600); + if (inverted) + telemetryPortInvertedInit(57600); + else + telemetryPortInit(57600, TELEMETRY_SERIAL_DEFAULT); } bool getByte(uint8_t& byte) const override @@ -125,14 +137,18 @@ class MultiExternalSoftSerialUpdateDriver: public MultiFirmwareUpdateDriver telemetryClearFifo(); } - void deinit() const override + void deinit(bool inverted) const override { - telemetryPortInvertedInit(0); + if (inverted) + telemetryPortInvertedInit(0); + else + telemetryPortInit(0, 0); + clear(); } }; -static const MultiExternalSoftSerialUpdateDriver multiExternalSoftSerialUpdateDriver; +static const MultiExternalUpdateDriver multiExternalUpdateDriver; bool MultiFirmwareUpdateDriver::getRxByte(uint8_t& byte) const { @@ -159,19 +175,27 @@ bool MultiFirmwareUpdateDriver::checkRxByte(uint8_t byte) const return getRxByte(rxchar) ? rxchar == byte : false; } -const char * MultiFirmwareUpdateDriver::waitForInitialSync() const +const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool& inverted) const { uint8_t byte; - int retries = 1000; + int retries = 200; clear(); do { + + // Invert at half-time + if (retries == 100) { + deinit(inverted); + inverted = !inverted; + init(inverted); + } + // Send sync request sendByte(STK_GET_SYNC); sendByte(CRC_EOP); getRxByte(byte); - wdt_reset(); + WDG_RESET(); } while((byte != STK_INSYNC) && --retries); @@ -195,6 +219,7 @@ const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t* signature) c // Read signature sendByte(STK_READ_SIGN); sendByte(CRC_EOP); + clear(); if (!checkRxByte(STK_INSYNC)) return "NoSync"; @@ -245,7 +270,7 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) uint8_t retries = 4; do { getRxByte(byte); - wdt_reset(); + WDG_RESET(); } while(!byte && --retries); if (!retries || (byte != STK_OK)) @@ -254,35 +279,38 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) return nullptr; } -void MultiFirmwareUpdateDriver::leaveProgMode() const +void MultiFirmwareUpdateDriver::leaveProgMode(bool inverted) const { sendByte(STK_LEAVE_PROGMODE); sendByte(CRC_EOP); // eat last sync byte checkRxByte(STK_INSYNC); - deinit(); + deinit(inverted); } const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* label) const { const char* result = nullptr; - init(); + moduleOn(); + + bool inverted = true; //false; // true + init(inverted); /* wait 500ms for power on */ - watchdogSuspend(500); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(500); - result = waitForInitialSync(); + result = waitForInitialSync(inverted); if (result) { - leaveProgMode(); + leaveProgMode(inverted); return result; } unsigned char signature[4]; // 3 bytes signature + STK_OK result = getDeviceSignature(signature); if (result) { - leaveProgMode(); + leaveProgMode(inverted); return result; } @@ -291,7 +319,7 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab uint32_t writeOffset = 0; if (signature[0] != 0x1E) { - leaveProgMode(); + leaveProgMode(inverted); return "Wrong signature"; } @@ -341,7 +369,7 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab #endif } - leaveProgMode(); + leaveProgMode(inverted); return result; } @@ -492,7 +520,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) } } - const MultiFirmwareUpdateDriver* driver = &multiExternalSoftSerialUpdateDriver; + const MultiFirmwareUpdateDriver* driver = &multiExternalUpdateDriver; #if defined(INTERNAL_MODULE_MULTI) if (moduleIdx == INTERNAL_MODULE) driver = &multiInternalUpdateDriver; @@ -517,7 +545,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) #endif /* wait 2s off */ - watchdogSuspend(2000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(2000); const char * result = driver->flashFirmware(&file, getBasename(filename)); @@ -534,12 +562,14 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS); } +#if defined(HARDWARE_INTERNAL_MODULE) INTERNAL_MODULE_OFF(); +#endif EXTERNAL_MODULE_OFF(); SPORT_UPDATE_POWER_OFF(); /* wait 2s off */ - watchdogSuspend(2000); + watchdogSuspend(500 /*5s*/); RTOS_WAIT_MS(2000); // reset telemetry protocol diff --git a/radio/src/io/multi_firmware_update.h b/radio/src/io/multi_firmware_update.h index 6713d5cfb..a4ad7156f 100644 --- a/radio/src/io/multi_firmware_update.h +++ b/radio/src/io/multi_firmware_update.h @@ -76,22 +76,26 @@ class MultiFirmwareInformation { bool isMultiExternalFirmware() const { - return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == true && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY); + return (telemetryInversion == true && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY); } const char * readMultiFirmwareInformation(const char * filename); const char * readMultiFirmwareInformation(FIL * file); private: - uint8_t boardType; - uint8_t optibootSupport; - uint8_t bootloaderCheck; - uint8_t telemetryType; - uint8_t telemetryInversion; + bool optibootSupport:1; + bool telemetryInversion:1; + bool bootloaderCheck:1; + uint8_t boardType:2; + uint8_t telemetryType:2; + bool spare:1; + +/* For future use uint8_t firmwareVersionMajor; uint8_t firmwareVersionMinor; uint8_t firmwareVersionRevision; uint8_t firmwareVersionSubRevision; +*/ const char * readV1Signature(const char * buffer); const char * readV2Signature(const char * buffer); diff --git a/radio/src/keys.cpp b/radio/src/keys.cpp index d0aaa4690..75025c619 100644 --- a/radio/src/keys.cpp +++ b/radio/src/keys.cpp @@ -186,7 +186,7 @@ bool waitKeysReleased() #endif while (keyDown()) { - wdt_reset(); + WDG_RESET(); #if !defined(BOOT) if ((get_tmr10ms() - start) >= 300) { // wait no more than 3 seconds diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index e1cfd4999..7ee2175b3 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -24,6 +24,7 @@ #include "stamp.h" #include "lua_api.h" #include "telemetry/frsky.h" +#include "telemetry/multi.h" #if defined(PCBX12S) #include "lua/lua_exports_x12s.inc" // this line must be after lua headers @@ -442,7 +443,7 @@ When called without parameters, it will only return the status of the output buf static int luaSportTelemetryPush(lua_State * L) { - if (telemetryProtocol != PROTOCOL_TELEMETRY_FRSKY_SPORT) { + if (!IS_FRSKY_SPORT_PROTOCOL()) { lua_pushboolean(L, false); return 1; } @@ -1506,6 +1507,40 @@ static int luaResetGlobalTimer(lua_State * L) return 0; } +/*luadoc +@function multiBuffer(address[,value]) + +This function reads/writes the Multi protocol buffer to interact with a protocol². + +@param address to read/write in the buffer +@param (optional): value to write in the buffer + +@retval buffer value (number) + +@status current Introduced in 2.3.2 +*/ +#if defined(MULTIMODULE) +uint8_t * Multi_Buffer = nullptr; + +static int luaMultiBuffer(lua_State * L) +{ + uint8_t address = luaL_checkunsigned(L, 1); + if (!Multi_Buffer) + Multi_Buffer = (uint8_t *) malloc(MULTI_BUFFER_SIZE); + + if (!Multi_Buffer || address >= MULTI_BUFFER_SIZE) { + lua_pushinteger(L, 0); + return 0; + } + uint16_t value = luaL_optunsigned(L, 2, 0x100); + if (value < 0x100) { + Multi_Buffer[address] = value; + } + lua_pushinteger(L, Multi_Buffer[address]); + return 1; +} +#endif + /*luadoc @function serialWrite(str) @param str (string) String to be written to the serial port. @@ -1586,6 +1621,9 @@ const luaL_Reg opentxLib[] = { #if defined(CROSSFIRE) { "crossfireTelemetryPop", luaCrossfireTelemetryPop }, { "crossfireTelemetryPush", luaCrossfireTelemetryPush }, +#endif +#if defined(MULTIMODULE) + { "multiBuffer", luaMultiBuffer }, #endif { "serialWrite", luaSerialWrite }, { nullptr, nullptr } /* sentinel */ diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 0a8711643..787c48c5c 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -174,8 +174,8 @@ void checkEeprom() #else void checkEeprom() { -#if defined(RAMBACKUP) - if (TIME_TO_RAMBACKUP()) { +#if defined(RTC_BACKUP_RAM) && !defined(SIMU) + if (TIME_TO_BACKUP_RAM()) { rambackupWrite(); rambackupDirtyMsk = 0; } @@ -296,6 +296,8 @@ void guiMain(event_t evt) lcdRefreshWait(); // WARNING: make sure no code above this line does any change to the LCD display buffer! #endif + bool screenshotRequested = (mainRequestFlags & (1u << REQUEST_SCREENSHOT)); + #if defined(LIBOPENUI) mainWindow.run(); #else @@ -305,7 +307,6 @@ void guiMain(event_t evt) // normal GUI from menus const char * warn = warningText; uint8_t menu = popupMenuItemsCount; - static bool popupDisplayed = false; if (warn || menu) { if (popupDisplayed == false) { @@ -315,7 +316,7 @@ void guiMain(event_t evt) lcdStoreBackupBuffer(); TIME_MEASURE_STOP(storebackup); } - if (popupDisplayed == false || evt) { + if (popupDisplayed == false || evt || screenshotRequested) { popupDisplayed = lcdRestoreBackupBuffer(); if (warn) { DISPLAY_WARNING(evt); @@ -368,6 +369,11 @@ void guiMain(event_t evt) DEBUG_TIMER_STOP(debugTimerMenus); } + if (screenshotRequested) { + writeScreenshot(); + mainRequestFlags &= ~(1u << REQUEST_SCREENSHOT); + } + if (refreshNeeded) { DEBUG_TIMER_START(debugTimerLcdRefresh); lcdRefresh(); @@ -376,7 +382,6 @@ void guiMain(event_t evt) #endif } #elif defined(GUI) - void handleGui(event_t event) { // if Lua standalone, run it and don't clear the screen (Lua will do it) // else if Lua telemetry view, run it and don't clear the screen @@ -474,6 +479,11 @@ void guiMain(event_t evt) } lcdRefresh(); + + if (mainRequestFlags & (1 << REQUEST_SCREENSHOT)) { + writeScreenshot(); + mainRequestFlags &= ~(1 << REQUEST_SCREENSHOT); + } } #endif @@ -507,7 +517,7 @@ void perMain() event_t evt = getEvent(false); #endif -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) if (globalData.unexpectedShutdown) { drawFatalErrorScreen(STR_EMERGENCY_MODE); return; @@ -552,11 +562,6 @@ void perMain() DEBUG_TIMER_STOP(debugTimerGuiMain); #endif - if (mainRequestFlags & (1 << REQUEST_SCREENSHOT)) { - writeScreenshot(); - mainRequestFlags &= ~(1 << REQUEST_SCREENSHOT); - } - #if defined(PCBX9E) && !defined(SIMU) toplcdRefreshStart(); setTopFirstTimer(getValue(MIXSRC_FIRST_TIMER+g_model.toplcdTimer)); diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 052031dee..2b72c57e8 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -228,7 +228,7 @@ int16_t applyLimits(uint8_t channel, int32_t value) #endif if (isFunctionActive(FUNCTION_TRAINER_CHANNELS) && IS_TRAINER_INPUT_VALID()) { - return ppmInput[channel]; + return ppmInput[channel] * 2; } LimitData * lim = limitAddress(channel); @@ -366,22 +366,22 @@ getvalue_t getValue(mixsrc_t i) #endif else if (i <= MIXSRC_LAST_LOGICAL_SWITCH) { - return getSwitch(SWSRC_FIRST_LOGICAL_SWITCH+i-MIXSRC_FIRST_LOGICAL_SWITCH) ? 1024 : -1024; + return getSwitch(SWSRC_FIRST_LOGICAL_SWITCH + i - MIXSRC_FIRST_LOGICAL_SWITCH) ? 1024 : -1024; } else if (i <= MIXSRC_LAST_TRAINER) { - int16_t x = ppmInput[i-MIXSRC_FIRST_TRAINER]; - if (i MODULE_SUBTYPE_MULTI_LAST) { + if (status.isValid()) + return (status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1); + else + return 7; + } + else { + return max((uint8_t )(status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1), pdef->maxSubtype); + } +} + inline bool isModuleMultimodule(uint8_t idx) { return g_model.moduleData[idx].type == MODULE_TYPE_MULTIMODULE; @@ -39,7 +76,7 @@ inline bool isModuleMultimodule(uint8_t idx) inline bool isModuleMultimoduleDSM2(uint8_t idx) { - return isModuleMultimodule(idx) && g_model.moduleData[idx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2; + return isModuleMultimodule(idx) && g_model.moduleData[idx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2; } #else inline bool isModuleMultimodule(uint8_t) @@ -341,6 +378,8 @@ inline int8_t sentModuleChannels(uint8_t idx) return CROSSFIRE_CHANNELS_COUNT; else if (isModuleMultimodule(idx) && !isModuleMultimoduleDSM2(idx)) return 16; + else if (isModuleSBUS(idx)) + return 16; else return 8 + g_model.moduleData[idx].channelsCount; } @@ -405,8 +444,14 @@ inline bool isModuleFailsafeAvailable(uint8_t moduleIdx) #if defined(MULTIMODULE) if (isModuleMultimodule(moduleIdx)){ - MultiModuleStatus& status = getMultiModuleStatus(moduleIdx); - return status.isValid() && status.supportsFailsafe(); + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.isValid()) { + return status.supportsFailsafe(); + } + else { + const mm_protocol_definition * pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol()); + return pdef->failsafe; + } } #endif @@ -428,7 +473,15 @@ inline uint8_t getMaxRxNum(uint8_t idx) #if defined(MULTIMODULE) if (isModuleMultimodule(idx)) - return g_model.moduleData[idx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_OLRS ? 4 : 15; + { + switch (g_model.moduleData[idx].getMultiProtocol()) { + case MODULE_SUBTYPE_MULTI_OLRS: + return 4; + case MODULE_SUBTYPE_MULTI_BUGS: + case MODULE_SUBTYPE_MULTI_BUGS_MINI: + return 15; + } + } #endif return 63; @@ -537,4 +590,24 @@ inline void setModuleType(uint8_t moduleIdx, uint8_t moduleType) extern bool isExternalAntennaEnabled(); +#if defined(MULTIMODULE) +inline void resetMultiProtocolsOptions(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) + return; + + // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { + g_model.moduleData[moduleIdx].multi.autoBindMode = 1; + } + else { + g_model.moduleData[moduleIdx].multi.autoBindMode = 0; + } + g_model.moduleData[moduleIdx].multi.optionValue = 0; + g_model.moduleData[moduleIdx].multi.disableTelemetry = 0; + g_model.moduleData[moduleIdx].multi.disableMapping = 0; + g_model.moduleData[moduleIdx].multi.lowPowerMode = 0; +} +#endif + #endif // _MODULES_HELPERS_H_ diff --git a/radio/src/pulses/multi.cpp b/radio/src/pulses/multi.cpp index 7c686546f..b49c61b7d 100644 --- a/radio/src/pulses/multi.cpp +++ b/radio/src/pulses/multi.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "multi.h" // for the MULTI protocol definition // see https://github.com/pascallanger/DIY-Multiprotocol-TX-Module @@ -31,9 +32,59 @@ #define MULTI_CHANS 16 #define MULTI_CHAN_BITS 11 -static void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe); +#define MULTI_NORMAL 0x00 +#define MULTI_FAILSAFE 0x01 +#define MULTI_DATA 0x02 +static void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe); void sendChannels(uint8_t moduleIdx); +#if defined(LUA) +static void sendSport(uint8_t moduleIdx); +static void sendHott(uint8_t moduleIdx); +#endif + +void multiPatchCustom(uint8_t moduleIdx) +{ + if (g_model.moduleData[moduleIdx].multi.customProto) { + uint8_t type = g_model.moduleData[moduleIdx].getMultiProtocol() - 1; // custom where starting at 1, otx list at 0 + int subtype = g_model.moduleData[moduleIdx].subType; + + g_model.moduleData[moduleIdx].multi.customProto = 0; + + if (type == 2) { // multi PROTO_FRSKYD + g_model.moduleData[moduleIdx].subType = 1; // D8 + return; + } + else if (type == 14) { // multi PROTO_FRSKYX + g_model.moduleData[moduleIdx].setMultiProtocol(2); + switch (subtype) { + case 0: //D16-16 + g_model.moduleData[moduleIdx].subType = 0; + break; + case 1: //D16-8 + g_model.moduleData[moduleIdx].subType = 2; + break; + case 2: //EU-16 + g_model.moduleData[moduleIdx].subType = 4; + break; + case 3: //EU-8 + g_model.moduleData[moduleIdx].subType = 5; + break; + } + return; + } + else if (type == 24) { // multi PROTO_FRSKYV + g_model.moduleData[moduleIdx].setMultiProtocol(2); + g_model.moduleData[moduleIdx].subType = 3; + return; + } + if (type > 14) + type -= 1; + if (type > 24) + type -= 1; + g_model.moduleData[moduleIdx].setMultiProtocol(type); + } +} static void sendMulti(uint8_t moduleIdx, uint8_t b) { @@ -46,22 +97,6 @@ static void sendMulti(uint8_t moduleIdx, uint8_t b) sendByteSbus(b); } -static void sendSetupFrame(uint8_t moduleIdx) -{ - // Old multi firmware will mark config messsages as invalid frame and throw them away - sendMulti(moduleIdx, 'M'); - sendMulti(moduleIdx, 'P'); - sendMulti(moduleIdx, 0x80); // Module Configuration - sendMulti(moduleIdx, 1); // 1 byte data - uint8_t config = 0x01 | 0x02; // inversion + multi_telemetry -#if !defined(PPM_PIN_SERIAL) - // TODO why PPM_PIN_SERIAL would change MULTI protocol? - config |= 0x04; // input synchronsisation -#endif - - sendMulti(moduleIdx, config); -} - static void sendFailsafeChannels(uint8_t moduleIdx) { uint32_t bits = 0; @@ -95,21 +130,64 @@ static void sendFailsafeChannels(uint8_t moduleIdx) void setupPulsesMulti(uint8_t moduleIdx) { static int counter[2] = {0,0}; //TODO + static uint8_t invert[2] = {0x00, //internal +#if defined(PCBTARANIS) || defined(PCBHORUS) + 0x08 //external +#else + 0x00 //external +#endif + }; + uint8_t type=MULTI_NORMAL; + + // Failsafe packets + if (counter[moduleIdx] % 1000 == 0 && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_RECEIVER) { + type|=MULTI_FAILSAFE; + } + + // Invert telemetry if needed + if (invert[moduleIdx] & 0x80 && !g_model.moduleData[moduleIdx].multi.disableTelemetry) { + if (getMultiModuleStatus(moduleIdx).isValid()) { + invert[moduleIdx] &= 0x08; // Telemetry received, stop searching + } + else if (counter[moduleIdx] % 100 == 0) { + invert[moduleIdx] ^= 0x08; // Try inverting telemetry + } + } - // Every 1000 cycles (=9s) send a config packet that configures the multimodule (inversion, telemetry type) counter[moduleIdx]++; - if (counter[moduleIdx] % 1000 == 500) { - sendSetupFrame(moduleIdx); - } - else if (counter[moduleIdx] % 1000 == 0 && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_RECEIVER) { - sendFrameProtocolHeader(moduleIdx, true); + + // Send header + sendFrameProtocolHeader(moduleIdx, type&MULTI_FAILSAFE); + + // Send channels + if (type & MULTI_FAILSAFE) sendFailsafeChannels(moduleIdx); - } - else { - // Normal Frame - sendFrameProtocolHeader(moduleIdx, false); + else sendChannels(moduleIdx); + + // Multi V1.3.X.X -> Send byte 26, Protocol (bits 7 & 6), RX_Num (bits 5 & 4), invert, not used, disable telemetry, disable mapping + sendMulti(moduleIdx, (uint8_t) (((g_model.moduleData[moduleIdx].getMultiProtocol()+3)&0xC0) + | (g_model.header.modelId[moduleIdx] & 0x30) + | (invert[moduleIdx] & 0x08) + //| 0x04 // Future use + | (g_model.moduleData[moduleIdx].multi.disableTelemetry << 1) + | g_model.moduleData[moduleIdx].multi.disableMapping)); + + // Multi V1.3.X.X -> Send protocol additional data: max 9 bytes +#if defined(LUA) + if (getMultiModuleStatus(moduleIdx).isValid()) { + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.minor >= 3 && !(status.flags & 0x80)) { //Version 1.3.x.x or more and Buffer not full + // SPort send + if (IS_D16_MULTI(moduleIdx) && outputTelemetryBuffer.destination == TELEMETRY_ENDPOINT_SPORT && outputTelemetryBuffer.size) { + sendSport(moduleIdx); //8 bytes of additional data + } + else if (IS_HOTT_MULTI(moduleIdx)) { + sendHott(moduleIdx); //1 byte of additional data + } + } } + #endif } void setupPulsesMultiExternalModule() @@ -166,7 +244,7 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) {// byte 1+2, protocol information // Our enumeration starts at 0 - int type = g_model.moduleData[moduleIdx].getMultiProtocol(false) + 1; + int type = g_model.moduleData[moduleIdx].getMultiProtocol() + 1; int subtype = g_model.moduleData[moduleIdx].subType; int8_t optionValue = g_model.moduleData[moduleIdx].multi.optionValue; @@ -186,16 +264,18 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) protoByte |= MULTI_SEND_RANGECHECK; // rfProtocol - if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) { + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { // Autobinding should always be done in DSMX 11ms if (g_model.moduleData[moduleIdx].multi.autoBindMode && moduleState[moduleIdx].mode == MODULE_MODE_BIND) subtype = MM_RF_DSM2_SUBTYPE_AUTO; // Multi module in DSM mode wants the number of channels to be used as option value - optionValue = sentModuleChannels(moduleIdx); - - } + if (optionValue) + optionValue = 0x80 | sentModuleChannels(moduleIdx); // Max throw + else + optionValue = sentModuleChannels(moduleIdx); +} // 15 for Multimodule is FrskyX or D16 which we map as a subprotocol of 3 (FrSky) // all protos > frskyx are therefore also off by one @@ -206,7 +286,7 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) if (type >= 25) type = type + 1; - if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_FRSKY) { + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) { if (subtype == MM_RF_FRSKY_SUBTYPE_D8) { //D8 type = 3; @@ -230,28 +310,27 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) // Set the highest bit of option byte in AFHDS2A protocol to instruct MULTI to passthrough telemetry bytes instead // of sending Frsky D telemetry - if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) optionValue = optionValue | 0x80; // For custom protocol send unmodified type byte - if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MM_RF_CUSTOM_SELECTED) - type = g_model.moduleData[moduleIdx].getMultiProtocol(false); + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MM_RF_CUSTOM_SELECTED) + type = g_model.moduleData[moduleIdx].getMultiProtocol(); - uint8_t headerByte = 0x54; + uint8_t headerByte = 0x55; + // header, byte 0, 0x55 for proto 0-31, 0x54 for proto 32-63 + if (type & 0x20) + headerByte &= 0xFE; + if (failsafe) - headerByte = 0x56; - - // header, byte 0, 0x55 for proto 0-31 0x54 for 32-63 - if (type <= 31) - sendMulti(moduleIdx, headerByte+1); - else - sendMulti(moduleIdx, headerByte); + headerByte |= 0x02; + sendMulti(moduleIdx, headerByte); // protocol byte protoByte |= (type & 0x1f); - if (g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2) + if (g_model.moduleData[moduleIdx].getMultiProtocol() != MODULE_SUBTYPE_MULTI_DSM2) protoByte |= (g_model.moduleData[moduleIdx].multi.autoBindMode << 6); sendMulti(moduleIdx, protoByte); @@ -265,3 +344,32 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) // byte 3 sendMulti(moduleIdx, (uint8_t) optionValue); } + +#if defined(LUA) +void sendSport(uint8_t moduleIdx) +{ + // example: B7 30 30 0C 80 00 00 00 13 + uint8_t j=0; + + // unstuff and remove crc + for (uint8_t i = 0; i < outputTelemetryBuffer.size - 1 && j < 8; i++, j++) { + if (outputTelemetryBuffer.data[i] == BYTE_STUFF) { + i++; + sendMulti(moduleIdx, outputTelemetryBuffer.data[i] ^ STUFF_MASK); + } + else { + sendMulti(moduleIdx, outputTelemetryBuffer.data[i]); + } + } + + outputTelemetryBuffer.reset(); // empty buffer +} + +void sendHott(uint8_t moduleIdx) +{ + if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0 && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) { + // HoTT Lua script is running + sendMulti(moduleIdx, Multi_Buffer[5]); + } +} +#endif diff --git a/radio/src/pulses/multi.h b/radio/src/pulses/multi.h index d3f088b7d..a19e526eb 100644 --- a/radio/src/pulses/multi.h +++ b/radio/src/pulses/multi.h @@ -23,6 +23,8 @@ #include "pulses_common.h" +void multiPatchCustom(uint8_t moduleIdx); + class UartMultiPulses: public DataBuffer { public: diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index 63b43943f..21c4d7eee 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -307,6 +307,9 @@ static void enablePulsesInternalModule(uint8_t protocol) #if defined(PXX2) case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); +#if defined(HARDWARE_INTERNAL_MODULE) && defined(INTERNAL_MODULE_PXX2) && defined(ACCESS_LIB) + globalData.authenticationCount = 0; +#endif break; #endif diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 51929a336..e6920e9e4 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -148,7 +148,7 @@ class BindInformation { class OtaUpdateInformation: public BindInformation { public: - char filename[32+1]; + char filename[_MAX_LFN + 1]; uint32_t address; }; diff --git a/radio/src/pulses/pxx1.cpp b/radio/src/pulses/pxx1.cpp index abc250040..dec339ba3 100644 --- a/radio/src/pulses/pxx1.cpp +++ b/radio/src/pulses/pxx1.cpp @@ -22,7 +22,7 @@ #include "pulses/pxx1.h" template -uint8_t Pxx1Pulses::addFlag1(uint8_t module) +void Pxx1Pulses::addFlag1(uint8_t module, uint8_t sendFailsafe) { uint8_t flag1 = (g_model.moduleData[module].subType << 6); if (moduleState[module].mode == MODULE_MODE_BIND) { @@ -31,21 +31,10 @@ uint8_t Pxx1Pulses::addFlag1(uint8_t module) else if (moduleState[module].mode == MODULE_MODE_RANGECHECK) { flag1 |= PXX_SEND_RANGECHECK; } - else { - bool failsafeNeeded = g_model.moduleData[module].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[module].failsafeMode != FAILSAFE_RECEIVER; - if (moduleState[module].counter-- == 0) { - // counter is also used for knowing if the frame is odd / even - moduleState[module].counter = 1000; - if (failsafeNeeded) { - flag1 |= PXX_SEND_FAILSAFE; - } - } - if (failsafeNeeded && moduleState[module].counter == 0 && g_model.moduleData[module].channelsCount > 0) { - flag1 |= PXX_SEND_FAILSAFE; - } + else if (sendFailsafe && g_model.moduleData[module].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[module].failsafeMode != FAILSAFE_RECEIVER) { + flag1 |= PXX_SEND_FAILSAFE; } PxxTransport::addByte(flag1); - return flag1; } template @@ -72,6 +61,7 @@ void Pxx1Pulses::addExtraFlags(uint8_t module) if (module == EXTERNAL_MODULE && isSportLineUsedByInternalModule()) { extraFlags |= (1 << 5); } + PxxTransport::addByte(extraFlags); } @@ -146,7 +136,7 @@ void Pxx1Pulses::addChannels(uint8_t port, uint8_t sendFailsafe, u } template -void Pxx1Pulses::add8ChannelsFrame(uint8_t module, uint8_t sendUpperChannels) +void Pxx1Pulses::add8ChannelsFrame(uint8_t module, uint8_t sendUpperChannels, uint8_t sendFailsafe) { PxxTransport::initCrc(); @@ -157,13 +147,13 @@ void Pxx1Pulses::add8ChannelsFrame(uint8_t module, uint8_t sendUpp PxxTransport::addByte(g_model.header.modelId[module]); // Flag1 - uint8_t flag1 = addFlag1(module); + addFlag1(module, sendFailsafe); // Flag2 PxxTransport::addByte(0); // Channels - addChannels(module, flag1 & PXX_SEND_FAILSAFE, sendUpperChannels); + addChannels(module, sendFailsafe, sendUpperChannels); // Extra flags addExtraFlags(module); @@ -181,24 +171,42 @@ void Pxx1Pulses::add8ChannelsFrame(uint8_t module, uint8_t sendUpp template void Pxx1Pulses::setupFrame(uint8_t module) { + uint8_t sendUpperChannels = 0; + uint8_t sendFailsafe = 0; + PxxTransport::initFrame(PXX_PULSES_PERIOD); #if defined(PXX_FREQUENCY_HIGH) if (moduleState[module].protocol == PROTOCOL_CHANNELS_PXX1_SERIAL) { - add8ChannelsFrame(module, 0); + if (moduleState[module].counter-- == 0) { + sendFailsafe = 1; + moduleState[module].counter = 1000; + } + add8ChannelsFrame(module, 0, sendFailsafe); if (sentModuleChannels(module) > 8) { - add8ChannelsFrame(module, 8); + add8ChannelsFrame(module, 8, sendFailsafe); } return; } #endif - uint8_t sendUpperChannels = 0; if (moduleState[module].counter & 0x01) { sendUpperChannels = g_model.moduleData[module].channelsCount; + if (sendUpperChannels && moduleState[module].counter == 1) { + sendFailsafe = 1; + } + } + else { + if (moduleState[module].counter == 0) { + sendFailsafe = 1; + } } - add8ChannelsFrame(module, sendUpperChannels); + add8ChannelsFrame(module, sendUpperChannels, sendFailsafe); + + if (moduleState[module].counter-- == 0) { + moduleState[module].counter = 1000; + } } template class Pxx1Pulses >; diff --git a/radio/src/pulses/pxx1.h b/radio/src/pulses/pxx1.h index 80dde1d5a..d2f581580 100644 --- a/radio/src/pulses/pxx1.h +++ b/radio/src/pulses/pxx1.h @@ -163,10 +163,10 @@ class Pxx1Pulses: public PxxTransport PxxTransport::addByteWithoutCrc(Pxx1CrcMixin::crc); } - uint8_t addFlag1(uint8_t port); + void addFlag1(uint8_t port, uint8_t sendFailsafe); void addExtraFlags(uint8_t port); void addChannels(uint8_t port, uint8_t sendFailsafe, uint8_t sendUpperChannels); - void add8ChannelsFrame(uint8_t port, uint8_t sendUpperChannels); + void add8ChannelsFrame(uint8_t port, uint8_t sendUpperChannels, uint8_t sendFailsafe); }; typedef Pxx1Pulses UartPxx1Pulses; diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 44f70e8f0..bdf066a19 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -446,7 +446,7 @@ bool Pxx2OtaUpdate::waitStep(uint8_t step, uint8_t timeout) OtaUpdateInformation * destination = moduleState[module].otaUpdateInformation; uint8_t elapsed = 0; - watchdogSuspend(100); + watchdogSuspend(100 /*1s*/); while (step != destination->step) { if (elapsed++ > timeout) { @@ -535,7 +535,7 @@ void Pxx2OtaUpdate::flashFirmware(const char * filename, ProgressHandler progres { pausePulses(); - watchdogSuspend(100); + watchdogSuspend(100 /*1s*/); RTOS_WAIT_MS(100); moduleState[module].mode = MODULE_MODE_OTA_UPDATE; diff --git a/radio/src/storage/datacopy.cpp b/radio/src/storage/datacopy.cpp deleted file mode 100644 index f25cbf720..000000000 --- a/radio/src/storage/datacopy.cpp +++ /dev/null @@ -1,357 +0,0 @@ -//This file was auto-generated by generate_datacopy.py script on Fri May 10 15:48:58 2019. Do not edit this file! - - - -template -void copyCurveRef(A * dest, B * src) -{ - dest->type = src->type; - dest->value = src->value; -} - -template -void copyMixData(A * dest, B * src) -{ - dest->weight = src->weight; - dest->destCh = src->destCh; - dest->srcRaw = src->srcRaw; - dest->carryTrim = src->carryTrim; - dest->mixWarn = src->mixWarn; - dest->mltpx = src->mltpx; - dest->spare = src->spare; - dest->offset = src->offset; - dest->swtch = src->swtch; - dest->flightModes = src->flightModes; - copyCurveRef(&dest->curve, &src->curve); - dest->delayUp = src->delayUp; - dest->delayDown = src->delayDown; - dest->speedUp = src->speedUp; - dest->speedDown = src->speedDown; -} - -template -void copyExpoData(A * dest, B * src) -{ - dest->mode = src->mode; - dest->scale = src->scale; - dest->srcRaw = src->srcRaw; - dest->carryTrim = src->carryTrim; - dest->chn = src->chn; - dest->swtch = src->swtch; - dest->flightModes = src->flightModes; - dest->weight = src->weight; - dest->spare = src->spare; - dest->offset = src->offset; - copyCurveRef(&dest->curve, &src->curve); -} - -template -void copyLimitData(A * dest, B * src) -{ - dest->min = src->min; - dest->max = src->max; - dest->ppmCenter = src->ppmCenter; - dest->offset = src->offset; - dest->symetrical = src->symetrical; - dest->revert = src->revert; - dest->spare = src->spare; - dest->curve = src->curve; -} - -template -void copyLogicalSwitchData(A * dest, B * src) -{ - dest->func = src->func; - dest->v1 = src->v1; - dest->v3 = src->v3; - dest->andsw = src->andsw; - dest->andswtype = src->andswtype; - dest->spare = src->spare; - dest->v2 = src->v2; - dest->delay = src->delay; - dest->duration = src->duration; -} - -template -void copyCustomFunctionData(A * dest, B * src) -{ - dest->swtch = src->swtch; - dest->func = src->func; - copyCustomFunctionData_all(&dest->all, &src->all); - dest->active = src->active; -} - -template -void copytrim_t(A * dest, B * src) -{ - dest->value = src->value; - dest->mode = src->mode; -} - -template -void copyFlightModeData(A * dest, B * src) -{ - for (int i=0; i<6; i++) { - copytrim_t(&dest->trim[i], &src->trim[i]); - } - dest->swtch = src->swtch; - dest->spare = src->spare; - dest->fadeIn = src->fadeIn; - dest->fadeOut = src->fadeOut; - memcpy(dest->gvars, src->gvars, sizeof(dest->gvars)); -} - -template -void copyCurveHeader(A * dest, B * src) -{ - dest->type = src->type; - dest->smooth = src->smooth; - dest->points = src->points; -} - -template -void copyGVarData(A * dest, B * src) -{ - dest->min = src->min; - dest->max = src->max; - dest->popup = src->popup; - dest->prec = src->prec; - dest->unit = src->unit; - dest->spare = src->spare; -} - -template -void copyTimerData(A * dest, B * src) -{ - dest->mode = src->mode; - dest->swtch = src->swtch; - dest->start = src->start; - dest->value = src->value; - dest->countdownBeep = src->countdownBeep; - dest->minuteBeep = src->minuteBeep; - dest->persistent = src->persistent; - dest->countdownStart = src->countdownStart; -} - -template -void copySwashRingData(A * dest, B * src) -{ - dest->type = src->type; - dest->value = src->value; - dest->collectiveSource = src->collectiveSource; - dest->aileronSource = src->aileronSource; - dest->elevatorSource = src->elevatorSource; - dest->collectiveWeight = src->collectiveWeight; - dest->aileronWeight = src->aileronWeight; - dest->elevatorWeight = src->elevatorWeight; -} - -template -void copyScriptData(A * dest, B * src) -{ - memcpy(dest->file, src->file, sizeof(dest->file)); - memcpy(dest->name, src->name, sizeof(dest->name)); - memcpy(dest->inputs, src->inputs, sizeof(dest->inputs)); -} - -template -void copyRssiAlarmData(A * dest, B * src) -{ - dest->disabled = src->disabled; - dest->spare = src->spare; - dest->warning = src->warning; - dest->spare2 = src->spare2; - dest->critical = src->critical; -} - -template -void copyVarioData(A * dest, B * src) -{ - dest->source = src->source; - dest->centerSilent = src->centerSilent; - dest->centerMax = src->centerMax; - dest->centerMin = src->centerMin; - dest->min = src->min; - dest->max = src->max; -} - -template -void copyTelemetrySensor(A * dest, B * src) -{ - dest->id = src->id; - copyTelemetrySensor_frskyInstance(&dest->frskyInstance, &src->frskyInstance); - memcpy(dest->label, src->label, sizeof(dest->label)); - dest->subId = src->subId; - dest->type = src->type; - dest->unit = src->unit; - dest->prec = src->prec; - dest->autoOffset = src->autoOffset; - dest->filter = src->filter; - dest->logs = src->logs; - dest->persistent = src->persistent; - dest->onlyPositive = src->onlyPositive; - dest->spare = src->spare; - dest->param = src->param; -} - -template -void copyTrainerModuleData(A * dest, B * src) -{ - dest->mode = src->mode; - dest->spare1 = src->spare1; - dest->channelsStart = src->channelsStart; - dest->channelsCount = src->channelsCount; - dest->frameLength = src->frameLength; - dest->delay = src->delay; - dest->pulsePol = src->pulsePol; - dest->spare2 = src->spare2; -} - -template -void copyModuleData(A * dest, B * src) -{ - dest->type = src->type; - dest->rfProtocol = src->rfProtocol; - dest->channelsStart = src->channelsStart; - dest->channelsCount = src->channelsCount; -} - -template -void copyModelHeader(A * dest, B * src) -{ - memcpy(dest->name, src->name, sizeof(dest->name)); - memcpy(dest->modelId, src->modelId, sizeof(dest->modelId)); -} - -template -void copyCustomScreenData(A * dest, B * src) -{ - memcpy(dest->layoutName, src->layoutName, sizeof(dest->layoutName)); - dest->layoutData = src->layoutData; -} - -template -void copyModelData(A * dest, B * src) -{ - copyModelHeader(&dest->header, &src->header); - for (int i=0; i<3; i++) { - copyTimerData(&dest->timers[i], &src->timers[i]); - } - dest->telemetryProtocol = src->telemetryProtocol; - dest->thrTrim = src->thrTrim; - dest->noGlobalFunctions = src->noGlobalFunctions; - dest->displayTrims = src->displayTrims; - dest->ignoreSensorIds = src->ignoreSensorIds; - dest->trimInc = src->trimInc; - dest->disableThrottleWarning = src->disableThrottleWarning; - dest->displayChecklist = src->displayChecklist; - dest->extendedLimits = src->extendedLimits; - dest->extendedTrims = src->extendedTrims; - dest->throttleReversed = src->throttleReversed; - dest->beepANACenter = src->beepANACenter; - for (int i=0; i<64; i++) { - copyMixData(&dest->mixData[i], &src->mixData[i]); - } - for (int i=0; i<32; i++) { - copyLimitData(&dest->limitData[i], &src->limitData[i]); - } - for (int i=0; i<64; i++) { - copyExpoData(&dest->expoData[i], &src->expoData[i]); - } - for (int i=0; i<32; i++) { - copyCurveHeader(&dest->curves[i], &src->curves[i]); - } - memcpy(dest->points, src->points, sizeof(dest->points)); - for (int i=0; i<64; i++) { - copyLogicalSwitchData(&dest->logicalSw[i], &src->logicalSw[i]); - } - for (int i=0; i<64; i++) { - copyCustomFunctionData(&dest->customFn[i], &src->customFn[i]); - } - copySwashRingData(&dest->swashR, &src->swashR); - for (int i=0; i<9; i++) { - copyFlightModeData(&dest->flightModeData[i], &src->flightModeData[i]); - } - for (int i=0; i<9; i++) { - copyGVarData(&dest->gvars[i], &src->gvars[i]); - } - for (int i=0; i<2; i++) { - copyModuleData(&dest->moduleData[i], &src->moduleData[i]); - } - memcpy(dest->failsafeChannels, src->failsafeChannels, sizeof(dest->failsafeChannels)); - copyTrainerModuleData(&dest->trainerData, &src->trainerData); - memcpy(dest->modelRegistrationID, src->modelRegistrationID, sizeof(dest->modelRegistrationID)); -} - -template -void copyStepsCalibData(A * dest, B * src) -{ - dest->count = src->count; - memcpy(dest->steps, src->steps, sizeof(dest->steps)); -} - -template -void copyCalibData(A * dest, B * src) -{ - dest->mid = src->mid; - dest->spanNeg = src->spanNeg; - dest->spanPos = src->spanPos; -} - -template -void copyTrainerMix(A * dest, B * src) -{ - dest->srcChn = src->srcChn; - dest->mode = src->mode; - dest->studWeight = src->studWeight; -} - -template -void copyTrainerData(A * dest, B * src) -{ - memcpy(dest->calib, src->calib, sizeof(dest->calib)); -} - -template -void copyRadioData(A * dest, B * src) -{ - for (int i=0; i<13; i++) { - copyCalibData(&dest->calib[i], &src->calib[i]); - } - dest->stickMode = src->stickMode; - dest->telemetryBaudrate = src->telemetryBaudrate; - // dest->splashSpares = src->splashSpares; - dest->switchesDelay = src->switchesDelay; - for (int i=0; i<64; i++) { - copyCustomFunctionData(&dest->customFn[i], &src->customFn[i]); - } - dest->slidersConfig = src->slidersConfig; - dest->switchConfig = src->switchConfig; - dest->potsConfig = src->potsConfig; - memcpy(dest->ownerRegistrationID, src->ownerRegistrationID, sizeof(dest->ownerRegistrationID)); -} - -template -void copyCustomFunctionData_all(A * dest, B * src) -{ - dest->val = src->val; - dest->mode = src->mode; - dest->param = src->param; -} - -template -void copyTelemetrySensor_frskyInstance(A * dest, B * src) -{ - dest->physID = src->physID; - dest->rxIndex = src->rxIndex; -} - -template -void copyModuleData_ppm(A * dest, B * src) -{ - dest->delay = src->delay; - dest->pulsePol = src->pulsePol; - dest->outputType = src->outputType; - dest->frameLength = src->frameLength; -} - diff --git a/radio/src/storage/eeprom_rlc.cpp b/radio/src/storage/eeprom_rlc.cpp index 3864ebb34..8c8d0c5f4 100644 --- a/radio/src/storage/eeprom_rlc.cpp +++ b/radio/src/storage/eeprom_rlc.cpp @@ -729,7 +729,7 @@ void RlcFile::nextRlcWriteStep() void RlcFile::flush() { while (!eepromIsTransferComplete()) - wdt_reset(); + WDG_RESET(); ENABLE_SYNC_WRITE(true); diff --git a/radio/src/storage/modelslist.cpp b/radio/src/storage/modelslist.cpp index cc63c5299..18e43c1d6 100644 --- a/radio/src/storage/modelslist.cpp +++ b/radio/src/storage/modelslist.cpp @@ -208,7 +208,7 @@ void ModelCell::setRfModuleData(uint8_t moduleIdx, ModuleData* modData) } else { // do we care here about MM_RF_CUSTOM_SELECTED? probably not... - moduleData[moduleIdx].rfProtocol = modData->getMultiProtocol(false); + moduleData[moduleIdx].rfProtocol = modData->getMultiProtocol(); } } diff --git a/radio/src/storage/rambackup.cpp b/radio/src/storage/rtc_backup.cpp similarity index 92% rename from radio/src/storage/rambackup.cpp rename to radio/src/storage/rtc_backup.cpp index ddf761fdb..dd86764e1 100644 --- a/radio/src/storage/rambackup.cpp +++ b/radio/src/storage/rtc_backup.cpp @@ -46,7 +46,7 @@ void rambackupWrite() { copyRadioData(&ramBackupUncompressed.radio, &g_eeGeneral); copyModelData(&ramBackupUncompressed.model, &g_model); - ramBackup->size = compress(ramBackup->data, 4094, (const uint8_t *)&ramBackupUncompressed, sizeof(ramBackupUncompressed)); + ramBackup->size = compress(ramBackup->data, sizeof(ramBackup->data), (const uint8_t *)&ramBackupUncompressed, sizeof(ramBackupUncompressed)); TRACE("RamBackupWrite sdsize=%d backupsize=%d rlcsize=%d", sizeof(ModelData)+sizeof(RadioData), sizeof(Backup::RamBackupUncompressed), ramBackup->size); } diff --git a/radio/src/storage/rtc_backup.h b/radio/src/storage/rtc_backup.h new file mode 100644 index 000000000..6fade3b70 --- /dev/null +++ b/radio/src/storage/rtc_backup.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + */ + +#ifndef _RAM_BACKUP_H_ +#define _RAM_BACKUP_H_ + +#include "definitions.h" + +PACK(struct RamBackup { + uint16_t size; + uint8_t data[4094]; +}); + +extern RamBackup * ramBackup; + +#endif // _RAM_BACKUP_H_ diff --git a/radio/src/storage/storage.h b/radio/src/storage/storage.h index 69e2a47f9..50d687779 100644 --- a/radio/src/storage/storage.h +++ b/radio/src/storage/storage.h @@ -23,7 +23,7 @@ #if defined(SIMU) #define WRITE_DELAY_10MS 100 -#elif defined(RAMBACKUP) +#elif defined(RTC_BACKUP_RAM) #define WRITE_DELAY_10MS 1500 /* 15s */ #elif defined(PCBTARANIS) #define WRITE_DELAY_10MS 500 @@ -37,10 +37,11 @@ extern uint8_t storageDirtyMsk; extern tmr10ms_t storageDirtyTime10ms; #define TIME_TO_WRITE() (storageDirtyMsk && (tmr10ms_t)(get_tmr10ms() - storageDirtyTime10ms) >= (tmr10ms_t)WRITE_DELAY_10MS) -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) +#include "storage/rtc_backup.h" extern uint8_t rambackupDirtyMsk; extern tmr10ms_t rambackupDirtyTime10ms; -#define TIME_TO_RAMBACKUP() (rambackupDirtyMsk && (tmr10ms_t)(get_tmr10ms() - rambackupDirtyTime10ms) >= (tmr10ms_t)100) +#define TIME_TO_BACKUP_RAM() (rambackupDirtyMsk && (tmr10ms_t)(get_tmr10ms() - rambackupDirtyTime10ms) >= (tmr10ms_t)100) #endif // @@ -69,7 +70,7 @@ void checkExternalAntenna(); #include "sdcard_common.h" #endif -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) #include "rambackup.h" #endif diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 1efd5c65d..e05caa08b 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -19,11 +19,12 @@ */ #include "opentx.h" +#include "pulses/multi.h" uint8_t storageDirtyMsk; tmr10ms_t storageDirtyTime10ms; -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) uint8_t rambackupDirtyMsk; tmr10ms_t rambackupDirtyTime10ms; #endif @@ -33,7 +34,7 @@ void storageDirty(uint8_t msk) storageDirtyMsk |= msk; storageDirtyTime10ms = get_tmr10ms(); -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) rambackupDirtyMsk = storageDirtyMsk; rambackupDirtyTime10ms = storageDirtyTime10ms; #endif @@ -133,11 +134,19 @@ void postModelLoad(bool alarms) if (!isInternalModuleAvailable(g_model.moduleData[INTERNAL_MODULE].type)) { memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); } +#if defined(MULTIMODULE) + else if (isModuleMultimodule(INTERNAL_MODULE)) + multiPatchCustom(INTERNAL_MODULE); +#endif #endif if (!isExternalModuleAvailable(g_model.moduleData[EXTERNAL_MODULE].type)) { memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData)); } +#if defined(MULTIMODULE) + else if (isModuleMultimodule(EXTERNAL_MODULE)) + multiPatchCustom(EXTERNAL_MODULE); +#endif AUDIO_FLUSH(); flightReset(false); diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index f6d6c7f00..a19103968 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -487,10 +487,10 @@ char * strAppendUnsigned(char * dest, uint32_t value, uint8_t digits, uint8_t ra } } uint8_t idx = digits; - while(idx > 0) { - uint32_t rem = value % radix; - dest[--idx] = (rem >= 10 ? 'A'-10 : '0') + rem; - value /= radix; + while (idx > 0) { + div_t qr = div(value, radix); + dest[--idx] = (qr.rem >= 10 ? 'A' - 10 : '0') + qr.rem; + value = qr.quot; } dest[digits] = '\0'; return &dest[digits]; diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 9937f25d6..8e8e0d884 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -568,7 +568,6 @@ void checkSwitches() #endif while (true) { - #if defined(PCBFRSKY) #define GETADC_COUNT 1 #endif @@ -728,6 +727,8 @@ void checkSwitches() #if defined(PWR_BUTTON_PRESS) uint32_t power = pwrCheck(); if (power == e_power_off) { + drawSleepBitmap(); + boardOff(); break; } else if (power == e_power_press) { @@ -746,7 +747,7 @@ void checkSwitches() doLoopCommonActions(); - wdt_reset(); + WDG_RESET(); RTOS_WAIT_MS(10); } diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index b2d9108ef..c7c70f977 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -147,7 +147,7 @@ endif() if(MULTIMODULE) add_definitions(-DMULTIMODULE) - set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/multi.cpp io/multi_firmware_update.cpp) + set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp) endif() if(CROSSFIRE) diff --git a/radio/src/targets/common/arm/stm32/board_common.h b/radio/src/targets/common/arm/stm32/board_common.h index e7d6ecbe5..c474dc37d 100644 --- a/radio/src/targets/common/arm/stm32/board_common.h +++ b/radio/src/targets/common/arm/stm32/board_common.h @@ -138,4 +138,13 @@ void delay_ms(uint32_t ms); } #endif +#define INIT_KEYS_PINS(GPIO) \ + GPIO_InitStructure.GPIO_Pin = KEYS_ ## GPIO ## _PINS; \ + GPIO_Init(GPIO, &GPIO_InitStructure) + +#define SET_KEYS_PINS_HIGH(GPIO) \ + GPIO_InitStructure.GPIO_Pin = KEYS_ ## GPIO ## _PINS; \ + GPIO_Init(GPIO, &GPIO_InitStructure); \ + GPIO_SetBits(GPIO, KEYS_ ## GPIO ## _PINS) + #endif diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index 1fb90fd21..140dfe6da 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -8,6 +8,8 @@ if(CPU_TYPE_FULL STREQUAL STM32F429xI) ../f4/system_stm32f4xx.c ../../../../../targets/${TARGET_DIR}/startup_stm32f42_43xxx.s ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c + ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c + ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c @@ -25,6 +27,8 @@ elseif(CPU_TYPE_FULL STREQUAL STM32F407xE) ../f4/system_stm32f4xx.c ../../../../../targets/${TARGET_DIR}/startup_stm32f40_41xxx.s ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c + ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c + ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c @@ -114,6 +118,7 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ../../../../../thirdparty/libopenui/src/libopenui_globals.cpp ../../../../../targets/${TARGET_DIR}/sdram_driver.c ../../../../../targets/common/arm/stm32/sdio_sd.c + ../../../../../targets/common/arm/stm32/rtc_driver.cpp ../../../../../targets/${TARGET_DIR}/haptic_driver.cpp ../../../../../syscalls.c ) @@ -125,6 +130,12 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ../../../../../serial.cpp ) endif() +else() + set(BOOTLOADER_SRC + ${BOOTLOADER_SRC} + ../../../../../targets/${TARGET_DIR}/i2c_driver.cpp + ) + remove_definitions(-DDEBUG) endif() remove_definitions(-DDEBUG) @@ -132,6 +143,8 @@ remove_definitions(-DDISK_CACHE) remove_definitions(-DLUA) remove_definitions(-DCLI) remove_definitions(-DUSB_SERIAL) +remove_definitions(-DWATCHDOG) + add_definitions(-DBOOT) set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC_DIR}/targets/${TARGET_DIR}/stm32_ramboot.ld -Wl,-Map=bootloader.map,--cref,--no-warn-mismatch,--gc-sections") diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index a0878eb05..106734a2f 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -69,13 +69,13 @@ FlashCheckRes valid; MemoryType memoryType; uint32_t unlocked = 0; -void interrupt10ms(void) +void interrupt10ms() { - tenms |= 1; // 10 mS has passed + tenms |= 1u; // 10 mS has passed uint8_t index = 0; uint8_t in = readKeys(); - for (uint8_t i = 1; i != uint8_t(1 << TRM_BASE); i <<= 1) { + for (uint8_t i = 1; i != uint8_t(1u << TRM_BASE); i <<= 1) { uint8_t value = (in & i); keys[index].input(value); ++index; @@ -195,8 +195,6 @@ int main() FRESULT fr; uint32_t nameCount = 0; - wdt_reset(); - RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | AUX_SERIAL_RCC_AHB1Periph | I2C_RCC_AHB1Periph | @@ -212,12 +210,12 @@ int main() pwrInit(); keysInit(); -#if defined(PCBHORUS) // wait a bit for the inputs to stabilize... - for (uint32_t i = 0; i < 50000; i++) { - wdt_reset(); + if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { + for (uint32_t i = 0; i < 150000; i++) { + __ASM volatile ("nop"); + } } -#endif // LHR & RHL trims not pressed simultanously if (readTrims() != BOOTLOADER_KEYS) { @@ -265,12 +263,12 @@ int main() #if defined(PWR_BUTTON_PRESS) // wait until power button is released while (pwrPressed()) { - wdt_reset(); + WDG_RESET(); } #endif for (;;) { - wdt_reset(); + WDG_RESET(); if (tenms) { tenms = 0; @@ -506,16 +504,12 @@ int main() lcdRefresh(); lcdRefreshWait(); -#if !defined(EEPROM) - // Use jump on radios with emergency mode - // to avoid triggering it with a soft reset - - // Jump to proper application address - jumpTo(APP_START_ADDRESS); -#else - // Use software reset everywhere else - NVIC_SystemReset(); +#if defined(RTC_BACKUP_RAM) + rtcInit(); + RTC->BKP0R = SOFTRESET_REQUEST; #endif + + NVIC_SystemReset(); } } @@ -523,5 +517,5 @@ int main() } #if defined(PCBHORUS) -void *__dso_handle = 0; +void *__dso_handle = nullptr; #endif diff --git a/radio/src/targets/common/arm/stm32/flash_driver.cpp b/radio/src/targets/common/arm/stm32/flash_driver.cpp index ab653c2d6..6fd4c1a29 100644 --- a/radio/src/targets/common/arm/stm32/flash_driver.cpp +++ b/radio/src/targets/common/arm/stm32/flash_driver.cpp @@ -20,6 +20,13 @@ #include "opentx.h" +void waitFlashIdle() +{ + do { + WDG_RESET(); + } while (FLASH->SR & FLASH_FLAG_BSY); +} + //After reset, write is not allowed in the Flash control register (FLASH_CR) to protect the //Flash memory against possible unwanted operations due, for example, to electric //disturbances. The following sequence is used to unlock this register: @@ -37,21 +44,16 @@ void unlockFlash() void lockFlash() { - while (FLASH->SR & FLASH_SR_BSY); + waitFlashIdle(); FLASH->CR |= FLASH_CR_LOCK; } -void waitFlashIdle() -{ - while (FLASH->SR & FLASH_FLAG_BSY) { - wdt_reset(); - } -} - #define SECTOR_MASK ((uint32_t)0xFFFFFF07) void eraseSector(uint32_t sector) { + WDG_ENABLE(3000); // some sectors may take > 1s to erase + waitFlashIdle(); FLASH->CR &= CR_PSIZE_MASK; @@ -66,9 +68,11 @@ void eraseSector(uint32_t sector) /* if the erase operation is completed, disable the SER Bit */ FLASH->CR &= (~FLASH_CR_SER); FLASH->CR &= SECTOR_MASK; + + WDG_ENABLE(WDG_DURATION); } -void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes +void flashWrite(uint32_t * address, const uint32_t * buffer) // page size is 256 bytes { #define SECTOR_ADDRESS (((uint32_t)address) & 0xFFFFF) @@ -110,7 +114,6 @@ void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes eraseSector(4 + FLASH_BANK); } else if ((((uint32_t)address) & 0x3FFF) == 0) { - // test other 16KB sectors if (SECTOR_ADDRESS == 0x04000) { eraseSector(1 + FLASH_BANK); @@ -141,7 +144,7 @@ void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes /* Wait for operation to be completed */ waitFlashIdle(); - FLASH->CR &= (~FLASH_CR_PG); + FLASH->CR &= ~FLASH_CR_PG; /* Check the written value */ if (*address != *buffer) { @@ -192,7 +195,7 @@ uint32_t isBootloaderStart(const uint8_t * buffer) { const uint32_t * block = (const uint32_t *)buffer; - for (int i=0; i<256; i++) { + for (int i = 0; i < 256; i++) { if (block[i] == 0x544F4F42/*BOOT*/) { return 1; } diff --git a/radio/src/targets/common/arm/stm32/rtc_driver.cpp b/radio/src/targets/common/arm/stm32/rtc_driver.cpp index 84c9bef5b..4ccceffb5 100644 --- a/radio/src/targets/common/arm/stm32/rtc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rtc_driver.cpp @@ -59,17 +59,14 @@ void rtcGetTime(struct gtm * t) void rtcInit() { - RTC_InitTypeDef RTC_InitStruct; - RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_BackupAccessCmd(ENABLE); RCC_LSEConfig(RCC_LSE_ON); // Prevent lockup in case of 32kHz oscillator failure uint32_t i = 0; - while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) - { - if ( ++i > 1000000 ) + while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) { + if (++i > 1000000) return; } @@ -77,17 +74,21 @@ void rtcInit() RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); +#if !defined(BOOT) + RTC_InitTypeDef RTC_InitStruct; + // RTC time base = LSE / ((AsynchPrediv+1) * (SynchPrediv+1)) = 1 Hz*/ RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24; RTC_InitStruct.RTC_AsynchPrediv = 127; RTC_InitStruct.RTC_SynchPrediv = 255; RTC_Init(&RTC_InitStruct); - + struct gtm utm; rtcGetTime(&utm); g_rtcTime = gmktime(&utm); +#endif -#if defined(RAMBACKUP) +#if defined(RTC_BACKUP_RAM) && !defined(BOOT) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); PWR_BackupRegulatorCmd(ENABLE); #endif diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 41502fb75..f26fe6b99 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -14,6 +14,11 @@ set(HAPTIC YES) set(GUI_DIR colorlcd) set(NAVIGATION_TYPE horus) set(TARGET_DIR horus) +set(LINKER_SCRIPT targets/horus/stm32f4_flash.ld) +set(RTC_BACKUP_RAM YES) +set(LUA YES) +set(PPM_LIMITS_SYMETRICAL YES) +set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)") if(BOOTLOADER) set(LINKER_SCRIPT targets/horus/stm32f4_flash_bootloader.ld) @@ -21,10 +26,6 @@ else() set(LINKER_SCRIPT targets/horus/stm32f4_flash.ld) endif() -set(RAMBACKUP YES) -set(PPM_LIMITS_SYMETRICAL YES) -set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)") - option(YAML_STORAGE "Enable YAML storage" NO) if(YAML_STORAGE) set(STORAGE_FORMAT YAML) @@ -104,7 +105,13 @@ endif() add_definitions(-DPCBREV=${PCBREV}) add_definitions(-DPCBREV_${PCBREV}) -set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET} truetype_fonts) +set(RADIO_DEPENDENCIES + ${RADIO_DEPENDENCIES} + ${BITMAPS_TARGET} + truetype_fonts + ) + +set(FIRMWARE_DEPENDENCIES datacopy) add_definitions(-DPCBHORUS -DSTM32F429_439xx -DSDRAM -DCOLORLCD -DHARDWARE_KEYS) add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK) @@ -198,9 +205,13 @@ set(STM32LIB_SRC ) if(PYTHONINTERP_FOUND) - add_custom_target(datacopy + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp WORKING_DIRECTORY ${RADIO_DIRECTORY}/src - COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DCOLORLCD -DBACKUP -Itargets/horus > storage/datacopy.cpp + COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DCOLORLCD -DBACKUP -Itargets/horus > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py - ) + ) + add_custom_target(datacopy + DEPENDS ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp + ) endif() diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index fd93f15ee..048817c69 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -29,10 +29,6 @@ extern "C" { } #endif -uint32_t shutdownRequest; // Stores intentional shutdown to avoid reboot loop -uint32_t shutdownReason; // Used for detecting unexpected reboots regardless of reason -uint32_t powerupReason __NOINIT; // Stores power up reason beyond initialization for emergency mode activation - HardwareOptions hardwareOptions; void watchdogInit(unsigned int duration) @@ -40,7 +36,7 @@ void watchdogInit(unsigned int duration) IWDG->KR = 0x5555; // Unlock registers IWDG->PR = 3; // Divide by 32 => 1kHz clock IWDG->KR = 0x5555; // Unlock registers - IWDG->RLR = duration; // 1.5 seconds nominal + IWDG->RLR = duration; IWDG->KR = 0xAAAA; // reload IWDG->KR = 0xCCCC; // start } @@ -173,6 +169,7 @@ void boardInit() #endif ledInit(); + #if defined(PCBX10) && !defined(RADIO_T16) sportUpdateInit(); #endif @@ -189,7 +186,7 @@ void boardOff() backlightEnable(0); while (pwrPressed()) { - wdt_reset(); + WDG_RESET(); } SysTick->CTRL = 0; // turn off systick @@ -209,8 +206,12 @@ void boardOff() // Shutdown the Haptic hapticDone(); - shutdownRequest = SHUTDOWN_REQUEST; - shutdownReason = NORMAL_POWER_OFF; +#if defined(RTC_BACKUP_RAM) + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, DISABLE); + PWR_BackupRegulatorCmd(DISABLE); +#endif + + RTC->BKP0R = SHUTDOWN_REQUEST; pwrOff(); } diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index e31f9c315..b87e62a3d 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -136,7 +136,7 @@ DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count); #define FLASH_PAGESIZE 256 void unlockFlash(); void lockFlash(); -void flashWrite(uint32_t * address, uint32_t * buffer); +void flashWrite(uint32_t * address, const uint32_t * buffer); uint32_t isFirmwareStart(const uint8_t * buffer); uint32_t isBootloaderStart(const uint8_t * buffer); @@ -305,28 +305,22 @@ void rotaryEncoderInit(); void rotaryEncoderCheck(); // WDT driver -#define WDTO_500MS 500 -extern uint32_t powerupReason; - -#define SHUTDOWN_REQUEST 0xDEADBEEF -#define NO_SHUTDOWN_REQUEST ~SHUTDOWN_REQUEST -#define DIRTY_SHUTDOWN 0xCAFEDEAD -#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN +#define WDG_DURATION 500 /*ms*/ void watchdogInit(unsigned int duration); #if defined(SIMU) #define WAS_RESET_BY_WATCHDOG() (false) #define WAS_RESET_BY_SOFTWARE() (false) #define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (false) - #define wdt_enable(x) - #define wdt_reset() + #define WDG_ENABLE(x) + #define WDG_RESET() #else #if defined(WATCHDOG) - #define wdt_enable(x) watchdogInit(x) - #define wdt_reset() IWDG->KR = 0xAAAA + #define WDG_ENABLE(x) watchdogInit(x) + #define WDG_RESET() IWDG->KR = 0xAAAA #else - #define wdt_enable(x) - #define wdt_reset() + #define WDG_ENABLE(x) + #define WDG_RESET() #endif #define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF)) #define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF) @@ -453,14 +447,41 @@ extern volatile uint32_t pwm_interrupt_count; #define BATTERY_MAX 115 // 11.5V #endif +#if defined(__cplusplus) +enum PowerReason { + SHUTDOWN_REQUEST = 0xDEADBEEF, + SOFTRESET_REQUEST = 0xCAFEDEAD, +}; + +constexpr uint32_t POWER_REASON_SIGNATURE = 0x0178746F; + +inline bool UNEXPECTED_SHUTDOWN() +{ +#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN) + return false; +#else + if (WAS_RESET_BY_WATCHDOG()) + return true; + else if (WAS_RESET_BY_SOFTWARE()) + return RTC->BKP0R != SOFTRESET_REQUEST; + else + return RTC->BKP1R == POWER_REASON_SIGNATURE && RTC->BKP0R != SHUTDOWN_REQUEST; +#endif +} + +inline void SET_POWER_REASON(uint32_t value) +{ + RTC->BKP0R = value; + RTC->BKP1R = POWER_REASON_SIGNATURE; +} +#endif + #if defined(__cplusplus) && !defined(SIMU) extern "C" { #endif // Power driver #define SOFT_PWR_CTRL -extern uint32_t shutdownRequest; // Stores intentional shutdown to avoid reboot loop -extern uint32_t shutdownReason; // Used for detecting unexpected reboots regardless of reason void pwrInit(); uint32_t pwrCheck(); void pwrOn(); @@ -468,11 +489,6 @@ void pwrOff(); void pwrResetHandler(); bool pwrPressed(); uint32_t pwrPressedDuration(); -#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN) - #define UNEXPECTED_SHUTDOWN() (false) -#else - #define UNEXPECTED_SHUTDOWN() ((powerupReason == DIRTY_SHUTDOWN) || WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) -#endif // Led driver void ledInit(); diff --git a/radio/src/targets/horus/bootloader/boot_menu.cpp b/radio/src/targets/horus/bootloader/boot_menu.cpp index 329ff1efb..f92c579cb 100644 --- a/radio/src/targets/horus/bootloader/boot_menu.cpp +++ b/radio/src/targets/horus/bootloader/boot_menu.cpp @@ -48,7 +48,7 @@ void bootloaderInitScreen() backlightEnable(BACKLIGHT_LEVEL_MAX); - //TODO: load/decompress bitmaps + // TODO: load/decompress bitmaps extern void loadFonts(); loadFonts(); } @@ -73,7 +73,7 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str) lcd->clear(DEFAULT_BGCOLOR); if (st == ST_START) { - bootloaderDrawTitle(88, "HORUS BOOTLOADER"); + bootloaderDrawTitle(88, "OpenTX Bootloader"); lcd->drawBitmapPattern(90, 72, LBM_FLASH, DEFAULT_COLOR); lcd->drawText(124, 75, "Write Firmware"); diff --git a/radio/src/targets/horus/keys_driver.cpp b/radio/src/targets/horus/keys_driver.cpp index 52d862ad1..9879135dd 100644 --- a/radio/src/targets/horus/keys_driver.cpp +++ b/radio/src/targets/horus/keys_driver.cpp @@ -199,34 +199,21 @@ uint32_t switchState(uint8_t index) void keysInit() { GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOB_PINS; - GPIO_Init(GPIOB, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOB); #if defined(KEYS_GPIOC_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOC_PINS; - GPIO_Init(GPIOC, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOC); #endif - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOD_PINS; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOE_PINS; - GPIO_Init(GPIOE, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOG_PINS; - GPIO_Init(GPIOG, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOH_PINS; - GPIO_Init(GPIOH, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOI_PINS; - GPIO_Init(GPIOI, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOJ_PINS; - GPIO_Init(GPIOJ, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOD); + INIT_KEYS_PINS(GPIOE); + INIT_KEYS_PINS(GPIOG); + INIT_KEYS_PINS(GPIOH); + INIT_KEYS_PINS(GPIOI); + INIT_KEYS_PINS(GPIOJ); } diff --git a/radio/src/targets/horus/pwr_driver.cpp b/radio/src/targets/horus/pwr_driver.cpp index 2bb89ddbb..aa9e13497 100644 --- a/radio/src/targets/horus/pwr_driver.cpp +++ b/radio/src/targets/horus/pwr_driver.cpp @@ -19,6 +19,7 @@ */ #include "board.h" +#include "storage/rtc_backup.h" void pwrInit() { @@ -81,9 +82,6 @@ void pwrOn() GPIO_Init(PWR_ON_GPIO, &GPIO_InitStructure); GPIO_SetBits(PWR_ON_GPIO, PWR_ON_GPIO_PIN); - - shutdownRequest = NO_SHUTDOWN_REQUEST; - shutdownReason = DIRTY_SHUTDOWN; } void pwrOff() @@ -105,38 +103,7 @@ void pwrResetHandler() __ASM volatile ("nop"); __ASM volatile ("nop"); - // We get here whether we are powering up normally, we had an unexpected reboot or we have just powered down normally. - // We want: - // - In the 2nd case, to power ON as soon as possible if an unexpected reboot happened - // (we get there running on remaining capacitor charge, soft power having been cut by the RESET). - // - In the 3rd case, NOT power on as that would prevent from turning the system off. - // - The 1st case does not need to be handled here, but will be as a result of the handling for the 3rd case, see below. - // - // shutdownRequest is used to handle the 3rd case. If we really powered down on purpose this will still be set to SHUTDOWN_REQUEST - // as we left it in pwrOff(). If however we had an unexpected reboot, it would be set to NO_SHUTDOWN_REQUEST as we set it in pwrOn(). - // Any other value (e.g. resulting from data corruption) would also keep power on for safety, so this variable can NOT be used - // to detect an unexpected reboot (on a normal power on the contents of the variable are random). - // - // shutdownReason is used to differentiate between an unexpected reboot and a normal power on. We set it to DIRTY_SHUTDOWN in pwrOn() - // in anticipation of a potential reboot. Should there be one the value should be preserved and signal below that we rebooted unexpectedly. - // If it is NOT set to DIRTY_SHUTDOWN we likely had a normal boot and its contents are random. Due to the need to initialize it to detect a - // potential failure ASAP we cannot use it to determine in the firmware why we got there, it has to be buffered. - // - // powerupReason is there to cater for that, and is what is used in the firmware to decide whether we have to enter emergency mode. - // This variable needs to be in a RAM section that is not initialized or zeroed, since once we exit this pwrResetHandler() function the - // C runtime would otherwise overwrite it during program init. - // Only for X12, X10 power circuit causes inability to shut down on some samples. - -#if defined(PCBX12S) - if (shutdownRequest != SHUTDOWN_REQUEST || WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { - if (shutdownReason == DIRTY_SHUTDOWN) { - powerupReason = DIRTY_SHUTDOWN; - } + if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { pwrOn(); } -#else - if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { - pwrOn(); - } -#endif } diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index fe143cfe2..ecd73b6ab 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -228,8 +228,14 @@ void telemetryPortSetDirectionOutput() TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver } +void sportWaitTransmissionComplete() +{ + while (!(TELEMETRY_USART->SR & USART_SR_TC)); +} + void telemetryPortSetDirectionInput() { + sportWaitTransmissionComplete(); TELEMETRY_DIR_GPIO->BSRRH = TELEMETRY_DIR_GPIO_PIN; // output disable TELEMETRY_USART->CR1 |= USART_CR1_RE; // turn on receiver } diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index c7d7412d0..a19dc323b 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -51,6 +51,7 @@ DMA_TypeDef dma2; USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4; SysTick_Type systick; ADC_Common_TypeDef adc; +RTC_TypeDef rtc; #else Pio Pioa, Piob, Pioc; Pmc pmc; @@ -682,7 +683,7 @@ void lockFlash() { } -void flashWrite(uint32_t *address, uint32_t *buffer) +void flashWrite(uint32_t *address, const uint32_t *buffer) { simuSleep(100); } @@ -706,7 +707,7 @@ void serialPutc(char c) { } uint16_t getBatteryVoltage() { - return (BATTERY_MAX + BATTERY_WARN) * 5; + return (g_eeGeneral.vBatWarn * 10) + 50; // 0.5 volt above alerm (value is PREC1) } void boardOff() diff --git a/radio/src/targets/simu/simpgmspace.h b/radio/src/targets/simu/simpgmspace.h index fa1318511..9ae195dc2 100644 --- a/radio/src/targets/simu/simpgmspace.h +++ b/radio/src/targets/simu/simpgmspace.h @@ -86,6 +86,7 @@ extern DMA_Stream_TypeDef dma1_stream0, dma1_stream1, dma1_stream2, dma1_stream3 extern DMA_TypeDef dma2; extern SysTick_Type systick; extern ADC_Common_TypeDef adc; +extern RTC_TypeDef rtc; #undef SysTick #define SysTick (&systick) #undef GPIOA @@ -166,6 +167,8 @@ extern ADC_Common_TypeDef adc; #define DMA2 (&dma2) #undef ADC #define ADC (&adc) +#undef RTC +#define RTC (&rtc) #elif defined(PCBSKY9X) extern Pmc pmc; #undef PMC diff --git a/radio/src/targets/sky9x/board.cpp b/radio/src/targets/sky9x/board.cpp index e97cc8ccc..2bc6e0225 100644 --- a/radio/src/targets/sky9x/board.cpp +++ b/radio/src/targets/sky9x/board.cpp @@ -330,6 +330,7 @@ void i2cInit() TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing NVIC_EnableIRQ(TWI0_IRQn) ; } +#endif void boardInit() { @@ -388,12 +389,11 @@ void boardInit() lcdInit(); init_SDcard(); -} -#else -void boardInit() -{ -} + +#if defined(PCBAR9X) + rtcInit(); #endif +} uint8_t temperature = 0; // Raw temp reading uint8_t maxTemperature = 0 ; // Raw temp reading diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index c6625e760..952e48282 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -218,7 +218,7 @@ void stop_trainer_capture(); // Write Flash driver #define FLASH_PAGESIZE 256 -void flashWrite(uint32_t * address, uint32_t * buffer); +void flashWrite(uint32_t * address, const uint32_t * buffer); // Keys driver uint32_t switchState(uint8_t index); @@ -259,12 +259,12 @@ extern "C" { // WDT driver #if !defined(WATCHDOG) || defined(SIMU) - #define wdt_enable(x) - #define wdt_reset() + #define WDG_ENABLE(x) + #define WDG_RESET() #define IS_RESET_REASON_WATCHDOG() false #else - #define wdt_enable(x) WDT->WDT_MR = 0x3FFF207F - #define wdt_reset() WDT->WDT_CR = 0xA5000001 + #define WDG_ENABLE(x) WDT->WDT_MR = 0x3FFF207F + #define WDG_RESET() WDT->WDT_CR = 0xA5000001 #define IS_RESET_REASON_WATCHDOG() ((ResetReason & RSTC_SR_RSTTYP) == (2 << 8)) #endif diff --git a/radio/src/targets/sky9x/flash_driver.cpp b/radio/src/targets/sky9x/flash_driver.cpp index 96bbfe763..da23a871d 100644 --- a/radio/src/targets/sky9x/flash_driver.cpp +++ b/radio/src/targets/sky9x/flash_driver.cpp @@ -22,7 +22,7 @@ uint32_t (*IAP_Function)(uint32_t, uint32_t); -void flashWrite(uint32_t *address, uint32_t *buffer) // size is 256 bytes +void flashWrite(uint32_t * address, const uint32_t * buffer) // size is 256 bytes { uint32_t FlashSectorNum; uint32_t flash_cmd = 0; diff --git a/radio/src/targets/sky9x/lcd_driver.cpp b/radio/src/targets/sky9x/lcd_driver.cpp index d8453ebe1..270d5b4c8 100644 --- a/radio/src/targets/sky9x/lcd_driver.cpp +++ b/radio/src/targets/sky9x/lcd_driver.cpp @@ -120,7 +120,7 @@ void lcdInit() TC0->TC_CHANNEL[0].TC_CCR = 5; // Enable clock and trigger it (may only need trigger) while ( TC0->TC_CHANNEL[0].TC_CV < 36000 ) { // Value depends on MCK/2 (used 18MHz) give 2mS delay - wdt_reset(); // Wait + WDG_RESET(); // Wait } } } diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 3be5e3457..ffd155d67 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -109,6 +109,7 @@ elseif(PCB STREQUAL X7) set(NAVIGATION_TYPE 9x) add_definitions(-DRADIO_T12) add_definitions(-DEEPROM_VARIANT=0x4001) + option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" OFF) else() option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) @@ -253,7 +254,7 @@ if(PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STRE ) endif() -if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR PCB STREQUAL X9LITES) +if(PCB STREQUAL X9E OR (PCB STREQUAL X7 AND NOT PCBREV STREQUAL T12) OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR PCB STREQUAL X9LITES) add_definitions(-DBLUETOOTH) set(TARGET_SRC ${TARGET_SRC} @@ -354,6 +355,15 @@ if(INTERNAL_MODULE_PXX2) add_definitions(-DINTERNAL_MODULE_PXX2) endif() +if(INTERNAL_MODULE_MULTI) + add_definitions(-DHARDWARE_INTERNAL_MODULE) + add_definitions(-DINTERNAL_MODULE_MULTI) + set(TARGET_SRC + ${TARGET_SRC} + ../common/arm/stm32/intmodule_serial_driver.cpp + ) +endif() + if(INTERNAL_MODULE_PPM) add_definitions(-DHARDWARE_INTERNAL_MODULE) add_definitions(-DINTERNAL_MODULE_PPM) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 2589cd643..2d7a980c7 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -36,7 +36,7 @@ void watchdogInit(unsigned int duration) IWDG->KR = 0x5555; // Unlock registers IWDG->PR = 3; // Divide by 32 => 1kHz clock IWDG->KR = 0x5555; // Unlock registers - IWDG->RLR = duration; // 1.5 seconds nominal + IWDG->RLR = duration; IWDG->KR = 0xAAAA; // reload IWDG->KR = 0xCCCC; // start } @@ -222,7 +222,7 @@ void boardOff() #if defined(PWR_BUTTON_PRESS) while (pwrPressed()) { - wdt_reset(); + WDG_RESET(); } #endif @@ -234,7 +234,7 @@ void boardOff() __disable_irq(); while (1) { - wdt_reset(); + WDG_RESET(); #if defined(PWR_BUTTON_PRESS) // X9E/X7 needs watchdog reset because CPU is still running while // the power key is held pressed by the user. diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 1dca15031..95a3aaca9 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -95,7 +95,7 @@ uint32_t sdMounted(); #define FLASH_PAGESIZE 256 void unlockFlash(); void lockFlash(); -void flashWrite(uint32_t * address, uint32_t * buffer); +void flashWrite(uint32_t * address, const uint32_t * buffer); uint32_t isFirmwareStart(const uint8_t * buffer); uint32_t isBootloaderStart(const uint8_t * buffer); @@ -122,6 +122,9 @@ uint32_t isBootloaderStart(const uint8_t * buffer); #endif void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength); +#if defined(INTERNAL_MODULE_MULTI) +void intmoduleTimerStart(uint32_t periodMs); +#endif void intmoduleSendByte(uint8_t byte); void intmoduleSendBuffer(const uint8_t * data, uint8_t size); void intmoduleSendNextFrame(); @@ -438,13 +441,13 @@ uint32_t readTrims(); #define KEYS_PRESSED() (readKeys()) // WDT driver -#define WDTO_500MS 500 +#define WDG_DURATION 500 /*ms*/ #if !defined(WATCHDOG) || defined(SIMU) - #define wdt_enable(x) - #define wdt_reset() + #define WDG_ENABLE(x) + #define WDG_RESET() #else - #define wdt_enable(x) watchdogInit(x) - #define wdt_reset() IWDG->KR = 0xAAAA + #define WDG_ENABLE(x) watchdogInit(x) + #define WDG_RESET() IWDG->KR = 0xAAAA #endif void watchdogInit(unsigned int duration); #define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF) diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 53cc66618..235e5eefb 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1003,26 +1003,31 @@ #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF5 #define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #elif defined(RADIO_T12) - //left here is somebody will mod the radio for internal module - #define INTMODULE_PULSES - #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) - #define INTMODULE_RCC_APB1Periph 0 - #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1 - #define INTMODULE_PWR_GPIO GPIOC - #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_6 // JUMPER INT PC.06 //X7 INT is PC.06 - #define INTMODULE_TX_GPIO GPIOA - #define INTMODULE_TX_GPIO_PIN GPIO_Pin_7 // JUMPER INT PA.07 //X7 INT is PA.10 - #define INTMODULE_TX_GPIO_PinSource GPIO_PinSource10 - #define INTMODULE_TIMER TIM1 - #define INTMODULE_TIMER_CC_IRQn TIM1_CC_IRQn - #define INTMODULE_TIMER_CC_IRQHandler TIM1_CC_IRQHandler - #define INTMODULE_TX_GPIO_AF GPIO_AF_TIM1 - #define INTMODULE_DMA_CHANNEL DMA_Channel_6 - #define INTMODULE_DMA_STREAM DMA2_Stream5 - #define INTMODULE_DMA_STREAM_IRQn DMA2_Stream5_IRQn - #define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream5_IRQHandler - #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF5 - #define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) + #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) + #define INTMODULE_PWR_GPIO GPIOC + #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_6 // PC.06 + #define INTMODULE_GPIO GPIOB + #define INTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PB.10 + #define INTMODULE_RX_GPIO_PIN GPIO_Pin_11 // PB.11 + #define INTMODULE_GPIO_PinSource_TX GPIO_PinSource10 + #define INTMODULE_GPIO_PinSource_RX GPIO_PinSource11 + #define INTMODULE_USART USART3 + #define INTMODULE_GPIO_AF GPIO_AF_USART3 + #define INTMODULE_USART_IRQn USART3_IRQn + #define INTMODULE_USART_IRQHandler USART3_IRQHandler + #define INTMODULE_DMA_STREAM DMA1_Stream3 + #define INTMODULE_DMA_STREAM_IRQ DMA1_Stream3_IRQn + #define INTMODULE_DMA_STREAM_IRQHandler DMA1_Stream3_IRQHandler + #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF3 + #define INTMODULE_DMA_CHANNEL DMA_Channel_4 + #define INTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 + #define INTMODULE_RCC_APB2Periph RCC_APB1Periph_USART3 + #define INTMODULE_TIMER TIM2 + #define INTMODULE_TIMER_IRQn TIM2_IRQn + #define INTMODULE_TIMER_IRQHandler TIM2_IRQHandler + #define INTMODULE_TIMER_CC_IRQn TIM2_CC_IRQn + #define INTMODULE_TIMER_CC_IRQHandler TIM2_CC_IRQHandler + #define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #else #define INTMODULE_PULSES #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp index acfcb822e..ccaf60760 100644 --- a/radio/src/targets/taranis/keys_driver.cpp +++ b/radio/src/targets/taranis/keys_driver.cpp @@ -238,43 +238,36 @@ uint32_t switchState(uint8_t index) void keysInit() { GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; #if defined(KEYS_GPIOA_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOA_PINS; - GPIO_Init(GPIOA, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOA); #endif #if defined(KEYS_GPIOB_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOB_PINS; - GPIO_Init(GPIOB, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOB); #endif #if defined(KEYS_GPIOC_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOC_PINS; - GPIO_Init(GPIOC, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOC); #endif #if defined(KEYS_GPIOD_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOD_PINS; - GPIO_Init(GPIOD, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOD); #endif #if defined(KEYS_GPIOE_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOE_PINS; - GPIO_Init(GPIOE, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOE); #endif #if defined(KEYS_GPIOF_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOF_PINS; - GPIO_Init(GPIOF, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOF); #endif #if defined(KEYS_GPIOG_PINS) - GPIO_InitStructure.GPIO_Pin = KEYS_GPIOG_PINS; - GPIO_Init(GPIOG, &GPIO_InitStructure); + INIT_KEYS_PINS(GPIOG); #endif } diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index 00e7d7b56..9cbe9e2bd 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -189,7 +189,7 @@ TASK_FUNCTION(mixerTask) DEBUG_TIMER_STOP(debugTimerTelemetryWakeup); if (heartbeat == HEART_WDT_CHECK) { - wdt_reset(); + WDG_RESET(); heartbeat = 0; } diff --git a/radio/src/telemetry/flysky_ibus.cpp b/radio/src/telemetry/flysky_ibus.cpp index 9074daa21..0869fb0da 100644 --- a/radio/src/telemetry/flysky_ibus.cpp +++ b/radio/src/telemetry/flysky_ibus.cpp @@ -88,10 +88,10 @@ enum AFHDS2A_ID_END = 0xFF, // AC type telemetry with multiple values in one packet - AFHDS2A_ID_GPS_FULL = 0xFD, + AFHDS2A_ID_GPS_FULL = 0xFD, AFHDS2A_ID_VOLT_FULL = 0xF0, AFHDS2A_ID_ACC_FULL = 0xEF, - TX_RSSI_ID = 0x200, // Pseudo id outside 1 byte range of FlySky sensors + AFHDS2A_ID_TX_RSSI = 0x200, // Pseudo id outside 1 byte range of FlySky sensors }; const FlySkySensor flySkySensors[] = { @@ -133,7 +133,7 @@ const FlySkySensor flySkySensors[] = { {AFHDS2A_ID_RX_NOISE, ZSTR_RX_NOISE, UNIT_DB, 0}, // RX Noise {AFHDS2A_ID_RX_RSSI, ZSTR_RSSI, UNIT_DB, 0}, // RX RSSI (0xfc) {AFHDS2A_ID_RX_ERR_RATE, ZSTR_RX_QUALITY, UNIT_RAW, 0}, // RX error rate - {TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo sensor for TRSSI + {AFHDS2A_ID_TX_RSSI, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo sensor for TRSSI {0x00, NULL, UNIT_RAW, 0}, // sentinel }; @@ -227,7 +227,7 @@ static void processFlySkySensor(const uint8_t * packet, uint8_t type) void processFlySkyPacket(const uint8_t * packet) { // Set TX RSSI Value, reverse MULTIs scaling - setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[0], UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, AFHDS2A_ID_TX_RSSI, 0, 0, packet[0], UNIT_RAW, 0); const uint8_t * buffer = packet + 1; int sesnor = 0; @@ -241,7 +241,7 @@ void processFlySkyPacket(const uint8_t * packet) void processFlySkyPacketAC(const uint8_t * packet) { // Set TX RSSI Value, reverse MULTIs scaling - setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[0], UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, AFHDS2A_ID_TX_RSSI, 0, 0, packet[0], UNIT_RAW, 0); const uint8_t * buffer = packet + 1; while (buffer - packet < 26) //28 + 1(multi TX rssi) - 3(ac header) { diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 0bf13e407..0fe1a5bfd 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -64,7 +64,7 @@ bool pushFrskyTelemetryData(uint8_t data) break; case STATE_DATA_IN_FRAME: - if (data == BYTESTUFF) { + if (data == BYTE_STUFF) { dataState = STATE_DATA_XOR; // XOR next byte } else if (data == START_STOP) { diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index f526478f6..d4a9ab87a 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -95,99 +95,106 @@ enum FrSkyDataState { // FrSky new DATA IDs (2 bytes) #define ALT_FIRST_ID 0x0100 -#define ALT_LAST_ID 0x010f +#define ALT_LAST_ID 0x010F #define VARIO_FIRST_ID 0x0110 -#define VARIO_LAST_ID 0x011f +#define VARIO_LAST_ID 0x011F #define CURR_FIRST_ID 0x0200 -#define CURR_LAST_ID 0x020f +#define CURR_LAST_ID 0x020F #define VFAS_FIRST_ID 0x0210 -#define VFAS_LAST_ID 0x021f +#define VFAS_LAST_ID 0x021F #define CELLS_FIRST_ID 0x0300 -#define CELLS_LAST_ID 0x030f +#define CELLS_LAST_ID 0x030F #define T1_FIRST_ID 0x0400 -#define T1_LAST_ID 0x040f +#define T1_LAST_ID 0x040F #define T2_FIRST_ID 0x0410 -#define T2_LAST_ID 0x041f +#define T2_LAST_ID 0x041F #define RPM_FIRST_ID 0x0500 -#define RPM_LAST_ID 0x050f +#define RPM_LAST_ID 0x050F #define FUEL_FIRST_ID 0x0600 -#define FUEL_LAST_ID 0x060f +#define FUEL_LAST_ID 0x060F #define ACCX_FIRST_ID 0x0700 -#define ACCX_LAST_ID 0x070f +#define ACCX_LAST_ID 0x070F #define ACCY_FIRST_ID 0x0710 -#define ACCY_LAST_ID 0x071f +#define ACCY_LAST_ID 0x071F #define ACCZ_FIRST_ID 0x0720 -#define ACCZ_LAST_ID 0x072f +#define ACCZ_LAST_ID 0x072F #define GPS_LONG_LATI_FIRST_ID 0x0800 -#define GPS_LONG_LATI_LAST_ID 0x080f +#define GPS_LONG_LATI_LAST_ID 0x080F #define GPS_ALT_FIRST_ID 0x0820 -#define GPS_ALT_LAST_ID 0x082f +#define GPS_ALT_LAST_ID 0x082F #define GPS_SPEED_FIRST_ID 0x0830 -#define GPS_SPEED_LAST_ID 0x083f +#define GPS_SPEED_LAST_ID 0x083F #define GPS_COURS_FIRST_ID 0x0840 -#define GPS_COURS_LAST_ID 0x084f +#define GPS_COURS_LAST_ID 0x084F #define GPS_TIME_DATE_FIRST_ID 0x0850 -#define GPS_TIME_DATE_LAST_ID 0x085f +#define GPS_TIME_DATE_LAST_ID 0x085F #define A3_FIRST_ID 0x0900 -#define A3_LAST_ID 0x090f +#define A3_LAST_ID 0x090F #define A4_FIRST_ID 0x0910 -#define A4_LAST_ID 0x091f -#define AIR_SPEED_FIRST_ID 0x0a00 -#define AIR_SPEED_LAST_ID 0x0a0f -#define RBOX_BATT1_FIRST_ID 0x0b00 -#define RBOX_BATT1_LAST_ID 0x0b0f -#define RBOX_BATT2_FIRST_ID 0x0b10 -#define RBOX_BATT2_LAST_ID 0x0b1f -#define RBOX_STATE_FIRST_ID 0x0b20 -#define RBOX_STATE_LAST_ID 0x0b2f -#define RBOX_CNSP_FIRST_ID 0x0b30 -#define RBOX_CNSP_LAST_ID 0x0b3f -#define SD1_FIRST_ID 0x0b40 -#define SD1_LAST_ID 0x0b4f -#define ESC_POWER_FIRST_ID 0x0b50 -#define ESC_POWER_LAST_ID 0x0b5f -#define ESC_RPM_CONS_FIRST_ID 0x0b60 -#define ESC_RPM_CONS_LAST_ID 0x0b6f -#define ESC_TEMPERATURE_FIRST_ID 0x0b70 -#define ESC_TEMPERATURE_LAST_ID 0x0b7f +#define A4_LAST_ID 0x091F +#define AIR_SPEED_FIRST_ID 0x0A00 +#define AIR_SPEED_LAST_ID 0x0A0F +#define RBOX_BATT1_FIRST_ID 0x0B00 +#define RBOX_BATT1_LAST_ID 0x0B0F +#define RBOX_BATT2_FIRST_ID 0x0B10 +#define RBOX_BATT2_LAST_ID 0x0B1F +#define RBOX_STATE_FIRST_ID 0x0B20 +#define RBOX_STATE_LAST_ID 0x0B2F +#define RBOX_CNSP_FIRST_ID 0x0B30 +#define RBOX_CNSP_LAST_ID 0x0B3F +#define SD1_FIRST_ID 0x0B40 +#define SD1_LAST_ID 0x0B4F +#define ESC_POWER_FIRST_ID 0x0B50 +#define ESC_POWER_LAST_ID 0x0B5F +#define ESC_RPM_CONS_FIRST_ID 0x0B60 +#define ESC_RPM_CONS_LAST_ID 0x0B6f +#define ESC_TEMPERATURE_FIRST_ID 0x0B70 +#define ESC_TEMPERATURE_LAST_ID 0x0B7f #define X8R_FIRST_ID 0x0c20 -#define X8R_LAST_ID 0x0c2f +#define X8R_LAST_ID 0x0c2F #define S6R_FIRST_ID 0x0c30 -#define S6R_LAST_ID 0x0c3f -#define GASSUIT_TEMP1_FIRST_ID 0x0d00 -#define GASSUIT_TEMP1_LAST_ID 0x0d0f -#define GASSUIT_TEMP2_FIRST_ID 0x0d10 -#define GASSUIT_TEMP2_LAST_ID 0x0d1f -#define GASSUIT_SPEED_FIRST_ID 0x0d20 -#define GASSUIT_SPEED_LAST_ID 0x0d2f -#define GASSUIT_RES_VOL_FIRST_ID 0x0d30 -#define GASSUIT_RES_VOL_LAST_ID 0x0d3f -#define GASSUIT_RES_PERC_FIRST_ID 0x0d40 -#define GASSUIT_RES_PERC_LAST_ID 0x0d4f -#define GASSUIT_FLOW_FIRST_ID 0x0d50 -#define GASSUIT_FLOW_LAST_ID 0x0d5f -#define GASSUIT_MAX_FLOW_FIRST_ID 0x0d60 -#define GASSUIT_MAX_FLOW_LAST_ID 0x0d6f -#define GASSUIT_AVG_FLOW_FIRST_ID 0x0d70 -#define GASSUIT_AVG_FLOW_LAST_ID 0x0d7f -#define SBEC_POWER_FIRST_ID 0x0e50 -#define SBEC_POWER_LAST_ID 0x0e5f +#define S6R_LAST_ID 0x0c3F +#define GASSUIT_TEMP1_FIRST_ID 0x0D00 +#define GASSUIT_TEMP1_LAST_ID 0x0D0F +#define GASSUIT_TEMP2_FIRST_ID 0x0D10 +#define GASSUIT_TEMP2_LAST_ID 0x0D1F +#define GASSUIT_SPEED_FIRST_ID 0x0D20 +#define GASSUIT_SPEED_LAST_ID 0x0D2F +#define GASSUIT_RES_VOL_FIRST_ID 0x0D30 +#define GASSUIT_RES_VOL_LAST_ID 0x0D3F +#define GASSUIT_RES_PERC_FIRST_ID 0x0D40 +#define GASSUIT_RES_PERC_LAST_ID 0x0D4F +#define GASSUIT_FLOW_FIRST_ID 0x0D50 +#define GASSUIT_FLOW_LAST_ID 0x0D5F +#define GASSUIT_MAX_FLOW_FIRST_ID 0x0D60 +#define GASSUIT_MAX_FLOW_LAST_ID 0x0D6f +#define GASSUIT_AVG_FLOW_FIRST_ID 0x0D70 +#define GASSUIT_AVG_FLOW_LAST_ID 0x0D7f +#define SBEC_POWER_FIRST_ID 0x0E50 +#define SBEC_POWER_LAST_ID 0x0E5F #define DIY_FIRST_ID 0x5100 -#define DIY_LAST_ID 0x52ff +#define DIY_LAST_ID 0x52FF #define DIY_STREAM_FIRST_ID 0x5000 -#define DIY_STREAM_LAST_ID 0x50ff -#define FACT_TEST_ID 0xf000 -#define RSSI_ID 0xf101 -#define ADC1_ID 0xf102 -#define ADC2_ID 0xf103 -#define BATT_ID 0xf104 -#define RAS_ID 0xf105 -#define XJT_VERSION_ID 0xf106 -#define R9_PWR_ID 0xf107 -#define SP2UART_A_ID 0xfd00 -#define SP2UART_B_ID 0xfd01 -#define FUEL_QTY_FIRST_ID 0x0a10 -#define FUEL_QTY_LAST_ID 0x0a1f +#define DIY_STREAM_LAST_ID 0x50FF +#define FACT_TEST_ID 0xF000 +#define RSSI_ID 0xF101 +#define ADC1_ID 0xF102 +#define ADC2_ID 0xF103 +#define BATT_ID 0xF104 +#define RAS_ID 0xF105 +#define XJT_VERSION_ID 0xF106 +#define R9_PWR_ID 0xF107 +#define SP2UART_A_ID 0xFD00 +#define SP2UART_B_ID 0xFD01 +#define FUEL_QTY_FIRST_ID 0x0A10 +#define FUEL_QTY_LAST_ID 0x0A1F + +#if defined(MULTIMODULE) +// Virtual IDs, value can be changed to anything only used for display +#define RX_LQI_ID 0xFFFC +#define TX_LQI_ID 0xFFFD +#define TX_RSSI_ID 0xFFFE +#endif // Default sensor data IDs (Physical IDs + CRC) #define DATA_ID_VARIO 0x00 // 0 @@ -234,9 +241,9 @@ inline uint8_t TELEMETRY_RSSI() return telemetryData.rssi.value(); } -#define START_STOP 0x7E -#define BYTESTUFF 0x7D -#define STUFF_MASK 0x20 +constexpr uint8_t START_STOP = 0x7E; +constexpr uint8_t BYTE_STUFF = 0x7D; +constexpr uint8_t STUFF_MASK = 0x20; typedef enum { TS_IDLE = 0, // waiting for 0x5e frame marker @@ -283,7 +290,7 @@ inline bool isRasValueValid() #elif defined(PCBX9DP) || defined(PCBX9E) inline bool isRasValueValid() { - return telemetryData.xjtVersion != 0x0000 && telemetryData.xjtVersion != 0x00ff; + return telemetryData.xjtVersion != 0x0000 && telemetryData.xjtVersion != 0x00FF; } #else inline bool isRasValueValid() diff --git a/radio/src/telemetry/frsky_d.cpp b/radio/src/telemetry/frsky_d.cpp index b46b93e11..67445c193 100644 --- a/radio/src/telemetry/frsky_d.cpp +++ b/radio/src/telemetry/frsky_d.cpp @@ -71,6 +71,13 @@ void frskyDProcessPacket(const uint8_t *packet) setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, D_A1_ID, 0, 0, packet[1], UNIT_VOLTS, 0); setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, D_A2_ID, 0, 0, packet[2], UNIT_VOLTS, 0); setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, D_RSSI_ID, 0, 0, packet[3], UNIT_RAW, 0); +#if defined(MULTIMODULE) + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE) { + setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, TX_RSSI_ID, 0, 0, packet[4]>>1, UNIT_DB, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, RX_LQI_ID, 0, 0, packet[5] , UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, TX_LQI_ID , 0, 0, packet[6] , UNIT_RAW, 0); + } +#endif telemetryData.rssi.set(packet[3]); telemetryStreaming = TELEMETRY_TIMEOUT10ms; // reset counter only if valid packets are being detected break; @@ -263,42 +270,59 @@ void processHubPacket(uint8_t id, int16_t value) void frskyDSetDefault(int index, uint16_t id) { - TelemetrySensor & telemetrySensor = g_model.telemetrySensors[index]; + TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index]; telemetrySensor.id = id; telemetrySensor.instance = 0; - const FrSkyDSensor * sensor = getFrSkyDSensor(id); - if (sensor) { - TelemetryUnit unit = sensor->unit; - uint8_t prec = min(2, sensor->prec); - telemetrySensor.init(sensor->name, unit, prec); - if (id == D_RSSI_ID) { - telemetrySensor.filter = 1; - telemetrySensor.logs = true; - } - else if (id >= D_A1_ID && id <= D_A2_ID) { - telemetrySensor.custom.ratio = 132; - telemetrySensor.filter = 1; - } - else if (id == CURRENT_ID) { - telemetrySensor.onlyPositive = 1; - } - else if (id == BARO_ALT_AP_ID) { - telemetrySensor.autoOffset = 1; - } - if (unit == UNIT_RPMS) { - telemetrySensor.custom.ratio = 1; - telemetrySensor.custom.offset = 1; - } - else if (unit == UNIT_METERS) { - if (IS_IMPERIAL_ENABLE()) { - telemetrySensor.unit = UNIT_FEET; +#if defined(MULTIMODULE) + if (id == TX_RSSI_ID) { + telemetrySensor.init(ZSTR_TX_RSSI, UNIT_DB, 0); + telemetrySensor.filter = 1; + } + else if (id == TX_LQI_ID) { + telemetrySensor.init(ZSTR_TX_QUALITY, UNIT_RAW, 0); + telemetrySensor.filter = 1; + } + else if (id == RX_LQI_ID) { + telemetrySensor.init(ZSTR_RX_QUALITY, UNIT_RAW, 0); + telemetrySensor.filter = 1; + } + else +#endif + { + const FrSkyDSensor * sensor = getFrSkyDSensor(id); + if (sensor) { + TelemetryUnit unit = sensor->unit; + uint8_t prec = min(2, sensor->prec); + telemetrySensor.init(sensor->name, unit, prec); + if (id == D_RSSI_ID) { + telemetrySensor.filter = 1; + telemetrySensor.logs = true; + } + else if (id >= D_A1_ID && id <= D_A2_ID) { + telemetrySensor.custom.ratio = 132; + telemetrySensor.filter = 1; + } + else if (id == CURRENT_ID) { + telemetrySensor.onlyPositive = 1; + } + else if (id == BARO_ALT_AP_ID) { + telemetrySensor.autoOffset = 1; + } + if (unit == UNIT_RPMS) { + telemetrySensor.custom.ratio = 1; + telemetrySensor.custom.offset = 1; + } + else if (unit == UNIT_METERS) { + if (IS_IMPERIAL_ENABLE()) { + telemetrySensor.unit = UNIT_FEET; + } } } - } - else { - telemetrySensor.init(id); + else { + telemetrySensor.init(id); + } } storageDirty(EE_MODEL); diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index 7f347fa0a..9153c504d 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -20,31 +20,7 @@ #include "opentx.h" -class Pxx2Telemetry -{ - protected: - static void processGetHardwareInfoFrame(uint8_t module, uint8_t *frame); - - static void processReceiverSettingsFrame(uint8_t module, uint8_t *frame); - - static void processRegisterFrame(uint8_t module, uint8_t * frame); - - static void processBindFrame(uint8_t module, uint8_t * frame); - - static void processTelemetryFrame(uint8_t module, uint8_t * frame); - - static void processSpectrumFrame(uint8_t module, uint8_t * frame); - - static void processRadioFrame(uint8_t module, uint8_t * frame); - - static void processPowerMeterFrame(uint8_t module, uint8_t * frame); - - static void processAuthenticationFrame(uint8_t module, uint8_t * frame); - - public: -}; - -void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) +void processGetHardwareInfoFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_GET_HARDWARE_INFO) { return; @@ -59,6 +35,11 @@ void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) memcpy(&destination->information, &frame[4], length); if (destination->information.capabilities & ~((1 << MODULE_CAPABILITY_COUNT) - 1)) destination->information.capabilityNotSupported = true; + if (!globalData.upgradeModulePopup && destination->information.modelID == PXX2_MODULE_ISRM_S_X10S && + destination->information.swVersion.major == 0 && destination->information.swVersion.minor == 1 && destination->information.swVersion.revision < 5) { + globalData.upgradeModulePopup = 1; + POPUP_WARNING(STR_MODULE_UPGRADE_ALERT); + } } else if (index < PXX2_MAX_RECEIVERS_PER_MODULE && modelId < DIM(PXX2ReceiversNames)) { memcpy(&destination->receivers[index].information, &frame[4], length); @@ -68,7 +49,7 @@ void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) } } -void processModuleSettingsFrame(uint8_t module, uint8_t * frame) +void processModuleSettingsFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_MODULE_SETTINGS) { return; @@ -88,7 +69,7 @@ void processModuleSettingsFrame(uint8_t module, uint8_t * frame) moduleState[module].mode = MODULE_MODE_NORMAL; } -void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) +void processReceiverSettingsFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_RECEIVER_SETTINGS) { return; @@ -116,7 +97,7 @@ void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) moduleState[module].mode = MODULE_MODE_NORMAL; } -void processRegisterFrame(uint8_t module, uint8_t * frame) +void processRegisterFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_REGISTER) { return; @@ -151,7 +132,7 @@ void processRegisterFrame(uint8_t module, uint8_t * frame) } } -void processBindFrame(uint8_t module, uint8_t * frame) +void processBindFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_BIND) { return; @@ -202,7 +183,7 @@ void processBindFrame(uint8_t module, uint8_t * frame) } } -void processResetFrame(uint8_t module, uint8_t * frame) +void processResetFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_RESET) { return; @@ -215,7 +196,7 @@ void processResetFrame(uint8_t module, uint8_t * frame) moduleState[module].mode = MODULE_MODE_NORMAL; } -void processTelemetryFrame(uint8_t module, uint8_t * frame) +void processTelemetryFrame(uint8_t module, const uint8_t * frame) { uint8_t origin = (module << 2) + (frame[3] & 0x03); if (origin != TELEMETRY_ENDPOINT_SPORT) { @@ -224,13 +205,16 @@ void processTelemetryFrame(uint8_t module, uint8_t * frame) } #if defined(ACCESS_LIB) && !defined(SIMU) -void processAuthenticationFrame(uint8_t module, uint8_t * frame) +void processAuthenticationFrame(uint8_t module, const uint8_t * frame) { uint8_t cryptoType = frame[3]; uint8_t messageDigest[16] = {0}; if (frame[0] == 4 && PXX2_AUTH_REFUSED_FLAG == frame[4]) { - POPUP_INFORMATION(STR_AUTH_FAILURE); + if (!globalData.upgradeModulePopup) { + globalData.upgradeModulePopup = 1; + POPUP_INFORMATION(STR_AUTH_FAILURE); + } return; } @@ -241,12 +225,22 @@ void processAuthenticationFrame(uint8_t module, uint8_t * frame) intmoduleSendBuffer(pxx2.getData(), pxx2.getSize()); // we remain in AUTHENTICATION mode to avoid a CHANNELS frame is sent at the end of the mixing process } + + if (!globalData.upgradeModulePopup) { + if (globalData.authenticationCount >= 2) { + globalData.upgradeModulePopup = 1; + POPUP_WARNING(STR_MODULE_UPGRADE_ALERT); + } + else { + globalData.authenticationCount += 1; + } + } } #else #define processAuthenticationFrame(module, frame) #endif -void processSpectrumAnalyserFrame(uint8_t module, uint8_t * frame) +void processSpectrumAnalyserFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_SPECTRUM_ANALYSER) { return; @@ -273,7 +267,7 @@ void processSpectrumAnalyserFrame(uint8_t module, uint8_t * frame) } } -void processPowerMeterFrame(uint8_t module, uint8_t * frame) +void processPowerMeterFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_POWER_METER) { return; @@ -285,7 +279,7 @@ void processPowerMeterFrame(uint8_t module, uint8_t * frame) } } -void processOtaUpdateFrame(uint8_t module, uint8_t * frame) +void processOtaUpdateFrame(uint8_t module, const uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_OTA_UPDATE) { return; @@ -311,7 +305,7 @@ void processOtaUpdateFrame(uint8_t module, uint8_t * frame) } } -void processModuleFrame(uint8_t module, uint8_t *frame) +void processModuleFrame(uint8_t module, const uint8_t *frame) { switch (frame[2]) { case PXX2_TYPE_ID_HW_INFO: @@ -348,7 +342,7 @@ void processModuleFrame(uint8_t module, uint8_t *frame) } } -void processToolsFrame(uint8_t module, uint8_t * frame) +void processToolsFrame(uint8_t module, const uint8_t * frame) { switch (frame[2]) { case PXX2_TYPE_ID_POWER_METER: @@ -361,8 +355,13 @@ void processToolsFrame(uint8_t module, uint8_t * frame) } } -void processPXX2Frame(uint8_t module, uint8_t *frame) +void processPXX2Frame(uint8_t module, const uint8_t * frame) { + LOG_TELEMETRY_WRITE_START(); + for (uint8_t i = 0; i < 1 + frame[0]; i++) { + LOG_TELEMETRY_WRITE_BYTE(frame[i]); + } + switch (frame[1]) { case PXX2_TYPE_C_MODULE: processModuleFrame(module, frame); diff --git a/radio/src/telemetry/frsky_sport.cpp b/radio/src/telemetry/frsky_sport.cpp index 73c3ec324..d67da2559 100644 --- a/radio/src/telemetry/frsky_sport.cpp +++ b/radio/src/telemetry/frsky_sport.cpp @@ -31,6 +31,10 @@ struct FrSkySportSensor { const FrSkySportSensor sportSensors[] = { { RSSI_ID, RSSI_ID, 0, ZSTR_RSSI, UNIT_DB, 0 }, +#if defined(MULTIMODULE) + { TX_RSSI_ID, TX_RSSI_ID, 0, ZSTR_TX_RSSI , UNIT_DB , 0 }, + { TX_LQI_ID , TX_LQI_ID, 0, ZSTR_TX_QUALITY, UNIT_RAW, 0 }, +#endif { ADC1_ID, ADC1_ID, 0, ZSTR_A1, UNIT_VOLTS, 1 }, { ADC2_ID, ADC2_ID, 0, ZSTR_A2, UNIT_VOLTS, 1 }, { A3_FIRST_ID, A3_LAST_ID, 0, ZSTR_A3, UNIT_VOLTS, 2 }, @@ -192,6 +196,12 @@ void sportProcessTelemetryPacketWithoutCrc(uint8_t origin, const uint8_t * packe else { telemetryData.rssi.set(data); } +#if defined(MULTIMODULE) + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE) { + sportProcessTelemetryPacket(TX_RSSI_ID, 0, instance, packet[5] >> 1, UNIT_DB); + sportProcessTelemetryPacket(TX_LQI_ID, 0, instance, packet[7], UNIT_RAW); + } +#endif } else if (dataId == R9_PWR_ID) { uint32_t r9pwr[] = {100, 200, 500, 1000}; diff --git a/radio/src/telemetry/hitec.cpp b/radio/src/telemetry/hitec.cpp index 93a0f6a37..3d4770b81 100644 --- a/radio/src/telemetry/hitec.cpp +++ b/radio/src/telemetry/hitec.cpp @@ -150,8 +150,8 @@ enum HITEC_ID_AIR_SPEED = 0x1A02, // Air speed HITEC_ID_VARIO = 0x1B00, // Vario HITEC_ID_ALT = 0x1B02, // Vario - TX_RSSI_ID = 0xFF00, // Pseudo id outside 1 byte range of Hitec sensors - TX_LQI_ID = 0xFF01, // Pseudo id outside 1 byte range of Hitec sensors + HITEC_ID_TX_RSSI = 0xFF00, // Pseudo id outside 1 byte range of Hitec sensors + HITEC_ID_TX_LQI = 0xFF01, // Pseudo id outside 1 byte range of Hitec sensors }; const HitecSensor hitecSensors[] = { @@ -193,8 +193,8 @@ const HitecSensor hitecSensors[] = { {HITEC_ID_VARIO, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 1}, // Vario {HITEC_ID_ALT, ZSTR_ALT, UNIT_METERS, 1}, // Altitude - {TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors - {TX_LQI_ID, ZSTR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors// Pseudo sensor for TLQI + {HITEC_ID_TX_RSSI, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors + {HITEC_ID_TX_LQI, ZSTR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors// Pseudo sensor for TLQI {0x00, NULL, UNIT_RAW, 0}, // sentinel }; @@ -212,12 +212,12 @@ void processHitecPacket(const uint8_t * packet) static uint16_t rssi = 0, lqi = 0; // Set TX RSSI Value, reverse MULTIs scaling rssi = ((packet[0] * 10) + (rssi * 90)) / 100; // quick filtering - setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, TX_RSSI_ID, 0, 0, rssi >> 1, UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TX_RSSI, 0, 0, rssi >> 1, UNIT_RAW, 0); telemetryData.rssi.set(rssi >> 1); if (packet[0] > 0) telemetryStreaming = TELEMETRY_TIMEOUT10ms; // Set TX LQI Value, reverse MULTIs scaling lqi = ((packet[1] * 10) + (lqi * 90)) / 100; // quick filtering - setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, TX_LQI_ID, 0, 0, lqi, UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TX_LQI, 0, 0, lqi, UNIT_RAW, 0); const HitecSensor * sensor; int32_t value, deg, min, sec, alt, amp; diff --git a/radio/src/telemetry/hott.cpp b/radio/src/telemetry/hott.cpp new file mode 100644 index 000000000..f36236add --- /dev/null +++ b/radio/src/telemetry/hott.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) OpenTX + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + */ + +#include "opentx.h" + +/* Telemetry +packet[0] = TX RSSI value +packet[1] = TX LQI value +packet[2] = frame number +packet[3-12] telemetry data + +The frame number takes the following values: 0x00, 0x01, 0x02, 0x03 and 0x04. The frames can be present or not, they also do not have to follow each others. +Here is a description of the telemetry data for each frame number: +- frame 0x00 +[3] = [12] = ?? +[4] = RX_Voltage*10 in V +[5] = Temperature-20 in °C +[6] = RX_RSSI +[7] = RX_LQI ?? +[8] = RX_STR ?? +[9,10] = [10]*256+[9]=max lost packet time in ms, max value seems 2s=0x7D0 +[11] = 0x00 ?? +- frame 0x01 Unknown +- frame 0x02 Unknown +- frame 0x03 Unknown +- frame 0x04 Unknown +*/ + +struct HottSensor +{ + const uint16_t id; + const char * name; + const TelemetryUnit unit; + const uint8_t precision; +}; + +// telemetry frames +enum +{ + HOTT_FRAME_00 = 0x00, + HOTT_FRAME_01 = 0x01, + HOTT_FRAME_02 = 0x02, + HOTT_FRAME_03 = 0x03, + HOTT_FRAME_04 = 0x04, +}; + +#define HOTT_TELEM_NORMAL 0x00 +#define HOTT_TELEM_BIND 0x40 +#define HOTT_TELEM_MENU 0x80 + +// telemetry sensors ID +enum +{ + HOTT_ID_RX_VOLTAGE = 0x0004, // RX_Batt Voltage + HOTT_ID_TEMP1 = 0x0005, // RX Temperature sensor + HOTT_TX_RSSI_ID = 0xFF00, // Pseudo id outside 1 byte range of Hott sensors + HOTT_TX_LQI_ID = 0xFF01, // Pseudo id outside 1 byte range of Hott sensors + HOTT_RX_RSSI_ID = 0xFF02, // Pseudo id outside 1 byte range of Hott sensors + HOTT_RX_LQI_ID = 0xFF03, // Pseudo id outside 1 byte range of Hott sensors +}; + +const HottSensor hottSensors[] = { + //frame 00 + {HOTT_ID_RX_VOLTAGE, ZSTR_BATT, UNIT_VOLTS, 1}, // RX_Batt Voltage + {HOTT_ID_TEMP1, ZSTR_TEMP1, UNIT_CELSIUS, 0}, // RX Temperature sensor + //frame 01 + //frame 02 + //frame 03 + //frame 04 + {HOTT_TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors + {HOTT_TX_LQI_ID, ZSTR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors + {HOTT_RX_RSSI_ID, ZSTR_RSSI, UNIT_DB, 0}, // RX RSSI + {HOTT_RX_LQI_ID, ZSTR_RX_QUALITY, UNIT_RAW, 0}, // RX LQI + {0x00, NULL, UNIT_RAW, 0}, // sentinel +}; + +const HottSensor * getHottSensor(uint16_t id) +{ + for (const HottSensor * sensor = hottSensors; sensor->id; sensor++) { + if (id == sensor->id) + return sensor; + } + return nullptr; +} + +void processHottPacket(const uint8_t * packet) +{ + // Set TX RSSI Value + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_TX_RSSI_ID, 0, 0, packet[0]>>1, UNIT_RAW, 0); + // Set TX LQI Value + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_TX_LQI_ID, 0, 0, packet[1], UNIT_RAW, 0); + +#if defined(LUA) + #define HOTT_MENU_NBR_PAGE 0x13 + // Config menu consists of the different telem pages put all together + // [3] = config mennu page 0x00 to 0x12. + // Page X [4] = seems like all the telem pages with the same value are going together to make the full config menu text. Seen so far 'a', 'b', 'c', 'd' + // Page X [5..13] = 9 ascii chars to be displayed, char is highlighted when ascii|0x80 + // Screen display is 21 characters large which means that once the first 21 chars are filled go to the begining of the next line + // Menu commands are sent through TX packets: + // packet[28]= 0xXF=>no key press, 0xXD=>down, 0xXB=>up, 0xX9=>enter, 0xXE=>right, 0xX7=>left with X=0 or D + // packet[29]= 0xX1/0xX9 with X=0 or X counting 0,1,1,2,2,..,9,9 + if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0) { + // HoTT Lua script is running + if (Multi_Buffer[4] == 0xFF) { + // Init + memset(&Multi_Buffer[6], ' ', HOTT_MENU_NBR_PAGE * 9); // Clear text buffer + } + + if (packet[3] < HOTT_MENU_NBR_PAGE && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) { + Multi_Buffer[4] = packet[4]; // Store current menu being received + memcpy(&Multi_Buffer[6 + packet[3] * 9], &packet[5], 9); // Store the received page in the buffer + } + return; + } +#endif + + const HottSensor * sensor; + int32_t value; + + if (packet[2] == HOTT_TELEM_NORMAL) { + switch (packet[3]) { + case HOTT_FRAME_00: + // RX_VOLT + value = packet[5]; + sensor = getHottSensor(HOTT_ID_RX_VOLTAGE); + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RX_VOLTAGE, 0, 0, value, sensor->unit, sensor->precision); + // RX_TEMP + value = packet[6] - 20; + sensor = getHottSensor(HOTT_ID_TEMP1); + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, 0, value, sensor->unit, sensor->precision); + // RX_RSSI + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_RX_RSSI_ID, 0, 0, packet[7], UNIT_DB, 0); + // RX_LQI + telemetryData.rssi.set(packet[8]); + if (packet[8] > 0) + telemetryStreaming = TELEMETRY_TIMEOUT10ms; + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_RX_LQI_ID, 0, 0, packet[8], UNIT_RAW, 0); + break; + + default: + // unknown + value = (packet[7] << 24) | (packet[6] << 16) | (packet[5] << 8) | packet[4]; + setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, 0xFE00 | packet[3], 0, 0, value, UNIT_RAW, 0); + break; + } + } +} + +void hottSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance) +{ + TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index]; + telemetrySensor.id = id; + telemetrySensor.subId = subId; + telemetrySensor.instance = instance; + + const HottSensor * sensor = getHottSensor(id); + if (sensor) { + TelemetryUnit unit = sensor->unit; + uint8_t prec = min(2, sensor->precision); + telemetrySensor.init(sensor->name, unit, prec); + if (unit == UNIT_RPMS) { + telemetrySensor.custom.ratio = 1; + telemetrySensor.custom.offset = 1; + } + } + else { + telemetrySensor.init(id); + } + + storageDirty(EE_MODEL); +} diff --git a/radio/src/telemetry/hott.h b/radio/src/telemetry/hott.h new file mode 100644 index 000000000..797601d11 --- /dev/null +++ b/radio/src/telemetry/hott.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + */ + +#ifndef _HOTT_H +#define _HOTT_H + +void hottSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); + +// Used by multi protocol +void processHottPacket(const uint8_t * packet); + +#endif diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index 5ae925fc4..07ab99392 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -39,7 +39,8 @@ enum MultiPacketTypes : uint8_t HitecTelemetry, SpectrumScannerPacket, FlyskyIBusTelemetryAC, - MultiRxChannels + MultiRxChannels, + HottTelemetry, }; enum MultiBufferState : uint8_t @@ -65,6 +66,7 @@ static MultiModuleSyncStatus multiSyncStatus[NUM_MODULES] = {MultiModuleSyncStat static uint8_t multiBindStatus[NUM_MODULES] = {MULTI_NORMAL_OPERATION, MULTI_NORMAL_OPERATION}; static MultiBufferState multiTelemetryBufferState[NUM_MODULES]; +static uint16_t multiTelemetryLastRxTS[NUM_MODULES]; MultiModuleStatus &getMultiModuleStatus(uint8_t module) { @@ -96,6 +98,11 @@ void setMultiTelemetryBufferState(uint8_t module, MultiBufferState state) multiTelemetryBufferState[module] = state; } +static uint16_t& getMultiTelemetryLastRxTS(uint8_t module) +{ + return multiTelemetryLastRxTS[module]; +} + // Use additional telemetry buffer uint8_t intTelemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; uint8_t intTelemetryRxBufferCount; @@ -107,6 +114,7 @@ static MultiModuleSyncStatus multiSyncStatus; static uint8_t multiBindStatus = MULTI_NORMAL_OPERATION; static MultiBufferState multiTelemetryBufferState; +static uint16_t multiTelemetryLastRxTS; MultiModuleStatus& getMultiModuleStatus(uint8_t) { @@ -138,6 +146,11 @@ void setMultiTelemetryBufferState(uint8_t, MultiBufferState state) multiTelemetryBufferState = state; } +uint16_t& getMultiTelemetryLastRxTS(uint8_t module) +{ + return multiTelemetryLastRxTS; +} + #endif // INTERNAL_MODULE_MULTI @@ -150,9 +163,9 @@ static MultiBufferState guessProtocol(uint8_t module) } #endif - if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_DSM2) + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) return SpektrumTelemetryFallback; - else if (g_model.moduleData[module].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) + else if (g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) return FlyskyTelemetryFallback; else return FrskyTelemetryFallback; @@ -196,20 +209,38 @@ static void processMultiScannerPacket(const uint8_t *data) } } -static void processMultiStatusPacket(const uint8_t * data, uint8_t module) +static void processMultiStatusPacket(const uint8_t * data, uint8_t module, uint8_t len) { MultiModuleStatus &status = getMultiModuleStatus(module); // At least two status packets without bind flag bool wasBinding = status.isBinding(); + status.lastUpdate = get_tmr10ms(); status.flags = data[0]; status.major = data[1]; status.minor = data[2]; status.revision = data[3]; status.patch = data[4]; - status.lastUpdate = get_tmr10ms(); - + if (len < 6) { + status.ch_order = 0xFF; + } + else { + status.ch_order = data[5]; + if (len >= 24) { + status.protocolNext = data[6]; + status.protocolPrev = data[7]; + memcpy(status.protocolName, &data[8], 7); + status.protocolName[7] = 0; + status.protocolSubNbr = data[15] & 0x0F; + memcpy(status.protocolSubName, &data[16], 8); + status.protocolSubName[8] = 0; + status.optionDisp = data[15] >> 4; + } + else { + status.protocolName[0] = 0; + } + } if (getMultiModuleStatus(module).requiresFailsafeCheck) { getMultiModuleStatus(module).requiresFailsafeCheck = false; if (getMultiModuleStatus(module).supportsFailsafe() && g_model.moduleData[module].failsafeMode == FAILSAFE_NOT_SET) @@ -289,7 +320,7 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) switch (type) { case MultiStatus: if (len >= 5) - processMultiStatusPacket(data, module); + processMultiStatusPacket(data, module, len); break; case DSMBindPacket: @@ -327,6 +358,13 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) TRACE("[MP] Received Hitec telemetry len %d < 8", len); break; + case HottTelemetry: + if (len >= 14) + processHottPacket(data); + else + TRACE("[MP] Received HoTT telemetry len %d < 14", len); + break; + case FrSkyHubTelemetry: if (len >= 4) frskyDProcessPacket(data); @@ -382,17 +420,7 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) } } -// sprintf does not work AVR ARM -// use a small helper function -static void appendInt(char * buf, uint32_t val) -{ - while (*buf) - buf++; - - strAppendUnsigned(buf, val); -} - -#define MIN_REFRESH_RATE 7000 +#define MIN_REFRESH_RATE 5500 void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag) { @@ -444,8 +472,8 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin adjustedRefreshRate = (adjustedRefreshRate + perframeps); // Safeguards - if (adjustedRefreshRate < 6 * 1000 * 1000) - adjustedRefreshRate = 6 * 1000 * 1000; + if (adjustedRefreshRate < MIN_REFRESH_RATE * 1000) + adjustedRefreshRate = MIN_REFRESH_RATE * 1000; if (adjustedRefreshRate > 30 * 1000 * 1000) adjustedRefreshRate = 30 * 1000 * 1000; @@ -454,12 +482,11 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin static uint8_t counter; -uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() +const uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() { if (!isValid() || refreshRate == 0) return 18000; - counter = (uint8_t) (counter + 1 % 10); uint16_t rate = (uint16_t) ((adjustedRefreshRate + counter * 50) / 500); // Check how far off we are from our target, positive means we are too slow, negative we are too fast @@ -471,37 +498,27 @@ uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() return rate; } - -static void prependSpaces(char * buf, int val) -{ - while (*buf) - buf++; - - int k = 10000; - while (val / k == 0 && k > 0) { - *buf = ' '; - buf++; - k /= 10; - } - *buf = '\0'; -} - void MultiModuleSyncStatus::getRefreshString(char * statusText) { if (!isValid()) { return; } - strcpy(statusText, "L "); - prependSpaces(statusText, inputLag); - appendInt(statusText, inputLag); - strcat(statusText, "ns R "); - prependSpaces(statusText, adjustedRefreshRate / 1000); - appendInt(statusText, (uint32_t) (adjustedRefreshRate / 1000)); - strcat(statusText, "ns"); + char * tmp = statusText; +#if defined(DEBUG) + *tmp++ = 'L'; + tmp = strAppendUnsigned(tmp, inputLag, 5); + tmp = strAppend(tmp, "us R "); + tmp = strAppendUnsigned(tmp, (uint32_t) (adjustedRefreshRate / 1000), 5); + tmp = strAppend(tmp, "us"); +#else + tmp = strAppend(tmp, "Sync at "); + tmp = strAppendUnsigned(tmp, (uint32_t) (adjustedRefreshRate / 1000000)); + tmp = strAppend(tmp, " ms"); +#endif } -void MultiModuleStatus::getStatusString(char * statusText) +void MultiModuleStatus::getStatusString(char * statusText) const { if (!isValid()) { #if defined(PCBFRSKY) @@ -531,19 +548,36 @@ void MultiModuleStatus::getStatusString(char * statusText) return; } + if (major == 1 && minor < 3 && SLOW_BLINK_ON_PHASE) { + strcpy(statusText, STR_MODULE_UPGRADE); + } + else { + char * tmp = statusText; + *tmp++ = 'V'; + tmp = strAppendUnsigned(tmp, major); + *tmp++ = '.'; + tmp = strAppendUnsigned(tmp, minor); + *tmp++ = '.'; + tmp = strAppendUnsigned(tmp, revision); + *tmp++ = '.'; + tmp = strAppendUnsigned(tmp, patch); - strcpy(statusText, "V"); - appendInt(statusText, major); - strcat(statusText, "."); - appendInt(statusText, minor); - strcat(statusText, "."); - appendInt(statusText, revision); - strcat(statusText, "."); - appendInt(statusText, patch); - strcat(statusText, " "); - - if (isBinding()) - strcat(statusText, STR_MODULE_BINDING); + if (isBinding()) { + strcpy(tmp, " " TR_MODULE_BINDING); + } + else if (ch_order != 0xFF) { + uint8_t temp = ch_order; + *tmp++ = ' '; + *(tmp + (temp & 0x03)) = 'A'; + temp >>= 2; + *(tmp + (temp & 0x03)) = 'E'; + temp >>= 2; + *(tmp + (temp & 0x03)) = 'T'; + temp >>= 2; + *(tmp + (temp & 0x03)) = 'R'; + *(tmp + 4) = '\0'; + } + } } static uint8_t * getRxBuffer(uint8_t moduleIdx) @@ -600,7 +634,14 @@ 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); + uint16_t &lastRxTS = getMultiTelemetryLastRxTS(module); + uint16_t nowMs = (uint16_t)RTOS_GET_MS(); + if (nowMs - lastRxTS > 15) + setMultiTelemetryBufferState(module, NoProtocolDetected); + lastRxTS = nowMs; + + // debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", getMultiTelemetryBufferState(module), data, rxBufferCount); + switch (getMultiTelemetryBufferState(module)) { case NoProtocolDetected: if (data == 'M') { @@ -691,16 +732,22 @@ void processMultiTelemetryData(uint8_t data, uint8_t module) break; case ReceivingMultiStatus: - rxBuffer[rxBufferCount++] = data; - if (rxBufferCount > 5 && rxBuffer[0] == rxBufferCount - 1) { - processMultiStatusPacket(rxBuffer + 1, module); - rxBufferCount = 0; - setMultiTelemetryBufferState(module, NoProtocolDetected); + if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + rxBuffer[rxBufferCount++] = data; + if (rxBufferCount > 5 && rxBuffer[0] == rxBufferCount - 1) { + processMultiStatusPacket(rxBuffer + 1, module, rxBuffer[0]); + rxBufferCount = 0; + setMultiTelemetryBufferState(module, NoProtocolDetected); + } + if (rxBufferCount > 24) { + // too long ignore + TRACE("Overlong multi status packet detected ignoring, wanted %d", rxBuffer[0]); + rxBufferCount = 0; + setMultiTelemetryBufferState(module, NoProtocolDetected); + } } - if (rxBufferCount > 10) { - // too long ignore - TRACE("Overlong multi status packet detected ignoring, wanted %d", rxBuffer[0]); - rxBufferCount = 0; + else { + TRACE("[MP] array size %d error", rxBufferCount); setMultiTelemetryBufferState(module, NoProtocolDetected); } break; diff --git a/radio/src/telemetry/multi.h b/radio/src/telemetry/multi.h index 83f3de6fb..e9b9ada15 100644 --- a/radio/src/telemetry/multi.h +++ b/radio/src/telemetry/multi.h @@ -21,6 +21,9 @@ #ifndef OPENTX_MULTI_H #define OPENTX_MULTI_H +#define MULTI_BUFFER_SIZE 177 +extern uint8_t * Multi_Buffer; + /* Multiprotocol telemetry definition @@ -93,23 +96,21 @@ void processMultiTelemetryData(uint8_t data, uint8_t module); // This should be put into the Module definition if other modules gain this functionality struct MultiModuleSyncStatus { - uint32_t adjustedRefreshRate; // in ps + uint32_t adjustedRefreshRate = 9000 * 1000; // in ps tmr10ms_t lastUpdate; uint16_t refreshRate; uint16_t inputLag; uint8_t interval; uint8_t target; - inline bool isValid() {return (get_tmr10ms() - lastUpdate < 100);} - void getRefreshString(char* refreshText); - uint16_t getAdjustedRefreshRate(); - void calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag); - - MultiModuleSyncStatus() { - // Initialise to a valid value - adjustedRefreshRate=9000 * 1000; + inline bool isValid() const + { + return (get_tmr10ms() - lastUpdate < 100); } - + + void getRefreshString(char * refreshText); + const uint16_t getAdjustedRefreshRate(); + void calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag); }; MultiModuleSyncStatus& getMultiSyncStatus(uint8_t module); @@ -121,14 +122,24 @@ struct MultiModuleStatus { uint8_t minor; uint8_t revision; uint8_t patch; + uint8_t ch_order; uint8_t flags; uint8_t requiresFailsafeCheck; tmr10ms_t lastUpdate; - void getStatusString(char* statusText); + uint8_t protocolPrev = 0; + uint8_t protocolNext = 0; + char protocolName[8] = {0}; + uint8_t protocolSubNbr = 0; + char protocolSubName[9] = {0}; + uint8_t optionDisp = 0; + + void getStatusString(char * statusText) const; inline bool isValid() const { return (bool)(get_tmr10ms() - lastUpdate < 200); } + inline bool isBufferFull() const { return (bool) (flags & 0x80); } + inline bool supportsDisableMapping() const { return (bool) (flags & 0x40); } inline bool supportsFailsafe() const { return (bool) (flags & 0x20); } inline bool isWaitingforBind() const { return (bool) (flags & 0x10); } inline bool isBinding() const { return (bool) (flags & 0x08); } diff --git a/radio/src/telemetry/spektrum.cpp b/radio/src/telemetry/spektrum.cpp index ae5435845..29229cf2b 100644 --- a/radio/src/telemetry/spektrum.cpp +++ b/radio/src/telemetry/spektrum.cpp @@ -373,7 +373,7 @@ void processSpektrumPacket(const uint8_t *packet) void processDSMBindPacket(uint8_t module, const uint8_t *packet) { uint32_t debugval; - if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 + if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2 && g_model.moduleData[module].multi.autoBindMode) { int channels = packet[5]; @@ -399,7 +399,7 @@ void processDSMBindPacket(uint8_t module, const uint8_t *packet) setTelemetryValue(PROTOCOL_TELEMETRY_SPEKTRUM, (I2C_PSEUDO_TX << 8) + 4, 0, 0, debugval, UNIT_RAW, 0); /* Finally stop binding as the rx just told us that it is bound */ - if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[module].mode == MODULE_MODE_BIND) { + if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[module].mode == MODULE_MODE_BIND) { setMultiBindStatus(module, MULTI_BIND_FINISHED); } } diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 7b95b3275..ec76c09f2 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -79,6 +79,7 @@ inline bool isBadAntennaDetected() void telemetryWakeup() { uint8_t requiredTelemetryProtocol = modelTelemetryProtocol(); + uint8_t data; #if defined(REVX) uint8_t requiredSerialInversion = g_model.moduleData[EXTERNAL_MODULE].invertedSerial; @@ -100,6 +101,7 @@ void telemetryWakeup() processPXX2Frame(INTERNAL_MODULE, frame); } #endif + #if defined(EXTMODULE_USART) while (extmoduleFifo.getFrame(frame)) { processPXX2Frame(EXTERNAL_MODULE, frame); @@ -108,15 +110,16 @@ void telemetryWakeup() #endif #if defined(INTERNAL_MODULE_MULTI) - while(!intmoduleFifo.isEmpty()) { - uint8_t b=0; - intmoduleFifo.pop(b); - processMultiTelemetryData(b, INTERNAL_MODULE); + if (intmoduleFifo.pop(data)) { + LOG_TELEMETRY_WRITE_START(); + do { + processMultiTelemetryData(data, INTERNAL_MODULE); + LOG_TELEMETRY_WRITE_BYTE(data); + } while (intmoduleFifo.pop(data)); } #endif #if defined(STM32) - uint8_t data; if (telemetryGetByte(&data)) { LOG_TELEMETRY_WRITE_START(); do { @@ -126,7 +129,6 @@ void telemetryWakeup() } #elif defined(PCBSKY9X) if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { - uint8_t data; while (telemetrySecondPortReceive(data)) { processTelemetryData(data); } diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 1cea88d9e..2f32d3551 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -28,6 +28,7 @@ #include "spektrum.h" #include "flysky_ibus.h" #include "hitec.h" + #include "hott.h" #include "multi.h" #endif #include "myeeprom.h" @@ -106,8 +107,13 @@ void frskyDSetDefault(int index, uint16_t id); extern uint8_t telemetryProtocol; #if defined (MULTIMODULE) -#define IS_D16_MULTI() ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FRSKY) && (g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH)) -#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && IS_D16_MULTI())) +#define IS_D16_MULTI(module) ((g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) && (g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_LBT || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_LBT_8CH)) +#define IS_HOTT_MULTI(module) (g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT) +#if defined(HARDWARE_INTERNAL_MODULE) +#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (IS_D16_MULTI(INTERNAL_MODULE)||IS_D16_MULTI(EXTERNAL_MODULE)))) +#else +#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && IS_D16_MULTI(EXTERNAL_MODULE))) +#endif #else #define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) #endif @@ -246,6 +252,6 @@ extern OutputTelemetryBuffer outputTelemetryBuffer __DMA; extern Fifo * luaInputTelemetryFifo; #endif -void processPXX2Frame(uint8_t module, uint8_t *frame); +void processPXX2Frame(uint8_t module, const uint8_t *frame); #endif // _TELEMETRY_H_ diff --git a/radio/src/telemetry/telemetry_sensors.cpp b/radio/src/telemetry/telemetry_sensors.cpp index 868396536..dc9742b55 100644 --- a/radio/src/telemetry/telemetry_sensors.cpp +++ b/radio/src/telemetry/telemetry_sensors.cpp @@ -530,6 +530,9 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui case PROTOCOL_TELEMETRY_HITEC: hitecSetDefault(index, id, subId, instance); break; + case PROTOCOL_TELEMETRY_HOTT: + hottSetDefault(index, id, subId, instance); + break; #endif #if defined(LUA) case PROTOCOL_TELEMETRY_LUA: diff --git a/radio/src/tests/CMakeLists.txt b/radio/src/tests/CMakeLists.txt index 97516f0c3..18f462aed 100644 --- a/radio/src/tests/CMakeLists.txt +++ b/radio/src/tests/CMakeLists.txt @@ -52,8 +52,8 @@ if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields") endif() - add_executable(gtests-radio EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp ../targets/simu/simufatfs.cpp) - add_dependencies(gtests-radio ${RADIO_DEPENDENCIES} gtests-radio-lib) + add_executable(gtests-radio EXCLUDE_FROM_ALL ${GTEST_SRC} ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp ../targets/simu/simufatfs.cpp) + add_dependencies(gtests-radio ${RADIO_DEPENDENCIES} ${FIRMWARE_DEPENDENCIES} gtests-radio-lib) if(PCB STREQUAL X12S OR PCB STREQUAL X10) add_dependencies(gtests-radio ${HORUS_MODEL_FILES}) endif() diff --git a/radio/src/tests/MidsizeNextPosPrec1_128x64.png b/radio/src/tests/MidsizeNextPosPrec1_128x64.png new file mode 100644 index 000000000..b302ea0d5 Binary files /dev/null and b/radio/src/tests/MidsizeNextPosPrec1_128x64.png differ diff --git a/radio/src/tests/MidsizeNextPosPrec1_212x64.png b/radio/src/tests/MidsizeNextPosPrec1_212x64.png new file mode 100644 index 000000000..2d00c5e6b Binary files /dev/null and b/radio/src/tests/MidsizeNextPosPrec1_212x64.png differ diff --git a/radio/src/tests/lcd.cpp b/radio/src/tests/lcd.cpp index 5bce5d535..5bbea96e9 100644 --- a/radio/src/tests/lcd.cpp +++ b/radio/src/tests/lcd.cpp @@ -96,9 +96,7 @@ bool checkScreenshot(const QString & test) } } -#if defined(COLORLCD) -// TODO -#else +#if !defined(COLORLCD) TEST(outdezNAtt, test_unsigned) { lcdClear(); @@ -238,6 +236,19 @@ TEST(Lcd, Midsize) EXPECT_TRUE(checkScreenshot("midsize")); } +TEST(Lcd, MidsizeNextPosPrec1) +{ + lcdClear(); + + lcdDrawText(10, 1, "80", MIDSIZE); + lcdDrawText(lcdNextPos, 1, "V", MIDSIZE); + + lcdDrawNumber(10, 15, 80, MIDSIZE | PREC1); + lcdDrawText(lcdNextPos, 15, "V", MIDSIZE); + + EXPECT_TRUE(checkScreenshot("MidsizeNextPosPrec1")); +} + TEST(Lcd, Dblsize) { lcdClear(); diff --git a/radio/src/thirdparty/libACCESS b/radio/src/thirdparty/libACCESS index 1bae46726..63802e6d5 160000 --- a/radio/src/thirdparty/libACCESS +++ b/radio/src/thirdparty/libACCESS @@ -1 +1 @@ -Subproject commit 1bae467262bbe8232111a6baee7195850cef2531 +Subproject commit 63802e6d50a9c7e07a6ae063f162320227995248 diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 22233dc42..c046eda70 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -149,7 +149,7 @@ const char STR_DELAYDOWN[] = TR_DELAYDOWN; const char STR_DELAYUP[] = TR_DELAYUP; const char STR_SLOWDOWN[] = TR_SLOWDOWN; const char STR_SLOWUP[] = TR_SLOWUP; -const char STR_MIXER[] = TR_MIXER; +const char STR_MIXES[] = TR_MIXES; const char STR_CV[] = TR_CV; const char STR_GV[] = TR_GV; const char STR_RANGE[] = TR_RANGE; @@ -444,6 +444,7 @@ const char STR_MIXNAME[] = TR_MIXNAME; const char STR_INPUTNAME[] = TR_INPUTNAME; const char STR_EXPONAME[] = TR_EXPONAME; const char STR_TRAINER[] = TR_TRAINER; +const char STR_CHANS[] = TR_CHANS; const char STR_MODULE_BIND[] = TR_MODULE_BIND; const char STR_POWERMETER_ATTN_NEEDED[] = TR_POWERMETER_ATTN_NEEDED; const char STR_PXX2_SELECT_RX[] = TR_PXX2_SELECT_RX; @@ -673,6 +674,8 @@ const char STR_MULTI_VIDFREQ[] = TR_MULTI_VIDFREQ; const char STR_MULTI_OPTION[] = TR_MULTI_OPTION; const char STR_MULTI_FIXEDID[] = TR_MULTI_FIXEDID; const char STR_MULTI_AUTOBIND[] = TR_MULTI_AUTOBIND; +const char STR_DISABLE_CH_MAP[] = TR_DISABLE_CH_MAP; +const char STR_DISABLE_TELEM[] = TR_DISABLE_TELEM; const char STR_MULTI_DSM_AUTODTECT[] = TR_MULTI_DSM_AUTODTECT; const char STR_MULTI_LOWPOWER[] = TR_MULTI_LOWPOWER; const char STR_MODULE_NO_SERIAL_MODE[] = TR_MODULE_NO_SERIAL_MODE; @@ -680,10 +683,14 @@ const char STR_MODULE_NO_INPUT[] = TR_MODULE_NO_INPUT; const char STR_MODULE_WAITFORBIND[] = TR_MODULE_WAITFORBIND; const char STR_MODULE_NO_TELEMETRY[] = TR_MODULE_NO_TELEMETRY; const char STR_MODULE_BINDING[] = TR_MODULE_BINDING; +const char STR_MODULE_UPGRADE_ALERT[] = TR_MODULE_UPGRADE_ALERT; +const char STR_MODULE_UPGRADE[] = TR_MODULE_UPGRADE; const char STR_PROTOCOL_INVALID[] = TR_PROTOCOL_INVALID; const char STR_MODULE_STATUS[] = TR_MODULE_STATUS; const char STR_MODULE_SYNC[] = TR_MODULE_SYNC; const char STR_MULTI_SERVOFREQ[] = TR_MULTI_SERVOFREQ; +const char STR_MULTI_MAX_THROW[] = TR_MULTI_MAX_THROW; +const char STR_MULTI_RFCHAN[] = TR_MULTI_RFCHAN; const char STR_NEEDS_FILE[] = TR_NEEDS_FILE; const char STR_EXT_MULTI_SPEC[] = TR_EXT_MULTI_SPEC; const char STR_INT_MULTI_SPEC[] = TR_INT_MULTI_SPEC; diff --git a/radio/src/translations.h b/radio/src/translations.h index 0597136a6..d4864afdb 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -264,7 +264,7 @@ extern const char STR_DELAYDOWN[]; extern const char STR_DELAYUP[]; extern const char STR_SLOWDOWN[]; extern const char STR_SLOWUP[]; -extern const char STR_MIXER[]; +extern const char STR_MIXES[]; extern const char STR_CV[]; extern const char STR_GV[]; extern const char STR_RANGE[]; @@ -393,7 +393,6 @@ extern const char STR_AND_SWITCH[]; extern const char STR_SF[]; extern const char STR_GF[]; -#if defined(MULTIMODULE) extern const char STR_MULTI_CUSTOM[]; extern const char STR_MULTI_FIXEDID[]; extern const char STR_MULTI_OPTION[]; @@ -401,6 +400,8 @@ extern const char STR_MULTI_VIDFREQ[]; extern const char STR_MULTI_RFTUNE[]; extern const char STR_MULTI_TELEMETRY[]; extern const char STR_MULTI_AUTOBIND[]; +extern const char STR_DISABLE_CH_MAP[]; +extern const char STR_DISABLE_TELEM[]; extern const char STR_MULTI_DSM_AUTODTECT[]; extern const char STR_MULTI_LOWPOWER[]; extern const char STR_MODULE_NO_SERIAL_MODE[]; @@ -408,14 +409,17 @@ extern const char STR_MODULE_NO_INPUT[]; extern const char STR_MODULE_WAITFORBIND[]; extern const char STR_MODULE_NO_TELEMETRY[]; extern const char STR_MODULE_BINDING[]; +extern const char STR_MODULE_UPGRADE_ALERT[]; +extern const char STR_MODULE_UPGRADE[]; extern const char STR_PROTOCOL_INVALID[]; extern const char STR_MODULE_STATUS[]; extern const char STR_MODULE_SYNC[]; extern const char STR_MULTI_SERVOFREQ[]; +extern const char STR_MULTI_MAX_THROW[]; +extern const char STR_MULTI_RFCHAN[]; #if LCD_W < 212 extern const char STR_SUBTYPE[]; #endif -#endif #if defined(DSM2) || defined(PXX) extern const char STR_RECEIVER_NUM[]; @@ -732,6 +736,7 @@ extern const char STR_EXPONAME[]; #endif extern const char STR_TRAINER[]; +extern const char STR_CHANS[]; extern const char STR_MODULE_BIND[]; extern const char STR_POWERMETER_ATTN_NEEDED[]; extern const char STR_PXX2_SELECT_RX[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 24ab7db0a..ea6101c1c 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -207,7 +207,7 @@ #endif #ifdef GVARS - #define TR_ADJUST_GVAR "Nastav \0 " + #define TR_ADJUST_GVAR "Nastav\0 " #else #define TR_ADJUST_GVAR "[Nastav GP]" #endif @@ -286,8 +286,8 @@ #define TR_VSWASHTYPE "---\0""120\0""120X""140\0""90\0" #if defined(PCBHORUS) -#define LEN_VKEYS "\006" -#define TR_VKEYS "Menu\0 ""Exit\0 ""Enter\0""Nahoru""Dolů\0 ""Vpravo""Vlevo" + #define LEN_VKEYS "\005" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(RADIO_T12) #define LEN_VKEYS "\005" #define TR_VKEYS "Exit\0""Enter""Dolů\0""Nhoru""Vprvo""Vlevo" @@ -480,7 +480,7 @@ #define TR_DELAYUP TR3("Zpoždění Zap", "Zdržet(\43)", "Zpoždění Zap") #define TR_SLOWDOWN TR3("Zpomalení(-)", "Zpomal(\177)", "Zpomalení(\177)") #define TR_SLOWUP TR3("Zpomalení(+)", "Zpomal(\176)", "Zpomalení(\176)") -#define TR_MIXER "MIXER" +#define TR_MIXES "MIXER" #define TR_CV "K" #if defined(PCBNV14) #define TR_GV "GP" @@ -633,7 +633,9 @@ #define TR_RF_POWER INDENT "Výkon RF" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR(INDENT "Možnosti", INDENT "Hodnota") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind při zapnutí") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind při zapnutí") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetekce", INDENT "Formát autodetekce") #define TR_MULTI_LOWPOWER TR(INDENT "Nízký výkon", INDENT "Režim nízkého výkonu") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -644,6 +646,8 @@ #define TR_MODULE_NO_TELEMETRY TR3("Bez telemetrie", "Bez MULTI_TELEMETIE", "Nedetekována MULTI_TELEMETRIE") #define TR_MODULE_WAITFORBIND "Párovat při zavedení protokolu" #define TR_MODULE_BINDING TR("Bind...","Párování") +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Nutno přepárovat" #define TR_REG_OK "Registrace ok" #define TR_BIND_OK "Úspěšné párovaní" @@ -653,8 +657,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "k9-16 telem vyp" #define TR_PROTOCOL_INVALID TR("Špat. protokol", "Špatný protokol") #define TR_MODULE_STATUS TR(INDENT "Stav", INDENT "Stav modulu") -#define TR_MODULE_SYNC TR(INDENT "Synchro", INDENT "Synchro modulu") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Frekv. serva", INDENT "Obnovovací frequence serva") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT"Limit" #define TR_MINRSSI "Min Rssi" @@ -914,6 +920,7 @@ #define TR_CALIBRATION "Kalibrace" #define TR_SET BUTTON("Nast") #define TR_TRAINER "Trenér" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "Problém s TX anténou!" #define TR_MODELIDUSED TR("ID již použito","ID modelu je již použito") #define TR_MODULE "Modul" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 29ce5ca8f..e69632ec6 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -211,7 +211,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Ändere \0 " + #define TR_ADJUST_GVAR "Ändere\0 " #else #define TR_ADJUST_GVAR "[ÄndereGV]" #endif @@ -292,8 +292,8 @@ #define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90\0" #if defined(PCBHORUS) - #define LEN_VKEYS "\006" - #define TR_VKEYS "Menu\0 ""Exit\0 ""Enter\0""Up\0 ""Down\0 ""Right\0""Left" + #define LEN_VKEYS "\005" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -485,7 +485,7 @@ #define TR_DELAYUP "Verz. Up" #define TR_SLOWDOWN "Langs.Dn" #define TR_SLOWUP "Langs.Up" -#define TR_MIXER "MISCHER" +#define TR_MIXES "MISCHER" #define TR_CV "KV" #if defined(PCBNV14) #define TR_GV "GV" @@ -641,7 +641,9 @@ #define TR_RF_POWER INDENT "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR(INDENT "Option", INDENT "Optionswert") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -652,6 +654,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -661,8 +665,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Grenzen" #define TR_MINRSSI "Min. RSSI" @@ -923,6 +929,7 @@ #define TR_CALIBRATION "Kalibrieren" #define TR_SET BUTTON("Set") #define TR_TRAINER "DSC Buchse PPM In/Out" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "TX-Antennenproblem!" #if defined(COLORLCD) #define TR_MODELIDUSED "ID used in:" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index eceeff58f..e8bc7676c 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -211,7 +211,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Adjust \0 " + #define TR_ADJUST_GVAR "Adjust\0 " #else #define TR_ADJUST_GVAR "[AdjustGV]" #endif @@ -293,7 +293,7 @@ #if defined(PCBHORUS) #define LEN_VKEYS "\005" - #define TR_VKEYS "Menu\0""Exit\0""Enter""Up\0 ""Down\0""Right""Left\0" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -483,7 +483,7 @@ #define TR_DELAYUP "Delay up" #define TR_SLOWDOWN "Slow dn" #define TR_SLOWUP "Slow up" -#define TR_MIXER "MIXER" +#define TR_MIXES "MIXES" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -637,7 +637,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -648,6 +650,8 @@ #define TR_MODULE_NO_TELEMETRY TR3("No telemetry", "No MULTI_TELEMETRY", "No MULTI_TELEMETRY detected") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING TR("Bind...","Binding") +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -657,8 +661,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT "Limit" #define TR_MINRSSI "Min Rssi" @@ -919,6 +925,7 @@ #define TR_ANALOGS_BTN BUTTON(TR("Anas", "Analogs")) #define TR_SET BUTTON("Set") #define TR_TRAINER "Trainer" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "TX antenna problem!" #if defined(COLORLCD) #define TR_MODELIDUSED "ID used in:" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 6ba9f2ddb..f88fe72aa 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -308,7 +308,7 @@ #if defined(PCBHORUS) #define LEN_VKEYS "\005" - #define TR_VKEYS "Menu\0""Exit\0""Enter""Up\0 ""Down\0""Right""Left\0" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -505,7 +505,7 @@ #define TR_DELAYUP "Delay Up" #define TR_SLOWDOWN "Slow Dn" #define TR_SLOWUP "Slow Up" -#define TR_MIXER "Mezclas" +#define TR_MIXES "Mezclas" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -663,7 +663,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -674,6 +676,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -683,8 +687,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "Sync " TR_ENTER #define TR_LIMIT INDENT"Limite" #define TR_MINRSSI "Min Rssi" @@ -946,6 +952,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Ajuste]" #define TR_TRAINER "Aprendiz" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "¡Problema antena TX!" #define TR_MODELIDUSED TR("ID en uso", "ID modelo en uso") #define TR_MODULE "Modulo" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index f01ca01ef..b8f71634f 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -211,7 +211,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Adjust \0 " + #define TR_ADJUST_GVAR "Adjust\0 " #else #define TR_ADJUST_GVAR "[AdjustGV]" #endif @@ -308,7 +308,7 @@ #if defined(PCBHORUS) #define LEN_VKEYS "\005" - #define TR_VKEYS "Menu\0""Exit\0""Enter""Up\0 ""Down\0""Right""Left\0" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -497,7 +497,7 @@ #define TR_DELAYUP "Delay Up" #define TR_SLOWDOWN "Slow Dn" #define TR_SLOWUP "Slow Up" -#define TR_MIXER "MIXER" +#define TR_MIXES "MIXER" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -657,7 +657,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -668,6 +670,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -677,8 +681,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT"Limit" #define TR_MINRSSI "Min Rssi" @@ -940,6 +946,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Set]" #define TR_TRAINER "Trainer" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!" #define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:") #define TR_MODULE "Module" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 4d5291ac3..46601495f 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -309,8 +309,8 @@ #define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90\0" #if defined(PCBHORUS) - #define LEN_VKEYS "\006" - #define TR_VKEYS "Menu\0 ""Exit\0 ""Entree""Haut\0 ""Bas\0 ""Droit\0""Gauche" + #define LEN_VKEYS "\005" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Bas\0 ""Haut\0""Droit""Gauch" @@ -503,7 +503,7 @@ #define TR_DELAYUP "Retard haut" #define TR_SLOWDOWN "Ralenti bas" #define TR_SLOWUP "Ralenti haut" -#define TR_MIXER "MIXEUR" +#define TR_MIXES "MIXEUR" #define TR_CV "CB" #if defined(PCBNV14) #define TR_GV "VG" @@ -658,10 +658,12 @@ #define TR_MULTI_RFTUNE TR(INDENT "Ajust.fréq", INDENT "Ajustement fréq.") #define TR_MULTI_TELEMETRY "Télémétrie" #define TR_MULTI_VIDFREQ TR(INDENT "Fréq. vidéo", INDENT "Fréquence vidéo") -#define TR_RF_POWER TR(INDENT "Puiss. RF", INDENT "Puissance RF") +#define TR_RF_POWER TR("Puiss. RF", "Puissance RF") #define TR_MULTI_FIXEDID "ID fixe" #define TR_MULTI_OPTION TR(INDENT "Option", INDENT "Option perso") -#define TR_MULTI_AUTOBIND TR(INDENT "Bind auto", INDENT "Bind automatique") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind voie", INDENT "Bind sur voie") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Désact réorg voies") +#define TR_DISABLE_TELEM TR("No Telem", "Désact Télémétrie") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodét.", INDENT "Autodétection") #define TR_MULTI_LOWPOWER TR(INDENT "Basse puis.", INDENT "Mode basse puiss.") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "Lien S.Port") @@ -672,6 +674,8 @@ #define TR_MODULE_NO_TELEMETRY TR3("Pas de télm.", "Télémétrie absente", "Télémétrie absente(act. MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Binder d'abord" #define TR_MODULE_BINDING "Bind..." +#define TR_MODULE_UPGRADE_ALERT "Mise à jour requise" +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebind requis" #define TR_REG_OK "Enregistr. ok" #define TR_BIND_OK "Bind ok" @@ -681,8 +685,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Télem OFF" #define TR_PROTOCOL_INVALID TR("Sél. invalide", "Protocole invalide") #define TR_MODULE_STATUS TR(INDENT "Etat", INDENT "Etat module") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Fréq.servo", INDENT "Fréquence servos") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Limite" #define TR_MINRSSI "RSSI Min." @@ -941,6 +947,7 @@ #define TR_ANALOGS_BTN BUTTON(TR("Anas", "Analogs")) #define TR_SET BUTTON("Déf") #define TR_TRAINER "Ecolage" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "Antenne radio défect.!" #define TR_MODELIDUSED TR("ID affecté à :", "No de récepteur utilisé par :") #define TR_MODULE "Module" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 0c7b31f72..e2d5bf4a9 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -215,7 +215,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Regola \0 " + #define TR_ADJUST_GVAR "Regola\0 " #else #define TR_ADJUST_GVAR "[RegolaVG]\0 " #endif @@ -314,7 +314,7 @@ #if defined(PCBHORUS) #define LEN_VKEYS "\005" - #define TR_VKEYS "Menu\0""Exit\0""Enter""Up\0 ""Down\0""Right""Left\0" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -508,7 +508,7 @@ #define TR_DELAYUP "Post.Su" #define TR_SLOWDOWN "Rall.Giù " #define TR_SLOWUP "Rall.Su" -#define TR_MIXER "MIXER" +#define TR_MIXES "MIXER" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -660,9 +660,11 @@ #define TR_MULTI_TELEMETRY "Telemetria" #define TR_MULTI_VIDFREQ TR("Freq. video", "Frequenza video") #define TR_RF_POWER "Potenza RF" -#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") -#define TR_MULTI_OPTION TR("Opzione", "Opzione valore") -#define TR_MULTI_AUTOBIND TR(INDENT "Autoassoc.",INDENT "Associa automat.") +#define TR_MULTI_FIXEDID TR(INDENT"ID fisso", INDENT"ID Fisso") +#define TR_MULTI_OPTION TR(INDENT"Opzione", INDENT"Opzione valore") +#define TR_MULTI_AUTOBIND TR(INDENT "Ass. Ch.",INDENT "Associa al canale") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disab. mappa Ch.") +#define TR_DISABLE_TELEM TR("No Telem", "Telem. disabil.") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Trova autom.", INDENT "Autoril. il formato") #define TR_MULTI_LOWPOWER TR(INDENT "Bassa pot.", INDENT "Modo bassa potenza") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "Link S.Port") @@ -673,6 +675,8 @@ #define TR_MODULE_NO_TELEMETRY TR3("No telemetria", "MULTI_TELEMETRY disattivato", "Nessuna telem. (abilita MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Associa per caricare il protocollo" #define TR_MODULE_BINDING "Associa" +#define TR_MODULE_UPGRADE_ALERT TR3("Richiede agg.", "Richiede agg. modulo", "Modulo\nRichiede agg.") +#define TR_MODULE_UPGRADE TR("Cons. agg.", "Consiglio agg. modulo") #define TR_REBIND "Richiede associazione" #define TR_REG_OK "Registrazione ok" #define TR_BIND_OK "Associazione riuscita" @@ -684,12 +688,14 @@ #define TR_MODULE_STATUS TR(INDENT "Stato", INDENT "Stato del modulo") #define TR_MODULE_SYNC TR(INDENT "Sinc.", INDENT "Sinc. del modulo") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Aggiorna servo rate") +#define TR_MULTI_MAX_THROW TR("Escurs. mass.", "Abilita escurs. mass.") +#define TR_MULTI_RFCHAN TR("Canale RF", "Selez. canale RF") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT "Limiti" #define TR_MINRSSI "Min. RSSI" #define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Use FlySky RSSI value without rescalling") #define TR_LATITUDE "Latitud." -#define TR_LONGITUDE "Longitud." +#define TR_LONGITUDE "Longitu." #define TR_GPS_COORDS_FORMAT TR("GPS Coords", "Formato Coordinate") #define TR_VARIO TR("Vario", "Variometro") #define TR_PITCH_AT_ZERO "Tono a Zero" @@ -763,7 +769,7 @@ #define TR_SWITCHWARN "CONTROLLI" #define TR_FAILSAFEWARN "FAILSAFE" #define TR_NIGHTLY_WARNING TR("NIGHTLY", "NIGHTLY BUILD") -#define TR_NIGHTLY_NOTSAFE "Versione non sicura per volare" +#define TR_NIGHTLY_NOTSAFE "Versione non sicura" #define TR_WRONG_SDCARDVERSION TR("Richiede ver: ", "Richiede versione: ") #define TR_WARN_RTC_BATTERY_LOW "Batteria RTC scarica" #define TR_WARN_MULTI_LOWPOWER "Modalità bassa pot." @@ -782,7 +788,7 @@ #define TR_CPU_MAH "Consumo" #define TR_COPROC "CoProc." #define TR_COPROC_TEMP "Temp. MB \016>" -#define TR_CAPAWARNING INDENT "CapacitàLow" +#define TR_CAPAWARNING INDENT "Capacità Bassa" #define TR_TEMPWARNING INDENT "Temp. Alta" #define TR_FUNC "Funz" #define TR_V1 "V1" @@ -808,13 +814,13 @@ #define TR_EXECUTE_FILE "Esegui" #define TR_REMOVED " rimosso" #define TR_SD_INFO "Informazioni" -#define TR_SD_FORMAT "Format" +#define TR_SD_FORMAT "Formatta" #define TR_NA "N/A" #define TR_HARDWARE "HARDWARE" #define TR_FORMATTING "Formattazione" #define TR_TEMP_CALIB "Temp. Calib." #define TR_TIME "Ora" -#define TR_MAXBAUDRATE "Bauds Max" +#define TR_MAXBAUDRATE "Max Bauds" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Cerca" @@ -945,6 +951,7 @@ #define TR_CALIBRATION TR("Calibraz.", "Calibrazione") #define TR_SET "[Set]" #define TR_TRAINER TR("Trainer", "Maestro/Allievo") +#define TR_CHANS "Canali" #define TR_ANTENNAPROBLEM CENTER "Problemi antenna TX!" #define TR_MODELIDUSED TR("ID già usato", "ID Modello già usato") #define TR_MODULE "Modulo" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 1b8cd8ff6..b51d8017a 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -212,7 +212,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Wijzig \0 " + #define TR_ADJUST_GVAR "Wijzig\0 " #else #define TR_ADJUST_GVAR "[WijzigGV]" #endif @@ -293,8 +293,8 @@ #define TR_VSWASHTYPE "---\0""120\0""120X""140\0""90\0" #if defined(PCBHORUS) - #define LEN_VKEYS "\006" - #define TR_VKEYS "Menu\0 ""Exit\0 ""Enter\0""Up\0 ""Down\0 ""Right\0""Left" + #define LEN_VKEYS "\005" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(RADIO_T12) #define LEN_VKEYS "\005" #define TR_VKEYS "Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -484,7 +484,7 @@ #define TR_DELAYUP "Vertr.Up" #define TR_SLOWDOWN "Langz.Dn" #define TR_SLOWUP "Langz.Up" -#define TR_MIXER "MIXER" +#define TR_MIXES "MIXER" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -645,7 +645,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -656,6 +658,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -665,8 +669,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Grenzen" #define TR_MINRSSI "Min. RSSI" @@ -928,6 +934,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Set]" #define TR_TRAINER "Trainer Poort" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "TX-Antenneprobleem!" #define TR_MODELIDUSED TR("ID al gebruikt", "Model-ID al gebruikt") #define TR_MODULE "Module-Type" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 86f2b731a..273052b4c 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -212,7 +212,7 @@ #endif #if defined(GVARS) - #define TR_ADJUST_GVAR "Ustaw \0 " + #define TR_ADJUST_GVAR "Ustaw\0 " #else #define TR_ADJUST_GVAR "[UstawZG] " #endif @@ -311,7 +311,7 @@ #if defined(PCBHORUS) #define LEN_VKEYS "\005" - #define TR_VKEYS "Menu\0""Exit\0""Enter""Up\0 ""Down\0""Right""Left\0" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(PCBXLITE) #define LEN_VKEYS "\005" #define TR_VKEYS "Shift""Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -504,7 +504,7 @@ #define TR_DELAYUP "Opózn.(+)" #define TR_SLOWDOWN "Spowoln.(-)" #define TR_SLOWUP "Spowoln.(+)" -#define TR_MIXER "MIKSERY" +#define TR_MIXES "MIKSERY" #define TR_CV "Kr" #if defined(PCBNV14) #define TR_GV "ZG" @@ -658,7 +658,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -669,6 +671,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -678,8 +682,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_SYNCMENU "[Synch]" #define TR_LIMIT INDENT "Limit" #define TR_MINRSSI "Min Rssi" @@ -941,6 +947,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Set]" #define TR_TRAINER "Port Trenera" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "Problem z anteną TX" #define TR_MODELIDUSED TR("ID zajęte","ID modelu zajęte") #define TR_MODULE "Moduł " diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 794ae9faa..eed4a4b14 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -210,9 +210,9 @@ #endif #ifdef GVARS - #define TR_ADJUST_GVAR "Ajuste\0 " + #define TR_ADJUST_GVAR "Ajuste\0 " #else - #define TR_ADJUST_GVAR "[AdjustGV]\0 " + #define TR_ADJUST_GVAR "[AdjustGV]\0 " #endif #if defined(LUA) @@ -490,7 +490,7 @@ #define TR_DELAYUP "Atraso Up" #define TR_SLOWDOWN "Lento Dn" #define TR_SLOWUP "Lento Up" -#define TR_MIXER "MIXAGENS" +#define TR_MIXES "MIXAGENS" #define TR_CV "CV" #if defined(PCBNV14) #define TR_GV "GV" @@ -649,7 +649,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -660,6 +662,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -669,8 +673,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_LIMIT INDENT"Limite" #define TR_MINRSSI "Min Rssi" #define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Use FlySky RSSI value without rescalling") @@ -931,6 +937,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Set]" #define TR_TRAINER "Trainer" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!" #define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:") #define TR_MODULE "Module" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 6e68b1b96..08d43ab44 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -310,8 +310,8 @@ #define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90\0 " #if defined(PCBHORUS) - #define LEN_VKEYS "\006" - #define TR_VKEYS "Menu\0 ""Exit\0 ""Enter\0""Upp\0 ""Ned\0 ""Höger\0""Vänst" + #define LEN_VKEYS "\005" + #define TR_VKEYS "PGUP\0""PGDN\0""ENTER""MDL\0 ""RTN\0 ""TELE\0""SYS\0 " #elif defined(RADIO_T12) #define LEN_VKEYS "\005" #define TR_VKEYS "Exit\0""Enter""Down\0""Up\0 ""Right""Left\0" @@ -506,7 +506,7 @@ #define TR_DELAYUP "Dröj Upp" #define TR_SLOWDOWN "Trög Ned" #define TR_SLOWUP "Trög Upp" -#define TR_MIXER "MIXAR" +#define TR_MIXES "MIXAR" #define TR_CV "KU" #if defined(PCBNV14) #define TR_GV "GV" @@ -661,7 +661,9 @@ #define TR_RF_POWER "RF Power" #define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") #define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") +#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel") +#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map") +#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") #define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") @@ -672,6 +674,8 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") +#define TR_MODULE_UPGRADE TR("Upg. needed", "Module update recommended") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" @@ -681,8 +685,10 @@ #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") +#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") #define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw") +#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel") #define TR_LIMIT INDENT "Nivå" #define TR_MINRSSI "Min Rssi" #define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Use FlySky RSSI value without rescalling") @@ -944,6 +950,7 @@ #define TR_CALIBRATION "Calibration" #define TR_SET "[Spara]" #define TR_TRAINER "Trainer" +#define TR_CHANS "Chans" #define TR_ANTENNAPROBLEM CENTER "Fel på TX-antennen" #define TR_MODELIDUSED TR("ID finns redan","ModellID används redan") #define TR_MODULE "Modul" diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index bc072fe5a..5e90b0c69 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -71,18 +71,12 @@ #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) && !defined(BLUETOOTH) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MULTI -#elif defined(PCBHORUS) +#if 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 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 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 TR_VTRAINER_MULTI + #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 #else - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #endif #define TR_VSRCRAW "---\0" TR_STICKS_VSRCRAW TR_POTS_VSRCRAW TR_ROTARY_ENCODERS TR_GYR_VSRCRAW "MAX\0" TR_CYC_VSRCRAW TR_TRIMS_VSRCRAW TR_SW_VSRCRAW TR_EXTRA_VSRCRAW @@ -135,4 +129,4 @@ #define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX" #define LEN_MULTI_PROTOCOLS "\007" -#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""SFHSS\0 ""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FSky 2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""FlyZone""Scanner""FrSkyRX""FS2A_RX" +#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""SFHSS\0 ""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FSky 2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""FlyZone""Scanner""FrSkyRX""FS2A_RX""HoTT\0 ""FX816\0 " diff --git a/radio/util/Dockerfile b/radio/util/Dockerfile deleted file mode 100644 index 7648b0302..000000000 --- a/radio/util/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# An Debian image for compiling OpenTX 2.2 - -FROM debian:stretch - -RUN DEBIAN_FRONTEND=noninteractive apt-get -y update -RUN DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential cmake gcc git lib32ncurses5 lib32z1 libfox-1.6-dev libsdl1.2-dev \ - qt5-default qtmultimedia5-dev qttools5-dev qttools5-dev-tools libqt5svg5-dev \ - software-properties-common wget zip python-pip python-pil libgtest-dev - -RUN python -m pip install filelock - -RUN wget -q https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q3-update/+download/gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2 && \ - tar xjf gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2 && \ - mv gcc-arm-none-eabi-4_7-2013q3 /opt/gcc-arm-none-eabi - - -#RUN wget -q http://ftp.de.debian.org/debian/pool/main/m/mpclib/libmpc2_0.9-4_amd64.deb && \ -# dpkg -i libmpc2_0.9-4_amd64.deb - -VOLUME ["/opentx"] - -ENV PATH $PATH:/opt/gcc-arm-none-eabi/bin:/opentx/code/radio/util - -ARG OPENTX_VERSION_SUFFIX= -ENV OPENTX_VERSION_SUFFIX ${OPENTX_VERSION_SUFFIX} - -WORKDIR /build diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index 630751a64..be3003c88 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -137,7 +137,7 @@ def main(): elif board_name == "t12": cmake_options["PCB"] = "X7" cmake_options["PCBREV"] = "T12" - firmware_options = options_taranis_x9dp + firmware_options = options_jumper_t12 maxsize = 65536 * 8 elif board_name == "t16": cmake_options["PCB"] = "X10" diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py index 104452561..1b7e5cfad 100755 --- a/radio/util/fwoptions.py +++ b/radio/util/fwoptions.py @@ -199,6 +199,18 @@ options_horus_x10express = { "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None) } +options_jumper_t12 = { + "noheli": ("HELI", "NO", "YES"), + "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), + "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), + "nogvars": ("GVARS", "NO", "YES"), + "faimode": ("FAI", "YES", None), + "faichoice": ("FAI", "CHOICE", None), + "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), + "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None), + "internalmulti": ("INTERNAL_MODULE_MULTI", "YES", "NO"), +} + options_jumper_t16 = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), @@ -207,7 +219,6 @@ options_jumper_t16 = { "faimode": ("FAI", "YES", None), "faichoice": ("FAI", "CHOICE", None), "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), - "eu": ("MODULE_PROTOCOL_D8", "NO", "YES"), "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None), "internalmulti": ("INTERNAL_MODULE_MULTI", "YES", "NO"), "bluetooth": ("BLUETOOTH", "YES", "NO"), diff --git a/radio/util/generate_datacopy.py b/radio/util/generate_datacopy.py index 4097de061..6da1c871b 100755 --- a/radio/util/generate_datacopy.py +++ b/radio/util/generate_datacopy.py @@ -14,14 +14,17 @@ if sys.platform == "darwin": clang.cindex.Config.set_library_file('/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib') elif os.path.exists('/Library/Developer/CommandLineTools/usr/lib/libclang.dylib'): clang.cindex.Config.set_library_file('/Library/Developer/CommandLineTools/usr/lib/libclang.dylib') - -if sys.platform == "linux2": - if os.path.exists('/usr/lib/x86_64-linux-gnu/libclang-3.8.so.1'): - clang.cindex.Config.set_library_file('/usr/lib/x86_64-linux-gnu/libclang-3.8.so.1') +elif sys.platform.startswith("linux"): + for version in ("7", "6.0", "3.8"): + libclang = "/usr/lib/x86_64-linux-gnu/libclang-%s.so.1" % version + if os.path.exists(libclang): + clang.cindex.Config.set_library_file(libclang) + break structs = [] extrastructs = [] + def build_struct(cursor, anonymousUnion=False): if not anonymousUnion: structs.append(cursor.spelling) @@ -30,9 +33,9 @@ def build_struct(cursor, anonymousUnion=False): for c in cursor.get_children(): if c.kind == clang.cindex.CursorKind.UNION_DECL: if c.spelling: - raise "Cannot handle non anonymous unions" + raise Exception("Cannot handle non anonymous unions") - copiedUnionMember = False + copied_union_member = False for uc in c.get_children(): if not uc.spelling or uc.kind == clang.cindex.CursorKind.PACKED_ATTR: # Ignore @@ -40,11 +43,11 @@ def build_struct(cursor, anonymousUnion=False): else: # per default we copy only the first member of a union and warn if there are more # members (declare the other members NOBACKUP) - if copiedUnionMember: - print ("Warning more than one union member (%s) in anynomous union inside struct %s, consider NOBACKUP statements" % (uc.spelling, cursor.spelling), file=sys.stderr) + if copied_union_member: + print("Warning more than one union member (%s) in anynomous union inside struct %s, consider NOBACKUP statements" % (uc.spelling, cursor.spelling), file=sys.stderr) else: copy_decl(uc, uc.spelling) - copiedUnionMember = True + copied_union_member = True elif c.kind == clang.cindex.CursorKind.FIELD_DECL: copy_decl(c, c.spelling) @@ -52,6 +55,7 @@ def build_struct(cursor, anonymousUnion=False): if not anonymousUnion: print("}\n") + def build(cursor): result = [] for c in cursor.get_children(): @@ -61,13 +65,13 @@ def build(cursor): for c, spelling in extrastructs: print("template \nvoid copy%s(A * dest, B * src)\n{" % spelling) build_struct(c, True) - print ("}\n") + print("}\n") return result def copy_decl(c, spelling): - childs = [ch for ch in c.get_children()] + children = [ch for ch in c.get_children()] if c.type.get_array_size() > 0: if c.type.get_array_element_type().spelling in structs: print(" for (int i=0; i<%d; i++) {" % c.type.get_array_size()) @@ -75,16 +79,15 @@ def copy_decl(c, spelling): print(" }") else: print(" memcpy(dest->%s, src->%s, sizeof(dest->%s));" % (spelling, spelling, spelling)) - elif len(childs)==1 and childs[0].kind == clang.cindex.CursorKind.STRUCT_DECL and not childs[0].spelling: + elif len(children) == 1 and children[0].kind == clang.cindex.CursorKind.STRUCT_DECL and not children[0].spelling: # inline declared structs if c.semantic_parent.spelling: - spellingFunc = c.semantic_parent.spelling + "_" + spelling + spelling_func = c.semantic_parent.spelling + "_" + spelling else: - spellingFunc = c.semantic_parent.semantic_parent.spelling + "_" + spelling - - extrastructs.append((childs[0], spellingFunc)) - print(" copy%s(&dest->%s, &src->%s);" % (spellingFunc, spelling, spelling)) + spelling_func = c.semantic_parent.semantic_parent.spelling + "_" + spelling + extrastructs.append((children[0], spelling_func)) + print(" copy%s(&dest->%s, &src->%s);" % (spelling_func, spelling, spelling)) elif c.type.get_declaration().spelling in structs: print(" copy%s(&dest->%s, &src->%s);" % (c.type.get_declaration().spelling, spelling, spelling)) else: @@ -92,7 +95,8 @@ def copy_decl(c, spelling): def header(): - print("//This file was auto-generated by %s script on %s. Do not edit this file!\n\n\n" % (os.path.basename(sys.argv[0]), time.asctime())) + print("// This file was auto-generated by %s script on %s. Do not edit this file!\n\n\n" % (os.path.basename(sys.argv[0]), time.asctime())) + index = clang.cindex.Index.create() translation_unit = index.parse(sys.argv[1], ['-x', 'c++', '-std=c++11'] + sys.argv[2:]) diff --git a/radio/util/lua/lua_old_event_check.lua b/radio/util/lua/lua_old_event_check.lua deleted file mode 100755 index 6a74a3c0f..000000000 --- a/radio/util/lua/lua_old_event_check.lua +++ /dev/null @@ -1,74 +0,0 @@ -local toolName = "TNS|LUA event tests|TNE" ----- ######################################################################### ----- # # ----- # Copyright (C) OpenTX # ------# # ----- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # ----- # # ----- # This program is free software; you can redistribute it and/or modify # ----- # it under the terms of the GNU General Public License version 2 as # ----- # published by the Free Software Foundation. # ----- # # ----- # This program 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. # ----- # # ----- ######################################################################### - -local virtual_next = 0 -local virtual_previous = 0 -local virtual_next_rept = 0 -local virtual_previous_rept = 0 -local virtual_page_next = 0 -local virtual_page_previous = 0 -local virtual_enter = 0 -local virtual_enter_long = 0 -local virtual_menu = 0 -local virtual_menu_long = 0 - --- Init -local function init() - -end - --- Main -local function run(event) - if event == nil then - error("Cannot be run as a model script!") - return 2 - elseif event == EVT_VIRTUAL_EXIT then - return 2 - elseif event == EVT_PLUS_FIRST then - virtual_next = virtual_next + 1 - elseif event == EVT_MINUS_FIRST then - virtual_previous = virtual_previous + 1 - elseif event == EVT_PLUS_REPT then - virtual_next_rept = virtual_next_rept + 1 - elseif event == EVT_MINUS_REPT then - virtual_previous_rept = virtual_previous_rept + 1 - elseif event == EVT_PAGE_BREAK then - virtual_page_next = virtual_page_next +1 - elseif event == EVT_PAGE_LONG then - virtual_page_previous = virtual_page_previous + 1 - killEvents(event); - elseif event == EVT_ENTER_BREAK then - virtual_enter = virtual_enter + 1 - elseif event == EVT_MENU_BREAK then - virtual_menu = virtual_menu + 1 - end - - lcd.clear() - lcd.drawScreenTitle("LUA EVENT TEST", 0, 0) - lcd.drawText(1, 10, "PLUS: "..virtual_next) - lcd.drawText(1, 20, "MINUS: "..virtual_previous) - lcd.drawText(1, 40, "PLUS_REPT: "..virtual_next_rept) - lcd.drawText(1, 50, "MINUS_REPT: "..virtual_previous_rept) - lcd.drawText(LCD_W/2, 10, "ENTER: "..virtual_enter) - lcd.drawText(LCD_W/2, 20, "MENU: "..virtual_menu) - lcd.drawText(LCD_W/2, 40, "NEXT_PAGE: "..virtual_page_next) - lcd.drawText(LCD_W/2, 50, "PREVIOUS_PAGE: "..virtual_page_previous) - return 0 -end - -return { init=init, run=run } diff --git a/radio/util/sport-parse.py b/radio/util/sport-parse.py index 6c8d70709..0f2eaac4b 100755 --- a/radio/util/sport-parse.py +++ b/radio/util/sport-parse.py @@ -10,7 +10,7 @@ import struct START_STOP = '\x7e' -BYTESTUFF = '\x7d' +BYTE_STUFF = '\x7d' STUFF_MASK = '\x20' DATA_FRAME = 0x10 @@ -110,7 +110,7 @@ def ParsePacket(packet): global lineNumber # unstuff packet while True: - pos = packet.find(BYTESTUFF) + pos = packet.find(BYTE_STUFF) if pos == -1: break # print "found stuff at %d in %s" % (pos, dump(packet, 20)) diff --git a/radio/util/tts.py b/radio/util/tts.py deleted file mode 100755 index c72a4b725..000000000 --- a/radio/util/tts.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - - -# To use this script you need the following installed within python -# Python 2.5 http://www.python.org/download/releases/2.5.4/ -# Python 2.7 http://www.python.org/download/releases/2.7.3/ -# PyTTS http://pypi.python.org/pypi/pyTTS -# PyWin32 http://sourceforge.net/projects/pywin32/files/pywin32/ -# -# Note -# At the moment, pyTTS is only available for Python 2.3, 2.4 and 2.5. To use it for later versions without having to -# recompile it, a quick and dirty solution is to: -# copy the entire pyTTS directory from Python25\Lib\site-packages to Python26 or Python27 -# replace TTSFast.py with an empty file. This way the version-dependent pyd file isn't loaded. - -# in addition you will need some tools. -# ffmpeg, sox, adconvertor ttscmd (2cnd speach centre) -# have fun! -# Sound pack maintainers (incomplete list) by language alphabetical order -# Czech : Martin Hotar -# French : Bertrand Songis & André Bernet -# English : Rob Thompson & Martin Hotar -# German : Romolo Manfredini (Some corrections by Peer) -# Italian : Romolo Manfredini -# Portuguese : Romolo Manfredini -# Spanish : Romolo Manfredini (With the help of Jose Moreno) - -# from __future__ import print_function - -import os -import sys -import subprocess -import zipfile -from tts_common import * - -try: - # Python 3 - from http.client import HTTPConnection - from urllib.parse import urlencode -except ImportError: - # Python 2 - from httplib import HTTPConnection - from urllib import urlencode - - -def wavstrip(filename): - output = "_" + filename - subprocess.Popen(["sox", filename, output, "silence", "1", "0.1", "0.1%", "reverse", "silence", "1", "0.1", "0.1%", "reverse"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - os.remove(filename) - os.rename(output, filename) - - -def generate(str, filename): - print(filename, str) - - if not str: - str = " !" # this is so blank wav files never exist! - - if "speak" in sys.argv: - if "sapi" in sys.argv: - tts.Speak(str) - elif "espeak" in sys.argv: - subprocess.Popen(["espeak", "-v", espeakVoice, "-s", espeakspeed, "-z", str.encode("utf-8")], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - elif "google" in sys.argv: - "speak not implemented with google tts engine" - exit() - else: - print("which speach engine?") - exit() - else: - if "sapi" in sys.argv: - ttsfilename = "ttsfile.wav" - tts.SpeakToWave(ttsfilename, str) - elif "sapi2" in sys.argv: - ttsfilename = "ttsfile.wav" - subprocess.Popen(["ttscmd", "/ttw", str.encode("utf-8"), ttsfilename, "-v", voiceID, "-b", "32", "-s", "\"-3\"", "-w", "32", "-f", "47"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - elif "espeak" in sys.argv: - ttsfilename = "ttsfile.wav" - subprocess.Popen(["espeak", "-v", espeakVoice, "-s", espeakspeed, "-z", "-w", ttsfilename, str.encode("utf-8")], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - elif "google" in sys.argv: - ttsmp3 = "ttsfile.mp3" - ttsfilename = "ttsfile.wav" - conn = HTTPConnection("translate.google.com") - params = urlencode({'ie': "UTF-8", 'tl': directory, 'q': str.encode("utf-8")}) - headers = {"User-Agent": "Mozilla"} - conn.request("GET", u"/translate_tts?%s" % params, headers=headers) - # conn.request("GET", "/translate_tts?ie=UTF-8&tl=%s&q=%s" % (directory, urllib.urlencode(str)), headers={"User-Agent": "Mozilla"}) - resp = conn.getresponse() - with open(ttsmp3, "wb") as f: - f.write(resp.read()) - subprocess.Popen(["ffmpeg", "-y", "-i", ttsmp3, "-acodec", "pcm_s16le", ttsfilename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - conn.close() - - else: - print("which speach engine?") - exit() - - wavstrip(ttsfilename) - - if board in ('sky9x', 'taranis'): - if 'sox' in sys.argv: - maxvolume = subprocess.Popen(["sox", ttsfilename, "-n", "stat", "-v"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1] - if "not sound" in maxvolume: - subprocess.Popen(["sox", "--show-progress", filename, ttsfilename], stdout=subprocess.PIPE).communicate()[0] - else: - subprocess.Popen(["sox", "--show-progress", "-v", maxvolume, filename, ttsfilename], stdout=subprocess.PIPE).communicate()[0] - if board == 'sky9x': - subprocess.Popen(["sox", "-twav", ttsfilename, "-b1600", "-c1", "-e", "a-law", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - else: - subprocess.Popen(["sox", "-twav", ttsfilename, "-b32000", "-c1", "-e", "a-law", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - else: - if board == 'sky9x': - subprocess.Popen(["ffmpeg", "-y", "-i", ttsfilename, "-acodec", defaultcodec, "-ar", "16000", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - else: - subprocess.Popen(["ffmpeg", "-y", "-i", ttsfilename, "-acodec", defaultcodec, "-ar", "32000", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - elif board == 'gruvin9x': - subprocess.Popen(["AD4CONVERTER", "-E4", ttsfilename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - os.rename(ttsfilename.replace(".wav", ".ad4"), filename) - else: - subprocess.Popen(["ffmpeg", "-y", "-i", ttsfilename, "-acodec", "pcm_u8", "-ar", "16000", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - os.remove(ttsfilename) - -################################################################ - -if __name__ == "__main__": - - - - if "sapi" in sys.argv: - import pyTTS - tts = pyTTS.Create() - # tts.SetOutputFormat(16, 16, 1) - # tts.Volume = 40 - # tts.SetRate(1) - if "list" in sys.argv: - print(tts.GetVoiceNames()) - exit() - - if "mulaw" in sys.argv: - defaultcodec = "pcm_mulaw" - else: - defaultcodec = "pcm_alaw" - - if "en" in sys.argv: - from tts_en import systemSounds, sounds - - directory = "en" - voice = "english" - if "sapi" in sys.argv: - if "scottish" in sys.argv: - tts.SetVoiceByName("ScanSoftFiona_Full_22kHz") - voice = "english-scottish" - elif "american" in sys.argv: - tts.SetVoiceByName("ScanSoftJennifer_Full_22kHz") - voice = "english-american" - elif "australian" in sys.argv: - tts.SetVoiceByName("ScanSoftKaren_Full_22kHz") - voice = "english-australian" - elif "irish" in sys.argv: - tts.SetVoiceByName("ScanSoftMoira_Full_22kHz") - voice = "english-irish" - else: - tts.SetVoiceByName("ScanSoftFiona_Full_22kHz") - voice = "english-english" - elif "sapi2" in sys.argv: - if "scottish" in sys.argv: - voiceID = "17" - voice = "english-scottish" - elif "american" in sys.argv: - voiceID = "18" - voice = "english-american" - elif "australian" in sys.argv: - voiceID = "20" - voice = "english-australian" - elif "irish" in sys.argv: - voiceID = "21" - voice = "english-irish" - elif "french" in sys.argv: - voiceID = "19" - voice = "english-french" - elif "german" in sys.argv: - voiceID = "22" - voice = "english-german" - else: - voiceID = "17" - voice = "english-english" - - elif "espeak" in sys.argv: - espeakVoice = "mb-us1" - espeakspeed = "150" - - elif "fr" in sys.argv: - from tts_fr import systemSounds, sounds - - directory = "fr" - voice = "french" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-fr4+f4" - espeakspeed = "140" - - elif "it" in sys.argv: - from tts_it import systemSounds, sounds - - directory = "it" - voice = "italian" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-it4" - espeakspeed = "160" - - elif "de" in sys.argv: - from tts_de import systemSounds, sounds - - directory = "de" - voice = "german" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-de4" - espeakspeed = "160" - - elif "pt" in sys.argv: - from tts_pt import systemSounds, sounds - - directory = "pt" - voice = "portuguese" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-pt1+f1" - espeakspeed = "160" - - elif "es" in sys.argv: - from tts_es import systemSounds, sounds - - directory = "es" - voice = "spanish" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-es1+f1" - espeakspeed = "160" - - elif "cz" in sys.argv: - from tts_cz import systemSounds, sounds - - directory = "cz" - voice = "czech" - if "sapi" in sys.argv: - tts.SetVoiceByName("ScanSoftZuzana_Full_22kHz") - elif "espeak" in sys.argv: - espeakVoice = "mb-cz2" - espeakspeed = "150" - - else: - print("which language?") - exit() - - if "csv" in sys.argv: - with open("%s-%s.csv" % (voice, board), "w") as csvFile: - for s, f in systemSounds: - if s and f: - l = u"" - if board in ("sky9x", "taranis"): - l += u"SOUNDS/%s/SYSTEM;" % directory - l += f + u";" + s + u"\n" - csvFile.write(l.encode("utf-8")) - for s, f in sounds: - if s and f: - l = u"" - if board in ("sky9x", "taranis"): - l += u"SOUNDS/%s;" % directory - l += f + u";" + s + u"\n" - csvFile.write(l.encode("utf-8")) - - if "zip" in sys.argv: - zip_name = "%s-%s.zip" % (voice, board) - with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zip: - for s, f in systemSounds: - if s and f: - generate(s, f) - if board in ("sky9x", "taranis"): - zip.write(f, "SOUNDS/%s/SYSTEM/" % directory + f) - else: - zip.write(f, f) - os.remove(f) - for s, f in sounds: - if s and f: - generate(s, f) - if board in ("sky9x", "taranis"): - zip.write(f, "SOUNDS/%s/" % directory + f) - else: - zip.write(f, f) - os.remove(f) diff --git a/radio/util/tts_common.py b/radio/util/tts_common.py deleted file mode 100644 index 2541b1fe9..000000000 --- a/radio/util/tts_common.py +++ /dev/null @@ -1,35 +0,0 @@ -NO_ALTERNATE = 1024 - -import sys - -def filename(idx, alternate=0): - if "gruvin9x" in sys.argv: - ext = ".ad4" - else: - ext = ".wav" - if isinstance(idx, int): - result = "%04d%s" % (idx, ext) - elif board in ('sky9x', 'taranis'): - result = idx + ext - else: - if alternate >= NO_ALTERNATE: - return None - result = "%04d%s" % (alternate, ext) - return result - -if "sky9x" in sys.argv: - board = "sky9x" - PROMPT_CUSTOM_BASE = 256 - PROMPT_SYSTEM_BASE = 0 -elif "taranis" in sys.argv or "horus" in sys.argv: - board = "taranis" - PROMPT_CUSTOM_BASE = 256 - PROMPT_SYSTEM_BASE = 0 -elif "gruvin9x" in sys.argv: - board = "gruvin9x" - PROMPT_CUSTOM_BASE = 0 - PROMPT_SYSTEM_BASE = 256 -else: - board = "stock" - PROMPT_CUSTOM_BASE = 0 - PROMPT_SYSTEM_BASE = 256 diff --git a/radio/util/video.sh b/radio/util/video.sh deleted file mode 100755 index dc65906bc..000000000 --- a/radio/util/video.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -x -set -e - -ffmpeg -i $1 -an -vb 1000k -s 960x540 `echo $1 | sed 's/\(.*\.\)mp4/\1mov/'` - diff --git a/radio/util/add-issue-links.py b/tools/add-issue-links.py similarity index 100% rename from radio/util/add-issue-links.py rename to tools/add-issue-links.py diff --git a/tools/build-jumper.py b/tools/build-jumper.py index 0a2db17f3..ab3fb9e45 100755 --- a/tools/build-jumper.py +++ b/tools/build-jumper.py @@ -14,6 +14,12 @@ boards = { "PCBREV": "T12", "DEFAULT_MODE": "2", }, + "T12PRO": { + "PCB": "X7", + "PCBREV": "T12", + "INTERNAL_MODULE_MULTI": "YES", + "DEFAULT_MODE": "2", + }, "T16": { "PCB": "X10", "PCBREV": "T16", diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index 61b1bc5c3..9e470343c 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -5,12 +5,12 @@ set -e set -x # Allow variable core usage, default uses all cpu cores, to set 8 cores for example : commit-tests.sh -j8 -num_cpus=`grep 'physical id' /proc/cpuinfo | sort -u | wc -l` -: ${CORES:=$num_cpus} +num_cpus=$(grep 'physical id' /proc/cpuinfo | sort -u | wc -l) +: "${CORES:=$num_cpus}" # Default build treats warnings as errors, set -Wno-error to override, e.g.: commit-tests.sh -Wno-error -: ${WERROR:=1} +: "${WERROR:=1}" # A board name to build for, or ALL -: ${FLAVOR:=ALL} +: "${FLAVOR:=ALL}" for i in "$@" do @@ -40,7 +40,7 @@ else SCRIPT=$(readlink -f "$0") fi -if [[ ! -z ${GCC_ARM} ]] ; then +if [[ -n ${GCC_ARM} ]] ; then export PATH=${GCC_ARM}:$PATH fi @@ -58,145 +58,145 @@ COMMON_OPTIONS+=${EXTRA_OPTIONS} mkdir build || true cd build -if [[ " SKY9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " SKY9X ARM9X ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on Sky9x - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=SKY9X -DHELI=YES DLUA=YES -DTELEMETRY=FRSKY -DPPM_LIMITS_SYMETRICAL=YES -DVARIO=YES -DAUTOSWITCH=YES -DAUTOSOURCE=YES -DAUDIO=YES -DGPS=YES -DPPM_CENTER_ADJUSTABLE=YES -DFLIGHT_MODES=YES -DOVERRIDE_CHANNEL_FUNCTION=YES -DFRSKY_STICKS=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=SKY9X -DHELI=YES DLUA=YES -DTELEMETRY=FRSKY -DPPM_LIMITS_SYMETRICAL=YES -DVARIO=YES -DAUTOSWITCH=YES -DAUTOSOURCE=YES -DAUDIO=YES -DGPS=YES -DPPM_CENTER_ADJUSTABLE=YES -DFLIGHT_MODES=YES -DOVERRIDE_CHANNEL_FUNCTION=YES -DFRSKY_STICKS=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " AR9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " AR9X ARM9X ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on AR9X - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=AR9X -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=AR9X -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " 9XRPRO ARM9X ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on Sky9x - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=9XRPRO -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=9XRPRO -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " X9LITE ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9LITE - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9LITE -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9LITE -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " X9LITES ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " X9LITES X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9LITES - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9LITES -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9LITES -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " X7 ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " X7 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X7 - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X7 -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X-Lite - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=XLITE -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X-Lites - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=XLITES -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X9D - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X9D+ X9 ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X9D+ - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X9D+2019 X9 ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X9D+ 2019 - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X9E X9 ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on Taranis X9E - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DPPM_UNIT=PERCENT_PREC1 ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X10 HORUS ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on X10 boards - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X10 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " X12S HORUS ALL " =~ " ${FLAVOR} " ]] ; then - # OpenTX on Horus - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X12S -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio -fi - -if [[ " T12 ALL " =~ " ${FLAVOR} " ]] ; then +if [[ " T12 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on T12 - rm -rf * - cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES ${SRCDIR} - make -j${CORES} ${FIRMARE_TARGET} - make -j${CORES} libsimulator - make -j${CORES} tests-radio + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio fi -if [[ " DEFAULT ALL " =~ " ${FLAVOR} " ]] ; then - # Companion - rm -rf * - cmake ${COMMON_OPTIONS} ${SRCDIR} - make -j${CORES} - make -j${CORES} tests +if [[ " XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X-Lite + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=XLITE -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " XLITES XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X-Lites + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=XLITES -DHELI=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X9D X9 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X9D + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X9D+ X9 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X9D+ + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X9D+2019 X9 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X9D+ 2019 + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X9E X9 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on Taranis X9E + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DPPM_UNIT=PERCENT_PREC1 "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X10 COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X10 boards + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X10 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X12S COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X12S + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X12S -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " COMPANION ALL " =~ \ ${FLAVOR}\ ]] ; then + # Companion + rm -rf ./* + cmake "${COMMON_OPTIONS}" "${SRCDIR}" + make -j"${CORES}" companion23 simulator23 + make -j"${CORES}" tests-companion fi diff --git a/tools/release23/build-sdcard.sh b/tools/release23/build-sdcard.sh deleted file mode 100755 index 97a4799b7..000000000 --- a/tools/release23/build-sdcard.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -set -e -set -x - -workdir=/home/opentx/release23 -output=/var/www/html/2.3/release - -# Handle opentx.sdcard.version -sdcard_version="2.3V"$(grep 'set(SDCARD_REVISION' ${workdir}/code/CMakeLists.txt | grep -o '".*"' | sed 's/"//g') -echo ${sdcard_version} > ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version -echo ${sdcard_version} > ${workdir}/code/radio/sdcard/taranis-x9/opentx.sdcard.version -echo ${sdcard_version} > ${workdir}/code/radio/sdcard/taranis-x7/opentx.sdcard.version - - -if cmp --silent ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir}/opentx.sdcard.version -then - exit -else - cd ${workdir} - - # Copy git sdcard data - rm -Rf ${workdir}/sdcard - cp -r ${workdir}/code/radio/sdcard . - - # Get images for Horus - mkdir -p ${workdir}/sdcard/horus/IMAGES - cp /home/opentx/horus-bitmaps/* ${workdir}/sdcard/horus/IMAGES/ - - - # Request sound pack generation - if [[ ! -d /tmp/SOUNDS/fr ]];then - ${workdir}/code/tools/release23/tts.py en csv files - fi - if [[ ! -d /tmp/SOUNDS/es ]];then - ${workdir}/code/tools/release23/tts.py fr csv files - fi - if [[ ! -d /tmp/SOUNDS/it ]];then - ${workdir}/code/tools/release23/tts.py es csv files - fi - if [[ ! -d /tmp/SOUNDS/de ]];then - ${workdir}/code/tools/release23/tts.py it csv files - fi - if [[ ! -d /tmp/SOUNDS/cz ]];then - ${workdir}/code/tools/release23/tts.py de csv files - fi - if [[ ! -d /tmp/SOUNDS/pl ]];then - ${workdir}/code/tools/release23/tts.py cz csv files - fi - if [[ ! -d /tmp/SOUNDS/ru ]];then - ${workdir}/code/tools/release23/tts.py pt csv files - fi - ${workdir}/code/tools/release23/tts.py ru csv psv files - - # Create sdcards.zips for supported platforms - mv /tmp/SOUNDS ${workdir}/sdcard/horus/ - mkdir ${workdir}/sdcard/taranis-x9/SOUNDS - mkdir ${workdir}/sdcard/taranis-x7/SOUNDS - cp -r ${workdir}/sdcard/horus/SOUNDS ${workdir}/sdcard/taranis-x9/ - cp -r ${workdir}/sdcard/horus/SOUNDS ${workdir}/sdcard/taranis-x7/ - cd ${workdir}/sdcard/horus && zip -r ${output}/sdcard/sdcard-horus-${sdcard_version}.zip * - cd ${workdir}/sdcard/taranis-x9 && zip -r ${output}/sdcard/sdcard-taranis-x9-${sdcard_version}.zip * - cd ${workdir}/sdcard/taranis-x7 && zip -r ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip * - - # Create symlinks for other radios - ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-taranis-xlite-${sdcard_version}.zip - ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-taranis-x9lite-${sdcard_version}.zip - ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-jumper-t12-${sdcard_version}.zip - - # remove LUA stuff for 9x platform - rm -Rf ${workdir}/sdcard/taranis-x7/SCRIPTS - rm -Rf ${workdir}/sdcard/taranis-x7/FrSky-utilities - cd ${workdir}/sdcard/taranis-x7 && zip -r ${output}/sdcard/sdcard-9xarm-${sdcard_version}.zip * - - rm -Rf ${workdir}/sdcard - cp -r ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir} -fi diff --git a/tools/release23/tts.py b/tools/release23/tts.py deleted file mode 100755 index fc42cfeb6..000000000 --- a/tools/release23/tts.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - - -# This script is a modified version to support Linux TTS fiel genration using PicoTTS - -# Sound pack maintainers (incomplete list) by language alphabetical order -# Czech : Martin Hotar -# French : Bertrand Songis & André Bernet -# English : Rob Thompson & Martin Hotar -# German : Romolo Manfredini (Some corrections by Peer) -# Italian : Romolo Manfredini -# Portuguese : Romolo Manfredini -# Spanish : Romolo Manfredini (With the help of Jose Moreno) - -# from __future__ import print_function - -import os -import sys -import subprocess -import zipfile -from gtts import gTTS -from tts_common import * -board = "taranis" - -reload(sys) -sys.setdefaultencoding('utf8') - -SOURCE_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) -lib_path = os.path.abspath(os.path.join(SOURCE_DIRECTORY, '..', '..', 'radio', 'util')) -sys.path.append(lib_path) - -def generate(str, filename): - if 0: - output = "output.wav" - command = 'pico2wave -l=%s -w=%s "%s"' % (voice, output, str) - os.system(command.encode('utf-8')) - command = "sox %s -r 32000 %s reverse silence 1 0.1 0.1%% reverse" % (output, filename) - os.system(command.encode('utf-8')) - else: - output = u"output.mp3" - tts = gTTS(text=str, lang=voice[:2]) - tts.save(output) - command = "sox --norm %s -r 32000 %s tempo 1.2" % (output, filename) - os.system(command.encode('utf-8')) - command = "rm -f output.mp3" - os.system(command.encode('utf-8')) - -################################################################ - -if __name__ == "__main__": - if "en" in sys.argv: - from tts_en import systemSounds, sounds - - directory = "en" - voice = "en-US" - - elif "fr" in sys.argv: - from tts_fr import systemSounds, sounds - - directory = "fr" - voice = "fr-FR" - - elif "it" in sys.argv: - from tts_it import systemSounds, sounds - - directory = "it" - voice = "it-IT" - - elif "de" in sys.argv: - from tts_de import systemSounds, sounds - - directory = "de" - voice = "de-DE" - - elif "es" in sys.argv: - from tts_es import systemSounds, sounds - - directory = "es" - voice = "es-ES" - - elif "cz" in sys.argv: - from tts_cz import systemSounds, sounds - - directory = "cz" - voice = "cs-CZ" - - elif "ru" in sys.argv: - from tts_ru import systemSounds, sounds - - directory = "ru" - voice = "ru-RU" - - elif "pt" in sys.argv: - from tts_pt import systemSounds, sounds - - directory = "pt" - voice = "pt-PT" - - else: - print("which language?") - exit() - - if "csv" in sys.argv: - path = "/tmp/SOUNDS/" + directory + "/SYSTEM/" - if not os.path.exists(path): - os.makedirs(path) - os.chdir(path) - with open("%s-%s.csv" % (voice, board), "wb") as csvFile: - for s, f in systemSounds: - if s and f: - l = u"" - if board in ("sky9x", "taranis"): - l += u"SOUNDS/%s/SYSTEM;" % directory - l += f + u";" + s + u"\n" - csvFile.write(l.encode("utf-8")) - for s, f in sounds: - if s and f: - l = u"" - if board in ("sky9x", "taranis"): - l += u"SOUNDS/%s;" % directory - l += f + u";" + s + u"\n" - csvFile.write(l.encode("utf-8")) - - if "psv" in sys.argv: - path = "/tmp/SOUNDS/" + directory + "/" - if not os.path.exists(path): - os.makedirs(path) - os.chdir(path) - with open("%s-%s.psv" % (voice, board), "wb") as csvFile: - for s, f in systemSounds: - if s and f: - l = u"SYSTEM|" + f.replace(".wav", "") + u"|" + s + u"\r\n" - csvFile.write(l.encode("windows-1251")) - for s, f in sounds: - if s and f: - l = u"|" + f.replace(".wav", "") + u"|" + s + u"\r\n" - csvFile.write(l.encode("windows-1251")) - - - if "files" in sys.argv: - path = "/tmp/SOUNDS/" + directory + "/SYSTEM/" - if not os.path.exists(path): - os.makedirs(path) - os.chdir(path) - for s, f in systemSounds: - if s and f: - generate(s, f) - os.chdir("..") - for s, f in sounds: - if s and f: - generate(s, f) diff --git a/tools/release23/tts_common.py b/tools/release23/tts_common.py deleted file mode 100644 index 25623b005..000000000 --- a/tools/release23/tts_common.py +++ /dev/null @@ -1,14 +0,0 @@ -NO_ALTERNATE = 1024 -PROMPT_CUSTOM_BASE = 256 -PROMPT_SYSTEM_BASE = 0 -board = "taranis" - -import sys - -def filename(idx, alternate=0): - ext = ".wav" - if isinstance(idx, int): - result = "%04d%s" % (idx, ext) - elif board in ('sky9x', 'taranis'): - result = idx + ext - return result