refactor(cpn): Support JSON radio hardware definitions (#4406)
This commit is contained in:
@@ -139,6 +139,22 @@ else()
|
||||
message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.")
|
||||
endif()
|
||||
|
||||
############# Import radio hardware definitions ###############
|
||||
|
||||
set(HWDEFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/../../radio/src")
|
||||
set(HWDEFS_TMPL "${COMPANION_SRC_DIRECTORY}/hwdefs.qrc.in")
|
||||
set(HWDEFS_PHDR "HWDEF_JSON_LIST")
|
||||
set(HWDEFS_QRC "${CMAKE_CURRENT_BINARY_DIR}/hwdefs.qrc")
|
||||
set(HWDEFS_CMD "${COMPANION_SRC_DIRECTORY}/../util/generate_hwdefs_qrc.py")
|
||||
|
||||
add_custom_command(OUTPUT ${HWDEFS_QRC}
|
||||
COMMAND ${HWDEFS_CMD} -d ${HWDEFS_DIR}
|
||||
-t ${HWDEFS_TMPL}
|
||||
-p ${HWDEFS_PHDR}
|
||||
-o ${HWDEFS_QRC}
|
||||
DEPENDS ${HWDEFS_TMPL}
|
||||
)
|
||||
|
||||
############# Common lib ###############
|
||||
|
||||
set(common_SRCS
|
||||
@@ -157,6 +173,7 @@ set(common_MOC_HDRS
|
||||
set(common_RESOURCES
|
||||
companion.qrc
|
||||
${TRANSLATIONS_QRC}
|
||||
${HWDEFS_QRC}
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
#include "helpers.h"
|
||||
#include "boardfactories.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QProxyStyle>
|
||||
@@ -231,6 +232,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_INIT_RESOURCE(hwdefs);
|
||||
gBoardFactories = new BoardFactories();
|
||||
registerStorageFactories();
|
||||
registerOpenTxFirmwares();
|
||||
SimulatorLoader::registerSimulators();
|
||||
@@ -264,6 +267,7 @@ int main(int argc, char *argv[])
|
||||
SimulatorLoader::unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterStorageFactories();
|
||||
gBoardFactories->unregisterBoardFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
|
||||
@@ -37,18 +37,24 @@
|
||||
#define CPN_MAX_MODULES 2
|
||||
#define CPN_MAX_STICKS Board::STICK_AXIS_COUNT
|
||||
#define CPN_MAX_TRIMS Board::TRIM_AXIS_COUNT
|
||||
#define CPN_MAX_POTS 8
|
||||
#define CPN_MAX_SLIDERS 4
|
||||
#define CPN_MAX_CYC 3
|
||||
#define CPN_MAX_SWITCHES 32
|
||||
#define CPN_MAX_FUNCTION_SWITCHES 6
|
||||
#define CPN_MAX_MOUSE_ANALOGS 2
|
||||
#define CPN_MAX_GYRO_ANALOGS 2
|
||||
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_SLIDERS + CPN_MAX_MOUSE_ANALOGS + CPN_MAX_GYRO_ANALOGS)
|
||||
#define CPN_MAX_SWITCHES_FLEX 4 // v2.10 cmake parameter FLEXSW
|
||||
#define CPN_MAX_SWITCHES_FUNCTION 6
|
||||
#define CPN_MAX_SWITCHES_STD 20
|
||||
#define CPN_MAX_SWITCHES (CPN_MAX_SWITCHES_STD + CPN_MAX_SWITCHES_FLEX + CPN_MAX_SWITCHES_FUNCTION)
|
||||
#define CPN_MAX_SENSORS 60
|
||||
#define CPN_MAX_SCRIPTS 9
|
||||
#define CPN_MAX_SCRIPT_INPUTS 10
|
||||
#define CPN_MAX_SPACEMOUSE 6
|
||||
#define CPN_MAX_INPUTS 32 // v2.10 replaces CPN_MAX_ANALOGS - the value is abitary as radio ADC refactor is still a WIP
|
||||
|
||||
// pre v2.10
|
||||
#define CPN_MAX_POTS 8
|
||||
#define CPN_MAX_SLIDERS 4
|
||||
#define CPN_MAX_MOUSE_ANALOGS 2
|
||||
#define CPN_MAX_GYRO_ANALOGS 2
|
||||
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_SLIDERS + CPN_MAX_MOUSE_ANALOGS + CPN_MAX_GYRO_ANALOGS)
|
||||
// =========
|
||||
|
||||
#define CPN_STR_APP_NAME QCoreApplication::translate("Companion", "EdgeTX Companion")
|
||||
#define CPN_STR_SIMU_NAME QCoreApplication::translate("Companion", "EdgeTX Simulator")
|
||||
|
||||
@@ -50,6 +50,8 @@ QString AbstractItemModel::idToString(const int value)
|
||||
return "CurveRefType";
|
||||
case IMID_CurveRefFunc:
|
||||
return "CurveRefFunc";
|
||||
case IMID_FlexSwitches:
|
||||
return "FlexSwitches";
|
||||
default:
|
||||
return "Custom";
|
||||
}
|
||||
@@ -108,13 +110,12 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
|
||||
for (int i = 0; i < firmware->getCapability(LuaScripts); i++)
|
||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, firmware->getCapability(LuaOutputsPerScript), i * 16);
|
||||
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, firmware->getCapability(VirtualInputs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board->getCapability(Board::MaxAnalogs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board->getCapability(Board::Inputs));
|
||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
|
||||
addItems(SOURCE_TYPE_SPACEMOUSE, RawSource::SourcesGroup, CPN_MAX_SPACEMOUSE);
|
||||
addItems(SOURCE_TYPE_MIN, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches));
|
||||
addItems(SOURCE_TYPE_FUNCTIONSWITCH, RawSource::SwitchesGroup, board->getCapability(Board::FunctionSwitches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, firmware->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs));
|
||||
@@ -175,13 +176,11 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_FUNCTIONSWITCH, -board->getCapability(Board::NumFunctionSwitchesPositions));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchesPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_FUNCTIONSWITCH, board->getCapability(Board::NumFunctionSwitchesPositions));
|
||||
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchesPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
|
||||
@@ -571,6 +570,57 @@ PrecisionItemModel::PrecisionItemModel(const int minDecimals, const int maxDecim
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FlexSwitchesItemModel
|
||||
//
|
||||
|
||||
FlexSwitchesItemModel::FlexSwitchesItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_FlexSwitches);
|
||||
|
||||
if (!generalSettings)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_FunctionSwitches);
|
||||
const int count = Boards::getCapability(boardType, Board::Inputs);
|
||||
|
||||
{
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(-1, IMDR_Id);
|
||||
modelItem->setText(tr("None"));
|
||||
modelItem->setData(true, IMDR_Available);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void FlexSwitchesItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(Boards::getInputName(value, boardType));
|
||||
item->setData(generalSettings->isInputFlexSwitchAvailable(value), IMDR_Available);
|
||||
}
|
||||
|
||||
void FlexSwitchesItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 1; i < rowCount(); ++i) { // skip None
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
}
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CompoundItemModelFactory
|
||||
//
|
||||
@@ -623,6 +673,9 @@ void CompoundItemModelFactory::addItemModel(const int id)
|
||||
case AbstractItemModel::IMID_CurveRefFunc:
|
||||
registerItemModel(new CurveRefFuncItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_FlexSwitches:
|
||||
registerItemModel(new FlexSwitchesItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Error: unknown item model: id";
|
||||
break;
|
||||
|
||||
@@ -45,6 +45,7 @@ class AbstractItemModel: public QStandardItemModel
|
||||
IMID_TeleSource,
|
||||
IMID_CurveRefType,
|
||||
IMID_CurveRefFunc,
|
||||
IMID_FlexSwitches,
|
||||
IMID_ReservedCount,
|
||||
IMID_Custom
|
||||
};
|
||||
@@ -332,6 +333,22 @@ class PrecisionItemModel : public AbstractStaticItemModel
|
||||
virtual ~PrecisionItemModel() {};
|
||||
};
|
||||
|
||||
class FlexSwitchesItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FlexSwitchesItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~FlexSwitchesItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// CompoundItemModelFactory
|
||||
//
|
||||
|
||||
@@ -3,6 +3,8 @@ project(firmwares)
|
||||
|
||||
set(${PROJECT_NAME}_NAMES
|
||||
adjustmentreference
|
||||
boardfactories
|
||||
boardjson
|
||||
boards
|
||||
curvedata
|
||||
curvereference
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "boardfactories.h"
|
||||
|
||||
BoardFactories* gBoardFactories = nullptr;
|
||||
|
||||
BoardFactories::BoardFactories() :
|
||||
m_default(nullptr)
|
||||
{
|
||||
if (registerBoard(Board::BOARD_UNKNOWN, ""))
|
||||
m_default = instance(Board::BOARD_UNKNOWN);
|
||||
}
|
||||
|
||||
BoardFactories::~BoardFactories()
|
||||
{
|
||||
unregisterBoardFactories();
|
||||
}
|
||||
|
||||
BoardJson* BoardFactories::instance(Board::Type board) const
|
||||
{
|
||||
for (auto *registeredFactory : registeredBoardFactories) {
|
||||
if (registeredFactory->instance()->board() == board)
|
||||
return registeredFactory->instance();
|
||||
}
|
||||
|
||||
return m_default;
|
||||
}
|
||||
|
||||
// Registering firmware triggers registering the associated board
|
||||
bool BoardFactories::registerBoard(Board::Type board, QString hwdefn)
|
||||
{
|
||||
if (board < Board::BOARD_UNKNOWN || board >= Board::BOARD_TYPE_COUNT)
|
||||
return false;
|
||||
|
||||
if (m_default || board != Board::BOARD_UNKNOWN) {
|
||||
BoardJson* regboard = instance(board);
|
||||
|
||||
if (regboard->board() == board) {
|
||||
if (regboard->hwdefn() == hwdefn) {
|
||||
//qDebug() << "Warning - Board" << Boards::getBoardName(regboard->board()) << "already registered";
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qDebug() << "Error - Board" << Boards::getBoardName(regboard->board()) << "already registered with"
|
||||
<< regboard->hwdefn() << "hwdefn!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BoardFactory *bf = new BoardFactory(board, hwdefn);
|
||||
if (bf->instance()->loadDefinition()) {
|
||||
if (registerBoardFactory(bf)) {
|
||||
qDebug() << "Registered board:" << (board != Board::BOARD_UNKNOWN ? Boards::getBoardName(board) : "UNKNOWN (default)");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
delete bf;
|
||||
}
|
||||
else
|
||||
delete bf;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BoardFactories::registerBoardFactory(BoardFactory * factory)
|
||||
{
|
||||
registeredBoardFactories.append(factory);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BoardFactories::unregisterBoardFactories()
|
||||
{
|
||||
for (auto *registeredFactory : registeredBoardFactories)
|
||||
delete registeredFactory;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "boardjson.h"
|
||||
|
||||
class BoardFactory
|
||||
{
|
||||
public:
|
||||
explicit BoardFactory(Board::Type board, QString hwdefn) :
|
||||
m_instance(new BoardJson(board, hwdefn))
|
||||
{}
|
||||
|
||||
virtual ~BoardFactory() {}
|
||||
|
||||
BoardJson* instance() const { return m_instance; }
|
||||
|
||||
private:
|
||||
BoardJson *m_instance;
|
||||
};
|
||||
|
||||
class BoardFactories
|
||||
{
|
||||
public:
|
||||
explicit BoardFactories();
|
||||
virtual ~BoardFactories();
|
||||
|
||||
BoardJson* instance(Board::Type board) const;
|
||||
|
||||
bool registerBoard(Board::Type board, QString hwdefn);
|
||||
bool registerBoardFactory(BoardFactory * factory);
|
||||
void unregisterBoardFactories();
|
||||
|
||||
private:
|
||||
QList<BoardFactory *> registeredBoardFactories;
|
||||
|
||||
BoardJson *m_default;
|
||||
};
|
||||
|
||||
extern BoardFactories* gBoardFactories;
|
||||
@@ -0,0 +1,991 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "boardjson.h"
|
||||
#include "datahelpers.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
static const StringTagMappingTable inputTypesLookupTable = {
|
||||
{std::to_string(Board::AIT_NONE), "NONE"},
|
||||
{std::to_string(Board::AIT_STICK), "STICK"},
|
||||
{std::to_string(Board::AIT_FLEX), "FLEX"},
|
||||
{std::to_string(Board::AIT_VBAT), "VBAT"},
|
||||
{std::to_string(Board::AIT_RTC_BAT), "RTC_BAT"},
|
||||
{std::to_string(Board::AIT_SWITCH), "SWITCH"},
|
||||
};
|
||||
|
||||
static const StringTagMappingTable flexTypesLookupTable = {
|
||||
{std::to_string(Board::FLEX_NONE), "NONE"},
|
||||
{std::to_string(Board::FLEX_POT), "POT"},
|
||||
{std::to_string(Board::FLEX_POT_CENTER), "POT_CENTER"},
|
||||
{std::to_string(Board::FLEX_SLIDER), "SLIDER"},
|
||||
{std::to_string(Board::FLEX_MULTIPOS), "MULTIPOS"},
|
||||
{std::to_string(Board::FLEX_AXIS_X), "AXIS_X"},
|
||||
{std::to_string(Board::FLEX_AXIS_Y), "AXIS_Y"},
|
||||
{std::to_string(Board::FLEX_SWITCH), "SWITCH"},
|
||||
};
|
||||
|
||||
static const StringTagMappingTable switchTypesLookupTable = {
|
||||
{std::to_string(Board::SWITCH_NOT_AVAILABLE), "NONE"},
|
||||
{std::to_string(Board::SWITCH_TOGGLE), "TOGGLE"},
|
||||
{std::to_string(Board::SWITCH_2POS), "2POS"},
|
||||
{std::to_string(Board::SWITCH_3POS), "3POS"},
|
||||
{std::to_string(Board::SWITCH_FUNC), "FSWITCH"},
|
||||
};
|
||||
|
||||
static const StringTagMappingTable stickNamesLookupTable = {
|
||||
{QCoreApplication::translate("BoardJson", "Rud").toStdString(), "LH"}, // air
|
||||
{QCoreApplication::translate("BoardJson", "Ele").toStdString(), "LV"}, // air
|
||||
{QCoreApplication::translate("BoardJson", "Thr").toStdString(), "RV"}, // air
|
||||
{QCoreApplication::translate("BoardJson", "Ail").toStdString(), "RH"}, // air
|
||||
{QCoreApplication::translate("BoardJson", "ST").toStdString(), "ST"}, // surface
|
||||
{QCoreApplication::translate("BoardJson", "TH").toStdString(), "TH"}, // surface
|
||||
};
|
||||
|
||||
BoardJson::BoardJson(Board::Type board, QString hwdefn) :
|
||||
m_board(board),
|
||||
m_hwdefn(hwdefn),
|
||||
m_inputs(new InputsTable),
|
||||
m_switches(new SwitchesTable),
|
||||
m_trims(new TrimsTable),
|
||||
m_inputCnt({0, 0, 0, 0, 0, 0, 0, 0, 0}),
|
||||
m_switchCnt({0, 0, 0})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BoardJson::~BoardJson()
|
||||
{
|
||||
delete m_inputs;
|
||||
delete m_switches;
|
||||
delete m_trims;
|
||||
}
|
||||
|
||||
// static
|
||||
void BoardJson::afterLoadFixups(Board::Type board, InputsTable * inputs, SwitchesTable * switches)
|
||||
{
|
||||
// TODO json files do not contain gyro defs
|
||||
// Radio cmake directive IMU is currently used
|
||||
if (IS_TARANIS_XLITES(board) || IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
if (getInputIndex(inputs, "TILT_X", Board::LVT_TAG) < 0) {
|
||||
InputDefn defn;
|
||||
defn.type = AIT_FLEX;
|
||||
defn.tag = "TILT_X";
|
||||
defn.name = "Tltx";
|
||||
defn.shortName = "X";
|
||||
defn.flexType = FLEX_AXIS_X;
|
||||
defn.inverted = false;
|
||||
defn.cfgYaml = Board::LVT_TAG;
|
||||
defn.refYaml = Board::LVT_TAG; // non-default
|
||||
inputs->insert(inputs->end(), defn);
|
||||
}
|
||||
|
||||
if (getInputIndex(inputs, "TILT_Y", Board::LVT_TAG) < 0) {
|
||||
InputDefn defn;
|
||||
defn.type = AIT_FLEX;
|
||||
defn.tag = "TILT_Y";
|
||||
defn.name = "Tlty";
|
||||
defn.shortName = "Y";
|
||||
defn.flexType = FLEX_AXIS_Y;
|
||||
defn.inverted = false;
|
||||
defn.cfgYaml = Board::LVT_TAG;
|
||||
defn.refYaml = Board::LVT_TAG; // non-default
|
||||
inputs->insert(inputs->end(), defn);
|
||||
}
|
||||
}
|
||||
|
||||
// Flex switches are not listed in json file
|
||||
int count = IS_RADIOMASTER_TX16S(board) ? 2 : 0;
|
||||
|
||||
for (int i = 1; i <= count; i++) {
|
||||
QString tag = QString("FL%1").arg(i);
|
||||
if (getSwitchIndex(switches, tag, Board::LVT_TAG) < 0) {
|
||||
SwitchDefn defn;
|
||||
defn.tag = tag.toStdString();
|
||||
defn.name = defn.tag;
|
||||
switches->insert(switches->end(), defn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called from Boards::getCapability if no capability match
|
||||
// WARNING - potential for infinite loop if Boards::getCapability(m_board, capability) called from here!!!!!
|
||||
const int BoardJson::getCapability(const Board::Capability capability) const
|
||||
{
|
||||
switch (capability) {
|
||||
case Board::FlexInputs:
|
||||
return (m_inputCnt.flexGyroAxes +
|
||||
m_inputCnt.flexJoystickAxes +
|
||||
m_inputCnt.flexPots +
|
||||
m_inputCnt.flexSliders +
|
||||
m_inputCnt.flexSwitches);
|
||||
|
||||
case Board::FlexSwitches:
|
||||
return m_switchCnt.flex;
|
||||
|
||||
case Board::FunctionSwitches:
|
||||
return m_switchCnt.func;
|
||||
|
||||
case Board::GyroAxes:
|
||||
return m_inputCnt.flexGyroAxes;
|
||||
|
||||
case Board::Gyros:
|
||||
return getCapability(Board::GyroAxes) / 2;
|
||||
|
||||
case Board::HasRTC:
|
||||
return m_inputCnt.rtcbat;
|
||||
|
||||
case Board::HasVBat:
|
||||
return m_inputCnt.vbat;
|
||||
|
||||
case Board::Inputs:
|
||||
return m_inputs->size();
|
||||
|
||||
case Board::InputSwitches:
|
||||
return m_inputCnt.switches;
|
||||
|
||||
case Board::MultiposPots:
|
||||
// assumes every input has potential to be one
|
||||
// index used for mapping 6 pos switches back to input
|
||||
return getCapability(Board::Inputs);
|
||||
|
||||
case Board::MultiposPotsPositions:
|
||||
return 6;
|
||||
|
||||
case Board::NumFunctionSwitchesPositions:
|
||||
return getCapability(Board::FunctionSwitches) * 3;
|
||||
|
||||
case Board::NumTrims:
|
||||
return m_trims->size();
|
||||
|
||||
case Board::NumTrimSwitches:
|
||||
return getCapability(Board::NumTrims) * 2;
|
||||
|
||||
case Board::Pots:
|
||||
return m_inputCnt.flexPots;
|
||||
|
||||
case Board::Sliders:
|
||||
return m_inputCnt.flexSliders;
|
||||
|
||||
case Board::StandardSwitches:
|
||||
return m_switchCnt.std;
|
||||
|
||||
case Board::Sticks:
|
||||
return m_inputCnt.sticks;
|
||||
|
||||
case Board::Switches:
|
||||
return (m_switchCnt.std +
|
||||
m_switchCnt.flex +
|
||||
m_switchCnt.func);
|
||||
|
||||
case Board::SwitchesPositions:
|
||||
return getCapability(Board::Switches) * 3;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const int BoardJson::getInputIndex(const QString val, Board::LookupValueType lvt) const
|
||||
{
|
||||
return getInputIndex(m_inputs, val, lvt);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getInputIndex(const InputsTable * inputs, QString val, Board::LookupValueType lvt)
|
||||
{
|
||||
for (int i = 0; i < (int)inputs->size(); i++) {
|
||||
if ((lvt == Board::LVT_TAG && inputs->at(i).tag.c_str() == val) ||
|
||||
(lvt == Board::LVT_NAME && inputs->at(i).name.c_str() == val))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString BoardJson::getInputName(int index) const
|
||||
{
|
||||
return getInputName(m_inputs, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getInputName(const InputsTable * inputs, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)inputs->size())
|
||||
return inputs->at(index).name.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const QString BoardJson::getInputTag(int index) const
|
||||
{
|
||||
return getInputTag(m_inputs, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getInputTag(const InputsTable * inputs, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)inputs->size())
|
||||
return inputs->at(index).tag.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputYamlIndex(const QString val, YamlLookupType ylt) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_inputs->size(); i++) {
|
||||
Board::LookupValueType type = (ylt == YLT_CONFIG ? m_inputs->at(i).cfgYaml : m_inputs->at(i).refYaml);
|
||||
QString tmp = (type == Board::LVT_NAME ? getInputName(m_inputs, i) : getInputTag(m_inputs, i));
|
||||
if (val == tmp)
|
||||
return getInputIndex(m_inputs, val, type);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString BoardJson::getInputYamlName(int index, YamlLookupType ylt) const
|
||||
{
|
||||
if (index > -1 && index < (int)m_inputs->size()) {
|
||||
if (ylt == YLT_CONFIG)
|
||||
return m_inputs->at(index).cfgYaml == Board::LVT_NAME ? getInputName(m_inputs, index) : getInputTag(m_inputs, index);
|
||||
else
|
||||
return m_inputs->at(index).refYaml == Board::LVT_NAME ? getInputName(m_inputs, index) : getInputTag(m_inputs, index);
|
||||
}
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputsCalibrated() const
|
||||
{
|
||||
return getInputsCalibrated(m_inputs);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getInputsCalibrated(const InputsTable * inputs)
|
||||
{
|
||||
unsigned int cnt = 0;
|
||||
|
||||
for (const auto &defn : *inputs) {
|
||||
if (isInputCalibrated(defn)) cnt++;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputTagOffset(QString tag)
|
||||
{
|
||||
return getInputTagOffset(m_inputs, tag);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getInputTagOffset(const InputsTable * inputs, QString tag)
|
||||
{
|
||||
for (int i = 0; i < (int)inputs->size(); i++) {
|
||||
if (tag == inputs->at(i).tag.c_str())
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputPotIndex(int index)
|
||||
{
|
||||
if (getCapability(Board::Pots) > 0)
|
||||
return getInputTagOffset(m_inputs, QString("P%1").arg(index));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputSliderIndex(int index)
|
||||
{
|
||||
if (getCapability(Board::Sliders) > 0)
|
||||
return getInputTagOffset(m_inputs, QString("SL%1").arg(index));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int BoardJson::getInputTypeOffset(Board::AnalogInputType type)
|
||||
{
|
||||
return getInputTypeOffset(m_inputs, type);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getInputTypeOffset(const InputsTable * inputs, Board::AnalogInputType type)
|
||||
{
|
||||
for (int i = 0; i < (int)inputs->size(); i++) {
|
||||
if (type == inputs->at(i).type)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Board::InputInfo BoardJson::getInputInfo(int index) const
|
||||
{
|
||||
return getInputInfo(m_inputs, index);
|
||||
}
|
||||
|
||||
// static
|
||||
Board::InputInfo BoardJson::getInputInfo(const InputsTable * inputs, int index)
|
||||
{
|
||||
Board::InputInfo info;
|
||||
|
||||
if (index >= 0 && index < (int)inputs->size()) {
|
||||
InputDefn defn = inputs->at(index);
|
||||
info.type = defn.type;
|
||||
info.tag = defn.tag;
|
||||
info.name = defn.name;
|
||||
info.shortName = defn.shortName;
|
||||
info.flexType = defn.flexType;
|
||||
info.inverted = defn.inverted;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getNumericSuffix(const std::string str)
|
||||
{
|
||||
std::string suffix = std::string();
|
||||
|
||||
for (int i = 0; i < (int)str.size(); i++) {
|
||||
if (str.substr(i, 1) >= "0" && str.substr(i, 1) <= "9")
|
||||
suffix.append(str.substr(i, 1));
|
||||
}
|
||||
|
||||
if (!suffix.empty())
|
||||
return std::stoi(suffix);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int BoardJson::getSwitchIndex(const QString val, Board::LookupValueType lvt) const
|
||||
{
|
||||
return getSwitchIndex(m_switches, val, lvt);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getSwitchIndex(const SwitchesTable * switches, QString val, Board::LookupValueType lvt)
|
||||
{
|
||||
for (int i = 0; i < (int)switches->size(); i++) {
|
||||
if ((lvt == Board::LVT_TAG && switches->at(i).tag.c_str() == val) ||
|
||||
(lvt == Board::LVT_NAME && switches->at(i).name.c_str() == val))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const Board::SwitchInfo BoardJson::getSwitchInfo(int index) const
|
||||
{
|
||||
return getSwitchInfo(m_switches, index);
|
||||
}
|
||||
|
||||
// static
|
||||
Board::SwitchInfo BoardJson::getSwitchInfo(const SwitchesTable * switches, int index)
|
||||
{
|
||||
Board::SwitchInfo info;
|
||||
|
||||
if (index >= 0 && index < (int)switches->size()) {
|
||||
SwitchDefn defn = switches->at(index);
|
||||
info.type = defn.type;
|
||||
info.tag = defn.tag;
|
||||
info.name = defn.name;
|
||||
info.inverted = defn.inverted;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
const QString BoardJson::getSwitchName(int index) const
|
||||
{
|
||||
return getSwitchName(m_switches, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getSwitchName(const SwitchesTable * switches, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)switches->size())
|
||||
return switches->at(index).name.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const QString BoardJson::getSwitchTag(int index) const
|
||||
{
|
||||
return getSwitchTag(m_switches, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getSwitchTag(const SwitchesTable * switches, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)switches->size())
|
||||
return switches->at(index).tag.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const int BoardJson::getSwitchTagNum(int index) const
|
||||
{
|
||||
return getSwitchTagNum(m_switches, index);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getSwitchTagNum(const SwitchesTable * switches, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)switches->size())
|
||||
return getNumericSuffix(switches->at(index).tag.c_str());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int BoardJson::getSwitchYamlIndex(const QString val, YamlLookupType ylt) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_switches->size(); i++) {
|
||||
Board::LookupValueType type = (ylt == YLT_CONFIG ? m_switches->at(i).cfgYaml : m_switches->at(i).refYaml);
|
||||
QString tmp = (type == Board::LVT_NAME ? getSwitchName(m_switches, i) : getSwitchTag(m_switches, i));
|
||||
if (val == tmp)
|
||||
return getSwitchIndex(m_switches, val, type);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString BoardJson::getSwitchYamlName(int index, YamlLookupType ylt) const
|
||||
{
|
||||
if (index > -1 && index < (int)m_switches->size()) {
|
||||
if (ylt == YLT_CONFIG)
|
||||
return m_switches->at(index).cfgYaml == Board::LVT_NAME ? getSwitchName(m_switches, index) : getSwitchTag(m_switches, index);
|
||||
else
|
||||
return m_switches->at(index).refYaml == Board::LVT_NAME ? getSwitchName(m_switches, index) : getSwitchTag(m_switches, index);
|
||||
}
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const int BoardJson::getTrimIndex(const QString val, Board::LookupValueType lvt) const
|
||||
{
|
||||
return getTrimIndex(m_trims, val, lvt);
|
||||
}
|
||||
|
||||
// static
|
||||
int BoardJson::getTrimIndex(const TrimsTable * trims, QString val, Board::LookupValueType lvt)
|
||||
{
|
||||
for (int i = 0; i < (int)trims->size(); i++) {
|
||||
if ((lvt == Board::LVT_TAG && trims->at(i).tag.c_str() == val) ||
|
||||
(lvt == Board::LVT_NAME && trims->at(i).name.c_str() == val))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString BoardJson::getTrimName(int index) const
|
||||
{
|
||||
return getTrimName(m_trims, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getTrimName(const TrimsTable * trims, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)trims->size())
|
||||
return trims->at(index).name.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const QString BoardJson::getTrimTag(int index) const
|
||||
{
|
||||
return getTrimTag(m_trims, index);
|
||||
}
|
||||
|
||||
// static
|
||||
QString BoardJson::getTrimTag(const TrimsTable * trims, int index)
|
||||
{
|
||||
if (index > -1 && index < (int)trims->size())
|
||||
return trims->at(index).tag.c_str();
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const int BoardJson::getTrimYamlIndex(const QString val, YamlLookupType ylt) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_trims->size(); i++) {
|
||||
Board::LookupValueType type = (ylt == YLT_CONFIG ? m_trims->at(i).cfgYaml : m_trims->at(i).refYaml);
|
||||
QString tmp = (type == Board::LVT_NAME ? getTrimName(m_trims, i) : getTrimTag(m_trims, i));
|
||||
if (val == tmp)
|
||||
return getTrimIndex(m_trims, val, type);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString BoardJson::getTrimYamlName(int index, YamlLookupType ylt) const
|
||||
{
|
||||
if (index > -1 && index < (int)m_trims->size()) {
|
||||
if (ylt == YLT_CONFIG)
|
||||
return m_trims->at(index).cfgYaml == Board::LVT_NAME ? getTrimName(m_trims, index) : getTrimTag(m_trims, index);
|
||||
else
|
||||
return m_trims->at(index).refYaml == Board::LVT_NAME ? getTrimName(m_trims, index) : getTrimTag(m_trims, index);
|
||||
}
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputAvailable(int index) const
|
||||
{
|
||||
return isInputAvailable(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputAvailable(const InputDefn & defn)
|
||||
{
|
||||
return (defn.type == Board::AIT_STICK ||
|
||||
(defn.type == Board::AIT_FLEX && defn.flexType != Board::FLEX_NONE && !isInputFlexJoystickAxis(defn)));
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputCalibrated(int index) const
|
||||
{
|
||||
return isInputCalibrated(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputCalibrated(const InputDefn & defn)
|
||||
{
|
||||
return (isInputStick(defn) || isInputFlexPot(defn) || isInputFlexSlider(defn));
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputConfigurable(int index) const
|
||||
{
|
||||
return isInputConfigurable(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputConfigurable(const InputDefn & defn)
|
||||
{
|
||||
return (isInputStick(defn) || isInputFlexPot(defn) || isInputFlexSlider(defn));
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputIgnored(int index) const
|
||||
{
|
||||
return isInputIgnored(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputIgnored(const InputDefn & defn)
|
||||
{
|
||||
return (isInputFlexJoystickAxis(defn) || isInputSwitch(defn));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlex(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_FLEX;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexGyroAxis(const InputDefn & defn)
|
||||
{
|
||||
const char* val = defn.tag.data();
|
||||
|
||||
return (defn.type == Board::AIT_FLEX && defn.tag.size() > 5 &&
|
||||
val[0] == 'T' && val[1] == 'I' && val[2] == 'L' && val[3] == 'T' && val[4] == '_' && (val[5] == 'X' || val[5] == 'Y'));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexJoystickAxis(const InputDefn & defn)
|
||||
{
|
||||
const char* val = defn.tag.data();
|
||||
|
||||
return (defn.type == Board::AIT_FLEX && defn.tag.size() > 2 &&
|
||||
val[0] == 'J' && val[1] == 'S' && (val[2] == 'x' || val[2] == 'y'));
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputFlexPot(int index) const
|
||||
{
|
||||
return isInputFlexPot(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexPot(const InputDefn & defn)
|
||||
{
|
||||
const char* val = defn.tag.data();
|
||||
size_t len = defn.tag.size();
|
||||
|
||||
return (defn.type == Board::AIT_FLEX &&
|
||||
((len > 1 && val[0] == 'P' && val[1] >= '0' && val[1] <= '9') ||
|
||||
(len > 3 && val[0] == 'E' && val[1] == 'X' && val[2] == 'T' && val[3] >= '0' && val[3] <= '9')));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexPotMultipos(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_FLEX && defn.flexType == Board::FLEX_MULTIPOS;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexSlider(const InputDefn & defn)
|
||||
{
|
||||
const char* val = defn.tag.data();
|
||||
|
||||
return (defn.type == Board::AIT_FLEX && defn.tag.size() > 2 &&
|
||||
val[0] == 'S' && val[1] == 'L' && val[2] >= '0' && val[2] <= '9');
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputFlexSwitch(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_FLEX && defn.flexType == Board::FLEX_SWITCH;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputRTCBat(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_RTC_BAT;
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputStick(int index) const
|
||||
{
|
||||
return isInputStick(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputStick(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_STICK;
|
||||
}
|
||||
|
||||
const bool BoardJson::isInputSwitch(int index) const
|
||||
{
|
||||
return isInputSwitch(m_inputs->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputSwitch(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_SWITCH;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isInputVBat(const InputDefn & defn)
|
||||
{
|
||||
return defn.type == Board::AIT_VBAT;
|
||||
}
|
||||
|
||||
const bool BoardJson::isSwitchConfigurable(int index) const
|
||||
{
|
||||
if (index >= 0 && index < getCapability(Board::Switches)) {
|
||||
SwitchDefn &defn = m_switches->at(index);
|
||||
if (isSwitchStd(defn))
|
||||
return true;
|
||||
|
||||
if (isSwitchFlex(defn)) {
|
||||
int sfx = getNumericSuffix(defn.tag);
|
||||
if (sfx > 0 && sfx <= getCapability(Board::FlexSwitches))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isSwitchStd(const SwitchDefn & defn)
|
||||
{
|
||||
return !(isSwitchFlex(defn) || isSwitchFunc(defn));
|
||||
}
|
||||
|
||||
const bool BoardJson::isSwitchFlex(int index) const
|
||||
{
|
||||
return isSwitchFlex(m_switches->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isSwitchFlex(const SwitchDefn & defn)
|
||||
{
|
||||
const char* val = defn.tag.data();
|
||||
|
||||
return (defn.tag.size() > 2 &&
|
||||
val[0] == 'F' && val[1] == 'L' && val[2] >= '0' && val[2] <= '9');
|
||||
}
|
||||
|
||||
const bool BoardJson::isSwitchFunc(int index) const
|
||||
{
|
||||
return isSwitchFunc(m_switches->at(index));
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::isSwitchFunc(const SwitchDefn & defn)
|
||||
{
|
||||
return defn.type == Board::SWITCH_FUNC;
|
||||
}
|
||||
|
||||
bool BoardJson::loadDefinition()
|
||||
{
|
||||
// safety net for BoardFactory::instance
|
||||
if (m_board == Board::BOARD_UNKNOWN)
|
||||
return true;
|
||||
|
||||
if (!loadFile(m_board, m_hwdefn, m_inputs, m_switches, m_trims))
|
||||
return false;
|
||||
|
||||
afterLoadFixups(m_board, m_inputs, m_switches);
|
||||
|
||||
setInputCounts(m_inputs, m_inputCnt);
|
||||
setSwitchCounts(m_switches, m_switchCnt);
|
||||
|
||||
// json files do not normally specify stick labels so load legacy labels
|
||||
for (int i = 0; i < getCapability(Board::Sticks); i++) {
|
||||
if (m_inputs->at(i).name.empty())
|
||||
m_inputs->at(i).name = DataHelpers::getStringTagMappingName(stickNamesLookupTable, m_inputs->at(i).tag.c_str());
|
||||
}
|
||||
|
||||
qDebug() << "Board:" << Boards::getBoardName(m_board) <<
|
||||
"inputs:" << getCapability(Board::Inputs) <<
|
||||
"sticks:" << getCapability(Board::Sticks) <<
|
||||
"pots:" << getCapability(Board::Pots) <<
|
||||
"sliders:" << getCapability(Board::Sliders) <<
|
||||
"gyro axes:" << getCapability(Board::GyroAxes) <<
|
||||
"joystick axes:" << getCapability(Board::JoystickAxes) <<
|
||||
"flex inputs:" << getCapability(Board::FlexInputs) <<
|
||||
"input switches:" << getCapability(Board::InputSwitches) <<
|
||||
"trims:" << getCapability(Board::NumTrims) <<
|
||||
"std switches:" << getCapability(Board::StandardSwitches) <<
|
||||
"flex switches:" << getCapability(Board::FlexSwitches) <<
|
||||
"func switches:" << getCapability(Board::FunctionSwitches) <<
|
||||
"rtcbat:" << getCapability(Board::HasRTC) <<
|
||||
"vbat:" << getCapability(Board::HasVBat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches, TrimsTable * trims)
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// required because of the way the Firmware class is used
|
||||
if (hwdefn.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString path = QString(":/hwdefs/%1.json").arg(hwdefn);
|
||||
QFile file(path);
|
||||
|
||||
if (!file.exists()) {
|
||||
QMessageBox::critical(nullptr, tr("Load Board Hardware Definition"),
|
||||
tr("Board: %1\nError: Unable to load file %2").arg(Boards::getBoardName(board)).arg(path));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
QMessageBox::critical(nullptr, tr("Load Board Hardware Definition"),
|
||||
tr("Board: %1\nError: Unable to open file %2").arg(Boards::getBoardName(board)).arg(path));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray buffer = file.readAll();
|
||||
file.close();
|
||||
|
||||
if (buffer.isEmpty()) {
|
||||
QMessageBox::critical(nullptr, tr("Load Board Hardware Definition"),
|
||||
tr("Board: %1\nError: Unable to read file %2").arg(Boards::getBoardName(board)).arg(path));
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonParseError res;
|
||||
QJsonDocument *json = new QJsonDocument();
|
||||
*json = QJsonDocument::fromJson(buffer, &res);
|
||||
|
||||
if (res.error || json->isNull() || !json->isObject()) {
|
||||
QMessageBox::critical(nullptr, tr("Load Board Hardware Definition"),
|
||||
tr("Board: %1\nError: %2 is not a valid json formatted file.\nError code: %3\nError description: %4").arg(Boards::getBoardName(board)).arg(path).arg(res.error).arg(res.errorString()));
|
||||
delete json;
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonObject &obj = json->object();
|
||||
|
||||
if (obj.value("adc_inputs").isObject()) {
|
||||
const QJsonObject &adcinputs = obj.value("adc_inputs").toObject();
|
||||
|
||||
if (adcinputs.value("inputs").isArray()) {
|
||||
const QJsonArray &in = adcinputs.value("inputs").toArray();
|
||||
|
||||
for (const QJsonValue &input : in)
|
||||
{
|
||||
if (input.isObject()) {
|
||||
const QJsonObject &o = input.toObject();
|
||||
InputDefn defn;
|
||||
|
||||
if (!o.value("name").isUndefined())
|
||||
defn.tag = o.value("name").toString().toStdString();
|
||||
|
||||
if (!o.value("type").isUndefined()) {
|
||||
std::string type = o.value("type").toString().toStdString();
|
||||
defn.type = (AnalogInputType)DataHelpers::getStringTagMappingIndex(inputTypesLookupTable, type.c_str());
|
||||
if (defn.type == AIT_STICK)
|
||||
defn.refYaml = LVT_NAME;
|
||||
}
|
||||
|
||||
if (!o.value("inverted").isUndefined())
|
||||
defn.inverted = o.value("inverted").toBool();
|
||||
|
||||
if (!o.value("label").isUndefined())
|
||||
defn.name = o.value("label").toString().toStdString();
|
||||
|
||||
if (!o.value("short_label").isUndefined())
|
||||
defn.shortName = o.value("short_label").toString().toStdString();
|
||||
|
||||
if (!o.value("default").isUndefined()) {
|
||||
std::string dflt = o.value("default").toString().toStdString();
|
||||
if (defn.type == AIT_FLEX) {
|
||||
int idx = DataHelpers::getStringTagMappingIndex(flexTypesLookupTable, dflt.c_str());
|
||||
defn.flexType = (FlexType)(idx < 0 ? FLEX_NONE : idx);
|
||||
}
|
||||
}
|
||||
|
||||
inputs->insert(inputs->end(), defn);
|
||||
|
||||
// qDebug() << "name:" << defn.name.c_str() <<
|
||||
// "type:" << defn.stype.c_str() << ">" <<
|
||||
// DataHelpers::getStringNameMappingTag(inputTypesLookupTable, std::to_string(defn.type).c_str()).c_str() <<
|
||||
// "label:" << defn.label.c_str() << "short:" << defn.shortLabel.c_str() << "inverted:" << defn.inverted <<
|
||||
// "dflt:" << defn.dflt.c_str() << ">" <<
|
||||
// DataHelpers::getStringNameMappingTag(flexTypesLookupTable, std::to_string(defn.flexType).c_str()).c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.value("switches").isArray()) {
|
||||
const QJsonArray &swtchs = obj.value("switches").toArray();
|
||||
|
||||
for (const QJsonValue &swtch : swtchs)
|
||||
{
|
||||
if (swtch.isObject()) {
|
||||
const QJsonObject &o = swtch.toObject();
|
||||
SwitchDefn sw;
|
||||
|
||||
if (!o.value("name").isUndefined()) {
|
||||
sw.name = o.value("name").toString().toStdString();
|
||||
sw.tag = sw.name;
|
||||
}
|
||||
|
||||
if (!o.value("type").isUndefined()) {
|
||||
std::string type = o.value("type").toString().toStdString();
|
||||
int idx = DataHelpers::getStringTagMappingIndex(switchTypesLookupTable, type.c_str());
|
||||
sw.type = idx < 0 ? Board::SWITCH_NOT_AVAILABLE : (Board::SwitchType)idx;
|
||||
}
|
||||
|
||||
if (!o.value("flags").isUndefined())
|
||||
sw.flags = o.value("flags").toInt();
|
||||
|
||||
if (!o.value("inverted").isUndefined())
|
||||
sw.inverted = o.value("inverted").toBool();
|
||||
|
||||
if (!o.value("default").isUndefined()) {
|
||||
std::string dflt = o.value("default").toString().toStdString();
|
||||
int idx = DataHelpers::getStringTagMappingIndex(switchTypesLookupTable, dflt.c_str());
|
||||
sw.dflt = idx < 0 ? Board::SWITCH_NOT_AVAILABLE : (Board::SwitchType)idx;
|
||||
}
|
||||
|
||||
if (o.value("display").isArray()) {
|
||||
const QJsonArray &d = obj.value("display").toArray();
|
||||
sw.display.x = (unsigned int)d.at(0).toInt(0);
|
||||
sw.display.y = (unsigned int)d.at(1).toInt(0);
|
||||
}
|
||||
|
||||
switches->insert(switches->end(), sw);
|
||||
|
||||
// qDebug() << "name:" << sw.name.c_str() << "type:" << sw.stype.c_str() << ">" << Boards::switchTypeToString(sw.type) <<
|
||||
// "flags:" << sw.flags << "default:" << sw.sdflt.c_str() << ">" << Boards::switchTypeToString(sw.dflt) <<
|
||||
// "inverted:" << sw.inverted << "display:" << QString("%1").arg(sw.display.x) << "," << QString("%1").arg(sw.display.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.value("trims").isArray()) {
|
||||
const QJsonArray &trms = obj.value("trims").toArray();
|
||||
|
||||
for (const QJsonValue &trm : trms)
|
||||
{
|
||||
if (trm.isObject()) {
|
||||
const QJsonObject &o = trm.toObject();
|
||||
TrimDefn t;
|
||||
|
||||
if (!o.value("name").isUndefined()) {
|
||||
t.name = o.value("name").toString().toStdString();
|
||||
t.tag = t.name;
|
||||
}
|
||||
|
||||
trims->insert(trims->end(), t);
|
||||
|
||||
// qDebug() << "name:" << t.name.c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete json;
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
void BoardJson::setInputCounts(const InputsTable * inputs, InputCounts & inputCounts)
|
||||
{
|
||||
for (const auto &defn : *inputs) {
|
||||
if (isInputStick(defn))
|
||||
inputCounts.sticks++;
|
||||
else if (isInputFlexPot(defn))
|
||||
inputCounts.flexPots++;
|
||||
else if (isInputFlexSlider(defn))
|
||||
inputCounts.flexSliders++;
|
||||
else if (isInputFlexGyroAxis(defn))
|
||||
inputCounts.flexGyroAxes++;
|
||||
else if (isInputFlexJoystickAxis(defn))
|
||||
inputCounts.flexJoystickAxes++;
|
||||
else if (isInputFlexSwitch(defn))
|
||||
inputCounts.flexSwitches++;
|
||||
else if (isInputRTCBat(defn))
|
||||
inputCounts.rtcbat++;
|
||||
else if (isInputVBat(defn))
|
||||
inputCounts.vbat++;
|
||||
else if (isInputSwitch(defn))
|
||||
inputCounts.switches++;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void BoardJson::setSwitchCounts(const SwitchesTable * switches, SwitchCounts & switchCounts)
|
||||
{
|
||||
for (const auto &swtch : *switches) {
|
||||
if (isSwitchStd(swtch))
|
||||
switchCounts.std++;
|
||||
else if (isSwitchFlex(swtch))
|
||||
switchCounts.flex++;
|
||||
else if (isSwitchFunc(swtch))
|
||||
switchCounts.func++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "boards.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace Board;
|
||||
|
||||
class BoardJson
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(BoardJson)
|
||||
|
||||
public:
|
||||
enum YamlLookupType {
|
||||
YLT_CONFIG,
|
||||
YLT_REF
|
||||
};
|
||||
|
||||
struct InputDefn {
|
||||
Board::AnalogInputType type = AIT_NONE;
|
||||
std::string tag = "";
|
||||
std::string name = "";
|
||||
std::string shortName = "";
|
||||
Board::FlexType flexType = FLEX_NONE;
|
||||
bool inverted = false;
|
||||
Board::LookupValueType cfgYaml = Board::LVT_TAG;
|
||||
Board::LookupValueType refYaml = Board::LVT_TAG;
|
||||
|
||||
InputDefn() = default;
|
||||
};
|
||||
|
||||
typedef std::vector<InputDefn> InputsTable;
|
||||
|
||||
struct Display {
|
||||
unsigned int x = 0;
|
||||
unsigned int y = 0;
|
||||
};
|
||||
|
||||
struct SwitchDefn {
|
||||
Board::SwitchType type = Board::SWITCH_NOT_AVAILABLE;
|
||||
std::string tag = "";
|
||||
std::string name = "";
|
||||
int flags = 0;
|
||||
bool inverted = false;
|
||||
Board::SwitchType dflt = Board::SWITCH_NOT_AVAILABLE;
|
||||
Display display;
|
||||
Board::LookupValueType cfgYaml = Board::LVT_TAG;
|
||||
Board::LookupValueType refYaml = Board::LVT_NAME;
|
||||
|
||||
SwitchDefn() = default;
|
||||
};
|
||||
|
||||
typedef std::vector<SwitchDefn> SwitchesTable;
|
||||
|
||||
struct TrimDefn {
|
||||
std::string tag = "";
|
||||
std::string name = "";
|
||||
Board::LookupValueType cfgYaml = Board::LVT_TAG;
|
||||
Board::LookupValueType refYaml = Board::LVT_NAME;
|
||||
|
||||
TrimDefn() = default;
|
||||
};
|
||||
|
||||
typedef std::vector<TrimDefn> TrimsTable;
|
||||
|
||||
explicit BoardJson(Board::Type board, QString hwdefn);
|
||||
virtual ~BoardJson();
|
||||
|
||||
Board::Type board() const { return m_board; }
|
||||
QString hwdefn() const { return m_hwdefn; }
|
||||
|
||||
bool loadDefinition();
|
||||
|
||||
const int getCapability(const Board::Capability capability) const;
|
||||
const int getInputsCalibrated() const;
|
||||
|
||||
const int getInputIndex(const QString val, Board::LookupValueType lvt) const;
|
||||
const Board::InputInfo getInputInfo(int index) const;
|
||||
const QString getInputName(int index) const;
|
||||
const int getInputPotIndex(int index);
|
||||
const int getInputSliderIndex(int index);
|
||||
const QString getInputTag(int index) const;
|
||||
const int getInputTagOffset(QString tag);
|
||||
const int getInputTypeOffset(Board::AnalogInputType type);
|
||||
const int getInputYamlIndex(const QString val, YamlLookupType ylt) const;
|
||||
const QString getInputYamlName(int index, YamlLookupType ylt) const;
|
||||
|
||||
const bool isInputAvailable(int index) const;
|
||||
const bool isInputCalibrated(int index) const;
|
||||
const bool isInputConfigurable(int index) const;
|
||||
const bool isInputIgnored(int index) const;
|
||||
const bool isInputFlexPot(int index) const;
|
||||
const bool isInputFlexSwitch(int index) const;
|
||||
const bool isInputStick(int index) const;
|
||||
const bool isInputSwitch(int index) const;
|
||||
|
||||
const int getSwitchIndex(const QString val, Board::LookupValueType lvt) const;
|
||||
const Board::SwitchInfo getSwitchInfo(int index) const;
|
||||
const QString getSwitchName(int index) const;
|
||||
const QString getSwitchTag(int index) const;
|
||||
const int getSwitchTagNum(int index) const;
|
||||
const int getSwitchYamlIndex(const QString val, YamlLookupType ylt) const;
|
||||
const QString getSwitchYamlName(int index, YamlLookupType ylt) const;
|
||||
|
||||
const int getTrimIndex(const QString val, Board::LookupValueType lvt) const;
|
||||
const QString getTrimName(int index) const;
|
||||
const QString getTrimTag(int index) const;
|
||||
const int getTrimYamlIndex(const QString val, YamlLookupType ylt) const;
|
||||
const QString getTrimYamlName(int index, YamlLookupType ylt) const;
|
||||
|
||||
const bool isSwitchConfigurable(int index) const;
|
||||
const bool isSwitchFlex(int index) const;
|
||||
const bool isSwitchFunc(int index) const;
|
||||
private:
|
||||
Board::Type m_board;
|
||||
QString m_hwdefn;
|
||||
|
||||
InputsTable *m_inputs;
|
||||
SwitchesTable *m_switches;
|
||||
TrimsTable *m_trims;
|
||||
|
||||
struct InputCounts {
|
||||
unsigned int flexGyroAxes;
|
||||
unsigned int flexJoystickAxes;
|
||||
unsigned int flexPots;
|
||||
unsigned int flexSliders;
|
||||
unsigned int flexSwitches;
|
||||
unsigned int rtcbat;
|
||||
unsigned int sticks;
|
||||
unsigned int switches;
|
||||
unsigned int vbat;
|
||||
};
|
||||
|
||||
InputCounts m_inputCnt;
|
||||
|
||||
struct SwitchCounts {
|
||||
unsigned int std;
|
||||
unsigned int flex;
|
||||
unsigned int func;
|
||||
};
|
||||
|
||||
SwitchCounts m_switchCnt;
|
||||
|
||||
static bool loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches, TrimsTable * trims);
|
||||
static void afterLoadFixups(Board::Type board, InputsTable * inputs, SwitchesTable * switches);
|
||||
|
||||
static int getInputsCalibrated(const InputsTable * inputs);
|
||||
|
||||
static int getInputIndex(const InputsTable * inputs, QString val, Board::LookupValueType lvt);
|
||||
static Board::InputInfo getInputInfo(const InputsTable * inputs, int index);
|
||||
static QString getInputName(const InputsTable * inputs, int index);
|
||||
static QString getInputTag(const InputsTable * inputs, int index);
|
||||
static int getInputTagOffset(const InputsTable * inputs, QString tag);
|
||||
static int getInputTypeOffset(const InputsTable * inputs, Board::AnalogInputType type);
|
||||
|
||||
static int getSwitchIndex(const SwitchesTable * switches, QString val, Board::LookupValueType lvt);
|
||||
static Board::SwitchInfo getSwitchInfo(const SwitchesTable * switches, int index);
|
||||
static QString getSwitchName(const SwitchesTable * switches, int index);
|
||||
static QString getSwitchTag(const SwitchesTable * switches, int index);
|
||||
static int getSwitchTagNum(const SwitchesTable * switches, int index);
|
||||
|
||||
static int getTrimIndex(const TrimsTable * trims, QString val, Board::LookupValueType lvt);
|
||||
static QString getTrimName(const TrimsTable * trims, int index);
|
||||
static QString getTrimTag(const TrimsTable * trims, int index);
|
||||
|
||||
static bool isInputAvailable(const InputDefn & defn);
|
||||
static bool isInputCalibrated(const InputDefn & defn);
|
||||
static bool isInputConfigurable(const InputDefn & defn);
|
||||
static bool isInputFlex(const InputDefn & defn);
|
||||
static bool isInputFlexGyroAxis(const InputDefn & defn);
|
||||
static bool isInputFlexJoystickAxis(const InputDefn & defn);
|
||||
static bool isInputFlexPot(const InputDefn & defn);
|
||||
static bool isInputFlexPotMultipos(const InputDefn & defn);
|
||||
static bool isInputFlexSlider(const InputDefn & defn);
|
||||
static bool isInputFlexSwitch(const InputDefn & defn);
|
||||
static bool isInputIgnored(const InputDefn & defn);
|
||||
static bool isInputRTCBat(const InputDefn & defn);
|
||||
static bool isInputStick(const InputDefn & defn);
|
||||
static bool isInputSwitch(const InputDefn & defn);
|
||||
static bool isInputVBat(const InputDefn & defn);
|
||||
|
||||
static bool isSwitchStd(const SwitchDefn & defn);
|
||||
static bool isSwitchFlex(const SwitchDefn & defn);
|
||||
static bool isSwitchFunc(const SwitchDefn & defn);
|
||||
|
||||
static void setInputCounts(const InputsTable * inputs, InputCounts & inputCounts);
|
||||
static void setSwitchCounts(const SwitchesTable * switches, SwitchCounts & switchCounts);
|
||||
|
||||
static int getNumericSuffix(const std::string str);
|
||||
};
|
||||
+347
-768
File diff suppressed because it is too large
Load Diff
@@ -27,12 +27,15 @@
|
||||
|
||||
class AbstractStaticItemModel;
|
||||
class SemanticVersion;
|
||||
class BoardJson;
|
||||
class GeneralSettings;
|
||||
|
||||
// identiying names of static abstract item models
|
||||
constexpr char AIM_BOARDS_POT_TYPE[] {"boards.pottype"};
|
||||
constexpr char AIM_BOARDS_SLIDER_TYPE[] {"boards.slidertype"};
|
||||
constexpr char AIM_BOARDS_SWITCH_TYPE[] {"boards.switchtype"};
|
||||
constexpr char AIM_BOARDS_MODULE_SIZE[] {"boards.extmodulesize"};
|
||||
constexpr char AIM_BOARDS_FLEX_TYPE[] {"boards.flextype"};
|
||||
|
||||
// TODO create a Board class with all these functions
|
||||
|
||||
@@ -104,6 +107,7 @@ namespace Board {
|
||||
SWITCH_TOGGLE,
|
||||
SWITCH_2POS,
|
||||
SWITCH_3POS,
|
||||
SWITCH_FUNC,
|
||||
SWITCH_TYPE_COUNT
|
||||
};
|
||||
|
||||
@@ -149,39 +153,41 @@ namespace Board {
|
||||
};
|
||||
|
||||
enum Capability {
|
||||
Sticks,
|
||||
Pots,
|
||||
FactoryInstalledPots,
|
||||
Sliders,
|
||||
MouseAnalogs,
|
||||
GyroAnalogs,
|
||||
MaxAnalogs,
|
||||
MultiposPots,
|
||||
MultiposPotsPositions,
|
||||
Switches,
|
||||
FunctionSwitches,
|
||||
SwitchPositions,
|
||||
NumFunctionSwitchesPositions,
|
||||
FactoryInstalledSwitches,
|
||||
NumTrims,
|
||||
NumTrimSwitches,
|
||||
HasRTC,
|
||||
HasColorLcd,
|
||||
HasSDCard,
|
||||
HasInternalModuleSupport,
|
||||
HasExternalModuleSupport,
|
||||
FlexInputs,
|
||||
FlexSwitches,
|
||||
FunctionSwitches,
|
||||
Gyros,
|
||||
GyroAxes,
|
||||
HasAudioMuteGPIO,
|
||||
SportMaxBaudRate,
|
||||
HasColorLcd,
|
||||
HasExternalModuleSupport,
|
||||
HasInternalModuleSupport,
|
||||
HasIntModuleHeartbeatGPIO,
|
||||
HasLedStripGPIO,
|
||||
HasRTC,
|
||||
HasSDCard,
|
||||
HasTrainerModuleCPPM,
|
||||
HasTrainerModuleSBUS,
|
||||
HasLedStripGPIO
|
||||
};
|
||||
|
||||
struct SwitchInfo
|
||||
{
|
||||
SwitchType config;
|
||||
QString name;
|
||||
HasVBat,
|
||||
MaxAnalogs,
|
||||
Inputs,
|
||||
InputSwitches,
|
||||
Joysticks,
|
||||
JoystickAxes,
|
||||
MultiposPots,
|
||||
MultiposPotsPositions,
|
||||
NumFunctionSwitchesPositions,
|
||||
NumTrims,
|
||||
NumTrimSwitches,
|
||||
Pots,
|
||||
Sliders,
|
||||
SportMaxBaudRate,
|
||||
StandardSwitches,
|
||||
Sticks,
|
||||
Switches,
|
||||
SwitchesPositions,
|
||||
};
|
||||
|
||||
struct SwitchPosition {
|
||||
@@ -195,10 +201,12 @@ namespace Board {
|
||||
};
|
||||
|
||||
enum SwitchTypeMasks {
|
||||
SwitchTypeFlag2Pos = 0x01,
|
||||
SwitchTypeFlag3Pos = 0x02,
|
||||
SwitchTypeContext2Pos = SwitchTypeFlag2Pos,
|
||||
SwitchTypeContext3Pos = SwitchTypeFlag2Pos | SwitchTypeFlag3Pos
|
||||
SwitchTypeFlagNone = 1 << 1,
|
||||
SwitchTypeFlag2Pos = 1 << 2,
|
||||
SwitchTypeFlag3Pos = 1 << 3,
|
||||
SwitchTypeContextNone = SwitchTypeFlagNone,
|
||||
SwitchTypeContext2Pos = SwitchTypeContextNone | SwitchTypeFlag2Pos,
|
||||
SwitchTypeContext3Pos = SwitchTypeContext2Pos | SwitchTypeFlag3Pos
|
||||
};
|
||||
|
||||
enum ExternalModuleSizes {
|
||||
@@ -209,6 +217,72 @@ namespace Board {
|
||||
EXTMODSIZE_COUNT
|
||||
};
|
||||
|
||||
enum AnalogInputType
|
||||
{
|
||||
AIT_NONE,
|
||||
AIT_STICK,
|
||||
AIT_FLEX,
|
||||
AIT_VBAT,
|
||||
AIT_RTC_BAT,
|
||||
AIT_SWITCH,
|
||||
};
|
||||
|
||||
enum FlexType {
|
||||
FLEX_NONE = 0,
|
||||
FLEX_POT,
|
||||
FLEX_POT_CENTER,
|
||||
FLEX_SLIDER,
|
||||
FLEX_MULTIPOS,
|
||||
FLEX_AXIS_X,
|
||||
FLEX_AXIS_Y,
|
||||
FLEX_SWITCH,
|
||||
FLEX_TYPE_COUNT
|
||||
};
|
||||
|
||||
enum FlexTypeMasks {
|
||||
FlexTypeFlagNotSwitch = 1 << 1,
|
||||
FlexTypeFlagSwitch = 1 << 2,
|
||||
FlexTypeContextNoSwitch = FlexTypeFlagNotSwitch,
|
||||
FlexTypeContextSwitch = FlexTypeContextNoSwitch | FlexTypeFlagSwitch
|
||||
};
|
||||
|
||||
enum LookupValueType {
|
||||
LVT_TAG = 0,
|
||||
LVT_NAME
|
||||
};
|
||||
|
||||
struct InputInfo {
|
||||
InputInfo() :
|
||||
type(AIT_NONE),
|
||||
tag(""),
|
||||
name(""),
|
||||
shortName(""),
|
||||
flexType(FLEX_NONE),
|
||||
inverted(false)
|
||||
{}
|
||||
|
||||
AnalogInputType type;
|
||||
std::string tag;
|
||||
std::string name;
|
||||
std::string label;
|
||||
std::string shortName;
|
||||
FlexType flexType;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
struct SwitchInfo {
|
||||
SwitchInfo() :
|
||||
type(SWITCH_NOT_AVAILABLE),
|
||||
tag(""),
|
||||
name(""),
|
||||
inverted(false)
|
||||
{}
|
||||
|
||||
SwitchType type;
|
||||
std::string tag;
|
||||
std::string name;
|
||||
bool inverted;
|
||||
};
|
||||
}
|
||||
|
||||
class Boards
|
||||
@@ -217,10 +291,8 @@ class Boards
|
||||
|
||||
public:
|
||||
|
||||
Boards(Board::Type board)
|
||||
{
|
||||
setBoardType(board);
|
||||
}
|
||||
Boards(Board::Type board);
|
||||
virtual ~Boards() {}
|
||||
|
||||
void setBoardType(const Board::Type & board);
|
||||
Board::Type getBoardType() const { return m_boardType; }
|
||||
@@ -228,43 +300,85 @@ class Boards
|
||||
const uint32_t getFourCC() const { return getFourCC(m_boardType); }
|
||||
const int getEEpromSize() const { return getEEpromSize(m_boardType); }
|
||||
const int getFlashSize() const { return getFlashSize(m_boardType); }
|
||||
const Board::SwitchInfo getSwitchInfo(int index) const { return getSwitchInfo(m_boardType, index); }
|
||||
const int getCapability(Board::Capability capability) const { return getCapability(m_boardType, capability); }
|
||||
const QString getAnalogInputName(int index) const { return getAnalogInputName(m_boardType, index); }
|
||||
const bool isBoardCompatible(Board::Type board2) const { return isBoardCompatible(m_boardType, board2); }
|
||||
|
||||
static uint32_t getFourCC(Board::Type board);
|
||||
static int getEEpromSize(Board::Type board);
|
||||
static int getFlashSize(Board::Type board);
|
||||
static Board::SwitchInfo getSwitchInfo(Board::Type board, int index);
|
||||
static StringTagMappingTable getSwitchesLookupTable(Board::Type board);
|
||||
static int getCapability(Board::Type board, Board::Capability capability);
|
||||
static QString getAxisName(int index);
|
||||
static StringTagMappingTable getAnalogNamesLookupTable(Board::Type board, const QString strVersion = "0.0.0");
|
||||
static QString getAnalogInputName(Board::Type board, int index);
|
||||
static bool isBoardCompatible(Board::Type board1, Board::Type board2);
|
||||
static QString getBoardName(Board::Type board);
|
||||
static QString potTypeToString(int value);
|
||||
static QString sliderTypeToString(int value);
|
||||
static QString switchTypeToString(int value);
|
||||
static AbstractStaticItemModel * potTypeItemModel();
|
||||
static AbstractStaticItemModel * sliderTypeItemModel();
|
||||
static AbstractStaticItemModel * switchTypeItemModel();
|
||||
static AbstractStaticItemModel * intModuleTypeItemModel();
|
||||
static StringTagMappingTable getTrimSwitchesLookupTable(Board::Type board);
|
||||
static StringTagMappingTable getTrimSourcesLookupTable(Board::Type board);
|
||||
static QList<int> getSupportedInternalModules(Board::Type board);
|
||||
static int getDefaultInternalModules(Board::Type board);
|
||||
static int getDefaultExternalModuleSize(Board::Type board);
|
||||
static QString externalModuleSizeToString(int value);
|
||||
static AbstractStaticItemModel * externalModuleSizeItemModel();
|
||||
|
||||
// TODO replace when refactored to support json defns
|
||||
static int adcPotsBeforeSliders(Board::Type board, SemanticVersion version);
|
||||
static BoardJson* getBoardJson(Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
protected:
|
||||
static int getInputsCalibrated(Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
Board::Type m_boardType;
|
||||
static Board::InputInfo getInputInfo(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputIndex(QString val, Board::LookupValueType lvt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getInputName(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputPotIndex(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputSliderIndex(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getInputTag(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputTagOffset(QString tag, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputTypeOffset(Board::AnalogInputType type, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getInputYamlIndex(QString val, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getInputYamlName(int index, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
static Board::SwitchInfo getSwitchInfo(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getSwitchIndex(QString val, Board::LookupValueType lvt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getSwitchName(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getSwitchTag(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getSwitchTagNum(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static int getSwitchYamlIndex(QString val, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getSwitchYamlName(int index, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
static int getTrimYamlIndex(QString val, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static QString getTrimYamlName(int index, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
STRINGTAGMAPPINGFUNCS(legacyTrimSourcesLookupTable, LegacyTrimSource);
|
||||
STRINGTAGMAPPINGFUNCS(trimSwitchesLookupTable, TrimSwitch);
|
||||
STRINGTAGMAPPINGFUNCS(rawSwitchTypesLookupTable, RawSwitchType);
|
||||
STRINGTAGMAPPINGFUNCS(rawSourceSpecialTypesLookupTable, RawSourceSpecialType);
|
||||
STRINGTAGMAPPINGFUNCS(rawSourceCyclicLookupTable, RawSourceCyclic);
|
||||
|
||||
static bool isInputAvailable(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isInputCalibrated(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isInputConfigurable(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isInputIgnored(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isInputPot(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isInputStick(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
static bool isSwitchConfigurable(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isSwitchFlex(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
static bool isSwitchFunc(int index, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
static QString flexTypeToString(int value);
|
||||
static AbstractStaticItemModel * flexTypeItemModel();
|
||||
|
||||
static std::string getLegacyAnalogMappedInputTag(const char * legacytag, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
|
||||
private:
|
||||
|
||||
Board::Type m_boardType = Board::BOARD_UNKNOWN;
|
||||
BoardJson* m_boardJson = nullptr;
|
||||
|
||||
const StringTagMappingTable legacyTrimSourcesLookupTable;
|
||||
const StringTagMappingTable trimSwitchesLookupTable;
|
||||
const StringTagMappingTable rawSwitchTypesLookupTable;
|
||||
const StringTagMappingTable rawSourceSpecialTypesLookupTable;
|
||||
const StringTagMappingTable rawSourceCyclicLookupTable;
|
||||
|
||||
static StringTagMappingTable getLegacyAnalogsLookupTable(Board::Type board = Board::BOARD_UNKNOWN);
|
||||
};
|
||||
|
||||
// temporary aliases for transition period, use Boards class instead.
|
||||
|
||||
@@ -64,7 +64,7 @@ QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
|
||||
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return tr("Trainer Sticks");
|
||||
return tr("Trainer Axis");
|
||||
else if (func == FuncTrainerRUD)
|
||||
return tr("Trainer RUD");
|
||||
else if (func == FuncTrainerELE)
|
||||
|
||||
@@ -92,19 +92,11 @@ std::string DataHelpers::getStringTagMappingTag(const StringTagMappingTable& lut
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int DataHelpers::getStringTagMappingSeq(const StringTagMappingTable& lut, unsigned int index)
|
||||
std::string DataHelpers::getStringNameMappingTag(const StringTagMappingTable& lut, const char * name)
|
||||
{
|
||||
if (index < lut.size())
|
||||
return lut[index].seq;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string DataHelpers::getStringSeqMappingTag(const StringTagMappingTable& lut, unsigned int seq)
|
||||
{
|
||||
const auto it =
|
||||
auto it =
|
||||
find_if(lut.begin(), lut.end(), [=](const StringTagMapping& elmt) {
|
||||
if (elmt.seq == seq) return true;
|
||||
if (elmt.name == name) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -114,3 +106,34 @@ std::string DataHelpers::getStringSeqMappingTag(const StringTagMappingTable& lut
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string DataHelpers::getStringTagMappingName(const StringTagMappingTable& lut, const char * tag)
|
||||
{
|
||||
auto it =
|
||||
find_if(lut.begin(), lut.end(), [=](const StringTagMapping& elmt) {
|
||||
if (elmt.tag == tag) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (it != lut.end()) {
|
||||
return it->name;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
QString DataHelpers::getCompositeName(const QString defaultName, const QString customName, const bool prefixCustom)
|
||||
{
|
||||
QString result;
|
||||
|
||||
if (customName.trimmed().isEmpty() || prefixCustom)
|
||||
result = defaultName;
|
||||
|
||||
if (!customName.trimmed().isEmpty()) {
|
||||
if (prefixCustom)
|
||||
result.append(":");
|
||||
result.append(customName.trimmed());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -27,23 +27,22 @@
|
||||
struct StringTagMapping {
|
||||
std::string name;
|
||||
std::string tag;
|
||||
unsigned int seq;
|
||||
|
||||
StringTagMapping() = default;
|
||||
StringTagMapping(const char* name) :
|
||||
name(name), tag(name), seq(0)
|
||||
name(name), tag(name)
|
||||
{
|
||||
}
|
||||
StringTagMapping(const std::string& name) :
|
||||
name(name), tag(name), seq(0)
|
||||
name(name), tag(name)
|
||||
{
|
||||
}
|
||||
StringTagMapping(const char* name, const char* tag, const unsigned int seq = 0) :
|
||||
name(name), tag(tag), seq(seq)
|
||||
StringTagMapping(const char* name, const char* tag) :
|
||||
name(name), tag(tag)
|
||||
{
|
||||
}
|
||||
StringTagMapping(const std::string& name, const std::string& tag, const unsigned int seq = 0) :
|
||||
name(name), tag(tag), seq(seq)
|
||||
StringTagMapping(const std::string& name, const std::string& tag) :
|
||||
name(name), tag(tag)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -59,33 +58,14 @@ typedef std::vector<StringTagMapping> StringTagMappingTable;
|
||||
inline std::string name##Tag (unsigned int index) \
|
||||
{ \
|
||||
return DataHelpers::getStringTagMappingTag(tbl, index); \
|
||||
}
|
||||
|
||||
#define STRINGTAGMAPPINGFUNCS_ADC_HELPER(tbl, tbladc, name) \
|
||||
STRINGTAGMAPPINGFUNCS_HELPER(tbl, name) \
|
||||
\
|
||||
inline int name##IndexADC (const char * tag) \
|
||||
{ \
|
||||
return DataHelpers::getStringTagMappingIndex(tbladc, tag); \
|
||||
} \
|
||||
\
|
||||
inline std::string name##TagADC (unsigned int index) \
|
||||
inline std::string name##Name (const char * tag) \
|
||||
{ \
|
||||
return DataHelpers::getStringTagMappingTag(tbladc, index); \
|
||||
} \
|
||||
\
|
||||
inline int name##SeqADC (unsigned int index) \
|
||||
{ \
|
||||
return DataHelpers::getStringTagMappingSeq(tbladc, index); \
|
||||
} \
|
||||
\
|
||||
inline std::string name##SeqTagADC (unsigned int seq) \
|
||||
{ \
|
||||
return DataHelpers::getStringSeqMappingTag(tbladc, seq); \
|
||||
return DataHelpers::getStringTagMappingName(tbl, tag); \
|
||||
}
|
||||
|
||||
#define STRINGTAGMAPPINGFUNCS(tbl, name) STRINGTAGMAPPINGFUNCS_HELPER(tbl, get##name)
|
||||
#define STRINGTAGMAPPINGFUNCS_ADC(tbl, tbladc, name) STRINGTAGMAPPINGFUNCS_ADC_HELPER(tbl, tbladc, get##name)
|
||||
|
||||
class FieldRange
|
||||
{
|
||||
@@ -132,6 +112,7 @@ namespace DataHelpers
|
||||
QString timeToString(const int value, const unsigned int mask);
|
||||
int getStringTagMappingIndex(const StringTagMappingTable& lut, const char * tag);
|
||||
std::string getStringTagMappingTag(const StringTagMappingTable& lut, unsigned int index);
|
||||
int getStringTagMappingSeq(const StringTagMappingTable& lut, unsigned int index);
|
||||
std::string getStringSeqMappingTag(const StringTagMappingTable& lut, unsigned int seq);
|
||||
std::string getStringNameMappingTag(const StringTagMappingTable& lut, const char * name);
|
||||
std::string getStringTagMappingName(const StringTagMappingTable& lut, const char * tag);
|
||||
QString getCompositeName(const QString defaultName, const QString customName, const bool prefixCustom);
|
||||
}
|
||||
|
||||
@@ -20,39 +20,39 @@
|
||||
|
||||
#include "yaml_calibdata.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "boardjson.h"
|
||||
|
||||
YamlCalibData::YamlCalibData()
|
||||
{
|
||||
memset(calib, 0, sizeof(calib));
|
||||
}
|
||||
|
||||
YamlCalibData::YamlCalibData(const int* calibMid, const int* calibSpanNeg,
|
||||
const int* calibSpanPos)
|
||||
YamlCalibData::YamlCalibData(const GeneralSettings::InputConfig* rhs)
|
||||
{
|
||||
for (int i = 0; i < CPN_MAX_ANALOGS; i++) {
|
||||
int seq = getCurrentFirmware()->getAnalogInputSeqADC(i);
|
||||
if (seq >= 0 && seq < CPN_MAX_ANALOGS) {
|
||||
calib[seq].mid = calibMid[i];
|
||||
calib[seq].spanNeg = calibSpanNeg[i];
|
||||
calib[seq].spanPos = calibSpanPos[i];
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
calib[i].mid = rhs[i].calib.mid;
|
||||
calib[i].spanNeg = rhs[i].calib.spanNeg;
|
||||
calib[i].spanPos = rhs[i].calib.spanPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YamlCalibData::copy(int* calibMid, int* calibSpanNeg,
|
||||
int* calibSpanPos) const
|
||||
void YamlCalibData::copy(GeneralSettings::InputConfig* rhs) const
|
||||
{
|
||||
for (int i = 0; i < CPN_MAX_ANALOGS; i++) {
|
||||
calibMid[i] = calib[i].mid;
|
||||
calibSpanNeg[i] = calib[i].spanNeg;
|
||||
calibSpanPos[i] = calib[i].spanPos;
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
rhs[i].calib.mid = calib[i].mid;
|
||||
rhs[i].calib.spanNeg = calib[i].spanNeg;
|
||||
rhs[i].calib.spanPos = calib[i].spanPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
||||
Node convert<CalibData>::encode(const CalibData& rhs)
|
||||
Node convert<GeneralSettings::InputCalib>::encode(const GeneralSettings::InputCalib& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["mid"] = rhs.mid;
|
||||
@@ -61,7 +61,7 @@ Node convert<CalibData>::encode(const CalibData& rhs)
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<CalibData>::decode(const Node& node, CalibData& rhs)
|
||||
bool convert<GeneralSettings::InputCalib>::decode(const Node& node, GeneralSettings::InputCalib& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
node["mid"] >> rhs.mid;
|
||||
@@ -73,22 +73,15 @@ bool convert<CalibData>::decode(const Node& node, CalibData& rhs)
|
||||
Node convert<YamlCalibData>::encode(const YamlCalibData& rhs)
|
||||
{
|
||||
Node node;
|
||||
auto fw = getCurrentFirmware();
|
||||
auto board = fw->getBoard();
|
||||
const auto* calibIdxLut = fw->getAnalogIndexNamesLookupTableADC();
|
||||
const int calibs = Boards::getCapability(board, Board::Sticks) +
|
||||
Boards::getCapability(board, Board::Pots) +
|
||||
Boards::getCapability(board, Board::Sliders);
|
||||
for (int i = 0; i < calibs; i++) {
|
||||
for (int j = 0; j < (int)calibIdxLut->size(); j++) {
|
||||
int seq = getCurrentFirmware()->getAnalogInputSeqADC(j);
|
||||
if (seq == i) {
|
||||
std::string tag = getCurrentFirmware()->getAnalogInputTagADC(j);
|
||||
node[tag] = rhs.calib[seq];
|
||||
break;
|
||||
}
|
||||
const int analogs = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
for (int i = 0; i < analogs; i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
std::string tag = Boards::getInputYamlName(i, BoardJson::YLT_CONFIG).toStdString();
|
||||
node[tag] = rhs.calib[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -99,16 +92,16 @@ bool convert<YamlCalibData>::decode(const Node& node, YamlCalibData& rhs)
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
int idx = 0;
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION)))
|
||||
idx = getCurrentFirmware()->getAnalogInputIndex(tag.c_str());
|
||||
else
|
||||
idx = getCurrentFirmware()->getAnalogInputIndexADC(tag.c_str());
|
||||
tag = Boards::getLegacyAnalogMappedInputTag(tag.c_str());
|
||||
|
||||
int idx = Boards::getInputYamlIndex(tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
|
||||
if (idx >= 0)
|
||||
kv.second >> rhs.calib[idx];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,26 +21,20 @@
|
||||
#include "yaml_ops.h"
|
||||
#include "generalsettings.h"
|
||||
|
||||
struct CalibData {
|
||||
int16_t mid;
|
||||
int16_t spanNeg;
|
||||
int16_t spanPos;
|
||||
};
|
||||
|
||||
struct YamlCalibData {
|
||||
CalibData calib[CPN_MAX_ANALOGS];
|
||||
GeneralSettings::InputCalib calib[CPN_MAX_ANALOGS];
|
||||
|
||||
YamlCalibData();
|
||||
YamlCalibData(const int* calibMid, const int* calibSpanNeg, const int* calibSpanPos);
|
||||
void copy(int* calibMid, int* calibSpanNeg, int* calibSpanPos) const;
|
||||
YamlCalibData(const GeneralSettings::InputConfig* rhs);
|
||||
void copy(GeneralSettings::InputConfig* rhs) const;
|
||||
};
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <>
|
||||
struct convert<CalibData> {
|
||||
static Node encode(const CalibData& rhs);
|
||||
static bool decode(const Node& node, CalibData& rhs);
|
||||
struct convert<GeneralSettings::InputCalib> {
|
||||
static Node encode(const GeneralSettings::InputCalib& rhs);
|
||||
static bool decode(const Node& node, GeneralSettings::InputCalib& rhs);
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -321,6 +321,11 @@ bool convert<CustomFunctionData>::decode(const Node& node,
|
||||
case FuncBacklight: {
|
||||
std::string src_str;
|
||||
getline(def, src_str, ',');
|
||||
if (def_str.size() >= 4 && def_str.substr(0, 4) == "lua(") {
|
||||
std::string tmp_str;
|
||||
getline(def, tmp_str, ',');
|
||||
src_str += ("," + tmp_str);
|
||||
}
|
||||
rhs.param = YamlRawSourceDecode(src_str).toValue();
|
||||
} break;
|
||||
case FuncAdjustGV1: {
|
||||
|
||||
@@ -43,7 +43,7 @@ enum BacklightMode {
|
||||
e_backlight_mode_off = 0,
|
||||
e_backlight_mode_keys = 1,
|
||||
e_backlight_mode_sticks = 2,
|
||||
e_backlight_mode_all = e_backlight_mode_keys+e_backlight_mode_sticks,
|
||||
e_backlight_mode_all = e_backlight_mode_keys + e_backlight_mode_sticks,
|
||||
e_backlight_mode_on
|
||||
};
|
||||
|
||||
@@ -165,7 +165,7 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
|
||||
std::string strboard = fw->getFlavour().toStdString();
|
||||
node["board"] = strboard;
|
||||
|
||||
YamlCalibData calib(rhs.calibMid, rhs.calibSpanNeg, rhs.calibSpanPos);
|
||||
YamlCalibData calib(rhs.inputConfig);
|
||||
node["calib"] = calib;
|
||||
|
||||
node["currModel"] = rhs.currModelIndex;
|
||||
@@ -263,49 +263,27 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
|
||||
}
|
||||
|
||||
Node sticksConfig;
|
||||
sticksConfig = YamlStickConfig(rhs.stickName);
|
||||
sticksConfig = YamlStickConfig(rhs.inputConfig);
|
||||
if (sticksConfig && sticksConfig.IsMap()) {
|
||||
node["sticksConfig"] = sticksConfig;
|
||||
}
|
||||
|
||||
Node potsConfig;
|
||||
potsConfig = YamlPotConfig(rhs.inputConfig);
|
||||
if (potsConfig && potsConfig.IsMap()) {
|
||||
node["potsConfig"] = potsConfig;
|
||||
}
|
||||
|
||||
Node switchConfig;
|
||||
switchConfig = YamlSwitchConfig(rhs.switchName, rhs.switchConfig);
|
||||
switchConfig = YamlSwitchConfig(rhs.switchConfig);
|
||||
if (switchConfig && switchConfig.IsMap()) {
|
||||
node["switchConfig"] = switchConfig;
|
||||
}
|
||||
|
||||
// TODO revisit when Companion refactored for adc
|
||||
// adc encoding requires pots and sliders to be merged in a prescribed sequence as defined in radio json
|
||||
int maxPots = CPN_MAX_POTS + CPN_MAX_SLIDERS;
|
||||
char potName[maxPots][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int potConfig[maxPots];
|
||||
|
||||
const int sticks = Boards::getCapability(board, Board::Sticks);
|
||||
int adcoffset = sticks;
|
||||
int seq = 0;
|
||||
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Pots); i++) {
|
||||
seq = getCurrentFirmware()->getAnalogInputSeqADC(adcoffset + i) - sticks;
|
||||
if (seq >= 0 && seq < maxPots) {
|
||||
strcpy(potName[seq], rhs.potName[i]);
|
||||
potConfig[seq] = rhs.potConfig[i];
|
||||
}
|
||||
}
|
||||
|
||||
adcoffset += Boards::getCapability(board, Board::Pots);
|
||||
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Sliders); i++) {
|
||||
seq = getCurrentFirmware()->getAnalogInputSeqADC(adcoffset + i) - sticks;
|
||||
if (seq >= 0 && seq < maxPots) {
|
||||
strcpy(potName[seq], rhs.sliderName[i]);
|
||||
potConfig[seq] = ((rhs.sliderConfig[i] == Board::SLIDER_WITH_DETENT) ? Board::POT_SLIDER_WITH_DETENT : Board::POT_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
Node potsConfig;
|
||||
potsConfig = YamlPotConfig(potName, potConfig);
|
||||
if (potsConfig && potsConfig.IsMap()) {
|
||||
node["potsConfig"] = potsConfig;
|
||||
Node flexSwitches;
|
||||
flexSwitches = YamlSwitchesFlex(rhs.switchConfig);
|
||||
if (flexSwitches && flexSwitches.IsMap()) {
|
||||
node["flexSwitches"] = flexSwitches;
|
||||
}
|
||||
|
||||
node["ownerRegistrationID"] = rhs.registrationId;
|
||||
@@ -323,6 +301,7 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
|
||||
// Radio level tabs control (global settings)
|
||||
if (hasColorLcd)
|
||||
node["radioThemesDisabled"] = (int)rhs.radioThemesDisabled;
|
||||
|
||||
node["radioGFDisabled"] = (int)rhs.radioGFDisabled;
|
||||
node["radioTrainerDisabled"] = (int)rhs.radioTrainerDisabled;
|
||||
// Model level tabs control (global setting)
|
||||
@@ -389,7 +368,6 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
node["board"] >> flavour;
|
||||
|
||||
auto fw = getCurrentFirmware();
|
||||
auto board = fw->getBoard();
|
||||
|
||||
qDebug() << "Settings version:" << rhs.semver << "File flavour:" << flavour.c_str() << "Firmware flavour:" << fw->getFlavour();
|
||||
|
||||
@@ -419,7 +397,7 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
|
||||
YamlCalibData calib;
|
||||
node["calib"] >> calib;
|
||||
calib.copy(rhs.calibMid, rhs.calibSpanNeg, rhs.calibSpanPos);
|
||||
calib.copy(rhs.inputConfig);
|
||||
|
||||
node["currModel"] >> rhs.currModelIndex;
|
||||
node["currModelFilename"] >> rhs.currModelFilename;
|
||||
@@ -547,39 +525,29 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
|
||||
YamlStickConfig stickConfig;
|
||||
node["sticksConfig"] >> stickConfig;
|
||||
stickConfig.copy(rhs.stickName);
|
||||
|
||||
YamlSwitchConfig switchConfig;
|
||||
node["switchConfig"] >> switchConfig;
|
||||
switchConfig.copy(rhs.switchName, rhs.switchConfig);
|
||||
|
||||
// TODO: revisit when Companion refactored to support adc
|
||||
// adc pots and sliders decoded into a single array but Compapanion has separate arrays
|
||||
int maxPots = CPN_MAX_POTS + CPN_MAX_SLIDERS; // must match YamlPotConfig declaration
|
||||
char potName[maxPots][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int potConfig[maxPots];
|
||||
stickConfig.copy(rhs.inputConfig);
|
||||
|
||||
YamlPotConfig potsConfig;
|
||||
node["potsConfig"] >> potsConfig;
|
||||
potsConfig.copy(potName, potConfig);
|
||||
potsConfig.copy(rhs.inputConfig);
|
||||
|
||||
int numPots = Boards::getCapability(board, Board::Pots);
|
||||
|
||||
for (int i = 0; i < numPots; i++) {
|
||||
strcpy(rhs.potName[i], potName[i]);
|
||||
rhs.potConfig[i] = potConfig[i];
|
||||
}
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
// for parsing pre v2.10 config - this is not encoded
|
||||
if (node["slidersConfig"]) {
|
||||
YamlSliderConfig slidersConfig;
|
||||
node["slidersConfig"] >> slidersConfig;
|
||||
slidersConfig.copy(rhs.sliderName, rhs.sliderConfig);
|
||||
slidersConfig.copy(rhs.inputConfig);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Sliders); i++) {
|
||||
strcpy(rhs.sliderName[i], potName[numPots + i]);
|
||||
rhs.sliderConfig[i] = ((potConfig[numPots + i] == Board::POT_SLIDER_WITH_DETENT) ? Board::SLIDER_WITH_DETENT : Board::SLIDER_NONE);
|
||||
}
|
||||
|
||||
YamlSwitchConfig switchConfig;
|
||||
node["switchConfig"] >> switchConfig;
|
||||
switchConfig.copy(rhs.switchConfig);
|
||||
|
||||
// MUST be parsed after switchConfig
|
||||
if (node["flexSwitches"]) {
|
||||
YamlSwitchesFlex flexSwitches;
|
||||
node["flexSwitches"] >> flexSwitches;
|
||||
// merge
|
||||
flexSwitches.copy(rhs.switchConfig);
|
||||
}
|
||||
|
||||
node["ownerRegistrationID"] >> rhs.registrationId;
|
||||
@@ -612,6 +580,9 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
node["modelCustomScriptsDisabled"] >> rhs.modelCustomScriptsDisabled;
|
||||
node["modelTelemetryDisabled"] >> rhs.modelTelemetryDisabled;
|
||||
|
||||
// fix ups
|
||||
rhs.validateFlexSwitches();
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace YAML
|
||||
|
||||
@@ -116,7 +116,7 @@ Node convert<LogicalSwitchData>::encode(const LogicalSwitchData& rhs)
|
||||
node["delay"] = rhs.delay;
|
||||
node["duration"] = rhs.duration;
|
||||
node["andsw"] = YamlRawSwitchEncode(RawSwitch(rhs.andsw));
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,11 @@ bool convert<LogicalSwitchData>::decode(const Node& node,
|
||||
case LS_FAMILY_VCOMP: {
|
||||
std::string src_str;
|
||||
getline(def, src_str, ',');
|
||||
if (def_str.size() >= 4 && def_str.substr(0, 4) == "lua(") {
|
||||
std::string tmp_str;
|
||||
getline(def, tmp_str, ',');
|
||||
src_str += ("," + tmp_str);
|
||||
}
|
||||
rhs.val1 = YamlRawSourceDecode(src_str).toValue();
|
||||
getline(def, src_str);
|
||||
rhs.val2 = YamlRawSourceDecode(src_str).toValue();
|
||||
@@ -178,6 +183,11 @@ bool convert<LogicalSwitchData>::decode(const Node& node,
|
||||
default: {
|
||||
std::string src_str;
|
||||
getline(def, src_str, ',');
|
||||
if (def_str.size() >= 4 && def_str.substr(0, 4) == "lua(") {
|
||||
std::string tmp_str;
|
||||
getline(def, tmp_str, ',');
|
||||
src_str += ("," + tmp_str);
|
||||
}
|
||||
rhs.val1 = YamlRawSourceDecode(src_str).toValue();
|
||||
def >> rhs.val2;
|
||||
} break;
|
||||
|
||||
@@ -155,40 +155,12 @@ struct YamlThrTrace {
|
||||
}
|
||||
};
|
||||
|
||||
// EdgeTX 2.10.0 ADC refactor changed order of pots and sliders that affected interpretation of model warnings
|
||||
// This conversion needs to be revisited when Companion is refactored to use ADC radio defns
|
||||
// Make ADC orders backwards compatible
|
||||
|
||||
// the values below are based on radio\src\util\hw_defns\pots_config.py
|
||||
|
||||
int adcPotsBeforeSliders()
|
||||
{
|
||||
auto board = getCurrentBoard();
|
||||
|
||||
if (version >= SemanticVersion("2.10.0")) {
|
||||
if (IS_TARANIS_X9(board) || IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board) || IS_RADIOMASTER_BOXER(board))
|
||||
return 3;
|
||||
else if (IS_TARANIS_X9LITE(board))
|
||||
return 1;
|
||||
else if (IS_JUMPER_TLITE(board) || IS_BETAFPV_LR3PRO(board) || IS_IFLIGHT_COMMANDO8(board))
|
||||
return 0;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
return Boards::getCapability(board, Board::Pots);
|
||||
}
|
||||
}
|
||||
|
||||
struct YamlPotsWarnEnabled {
|
||||
unsigned int value;
|
||||
|
||||
const Board::Type board = getCurrentBoard();
|
||||
const int maxradio = 8 * (int)(Boards::getCapability(board, Board::HasColorLcd) ? sizeof(uint16_t) : sizeof(uint8_t));
|
||||
const int maxcpn = CPN_MAX_POTS + CPN_MAX_SLIDERS;
|
||||
const int slidersStart = Boards::adcPotsBeforeSliders(board, modelSettingsVersion);
|
||||
const int numpots = Boards::getCapability(board, Board::Pots);
|
||||
const int offset = numpots - slidersStart;
|
||||
const int maxcpn = Boards::getCapability(board, Board::FlexInputs);
|
||||
|
||||
YamlPotsWarnEnabled() = default;
|
||||
|
||||
@@ -196,37 +168,17 @@ struct YamlPotsWarnEnabled {
|
||||
{
|
||||
value = 0;
|
||||
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < maxcpn; i++) {
|
||||
if (i < slidersStart)
|
||||
idx = i;
|
||||
else if (i >= numpots)
|
||||
idx = i - offset;
|
||||
else
|
||||
continue;
|
||||
if (idx >= 0 && idx < maxradio) {
|
||||
value |= (*(potsWarnEnabled + i)) << idx;
|
||||
//qDebug() << "i:" << i << "idx:" << idx << "value:" << *(potsWarnEnabled + i);
|
||||
}
|
||||
for (int i = 0; i < maxcpn && i < maxradio; i++) {
|
||||
value |= (*(potsWarnEnabled + i)) << i;
|
||||
}
|
||||
}
|
||||
|
||||
void toCpn(bool * potsWarnEnabled)
|
||||
{
|
||||
memset(potsWarnEnabled, 0, sizeof(bool) * maxcpn);
|
||||
memset(potsWarnEnabled, 0, sizeof(bool) * CPN_MAX_INPUTS);
|
||||
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < maxradio; i++) {
|
||||
if (i >= slidersStart)
|
||||
idx = i + offset;
|
||||
else
|
||||
idx = i;
|
||||
if (idx >= 0 && idx <= maxcpn) {
|
||||
*(potsWarnEnabled + idx) = (bool)((value >> i) & 1);
|
||||
//qDebug() << "i:" << i << "idx:" << idx << "value:" << (bool)((value >> i) & 1);
|
||||
}
|
||||
for (int i = 0; i < maxradio && i < maxcpn; i++) {
|
||||
*(potsWarnEnabled + i) = (bool)((value >> i) & 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -234,48 +186,26 @@ struct YamlPotsWarnEnabled {
|
||||
struct YamlBeepANACenter {
|
||||
unsigned int value;
|
||||
|
||||
const Board::Type board = getCurrentBoard();
|
||||
const int maxradio = 8 * (int)sizeof(uint16_t);
|
||||
const int numstickspots = CPN_MAX_STICKS + Boards::getCapability(board, Board::Pots);
|
||||
const int maxcpn = numstickspots + getBoardCapability(board, Board::Sliders);
|
||||
const int slidersStart = CPN_MAX_STICKS + Boards::adcPotsBeforeSliders(board, modelSettingsVersion);
|
||||
const int offset = numstickspots - slidersStart;
|
||||
const int maxcpn = 8 * (int)sizeof(unsigned int);
|
||||
|
||||
YamlBeepANACenter() = default;
|
||||
|
||||
YamlBeepANACenter(unsigned int beepANACenter)
|
||||
{
|
||||
value = 0;
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < maxcpn; i++) {
|
||||
if (i < slidersStart)
|
||||
idx = i;
|
||||
else if (i >= numstickspots)
|
||||
idx = i - offset;
|
||||
else
|
||||
continue;
|
||||
if (idx >= 0 && idx < maxradio) {
|
||||
Helpers::setBitmappedValue(value, Helpers::getBitmappedValue(beepANACenter, i), idx);
|
||||
//qDebug() << "i:" << i << "bit:" << Helpers::getBitmappedValue(beepANACenter, i) << "idx:" << idx << "value:" << value;
|
||||
}
|
||||
for (int i = 0; i < maxcpn && i < maxradio; i++) {
|
||||
Helpers::setBitmappedValue(value, Helpers::getBitmappedValue(beepANACenter, i), i);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int toCpn()
|
||||
{
|
||||
unsigned int beepANACenter = 0;
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < maxradio; i++) {
|
||||
if (i >= slidersStart)
|
||||
idx = i + offset;
|
||||
else
|
||||
idx = i;
|
||||
if (idx >= 0 && idx < maxcpn) {
|
||||
Helpers::setBitmappedValue(beepANACenter, Helpers::getBitmappedValue(value, i), idx);
|
||||
//qDebug() << "i:" << i << "bit:" << Helpers::getBitmappedValue(value, i) << "idx:" << idx << "beepANACenter:" << beepANACenter;
|
||||
}
|
||||
for (int i = 0; i < maxradio && i < maxcpn; i++) {
|
||||
Helpers::setBitmappedValue(beepANACenter, Helpers::getBitmappedValue(value, i), i);
|
||||
}
|
||||
|
||||
return beepANACenter;
|
||||
@@ -303,7 +233,7 @@ struct YamlSwitchWarningState {
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
|
||||
//TODO: exclude 2-pos toggle from switch warnings
|
||||
if (enabled & (1 << i)) {
|
||||
std::string tag = getCurrentFirmware()->getSwitchesTag(i);
|
||||
std::string tag = Boards::getSwitchTag(i).toStdString();
|
||||
const char *sw = tag.data();
|
||||
|
||||
if (tag.size() >= 2 && sw[0] == 'S') {
|
||||
@@ -341,7 +271,7 @@ struct YamlSwitchWarningState {
|
||||
}
|
||||
|
||||
std::string sw = std::string("S") + (char)c;
|
||||
int index = getCurrentFirmware()->getSwitchesIndex(sw.c_str());
|
||||
int index = Boards::getSwitchIndex(sw.c_str(), Board::LVT_NAME);
|
||||
if (index < 0) {
|
||||
ss.ignore();
|
||||
continue;
|
||||
@@ -1009,11 +939,11 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
|
||||
node["thrTrimSw"] = rhs.thrTrimSwitch;
|
||||
node["potsWarnMode"] = potsWarningModeLut << rhs.potsWarningMode;
|
||||
node["jitterFilter"] = globalOnOffFilterLut << rhs.jitterFilter;
|
||||
|
||||
YamlPotsWarnEnabled potsWarnEnabled(&rhs.potsWarnEnabled[0]);
|
||||
node["potsWarnEnabled"] = potsWarnEnabled.value;
|
||||
|
||||
node["jitterFilter"] = globalOnOffFilterLut << rhs.jitterFilter;
|
||||
|
||||
for (int i = 0; i < CPN_MAX_POTS + CPN_MAX_SLIDERS; i++) {
|
||||
if (rhs.potsWarnPosition[i] != 0)
|
||||
node["potsWarnPosition"][std::to_string(i)]["val"] = rhs.potsWarnPosition[i];
|
||||
@@ -1123,7 +1053,7 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
node["functionSwitchStartConfig"] = rhs.functionSwitchStartConfig;
|
||||
node["functionSwitchLogicalState"] = rhs.functionSwitchLogicalState;
|
||||
|
||||
for (int i = 0; i < CPN_MAX_FUNCTION_SWITCHES; i++) {
|
||||
for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i++) {
|
||||
if (strlen(rhs.functionSwitchNames[i]) > 0) {
|
||||
node["switchNames"][std::to_string(i)]["val"] = rhs.functionSwitchNames[i];
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "yaml_rawsource.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "boardjson.h"
|
||||
|
||||
static const YamlLookupTable spacemouseLut = {
|
||||
{ 0, "SPACEMOUSE_A" },
|
||||
@@ -33,6 +34,8 @@ static const YamlLookupTable spacemouseLut = {
|
||||
|
||||
std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
Boards b = Boards(board);
|
||||
std::string src_str;
|
||||
char c = 'A';
|
||||
switch (rhs.type) {
|
||||
@@ -47,10 +50,10 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
src_str += ")";
|
||||
break;
|
||||
case SOURCE_TYPE_STICK:
|
||||
src_str = getCurrentFirmware()->getAnalogInputTag(rhs.index);
|
||||
src_str = Boards::getInputYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
|
||||
break;
|
||||
case SOURCE_TYPE_TRIM:
|
||||
src_str = getCurrentFirmware()->getTrimSourcesTag(rhs.index);
|
||||
src_str = Boards::getTrimYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
|
||||
break;
|
||||
case SOURCE_TYPE_MIN:
|
||||
src_str += "MIN";
|
||||
@@ -59,21 +62,15 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
src_str += "MAX";
|
||||
break;
|
||||
case SOURCE_TYPE_SWITCH:
|
||||
src_str += getCurrentFirmware()->getSwitchesTag(rhs.index);
|
||||
src_str += Boards::getSwitchYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
|
||||
break;
|
||||
case SOURCE_TYPE_CUSTOM_SWITCH:
|
||||
src_str += "ls(";
|
||||
src_str += std::to_string(rhs.index + 1);
|
||||
src_str += ")";
|
||||
break;
|
||||
case SOURCE_TYPE_FUNCTIONSWITCH:
|
||||
if (Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
src_str += "SW";
|
||||
src_str += std::to_string(rhs.index + 1);
|
||||
}
|
||||
break;
|
||||
case SOURCE_TYPE_CYC:
|
||||
src_str = getCurrentFirmware()->getRawSourceCyclicTag(rhs.index);
|
||||
src_str = b.getRawSourceCyclicTag(rhs.index);
|
||||
break;
|
||||
case SOURCE_TYPE_PPM:
|
||||
src_str += "tr(";
|
||||
@@ -91,7 +88,7 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
src_str += ")";
|
||||
break;
|
||||
case SOURCE_TYPE_SPECIAL:
|
||||
src_str = getCurrentFirmware()->getRawSourceSpecialTypesTag(rhs.index);
|
||||
src_str = b.getRawSourceSpecialTypeTag(rhs.index);
|
||||
break;
|
||||
case SOURCE_TYPE_TELEMETRY:
|
||||
src_str = "tele(";
|
||||
@@ -122,6 +119,8 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
|
||||
RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
Boards b = Boards(board);
|
||||
RawSource rhs;
|
||||
const char* val = src_str.data();
|
||||
size_t val_len = src_str.size();
|
||||
@@ -133,32 +132,19 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
if (idx < CPN_MAX_INPUTS) {
|
||||
rhs = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, idx);
|
||||
}
|
||||
} else if (val_len == 2
|
||||
&& val[0] == 'S'
|
||||
&& val[1] >= 'A'
|
||||
&& val[1] <= 'Z') {
|
||||
|
||||
int idx = getCurrentFirmware()->getSwitchesIndex(src_str.c_str());
|
||||
if (idx >= 0 && idx < CPN_MAX_SWITCHES) {
|
||||
} else if ((val_len == 2 &&
|
||||
val[0] == 'S' &&
|
||||
val[1] >= 'A' && val[1] <= 'Z') ||
|
||||
(val_len == 3 && (
|
||||
(val[0] == 'F' && val[1] == 'L') ||
|
||||
(val[0] == 'S' && val[1] == 'W')) &&
|
||||
val[2] >= '1' && val[2] <= '9')) {
|
||||
|
||||
int idx = Boards::getSwitchYamlIndex(src_str.c_str(), BoardJson::YLT_REF);
|
||||
if (idx >= 0) {
|
||||
rhs = RawSource(SOURCE_TYPE_SWITCH, idx);
|
||||
|
||||
} else if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
int numSw = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
idx = val[1] - 'A';
|
||||
idx -= numSw;
|
||||
|
||||
if(idx >= 0 and idx < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, idx);
|
||||
}
|
||||
}
|
||||
} else if (val_len == 3
|
||||
&& val[0] == 'S'
|
||||
&& val[1] == 'W'
|
||||
&& (val[2] >= '1' && val[2] <= '6')
|
||||
&& Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
// Customisable switches
|
||||
int idx = val[2] - '1';
|
||||
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, idx);
|
||||
|
||||
} else if (val_len > 4 &&
|
||||
val[0] == 'l' &&
|
||||
@@ -185,6 +171,7 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
if (ls > 0 && ls <= CPN_MAX_LOGICAL_SWITCHES)
|
||||
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls - 1);
|
||||
|
||||
// appears depreciated - maybe early support for T20 as SWn the current std and no match in encode
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 'f' &&
|
||||
val[1] == 's' &&
|
||||
@@ -193,8 +180,11 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
std::stringstream src(src_str.substr(3));
|
||||
int fs = 0;
|
||||
src >> fs;
|
||||
if (fs > 0 && fs <= CPN_MAX_FUNCTION_SWITCHES)
|
||||
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, fs - 1);
|
||||
if (fs > 0) {
|
||||
int fsidx = Boards::getSwitchYamlIndex(QString("SW%1").arg(fs), BoardJson::YLT_REF);
|
||||
if (fsidx >= 0)
|
||||
rhs = RawSource(SOURCE_TYPE_SWITCH, fsidx);
|
||||
}
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 't' &&
|
||||
@@ -257,58 +247,73 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
} else {
|
||||
|
||||
YAML::Node node(src_str);
|
||||
|
||||
if (node.IsScalar() && node.as<std::string>() == "MAX") {
|
||||
rhs.type = SOURCE_TYPE_MAX;
|
||||
rhs.index = 0;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
if (node.IsScalar() && node.as<std::string>() == "MIN") {
|
||||
rhs.type = SOURCE_TYPE_MIN;
|
||||
rhs.index = 0;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
std::string ana_str;
|
||||
node >> ana_str;
|
||||
|
||||
// 2.8 conversion of GYRO1 and GYRO2 to TILT_X and TILT_Y respectively
|
||||
if (ana_str.size() == 5) {
|
||||
if (ana_str.substr(0, 5) == "GYRO1") {
|
||||
ana_str = "TILT_X";
|
||||
} else if (ana_str.substr(0, 5) == "GYRO2") {
|
||||
ana_str = "TILT_Y";
|
||||
}
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
ana_str = Boards::getLegacyAnalogMappedInputTag(ana_str.c_str());
|
||||
int idx = Boards::getInputIndex(ana_str.c_str(), Board::LVT_TAG);
|
||||
if (idx >= 0 && Boards::isInputStick(idx))
|
||||
ana_str = Boards::getInputName(idx).toStdString();
|
||||
}
|
||||
|
||||
int ana_idx = getCurrentFirmware()->getAnalogInputIndex(ana_str.c_str());
|
||||
if (ana_idx < 0)
|
||||
ana_idx = getCurrentFirmware()->getAnalogInputIndexADC(ana_str.c_str());
|
||||
int ana_idx = Boards::getInputYamlIndex(ana_str.c_str(), BoardJson::YLT_REF);
|
||||
if (ana_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_STICK;
|
||||
rhs.index = ana_idx;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
int trm_idx = getCurrentFirmware()->getTrimSourcesIndex(src_str.c_str());
|
||||
std::string trim_str;
|
||||
node >> trim_str;
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
int idx = b.getLegacyTrimSourceIndex(src_str.c_str());
|
||||
if (idx >= 0)
|
||||
trim_str = Boards::getTrimYamlName(idx, BoardJson::YLT_REF).toStdString();
|
||||
}
|
||||
|
||||
int trm_idx = Boards::getTrimYamlIndex(trim_str.c_str(), BoardJson::YLT_REF);
|
||||
if (trm_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_TRIM;
|
||||
rhs.index = trm_idx;
|
||||
}
|
||||
|
||||
int cyc_idx = getCurrentFirmware()->getRawSourceCyclicIndex(src_str.c_str());
|
||||
if (cyc_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_CYC;
|
||||
rhs.index = cyc_idx;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
std::string special_str;
|
||||
node >> special_str;
|
||||
|
||||
// 2.10 conversion of TIMERx to Tmrx
|
||||
if (special_str.size() == 6) {
|
||||
if (special_str.substr(0, 6) == "TIMER1") {
|
||||
special_str = "Tmr1";
|
||||
}
|
||||
else if (special_str.substr(0, 6) == "TIMER2") {
|
||||
special_str = "Tmr2";
|
||||
}
|
||||
else if (special_str.substr(0, 6) == "TIMER3") {
|
||||
special_str = "Tmr3";
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
if (special_str.size() == 6 && special_str.substr(0, 5) == "TIMER") {
|
||||
special_str = "Tmr" + special_str.substr(5, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int sp_idx = getCurrentFirmware()->getRawSourceSpecialTypesIndex(special_str.c_str());
|
||||
int sp_idx = b.getRawSourceSpecialTypeIndex(special_str.c_str());
|
||||
if (sp_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_SPECIAL;
|
||||
rhs.index = sp_idx;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
int cyc_idx = b.getRawSourceCyclicIndex(src_str.c_str());
|
||||
if (cyc_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_CYC;
|
||||
rhs.index = cyc_idx;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
if (node.IsScalar() && node.as<std::string>().size() == 12 && node.as<std::string>().substr(0, 11) == "SPACEMOUSE_") {
|
||||
@@ -317,18 +322,9 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
if (sm_idx >= 0) {
|
||||
rhs.type = SOURCE_TYPE_SPACEMOUSE;
|
||||
rhs.index = sm_idx;
|
||||
return rhs;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.IsScalar() && node.as<std::string>() == "MIN") {
|
||||
rhs.type = SOURCE_TYPE_MIN;
|
||||
rhs.index = 0;
|
||||
}
|
||||
|
||||
if (node.IsScalar() && node.as<std::string>() == "MAX") {
|
||||
rhs.type = SOURCE_TYPE_MAX;
|
||||
rhs.index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rhs;
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
|
||||
#include "yaml_rawswitch.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "boardjson.h"
|
||||
|
||||
std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
Boards b = Boards(board);
|
||||
std::string sw_str;
|
||||
int32_t sval = rhs.index;
|
||||
if (rhs.index < 0) {
|
||||
@@ -30,11 +33,11 @@ std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
sw_str += "!";
|
||||
}
|
||||
|
||||
int multiposcnt = Boards::getCapability(getCurrentBoard(), Board::MultiposPotsPositions);
|
||||
int multiposcnt = Boards::getCapability(board, Board::MultiposPotsPositions);
|
||||
|
||||
switch (rhs.type) {
|
||||
case SWITCH_TYPE_SWITCH:
|
||||
sw_str += getCurrentFirmware()->getSwitchesTag((sval - 1) / 3);
|
||||
sw_str += Boards::getSwitchYamlName((sval - 1) / 3, BoardJson::YLT_REF).toStdString();
|
||||
sw_str += std::to_string((sval - 1) % 3);
|
||||
break;
|
||||
|
||||
@@ -43,22 +46,14 @@ std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
sw_str += std::to_string(sval);
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_FUNCTIONSWITCH:
|
||||
if (Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
sw_str += "SW";
|
||||
sw_str += std::to_string(1 + ((sval - 1) / 3));
|
||||
sw_str += std::to_string((sval - 1) % 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_MULTIPOS_POT:
|
||||
sw_str += "6P";
|
||||
sw_str += std::to_string((sval - 1) / multiposcnt);
|
||||
sw_str += std::to_string((sval - 1) / multiposcnt - Boards::getCapability(board, Board::Sticks));
|
||||
sw_str += std::to_string((sval - 1) % multiposcnt);
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TRIM:
|
||||
sw_str += getCurrentFirmware()->getTrimSwitchesTag(sval - 1);
|
||||
sw_str += b.getTrimSwitchTag(sval - 1);
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
@@ -72,7 +67,7 @@ std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
break;
|
||||
|
||||
default:
|
||||
sw_str += getCurrentFirmware()->getRawSwitchTypesTag(rhs.type);
|
||||
sw_str += b.getRawSwitchTypeTag(rhs.type);
|
||||
break;
|
||||
}
|
||||
return sw_str;
|
||||
@@ -80,6 +75,8 @@ std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
|
||||
RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
Boards b = Boards(board);
|
||||
RawSwitch rhs; // constructor sets to SWITCH_TYPE_NONE
|
||||
const char* val = sw_str.data();
|
||||
size_t val_len = sw_str.size();
|
||||
@@ -99,7 +96,7 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
sw_str_tmp = sw_str_tmp.substr(1);
|
||||
}
|
||||
|
||||
int multiposcnt = Boards::getCapability(getCurrentBoard(), Board::MultiposPotsPositions);
|
||||
const int multiposcnt = Boards::getCapability(board, Board::MultiposPotsPositions);
|
||||
|
||||
// TODO: validate all expected numeric chars are numeric not just first
|
||||
|
||||
@@ -110,12 +107,33 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
rhs = RawSwitch(SWITCH_TYPE_VIRTUAL, sw_idx);
|
||||
}
|
||||
|
||||
// format 6Piip where ii = input index - number sticks and p = pos index 0-5
|
||||
} else if (val_len > 3 && val[0] == '6' && val[1] == 'P' &&
|
||||
(val[2] >= '0' && val[2] <= '9') &&
|
||||
(val[3] >= '0' && val[3] < (multiposcnt + '0'))) {
|
||||
(val[val_len - 1] >= '0' && val[val_len - 1] < (multiposcnt + '0'))) {
|
||||
|
||||
rhs = RawSwitch(SWITCH_TYPE_MULTIPOS_POT,
|
||||
(val[2] - '0') * multiposcnt + (val[3] - '0') + 1);
|
||||
RawSwitchType mp_type = SWITCH_TYPE_MULTIPOS_POT;
|
||||
int mp_index = 0;
|
||||
int mp_input_index = 0;
|
||||
|
||||
try {
|
||||
mp_input_index = std::stoi(sw_str_tmp.substr(2, val_len - 3));
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
|
||||
if (mp_input_index > 2)
|
||||
mp_input_index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
mp_index = (mp_input_index + Boards::getCapability(board, Board::Sticks)) * multiposcnt + (val[val_len - 1] - '0') + 1;
|
||||
|
||||
} catch(...) {
|
||||
mp_type = SWITCH_TYPE_NONE;
|
||||
mp_index = 0;
|
||||
}
|
||||
|
||||
rhs = RawSwitch(mp_type, mp_index);
|
||||
|
||||
} else if (val_len == 3 && val[0] == 'F' && val[1] == 'M' &&
|
||||
(val[2] >= '0' && val[2] <= '9')) {
|
||||
@@ -133,41 +151,29 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
|
||||
} else if (sw_str_tmp.substr(0, 4) == std::string("Trim")) {
|
||||
|
||||
int tsw_idx = getCurrentFirmware()->getTrimSwitchesIndex(sw_str_tmp.c_str());
|
||||
int tsw_idx = b.getTrimSwitchIndex(sw_str_tmp.c_str());
|
||||
if (tsw_idx >= 0) {
|
||||
rhs.type = SWITCH_TYPE_TRIM;
|
||||
rhs.index = tsw_idx + 1;
|
||||
}
|
||||
} else if (val_len >= 3 && val[0] == 'S' && val[1] == 'W' &&
|
||||
(val[2] >= '1' && val[2] <= '6') &&
|
||||
(val[3] >= '0' && val[3] <= '2') &&
|
||||
Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
// Customisable switches
|
||||
int idx = val[2] - '1';
|
||||
idx = idx * 3 + (val[3] - '0' + 1);
|
||||
rhs = RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, idx);
|
||||
} else if (val_len >= 3 && val[0] == 'S' &&
|
||||
(val[1] >= 'A' && val[1] <= 'Z') &&
|
||||
(val[2] >= '0' && val[2] <= '2')) {
|
||||
|
||||
int sw_idx = getCurrentFirmware()->getSwitchesIndex(sw_str_tmp.substr(0, 2).c_str());
|
||||
} else if ((val_len >= 4 && (
|
||||
(val[0] == 'F' && val[1] == 'L') ||
|
||||
(val[0] == 'S' && val[1] == 'W')) &&
|
||||
val[2] >= '1' && val[2] <= '9' &&
|
||||
val[val_len - 1] >= '0' && val[val_len - 1] <= '2') ||
|
||||
(val_len >= 3 && val[0] == 'S' &&
|
||||
val[1] >= 'A' && val[1] <= 'Z' &&
|
||||
val[2] >= '0' && val[2] <= '2')) {
|
||||
|
||||
int sw_idx = Boards::getSwitchYamlIndex(sw_str_tmp.substr(0, val_len - 1).c_str(), BoardJson::YLT_REF);
|
||||
if (sw_idx >= 0) {
|
||||
rhs.type = SWITCH_TYPE_SWITCH;
|
||||
rhs.index = sw_idx * 3 + (val[2] - '0' + 1);
|
||||
|
||||
} else if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
int numSw = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
int idx = val[1] - 'A';
|
||||
idx = idx - numSw;
|
||||
|
||||
if(idx >= 0 and idx < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
idx = idx * 3 + (val[2] - '0' + 1);
|
||||
rhs = RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, idx);
|
||||
}
|
||||
rhs.index = sw_idx * 3 + (val[val_len - 1] - '0' + 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
int sw_type = getCurrentFirmware()->getRawSwitchTypesIndex(sw_str_tmp.c_str());
|
||||
int sw_type = b.getRawSwitchTypeIndex(sw_str_tmp.c_str());
|
||||
if (sw_type >= 0) {
|
||||
rhs.type = (RawSwitchType)sw_type;
|
||||
if (rhs.type == SWITCH_TYPE_TELEMETRY || rhs.type == SWITCH_TYPE_TRAINER || rhs.type == SWITCH_TYPE_ACT || rhs.type == SWITCH_TYPE_ONE)
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "boards.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "generalsettings.h"
|
||||
#include "boardjson.h"
|
||||
|
||||
const YamlLookupTable switchConfigLut = {
|
||||
{Board::SWITCH_NOT_AVAILABLE, "none"},
|
||||
@@ -30,131 +32,388 @@ const YamlLookupTable switchConfigLut = {
|
||||
{Board::SWITCH_3POS, "3pos"},
|
||||
};
|
||||
|
||||
|
||||
const YamlLookupTable potConfigLut = {
|
||||
{Board::POT_NONE, "none"},
|
||||
{Board::POT_WITH_DETENT, "with_detent"},
|
||||
{Board::POT_MULTIPOS_SWITCH, "multipos_switch"},
|
||||
{Board::POT_WITHOUT_DETENT, "without_detent"},
|
||||
{Board::POT_SLIDER_WITH_DETENT, "slider"},
|
||||
};
|
||||
|
||||
const YamlLookupTable slidersLut = {
|
||||
{0, "LS"},
|
||||
{1, "RS"},
|
||||
{Board::FLEX_NONE, "none"},
|
||||
{Board::FLEX_POT, "without_detent"},
|
||||
{Board::FLEX_POT_CENTER, "with_detent"},
|
||||
{Board::FLEX_SLIDER, "slider"},
|
||||
{Board::FLEX_MULTIPOS, "multipos_switch"},
|
||||
{Board::FLEX_AXIS_X, "axis_x"},
|
||||
{Board::FLEX_AXIS_Y, "axis_y"},
|
||||
{Board::FLEX_SWITCH, "switch"},
|
||||
};
|
||||
|
||||
// pre v2.10
|
||||
const YamlLookupTable sliderConfigLut = {
|
||||
{Board::SLIDER_NONE, "none"},
|
||||
{Board::SLIDER_WITH_DETENT, "with_detent"},
|
||||
};
|
||||
|
||||
int YamlStickLookup::name2idx(const std::string& name)
|
||||
{
|
||||
try {
|
||||
int idx = std::stoi(name);
|
||||
if (idx < 4) {
|
||||
return idx;
|
||||
}
|
||||
} catch(...) {}
|
||||
// pre v2.10
|
||||
const YamlLookupTable sticksLut = {
|
||||
{0, "Rud"},
|
||||
{1, "Ele"},
|
||||
{2, "Thr"},
|
||||
{3, "Ali"},
|
||||
};
|
||||
|
||||
return -1;
|
||||
YamlPotConfig::YamlPotConfig(const GeneralSettings::InputConfig* rhs)
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (Boards::isInputConfigurable(i)) {
|
||||
config[i].tag = Boards::getInputYamlName(i, BoardJson::YLT_CONFIG).toStdString();
|
||||
config[i].type = rhs[i].type;
|
||||
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
config[i].flexType = rhs[i].flexType;
|
||||
config[i].inverted = rhs[i].inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string YamlStickLookup::idx2name(unsigned int idx)
|
||||
void YamlPotConfig::copy(GeneralSettings::InputConfig* rhs) const
|
||||
{
|
||||
if (idx < 4) {
|
||||
return std::to_string(idx);
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (config[i].type == (unsigned int)Board::AIT_FLEX) {
|
||||
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
rhs[i].flexType = (Board::FlexType)config[i].flexType;
|
||||
rhs[i].inverted = config[i].inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YamlSliderConfig::copy(GeneralSettings::InputConfig* rhs) const
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (config[i].type == (unsigned int)Board::AIT_FLEX) {
|
||||
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
rhs[i].flexType = (Board::FlexType)config[i].flexType;
|
||||
rhs[i].inverted = config[i].inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YamlStickConfig::YamlStickConfig(const GeneralSettings::InputConfig* rhs)
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
config[i].tag = std::to_string(i);
|
||||
config[i].type = rhs[i].type;
|
||||
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
}
|
||||
}
|
||||
|
||||
void YamlStickConfig::copy(GeneralSettings::InputConfig* rhs) const
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
|
||||
if (config[i].type == (unsigned int)Board::AIT_STICK) {
|
||||
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YamlSwitchConfig::YamlSwitchConfig(const GeneralSettings::SwitchConfig* rhs)
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
|
||||
config[i].tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
|
||||
config[i].type = rhs[i].type;
|
||||
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
// config[i].inverted = rhs[i].inverted;
|
||||
}
|
||||
}
|
||||
|
||||
void YamlSwitchConfig::copy(GeneralSettings::SwitchConfig* rhs) const
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
|
||||
if (config[i].type != (unsigned int)Board::SWITCH_NOT_AVAILABLE) {
|
||||
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
|
||||
rhs[i].type = (Board::SwitchType)config[i].type;
|
||||
// rhs[i].inverted = config[i].inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YamlSwitchesFlex::YamlSwitchesFlex(const GeneralSettings::SwitchConfig* rhs)
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
|
||||
if (Boards::isSwitchFlex(i) && rhs[i].inputIdx != SWITCH_INPUTINDEX_NONE) {
|
||||
int idx = Boards::getSwitchTagNum(i) - 1;
|
||||
if (idx >= 0 && idx < CPN_MAX_SWITCHES_FLEX) {
|
||||
config[idx].tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
|
||||
config[idx].channel = Boards::getInputYamlName(rhs[i].inputIdx, BoardJson::YLT_CONFIG).toStdString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YamlSwitchesFlex::copy(GeneralSettings::SwitchConfig* rhs) const
|
||||
{
|
||||
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::FlexSwitches); i++) {
|
||||
int idx = Boards::getSwitchYamlIndex(config[i].tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
rhs[idx].inputIdx = config[i].inputIndx;
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
||||
Node convert<InputConfig>::encode(const InputConfig& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["name"] = rhs.name;
|
||||
|
||||
if (rhs.type != Board::AIT_STICK) {
|
||||
node["type"] = potConfigLut << rhs.flexType;
|
||||
node["inv"] = (int)rhs.inverted;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<InputConfig>::decode(const Node& node, InputConfig& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
node["name"] >> rhs.name;
|
||||
node["type"] >> potConfigLut >> rhs.flexType;
|
||||
node["inv"] >> rhs.inverted;
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
int idx = Boards::getInputYamlIndex(rhs.tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
if (idx >= 0) {
|
||||
Board::InputInfo info = Boards::getInputInfo(idx);
|
||||
rhs.inverted = info.inverted;
|
||||
}
|
||||
else
|
||||
rhs.inverted = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Node convert<SwitchConfig>::encode(const SwitchConfig& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["type"] = switchConfigLut << rhs.type;
|
||||
node["name"] = rhs.name;
|
||||
// node["inv"] = (int)rhs.inverted; in hwdef json but not implemented in radio yaml
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<SwitchConfig>::decode(const Node& node, SwitchConfig& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
node["type"] >> switchConfigLut >> rhs.type;
|
||||
node["name"] >> rhs.name;
|
||||
// node["inv"] >> rhs.inverted; in hwdef json but not implemented in radio yaml
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
|
||||
int idx = Boards::getSwitchYamlIndex(rhs.tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
if (idx >= 0) {
|
||||
Board::SwitchInfo info = Boards::getSwitchInfo(idx);
|
||||
rhs.inverted = info.inverted;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Node convert<SwitchFlex>::encode(const SwitchFlex& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["channel"] = rhs.channel;
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<SwitchFlex>::decode(const Node& node, SwitchFlex& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
node["channel"] >> rhs.channel;
|
||||
rhs.inputIndx = Boards::getInputYamlIndex(rhs.channel.c_str(), BoardJson::YLT_CONFIG);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Node convert<YamlPotConfig>::encode(const YamlPotConfig& rhs)
|
||||
{
|
||||
Node node;
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
for (int i = 0; i < maxcnt; i++) {
|
||||
if (rhs.config[i].type == (unsigned int)Board::AIT_FLEX && rhs.config[i].flexType != (unsigned int)Board::FLEX_NONE) {
|
||||
std::string tag = rhs.config[i].tag;
|
||||
node[tag] = rhs.config[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<YamlPotConfig>::decode(const Node& node, YamlPotConfig& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION)))
|
||||
tag = Boards::getLegacyAnalogMappedInputTag(tag.c_str());
|
||||
|
||||
int idx = Boards::getInputYamlIndex(tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
|
||||
if (idx >= 0 && idx < maxcnt) {
|
||||
kv.second >> rhs.config[idx];
|
||||
rhs.config[idx].tag = tag;
|
||||
rhs.config[idx].type = Board::AIT_FLEX;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
bool convert<YamlSliderConfig>::decode(const Node& node, YamlSliderConfig& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
if (Boards::getCapability(getCurrentBoard(), Board::Sliders) < 1)
|
||||
return true;
|
||||
|
||||
int i = 1;
|
||||
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
int idx = Boards::getInputSliderIndex(i);
|
||||
|
||||
if (idx >= 0 && idx < maxcnt) {
|
||||
kv.second >> rhs.config[idx];
|
||||
rhs.config[idx].tag = Boards::getInputTag(idx).toStdString();
|
||||
rhs.config[idx].type = Board::AIT_FLEX;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int YamlSwitchLookup::name2idx(const std::string& name)
|
||||
Node convert<YamlStickConfig>::encode(const YamlStickConfig& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
int idx = fw->getSwitchesIndex(name.c_str());
|
||||
if (idx < 0) return -1;
|
||||
Node node;
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
return idx;
|
||||
for (int i = 0; i < maxcnt; i++) {
|
||||
if (rhs.config[i].type == (unsigned int)Board::AIT_STICK) {
|
||||
std::string tag = rhs.config[i].tag;
|
||||
node[tag] = rhs.config[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string YamlSwitchLookup::idx2name(unsigned int idx)
|
||||
bool convert<YamlStickConfig>::decode(const Node& node, YamlStickConfig& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
unsigned int switches = Boards::getCapability(fw->getBoard(), Board::Switches);
|
||||
if (idx >= switches) return std::string();
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
return fw->getSwitchesTag(idx);
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
|
||||
if (!tag.empty()) {
|
||||
int idx = std::stoi(tag);
|
||||
|
||||
if (idx >= 0 && idx < maxcnt) {
|
||||
kv.second >> rhs.config[idx];
|
||||
rhs.config[idx].tag = tag;
|
||||
rhs.config[idx].type = Board::AIT_STICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int YamlPotLookup::name2idx(const std::string& name)
|
||||
Node convert<YamlSwitchConfig>::encode(const YamlSwitchConfig& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
int idx = 0;
|
||||
Node node;
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION)))
|
||||
idx = fw->getAnalogInputIndex(name.c_str());
|
||||
else
|
||||
idx = fw->getAnalogInputIndexADC(name.c_str());
|
||||
for (int i = 0; i < maxcnt; i++) {
|
||||
if (rhs.config[i].type != Board::SWITCH_NOT_AVAILABLE) {
|
||||
std::string tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
|
||||
node[tag] = rhs.config[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (idx < 0) return idx;
|
||||
|
||||
int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks);
|
||||
if (idx < sticks) return -1;
|
||||
idx -= sticks;
|
||||
|
||||
int pots = Boards::getCapability(fw->getBoard(), Board::Pots);
|
||||
int sliders = Boards::getCapability(fw->getBoard(), Board::Sliders);
|
||||
if (idx >= pots + sliders) return -1;
|
||||
|
||||
return idx;
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string YamlPotLookup::idx2name(unsigned int idx)
|
||||
bool convert<YamlSwitchConfig>::decode(const Node& node, YamlSwitchConfig& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
auto board = fw->getBoard();
|
||||
unsigned int pots = Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders);
|
||||
if (idx >= pots) return std::string();
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
unsigned int sticks = Boards::getCapability(board, Board::Sticks);
|
||||
return fw->getAnalogInputSeqTagADC(idx + sticks);
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
int idx = Boards::getSwitchYamlIndex(tag.c_str(), BoardJson::YLT_CONFIG);
|
||||
|
||||
if (idx >= 0 && idx < maxcnt) {
|
||||
kv.second >> rhs.config[idx];
|
||||
rhs.config[idx].tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int YamlSliderLookup::name2idx(const std::string& name)
|
||||
Node convert<YamlSwitchesFlex>::encode(const YamlSwitchesFlex& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
int idx = 0;
|
||||
Node node;
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::FlexSwitches);
|
||||
|
||||
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION)))
|
||||
idx = fw->getAnalogInputIndex(name.c_str());
|
||||
else
|
||||
idx = fw->getAnalogInputIndexADC(name.c_str());
|
||||
for (int i = 0; i < maxcnt; i++) {
|
||||
if (!rhs.config[i].tag.empty())
|
||||
node[rhs.config[i].tag] = rhs.config[i];
|
||||
}
|
||||
|
||||
if (idx < 0) return idx;
|
||||
|
||||
int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks);
|
||||
if (idx < sticks) return -1;
|
||||
idx -= sticks;
|
||||
|
||||
int pots = Boards::getCapability(fw->getBoard(), Board::Pots);
|
||||
if (idx < pots) return -1;
|
||||
idx -= pots;
|
||||
|
||||
int sliders = Boards::getCapability(fw->getBoard(), Board::Sliders);
|
||||
if (idx >= sliders) return -1;
|
||||
|
||||
return idx;
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string YamlSliderLookup::idx2name(unsigned int idx)
|
||||
bool convert<YamlSwitchesFlex>::decode(const Node& node, YamlSwitchesFlex& rhs)
|
||||
{
|
||||
auto fw = getCurrentFirmware();
|
||||
unsigned int sliders = Boards::getCapability(fw->getBoard(), Board::Sliders);
|
||||
if (idx >= sliders) return std::string();
|
||||
if (!node.IsMap()) return false;
|
||||
|
||||
unsigned int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks);
|
||||
unsigned int pots = Boards::getCapability(fw->getBoard(), Board::Pots);
|
||||
return fw->getAnalogInputTag(idx + pots + sticks);
|
||||
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::FlexSwitches);
|
||||
|
||||
for (const auto& kv : node) {
|
||||
std::string tag;
|
||||
kv.first >> tag;
|
||||
|
||||
const char* val = tag.data();
|
||||
size_t len = tag.size();
|
||||
|
||||
if (len > 2 && val[0] == 'F' && val[1] == 'L' && val[2] > '0' && val[2] <= '9') {
|
||||
int idx = std::stoi(tag.substr(2, len - 2)) - 1;
|
||||
|
||||
if (idx >= 0 && idx < maxcnt) {
|
||||
kv.second >> rhs.config[idx];
|
||||
rhs.config[idx].tag = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML
|
||||
|
||||
@@ -24,139 +24,65 @@
|
||||
#include "generalsettings.h"
|
||||
#include <string.h>
|
||||
|
||||
struct YamlStickLookup {
|
||||
static int name2idx(const std::string& name);
|
||||
static std::string idx2name(unsigned int idx);
|
||||
};
|
||||
class GeneralSettings;
|
||||
|
||||
template <unsigned int N, class name_lookup>
|
||||
struct YamlNameConfig {
|
||||
char name[N][HARDWARE_NAME_LEN + 1];
|
||||
|
||||
YamlNameConfig() { memset(name, 0, sizeof(name)); }
|
||||
|
||||
YamlNameConfig(const char in_names[N][HARDWARE_NAME_LEN + 1])
|
||||
{
|
||||
memcpy(name, in_names, sizeof(name));
|
||||
#define ENCODE_DECODE_CONFIG(cfgstruct) \
|
||||
namespace YAML \
|
||||
{ \
|
||||
template <> \
|
||||
struct convert<cfgstruct> { \
|
||||
static Node encode(const cfgstruct& rhs); \
|
||||
static bool decode(const Node& node, cfgstruct& rhs); \
|
||||
}; \
|
||||
}
|
||||
|
||||
void copy(char out_names[N][HARDWARE_NAME_LEN + 1])
|
||||
{
|
||||
memcpy(out_names, name, sizeof(name));
|
||||
}
|
||||
};
|
||||
|
||||
typedef YamlNameConfig<CPN_MAX_STICKS, YamlStickLookup> YamlStickConfig;
|
||||
|
||||
template <unsigned int N, class name_lookup, const YamlLookupTable& cfg_lut>
|
||||
struct YamlKnobConfig : public YamlNameConfig<N, name_lookup> {
|
||||
unsigned int config[N];
|
||||
|
||||
YamlKnobConfig() { memset(config, 0, sizeof(config)); }
|
||||
|
||||
YamlKnobConfig(const char in_names[N][HARDWARE_NAME_LEN + 1],
|
||||
const unsigned int in_configs[N]) :
|
||||
YamlNameConfig<N, name_lookup>(in_names)
|
||||
{
|
||||
memcpy(config, in_configs, sizeof(config));
|
||||
#define INPUT_SWITCH_CONFIG(name, cfgsize, cfgstruct, gsstruct) \
|
||||
struct name { \
|
||||
cfgstruct config[cfgsize]; \
|
||||
\
|
||||
name() = default; \
|
||||
name(const GeneralSettings::gsstruct* rhs); \
|
||||
void copy(GeneralSettings::gsstruct* rhs) const; \
|
||||
}; \
|
||||
\
|
||||
namespace YAML \
|
||||
{ \
|
||||
template <> \
|
||||
struct convert<name> { \
|
||||
static Node encode(const name& rhs); \
|
||||
static bool decode(const Node& node, name& rhs); \
|
||||
}; \
|
||||
}
|
||||
|
||||
void copy(char out_names[N][HARDWARE_NAME_LEN + 1],
|
||||
unsigned int out_configs[N])
|
||||
{
|
||||
YamlNameConfig<N, name_lookup>::copy(out_names);
|
||||
memcpy(out_configs, config, sizeof(config));
|
||||
}
|
||||
struct InputConfig {
|
||||
std::string tag = std::string();
|
||||
unsigned int type = 0;
|
||||
char name[HARDWARE_NAME_LEN + 1] = {'\0'};
|
||||
unsigned int flexType = 0;
|
||||
bool inverted = false;
|
||||
};
|
||||
|
||||
// SA:
|
||||
// type: 3pos
|
||||
// name:
|
||||
struct YamlSwitchLookup {
|
||||
static int name2idx(const std::string& name);
|
||||
static std::string idx2name(unsigned int idx);
|
||||
};
|
||||
extern const YamlLookupTable switchConfigLut;
|
||||
typedef YamlKnobConfig<CPN_MAX_SWITCHES, YamlSwitchLookup, switchConfigLut>
|
||||
YamlSwitchConfig;
|
||||
ENCODE_DECODE_CONFIG(InputConfig)
|
||||
|
||||
// S1:
|
||||
// type: with_detent
|
||||
// name:
|
||||
struct YamlPotLookup {
|
||||
static int name2idx(const std::string& name);
|
||||
static std::string idx2name(unsigned int idx);
|
||||
};
|
||||
extern const YamlLookupTable potConfigLut;
|
||||
typedef YamlKnobConfig<CPN_MAX_POTS + CPN_MAX_SLIDERS, YamlPotLookup, potConfigLut> YamlPotConfig;
|
||||
|
||||
// S1:
|
||||
// type: with_detent
|
||||
// name:
|
||||
struct YamlSliderLookup {
|
||||
static int name2idx(const std::string& name);
|
||||
static std::string idx2name(unsigned int idx);
|
||||
};
|
||||
extern const YamlLookupTable sliderConfigLut;
|
||||
typedef YamlKnobConfig<CPN_MAX_SLIDERS, YamlSliderLookup, sliderConfigLut>
|
||||
YamlSliderConfig;
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <unsigned int N, class name_lookup>
|
||||
struct convert<YamlNameConfig<N, name_lookup> > {
|
||||
static Node encode(const YamlNameConfig<N, name_lookup>& rhs)
|
||||
{
|
||||
Node node;
|
||||
for (unsigned int i=0; i<N; i++) {
|
||||
std::string name = name_lookup::idx2name(i);
|
||||
if (!name.empty() && rhs.name[i][0]) {
|
||||
node[name]["name"] = rhs.name[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
static bool decode(const Node& node, YamlNameConfig<N, name_lookup>& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
int idx = 0;
|
||||
for (const auto& kv : node) {
|
||||
idx = name_lookup::name2idx(kv.first.Scalar());
|
||||
if (idx >= 0) {
|
||||
kv.second["name"] >> rhs.name[idx];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
struct SwitchConfig {
|
||||
std::string tag = std::string();
|
||||
char name[HARDWARE_NAME_LEN + 1] = {'\0'};
|
||||
unsigned int type = 0;
|
||||
bool inverted = false;
|
||||
};
|
||||
|
||||
template <unsigned int N, class name_lookup, const YamlLookupTable& cfg_lut>
|
||||
struct convert<YamlKnobConfig<N, name_lookup, cfg_lut> > {
|
||||
static Node encode(const YamlKnobConfig<N, name_lookup, cfg_lut>& rhs)
|
||||
{
|
||||
Node node;
|
||||
for (unsigned int i=0; i<N; i++) {
|
||||
std::string name = name_lookup::idx2name(i);
|
||||
if (!name.empty() && (rhs.config[i] || rhs.name[i][0])) {
|
||||
node[name]["type"] = cfg_lut << rhs.config[i];
|
||||
node[name]["name"] = rhs.name[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
static bool decode(const Node& node,
|
||||
YamlKnobConfig<N, name_lookup, cfg_lut>& rhs)
|
||||
{
|
||||
if (!node.IsMap()) return false;
|
||||
int idx = 0;
|
||||
for (const auto& kv : node) {
|
||||
idx = name_lookup::name2idx(kv.first.Scalar());
|
||||
if (idx >= 0) {
|
||||
kv.second["type"] >> cfg_lut >> rhs.config[idx];
|
||||
kv.second["name"] >> rhs.name[idx];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ENCODE_DECODE_CONFIG(SwitchConfig)
|
||||
|
||||
struct SwitchFlex {
|
||||
std::string tag = std::string();
|
||||
std::string channel = std::string();
|
||||
int inputIndx = SWITCH_INPUTINDEX_NONE;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
ENCODE_DECODE_CONFIG(SwitchFlex)
|
||||
|
||||
INPUT_SWITCH_CONFIG(YamlPotConfig, CPN_MAX_INPUTS, InputConfig, InputConfig)
|
||||
INPUT_SWITCH_CONFIG(YamlSliderConfig, CPN_MAX_INPUTS, InputConfig, InputConfig)
|
||||
INPUT_SWITCH_CONFIG(YamlStickConfig, CPN_MAX_INPUTS, InputConfig, InputConfig)
|
||||
INPUT_SWITCH_CONFIG(YamlSwitchConfig, CPN_MAX_SWITCHES, SwitchConfig, SwitchConfig)
|
||||
INPUT_SWITCH_CONFIG(YamlSwitchesFlex, CPN_MAX_SWITCHES_FLEX, SwitchFlex, SwitchConfig)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "eeprominterface.h"
|
||||
#include "firmwares/opentx/opentxeeprom.h"
|
||||
#include "firmwareinterface.h"
|
||||
#include "boardfactories.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QMessageBox>
|
||||
@@ -119,6 +120,21 @@ QString EEPROMInterface::getEepromWarnings(unsigned long errorsFound)
|
||||
* Firmware
|
||||
*/
|
||||
|
||||
Firmware::Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board,
|
||||
const QString & downloadId, const QString & simulatorId, const QString & hwdefnId) :
|
||||
id(id),
|
||||
name(name),
|
||||
board(board),
|
||||
variantBase(0),
|
||||
base(base),
|
||||
eepromInterface(nullptr),
|
||||
downloadId(downloadId),
|
||||
simulatorId(simulatorId),
|
||||
hwdefnId(hwdefnId)
|
||||
{
|
||||
gBoardFactories->registerBoard(board, hwdefnId);
|
||||
}
|
||||
|
||||
// static
|
||||
QVector<Firmware *> Firmware::registeredFirmwares;
|
||||
Firmware * Firmware::defaultVariant = nullptr;
|
||||
|
||||
@@ -286,29 +286,14 @@ class Firmware
|
||||
typedef QList<OptionsGroup> OptionsList;
|
||||
|
||||
|
||||
explicit Firmware(const QString & id, const QString & name, Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()) :
|
||||
Firmware(nullptr, id, name, board, downloadId, simulatorId)
|
||||
explicit Firmware(const QString & id, const QString & name, Board::Type board, const QString & downloadId = QString(),
|
||||
const QString & simulatorId = QString(), const QString & hwdefnId = QString()) :
|
||||
Firmware(nullptr, id, name, board, downloadId, simulatorId, hwdefnId)
|
||||
{ }
|
||||
|
||||
explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()) :
|
||||
id(id),
|
||||
name(name),
|
||||
board(board),
|
||||
variantBase(0),
|
||||
base(base),
|
||||
eepromInterface(nullptr),
|
||||
downloadId(downloadId),
|
||||
simulatorId(simulatorId),
|
||||
analogInputNamesLookupTable(Boards::getAnalogNamesLookupTable(board)),
|
||||
analogInputNamesLookupTableADC(Boards::getAnalogNamesLookupTable(board, QString(CPN_ADC_REFACTOR_VERSION))),
|
||||
switchesLookupTable(Boards::getSwitchesLookupTable(board)),
|
||||
trimSwitchesLookupTable(Boards::getTrimSwitchesLookupTable(board)),
|
||||
trimSourcesLookupTable(Boards::getTrimSourcesLookupTable(board)),
|
||||
rawSwitchTypesLookupTable(RawSwitch::getRawSwitchTypesLookupTable()),
|
||||
rawSourceSpecialTypesLookupTable(RawSource::getSpecialTypesLookupTable()),
|
||||
rawSourceCyclicLookupTable(RawSource::getCyclicLookupTable())
|
||||
{
|
||||
}
|
||||
explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board,
|
||||
const QString & downloadId = QString(), const QString & simulatorId = QString(),
|
||||
const QString & hwdefnId = QString());
|
||||
|
||||
virtual ~Firmware() { }
|
||||
|
||||
@@ -431,26 +416,9 @@ class Firmware
|
||||
return getFirmwareForId(FIRMWARE_ID_PREFIX + flavour);
|
||||
}
|
||||
|
||||
const StringTagMappingTable* getAnalogIndexNamesLookupTable()
|
||||
{
|
||||
return &analogInputNamesLookupTable;
|
||||
}
|
||||
|
||||
const StringTagMappingTable* getAnalogIndexNamesLookupTableADC()
|
||||
{
|
||||
return &analogInputNamesLookupTableADC;
|
||||
}
|
||||
|
||||
STRINGTAGMAPPINGFUNCS_ADC(analogInputNamesLookupTable, analogInputNamesLookupTableADC, AnalogInput);
|
||||
STRINGTAGMAPPINGFUNCS(switchesLookupTable, Switches);
|
||||
STRINGTAGMAPPINGFUNCS(trimSwitchesLookupTable, TrimSwitches);
|
||||
STRINGTAGMAPPINGFUNCS(trimSourcesLookupTable, TrimSources);
|
||||
STRINGTAGMAPPINGFUNCS(rawSwitchTypesLookupTable, RawSwitchTypes);
|
||||
STRINGTAGMAPPINGFUNCS(rawSourceSpecialTypesLookupTable, RawSourceSpecialTypes);
|
||||
STRINGTAGMAPPINGFUNCS(rawSourceCyclicLookupTable, RawSourceCyclic);
|
||||
|
||||
const QString getDownloadId() { return getFirmwareBase()->downloadId.isEmpty() ? getFlavour() : getFirmwareBase()->downloadId; }
|
||||
const QString getSimulatorId() { return getFirmwareBase()->simulatorId.isEmpty() ? getId() : getFirmwareBase()->simulatorId; }
|
||||
const QString getHwDefnId() { return getFirmwareBase()->hwdefnId.isEmpty() ? getFlavour() : getFirmwareBase()->hwdefnId; }
|
||||
|
||||
protected:
|
||||
QString id;
|
||||
@@ -461,16 +429,7 @@ class Firmware
|
||||
EEPROMInterface * eepromInterface;
|
||||
QString downloadId;
|
||||
QString simulatorId;
|
||||
|
||||
// used by YAML encode and decode
|
||||
const StringTagMappingTable analogInputNamesLookupTable;
|
||||
const StringTagMappingTable analogInputNamesLookupTableADC;
|
||||
const StringTagMappingTable switchesLookupTable;
|
||||
const StringTagMappingTable trimSwitchesLookupTable;
|
||||
const StringTagMappingTable trimSourcesLookupTable;
|
||||
const StringTagMappingTable rawSwitchTypesLookupTable;
|
||||
const StringTagMappingTable rawSourceSpecialTypesLookupTable;
|
||||
const StringTagMappingTable rawSourceCyclicLookupTable;
|
||||
QString hwdefnId;
|
||||
|
||||
QList<const char *> languages;
|
||||
//QList<const char *> ttslanguages;
|
||||
|
||||
@@ -32,53 +32,147 @@ const uint8_t chout_ar[] = { // First number is 0..23 -> template setup, Second
|
||||
4,1,2,3 , 4,1,3,2 , 4,2,1,3 , 4,2,3,1 , 4,3,1,2 , 4,3,2,1
|
||||
};
|
||||
|
||||
bool GeneralSettings::switchPositionAllowedTaranis(int index) const
|
||||
bool GeneralSettings::switchPositionAllowed(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
|
||||
div_t qr = div(abs(index) - 1, 3);
|
||||
|
||||
if (index < 0 && switchConfig[qr.quot] != Board::SWITCH_3POS)
|
||||
if (index < 0 && switchConfig[qr.quot].type != Board::SWITCH_3POS)
|
||||
return false;
|
||||
else if (qr.rem == 1)
|
||||
return switchConfig[qr.quot] == Board::SWITCH_3POS;
|
||||
return switchConfig[qr.quot].type == Board::SWITCH_3POS;
|
||||
else
|
||||
return switchConfig[qr.quot] != Board::SWITCH_NOT_AVAILABLE;
|
||||
return switchConfig[qr.quot].type != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::switchSourceAllowedTaranis(int index) const
|
||||
bool GeneralSettings::switchSourceAllowed(int index) const
|
||||
{
|
||||
return switchConfig[index] != Board::SWITCH_NOT_AVAILABLE;
|
||||
return switchConfig[index].type != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isPotAvailable(int index) const
|
||||
bool GeneralSettings::isInputAvailable(int index) const
|
||||
{
|
||||
int numPots = Boards::getCapability(getCurrentBoard(), Board::Pots);
|
||||
if (getCurrentFirmware()->getCapability(HasFlySkyGimbals))
|
||||
numPots -= 2;
|
||||
Board::Type board = getCurrentBoard();
|
||||
|
||||
if (index < 0 || index >= numPots)
|
||||
if (index < 0 || index >= Boards::getCapability(board, Board::Inputs))
|
||||
return false;
|
||||
return potConfig[index] != Board::POT_NONE;
|
||||
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return (config.type == Board::AIT_STICK ||
|
||||
(config.type == Board::AIT_FLEX && config.flexType != Board::FLEX_NONE));
|
||||
}
|
||||
|
||||
bool GeneralSettings::isSliderAvailable(int index) const
|
||||
bool GeneralSettings::isInputFlexSwitchAvailable(int index) const
|
||||
{
|
||||
if (index < 0 || index >= Boards::getCapability(getCurrentBoard(), Board::Sliders))
|
||||
Board::Type board = getCurrentBoard();
|
||||
|
||||
if (index < 0 || index >= Boards::getCapability(board, Board::Inputs))
|
||||
return false;
|
||||
return sliderConfig[index] != Board::SLIDER_NONE;
|
||||
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return (config.type == Board::AIT_FLEX && config.flexType == Board::FLEX_SWITCH);
|
||||
}
|
||||
|
||||
bool GeneralSettings::isMultiPosPot(int index) const
|
||||
bool GeneralSettings::isInputMultiPosPot(int index) const
|
||||
{
|
||||
if (isPotAvailable(index)) {
|
||||
if (potConfig[index] == Board::POT_MULTIPOS_SWITCH)
|
||||
return true;
|
||||
if (isInputAvailable(index)) {
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return (config.type == Board::AIT_FLEX &&
|
||||
config.flexType == Board::FLEX_MULTIPOS);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isInputPot(int index) const
|
||||
{
|
||||
if (isInputAvailable(index)) {
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return (config.type == Board::AIT_FLEX &&
|
||||
(config.flexType == Board::FLEX_POT ||
|
||||
config.flexType == Board::FLEX_POT_CENTER ||
|
||||
config.flexType == Board::FLEX_MULTIPOS));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isInputSlider(int index) const
|
||||
{
|
||||
if (isInputAvailable(index)) {
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return (config.type == Board::AIT_FLEX &&
|
||||
config.flexType == Board::FLEX_SLIDER);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isInputStick(int index) const
|
||||
{
|
||||
if (isInputAvailable(index)) {
|
||||
const InputConfig &config = inputConfig[index];
|
||||
|
||||
return config.type == Board::AIT_STICK;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// pre v2.10 support
|
||||
// post refactor clean up - where do we call this from?
|
||||
bool GeneralSettings::isMultiPosPot(int index) const
|
||||
{
|
||||
return isInputMultiPosPot(Boards::getInputPotIndex(index));
|
||||
}
|
||||
|
||||
// pre v2.10 support
|
||||
// post refactor clean up - where do we call this from?
|
||||
bool GeneralSettings::isPotAvailable(int index) const
|
||||
{
|
||||
return isInputPot(Boards::getInputPotIndex(index));
|
||||
}
|
||||
|
||||
// pre v2.10 support
|
||||
// post refactor clean up - where do we call this from?
|
||||
bool GeneralSettings::isSliderAvailable(int index) const
|
||||
{
|
||||
return isInputSlider(Boards::getInputSliderIndex(index));
|
||||
}
|
||||
|
||||
bool GeneralSettings::isSwitchAvailable(int index) const
|
||||
{
|
||||
if (index < 0 || index >= Boards::getCapability(getCurrentBoard(), Board::Switches))
|
||||
return false;
|
||||
|
||||
const SwitchConfig &config = switchConfig[index];
|
||||
|
||||
return config.type != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isSwitchFlex(int index) const
|
||||
{
|
||||
return Boards::isSwitchFlex(index);
|
||||
}
|
||||
|
||||
bool GeneralSettings::unassignedInputFlexSwitches() const
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
int cnt = 0;
|
||||
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Inputs); i++) {
|
||||
if (inputConfig[i].flexType == Board::FLEX_SWITCH)
|
||||
cnt++;
|
||||
}
|
||||
return cnt < Boards::getCapability(board, Board::FlexSwitches);
|
||||
}
|
||||
|
||||
void GeneralSettings::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(GeneralSettings));
|
||||
@@ -119,18 +213,6 @@ void GeneralSettings::init()
|
||||
|
||||
setDefaultControlTypes(board);
|
||||
|
||||
for (int i = 0; i < CPN_MAX_ANALOGS; ++i) {
|
||||
if ((i >= CPN_MAX_STICKS) && (i < CPN_MAX_STICKS + CPN_MAX_POTS) && (potConfig[i-CPN_MAX_STICKS] == Board::POT_MULTIPOS_SWITCH)) {
|
||||
calibMid[i] = 773;;
|
||||
calibSpanNeg[i] = 5388;
|
||||
calibSpanPos[i] = 9758;
|
||||
} else {
|
||||
calibMid[i] = 0x200;
|
||||
calibSpanNeg[i] = 0x180;
|
||||
calibSpanPos[i] = 0x180;
|
||||
}
|
||||
}
|
||||
|
||||
backlightMode = 3; // keys and sticks
|
||||
backlightDelay = 2; // 2 * 5 = 10 secs
|
||||
inactivityTimer = 10;
|
||||
@@ -174,7 +256,6 @@ void GeneralSettings::init()
|
||||
stickMode = g.profile[g.sessionId()].defaultMode();
|
||||
|
||||
QString t_calib = g.profile[g.sessionId()].stickPotCalib();
|
||||
int potsnum = getBoardCapability(getCurrentBoard(), Board::Pots);
|
||||
if (!t_calib.isEmpty()) {
|
||||
QString t_trainercalib=g.profile[g.sessionId()].trainerCalib();
|
||||
int8_t t_txVoltageCalibration=(int8_t)g.profile[g.sessionId()].txVoltageCalibration();
|
||||
@@ -188,34 +269,32 @@ void GeneralSettings::init()
|
||||
QString t_SpeakerSet=g.profile[g.sessionId()].speaker();
|
||||
QString t_CountrySet=g.profile[g.sessionId()].countryCode();
|
||||
|
||||
if ((t_calib.length()==(CPN_MAX_STICKS+potsnum)*12) && (t_trainercalib.length()==16)) {
|
||||
if ((t_calib.length() == (Boards::getInputsCalibrated() * 12)) && (t_trainercalib.length() == 16)) {
|
||||
QString Byte;
|
||||
int16_t byte16;
|
||||
bool ok;
|
||||
for (int i=0; i<(CPN_MAX_STICKS+potsnum); i++) {
|
||||
Byte=t_calib.mid(i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibMid[i]=byte16;
|
||||
Byte=t_calib.mid(4+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanNeg[i]=byte16;
|
||||
Byte=t_calib.mid(8+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanPos[i]=byte16;
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Inputs); i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
Byte = t_calib.mid(i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) inputConfig[i].calib.mid = byte16;
|
||||
Byte = t_calib.mid(4 + i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) inputConfig[i].calib.spanNeg = byte16;
|
||||
Byte = t_calib.mid(8 + i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) inputConfig[i].calib.spanPos = byte16;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<4; i++) {
|
||||
Byte=t_trainercalib.mid(i*4,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
trainer.calib[i]=byte16;
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Sticks); i++) {
|
||||
Byte = t_trainercalib.mid(i * 4, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) trainer.calib[i] = byte16;
|
||||
}
|
||||
txCurrentCalibration=t_txCurrentCalibration;
|
||||
txVoltageCalibration=t_txVoltageCalibration;
|
||||
vBatWarn=t_vBatWarn;
|
||||
PPM_Multiplier=t_PPM_Multiplier;
|
||||
txCurrentCalibration = t_txCurrentCalibration;
|
||||
txVoltageCalibration = t_txVoltageCalibration;
|
||||
vBatWarn = t_vBatWarn;
|
||||
PPM_Multiplier = t_PPM_Multiplier;
|
||||
stickMode = t_stickMode;
|
||||
}
|
||||
if ((t_DisplaySet.length()==6) && (t_BeeperSet.length()==4) && (t_HapticSet.length()==6) && (t_SpeakerSet.length()==6)) {
|
||||
@@ -278,76 +357,37 @@ void GeneralSettings::init()
|
||||
|
||||
void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
||||
{
|
||||
for (int i=0; i<getBoardCapability(board, Board::FactoryInstalledSwitches); i++) {
|
||||
switchConfig[i] = Boards::getSwitchInfo(board, i).config;
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Inputs); i++) {
|
||||
if (!Boards::isInputIgnored(i, board)) {
|
||||
Board::InputInfo info = Boards::getInputInfo(i, board);
|
||||
inputConfig[i].type = info.type;
|
||||
inputConfig[i].flexType = info.flexType;
|
||||
inputConfig[i].inverted = info.inverted;
|
||||
}
|
||||
}
|
||||
|
||||
// TLite does not have pots or sliders
|
||||
if (IS_JUMPER_TLITE(board))
|
||||
return;
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Inputs); ++i) {
|
||||
if (!Boards::isInputCalibrated(i, board))
|
||||
continue;
|
||||
|
||||
// TODO: move to Boards, like with switches
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_MULTIPOS_SWITCH;
|
||||
potConfig[2] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_FLYSKY_NV14(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_FLYSKY_PL18(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X7(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if(IS_RADIOMASTER_ZORRO(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if(IS_RADIOMASTER_BOXER(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
potConfig[2] = Board::POT_MULTIPOS_SWITCH;
|
||||
}
|
||||
else if(IS_RADIOMASTER_POCKET(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if(IS_JUMPER_T20(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_FAMILY_T12(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
Board::InputInfo info = Boards::getInputInfo(i, board);
|
||||
|
||||
if (info.type == Board::AIT_FLEX && info.flexType == Board::FLEX_MULTIPOS) {
|
||||
inputConfig[i].calib.mid = 773;
|
||||
inputConfig[i].calib.spanNeg = 5388;
|
||||
inputConfig[i].calib.spanPos = 9758;
|
||||
} else {
|
||||
inputConfig[i].calib.mid = 0x200;
|
||||
inputConfig[i].calib.spanNeg = 0x180;
|
||||
inputConfig[i].calib.spanPos = 0x180;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board) || IS_JUMPER_T20(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[2] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[3] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Switches); i++) {
|
||||
Board::SwitchInfo info = Boards::getSwitchInfo(i, board);
|
||||
switchConfig[i].type = info.type;
|
||||
switchConfig[i].inverted = info.inverted;
|
||||
switchConfig[i].inputIdx = SWITCH_INPUTINDEX_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +396,7 @@ int GeneralSettings::getDefaultStick(unsigned int channel) const
|
||||
if (channel >= CPN_MAX_STICKS)
|
||||
return -1;
|
||||
else
|
||||
return chout_ar[4*templateSetup + channel] - 1;
|
||||
return chout_ar[4 * templateSetup + channel] - 1;
|
||||
}
|
||||
|
||||
RawSource GeneralSettings::getDefaultSource(unsigned int channel) const
|
||||
@@ -370,7 +410,7 @@ RawSource GeneralSettings::getDefaultSource(unsigned int channel) const
|
||||
|
||||
int GeneralSettings::getDefaultChannel(unsigned int stick) const
|
||||
{
|
||||
for (int i=0; i<4; i++){
|
||||
for (int i = 0; i < 4; i++){
|
||||
if (getDefaultStick(i) == (int)stick)
|
||||
return i;
|
||||
}
|
||||
@@ -383,10 +423,8 @@ void GeneralSettings::convert(RadioDataConversionState & cstate)
|
||||
|
||||
cstate.setOrigin(tr("Radio Settings"));
|
||||
|
||||
setDefaultControlTypes(cstate.toType); // start with default switches/pots/sliders
|
||||
|
||||
cstate.setComponent("Hardware");
|
||||
cstate.setItemType("Int. Module");
|
||||
cstate.setComponent(tr("Hardware"));
|
||||
cstate.setSubComp(tr("Internal Module"));
|
||||
RadioDataConversionState::LogField oldData(internalModule, ModuleData::typeToString(internalModule));
|
||||
|
||||
if (internalModule != MODULE_TYPE_NONE && (int)internalModule != g.currentProfile().defaultInternalModule()) {
|
||||
@@ -394,66 +432,97 @@ void GeneralSettings::convert(RadioDataConversionState & cstate)
|
||||
cstate.setInvalid(oldData);
|
||||
}
|
||||
|
||||
// Try to intelligently copy any custom control names
|
||||
// Try to intelligently copy any custom controls
|
||||
// step 1 clear current config
|
||||
memset(&inputConfig[0], '0', sizeof(InputConfig) * CPN_MAX_INPUTS);
|
||||
memset(&switchConfig[0], '0', sizeof(SwitchConfig) * CPN_MAX_SWITCHES);
|
||||
// step 2 load default config
|
||||
setDefaultControlTypes(cstate.toType);
|
||||
// step 3 copy matching config based on tags
|
||||
cstate.setSubComp(tr("Axis & Pots"));
|
||||
|
||||
// SE and SG are skipped on X7 board
|
||||
if (IS_TARANIS_X7(cstate.toType)) {
|
||||
if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) {
|
||||
strncpy(switchName[4], switchName[5], sizeof(switchName[4]));
|
||||
strncpy(switchName[5], switchName[7], sizeof(switchName[5]));
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS_X7(cstate.fromType)) {
|
||||
if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
|
||||
strncpy(switchName[5], switchName[4], sizeof(switchName[5]));
|
||||
strncpy(switchName[7], switchName[5], sizeof(switchName[7]));
|
||||
for (int i = 0; i < Boards::getCapability(cstate.fromType, Board::Inputs); i++) {
|
||||
if (Boards::isInputConfigurable(i, cstate.fromType)) {
|
||||
cstate.setItemType(Boards::isInputStick(i, cstate.fromType) ? tr("Axis") : tr("Pot"));
|
||||
RadioDataConversionState::LogField oldData(i, Boards::getInputName(i, cstate.fromType));
|
||||
const int idx = Boards::getInputIndex(Boards::getInputTag(i, cstate.fromType), Board::LVT_TAG, cstate.toType);
|
||||
|
||||
if (idx > -1) {
|
||||
const InputConfig &fromcfg = cstate.fromGS()->inputConfig[i];
|
||||
InputConfig &tocfg = inputConfig[idx];
|
||||
strncpy(tocfg.name, fromcfg.name, sizeof(inputConfig[0].name));
|
||||
tocfg.type = fromcfg.type;
|
||||
|
||||
if (tocfg.type == Board::AIT_FLEX && !Boards::getCapability(cstate.toType, Board::FlexSwitches) &&
|
||||
fromcfg.flexType == Board::FLEX_SWITCH) {
|
||||
cstate.withComponentField(Boards::getInputName(i, cstate.fromType));
|
||||
RadioDataConversionState::LogField oldFT(i, Boards::flexTypeToString(fromcfg.flexType));
|
||||
tocfg.flexType = Board::FLEX_NONE;
|
||||
cstate.setConverted(oldFT, RadioDataConversionState::LogField(i, Boards::flexTypeToString(tocfg.flexType)));
|
||||
}
|
||||
else
|
||||
tocfg.flexType = fromcfg.flexType;
|
||||
|
||||
tocfg.inverted = fromcfg.inverted;
|
||||
// do not copy calibration - use defaults as safer
|
||||
}
|
||||
else if (cstate.fromGS()->inputConfig[i].type == Board::AIT_FLEX && cstate.fromGS()->inputConfig[i].flexType != Board::FLEX_NONE) {
|
||||
cstate.setInvalid(oldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_FAMILY_T12(cstate.toType)) {
|
||||
if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) {
|
||||
strncpy(switchName[4], switchName[5], sizeof(switchName[0]));
|
||||
strncpy(switchName[5], switchName[7], sizeof(switchName[0]));
|
||||
}
|
||||
}
|
||||
cstate.setSubComp(tr("Switches"));
|
||||
|
||||
else if (IS_FAMILY_T12(cstate.fromType)) {
|
||||
if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
|
||||
strncpy(switchName[5], switchName[4], sizeof(switchName[0]));
|
||||
strncpy(switchName[7], switchName[5], sizeof(switchName[0]));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Boards::getCapability(cstate.fromType, Board::Switches); i++) {
|
||||
if (Boards::isSwitchConfigurable(i, cstate.fromType)) {
|
||||
cstate.setItemType(Boards::isSwitchFlex(i, cstate.fromType) ? tr("Flex Switch") :
|
||||
Boards::isSwitchFunc(i, cstate.fromType) ? tr("Function Switch") : tr("Switch"));
|
||||
RadioDataConversionState::LogField oldData(i, Boards::getSwitchName(i, cstate.fromType));
|
||||
const int idx = Boards::getSwitchIndex(Boards::getSwitchTag(i, cstate.fromType), Board::LVT_TAG, cstate.toType);
|
||||
|
||||
// LS and RS sliders are after 2 aux sliders on X12 and X9E
|
||||
if ((IS_HORUS_X12S(cstate.toType) || IS_TARANIS_X9E(cstate.toType)) && !IS_HORUS_X12S(cstate.fromType) && !IS_TARANIS_X9E(cstate.fromType)) {
|
||||
strncpy(sliderName[0], sliderName[2], sizeof(sliderName[0]));
|
||||
strncpy(sliderName[1], sliderName[3], sizeof(sliderName[1]));
|
||||
}
|
||||
else if (!IS_TARANIS_X9E(cstate.toType) && !IS_HORUS_X12S(cstate.toType) && (IS_HORUS_X12S(cstate.fromType) || IS_TARANIS_X9E(cstate.fromType))) {
|
||||
strncpy(sliderName[2], sliderName[0], sizeof(sliderName[2]));
|
||||
strncpy(sliderName[3], sliderName[1], sizeof(sliderName[3]));
|
||||
}
|
||||
if (idx > -1) {
|
||||
const SwitchConfig &fromcfg = cstate.fromGS()->switchConfig[i];
|
||||
SwitchConfig &tocfg = switchConfig[idx];
|
||||
strncpy(tocfg.name, fromcfg.name, sizeof(switchConfig[0].name));
|
||||
|
||||
if (IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
|
||||
// 6P switch is only on Horus (by default)
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) == 2) {
|
||||
strncpy(potName[2], potName[1], sizeof(potName[2]));
|
||||
potName[1][0] = '\0';
|
||||
if (Boards::getSwitchInfo(i, cstate.fromType).type > Boards::getSwitchInfo(idx, cstate.toType).type) {
|
||||
cstate.withComponentField(Boards::getSwitchName(i, cstate.fromType));
|
||||
RadioDataConversionState::LogField oldSWT(i, Boards::switchTypeToString(fromcfg.type));
|
||||
tocfg.type = Board::SWITCH_NOT_AVAILABLE;
|
||||
cstate.setConverted(oldSWT, RadioDataConversionState::LogField(i, Boards::switchTypeToString(fromcfg.type)));
|
||||
}
|
||||
else
|
||||
tocfg.type = fromcfg.type;
|
||||
|
||||
tocfg.inverted = fromcfg.inverted;
|
||||
|
||||
if (fromcfg.inputIdx != SWITCH_INPUTINDEX_NONE) {
|
||||
if (!Boards::getCapability(cstate.toType, Board::FlexSwitches) ||
|
||||
Boards::getInputIndex(Boards::getInputTag(fromcfg.inputIdx, cstate.fromType), Board::LVT_TAG, cstate.toType) < 0) {
|
||||
cstate.withComponentField(Boards::getSwitchName(i, cstate.fromType));
|
||||
RadioDataConversionState::LogField oldFT(i, Boards::getInputName(fromcfg.inputIdx, cstate.fromType));
|
||||
tocfg.inputIdx = SWITCH_INPUTINDEX_NONE;
|
||||
cstate.setConverted(oldFT, RadioDataConversionState::LogField(i, tr("None")));
|
||||
}
|
||||
else
|
||||
tocfg.inputIdx = fromcfg.inputIdx;
|
||||
}
|
||||
}
|
||||
else if (cstate.fromGS()->switchConfig[i].type != Board::SWITCH_NOT_AVAILABLE) {
|
||||
cstate.setInvalid(oldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS(cstate.toType)) {
|
||||
// No S3 pot on Taranis boards by default
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) > 2)
|
||||
strncpy(potName[1], potName[2], sizeof(potName[1]));
|
||||
|
||||
contrast = qBound<int>(getCurrentFirmware()->getCapability(MinContrast), contrast, getCurrentFirmware()->getCapability(MaxContrast));
|
||||
}
|
||||
|
||||
// TODO: Would be nice at this point to have GUI pause and ask the user to set up any custom hardware they have on the destination radio.
|
||||
|
||||
// Convert all global functions (do this after HW adjustments)
|
||||
for (int i=0; i<CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
for (int i = 0; i < CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
customFn[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
@@ -706,7 +775,7 @@ bool GeneralSettings::fix6POSCalibration()
|
||||
{
|
||||
bool changed = false;
|
||||
// Fix default 6POS calibration
|
||||
for (int i = CPN_MAX_STICKS; i < CPN_MAX_STICKS+CPN_MAX_POTS; i += 1) {
|
||||
for (int i = CPN_MAX_STICKS; i < CPN_MAX_STICKS + CPN_MAX_POTS; i += 1) {
|
||||
if ((potConfig[i-CPN_MAX_STICKS] == Board::POT_MULTIPOS_SWITCH) && (calibMid[i] == 0x200) && (calibSpanNeg[i] == 0x180) && (calibSpanPos[i] == 0x180)) {
|
||||
calibMid[i] = 773;;
|
||||
calibSpanNeg[i] = 5388;
|
||||
@@ -748,6 +817,78 @@ AbstractStaticItemModel * GeneralSettings::hatsModeItemModel(bool radio_setup)
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// Legacy mapping
|
||||
static const StringTagMappingTable potTypesConversionTable = {
|
||||
{std::to_string(Board::POT_NONE), std::to_string(Board::FLEX_NONE)},
|
||||
{std::to_string(Board::POT_WITH_DETENT), std::to_string(Board::FLEX_POT_CENTER)},
|
||||
{std::to_string(Board::POT_MULTIPOS_SWITCH), std::to_string(Board::FLEX_MULTIPOS)},
|
||||
{std::to_string(Board::POT_WITHOUT_DETENT), std::to_string(Board::FLEX_POT)},
|
||||
{std::to_string(Board::POT_SLIDER_WITH_DETENT), std::to_string(Board::FLEX_SLIDER)},
|
||||
};
|
||||
|
||||
static const StringTagMappingTable sliderTypesConversionTable = {
|
||||
{std::to_string(Board::SLIDER_NONE), std::to_string(Board::FLEX_NONE)},
|
||||
{std::to_string(Board::SLIDER_WITH_DETENT), std::to_string(Board::FLEX_SLIDER)},
|
||||
};
|
||||
|
||||
// This copies the pre v2.10 config to the new structs
|
||||
bool GeneralSettings::convertLegacyConfiguration(Board::Type board)
|
||||
{
|
||||
for (int i = 0; i < CPN_MAX_STICKS && i < Boards::getCapability(board, Board::Sticks); i++) {
|
||||
inputConfig[i].type = Board::AIT_STICK;
|
||||
strncpy(inputConfig[i].name, stickName[i], HARDWARE_NAME_LEN);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_POTS && i < Boards::getCapability(board, Board::Pots); i++) {
|
||||
int idx = Boards::getInputPotIndex(i, board);
|
||||
if (idx >= 0) {
|
||||
inputConfig[idx].type = Board::AIT_FLEX;
|
||||
strncpy(inputConfig[idx].name, potName[i], HARDWARE_NAME_LEN);
|
||||
int ft = std::stoi(DataHelpers::getStringTagMappingTag(potTypesConversionTable, potConfig[i]));
|
||||
if (ft > -1)
|
||||
inputConfig[idx].flexType = (Board::FlexType)ft;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_SLIDERS && i < Boards::getCapability(board, Board::Sliders); i++) {
|
||||
int idx = Boards::getInputSliderIndex(i, board);
|
||||
if (idx >= 0) {
|
||||
inputConfig[idx].type = Board::AIT_FLEX;
|
||||
strncpy(inputConfig[idx].name, sliderName[i], HARDWARE_NAME_LEN);
|
||||
int ft = std::stoi(DataHelpers::getStringTagMappingTag(sliderTypesConversionTable, sliderConfig[i]));
|
||||
if (ft > -1)
|
||||
inputConfig[idx].flexType = (Board::FlexType)ft;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_ANALOGS && i < Boards::getInputsCalibrated(board); i++) {
|
||||
inputConfig[i].calib.mid = calibMid[i];
|
||||
inputConfig[i].calib.spanNeg = calibSpanNeg[i];
|
||||
inputConfig[i].calib.spanPos = calibSpanPos[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_SWITCHES && i < Boards::getCapability(board, Board::Switches); i++) {
|
||||
switchConfig[i].type = (Board::SwitchType)swtchConfig[i];
|
||||
strncpy(switchConfig[i].name, swtchName[i], HARDWARE_NAME_LEN);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GeneralSettings::validateFlexSwitches()
|
||||
{
|
||||
for (int i = 0; i < CPN_MAX_SWITCHES_FLEX; i++) {
|
||||
if (inputConfig[switchConfig[i].inputIdx].flexType != Board::FLEX_SWITCH)
|
||||
switchConfig[i].inputIdx = -1;
|
||||
|
||||
int idx = Boards::getSwitchIndex(QString("FL%1").arg(i), Board::LVT_TAG);
|
||||
if (idx >= 0) {
|
||||
if (switchConfig[idx].type == Board::SWITCH_NOT_AVAILABLE)
|
||||
switchConfig[i].inputIdx = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TrainerMix
|
||||
*/
|
||||
|
||||
@@ -103,6 +103,7 @@ constexpr int TTS_LANGUAGE_LEN {2};
|
||||
constexpr int HARDWARE_NAME_LEN {3};
|
||||
constexpr int REGISTRATION_ID_LEN {8};
|
||||
constexpr int SELECTED_THEME_NAME_LEN {26};
|
||||
constexpr int SWITCH_INPUTINDEX_NONE {-1};
|
||||
|
||||
class GeneralSettings {
|
||||
Q_DECLARE_TR_FUNCTIONS(GeneralSettings)
|
||||
@@ -200,9 +201,6 @@ class GeneralSettings {
|
||||
char semver[8 + 1];
|
||||
unsigned int version;
|
||||
unsigned int variant;
|
||||
int calibMid[CPN_MAX_ANALOGS];
|
||||
int calibSpanNeg[CPN_MAX_ANALOGS];
|
||||
int calibSpanPos[CPN_MAX_ANALOGS];
|
||||
unsigned int currModelIndex;
|
||||
char currModelFilename[CURR_MODEL_FILENAME_LEN + 1];
|
||||
unsigned int contrast;
|
||||
@@ -287,13 +285,6 @@ class GeneralSettings {
|
||||
unsigned int backlightColor;
|
||||
bool modelQuickSelect;
|
||||
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||
char switchName[CPN_MAX_SWITCHES][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int switchConfig[CPN_MAX_SWITCHES];
|
||||
char stickName[CPN_MAX_STICKS][HARDWARE_NAME_LEN + 1];
|
||||
char potName[CPN_MAX_POTS][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int potConfig[CPN_MAX_POTS];
|
||||
char sliderName[CPN_MAX_SLIDERS][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int sliderConfig[CPN_MAX_SLIDERS];
|
||||
|
||||
char registrationId[REGISTRATION_ID_LEN + 1];
|
||||
int gyroMax;
|
||||
@@ -319,11 +310,74 @@ class GeneralSettings {
|
||||
bool modelCustomScriptsDisabled;
|
||||
bool modelTelemetryDisabled;
|
||||
|
||||
bool switchPositionAllowedTaranis(int index) const;
|
||||
bool switchSourceAllowedTaranis(int index) const;
|
||||
// v 2.10 ADC refactor
|
||||
// earlier version data is read into legacy structs to maintain older version compatibility
|
||||
// post reading the legacy structs are manipulated into the new structs
|
||||
// An opportunity was taken group related structs
|
||||
// Companion gui only references the new structs
|
||||
|
||||
// pre v2.10 legacy
|
||||
// TODO remove when importing and conversion no longer neceesary
|
||||
int calibMid[CPN_MAX_ANALOGS];
|
||||
int calibSpanNeg[CPN_MAX_ANALOGS];
|
||||
int calibSpanPos[CPN_MAX_ANALOGS];
|
||||
char swtchName[CPN_MAX_SWITCHES][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int swtchConfig[CPN_MAX_SWITCHES];
|
||||
char stickName[CPN_MAX_STICKS][HARDWARE_NAME_LEN + 1];
|
||||
char potName[CPN_MAX_POTS][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int potConfig[CPN_MAX_POTS];
|
||||
char sliderName[CPN_MAX_SLIDERS][HARDWARE_NAME_LEN + 1];
|
||||
unsigned int sliderConfig[CPN_MAX_SLIDERS];
|
||||
|
||||
// ===================================================================================
|
||||
// IMPORTANT: starting v2.10 this function MUST be called after importing non-yaml formats
|
||||
// yaml conversion is performed on the fly
|
||||
bool convertLegacyConfiguration(Board::Type board);
|
||||
// ===================================================================================
|
||||
|
||||
// default values are retrieved from the radio json file
|
||||
|
||||
struct InputCalib {
|
||||
int mid;
|
||||
int spanNeg;
|
||||
int spanPos;
|
||||
};
|
||||
|
||||
struct InputConfig {
|
||||
Board::AnalogInputType type;
|
||||
char name[HARDWARE_NAME_LEN + 1];
|
||||
Board::FlexType flexType;
|
||||
bool inverted;
|
||||
InputCalib calib;
|
||||
};
|
||||
|
||||
InputConfig inputConfig[CPN_MAX_INPUTS];
|
||||
|
||||
struct SwitchConfig {
|
||||
char name[HARDWARE_NAME_LEN + 1];
|
||||
Board::SwitchType type;
|
||||
bool inverted;
|
||||
int inputIdx; // used if switch tag = FLn, value -1 = none selected
|
||||
};
|
||||
|
||||
SwitchConfig switchConfig[CPN_MAX_SWITCHES];
|
||||
|
||||
bool switchPositionAllowed(int index) const;
|
||||
bool switchSourceAllowed(int index) const;
|
||||
|
||||
bool isInputAvailable(int index) const;
|
||||
bool isInputMultiPosPot(int index) const;
|
||||
bool isInputPot(int index) const;
|
||||
bool isInputSlider(int index) const;
|
||||
bool isInputStick(int index) const;
|
||||
bool isInputFlexSwitchAvailable(int index) const;
|
||||
bool isPotAvailable(int index) const;
|
||||
bool isSliderAvailable(int index) const;
|
||||
bool isSwitchAvailable(int index) const;
|
||||
bool isSwitchFlex(int index) const;
|
||||
bool isMultiPosPot(int index) const;
|
||||
bool unassignedInputFlexSwitches() const;
|
||||
|
||||
QString antennaModeToString() const;
|
||||
QString bluetoothModeToString() const;
|
||||
QString serialPortModeToString(int port_nr) const;
|
||||
@@ -347,4 +401,6 @@ class GeneralSettings {
|
||||
static AbstractStaticItemModel * stickDeadZoneItemModel();
|
||||
static AbstractStaticItemModel * uartSampleModeItemModel();
|
||||
static AbstractStaticItemModel * hatsModeItemModel(bool radio_setup = true);
|
||||
|
||||
void validateFlexSwitches();
|
||||
};
|
||||
|
||||
@@ -387,25 +387,28 @@ int ModelData::getChannelsMax(bool forceExtendedLimits) const
|
||||
}
|
||||
|
||||
bool ModelData::isFunctionSwitchPositionAvailable(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
|
||||
div_t qr = div(abs(index) - 1, 3);
|
||||
int fs = getFuncSwitchConfig(qr.quot);
|
||||
div_t qr = div(abs(index) - 1, 3);
|
||||
int fs = getFuncSwitchConfig(qr.quot);
|
||||
|
||||
if (qr.rem == 1) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return fs != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
if (qr.rem == 1) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return fs != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelData::isFunctionSwitchSourceAllowed(int index) const
|
||||
{
|
||||
return (int)getFuncSwitchConfig(index) != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
bool ModelData::isFunctionSwitchSourceAllowed(int index) const
|
||||
{
|
||||
if (index >= 0 && index < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches))
|
||||
return (int)getFuncSwitchConfig(index) != Board::SWITCH_NOT_AVAILABLE;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
@@ -421,9 +424,6 @@ bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
else if (swtch.type == SWITCH_TYPE_SENSOR) {
|
||||
return strlen(sensorData[index].label) > 0;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_FUNCTIONSWITCH) {
|
||||
return isFunctionSwitchPositionAvailable(index + 1);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
@@ -1500,15 +1500,14 @@ QString ModelData::thrTraceSrcToString() const
|
||||
|
||||
QString ModelData::thrTraceSrcToString(const int index) const
|
||||
{
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
const int pscnt = board.getCapability(Board::Pots) + board.getCapability(Board::Sliders);
|
||||
const Board::Type board = getCurrentBoard();
|
||||
const int pscnt = Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders);
|
||||
|
||||
if (index == 0)
|
||||
return tr("THR");
|
||||
else if (index <= pscnt)
|
||||
return board.getAnalogInputName(index + board.getCapability(Board::Sticks) - 1);
|
||||
else if (index <= pscnt + firmware->getCapability(Outputs))
|
||||
return Boards::getInputName(index + Boards::getCapability(board, Board::Sticks) - 1, board);
|
||||
else if (index <= pscnt + getCurrentFirmware()->getCapability(Outputs))
|
||||
return RawSource(SOURCE_TYPE_CH, index - pscnt - 1).toString(this);
|
||||
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
@@ -1516,18 +1515,18 @@ QString ModelData::thrTraceSrcToString(const int index) const
|
||||
|
||||
int ModelData::thrTraceSrcCount() const
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
const Board::Type board = firmware->getBoard();
|
||||
|
||||
return 1 + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + firmware->getCapability(Outputs);
|
||||
return 1 + Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders) + firmware->getCapability(Outputs);
|
||||
}
|
||||
|
||||
bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
const Board::Type board = getCurrentBoard();
|
||||
|
||||
if (index > 0 && index <= board.getCapability(Board::Pots) + board.getCapability(Board::Sliders))
|
||||
return RawSource(SOURCE_TYPE_STICK, index + board.getCapability(Board::Sticks) - 1).isAvailable(this, generalSettings, board.getBoardType());
|
||||
if (index > 0 && index <= Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders))
|
||||
return RawSource(SOURCE_TYPE_STICK, index + Boards::getCapability(board, Board::Sticks) - 1).isAvailable(this, generalSettings, board);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
@@ -1705,7 +1704,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
unsigned int ModelData::getFuncSwitchConfig(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
return Helpers::getBitmappedValue(functionSwitchConfig, index, 2);
|
||||
else
|
||||
return FUNC_SWITCH_CONFIG_NONE;
|
||||
@@ -1713,7 +1712,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
void ModelData::setFuncSwitchConfig(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
Helpers::setBitmappedValue(functionSwitchConfig, value, index, 2);
|
||||
}
|
||||
|
||||
@@ -1748,7 +1747,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
unsigned int ModelData::getFuncSwitchGroup(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
return Helpers::getBitmappedValue(functionSwitchGroup, index, 2);
|
||||
else
|
||||
return 0;
|
||||
@@ -1756,13 +1755,13 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
void ModelData::setFuncSwitchGroup(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
Helpers::setBitmappedValue(functionSwitchGroup, value, index, 2);
|
||||
}
|
||||
|
||||
unsigned int ModelData::getFuncSwitchAlwaysOnGroup(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES) {
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION) {
|
||||
unsigned int grp = getFuncSwitchGroup(index);
|
||||
unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches);
|
||||
return Helpers::getBitmappedValue(functionSwitchGroup, grp, 1, 2 * switchcnt);
|
||||
@@ -1773,7 +1772,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
void ModelData::setFuncSwitchAlwaysOnGroup(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES) {
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION) {
|
||||
unsigned int grp = getFuncSwitchGroup(index);
|
||||
unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches);
|
||||
Helpers::setBitmappedValue(functionSwitchGroup, value, grp, 1, 2 * switchcnt);
|
||||
@@ -1782,7 +1781,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
unsigned int ModelData::getFuncSwitchStart(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
return Helpers::getBitmappedValue(functionSwitchStartConfig, index, 2);
|
||||
else
|
||||
return FUNC_SWITCH_START_INACTIVE;
|
||||
@@ -1790,7 +1789,7 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
|
||||
void ModelData::setFuncSwitchStart(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
if (index < CPN_MAX_SWITCHES_FUNCTION)
|
||||
Helpers::setBitmappedValue(functionSwitchStartConfig, value, index, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,8 +163,8 @@ class ModelData {
|
||||
unsigned int switchWarningEnable;
|
||||
unsigned int thrTrimSwitch;
|
||||
unsigned int potsWarningMode;
|
||||
bool potsWarnEnabled[CPN_MAX_POTS + CPN_MAX_SLIDERS];
|
||||
int potsWarnPosition[CPN_MAX_POTS + CPN_MAX_SLIDERS];
|
||||
bool potsWarnEnabled[CPN_MAX_INPUTS];
|
||||
int potsWarnPosition[CPN_MAX_INPUTS];
|
||||
bool displayChecklist;
|
||||
|
||||
GVarData gvarData[CPN_MAX_GVARS];
|
||||
@@ -230,7 +230,7 @@ class ModelData {
|
||||
unsigned int functionSwitchGroup;
|
||||
unsigned int functionSwitchStartConfig;
|
||||
unsigned int functionSwitchLogicalState;
|
||||
char functionSwitchNames[CPN_MAX_FUNCTION_SWITCHES][HARDWARE_NAME_LEN + 1];
|
||||
char functionSwitchNames[CPN_MAX_SWITCHES_FUNCTION][HARDWARE_NAME_LEN + 1];
|
||||
|
||||
// Custom USB joytsick mapping
|
||||
unsigned int usbJoystickExtMode;
|
||||
|
||||
@@ -69,11 +69,11 @@ inline int MAX_SWITCHES_SOURCE(Board::Type board, int version)
|
||||
inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
|
||||
{
|
||||
if (IS_JUMPER_TPRO(board))
|
||||
return Boards::getCapability(board, Board::SwitchPositions);
|
||||
return Boards::getCapability(board, Board::SwitchesPositions);
|
||||
else if (IS_HORUS_OR_TARANIS(board))
|
||||
return MAX_SWITCHES(board, version) * 3;
|
||||
else
|
||||
return Boards::getCapability(board, Board::SwitchPositions);
|
||||
return Boards::getCapability(board, Board::SwitchesPositions);
|
||||
}
|
||||
|
||||
inline int MAX_FUNCTIONSWITCHES(Board::Type board, int version)
|
||||
@@ -196,7 +196,7 @@ inline int MAX_GYRO_ANALOGS(Board::Type board, int version)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Boards::getCapability(board, Board::GyroAnalogs);
|
||||
return Boards::getCapability(board, Board::GyroAxes);
|
||||
}
|
||||
|
||||
#define MAX_ROTARY_ENCODERS(board) 0
|
||||
@@ -3173,7 +3173,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
if (IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
for (int i=0; i<SWITCHES_CONFIG_SIZE(board, version) / 2; i++) {
|
||||
if (i < MAX_SWITCHES(board, version))
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.switchConfig[i]));
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.swtchConfig[i]));
|
||||
else
|
||||
internalField.Append(new SpareBitsField<2>(this));
|
||||
}
|
||||
@@ -3231,9 +3231,9 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
if (IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
for (int i = 0; i < MAX_SWITCHES(board, version); ++i) {
|
||||
if (version >= 220)
|
||||
internalField.Append(new CharField<3>(this, generalData.switchName[i], "Switch name"));
|
||||
internalField.Append(new CharField<3>(this, generalData.swtchName[i], "Switch name"));
|
||||
else
|
||||
internalField.Append(new ZCharField<3>(this, generalData.switchName[i], "Switch name"));
|
||||
internalField.Append(new ZCharField<3>(this, generalData.swtchName[i], "Switch name"));
|
||||
}
|
||||
for (int i = 0; i < CPN_MAX_STICKS; ++i) {
|
||||
if (version >= 220)
|
||||
@@ -3261,15 +3261,15 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
else if (IS_TARANIS(board)) {
|
||||
for (int i = 0; i < SWITCHES_CONFIG_SIZE(board, version) / 2; i++) {
|
||||
if (i < MAX_SWITCHES(board, version))
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.switchConfig[i]));
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.swtchConfig[i]));
|
||||
else
|
||||
internalField.Append(new SpareBitsField<2>(this));
|
||||
}
|
||||
for (int i = 0; i < MAX_SWITCHES(board, version); ++i) {
|
||||
if (version >= 220)
|
||||
internalField.Append(new CharField<3>(this, generalData.switchName[i], "Switch name"));
|
||||
internalField.Append(new CharField<3>(this, generalData.swtchName[i], "Switch name"));
|
||||
else
|
||||
internalField.Append(new ZCharField<3>(this, generalData.switchName[i], "Switch name"));
|
||||
internalField.Append(new ZCharField<3>(this, generalData.swtchName[i], "Switch name"));
|
||||
}
|
||||
for (int i = 0; i < CPN_MAX_STICKS; ++i) {
|
||||
if (version >= 220)
|
||||
|
||||
@@ -840,11 +840,6 @@ QString OpenTxFirmware::getCapabilityStr(::Capability capability)
|
||||
}
|
||||
}
|
||||
|
||||
QString OpenTxFirmware::getAnalogInputName(unsigned int index)
|
||||
{
|
||||
return Boards::getAnalogInputName(board, index);
|
||||
}
|
||||
|
||||
QTime OpenTxFirmware::getMaxTimerStart()
|
||||
{
|
||||
if (IS_HORUS_OR_TARANIS(board))
|
||||
@@ -1501,22 +1496,22 @@ void registerOpenTxFirmwares()
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS2A + AFHDS3);
|
||||
|
||||
/* 9XR-Pro */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("9xrpro"), Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
|
||||
addOpenTxArm9xOptions(firmware, false);
|
||||
registerOpenTxFirmware(firmware, true);
|
||||
|
||||
/* ar9x board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("ar9x"), Firmware::tr("9X with AR9X board"), BOARD_AR9X);
|
||||
addOpenTxArm9xOptions(firmware, true);
|
||||
//firmware->addOption("rtc", Firmware::tr("Optional RTC added"));
|
||||
//firmware->addOption("volume", Firmware::tr("i2c volume control added"));
|
||||
registerOpenTxFirmware(firmware, true);
|
||||
|
||||
/* Sky9x board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("sky9x"), Firmware::tr("9X with Sky9x board"), BOARD_SKY9X);
|
||||
addOpenTxArm9xOptions(firmware);
|
||||
registerOpenTxFirmware(firmware, true);
|
||||
// /* 9XR-Pro */
|
||||
// firmware = new OpenTxFirmware(FIRMWAREID("9xrpro"), Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
|
||||
// addOpenTxArm9xOptions(firmware, false);
|
||||
// registerOpenTxFirmware(firmware, true);
|
||||
//
|
||||
// /* ar9x board */
|
||||
// firmware = new OpenTxFirmware(FIRMWAREID("ar9x"), Firmware::tr("9X with AR9X board"), BOARD_AR9X);
|
||||
// addOpenTxArm9xOptions(firmware, true);
|
||||
// //firmware->addOption("rtc", Firmware::tr("Optional RTC added"));
|
||||
// //firmware->addOption("volume", Firmware::tr("i2c volume control added"));
|
||||
// registerOpenTxFirmware(firmware, true);
|
||||
//
|
||||
// /* Sky9x board */
|
||||
// firmware = new OpenTxFirmware(FIRMWAREID("sky9x"), Firmware::tr("9X with Sky9x board"), BOARD_SKY9X);
|
||||
// addOpenTxArm9xOptions(firmware);
|
||||
// registerOpenTxFirmware(firmware, true);
|
||||
|
||||
Firmware::sortRegisteredFirmwares();
|
||||
Firmware::setDefaultVariant(Firmware::getFirmwareForFlavour("tx16s"));
|
||||
|
||||
@@ -88,13 +88,15 @@ class OpenTxFirmware: public Firmware
|
||||
|
||||
public:
|
||||
OpenTxFirmware(const QString & id, OpenTxFirmware * parent):
|
||||
Firmware(parent, id, parent->getName(), parent->getBoard(), parent->getDownloadId(), parent->getSimulatorId())
|
||||
Firmware(parent, id, parent->getName(), parent->getBoard(),
|
||||
parent->getDownloadId(), parent->getSimulatorId(), parent->getHwDefnId())
|
||||
{
|
||||
setEEpromInterface(parent->getEEpromInterface());
|
||||
}
|
||||
|
||||
OpenTxFirmware(const QString & id, const QString & name, const Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()):
|
||||
Firmware(id, name, board, downloadId, simulatorId)
|
||||
OpenTxFirmware(const QString & id, const QString & name, const Board::Type board,
|
||||
const QString & downloadId = QString(), const QString & simulatorId = QString(), const QString & hwdefnId = QString()):
|
||||
Firmware(id, name, board, downloadId, simulatorId, hwdefnId)
|
||||
{
|
||||
// Note: these align with the radio NOT computer locales - TODO harmonise with ISO and one list!!!
|
||||
addLanguage("en");
|
||||
@@ -131,7 +133,11 @@ class OpenTxFirmware: public Firmware
|
||||
|
||||
virtual QString getCapabilityStr(Capability);
|
||||
|
||||
virtual QString getAnalogInputName(unsigned int index);
|
||||
virtual QString getAnalogInputName(unsigned int index)
|
||||
{
|
||||
qDebug() << "WARNING: Depreciate function called. Always returns empty string!";
|
||||
return QString();
|
||||
}
|
||||
|
||||
virtual QTime getMaxTimerStart();
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
|
||||
return result;
|
||||
}
|
||||
|
||||
QString RawSource::toString(const ModelData * model, const GeneralSettings * const generalSettings, Board::Type board) const
|
||||
QString RawSource::toString(const ModelData * model, const GeneralSettings * const generalSettings, Board::Type board, bool prefixCustomName) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN) {
|
||||
board = getCurrentBoard();
|
||||
@@ -146,12 +146,14 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
|
||||
static const QString rotary[] = { tr("REa"), tr("REb") };
|
||||
|
||||
if (index<0) {
|
||||
if (index < 0) {
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
QString result;
|
||||
int genAryIdx = 0;
|
||||
QString dfltName;
|
||||
QString custName;
|
||||
|
||||
switch (type) {
|
||||
case SOURCE_TYPE_NONE:
|
||||
return QString(CPN_STR_NONE_ITEM);
|
||||
@@ -168,17 +170,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return tr("LUA%1%2").arg(index / 16 + 1).arg(QChar('a' + index % 16));
|
||||
|
||||
case SOURCE_TYPE_STICK:
|
||||
if (generalSettings) {
|
||||
if (isPot(&genAryIdx))
|
||||
result = QString(generalSettings->potName[genAryIdx]);
|
||||
else if (isSlider(&genAryIdx))
|
||||
result = QString(generalSettings->sliderName[genAryIdx]);
|
||||
else if (isStick(&genAryIdx))
|
||||
result = QString(generalSettings->stickName[genAryIdx]);
|
||||
}
|
||||
if (result.trimmed().isEmpty())
|
||||
result = Boards::getAnalogInputName(board, index);
|
||||
return result;
|
||||
dfltName = Boards::getInputName(index, board);
|
||||
if (generalSettings)
|
||||
custName = QString(generalSettings->inputConfig[index].name).trimmed();
|
||||
return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName);
|
||||
|
||||
case SOURCE_TYPE_TRIM:
|
||||
return (Boards::getCapability(board, Board::NumTrims) == 2 ? CHECK_IN_ARRAY(trims2, index) : CHECK_IN_ARRAY(trims, index));
|
||||
@@ -193,18 +188,20 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return tr("MAX");
|
||||
|
||||
case SOURCE_TYPE_SWITCH:
|
||||
if (generalSettings)
|
||||
result = QString(generalSettings->switchName[index]).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = Boards::getSwitchInfo(board, index).name;
|
||||
return result;
|
||||
dfltName = Boards::getSwitchInfo(index, board).name.c_str();
|
||||
if (Boards::isSwitchFunc(index, board)) {
|
||||
if (model) {
|
||||
int fsindex = Boards::getSwitchTagNum(index, board) - 1;
|
||||
custName = QString(model->functionSwitchNames[fsindex]).trimmed();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (generalSettings) {
|
||||
custName = QString(generalSettings->switchConfig[index].name).trimmed();
|
||||
}
|
||||
}
|
||||
|
||||
case SOURCE_TYPE_FUNCTIONSWITCH:
|
||||
if (model)
|
||||
result = QString(model->functionSwitchNames[index]).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = tr("SW%1").arg(index + 1);
|
||||
return result;
|
||||
return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName);
|
||||
|
||||
case SOURCE_TYPE_CUSTOM_SWITCH:
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
|
||||
@@ -217,15 +214,16 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
|
||||
case SOURCE_TYPE_CH:
|
||||
if (model)
|
||||
return model->limitData[index].nameToString(index);
|
||||
else
|
||||
result = QString(model->limitData[index].nameToString(index)).trimmed();
|
||||
if (result.isEmpty())
|
||||
return LimitData().nameToString(index);
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_SPECIAL:
|
||||
if (index >= SOURCE_TYPE_SPECIAL_FIRST_TIMER && index <= SOURCE_TYPE_SPECIAL_LAST_TIMER) {
|
||||
if (model)
|
||||
result = model->timers[index - SOURCE_TYPE_SPECIAL_FIRST_TIMER].nameToString(index - SOURCE_TYPE_SPECIAL_FIRST_TIMER);
|
||||
else
|
||||
result = QString(model->timers[index - SOURCE_TYPE_SPECIAL_FIRST_TIMER].nameToString(index - SOURCE_TYPE_SPECIAL_FIRST_TIMER)).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = TimerData().nameToString(index - SOURCE_TYPE_SPECIAL_FIRST_TIMER);
|
||||
}
|
||||
else
|
||||
@@ -237,8 +235,8 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
{
|
||||
div_t qr = div(index, 3);
|
||||
if (model)
|
||||
result = model->sensorData[qr.quot].nameToString(qr.quot);
|
||||
else
|
||||
result = QString(model->sensorData[qr.quot].nameToString(qr.quot)).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = SensorData().nameToString(qr.quot);
|
||||
if (qr.rem)
|
||||
result += (qr.rem == 1 ? "-" : "+");
|
||||
@@ -247,9 +245,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
|
||||
case SOURCE_TYPE_GVAR:
|
||||
if (model)
|
||||
return model->gvarData[index].nameToString(index);
|
||||
else
|
||||
return GVarData().nameToString(index);
|
||||
result = QString(model->gvarData[index].nameToString(index)).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = GVarData().nameToString(index);
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_SPACEMOUSE:
|
||||
return tr("sm%1").arg(QChar('A' + index));
|
||||
@@ -259,46 +258,12 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
}
|
||||
}
|
||||
|
||||
bool RawSource::isStick(int * stickIndex, Board::Type board) const
|
||||
bool RawSource::isStick(Board::Type board) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN)
|
||||
board = getCurrentBoard();
|
||||
|
||||
if (type == SOURCE_TYPE_STICK && index < Boards::getCapability(board, Board::Sticks)) {
|
||||
if (stickIndex)
|
||||
*stickIndex = index;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RawSource::isPot(int * potsIndex, Board::Type board) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN)
|
||||
board = getCurrentBoard();
|
||||
|
||||
Boards b(board);
|
||||
if (type == SOURCE_TYPE_STICK &&
|
||||
index >= b.getCapability(Board::Sticks) &&
|
||||
index < b.getCapability(Board::Sticks) + b.getCapability(Board::Pots)) {
|
||||
if (potsIndex)
|
||||
*potsIndex = index - b.getCapability(Board::Sticks);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RawSource::isSlider(int * sliderIndex, Board::Type board) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN)
|
||||
board = getCurrentBoard();
|
||||
|
||||
Boards b(board);
|
||||
if (type == SOURCE_TYPE_STICK &&
|
||||
index >= b.getCapability(Board::Sticks) + b.getCapability(Board::Pots) &&
|
||||
index < b.getCapability(Board::Sticks) + b.getCapability(Board::Pots) + b.getCapability(Board::Sliders)) {
|
||||
if (sliderIndex)
|
||||
*sliderIndex = index - b.getCapability(Board::Sticks) - b.getCapability(Board::Pots);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -316,16 +281,12 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
|
||||
Boards b(board);
|
||||
|
||||
if (type == SOURCE_TYPE_STICK && index >= b.getCapability(Board::MaxAnalogs))
|
||||
if (type == SOURCE_TYPE_STICK && index >= b.getCapability(Board::Inputs))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_SWITCH && index >= b.getCapability(Board::Switches))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_FUNCTIONSWITCH)
|
||||
if (!model || index >= b.getCapability(Board::FunctionSwitches))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_SPECIAL && index >= SOURCE_TYPE_SPECIAL_FIRST_RESERVED && index <= SOURCE_TYPE_SPECIAL_LAST_RESERVED)
|
||||
return false;
|
||||
|
||||
@@ -334,7 +295,8 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
model->timers[index - SOURCE_TYPE_SPECIAL_FIRST_TIMER].isModeOff())
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_FUNCTIONSWITCH && !model->isFunctionSwitchSourceAllowed(index))
|
||||
if (type == SOURCE_TYPE_SWITCH && b.isSwitchFunc(index, board) &&
|
||||
!model->isFunctionSwitchSourceAllowed(b.getSwitchTagNum(index, board) - 1))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_VIRTUAL_INPUT && !model->isInputValid(index))
|
||||
@@ -357,13 +319,25 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
}
|
||||
|
||||
if (gs) {
|
||||
int gsIdx = 0;
|
||||
if (type == SOURCE_TYPE_STICK && ((isPot(&gsIdx) && !gs->isPotAvailable(gsIdx)) || (isSlider(&gsIdx) && !gs->isSliderAvailable(gsIdx))))
|
||||
return false;
|
||||
if (type == SOURCE_TYPE_STICK) {
|
||||
if (!gs->isInputAvailable(index))
|
||||
return false;
|
||||
if (gs->inputConfig[index].flexType == Board::FLEX_SWITCH)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == SOURCE_TYPE_SWITCH && IS_HORUS_OR_TARANIS(board) && !gs->switchSourceAllowedTaranis(index))
|
||||
if (type == SOURCE_TYPE_SWITCH && !b.isSwitchFunc(index, board) && IS_HORUS_OR_TARANIS(board) &&
|
||||
!gs->switchSourceAllowed(index))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (type == SOURCE_TYPE_STICK) {
|
||||
if (!Boards::isInputAvailable(index, board))
|
||||
return false;
|
||||
if (Boards::getInputInfo(index, board).flexType == Board::FLEX_SWITCH)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == SOURCE_TYPE_TRIM && index >= b.getCapability(Board::NumTrims))
|
||||
return false;
|
||||
@@ -380,81 +354,22 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
RawSource RawSource::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setItemType(tr("SRC"), 1);
|
||||
RadioDataConversionState::EventType evt = RadioDataConversionState::EVT_NONE;
|
||||
RadioDataConversionState::LogField oldData(index, toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType));
|
||||
|
||||
if (type == SOURCE_TYPE_STICK) {
|
||||
QStringList fromStickList(getStickList(cstate.fromBoard));
|
||||
QStringList toStickList(getStickList(cstate.toBoard));
|
||||
if (oldData.id < fromStickList.count())
|
||||
index = toStickList.indexOf(fromStickList.at(oldData.id));
|
||||
else
|
||||
index = -1;
|
||||
// perform forced mapping
|
||||
}
|
||||
|
||||
if (type == SOURCE_TYPE_SWITCH) {
|
||||
QStringList fromSwitchList(getSwitchList(cstate.fromBoard));
|
||||
QStringList toSwitchList(getSwitchList(cstate.toBoard));
|
||||
// index set to -1 if no match found
|
||||
if (oldData.id < fromSwitchList.count())
|
||||
index = toSwitchList.indexOf(fromSwitchList.at(oldData.id));
|
||||
else
|
||||
index = -1;
|
||||
// perform forced mapping
|
||||
if (index < 0) {
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on X7 board
|
||||
index = toSwitchList.indexOf("SD");
|
||||
if (index >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (IS_FAMILY_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on T12 board
|
||||
index = toSwitchList.indexOf("SD");
|
||||
if (index >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == SOURCE_TYPE_STICK)
|
||||
index = Boards::getInputIndex(Boards::getInputTag(oldData.id, cstate.fromType), Board::LVT_TAG, cstate.toType);
|
||||
else if (type == SOURCE_TYPE_SWITCH)
|
||||
index = Boards::getSwitchIndex(Boards::getSwitchTag(oldData.id, cstate.fromType), Board::LVT_TAG, cstate.toType);
|
||||
|
||||
// final validation (we do not pass model to isAvailable() because we don't know what has or hasn't been converted)
|
||||
if (index < 0 || !isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
if (index < 0 || !isAvailable(nullptr, cstate.toGS(), cstate.toType)) {
|
||||
cstate.setInvalid(oldData);
|
||||
// no source is safer than an invalid one
|
||||
clear();
|
||||
}
|
||||
else if (evt == RadioDataConversionState::EVT_CVRT) {
|
||||
cstate.setConverted(oldData, RadioDataConversionState::LogField(index, toString(cstate.toModel(), cstate.toGS(), cstate.toType)));
|
||||
}
|
||||
else if (oldData.id != index) {
|
||||
// provide info by default if anything changed
|
||||
cstate.setMoved(oldData, RadioDataConversionState::LogField(index, toString(cstate.toModel(), cstate.toGS(), cstate.toType)));
|
||||
clear(); // no source is safer than an invalid one
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QStringList RawSource::getStickList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::MaxAnalogs); i++) {
|
||||
ret.append(board.getAnalogInputName(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList RawSource::getSwitchList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::Switches); i++) {
|
||||
ret.append(board.getSwitchInfo(i).name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
StringTagMappingTable RawSource::getSpecialTypesLookupTable()
|
||||
{
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWSOURCE_H
|
||||
#define RAWSOURCE_H
|
||||
#pragma once
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
@@ -164,13 +163,13 @@ enum RawSourceType {
|
||||
SOURCE_TYPE_NONE,
|
||||
SOURCE_TYPE_VIRTUAL_INPUT,
|
||||
SOURCE_TYPE_LUA_OUTPUT,
|
||||
SOURCE_TYPE_STICK, // and POTS
|
||||
SOURCE_TYPE_STICK, // and POTS and Flex pots TODO rename to more appropriate
|
||||
SOURCE_TYPE_ROTARY_ENCODER,
|
||||
SOURCE_TYPE_TRIM,
|
||||
SOURCE_TYPE_MIN,
|
||||
SOURCE_TYPE_MAX,
|
||||
SOURCE_TYPE_SWITCH,
|
||||
SOURCE_TYPE_FUNCTIONSWITCH,
|
||||
SOURCE_TYPE_FUNCTIONSWITCH, // v2.10 only used for reading binary files
|
||||
SOURCE_TYPE_CUSTOM_SWITCH,
|
||||
SOURCE_TYPE_CYC,
|
||||
SOURCE_TYPE_PPM,
|
||||
@@ -267,17 +266,13 @@ class RawSource {
|
||||
}
|
||||
|
||||
RawSource convert(RadioDataConversionState & cstate);
|
||||
QString toString(const ModelData * model = NULL, const GeneralSettings * const generalSettings = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
QString toString(const ModelData * model = nullptr, const GeneralSettings * const generalSettings = nullptr, Board::Type board = Board::BOARD_UNKNOWN, bool prefixCustomName = true) const;
|
||||
RawSourceRange getRange(const ModelData * model, const GeneralSettings & settings, unsigned int flags=0) const;
|
||||
bool isStick(int * potsIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isPot(int * potsIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isSlider(int * sliderIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isStick(Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isTimeBased(Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isAvailable(const ModelData * const model = nullptr, const GeneralSettings * const gs = nullptr, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isSet() const { return type != SOURCE_TYPE_NONE || index != 0; }
|
||||
void clear() { type = SOURCE_TYPE_NONE; index = 0; }
|
||||
QStringList getStickList(Boards board) const;
|
||||
QStringList getSwitchList(Boards board) const;
|
||||
static StringTagMappingTable getSpecialTypesLookupTable();
|
||||
static StringTagMappingTable getCyclicLookupTable();
|
||||
|
||||
@@ -291,6 +286,6 @@ class RawSource {
|
||||
|
||||
RawSourceType type;
|
||||
int index;
|
||||
};
|
||||
|
||||
#endif // RAWSOURCE_H
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
QString RawSwitch::toString(Board::Type board, const GeneralSettings * const generalSettings, const ModelData * const modelData) const
|
||||
QString RawSwitch::toString(Board::Type board, const GeneralSettings * const generalSettings, const ModelData * const modelData, bool prefixCustomName) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN) {
|
||||
board = getCurrentBoard();
|
||||
@@ -37,14 +37,14 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
};
|
||||
|
||||
static const QString trimsSwitches[] = {
|
||||
tr("RudTrim Left"), tr("RudTrim Right"),
|
||||
tr("EleTrim Down"), tr("EleTrim Up"),
|
||||
tr("ThrTrim Down"), tr("ThrTrim Up"),
|
||||
tr("AilTrim Left"), tr("AilTrim Right"),
|
||||
tr("Trim 5 Down"), tr("Trim 5 Up"),
|
||||
tr("Trim 6 Down"), tr("Trim 6 Up"),
|
||||
tr("Trim 7 Down"), tr("Trim 7 Up"),
|
||||
tr("Trim 8 Down"), tr("Trim 8 Up")
|
||||
tr("Rud-"), tr("Rud+"),
|
||||
tr("Ele-"), tr("Ele+"),
|
||||
tr("Thr-"), tr("Thr+"),
|
||||
tr("Ail-"), tr("Ail+"),
|
||||
tr("T5-"), tr("T5+"),
|
||||
tr("T6-"), tr("T6+"),
|
||||
tr("T7-"), tr("T7+"),
|
||||
tr("T8-"), tr("T8+")
|
||||
};
|
||||
|
||||
static const QString trimsSwitches2[] = {
|
||||
@@ -71,16 +71,26 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
}
|
||||
else {
|
||||
QString swName;
|
||||
QString custName;
|
||||
div_t qr;
|
||||
switch(type) {
|
||||
case SWITCH_TYPE_SWITCH:
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
qr = div(index - 1, 3);
|
||||
if (generalSettings)
|
||||
swName = QString(generalSettings->switchName[qr.quot]).trimmed();
|
||||
if (swName.isEmpty())
|
||||
swName = Boards::getSwitchInfo(board, qr.quot).name;
|
||||
return swName + directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1);
|
||||
swName = Boards::getSwitchInfo(qr.quot, board).name.c_str();
|
||||
if (Boards::isSwitchFunc(qr.quot, board)) {
|
||||
if (modelData) {
|
||||
int fsindex = Boards::getSwitchTagNum(qr.quot, board) - 1;
|
||||
custName = QString(modelData->functionSwitchNames[fsindex]).trimmed();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (generalSettings) {
|
||||
custName = QString(generalSettings->switchConfig[qr.quot].name).trimmed();
|
||||
}
|
||||
}
|
||||
return DataHelpers::getCompositeName(swName, custName, prefixCustomName) +
|
||||
directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1);
|
||||
}
|
||||
else {
|
||||
return CHECK_IN_ARRAY(switches9X, index - 1);
|
||||
@@ -88,35 +98,26 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
if (modelData)
|
||||
return modelData->logicalSw[index].nameToString(index-1);
|
||||
return modelData->logicalSw[index].nameToString(index - 1);
|
||||
else
|
||||
return LogicalSwitchData().nameToString(index-1);
|
||||
|
||||
case SWITCH_TYPE_FUNCTIONSWITCH:
|
||||
if (!Boards::getCapability(board, Board::FunctionSwitches))
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
qr = div(index - 1, 3);
|
||||
if (modelData)
|
||||
swName = QString(modelData->functionSwitchNames[qr.quot]).trimmed();
|
||||
if (swName.isEmpty())
|
||||
swName = tr("SW%1").arg(qr.quot + 1);
|
||||
return swName + directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1);
|
||||
return LogicalSwitchData().nameToString(index - 1);
|
||||
|
||||
case SWITCH_TYPE_MULTIPOS_POT:
|
||||
if (!Boards::getCapability(board, Board::MultiposPotsPositions))
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
qr = div(index - 1, Boards::getCapability(board, Board::MultiposPotsPositions));
|
||||
if (generalSettings && qr.quot < (int)DIM(generalSettings->potConfig))
|
||||
swName = QString(generalSettings->potName[qr.quot]);
|
||||
if (generalSettings && qr.quot < (int)DIM(generalSettings->inputConfig))
|
||||
swName = QString(generalSettings->inputConfig[qr.quot].name);
|
||||
if (swName.isEmpty())
|
||||
swName = Boards::getAnalogInputName(board, qr.quot + Boards::getCapability(board, Board::Sticks));
|
||||
swName = Boards::getInputName(qr.quot, board);
|
||||
return swName + "_" + QString::number(qr.rem + 1);
|
||||
|
||||
case SWITCH_TYPE_TRIM:
|
||||
return (Boards::getCapability(board, Board::NumTrims) == 2 ? CHECK_IN_ARRAY(trimsSwitches2, index-1) : CHECK_IN_ARRAY(trimsSwitches, index-1));
|
||||
return (Boards::getCapability(board, Board::NumTrims) == 2 ?
|
||||
CHECK_IN_ARRAY(trimsSwitches2, index - 1) : CHECK_IN_ARRAY(trimsSwitches, index - 1));
|
||||
|
||||
case SWITCH_TYPE_ROTARY_ENCODER:
|
||||
return CHECK_IN_ARRAY(rotaryEncoders, index-1);
|
||||
return CHECK_IN_ARRAY(rotaryEncoders, index - 1);
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
return tr("ON");
|
||||
@@ -132,7 +133,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
if (modelData)
|
||||
return modelData->flightModeData[index-1].nameToString(index - 1);
|
||||
return modelData->flightModeData[index - 1].nameToString(index - 1);
|
||||
else
|
||||
return FlightModeData().nameToString(index - 1);
|
||||
|
||||
@@ -144,9 +145,9 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
if (modelData)
|
||||
return modelData->sensorData[index-1].nameToString(index-1);
|
||||
return modelData->sensorData[index - 1].nameToString(index - 1);
|
||||
else
|
||||
return SensorData().nameToString(index-1);
|
||||
return SensorData().nameToString(index - 1);
|
||||
|
||||
case SWITCH_TYPE_TELEMETRY:
|
||||
return tr("Telemetry");
|
||||
@@ -166,33 +167,36 @@ bool RawSwitch::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
board = getCurrentBoard();
|
||||
|
||||
Boards b(board);
|
||||
div_t sw;
|
||||
|
||||
if (type == SWITCH_TYPE_SWITCH && abs(index) > b.getCapability(Board::SwitchPositions))
|
||||
if (type == SWITCH_TYPE_SWITCH && abs(index) > b.getCapability(Board::SwitchesPositions))
|
||||
return false;
|
||||
|
||||
if (type == SWITCH_TYPE_FUNCTIONSWITCH) {
|
||||
if (!model || abs(index) > b.getCapability(Board::NumFunctionSwitchesPositions))
|
||||
return false;
|
||||
else if (!model->isFunctionSwitchPositionAvailable(abs(index)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == SWITCH_TYPE_TRIM && abs(index) > b.getCapability(Board::NumTrimSwitches))
|
||||
return false;
|
||||
|
||||
if (type == SWITCH_TYPE_SWITCH)
|
||||
sw = div(abs(index) - 1, 3);
|
||||
|
||||
if (gs) {
|
||||
if (type == SWITCH_TYPE_SWITCH && IS_HORUS_OR_TARANIS(board) && !gs->switchPositionAllowedTaranis(abs(index)))
|
||||
if (type == SWITCH_TYPE_SWITCH && !b.isSwitchFunc(sw.quot, board) && !gs->switchPositionAllowed(abs(index)))
|
||||
return false;
|
||||
|
||||
if (type == SWITCH_TYPE_MULTIPOS_POT) {
|
||||
int pot = div(abs(index) - 1, b.getCapability(Board::MultiposPotsPositions)).quot;
|
||||
if (!gs->isPotAvailable(pot) || gs->potConfig[pot] != Board::POT_MULTIPOS_SWITCH)
|
||||
int idx = div(abs(index) - 1, b.getCapability(Board::MultiposPotsPositions)).quot;
|
||||
if (!gs->isInputAvailable(idx) || gs->inputConfig[idx].flexType != Board::FLEX_MULTIPOS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (model && !model->isAvailable(*this))
|
||||
return false;
|
||||
if (model) {
|
||||
if (type == SWITCH_TYPE_SWITCH && b.isSwitchFunc(sw.quot, board)) {
|
||||
int fsindex = (((Boards::getSwitchTagNum(sw.quot, board) - 1) * 3) + sw.rem + 1) * ( index < 0 ? -1 : 1);
|
||||
return model->isFunctionSwitchPositionAvailable(fsindex);
|
||||
}
|
||||
else
|
||||
return model->isAvailable(*this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -203,67 +207,27 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
|
||||
return *this;
|
||||
|
||||
cstate.setItemType(tr("SW"), 2);
|
||||
RadioDataConversionState::EventType evt = RadioDataConversionState::EVT_NONE;
|
||||
RadioDataConversionState::LogField oldData(index, toString(cstate.fromType, cstate.fromGS(), cstate.fromModel()));
|
||||
|
||||
int newIdx = 0;
|
||||
|
||||
if (type == SWITCH_TYPE_SWITCH) {
|
||||
div_t swtch = div(abs(index) - 1, 3); // rawsource index
|
||||
QStringList fromSwitchList(getSwitchList(cstate.fromBoard));
|
||||
QStringList toSwitchList(getSwitchList(cstate.toBoard));
|
||||
// set to -1 if no match found
|
||||
if (swtch.quot < fromSwitchList.count())
|
||||
newIdx = toSwitchList.indexOf(fromSwitchList.at(swtch.quot));
|
||||
else
|
||||
newIdx = -1;
|
||||
// perform forced mapping
|
||||
if (newIdx < 0) {
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on X7 board
|
||||
newIdx = toSwitchList.indexOf("SD");
|
||||
if (newIdx >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (IS_FAMILY_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on T12 board
|
||||
newIdx = toSwitchList.indexOf("SD");
|
||||
if (newIdx >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
}
|
||||
div_t swtch = div(abs(index) - 1, 3);
|
||||
newIdx = Boards::getSwitchIndex(Boards::getSwitchTag(swtch.quot, cstate.fromType), Board::LVT_TAG, cstate.toType);
|
||||
|
||||
if (newIdx >= 0)
|
||||
index = (newIdx * 3 + 1 + swtch.rem) * (index < 0 ? -1 : 1);
|
||||
} // SWITCH_TYPE_SWITCH
|
||||
}
|
||||
|
||||
// final validation (we do not pass model to isAvailable() because we don't know what has or hasn't been converted)
|
||||
if (newIdx < 0 || !isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
if (newIdx < 0 || !isAvailable(nullptr, cstate.toGS(), cstate.toType)) {
|
||||
cstate.setInvalid(oldData);
|
||||
// no switch is safer than an invalid one
|
||||
clear();
|
||||
}
|
||||
else if (evt == RadioDataConversionState::EVT_CVRT) {
|
||||
cstate.setConverted(oldData, RadioDataConversionState::LogField(index, toString(cstate.toType, cstate.toGS(), cstate.toModel())));
|
||||
}
|
||||
else if (oldData.id != index) {
|
||||
// provide info by default if anything changed
|
||||
cstate.setMoved(oldData, RadioDataConversionState::LogField(index, toString(cstate.toType, cstate.toGS(), cstate.toModel())));
|
||||
clear(); // no switch is safer than an invalid one
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QStringList RawSwitch::getSwitchList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::Switches); i++) {
|
||||
ret.append(board.getSwitchInfo(i).name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
StringTagMappingTable RawSwitch::getRawSwitchTypesLookupTable()
|
||||
{
|
||||
@@ -272,7 +236,7 @@ StringTagMappingTable RawSwitch::getRawSwitchTypesLookupTable()
|
||||
tbl.insert(tbl.end(), {
|
||||
{std::to_string(SWITCH_TYPE_NONE), "NONE"},
|
||||
{std::to_string(SWITCH_TYPE_SWITCH), "Sxn"},
|
||||
{std::to_string(SWITCH_TYPE_FUNCTIONSWITCH), "Sxn"},
|
||||
{std::to_string(SWITCH_TYPE_FUNCTIONSWITCH), "FSn"},
|
||||
{std::to_string(SWITCH_TYPE_VIRTUAL), "Ln"},
|
||||
{std::to_string(SWITCH_TYPE_MULTIPOS_POT), "6Pn"},
|
||||
{std::to_string(SWITCH_TYPE_TRIM), "Trim"},
|
||||
|
||||
@@ -34,7 +34,7 @@ class RadioDataConversionState;
|
||||
enum RawSwitchType {
|
||||
SWITCH_TYPE_NONE,
|
||||
SWITCH_TYPE_SWITCH,
|
||||
SWITCH_TYPE_FUNCTIONSWITCH,
|
||||
SWITCH_TYPE_FUNCTIONSWITCH, // depreciated kept to preserve following enums
|
||||
SWITCH_TYPE_VIRTUAL,
|
||||
SWITCH_TYPE_MULTIPOS_POT,
|
||||
SWITCH_TYPE_TRIM,
|
||||
@@ -86,11 +86,10 @@ class RawSwitch {
|
||||
}
|
||||
|
||||
RawSwitch convert(RadioDataConversionState & cstate);
|
||||
QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL) const;
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = nullptr, const ModelData * const modelData = nullptr, bool prefixCustomName = true) const;
|
||||
bool isAvailable(const ModelData * const model = nullptr, const GeneralSettings * const gs = nullptr, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isSet() const { return type != SWITCH_TYPE_NONE || index != 0; }
|
||||
void clear() { type = SWITCH_TYPE_NONE; index = 0; }
|
||||
QStringList getSwitchList(Boards board) const;
|
||||
static StringTagMappingTable getRawSwitchTypesLookupTable();
|
||||
|
||||
bool operator== ( const RawSwitch& other) const {
|
||||
|
||||
@@ -25,38 +25,37 @@
|
||||
CalibrationPanel::CalibrationPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware):
|
||||
GeneralPanel(parent, generalSettings, firmware)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
int rows = Boards::getCapability(board, Board::MaxAnalogs);
|
||||
int maxrows = Boards::getInputsCalibrated();
|
||||
int maxinputs = Boards::getCapability(getCurrentBoard(), Board::Inputs);
|
||||
|
||||
QStringList headerLabels;
|
||||
headerLabels << "" << tr("Negative span") << tr("Mid value") << tr("Positive span");
|
||||
|
||||
TableLayout * tableLayout = new TableLayout(this, rows, headerLabels);
|
||||
TableLayout * tableLayout = new TableLayout(this, maxrows, headerLabels);
|
||||
|
||||
for (int i = 0, row = 0; i < rows; i++) {
|
||||
int col = 0;
|
||||
if (firmware->getCapability(HasFlySkyGimbals) &&
|
||||
i >= (Boards::getCapability(board, Board::Sticks) + 5) &&
|
||||
i < (Boards::getCapability(board, Board::Sticks) + 7))
|
||||
for (int i = 0, row = 0; i < maxinputs; i++) {
|
||||
if (!Boards::isInputCalibrated(i))
|
||||
continue;
|
||||
|
||||
GeneralSettings::InputCalib &calib = generalSettings.inputConfig[i].calib;
|
||||
int col = 0;
|
||||
row++;
|
||||
QLabel * label = new QLabel(this);
|
||||
label->setText(firmware->getAnalogInputName(i));
|
||||
label->setText(Boards::getInputName(i));
|
||||
tableLayout->addWidget(i, col++, label);
|
||||
|
||||
QLineEdit * leNeg = new QLineEdit(this);
|
||||
leNeg->setText(QString("%1").arg(generalSettings.calibSpanNeg[i]));
|
||||
leNeg->setText(QString("%1").arg(calib.spanNeg));
|
||||
leNeg->setReadOnly(true);
|
||||
tableLayout->addWidget(i, col++, leNeg);
|
||||
|
||||
QLineEdit * leMid = new QLineEdit(this);
|
||||
leMid->setText(QString("%1").arg(generalSettings.calibMid[i]));
|
||||
leMid->setText(QString("%1").arg(calib.mid));
|
||||
leMid->setReadOnly(true);
|
||||
tableLayout->addWidget(i, col++, leMid);
|
||||
|
||||
QLineEdit * lePos = new QLineEdit(this);
|
||||
lePos->setText(QString("%1").arg(generalSettings.calibSpanPos[i]));
|
||||
lePos->setText(QString("%1").arg(calib.spanPos));
|
||||
lePos->setReadOnly(true);
|
||||
tableLayout->addWidget(i, col++, lePos);
|
||||
}
|
||||
@@ -65,5 +64,5 @@ CalibrationPanel::CalibrationPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
tableLayout->resizeColumnsToContents();
|
||||
tableLayout->setColumnWidth(0, QString(15, ' '));
|
||||
tableLayout->pushColumnsLeft(headerLabels.count());
|
||||
tableLayout->pushRowsUp(rows + 1);
|
||||
tableLayout->pushRowsUp(maxrows + 1);
|
||||
}
|
||||
|
||||
@@ -114,17 +114,18 @@ void GeneralEdit::on_tabWidget_currentChanged(int index)
|
||||
void GeneralEdit::on_calretrieve_PB_clicked()
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
int profile_id=ui->profile_CB->itemData(ui->profile_CB->currentIndex()).toInt();
|
||||
QString calib=g.profile[profile_id].stickPotCalib();
|
||||
int potsnum=getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders);
|
||||
int numSwPots=getBoardCapability(board, Board::Switches)+getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders);
|
||||
int profile_id = ui->profile_CB->itemData(ui->profile_CB->currentIndex()).toInt();
|
||||
QString calib = g.profile[profile_id].stickPotCalib();
|
||||
int ttlSticks = getBoardCapability(board, Board::Sticks);
|
||||
int ttlInputs = getBoardCapability(board, Board::Inputs);
|
||||
int ttlSwitches = getBoardCapability(board, Board::Switches);
|
||||
if (calib.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
QString trainercalib = g.profile[profile_id].trainerCalib();
|
||||
QString hwtypes = g.profile[profile_id].controlTypes();
|
||||
QString controlNames=g.profile[profile_id].controlNames();
|
||||
QString controlNames = g.profile[profile_id].controlNames();
|
||||
int8_t txVoltageCalibration = (int8_t)g.profile[profile_id].txVoltageCalibration();
|
||||
int8_t txCurrentCalibration = (int8_t)g.profile[profile_id].txCurrentCalibration();
|
||||
int8_t PPM_Multiplier = (int8_t)g.profile[profile_id].ppmMultiplier();
|
||||
@@ -136,74 +137,60 @@ void GeneralEdit::on_calretrieve_PB_clicked()
|
||||
QString SpeakerSet = g.profile[profile_id].speaker();
|
||||
QString CountrySet = g.profile[profile_id].countryCode();
|
||||
|
||||
if ((calib.length()==(CPN_MAX_STICKS+potsnum)*12) && (trainercalib.length()==16)) {
|
||||
if ((calib.length() == (Boards::getInputsCalibrated() * 12)) && (trainercalib.length() == 16)) {
|
||||
QString Byte;
|
||||
int16_t byte16;
|
||||
bool ok;
|
||||
for (int i=0; i<(CPN_MAX_STICKS+potsnum); i++) {
|
||||
Byte=calib.mid(i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok) generalSettings.calibMid[i]=byte16;
|
||||
Byte=calib.mid(4+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok) generalSettings.calibSpanNeg[i]=byte16;
|
||||
Byte=calib.mid(8+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok) generalSettings.calibSpanPos[i]=byte16;
|
||||
for (int i = 0; i < ttlInputs; i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
Byte = calib.mid(i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) generalSettings.inputConfig[i].calib.mid = byte16;
|
||||
Byte = calib.mid(4 + i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) generalSettings.inputConfig[i].calib.spanNeg = byte16;
|
||||
Byte = calib.mid(8 + i * 12, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) generalSettings.inputConfig[i].calib.spanPos = byte16;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<4; i++) {
|
||||
Byte=trainercalib.mid(i*4,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok) generalSettings.trainer.calib[i]=byte16;
|
||||
for (int i = 0; i < ttlSticks; i++) {
|
||||
Byte = trainercalib.mid(i * 4, 4);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
if (ok) generalSettings.trainer.calib[i] = byte16;
|
||||
}
|
||||
generalSettings.txCurrentCalibration=txCurrentCalibration;
|
||||
generalSettings.txVoltageCalibration=txVoltageCalibration;
|
||||
generalSettings.txCurrentCalibration = txCurrentCalibration;
|
||||
generalSettings.txVoltageCalibration = txVoltageCalibration;
|
||||
generalSettings.vBatWarn=vBatWarn;
|
||||
if (getCurrentFirmware()->getCapability(HasBatMeterRange)) {
|
||||
generalSettings.vBatMin = (int8_t) g.profile[profile_id].vBatMin();
|
||||
generalSettings.vBatMax = (int8_t) g.profile[profile_id].vBatMax();
|
||||
}
|
||||
generalSettings.PPM_Multiplier=PPM_Multiplier;
|
||||
generalSettings.PPM_Multiplier = PPM_Multiplier;
|
||||
} else {
|
||||
QMessageBox::critical(this, CPN_STR_TTL_WARNING, tr("Wrong data in profile, radio calibration was not retrieved"));
|
||||
}
|
||||
if (hwtypes.length()==numSwPots) {
|
||||
if (hwtypes.length() == ttlSwitches + ttlInputs) {
|
||||
QString Byte;
|
||||
int16_t byte16;
|
||||
QByteArray qba;
|
||||
int16_t offset;
|
||||
bool ok;
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
qba = controlNames.mid(3*i,3).toLatin1();
|
||||
strcpy(generalSettings.stickName[i], qba.data());
|
||||
}
|
||||
for (int i=0; i<getBoardCapability(board, Board::Switches); i++) {
|
||||
for (int i = 0; i < ttlSwitches; i++) {
|
||||
Byte = hwtypes.mid(i, 1);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
qba=controlNames.mid(3*(i+CPN_MAX_STICKS),3).toLatin1();
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
qba = controlNames.mid(3 * i, 3).toLatin1();
|
||||
if (ok) {
|
||||
generalSettings.switchConfig[i]=byte16;
|
||||
strcpy(generalSettings.switchName[i], qba.data());
|
||||
generalSettings.switchConfig[i].type = (Board::SwitchType)byte16;
|
||||
strcpy(generalSettings.switchConfig[i].name, qba.data());
|
||||
}
|
||||
}
|
||||
offset = getBoardCapability(board, Board::Switches);
|
||||
for (int i=0; i<getBoardCapability(board, Board::Pots); i++) {
|
||||
Byte=hwtypes.mid(i+offset,1);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
qba=controlNames.mid(3*(i+CPN_MAX_STICKS+offset),3).toLatin1();
|
||||
for (int i = 0; i < getBoardCapability(board, Board::Inputs); i++) {
|
||||
Byte = hwtypes.mid(i + ttlSwitches, 1);
|
||||
byte16 = (int16_t)Byte.toInt(&ok, 16);
|
||||
qba = controlNames.mid(3 * (i + ttlSwitches), 3).toLatin1();
|
||||
if (ok) {
|
||||
generalSettings.potConfig[i]=byte16;
|
||||
strcpy(generalSettings.potName[i], qba.data());
|
||||
}
|
||||
}
|
||||
offset += getBoardCapability(board, Board::Pots);
|
||||
for (int i=0; i<getBoardCapability(board, Board::Sliders); i++) {
|
||||
Byte=hwtypes.mid(i+offset,1);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
qba=controlNames.mid(3*(i+CPN_MAX_STICKS+offset),3).toLatin1();
|
||||
if (ok) {
|
||||
generalSettings.sliderConfig[i]=byte16;
|
||||
strcpy(generalSettings.sliderName[i], qba.data());
|
||||
generalSettings.inputConfig[i].flexType = (Board::FlexType)byte16;
|
||||
strcpy(generalSettings.inputConfig[i].name, qba.data());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -215,36 +202,36 @@ void GeneralEdit::on_calretrieve_PB_clicked()
|
||||
int8_t byte8;
|
||||
QString chars;
|
||||
bool ok;
|
||||
byte8=(int8_t)DisplaySet.mid(0,2).toInt(&ok,16);
|
||||
if (ok) generalSettings.optrexDisplay=(byte8==1 ? true : false);
|
||||
byte8u=(uint8_t)DisplaySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.contrast=byte8u;
|
||||
byte8u=(uint8_t)DisplaySet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.backlightBright=byte8u;
|
||||
byte8=(int8_t)BeeperSet.mid(0,2).toUInt(&ok,16);
|
||||
byte8 = (int8_t)DisplaySet.mid(0,2).toInt(&ok, 16);
|
||||
if (ok) generalSettings.optrexDisplay = (byte8 == 1 ? true : false);
|
||||
byte8u = (uint8_t)DisplaySet.mid(2,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.contrast = byte8u;
|
||||
byte8u = (uint8_t)DisplaySet.mid(4,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.backlightBright = byte8u;
|
||||
byte8 = (int8_t)BeeperSet.mid(0,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.beeperMode = (GeneralSettings::BeeperMode)byte8;
|
||||
byte8=(int8_t)BeeperSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok) generalSettings.beeperLength=byte8;
|
||||
byte8=(int8_t)HapticSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.hapticMode=(GeneralSettings::BeeperMode)byte8;
|
||||
byte8=(int8_t)HapticSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok) generalSettings.hapticStrength=byte8;
|
||||
byte8=(int8_t)HapticSet.mid(4,2).toInt(&ok,16);
|
||||
if (ok) generalSettings.hapticLength=byte8;
|
||||
byte8u=(uint8_t)SpeakerSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.speakerMode=byte8u;
|
||||
byte8u=(uint8_t)SpeakerSet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.speakerPitch=byte8u;
|
||||
byte8u=(uint8_t)SpeakerSet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.speakerVolume=byte8u;
|
||||
if (CountrySet.length()==6) {
|
||||
byte8u=(uint8_t)CountrySet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.countryCode=byte8u;
|
||||
byte8u=(uint8_t)CountrySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok) generalSettings.imperial=byte8u;
|
||||
chars=CountrySet.mid(4,2);
|
||||
generalSettings.ttsLanguage[0]=chars[0].toLatin1();
|
||||
generalSettings.ttsLanguage[1]=chars[1].toLatin1();
|
||||
byte8 = (int8_t)BeeperSet.mid(2,2).toInt(&ok, 16);
|
||||
if (ok) generalSettings.beeperLength = byte8;
|
||||
byte8 = (int8_t)HapticSet.mid(0,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.hapticMode = (GeneralSettings::BeeperMode)byte8;
|
||||
byte8 = (int8_t)HapticSet.mid(2,2).toInt(&ok, 16);
|
||||
if (ok) generalSettings.hapticStrength = byte8;
|
||||
byte8 = (int8_t)HapticSet.mid(4,2).toInt(&ok, 16);
|
||||
if (ok) generalSettings.hapticLength = byte8;
|
||||
byte8u = (uint8_t)SpeakerSet.mid(0,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.speakerMode = byte8u;
|
||||
byte8u = (uint8_t)SpeakerSet.mid(2,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.speakerPitch = byte8u;
|
||||
byte8u = (uint8_t)SpeakerSet.mid(4,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.speakerVolume = byte8u;
|
||||
if (CountrySet.length() == 6) {
|
||||
byte8u = (uint8_t)CountrySet.mid(0,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.countryCode = byte8u;
|
||||
byte8u = (uint8_t)CountrySet.mid(2,2).toUInt(&ok, 16);
|
||||
if (ok) generalSettings.imperial = byte8u;
|
||||
chars = CountrySet.mid(4,2);
|
||||
generalSettings.ttsLanguage[0] = chars[0].toLatin1();
|
||||
generalSettings.ttsLanguage[1] = chars[1].toLatin1();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -257,18 +244,18 @@ void GeneralEdit::on_calretrieve_PB_clicked()
|
||||
|
||||
void GeneralEdit::on_calstore_PB_clicked()
|
||||
{
|
||||
int profile_id=ui->profile_CB->itemData(ui->profile_CB->currentIndex()).toInt();
|
||||
Board::Type board = getCurrentBoard();
|
||||
int profile_id = ui->profile_CB->itemData(ui->profile_CB->currentIndex()).toInt();
|
||||
|
||||
QString name=g.profile[profile_id].name();
|
||||
int potsnum=getBoardCapability(getCurrentBoard(), Board::Pots)+getBoardCapability(getCurrentBoard(), Board::Sliders);
|
||||
QString name = g.profile[profile_id].name();
|
||||
if (name.isEmpty()) {
|
||||
ui->calstore_PB->setDisabled(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
QString calib=g.profile[profile_id].stickPotCalib();
|
||||
QString hwtypes=g.profile[profile_id].controlTypes();
|
||||
QString controlNames=g.profile[profile_id].controlNames();
|
||||
QString calib = g.profile[profile_id].stickPotCalib();
|
||||
QString hwtypes = g.profile[profile_id].controlTypes();
|
||||
QString controlNames = g.profile[profile_id].controlNames();
|
||||
if (!(calib.isEmpty())) {
|
||||
int ret = QMessageBox::question(this, CPN_STR_APP_NAME,
|
||||
tr("Do you want to store calibration in %1 profile<br>overwriting existing calibration?").arg(name) ,
|
||||
@@ -277,34 +264,34 @@ void GeneralEdit::on_calstore_PB_clicked()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ttlSticks = getBoardCapability(board, Board::Sticks);
|
||||
int ttlInputs = getBoardCapability(board, Board::Inputs);
|
||||
int ttlSwitches = getBoardCapability(board, Board::Switches);
|
||||
calib.clear();
|
||||
for (int i=0; i< (CPN_MAX_STICKS+potsnum); i++) {
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.calibMid[i], 4, 16, QChar('0')));
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.calibSpanNeg[i], 4, 16, QChar('0')));
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.calibSpanPos[i], 4, 16, QChar('0')));
|
||||
|
||||
for (int i = 0; i < ttlInputs; i++) {
|
||||
if (Boards::isInputCalibrated(i)) {
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.inputConfig[i].calib.mid, 4, 16, QChar('0')));
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.inputConfig[i].calib.spanNeg, 4, 16, QChar('0')));
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.inputConfig[i].calib.spanPos, 4, 16, QChar('0')));
|
||||
}
|
||||
}
|
||||
g.profile[profile_id].stickPotCalib( calib );
|
||||
calib.clear();
|
||||
for (int i=0; i< 4; i++) {
|
||||
for (int i = 0; i < ttlSticks; i++) {
|
||||
calib.append(QString("%1").arg((uint16_t)generalSettings.trainer.calib[i], 4, 16, QChar('0')));
|
||||
}
|
||||
g.profile[profile_id].trainerCalib( calib );
|
||||
hwtypes.clear();
|
||||
controlNames.clear();
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
controlNames.append(QString("%1").arg(generalSettings.stickName[i], -3));
|
||||
for (int i = 0; i < ttlSwitches; i++) {
|
||||
hwtypes.append(QString("%1").arg((uint16_t)generalSettings.switchConfig[i].type, 1));
|
||||
controlNames.append(QString("%1").arg(generalSettings.switchConfig[i].name, -3));
|
||||
}
|
||||
for (int i=0; i<getBoardCapability(getCurrentBoard(), Board::Switches); i++) {
|
||||
hwtypes.append(QString("%1").arg((uint16_t)generalSettings.switchConfig[i], 1));
|
||||
controlNames.append(QString("%1").arg(generalSettings.switchName[i], -3));
|
||||
}
|
||||
for (int i=0; i<getBoardCapability(getCurrentBoard(), Board::Pots); i++) {
|
||||
hwtypes.append(QString("%1").arg((uint16_t)generalSettings.potConfig[i], 1));
|
||||
controlNames.append(QString("%1").arg(generalSettings.potName[i], -3));
|
||||
}
|
||||
for (int i=0; i<getBoardCapability(getCurrentBoard(), Board::Sliders); i++) {
|
||||
hwtypes.append(QString("%1").arg((uint16_t)generalSettings.sliderConfig[i], 1));
|
||||
controlNames.append(QString("%1").arg(generalSettings.sliderName[i], -3));
|
||||
for (int i = 0; i < ttlInputs; i++) {
|
||||
hwtypes.append(QString("%1").arg((uint16_t)generalSettings.inputConfig[i].flexType, 1));
|
||||
controlNames.append(QString("%1").arg(generalSettings.inputConfig[i].name, -3));
|
||||
}
|
||||
g.profile[profile_id].controlTypes( hwtypes );
|
||||
g.profile[profile_id].controlNames( controlNames );
|
||||
|
||||
@@ -26,60 +26,75 @@
|
||||
#include "autocheckbox.h"
|
||||
#include "autospinbox.h"
|
||||
#include "autodoublespinbox.h"
|
||||
#include "autobitmappedcombobox.h"
|
||||
#include "autobitmappedcheckbox.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QGridLayout>
|
||||
#include <QFrame>
|
||||
|
||||
constexpr char FIM_SWITCHTYPE2POS[] {"Switch Type 2 Pos"};
|
||||
constexpr char FIM_SWITCHTYPE3POS[] {"Switch Type 3 Pos"};
|
||||
constexpr char FIM_INTERNALMODULES[] {"Internal Modules"};
|
||||
constexpr char FIM_AUX1SERIALMODES[] {"AUX1 Modes"};
|
||||
constexpr char FIM_AUX2SERIALMODES[] {"AUX2 Modes"};
|
||||
constexpr char FIM_VCPSERIALMODES[] {"VCP Modes"};
|
||||
constexpr char FIM_SWITCHTYPENONE[] {"Switch Type None"};
|
||||
constexpr char FIM_SWITCHTYPE2POS[] {"Switch Type 2 Pos"};
|
||||
constexpr char FIM_SWITCHTYPE3POS[] {"Switch Type 3 Pos"};
|
||||
constexpr char FIM_INTERNALMODULES[] {"Internal Modules"};
|
||||
constexpr char FIM_AUX1SERIALMODES[] {"AUX1 Modes"};
|
||||
constexpr char FIM_AUX2SERIALMODES[] {"AUX2 Modes"};
|
||||
constexpr char FIM_VCPSERIALMODES[] {"VCP Modes"};
|
||||
constexpr char FIM_FLEXSWITCHES[] {"Flex Switches"};
|
||||
constexpr char FIM_FLEXTYPE_SWITCH[] {"Flex Type Switch"};
|
||||
constexpr char FIM_FLEXTYPE_NOSWITCH[] {"Flex Type No Switch"};
|
||||
|
||||
class ExclusiveComboGroup: public QObject
|
||||
{
|
||||
static constexpr auto _role = Qt::UserRole + 500;
|
||||
public:
|
||||
ExclusiveComboGroup(QObject *parent, std::function<bool(const QVariant&)> filter) :
|
||||
QObject(parent), filter(std::move(filter))
|
||||
{
|
||||
}
|
||||
|
||||
QList<QComboBox*> combos;
|
||||
std::function<bool(const QVariant&)> filter;
|
||||
typedef QList<QComboBox*> ComboBoxes;
|
||||
|
||||
public:
|
||||
ExclusiveComboGroup(QObject *parent, std::function<bool(const QVariant&)> filter) :
|
||||
QObject(parent), filter(std::move(filter))
|
||||
{
|
||||
}
|
||||
ComboBoxes* getComboBoxes()
|
||||
{
|
||||
return &combos;
|
||||
}
|
||||
|
||||
void addCombo(QComboBox *comboBox)
|
||||
{
|
||||
connect(comboBox, QOverload<int>::of(&QComboBox::activated),
|
||||
[=](int index) { this->handleActivated(comboBox, index); });
|
||||
combos.append(comboBox);
|
||||
}
|
||||
void addCombo(QComboBox *comboBox)
|
||||
{
|
||||
connect(comboBox, QOverload<int>::of(&QComboBox::activated),
|
||||
[=](int index) { this->handleActivated(comboBox, index); });
|
||||
combos.append(comboBox);
|
||||
}
|
||||
|
||||
void handleActivated(QComboBox* target, int index) {
|
||||
auto data = target->itemData(index);
|
||||
auto targetidx = combos.indexOf(target);
|
||||
for (auto combo : combos) {
|
||||
if (target == combo) continue;
|
||||
auto view = dynamic_cast<QListView*>(combo->view());
|
||||
Q_ASSERT(view);
|
||||
void handleActivated(QComboBox* target, int index) {
|
||||
auto data = target->itemData(index);
|
||||
auto targetidx = combos.indexOf(target);
|
||||
for (auto combo : combos) {
|
||||
if (target == combo) continue;
|
||||
auto view = dynamic_cast<QListView*>(combo->view());
|
||||
Q_ASSERT(view);
|
||||
|
||||
auto previous = combo->findData(targetidx, _role);
|
||||
if (previous >= 0) {
|
||||
view->setRowHidden(previous, false);
|
||||
combo->setItemData(previous, QVariant(), _role);
|
||||
}
|
||||
if (!filter(data)) {
|
||||
auto idx = combo->findData(data);
|
||||
if (idx >= 0) {
|
||||
view->setRowHidden(idx, true);
|
||||
combo->setItemData(idx, targetidx, _role);
|
||||
auto previous = combo->findData(targetidx, _role);
|
||||
if (previous >= 0) {
|
||||
view->setRowHidden(previous, false);
|
||||
combo->setItemData(previous, QVariant(), _role);
|
||||
}
|
||||
if (!filter(data)) {
|
||||
auto idx = combo->findData(data);
|
||||
if (idx >= 0) {
|
||||
view->setRowHidden(idx, true);
|
||||
combo->setItemData(idx, targetidx, _role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr auto _role = Qt::UserRole + 500;
|
||||
|
||||
ComboBoxes combos;
|
||||
std::function<bool(const QVariant&)> filter;
|
||||
|
||||
};
|
||||
|
||||
HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
|
||||
@@ -88,13 +103,17 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
editorItemModels(sharedItemModels),
|
||||
serialPortUSBVCP(nullptr),
|
||||
params(new QList<QWidget *>),
|
||||
row(0)
|
||||
row(0),
|
||||
exclFlexSwitchesGroup(nullptr)
|
||||
{
|
||||
editorItemModels->registerItemModel(Boards::potTypeItemModel());
|
||||
editorItemModels->registerItemModel(Boards::sliderTypeItemModel());
|
||||
int id = editorItemModels->registerItemModel(Boards::switchTypeItemModel());
|
||||
|
||||
tabFilteredModels = new FilteredItemModelFactory();
|
||||
|
||||
int id = editorItemModels->registerItemModel(Boards::flexTypeItemModel());
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id), Board::FlexTypeContextSwitch), FIM_FLEXTYPE_SWITCH);
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id), Board::FlexTypeContextNoSwitch), FIM_FLEXTYPE_NOSWITCH);
|
||||
|
||||
id = editorItemModels->registerItemModel(Boards::switchTypeItemModel());
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id), Board::SwitchTypeContextNone), FIM_SWITCHTYPENONE);
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id), Board::SwitchTypeContext2Pos), FIM_SWITCHTYPE2POS);
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id), Board::SwitchTypeContext3Pos), FIM_SWITCHTYPE3POS);
|
||||
|
||||
@@ -110,13 +129,15 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
id = editorItemModels->registerItemModel(ModuleData::internalModuleItemModel());
|
||||
tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id)), FIM_INTERNALMODULES);
|
||||
|
||||
editorItemModels->addItemModel(AbstractItemModel::IMID_FlexSwitches);
|
||||
|
||||
grid = new QGridLayout(this);
|
||||
int count;
|
||||
|
||||
addSection(tr("Sticks"));
|
||||
addSection(tr("Axis"));
|
||||
|
||||
count = Boards::getCapability(board, Board::Sticks);
|
||||
if (count) {
|
||||
if (count > 0) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
addStick(i);
|
||||
}
|
||||
@@ -131,28 +152,33 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
addParams();
|
||||
}
|
||||
|
||||
count = Boards::getCapability(board, Board::Pots);
|
||||
count -= firmware->getCapability(HasFlySkyGimbals) ? 2 : 0;
|
||||
count = Boards::getCapability(board, Board::Inputs);
|
||||
|
||||
if (count > 0) {
|
||||
addSection(tr("Pots"));
|
||||
for (int i = 0; i < count; i++) {
|
||||
addPot(i);
|
||||
}
|
||||
}
|
||||
|
||||
count = Boards::getCapability(board, Board::Sliders);
|
||||
if (count) {
|
||||
addSection(tr("Sliders"));
|
||||
for (int i = 0; i < count; i++) {
|
||||
addSlider(i);
|
||||
for (int i = Boards::getCapability(board, Board::Sticks); i < count; i++) {
|
||||
if (Boards::isInputConfigurable(i, board))
|
||||
addFlex(i);
|
||||
}
|
||||
}
|
||||
|
||||
count = Boards::getCapability(board, Board::Switches);
|
||||
|
||||
if (count) {
|
||||
// All values except -1 (None) are mutually exclusive
|
||||
exclFlexSwitchesGroup = new ExclusiveComboGroup(
|
||||
this, [=](const QVariant &value) { return value == -1; });
|
||||
|
||||
addSection(tr("Switches"));
|
||||
for (int i = 0; i < count; i++) {
|
||||
addSwitch(i);
|
||||
for (int i = 0; i < count && i < CPN_MAX_SWITCHES; i++) {
|
||||
if (Boards::isSwitchConfigurable(i, board))
|
||||
addSwitch(i);
|
||||
}
|
||||
|
||||
// if multiple combo boxes force update to lists
|
||||
if (exclFlexSwitchesGroup->getComboBoxes()->count() > 1) {
|
||||
QComboBox *cb = exclFlexSwitchesGroup->getComboBoxes()->at(0);
|
||||
exclFlexSwitchesGroup->handleActivated(cb, cb->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,62 +409,109 @@ void HardwarePanel::on_internalModuleChanged()
|
||||
|
||||
void HardwarePanel::addStick(int index)
|
||||
{
|
||||
addLabel(Boards::getAnalogInputName(board, index));
|
||||
GeneralSettings::InputConfig &config = generalSettings.inputConfig[index];
|
||||
|
||||
addLabel(Boards::getInputName(index, board));
|
||||
|
||||
AutoLineEdit *name = new AutoLineEdit(this);
|
||||
name->setField(generalSettings.stickName[index], HARDWARE_NAME_LEN, this);
|
||||
name->setField(config.name, HARDWARE_NAME_LEN, this);
|
||||
params->append(name);
|
||||
addParams();
|
||||
}
|
||||
|
||||
void HardwarePanel::addPot(int index)
|
||||
void HardwarePanel::addFlex(int index)
|
||||
{
|
||||
addLabel(Boards::getAnalogInputName(board, Boards::getCapability(board, Board::Sticks) + index));
|
||||
GeneralSettings::InputConfig &config = generalSettings.inputConfig[index];
|
||||
|
||||
addLabel(Boards::getInputName(index, board));
|
||||
|
||||
AutoLineEdit *name = new AutoLineEdit(this);
|
||||
name->setField(generalSettings.potName[index], HARDWARE_NAME_LEN, this);
|
||||
name->setField(config.name, HARDWARE_NAME_LEN, this);
|
||||
params->append(name);
|
||||
|
||||
AutoComboBox *type = new AutoComboBox(this);
|
||||
type->setModel(editorItemModels->getItemModel(AIM_BOARDS_POT_TYPE));
|
||||
type->setField(generalSettings.potConfig[index], this);
|
||||
setFlexTypeModel(type, index);
|
||||
int & flexType = (int &)config.flexType;
|
||||
type->setField(flexType, this);
|
||||
|
||||
connect(type, &AutoComboBox::currentDataChanged, [=] (int val) {
|
||||
AbstractItemModel *mdl = editorItemModels->getItemModel(AbstractItemModel::IMID_FlexSwitches);
|
||||
if (mdl)
|
||||
mdl->update(AbstractItemModel::IMUE_FunctionSwitches);
|
||||
emit InputFlexTypeChanged();
|
||||
});
|
||||
|
||||
connect(this, &HardwarePanel::InputFlexTypeChanged, [=]() { setFlexTypeModel(type, index); });
|
||||
|
||||
params->append(type);
|
||||
|
||||
AutoCheckBox *inverted = new AutoCheckBox(this);
|
||||
inverted->setField(config.inverted, this);
|
||||
params->append(inverted);
|
||||
|
||||
addParams();
|
||||
}
|
||||
|
||||
void HardwarePanel::addSlider(int index)
|
||||
void HardwarePanel::setFlexTypeModel(AutoComboBox * cb, int index)
|
||||
{
|
||||
addLabel(Boards::getAnalogInputName(board, Boards::getCapability(board, Board::Sticks) +
|
||||
Boards::getCapability(board, Board::Pots) + index));
|
||||
|
||||
AutoLineEdit *name = new AutoLineEdit(this);
|
||||
name->setField(generalSettings.sliderName[index], HARDWARE_NAME_LEN, this);
|
||||
params->append(name);
|
||||
|
||||
AutoComboBox *type = new AutoComboBox(this);
|
||||
type->setModel(editorItemModels->getItemModel(AIM_BOARDS_SLIDER_TYPE));
|
||||
type->setField(generalSettings.sliderConfig[index], this);
|
||||
params->append(type);
|
||||
|
||||
addParams();
|
||||
cb->setModel((generalSettings.inputConfig[index].flexType == Board::FLEX_SWITCH || generalSettings.unassignedInputFlexSwitches()) ?
|
||||
tabFilteredModels->getItemModel(FIM_FLEXTYPE_SWITCH) :
|
||||
tabFilteredModels->getItemModel(FIM_FLEXTYPE_NOSWITCH));
|
||||
}
|
||||
|
||||
void HardwarePanel::addSwitch(int index)
|
||||
{
|
||||
addLabel(Boards::getSwitchInfo(board, index).name);
|
||||
GeneralSettings::SwitchConfig &config = generalSettings.switchConfig[index];
|
||||
Board::SwitchInfo info = Boards::getSwitchInfo(index);
|
||||
|
||||
addLabel(Boards::getSwitchName(index));
|
||||
|
||||
AutoLineEdit *name = new AutoLineEdit(this);
|
||||
name->setField(generalSettings.switchName[index], HARDWARE_NAME_LEN, this);
|
||||
name->setField(config.name, HARDWARE_NAME_LEN, this);
|
||||
params->append(name);
|
||||
|
||||
AutoComboBox *input = nullptr;
|
||||
|
||||
if (generalSettings.isSwitchFlex(index)) {
|
||||
int id = tabFilteredModels->registerItemModel(
|
||||
new FilteredItemModel(editorItemModels->getItemModel(AbstractItemModel::IMID_FlexSwitches)),
|
||||
QString("%1 %2").arg(FIM_FLEXSWITCHES).arg(index));
|
||||
input = new AutoComboBox(this);
|
||||
input->setModel(tabFilteredModels->getItemModel(id));
|
||||
input->setField(config.inputIdx, this);
|
||||
exclFlexSwitchesGroup->addCombo(input);
|
||||
params->append(input);
|
||||
}
|
||||
|
||||
AutoComboBox *type = new AutoComboBox(this);
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board, index);
|
||||
type->setModel(switchInfo.config < Board::SWITCH_3POS ? tabFilteredModels->getItemModel(FIM_SWITCHTYPE2POS) :
|
||||
tabFilteredModels->getItemModel(FIM_SWITCHTYPE3POS));
|
||||
type->setField(generalSettings.switchConfig[index], this);
|
||||
type->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
if (generalSettings.isSwitchFlex(index))
|
||||
if (config.type == Board::SWITCH_NOT_AVAILABLE)
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPENONE));
|
||||
else
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPE3POS));
|
||||
else if (info.type < Board::SWITCH_3POS)
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPE2POS));
|
||||
else
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPE3POS));
|
||||
|
||||
int & swtype = (int &)config.type;
|
||||
type->setField(swtype, this);
|
||||
params->append(type);
|
||||
|
||||
if (generalSettings.isSwitchFlex(index)) {
|
||||
connect(input, &AutoComboBox::currentDataChanged, [=] (int val) {
|
||||
if (val < 0) {
|
||||
generalSettings.switchConfig[index].type = Board::SWITCH_NOT_AVAILABLE;
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPENONE));
|
||||
type->updateValue();
|
||||
}
|
||||
else
|
||||
type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPE3POS));
|
||||
});
|
||||
}
|
||||
|
||||
addParams();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class CompoundItemModelFactory;
|
||||
class FilteredItemModelFactory;
|
||||
class QGridLayout;
|
||||
class AutoComboBox;
|
||||
class ExclusiveComboGroup;
|
||||
|
||||
class HardwarePanel : public GeneralPanel
|
||||
{
|
||||
@@ -37,6 +38,7 @@ class HardwarePanel : public GeneralPanel
|
||||
|
||||
signals:
|
||||
void internalModuleChanged();
|
||||
void InputFlexTypeChanged();
|
||||
|
||||
private slots:
|
||||
void on_internalModuleChanged();
|
||||
@@ -55,15 +57,16 @@ class HardwarePanel : public GeneralPanel
|
||||
AutoComboBox *antennaMode;
|
||||
QList<QWidget *> *params;
|
||||
int row;
|
||||
ExclusiveComboGroup *exclFlexSwitchesGroup;
|
||||
|
||||
void addStick(int index);
|
||||
void addPot(int index);
|
||||
void addSlider(int index);
|
||||
void addFlex(int index);
|
||||
void addSwitch(int index);
|
||||
void addLabel(QString text);
|
||||
void addLine();
|
||||
void addParams();
|
||||
void addSection(QString text);
|
||||
|
||||
void setFlexTypeModel(AutoComboBox * cb, int index);
|
||||
void updateSerialPortUSBVCP();
|
||||
};
|
||||
|
||||
@@ -35,8 +35,7 @@ TrainerPanel::TrainerPanel(QWidget * parent, GeneralSettings & generalSettings,
|
||||
int modeid = editorItemModels->registerItemModel(TrainerMix::modeItemModel());
|
||||
int srcid = editorItemModels->registerItemModel(TrainerMix::srcItemModel());
|
||||
|
||||
Board::Type board = getCurrentBoard();
|
||||
const int stickcnt = Boards::getCapability(board, Board::Sticks);
|
||||
const int stickcnt = Boards::getCapability(getCurrentBoard(), Board::Sticks);
|
||||
|
||||
const FieldRange weightrng = TrainerMix::getWeightRange();
|
||||
|
||||
@@ -50,9 +49,9 @@ TrainerPanel::TrainerPanel(QWidget * parent, GeneralSettings & generalSettings,
|
||||
addLabel(tr("Weight"), row, 2);
|
||||
addLabel(tr("Source"), row++, 3);
|
||||
|
||||
for (int i = 0; i < 4; i++, row++) { // TODO constant
|
||||
for (int i = 0; i < CPN_MAX_STICKS; i++, row++) {
|
||||
col = 0;
|
||||
addLabel(Boards::getAnalogInputName(board, i), row, col++);
|
||||
addLabel(Boards::getInputName(i), row, col++);
|
||||
|
||||
AutoComboBox *mode = new AutoComboBox(this);
|
||||
mode->setModel(editorItemModels->getItemModel(modeid));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource prefix="/hwdefs/">
|
||||
@HWDEF_JSON_LIST@
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -85,7 +85,7 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
// The trims
|
||||
QString labels[CPN_MAX_TRIMS];
|
||||
for(int i = 0; i < CPN_MAX_STICKS; i++) {
|
||||
labels[i] = firmware->getAnalogInputName(i);
|
||||
labels[i] = Boards::getInputName(i);
|
||||
}
|
||||
labels[4] = "T5"; // TODO firmware function
|
||||
labels[5] = "T6"; // TODO firmware function
|
||||
|
||||
@@ -36,6 +36,8 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
dialogFilteredItemModels = new FilteredItemModelFactory();
|
||||
int id;
|
||||
|
||||
@@ -84,7 +86,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
|
||||
|
||||
if (!firmware->getCapability(VirtualInputs)) {
|
||||
for(int i = 0; i < CPN_MAX_STICKS; i++) {
|
||||
ui->trimCB->addItem(firmware->getAnalogInputName(i));
|
||||
ui->trimCB->addItem(Boards::getInputName(i, board));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1603,10 +1603,13 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
|
||||
// Beep Center checkboxes
|
||||
prevFocus = ui->trimsDisplay;
|
||||
int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders);
|
||||
int genAryIdx = 0;
|
||||
for (int i = 0; i < analogs + firmware->getCapability(RotaryEncoders); i++) {
|
||||
RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i);
|
||||
|
||||
const int ttlSticks = Boards::getBoardCapability(board, Board::Sticks);
|
||||
const int ttlFlexInputs = Boards::getBoardCapability(board, Board::FlexInputs);
|
||||
const int ttlInputs = ttlSticks + ttlFlexInputs;
|
||||
|
||||
for (int i = 0; i < ttlInputs + firmware->getCapability(RotaryEncoders); i++) {
|
||||
RawSource src((i < ttlInputs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < ttlInputs) ? i : ttlInputs - i);
|
||||
QCheckBox * checkbox = new QCheckBox(this);
|
||||
checkbox->setProperty("index", i);
|
||||
checkbox->setText(src.toString(&model, &generalSettings));
|
||||
@@ -1614,25 +1617,24 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
|
||||
centerBeepCheckboxes << checkbox;
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
if (src.isPot(&genAryIdx) && (!generalSettings.isPotAvailable(genAryIdx) || generalSettings.isMultiPosPot(genAryIdx))) {
|
||||
if (!(generalSettings.isInputAvailable(i) &&
|
||||
(generalSettings.isInputStick(i) || (generalSettings.isInputPot(i) && !generalSettings.isInputMultiPosPot(i)) ||
|
||||
generalSettings.isInputSlider(i))))
|
||||
checkbox->hide();
|
||||
}
|
||||
else if (src.isSlider(&genAryIdx) && !generalSettings.isSliderAvailable(genAryIdx)) {
|
||||
checkbox->hide();
|
||||
}
|
||||
}
|
||||
QWidget::setTabOrder(prevFocus, checkbox);
|
||||
prevFocus = checkbox;
|
||||
}
|
||||
|
||||
// Startup switches warnings
|
||||
for (int i = 0; i < getBoardCapability(board, Board::Switches); i++) {
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board, i);
|
||||
switchInfo.config = Board::SwitchType(generalSettings.switchConfig[i]);
|
||||
if (switchInfo.config == Board::SWITCH_NOT_AVAILABLE || switchInfo.config == Board::SWITCH_TOGGLE) {
|
||||
for (int i = 0; i < Boards::getBoardCapability(board, Board::Switches); i++) {
|
||||
GeneralSettings::SwitchConfig &swcfg = generalSettings.switchConfig[i];
|
||||
|
||||
if (Boards::isSwitchFunc(i, board) || !generalSettings.isSwitchAvailable(i) || swcfg.type == Board::SWITCH_TOGGLE) {
|
||||
model.switchWarningEnable |= (1 << i);
|
||||
continue;
|
||||
}
|
||||
|
||||
RawSource src(RawSourceType::SOURCE_TYPE_SWITCH, i);
|
||||
QLabel * label = new QLabel(this);
|
||||
QSlider * slider = new QSlider(this);
|
||||
@@ -1649,7 +1651,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
slider->setPageStep(1);
|
||||
slider->setTickInterval(1);
|
||||
label->setText(src.toString(&model, &generalSettings));
|
||||
slider->setMaximum(switchInfo.config == Board::SWITCH_3POS ? 2 : 1);
|
||||
slider->setMaximum(swcfg.type == Board::SWITCH_3POS ? 2 : 1);
|
||||
cb->setProperty("index", i);
|
||||
ui->switchesStartupLayout->addWidget(label, 0, i + 1);
|
||||
ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter);
|
||||
@@ -1668,23 +1670,18 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
|
||||
// Pot warnings
|
||||
prevFocus = ui->potWarningMode;
|
||||
int count = getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders);
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board) && count > 0) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
|
||||
if (IS_HORUS_OR_TARANIS(board) && ttlInputs > 0) {
|
||||
for (int i = ttlSticks; i < ttlInputs; i++) {
|
||||
RawSource src(SOURCE_TYPE_STICK, i);
|
||||
QCheckBox * cb = new QCheckBox(this);
|
||||
cb->setProperty("index", i);
|
||||
cb->setProperty("index", i - ttlSticks);
|
||||
cb->setText(src.toString(&model, &generalSettings));
|
||||
ui->potWarningLayout->addWidget(cb, 0, i + 1);
|
||||
ui->potWarningLayout->addWidget(cb, 0, i - ttlSticks + 1);
|
||||
connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool)));
|
||||
potWarningCheckboxes << cb;
|
||||
if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) {
|
||||
if (!(generalSettings.isInputAvailable(i) && (generalSettings.isInputPot(i) || generalSettings.isInputSlider(i))))
|
||||
cb->hide();
|
||||
}
|
||||
else if (src.isSlider(&genAryIdx) && !generalSettings.isSliderAvailable(genAryIdx)) {
|
||||
cb->hide();
|
||||
}
|
||||
QWidget::setTabOrder(prevFocus, cb);
|
||||
prevFocus = cb;
|
||||
}
|
||||
@@ -1916,7 +1913,7 @@ void SetupPanel::updateStartupSwitches()
|
||||
bool enabled = !(model->switchWarningEnable & (1 << index));
|
||||
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
|
||||
value = (switchStates >> (2 * index)) & 0x03;
|
||||
if (generalSettings.switchConfig[index] != Board::SWITCH_3POS && value == 2) {
|
||||
if (generalSettings.switchConfig[index].type != Board::SWITCH_3POS && value == 2) {
|
||||
value = 1;
|
||||
}
|
||||
}
|
||||
@@ -1955,7 +1952,7 @@ void SetupPanel::startupSwitchEdited(int value)
|
||||
|
||||
model->switchWarningStates &= ~mask;
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(firmware->getBoard()) && generalSettings.switchConfig[index] != Board::SWITCH_3POS) {
|
||||
if (IS_HORUS_OR_TARANIS(firmware->getBoard()) && generalSettings.switchConfig[index].type != Board::SWITCH_3POS) {
|
||||
if (value == 1) {
|
||||
value = 2;
|
||||
}
|
||||
@@ -1989,12 +1986,14 @@ void SetupPanel::updatePotWarnings()
|
||||
{
|
||||
lock = true;
|
||||
ui->potWarningMode->setCurrentIndex(model->potsWarningMode);
|
||||
|
||||
for (int i = 0; i < potWarningCheckboxes.size(); i++) {
|
||||
QCheckBox *checkbox = potWarningCheckboxes[i];
|
||||
int index = checkbox->property("index").toInt();
|
||||
checkbox->setChecked(model->potsWarnEnabled[index]);
|
||||
checkbox->setDisabled(model->potsWarningMode == 0);
|
||||
}
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1024</width>
|
||||
<width>1046</width>
|
||||
<height>435</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -393,7 +393,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Manual</string>
|
||||
<string>ON</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -268,12 +268,12 @@ QString ModelPrinter::printHeliSwashType ()
|
||||
QString ModelPrinter::printCenterBeep()
|
||||
{
|
||||
QStringList strl;
|
||||
Board::Type board = firmware->getBoard();
|
||||
int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders);
|
||||
Board::Type board = getCurrentBoard();
|
||||
int inputs = Boards::getBoardCapability(board, Board::Inputs);
|
||||
|
||||
for (int i=0; i < analogs + firmware->getCapability(RotaryEncoders); i++) {
|
||||
RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i);
|
||||
for (int i = 0; i < inputs + firmware->getCapability(RotaryEncoders); i++) {
|
||||
if (model.beepANACenter & (0x01 << i)) {
|
||||
RawSource src((i < inputs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < inputs) ? i : inputs - i);
|
||||
strl << src.toString(&model, &generalSettings);
|
||||
}
|
||||
}
|
||||
@@ -507,20 +507,25 @@ QString ModelPrinter::printLogicalSwitchLine(int idx)
|
||||
{
|
||||
QString result = "";
|
||||
const LogicalSwitchData & ls = model.logicalSw[idx];
|
||||
const QString sw1Name = RawSwitch(ls.val1).toString(getCurrentBoard(), &generalSettings);
|
||||
const QString sw2Name = RawSwitch(ls.val2).toString(getCurrentBoard(), &generalSettings);
|
||||
|
||||
if (ls.isEmpty())
|
||||
return result;
|
||||
|
||||
QString sw1Name;
|
||||
QString sw2Name;
|
||||
|
||||
if (ls.andsw!=0) {
|
||||
result +="( ";
|
||||
}
|
||||
switch (ls.getFunctionFamily()) {
|
||||
case LS_FAMILY_EDGE:
|
||||
result += tr("Edge") + QString("(%1, [%2:%3])").arg(sw1Name).arg(ValToTim(ls.val2)).arg(ls.val3<0 ? tr("instant") : QString("%1").arg(ValToTim(ls.val2+ls.val3)));
|
||||
sw1Name = RawSwitch(ls.val1).toString(getCurrentBoard(), &generalSettings);
|
||||
result += tr("Edge") + QString("(%1, [%2:%3])").arg(sw1Name).arg(ValToTim(ls.val2)).arg(ls.val3 < 0 ?
|
||||
tr("instant") : (ls.val3 == 0 ? tr("infinite") : QString("%1").arg(ValToTim(ls.val2 + ls.val3))));
|
||||
break;
|
||||
case LS_FAMILY_STICKY:
|
||||
sw1Name = RawSwitch(ls.val1).toString(getCurrentBoard(), &generalSettings);
|
||||
sw2Name = RawSwitch(ls.val2).toString(getCurrentBoard(), &generalSettings);
|
||||
result += tr("Sticky") + QString("(%1, %2)").arg(sw1Name).arg(sw2Name);
|
||||
break;
|
||||
case LS_FAMILY_TIMER:
|
||||
@@ -553,9 +558,12 @@ QString ModelPrinter::printLogicalSwitchLine(int idx)
|
||||
else
|
||||
result += tr(" missing");
|
||||
result += QString::number(range.step * (ls.val2 /*TODO+ source.getRawOffset(model)*/) + range.offset);
|
||||
result += range.unit;
|
||||
break;
|
||||
}
|
||||
case LS_FAMILY_VBOOL:
|
||||
sw1Name = RawSwitch(ls.val1).toString(getCurrentBoard(), &generalSettings);
|
||||
sw2Name = RawSwitch(ls.val2).toString(getCurrentBoard(), &generalSettings);
|
||||
result += sw1Name;
|
||||
switch (ls.func) {
|
||||
case LS_FN_AND:
|
||||
@@ -603,8 +611,12 @@ QString ModelPrinter::printLogicalSwitchLine(int idx)
|
||||
result += " foo ";
|
||||
break;
|
||||
}
|
||||
if (ls.val2)
|
||||
result += RawSource(ls.val2).toString(&model, &generalSettings);
|
||||
if (ls.val2) {
|
||||
RawSource source = RawSource(ls.val2);
|
||||
RawSourceRange range = source.getRange(&model, generalSettings);
|
||||
result += source.toString(&model, &generalSettings);
|
||||
result += range.unit;
|
||||
}
|
||||
else
|
||||
result += "0";
|
||||
break;
|
||||
@@ -737,25 +749,24 @@ QString ModelPrinter::printSettingsOther()
|
||||
QString ModelPrinter::printSwitchWarnings()
|
||||
{
|
||||
QStringList str;
|
||||
Boards board = firmware->getBoard();
|
||||
Board::Type board = getCurrentBoard();
|
||||
uint64_t switchStates = model.switchWarningStates;
|
||||
uint64_t value;
|
||||
|
||||
for (int idx=0; idx<board.getCapability(Board::Switches) + board.getCapability(Board::FunctionSwitches); idx++) {
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board.getBoardType(), idx);
|
||||
switchInfo.config = Board::SwitchType(generalSettings.switchConfig[idx]);
|
||||
if (switchInfo.config == Board::SWITCH_NOT_AVAILABLE || switchInfo.config == Board::SWITCH_TOGGLE) {
|
||||
for (int i = 0; i < Boards::getCapability(board, Board::Switches); i++) {
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(i);
|
||||
if (switchInfo.type == Board::SWITCH_NOT_AVAILABLE || switchInfo.type == Board::SWITCH_TOGGLE) {
|
||||
continue;
|
||||
}
|
||||
if (!(model.switchWarningEnable & (1 << idx))) {
|
||||
if (IS_HORUS_OR_TARANIS(board.getBoardType())) {
|
||||
value = (switchStates >> (2*idx)) & 0x03;
|
||||
if (!(model.switchWarningEnable & (1 << i))) {
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
value = (switchStates >> (2 * i)) & 0x03;
|
||||
}
|
||||
else {
|
||||
value = (idx==0 ? switchStates & 0x3 : switchStates & 0x1);
|
||||
switchStates >>= (idx==0 ? 2 : 1);
|
||||
value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1);
|
||||
switchStates >>= (i == 0 ? 2 : 1);
|
||||
}
|
||||
str += RawSwitch(SWITCH_TYPE_SWITCH, 1+idx*3+value).toString(board.getBoardType(), &generalSettings, &model);
|
||||
str += RawSwitch(SWITCH_TYPE_SWITCH, 1 + i * 3 + value).toString(board, &generalSettings, &model);
|
||||
}
|
||||
}
|
||||
return (str.isEmpty() ? tr("None") : str.join(" ")) ;
|
||||
@@ -763,19 +774,20 @@ QString ModelPrinter::printSwitchWarnings()
|
||||
|
||||
QString ModelPrinter::printPotWarnings()
|
||||
{
|
||||
QStringList str;
|
||||
int genAryIdx = 0;
|
||||
Boards board = firmware->getBoard();
|
||||
Board::Type board = getCurrentBoard();
|
||||
QStringList str = { printLabelValue(tr("Mode"), printPotsWarningMode()) };
|
||||
|
||||
if (model.potsWarningMode) {
|
||||
for (int i=0; i<board.getCapability(Board::Pots)+board.getCapability(Board::Sliders); i++) {
|
||||
RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
|
||||
if ((src.isPot(&genAryIdx) && generalSettings.isPotAvailable(genAryIdx)) || (src.isSlider(&genAryIdx) && generalSettings.isSliderAvailable(genAryIdx))) {
|
||||
if (model.potsWarnEnabled[i])
|
||||
for (int i = Boards::getCapability(board, Board::Sticks); i < Boards::getCapability(board, Board::Inputs); i++) {
|
||||
if (generalSettings.isInputAvailable(i) && (generalSettings.isInputPot(i) || generalSettings.isInputSlider(i))) {
|
||||
if (model.potsWarnEnabled[i]) {
|
||||
RawSource src(SOURCE_TYPE_STICK, i);
|
||||
str += src.toString(&model, &generalSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
str << printLabelValue(tr("Mode"), printPotsWarningMode());
|
||||
|
||||
return str.join(" ");
|
||||
}
|
||||
|
||||
@@ -851,14 +863,17 @@ QString ModelPrinter::printSettingsTrim()
|
||||
|
||||
QString ModelPrinter::printThrottleSource(int idx)
|
||||
{
|
||||
Boards board = firmware->getBoard();
|
||||
int chnstart = board.getCapability(Board::Pots)+board.getCapability(Board::Sliders);
|
||||
Board::Type board = firmware->getBoard();
|
||||
int pscnt = Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders);
|
||||
|
||||
if (idx == 0)
|
||||
return "THR";
|
||||
else if (idx < (chnstart+1))
|
||||
return firmware->getAnalogInputName(idx+board.getCapability(Board::Sticks)-1);
|
||||
else
|
||||
return RawSource(SOURCE_TYPE_CH, idx-chnstart-1).toString(&model, &generalSettings);
|
||||
else if (idx <= pscnt)
|
||||
return Boards::getInputName(idx + Boards::getCapability(board, Board::Sticks) - 1, board);
|
||||
else if (idx <= pscnt + getCurrentFirmware()->getCapability(Outputs))
|
||||
return RawSource(SOURCE_TYPE_CH, idx - pscnt - 1).toString(&model, &generalSettings);
|
||||
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
QString ModelPrinter::printTrimsDisplayMode()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
project(shared)
|
||||
|
||||
set(${PROJECT_NAME}_NAMES
|
||||
autobitmappedcheckbox
|
||||
autobitmappedcombobox
|
||||
autobitsetcheckbox
|
||||
autocheckbox
|
||||
autocombobox
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "autobitmappedcheckbox.h"
|
||||
|
||||
AutoBitMappedCheckBox::AutoBitMappedCheckBox(QWidget * parent):
|
||||
QCheckBox(parent),
|
||||
AutoWidget(),
|
||||
m_field(nullptr),
|
||||
m_invert(false)
|
||||
{
|
||||
setBits();
|
||||
connect(this, &QCheckBox::toggled, this, &AutoBitMappedCheckBox::onToggled);
|
||||
}
|
||||
|
||||
AutoBitMappedCheckBox::~AutoBitMappedCheckBox()
|
||||
{
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::setField(int & field, GenericPanel * panel, bool invert)
|
||||
{
|
||||
m_field = &field;
|
||||
m_invert = invert;
|
||||
setPanel(panel);
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::setField(unsigned int & field, GenericPanel * panel, bool invert)
|
||||
{
|
||||
m_field = (int *)&field;
|
||||
m_invert = invert;
|
||||
setPanel(panel);
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::setInvert(bool invert)
|
||||
{
|
||||
m_invert = invert;
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::setBits(const unsigned int numBits, const unsigned int offsetBits,
|
||||
const unsigned int index, const unsigned int indexBits)
|
||||
{
|
||||
m_bits = numBits;
|
||||
m_offsetBits = offsetBits;
|
||||
m_index = index;
|
||||
m_indexBits = indexBits;
|
||||
|
||||
if (m_offsetBits + m_bits > m_indexBits)
|
||||
m_indexBits = m_offsetBits + m_bits;
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::onToggled(bool checked)
|
||||
{
|
||||
if (m_field && !lock()) {
|
||||
const bool val = m_invert ? !checked : checked;
|
||||
unsigned int fieldmask = (bitmask() << shiftbits());
|
||||
*m_field = (*m_field & ~fieldmask) | (val << shiftbits());
|
||||
emit currentDataChanged(val);
|
||||
dataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBitMappedCheckBox::updateValue()
|
||||
{
|
||||
if (m_field) {
|
||||
setLock(true);
|
||||
bool val = (bool)((*m_field >> shiftbits()) & bitmask());
|
||||
setChecked(m_invert ? !val : val);
|
||||
setLock(false);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int AutoBitMappedCheckBox::shiftbits()
|
||||
{
|
||||
return m_indexBits * m_index + m_offsetBits;
|
||||
}
|
||||
|
||||
unsigned int AutoBitMappedCheckBox::bitmask()
|
||||
{
|
||||
int mask = -1;
|
||||
mask = ~(mask << m_bits);
|
||||
return (unsigned int)mask;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "autowidget.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
class AutoBitMappedCheckBox : public QCheckBox, public AutoWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AutoBitMappedCheckBox(QWidget * parent = nullptr);
|
||||
virtual ~AutoBitMappedCheckBox();
|
||||
|
||||
virtual void updateValue() override;
|
||||
|
||||
void setField(int & field, GenericPanel * panel = nullptr, bool invert = false);
|
||||
void setField(unsigned int & field, GenericPanel * panel = nullptr, bool invert = false);
|
||||
void setInvert(bool invert);
|
||||
void setBits(const unsigned int numBits = 1, const unsigned int offsetBits = 0, const unsigned int index = 0,
|
||||
const unsigned int indexBits = 1);
|
||||
|
||||
signals:
|
||||
void currentDataChanged(bool value);
|
||||
|
||||
protected slots:
|
||||
void onToggled(bool checked);
|
||||
|
||||
private:
|
||||
int *m_field;
|
||||
bool m_invert;
|
||||
unsigned int m_index;
|
||||
unsigned int m_indexBits;
|
||||
unsigned int m_bits;
|
||||
unsigned int m_offsetBits;
|
||||
|
||||
unsigned int shiftbits();
|
||||
unsigned int bitmask();
|
||||
};
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "autobitmappedcombobox.h"
|
||||
|
||||
AutoBitMappedComboBox::AutoBitMappedComboBox(QWidget * parent):
|
||||
QComboBox(parent),
|
||||
AutoWidget(),
|
||||
m_field(nullptr),
|
||||
m_next(0),
|
||||
m_hasModel(false),
|
||||
m_rawSource(nullptr),
|
||||
m_rawSwitch(nullptr)
|
||||
{
|
||||
setBits();
|
||||
connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AutoBitMappedComboBox::onCurrentIndexChanged);
|
||||
}
|
||||
|
||||
AutoBitMappedComboBox::~AutoBitMappedComboBox()
|
||||
{
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::clear()
|
||||
{
|
||||
if (m_hasModel)
|
||||
return;
|
||||
|
||||
setLock(true);
|
||||
QComboBox::clear();
|
||||
m_next = 0;
|
||||
setLock(false);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::insertItems(int index, const QStringList & items)
|
||||
{
|
||||
if (m_hasModel)
|
||||
return;
|
||||
|
||||
foreach(QString item, items) {
|
||||
addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::addItem(const QString & item)
|
||||
{
|
||||
if (m_hasModel)
|
||||
return;
|
||||
|
||||
addItem(item, m_next++);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::addItem(const QString & item, int value)
|
||||
{
|
||||
if (m_hasModel)
|
||||
return;
|
||||
|
||||
setLock(true);
|
||||
QComboBox::addItem(item, value);
|
||||
setLock(false);
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setField(unsigned int & field, GenericPanel * panel)
|
||||
{
|
||||
m_field = (int *)&field;
|
||||
m_rawSource = nullptr;
|
||||
m_rawSwitch = nullptr;
|
||||
setFieldInit(panel);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setField(int & field, GenericPanel * panel)
|
||||
{
|
||||
m_field = &field;
|
||||
m_rawSource = nullptr;
|
||||
m_rawSwitch = nullptr;
|
||||
setFieldInit(panel);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setField(RawSource & field, GenericPanel * panel)
|
||||
{
|
||||
m_rawSource = &field;
|
||||
m_rawSwitch = nullptr;
|
||||
m_field = nullptr;
|
||||
setFieldInit(panel);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setField(RawSwitch & field, GenericPanel * panel)
|
||||
{
|
||||
m_rawSwitch = &field;
|
||||
m_rawSource = nullptr;
|
||||
m_field = nullptr;
|
||||
setFieldInit(panel);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setFieldInit(GenericPanel * panel)
|
||||
{
|
||||
setPanel(panel);
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setBits(const unsigned int numBits, const unsigned int offsetBits,
|
||||
const unsigned int index, const unsigned int indexBits)
|
||||
{
|
||||
m_bits = numBits;
|
||||
m_offsetBits = offsetBits;
|
||||
m_index = index;
|
||||
m_indexBits = indexBits;
|
||||
|
||||
if (m_offsetBits + m_bits > m_indexBits)
|
||||
m_indexBits = m_offsetBits + m_bits;
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setModel(QAbstractItemModel * model)
|
||||
{
|
||||
setLock(true);
|
||||
QComboBox::setModel(model);
|
||||
setLock(false);
|
||||
m_hasModel = true;
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::setAutoIndexes()
|
||||
{
|
||||
if (m_hasModel)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < count(); ++i)
|
||||
setItemData(i, i);
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::updateValue()
|
||||
{
|
||||
if (!m_field && !m_rawSource && !m_rawSwitch)
|
||||
return;
|
||||
|
||||
setLock(true);
|
||||
|
||||
if (m_field) {
|
||||
int val = (*m_field >> shiftbits()) & bitmask();
|
||||
setCurrentIndex(findData(val));
|
||||
}
|
||||
else if (m_rawSource)
|
||||
setCurrentIndex(findData(m_rawSource->toValue()));
|
||||
else if (m_rawSwitch)
|
||||
setCurrentIndex(findData(m_rawSwitch->toValue()));
|
||||
|
||||
setLock(false);
|
||||
}
|
||||
|
||||
void AutoBitMappedComboBox::onCurrentIndexChanged(int index)
|
||||
{
|
||||
if (lock() || index < 0)
|
||||
return;
|
||||
|
||||
bool ok;
|
||||
const int val = itemData(index).toInt(&ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
if (m_field && *m_field != val) {
|
||||
unsigned int fieldmask = (bitmask() << shiftbits());
|
||||
*m_field = (*m_field & ~fieldmask) | (val << shiftbits());
|
||||
}
|
||||
else if (m_rawSource && m_rawSource->toValue() != val) {
|
||||
*m_rawSource = RawSource(val);
|
||||
}
|
||||
else if (m_rawSwitch && m_rawSwitch->toValue() != val) {
|
||||
*m_rawSwitch = RawSwitch(val);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
emit currentDataChanged(val);
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
unsigned int AutoBitMappedComboBox::shiftbits()
|
||||
{
|
||||
return m_indexBits * m_index + m_offsetBits;
|
||||
}
|
||||
|
||||
unsigned int AutoBitMappedComboBox::bitmask()
|
||||
{
|
||||
int mask = -1;
|
||||
mask = ~(mask << m_bits);
|
||||
return (unsigned int)mask;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "autowidget.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
class AutoBitMappedComboBox : public QComboBox, public AutoWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AutoBitMappedComboBox(QWidget * parent = nullptr);
|
||||
virtual ~AutoBitMappedComboBox();
|
||||
|
||||
// QComboBox
|
||||
virtual void addItem(const QString & item);
|
||||
virtual void addItem(const QString & item, int value);
|
||||
virtual void insertItems(int index, const QStringList & items);
|
||||
// AutoWidget
|
||||
virtual void updateValue() override;
|
||||
|
||||
void clear();
|
||||
|
||||
void setBits(const unsigned int numBits = 1, const unsigned int offsetBits = 0, const unsigned int index = 0,
|
||||
const unsigned int indexBits = 1);
|
||||
void setField(unsigned int & field, GenericPanel * panel = nullptr);
|
||||
void setField(int & field, GenericPanel * panel = nullptr);
|
||||
void setField(RawSource & field, GenericPanel * panel = nullptr);
|
||||
void setField(RawSwitch & field, GenericPanel * panel = nullptr);
|
||||
|
||||
void setAutoIndexes();
|
||||
void setModel(QAbstractItemModel * model);
|
||||
|
||||
signals:
|
||||
void currentDataChanged(int value);
|
||||
|
||||
protected slots:
|
||||
void onCurrentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
int *m_field;
|
||||
int m_next;
|
||||
bool m_hasModel;
|
||||
RawSource *m_rawSource;
|
||||
RawSwitch *m_rawSwitch;
|
||||
unsigned int m_index;
|
||||
unsigned int m_indexBits;
|
||||
unsigned int m_bits;
|
||||
unsigned int m_offsetBits;
|
||||
|
||||
unsigned int shiftbits();
|
||||
unsigned int bitmask();
|
||||
|
||||
void setFieldInit(GenericPanel * panel);
|
||||
};
|
||||
@@ -30,3 +30,5 @@
|
||||
#include "autoslider.h"
|
||||
#include "autospinbox.h"
|
||||
#include "autotimeedit.h"
|
||||
#include "autobitmappedcheckbox.h"
|
||||
#include "autobitmappedcombobox.h"
|
||||
|
||||
@@ -82,8 +82,8 @@ void joystickDialog::loadGrid()
|
||||
}
|
||||
|
||||
memset(sliders, 0, sizeof(sliders));
|
||||
memset(sticks, 0, sizeof(sliders));
|
||||
memset(invert, 0, sizeof(sliders));
|
||||
memset(sticks, 0, sizeof(sticks));
|
||||
memset(invert, 0, sizeof(invert));
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
@@ -151,29 +151,19 @@ void joystickDialog::populateSourceCombo(QComboBox * cb)
|
||||
Board::Type m_board = getCurrentBoard();
|
||||
GeneralSettings radioSettings = GeneralSettings();
|
||||
|
||||
int ttlSticks = Boards::getCapability(m_board, Board::Sticks);
|
||||
int ttlKnobs = Boards::getCapability(m_board, Board::Pots);
|
||||
int ttlFaders = Boards::getCapability(m_board, Board::Sliders);
|
||||
int ttlInputs = Boards::getCapability(m_board, Board::Inputs);
|
||||
|
||||
cb->clear();
|
||||
cb->addItem(tr("Not Assigned"), -1);
|
||||
|
||||
for (i=0; i < ttlSticks; ++i) {
|
||||
wname = Boards::getAxisName(i);
|
||||
cb->addItem(wname, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < ttlKnobs; ++i) {
|
||||
if (radioSettings.isPotAvailable(i)) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + i).toString(nullptr, &radioSettings);
|
||||
cb->addItem(wname, i + ttlSticks);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ttlFaders; ++i) {
|
||||
if (radioSettings.isSliderAvailable(i)) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + ttlKnobs + i).toString(nullptr, &radioSettings);
|
||||
cb->addItem(wname, i + ttlSticks + ttlKnobs);
|
||||
for (i = 0; i < ttlInputs; ++i) {
|
||||
if (radioSettings.isInputAvailable(i) &&
|
||||
(radioSettings.isInputStick(i) || radioSettings.isInputPot(i) || radioSettings.isInputSlider(i))) {
|
||||
if (radioSettings.isInputStick(i))
|
||||
wname = Boards::getAxisName(i);
|
||||
else
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings);
|
||||
cb->addItem(wname, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,12 +182,12 @@ void joystickDialog::populateButtonCombo(QComboBox * cb)
|
||||
cb->clear();
|
||||
cb->addItem(tr("Not Assigned"), -1);
|
||||
|
||||
Board::SwitchType swcfg;
|
||||
Board::SwitchType swtype;
|
||||
for (i = 0; i < ttlSwitches; ++i) {
|
||||
if (radioSettings.switchConfig[i] != Board::SWITCH_NOT_AVAILABLE) {
|
||||
swcfg = Board::SwitchType(radioSettings.switchConfig[i]);
|
||||
if (radioSettings.switchConfig[i].type != Board::SWITCH_NOT_AVAILABLE) {
|
||||
swtype = Board::SwitchType(radioSettings.switchConfig[i].type);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(nullptr, &radioSettings);
|
||||
if (swcfg == Board::SWITCH_3POS) {
|
||||
if (swtype == Board::SWITCH_3POS) {
|
||||
cb->addItem(wname + CPN_STR_SW_INDICATOR_UP, i | JS_BUTTON_3POS_UP);
|
||||
cb->addItem(wname + CPN_STR_SW_INDICATOR_DN, i | JS_BUTTON_3POS_DN);
|
||||
} else {
|
||||
|
||||
@@ -575,8 +575,7 @@ void SimulatorWidget::setupRadioWidgets()
|
||||
int i, midpos;
|
||||
const int ttlSticks = Boards::getCapability(m_board, Board::Sticks);
|
||||
const int ttlSwitches = Boards::getCapability(m_board, Board::Switches);
|
||||
const int ttlKnobs = Boards::getCapability(m_board, Board::Pots);
|
||||
const int ttlFaders = Boards::getCapability(m_board, Board::Sliders);
|
||||
const int ttlInputs = Boards::getCapability(m_board, Board::Inputs);
|
||||
const int extraTrims = Boards::getCapability(m_board, Board::NumTrims) - ttlSticks;
|
||||
|
||||
// First clear out any existing widgets.
|
||||
@@ -604,11 +603,11 @@ void SimulatorWidget::setupRadioWidgets()
|
||||
// switches
|
||||
Board::SwitchType swcfg;
|
||||
for (i = 0; i < ttlSwitches; ++i) {
|
||||
if (radioSettings.switchConfig[i] == Board::SWITCH_NOT_AVAILABLE)
|
||||
if (!radioSettings.isSwitchAvailable(i) || Boards::isSwitchFunc(i))
|
||||
continue;
|
||||
|
||||
swcfg = Board::SwitchType(radioSettings.switchConfig[i]);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(nullptr, &radioSettings);
|
||||
swcfg = Board::SwitchType(radioSettings.switchConfig[i].type);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
|
||||
RadioSwitchWidget * sw = new RadioSwitchWidget(swcfg, wname, -1, ui->radioWidgetsHT);
|
||||
sw->setIndex(i);
|
||||
ui->radioWidgetsHTLayout->addWidget(sw);
|
||||
@@ -619,12 +618,12 @@ void SimulatorWidget::setupRadioWidgets()
|
||||
midpos = (int)floorf(m_radioWidgets.size() / 2.0f);
|
||||
|
||||
// pots in middle of switches
|
||||
for (i = 0; i < ttlKnobs; ++i) {
|
||||
if (!radioSettings.isPotAvailable(i))
|
||||
for (i = 0; i < ttlInputs; ++i) {
|
||||
if (!(radioSettings.isInputAvailable(i) && radioSettings.isInputPot(i)))
|
||||
continue;
|
||||
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + i).toString(nullptr, &radioSettings);
|
||||
RadioKnobWidget * pot = new RadioKnobWidget(Board::PotType(radioSettings.potConfig[i]), wname, 0, ui->radioWidgetsHT);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
|
||||
RadioKnobWidget * pot = new RadioKnobWidget(radioSettings.inputConfig[i].flexType, wname, 0, ui->radioWidgetsHT);
|
||||
pot->setIndex(i);
|
||||
ui->radioWidgetsHTLayout->insertWidget(midpos++, pot);
|
||||
m_radioWidgets.append(pot);
|
||||
@@ -632,15 +631,15 @@ void SimulatorWidget::setupRadioWidgets()
|
||||
|
||||
// faders between sticks
|
||||
int fc = extraTrims / 2; // leave space for any extra trims
|
||||
for (i = 0; i < ttlFaders; ++i) {
|
||||
if (!radioSettings.isSliderAvailable(i))
|
||||
|
||||
for (i = 0; i < ttlInputs; ++i) {
|
||||
if (!(radioSettings.isInputAvailable(i) && radioSettings.isInputSlider(i)))
|
||||
continue;
|
||||
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + ttlKnobs + i).toString(nullptr, &radioSettings);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
|
||||
RadioFaderWidget * sl = new RadioFaderWidget(wname, 0, ui->radioWidgetsVC);
|
||||
sl->setIndex(i);
|
||||
ui->VCGridLayout->addWidget(sl, 0, fc++, 1, 1);
|
||||
|
||||
m_radioWidgets.append(sl);
|
||||
}
|
||||
|
||||
@@ -648,7 +647,7 @@ void SimulatorWidget::setupRadioWidgets()
|
||||
int tc = 0;
|
||||
int tridx = ttlSticks;
|
||||
for (i = 0; i < extraTrims; i += 1, tridx += 1) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_TRIM, tridx).toString(nullptr, &radioSettings);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_TRIM, tridx).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
|
||||
wname = wname.left(1) % wname.right(1);
|
||||
RadioTrimWidget * tw = new RadioTrimWidget(Qt::Vertical, ui->radioWidgetsVC);
|
||||
tw->setIndices(tridx, tridx * 2, tridx * 2 + 1);
|
||||
@@ -814,17 +813,25 @@ void SimulatorWidget::onPhaseChanged(qint32 phase, const QString & name)
|
||||
setWindowTitle(windowName + tr(" - Flight Mode %1 (#%2)").arg(name).arg(phase));
|
||||
}
|
||||
|
||||
void SimulatorWidget::onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, const int index, int value)
|
||||
void SimulatorWidget::onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, int index, int value)
|
||||
{
|
||||
//qDebug() << type << index << value;
|
||||
if (!simulator || index < 0)
|
||||
return;
|
||||
|
||||
SimulatorInterface::InputSourceType inpType = SimulatorInterface::INPUT_SRC_NONE;
|
||||
GeneralSettings::SwitchConfig *cfg = nullptr;
|
||||
|
||||
switch (type) {
|
||||
case RadioWidget::RADIO_WIDGET_SWITCH :
|
||||
inpType = SimulatorInterface::INPUT_SRC_SWITCH;
|
||||
cfg = &radioSettings.switchConfig[index];
|
||||
if (cfg->inputIdx != SWITCH_INPUTINDEX_NONE) {
|
||||
inpType = SimulatorInterface::INPUT_SRC_STICK;
|
||||
index = cfg->inputIdx;
|
||||
value = value * 1024;
|
||||
}
|
||||
else
|
||||
inpType = SimulatorInterface::INPUT_SRC_SWITCH;
|
||||
break;
|
||||
|
||||
case RadioWidget::RADIO_WIDGET_KNOB :
|
||||
|
||||
@@ -110,7 +110,7 @@ class SimulatorWidget : public QWidget
|
||||
void onSimulatorHeartbeat(qint32 loops, qint64 timestamp);
|
||||
void onPhaseChanged(qint32 phase, const QString & name);
|
||||
void onSimulatorError(const QString & error);
|
||||
void onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, const int index, int value);
|
||||
void onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, int index, int value);
|
||||
void onjoystickAxisValueChanged(int axis, int value);
|
||||
void onjoystickButtonValueChanged(int button, bool state);
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _RADIOKNOBWIDGET_H_
|
||||
#define _RADIOKNOBWIDGET_H_
|
||||
#pragma once
|
||||
|
||||
#include "radiowidget.h"
|
||||
#include "boards.h"
|
||||
@@ -38,23 +37,23 @@ class RadioKnobWidget : public RadioWidget
|
||||
|
||||
public:
|
||||
|
||||
explicit RadioKnobWidget(Board::PotType type = Board::POT_WITH_DETENT, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
|
||||
explicit RadioKnobWidget(Board::FlexType type = Board::FLEX_POT_CENTER, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
|
||||
RadioWidget(parent, f)
|
||||
{
|
||||
init(type);
|
||||
}
|
||||
|
||||
explicit RadioKnobWidget(Board::PotType type, const QString & labelText, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
|
||||
explicit RadioKnobWidget(Board::FlexType type, const QString & labelText, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
|
||||
RadioWidget(labelText, value, parent, f)
|
||||
{
|
||||
init(type);
|
||||
}
|
||||
|
||||
void init(Board::PotType potType)
|
||||
void init(Board::FlexType potType)
|
||||
{
|
||||
m_type = RADIO_WIDGET_KNOB;
|
||||
|
||||
m_stepSize = (potType == Board::POT_MULTIPOS_SWITCH) ? 2048 / 5 : 1;
|
||||
m_stepSize = (potType == Board::FLEX_MULTIPOS) ? 2048 / 5 : 1;
|
||||
|
||||
m_toolTip = tr("<p>Value (input): <b>%1</b></p>");
|
||||
if (m_stepSize == 1)
|
||||
@@ -88,7 +87,7 @@ class RadioKnobWidget : public RadioWidget
|
||||
}
|
||||
|
||||
m_dial->setValue(m_value);
|
||||
|
||||
|
||||
connect(m_dial, &QDial::valueChanged, this, &RadioKnobWidget::setValueFromDial);
|
||||
connect(this, &RadioWidget::valueChanged, m_dial, &QDial::setValue);
|
||||
|
||||
@@ -157,6 +156,3 @@ class RadioKnobWidget : public RadioWidget
|
||||
QString m_toolTip;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _RADIOKNOBWIDGET_H_
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
#include "version.h"
|
||||
#include "boardfactories.h"
|
||||
|
||||
using namespace Simulator;
|
||||
|
||||
@@ -276,6 +277,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_INIT_RESOURCE(hwdefs);
|
||||
gBoardFactories = new BoardFactories();
|
||||
registerStorageFactories();
|
||||
registerOpenTxFirmwares();
|
||||
SimulatorLoader::registerSimulators();
|
||||
@@ -293,7 +296,7 @@ int main(int argc, char *argv[])
|
||||
simOptions.firmwareId = g.profile[profileId].fwType();
|
||||
}
|
||||
|
||||
// do not used saved simulatorId always refresh
|
||||
// DO NOT use saved simulatorId as could be changed in later releases
|
||||
simOptions.simulatorId = SimulatorLoader::findSimulatorByName(Firmware::getFirmwareForId(simOptions.firmwareId)->getSimulatorId());
|
||||
|
||||
if (simOptions.dataFolder.isEmpty())
|
||||
@@ -343,6 +346,11 @@ int main(int argc, char *argv[])
|
||||
g.sessionId(profileId);
|
||||
g.simuLastProfId(profileId);
|
||||
|
||||
// TODO: fix this in Firmware and Boards refactor
|
||||
// Append a dummy variant to firmware name to force the Board Type to be registered
|
||||
Firmware * simfw = Firmware::getFirmwareForId(simOptions.firmwareId + "-simulator");
|
||||
delete simfw;
|
||||
|
||||
// Set global firmware environment
|
||||
Firmware::setCurrentVariant(Firmware::getFirmwareForId(simOptions.firmwareId));
|
||||
//qDebug() << "current firmware:" << getCurrentFirmware()->getId();
|
||||
@@ -375,6 +383,7 @@ int finish(int exitCode)
|
||||
SimulatorLoader::unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterStorageFactories();
|
||||
gBoardFactories->unregisterBoardFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
|
||||
@@ -72,8 +72,11 @@ bool LabelsStorageFormat::loadBin(RadioData & radioData)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
board = loadInterface->getBoard();
|
||||
|
||||
radioData.generalSettings.convertLegacyConfiguration(board);
|
||||
|
||||
QByteArray modelsListBuffer;
|
||||
if (!loadFile(modelsListBuffer, "RADIO/models.txt")) {
|
||||
setError(tr("Cannot extract RADIO/models.txt"));
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
from os import path
|
||||
|
||||
def main(jsondir, template, placeholder, output):
|
||||
if not path.isdir(jsondir):
|
||||
raise Exception(jsondir + " is not a directory")
|
||||
|
||||
try:
|
||||
tmplt = open(template, "r")
|
||||
except:
|
||||
raise Exception("Unable to open template file " + template)
|
||||
|
||||
try:
|
||||
qrc = open(output, "w")
|
||||
except:
|
||||
raise Exception("Unable to open " + output + " for writing")
|
||||
|
||||
line = tmplt.readline()
|
||||
|
||||
while placeholder not in line and line != '':
|
||||
qrc.write(line)
|
||||
line = tmplt.readline()
|
||||
|
||||
for f in sorted(glob.iglob(path.join(jsondir, '*.json'), recursive = False)):
|
||||
fname = path.basename(f)
|
||||
qrc.write(' <file alias="' + fname + '">' + f + '</file>' + '\n')
|
||||
|
||||
line = tmplt.readline()
|
||||
|
||||
while line != '':
|
||||
qrc.write(line)
|
||||
line = tmplt.readline()
|
||||
|
||||
tmplt.close()
|
||||
qrc.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate hardware definitions resource file')
|
||||
parser.add_argument('-d', metavar='json files directory', required=True)
|
||||
parser.add_argument('-t', metavar='template file', required=True)
|
||||
parser.add_argument('-p', metavar='placeholder', required=True)
|
||||
parser.add_argument('-o', metavar='qrc file', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args.d, args.t, args.p, args.o)
|
||||
@@ -252,18 +252,9 @@ void OpenTxSimulator::setInputValue(int type, uint8_t index, int16_t value)
|
||||
switch (type) {
|
||||
case INPUT_SRC_ANALOG :
|
||||
case INPUT_SRC_STICK :
|
||||
setAnalogValue(index, value);
|
||||
break;
|
||||
case INPUT_SRC_KNOB :
|
||||
setAnalogValue(index + adcGetInputOffset(ADC_INPUT_FLEX), value);
|
||||
break;
|
||||
case INPUT_SRC_SLIDER :
|
||||
// TODO redo this when Companion refactored to use radio json adc files
|
||||
//setAnalogValue(index + adcGetInputOffset(ADC_INPUT_FLEX), value);
|
||||
static const int slideroffset = adcGetInputIdx("SL1", 3);
|
||||
//qDebug() << "SL1:" << slideroffset;
|
||||
if (slideroffset >= 0)
|
||||
setAnalogValue(index + slideroffset, value);
|
||||
setAnalogValue(index, value);
|
||||
break;
|
||||
case INPUT_SRC_TXVIN :
|
||||
if (adcGetMaxInputs(ADC_INPUT_VBAT) > 0) {
|
||||
|
||||
Reference in New Issue
Block a user