mirror of
https://github.com/opentx/opentx.git
synced 2025-07-23 16:25:16 +03:00
Merge with latest 2.3
This commit is contained in:
commit
5d131093ef
141 changed files with 5095 additions and 3762 deletions
|
@ -16,6 +16,8 @@ addons:
|
||||||
- libmpc3
|
- libmpc3
|
||||||
- libfox-1.6-dev
|
- libfox-1.6-dev
|
||||||
- libgtest-dev
|
- libgtest-dev
|
||||||
|
- lib32stdc++6
|
||||||
|
- libclang-common-6.0-dev
|
||||||
- clang-6.0
|
- clang-6.0
|
||||||
- python3-pip
|
- python3-pip
|
||||||
|
|
||||||
|
|
98
CREDITS.txt
98
CREDITS.txt
|
@ -2126,3 +2126,101 @@ Ian Parris
|
||||||
Danny Music
|
Danny Music
|
||||||
Eric Bissonnette
|
Eric Bissonnette
|
||||||
Riso LTD
|
Riso LTD
|
||||||
|
William Booth
|
||||||
|
Ferenc Kunkli
|
||||||
|
Offer Shmuely
|
||||||
|
Troy Atneosen
|
||||||
|
Long Technologies
|
||||||
|
John Jaugilas
|
||||||
|
Jan-Hinrich Klee
|
||||||
|
Hans-Reinhard Mette
|
||||||
|
Alejandro Casals Oliver
|
||||||
|
David Homewood
|
||||||
|
John Dunning
|
||||||
|
Konrad Helbach
|
||||||
|
Bernard Delpy
|
||||||
|
Raymond Ellsworth
|
||||||
|
Bogdan Musial
|
||||||
|
Гасак Сергей
|
||||||
|
Philip Garcia
|
||||||
|
Helder Simoes
|
||||||
|
Thomas Blanchin
|
||||||
|
Jean-Luc Mesnier
|
||||||
|
Michael Bajer
|
||||||
|
David Homewood
|
||||||
|
Marc Sanders
|
||||||
|
Буров Александр
|
||||||
|
Rudy T'Jolleyn
|
||||||
|
Jay Watkins
|
||||||
|
Blaz Vodopivec
|
||||||
|
David De Salvo
|
||||||
|
Willem Verschoren
|
||||||
|
Dennis Kathrens
|
||||||
|
Alan Aucote
|
||||||
|
Richard Jerome Danstrom
|
||||||
|
David Garcia-Mendia
|
||||||
|
Mark Jones
|
||||||
|
John Zseleczky
|
||||||
|
Xiao Sun
|
||||||
|
Glenn Harvey
|
||||||
|
Albrecht Friebel
|
||||||
|
Gunter Klemke
|
||||||
|
Travis McCarthy
|
||||||
|
Franz Zier
|
||||||
|
Ian Contessa
|
||||||
|
Sean Sadler
|
||||||
|
Richard F Janczak
|
||||||
|
Mateusz Dziadosz
|
||||||
|
Thomas Merchant
|
||||||
|
M L Perkins
|
||||||
|
Stefano Boggia
|
||||||
|
Новоселов Юрий
|
||||||
|
James Rhodes
|
||||||
|
Peter Gaskill
|
||||||
|
Jacques Temey
|
||||||
|
Anthony Challis
|
||||||
|
Gerard Falaise
|
||||||
|
George McGinnis
|
||||||
|
Antoine Soulie
|
||||||
|
Tjeerd Jager
|
||||||
|
Bertold Van den Bergh
|
||||||
|
Stefanie Zerbe
|
||||||
|
James Mandelbaum
|
||||||
|
Javier J. Cordovez
|
||||||
|
Jess Barkley
|
||||||
|
Schneider Modell
|
||||||
|
Michael Hasselgaard
|
||||||
|
Thomas Young
|
||||||
|
Непочатов Алексей
|
||||||
|
Thomas Goebel
|
||||||
|
Joseph Macias
|
||||||
|
Paw Melin-Nielsen
|
||||||
|
Liam O'Brien
|
||||||
|
Ronald B Backman
|
||||||
|
Corvus Inspection Services Inc
|
||||||
|
Stuart Posnett
|
||||||
|
Clark Emerick
|
||||||
|
Helmut Sippel
|
||||||
|
Jhon Lennon Silva do Nascimento
|
||||||
|
Peter McCarthy
|
||||||
|
Bob Brown
|
||||||
|
Claude Lawyer
|
||||||
|
Peter Fithern
|
||||||
|
Michael Hoffman
|
||||||
|
Tim Smith
|
||||||
|
OpenSki Institute
|
||||||
|
Simon Melov
|
||||||
|
Richard Podolsky
|
||||||
|
James Wilson
|
||||||
|
John Norrbin
|
||||||
|
James Goins
|
||||||
|
Phillip Nguyen
|
||||||
|
Jeffrey M Engel
|
||||||
|
Richard Marotto
|
||||||
|
Greg Bell
|
||||||
|
Scott Geer
|
||||||
|
Thomas Abshier
|
||||||
|
Ernst Camenzind
|
||||||
|
Radomir Sterba
|
||||||
|
Ignacio Barrio
|
||||||
|
Bradley Murchie
|
||||||
|
|
|
@ -46,6 +46,8 @@ QString AbstractItemModel::idToString(const int value)
|
||||||
return "CustomFuncResetParam";
|
return "CustomFuncResetParam";
|
||||||
case IMID_TeleSource:
|
case IMID_TeleSource:
|
||||||
return "TeleSource";
|
return "TeleSource";
|
||||||
|
case IMID_RssiSource:
|
||||||
|
return "RssiSource";
|
||||||
case IMID_CurveRefType:
|
case IMID_CurveRefType:
|
||||||
return "CurveRefType";
|
return "CurveRefType";
|
||||||
case IMID_CurveRefFunc:
|
case IMID_CurveRefFunc:
|
||||||
|
@ -109,7 +111,6 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
|
||||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, firmware->getCapability(LuaOutputsPerScript), i * 16);
|
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_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::MaxAnalogs));
|
||||||
addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, firmware->getCapability(RotaryEncoders));
|
|
||||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
|
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
|
||||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches));
|
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches));
|
||||||
|
@ -170,7 +171,6 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||||
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
||||||
addItems(SWITCH_TYPE_FLIGHT_MODE, -firmware->getCapability(FlightModes));
|
addItems(SWITCH_TYPE_FLIGHT_MODE, -firmware->getCapability(FlightModes));
|
||||||
addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
|
addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
|
||||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, -firmware->getCapability(RotaryEncoders));
|
|
||||||
addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
|
addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
|
||||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
|
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
|
||||||
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
|
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
|
||||||
|
@ -181,7 +181,6 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||||
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
|
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
|
||||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
|
addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
|
||||||
addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
|
addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
|
||||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, firmware->getCapability(RotaryEncoders));
|
|
||||||
addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
|
addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
|
||||||
addItems(SWITCH_TYPE_FLIGHT_MODE, firmware->getCapability(FlightModes));
|
addItems(SWITCH_TYPE_FLIGHT_MODE, firmware->getCapability(FlightModes));
|
||||||
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
||||||
|
@ -420,7 +419,7 @@ CustomFuncActionItemModel::CustomFuncActionItemModel(const GeneralSettings * con
|
||||||
|
|
||||||
void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||||
{
|
{
|
||||||
item->setText(CustomFunctionData(AssignFunc(value)).funcToString(modelData));
|
item->setText(CustomFunctionData::funcToString((AssignFunc)value, modelData));
|
||||||
item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available);
|
item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,9 +444,9 @@ CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettin
|
||||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||||
{
|
{
|
||||||
setId(IMID_CustomFuncResetParam);
|
setId(IMID_CustomFuncResetParam);
|
||||||
setUpdateMask(IMUE_TeleSensors);
|
setUpdateMask(IMUE_TeleSensors | IMUE_Timers);
|
||||||
|
|
||||||
for (int i = 0; i < CustomFunctionData::resetParamCount(modelData); i++) {
|
for (int i = 0; i < CustomFunctionData::resetParamCount(); i++) {
|
||||||
QStandardItem * modelItem = new QStandardItem();
|
QStandardItem * modelItem = new QStandardItem();
|
||||||
modelItem->setData(i, IMDR_Id);
|
modelItem->setData(i, IMDR_Id);
|
||||||
setDynamicItemData(modelItem, i);
|
setDynamicItemData(modelItem, i);
|
||||||
|
@ -457,10 +456,8 @@ CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettin
|
||||||
|
|
||||||
void CustomFuncResetParamItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
void CustomFuncResetParamItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||||
{
|
{
|
||||||
CustomFunctionData cfd = CustomFunctionData(AssignFunc::FuncReset);
|
item->setText(CustomFunctionData::resetToString(value, modelData));
|
||||||
cfd.param = value;
|
item->setData(CustomFunctionData::isResetParamAvailable(value, modelData), IMDR_Available);
|
||||||
item->setText(cfd.paramToString(modelData));
|
|
||||||
item->setData(CustomFunctionData::isResetParamAvailable(modelData, value), IMDR_Available);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFuncResetParamItemModel::update(const int event)
|
void CustomFuncResetParamItemModel::update(const int event)
|
||||||
|
@ -488,7 +485,7 @@ TelemetrySourceItemModel::TelemetrySourceItemModel(const GeneralSettings * const
|
||||||
if (!modelData)
|
if (!modelData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setUpdateMask(IMUE_TeleSensors);
|
setUpdateMask(IMUE_TeleSensors | IMUE_Modules);
|
||||||
const int count = firmware->getCapability(Sensors);
|
const int count = firmware->getCapability(Sensors);
|
||||||
|
|
||||||
for (int i = -count; i <= count; ++i) {
|
for (int i = -count; i <= count; ++i) {
|
||||||
|
@ -519,6 +516,49 @@ void TelemetrySourceItemModel::update(const int event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// RssiSourceItemModel
|
||||||
|
//
|
||||||
|
|
||||||
|
RssiSourceItemModel::RssiSourceItemModel(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_RssiSource);
|
||||||
|
|
||||||
|
if (!modelData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setUpdateMask(IMUE_TeleSensors | IMUE_Modules);
|
||||||
|
|
||||||
|
for (int i = 0; i <= firmware->getCapability(Sensors); ++i) {
|
||||||
|
QStandardItem * modelItem = new QStandardItem();
|
||||||
|
modelItem->setData(i, IMDR_Id);
|
||||||
|
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
|
||||||
|
setDynamicItemData(modelItem, i);
|
||||||
|
appendRow(modelItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RssiSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||||
|
{
|
||||||
|
item->setText(SensorData::rssiSensorToString(modelData, value));
|
||||||
|
item->setData(SensorData::isRssiSensorAvailable(modelData, value), IMDR_Available);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RssiSourceItemModel::update(const int event)
|
||||||
|
{
|
||||||
|
if (doUpdate(event)) {
|
||||||
|
emit aboutToBeUpdated();
|
||||||
|
|
||||||
|
for (int i = 0; i < rowCount(); ++i) {
|
||||||
|
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
emit updateComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// CurveRefTypeItemModel
|
// CurveRefTypeItemModel
|
||||||
//
|
//
|
||||||
|
@ -624,6 +664,9 @@ void CompoundItemModelFactory::addItemModel(const int id)
|
||||||
case AbstractItemModel::IMID_TeleSource:
|
case AbstractItemModel::IMID_TeleSource:
|
||||||
registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||||
break;
|
break;
|
||||||
|
case AbstractItemModel::IMID_RssiSource:
|
||||||
|
registerItemModel(new RssiSourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||||
|
break;
|
||||||
case AbstractItemModel::IMID_CurveRefType:
|
case AbstractItemModel::IMID_CurveRefType:
|
||||||
registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType));
|
registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||||
break;
|
break;
|
||||||
|
@ -674,6 +717,16 @@ AbstractItemModel * CompoundItemModelFactory::getItemModel(const int id) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractItemModel * CompoundItemModelFactory::getItemModel(const QString name) const
|
||||||
|
{
|
||||||
|
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||||
|
if (itemModel->getName() == name)
|
||||||
|
return itemModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool CompoundItemModelFactory::isItemModelRegistered(const int id) const
|
bool CompoundItemModelFactory::isItemModelRegistered(const int id) const
|
||||||
{
|
{
|
||||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMPOUNDITEMMODELS_H
|
#pragma once
|
||||||
#define COMPOUNDITEMMODELS_H
|
|
||||||
|
|
||||||
#include "rawsource.h"
|
#include "rawsource.h"
|
||||||
#include "rawswitch.h"
|
#include "rawswitch.h"
|
||||||
|
@ -44,6 +43,7 @@ class AbstractItemModel: public QStandardItemModel
|
||||||
IMID_CustomFuncAction,
|
IMID_CustomFuncAction,
|
||||||
IMID_CustomFuncResetParam,
|
IMID_CustomFuncResetParam,
|
||||||
IMID_TeleSource,
|
IMID_TeleSource,
|
||||||
|
IMID_RssiSource,
|
||||||
IMID_CurveRefType,
|
IMID_CurveRefType,
|
||||||
IMID_CurveRefFunc,
|
IMID_CurveRefFunc,
|
||||||
IMID_ReservedCount,
|
IMID_ReservedCount,
|
||||||
|
@ -78,8 +78,9 @@ class AbstractItemModel: public QStandardItemModel
|
||||||
IMUE_Scripts = 1 << 7,
|
IMUE_Scripts = 1 << 7,
|
||||||
IMUE_TeleSensors = 1 << 8,
|
IMUE_TeleSensors = 1 << 8,
|
||||||
IMUE_Timers = 1 << 9,
|
IMUE_Timers = 1 << 9,
|
||||||
|
IMUE_Modules = 1 << 10,
|
||||||
IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
|
IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
|
||||||
IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers
|
IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers | IMUE_Modules
|
||||||
};
|
};
|
||||||
Q_ENUM(ItemModelUpdateEvent)
|
Q_ENUM(ItemModelUpdateEvent)
|
||||||
|
|
||||||
|
@ -305,6 +306,21 @@ class TelemetrySourceItemModel: public AbstractDynamicItemModel
|
||||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RssiSourceItemModel: public AbstractDynamicItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RssiSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||||
|
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||||
|
virtual ~RssiSourceItemModel() {};
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||||
|
};
|
||||||
|
|
||||||
class CurveRefTypeItemModel : public AbstractStaticItemModel
|
class CurveRefTypeItemModel : public AbstractStaticItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -347,6 +363,7 @@ class CompoundItemModelFactory
|
||||||
void unregisterItemModel(const int id);
|
void unregisterItemModel(const int id);
|
||||||
bool isItemModelRegistered(const int id) const;
|
bool isItemModelRegistered(const int id) const;
|
||||||
AbstractItemModel * getItemModel(const int id) const;
|
AbstractItemModel * getItemModel(const int id) const;
|
||||||
|
AbstractItemModel * getItemModel(const QString name) const;
|
||||||
void update(const int event = AbstractItemModel::IMUE_SystemRefresh);
|
void update(const int event = AbstractItemModel::IMUE_SystemRefresh);
|
||||||
void dumpAllItemModelContents() const;
|
void dumpAllItemModelContents() const;
|
||||||
|
|
||||||
|
@ -361,5 +378,3 @@ class CompoundItemModelFactory
|
||||||
private:
|
private:
|
||||||
void setSourceId(AbstractItemModel * itemModel);
|
void setSourceId(AbstractItemModel * itemModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMPOUNDITEMMODELS_H
|
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) :
|
FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
|
|
@ -2,27 +2,34 @@
|
||||||
set(firmwares_SRCS
|
set(firmwares_SRCS
|
||||||
adjustmentreference.cpp
|
adjustmentreference.cpp
|
||||||
boards.cpp
|
boards.cpp
|
||||||
|
curvedata.cpp
|
||||||
curvereference.cpp
|
curvereference.cpp
|
||||||
customfunctiondata.cpp
|
customfunctiondata.cpp
|
||||||
eeprominterface.cpp
|
eeprominterface.cpp
|
||||||
generalsettings.cpp
|
generalsettings.cpp
|
||||||
gvardata.cpp
|
gvardata.cpp
|
||||||
io_data.cpp
|
input_data.cpp
|
||||||
|
flightmodedata.cpp
|
||||||
|
heli_data.cpp
|
||||||
logicalswitchdata.cpp
|
logicalswitchdata.cpp
|
||||||
|
mixdata.cpp
|
||||||
modeldata.cpp
|
modeldata.cpp
|
||||||
moduledata.cpp
|
moduledata.cpp
|
||||||
multiprotocols.cpp
|
multiprotocols.cpp
|
||||||
|
output_data.cpp
|
||||||
radiodata.cpp
|
radiodata.cpp
|
||||||
radiodataconversionstate.cpp
|
radiodataconversionstate.cpp
|
||||||
rawsource.cpp
|
rawsource.cpp
|
||||||
rawswitch.cpp
|
rawswitch.cpp
|
||||||
sensordata.cpp
|
sensordata.cpp
|
||||||
telem_data.cpp
|
telem_data.cpp
|
||||||
|
timerdata.cpp
|
||||||
afhds3.cpp
|
afhds3.cpp
|
||||||
ersky9x/ersky9xeeprom.cpp
|
ersky9x/ersky9xeeprom.cpp
|
||||||
ersky9x/ersky9xinterface.cpp
|
ersky9x/ersky9xinterface.cpp
|
||||||
opentx/opentxeeprom.cpp
|
opentx/opentxeeprom.cpp
|
||||||
opentx/opentxinterface.cpp
|
opentx/opentxinterface.cpp
|
||||||
|
datahelpers.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
||||||
|
@ -30,7 +37,6 @@ string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
||||||
list(APPEND firmwares_HDRS
|
list(APPEND firmwares_HDRS
|
||||||
eepromimportexport.h
|
eepromimportexport.h
|
||||||
moduledata.h
|
moduledata.h
|
||||||
helpersdata.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(firmwares_QT
|
set(firmwares_QT
|
||||||
|
|
48
companion/src/firmwares/curvedata.cpp
Normal file
48
companion/src/firmwares/curvedata.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "curvedata.h"
|
||||||
|
#include "radiodata.h"
|
||||||
|
|
||||||
|
CurveData::CurveData()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurveData::clear(int count)
|
||||||
|
{
|
||||||
|
memset(reinterpret_cast<void *>(this), 0, sizeof(CurveData));
|
||||||
|
this->count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CurveData::isEmpty() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (points[i].y != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CurveData::nameToString(const int idx) const
|
||||||
|
{
|
||||||
|
return RadioData::getElementName(tr("CV"), idx + 1, name);
|
||||||
|
}
|
56
companion/src/firmwares/curvedata.h
Normal file
56
companion/src/firmwares/curvedata.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class CurvePoint {
|
||||||
|
public:
|
||||||
|
int8_t x;
|
||||||
|
int8_t y;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CURVEDATA_NAME_LEN 6
|
||||||
|
|
||||||
|
class CurveData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(CurveData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum CurveType {
|
||||||
|
CURVE_TYPE_STANDARD,
|
||||||
|
CURVE_TYPE_CUSTOM,
|
||||||
|
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
||||||
|
};
|
||||||
|
|
||||||
|
CurveData();
|
||||||
|
|
||||||
|
CurveType type;
|
||||||
|
bool smooth;
|
||||||
|
int count;
|
||||||
|
CurvePoint points[CPN_MAX_POINTS];
|
||||||
|
char name[CURVEDATA_NAME_LEN + 1];
|
||||||
|
|
||||||
|
void clear(int count = 5);
|
||||||
|
bool isEmpty() const;
|
||||||
|
QString nameToString(const int idx) const;
|
||||||
|
};
|
|
@ -22,6 +22,17 @@
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
#include "radiodata.h"
|
#include "radiodata.h"
|
||||||
#include "radiodataconversionstate.h"
|
#include "radiodataconversionstate.h"
|
||||||
|
#include "compounditemmodels.h"
|
||||||
|
|
||||||
|
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
||||||
|
{
|
||||||
|
cstate.setComponent(tr("CFN"), 8);
|
||||||
|
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
||||||
|
swtch.convert(cstate);
|
||||||
|
if (func == FuncVolume || func == FuncBacklight || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
||||||
|
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CustomFunctionData::clear()
|
void CustomFunctionData::clear()
|
||||||
{
|
{
|
||||||
|
@ -36,12 +47,19 @@ bool CustomFunctionData::isEmpty() const
|
||||||
return (swtch.type == SWITCH_TYPE_NONE);
|
return (swtch.type == SWITCH_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CustomFunctionData::nameToString(int index, bool globalContext) const
|
// static
|
||||||
|
QString CustomFunctionData::nameToString(const int index, const bool globalContext)
|
||||||
{
|
{
|
||||||
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true);
|
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CustomFunctionData::funcToString(const ModelData * model) const
|
QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||||
|
{
|
||||||
|
return funcToString(func, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData * model)
|
||||||
{
|
{
|
||||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
|
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
|
||||||
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||||
|
@ -76,7 +94,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||||
else if (func == FuncPlayValue)
|
else if (func == FuncPlayValue)
|
||||||
return tr("Play Value");
|
return tr("Play Value");
|
||||||
else if (func == FuncPlayScript)
|
else if (func == FuncPlayScript)
|
||||||
return tr("Play Script");
|
return tr("Lua Script");
|
||||||
else if (func == FuncLogs)
|
else if (func == FuncLogs)
|
||||||
return tr("SD Logs");
|
return tr("SD Logs");
|
||||||
else if (func == FuncVolume)
|
else if (func == FuncVolume)
|
||||||
|
@ -94,9 +112,9 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||||
else if (func == FuncSetFailsafe)
|
else if (func == FuncSetFailsafe)
|
||||||
return tr("Set Failsafe");
|
return tr("Set Failsafe");
|
||||||
else if (func == FuncRangeCheckInternalModule)
|
else if (func == FuncRangeCheckInternalModule)
|
||||||
return tr("RangeCheck Int. Module");
|
return tr("Range Check Int. Module");
|
||||||
else if (func == FuncRangeCheckExternalModule)
|
else if (func == FuncRangeCheckExternalModule)
|
||||||
return tr("RangeCheck Ext. Module");
|
return tr("Range Check Ext. Module");
|
||||||
else if (func == FuncBindInternalModule)
|
else if (func == FuncBindInternalModule)
|
||||||
return tr("Bind Int. Module");
|
return tr("Bind Int. Module");
|
||||||
else if (func == FuncBindExternalModule)
|
else if (func == FuncBindExternalModule)
|
||||||
|
@ -106,53 +124,6 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox * b, unsigned int value = 0)
|
|
||||||
{
|
|
||||||
int val = 0;
|
|
||||||
Firmware * firmware = Firmware::getCurrentVariant();
|
|
||||||
|
|
||||||
for (int i = 0; i < CPN_MAX_TIMERS; i++, val++) {
|
|
||||||
if (i < firmware->getCapability(Timers)) {
|
|
||||||
RawSource item = RawSource(SOURCE_TYPE_SPECIAL, i + SOURCE_TYPE_SPECIAL_TIMER1_IDX);
|
|
||||||
b->addItem(item.toString(model), val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b->addItem(tr("Flight"), val++);
|
|
||||||
b->addItem(tr("Telemetry"), val++);
|
|
||||||
|
|
||||||
int reCount = firmware->getCapability(RotaryEncoders);
|
|
||||||
if (reCount == 1) {
|
|
||||||
b->addItem(tr("Rotary Encoder"), val++);
|
|
||||||
}
|
|
||||||
else if (reCount == 2) {
|
|
||||||
b->addItem(tr("REa"), val++);
|
|
||||||
b->addItem(tr("REb"), val++);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model) {
|
|
||||||
for (int i = 0; i < firmware->getCapability(Sensors); ++i) {
|
|
||||||
if (model->sensorData[i].isAvailable()) {
|
|
||||||
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3 * i);
|
|
||||||
b->addItem(item.toString(model), val + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b->setCurrentIndex(b->findData(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomFunctionData::populatePlaySoundParams(QStringList & qs)
|
|
||||||
{
|
|
||||||
qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ;
|
|
||||||
qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomFunctionData::populateHapticParams(QStringList & qs)
|
|
||||||
{
|
|
||||||
qs << "0" << "1" << "2" << "3";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CustomFunctionData::paramToString(const ModelData * model) const
|
QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||||
{
|
{
|
||||||
QStringList qs;
|
QStringList qs;
|
||||||
|
@ -163,31 +134,16 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||||
return QString("%1").arg(param / 10.0) + tr("s");
|
return QString("%1").arg(param / 10.0) + tr("s");
|
||||||
}
|
}
|
||||||
else if (func == FuncPlaySound) {
|
else if (func == FuncPlaySound) {
|
||||||
CustomFunctionData::populatePlaySoundParams(qs);
|
return playSoundToString(param);
|
||||||
if (param >= 0 && param < (int)qs.count())
|
|
||||||
return qs.at(param);
|
|
||||||
else
|
|
||||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
|
||||||
}
|
}
|
||||||
else if (func == FuncPlayHaptic) {
|
else if (func == FuncPlayHaptic) {
|
||||||
CustomFunctionData::populateHapticParams(qs);
|
return harpicToString(param);
|
||||||
if (param >= 0 && param < (int)qs.count())
|
|
||||||
return qs.at(param);
|
|
||||||
else
|
|
||||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
|
||||||
}
|
}
|
||||||
else if (func == FuncReset) {
|
else if (func == FuncReset) {
|
||||||
QComboBox cb;
|
return resetToString(param, model);
|
||||||
CustomFunctionData::populateResetParams(model, &cb);
|
|
||||||
int pos = cb.findData(param);
|
|
||||||
if (pos >= 0)
|
|
||||||
return cb.itemText(pos);
|
|
||||||
else
|
|
||||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
|
||||||
}
|
}
|
||||||
else if (func == FuncVolume || func == FuncPlayValue || func == FuncBacklight) {
|
else if (func == FuncVolume || func == FuncPlayValue || func == FuncBacklight) {
|
||||||
RawSource item(param);
|
return RawSource(param).toString(model);
|
||||||
return item.toString(model);
|
|
||||||
}
|
}
|
||||||
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
|
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
|
||||||
if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) {
|
if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) {
|
||||||
|
@ -200,16 +156,14 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||||
else if (func >= FuncAdjustGV1 && func < FuncCount) {
|
else if (func >= FuncAdjustGV1 && func < FuncCount) {
|
||||||
switch (adjustMode) {
|
switch (adjustMode) {
|
||||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||||
return tr("Value ") + QString("%1").arg(param);
|
return gvarAdjustModeToString(adjustMode) + QString(" %1").arg(param);
|
||||||
case FUNC_ADJUST_GVAR_SOURCE:
|
case FUNC_ADJUST_GVAR_SOURCE:
|
||||||
case FUNC_ADJUST_GVAR_GVAR:
|
case FUNC_ADJUST_GVAR_GVAR:
|
||||||
return RawSource(param).toString();
|
return RawSource(param).toString();
|
||||||
case FUNC_ADJUST_GVAR_INCDEC:
|
case FUNC_ADJUST_GVAR_INCDEC:
|
||||||
float val;
|
const float val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
|
||||||
QString unit;
|
const QString unit = model->gvarData[func - FuncAdjustGV1].unitToString();
|
||||||
val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
|
return gvarAdjustModeToString(adjustMode) + QString(": %1%2").arg(val).arg(unit);
|
||||||
unit = model->gvarData[func - FuncAdjustGV1].unitToString();
|
|
||||||
return QString("Increment: %1%2").arg(val).arg(unit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
@ -217,15 +171,20 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||||
|
|
||||||
QString CustomFunctionData::repeatToString() const
|
QString CustomFunctionData::repeatToString() const
|
||||||
{
|
{
|
||||||
if (repeatParam == -1) {
|
return repeatToString(repeatParam);
|
||||||
return tr("played once, not during startup");
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString CustomFunctionData::repeatToString(const int value)
|
||||||
|
{
|
||||||
|
if (value == -1) {
|
||||||
|
return tr("Played once, not during startup");
|
||||||
}
|
}
|
||||||
else if (repeatParam == 0) {
|
else if (value == 0) {
|
||||||
return "";
|
return tr("No repeat");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned int step = 1;
|
return tr("Repeat %1s").arg(value);
|
||||||
return tr("repeat(%1s)").arg(step * repeatParam);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +205,7 @@ QString CustomFunctionData::enabledToString() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool CustomFunctionData::isFuncAvailable(int index)
|
bool CustomFunctionData::isFuncAvailable(const int index)
|
||||||
{
|
{
|
||||||
Firmware * fw = getCurrentFirmware();
|
Firmware * fw = getCurrentFirmware();
|
||||||
|
|
||||||
|
@ -265,7 +224,7 @@ bool CustomFunctionData::isFuncAvailable(int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int CustomFunctionData::funcContext(int index)
|
int CustomFunctionData::funcContext(const int index)
|
||||||
{
|
{
|
||||||
int ret = AllFunctionContexts;
|
int ret = AllFunctionContexts;
|
||||||
|
|
||||||
|
@ -276,16 +235,42 @@ int CustomFunctionData::funcContext(int index)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int CustomFunctionData::resetParamCount(const ModelData * model)
|
QString CustomFunctionData::resetToString(const int value, const ModelData * model)
|
||||||
{
|
{
|
||||||
QComboBox cb;
|
Firmware * firmware = getCurrentFirmware();
|
||||||
CustomFunctionData::populateResetParams(model, &cb);
|
int step = CPN_MAX_TIMERS;
|
||||||
return cb.count();
|
|
||||||
|
if (value < step) {
|
||||||
|
if (value < firmware->getCapability(Timers))
|
||||||
|
return RawSource(SOURCE_TYPE_SPECIAL, value + SOURCE_TYPE_SPECIAL_TIMER1_IDX).toString(model);
|
||||||
|
else
|
||||||
|
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < ++step)
|
||||||
|
return tr("Flight");
|
||||||
|
|
||||||
|
if (value < ++step)
|
||||||
|
return tr("Telemetry");
|
||||||
|
|
||||||
|
if (value < step + firmware->getCapability(Sensors))
|
||||||
|
return RawSource(SOURCE_TYPE_TELEMETRY, 3 * (value - step)).toString(model);
|
||||||
|
|
||||||
|
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int index)
|
int CustomFunctionData::resetParamCount()
|
||||||
|
{
|
||||||
|
Firmware * firmware = getCurrentFirmware();
|
||||||
|
|
||||||
|
return CPN_MAX_TIMERS + 2 + firmware->getCapability(Sensors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool CustomFunctionData::isResetParamAvailable(const int index, const ModelData * model)
|
||||||
{
|
{
|
||||||
Firmware * firmware = getCurrentFirmware();
|
Firmware * firmware = getCurrentFirmware();
|
||||||
|
|
||||||
|
@ -295,20 +280,121 @@ bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int inde
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders))
|
else if (index < CPN_MAX_TIMERS + 2)
|
||||||
return true;
|
return true;
|
||||||
else if (model && index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders) + firmware->getCapability(Sensors))
|
else if (model && index < resetParamCount())
|
||||||
return model->sensorData[index - CPN_MAX_TIMERS - firmware->getCapability(RotaryEncoders)].isAvailable();
|
return model->sensorData[index - (CPN_MAX_TIMERS + 2)].isAvailable();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
QString CustomFunctionData::harpicToString() const
|
||||||
{
|
{
|
||||||
cstate.setComponent(tr("CFN"), 8);
|
return harpicToString(param);
|
||||||
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
}
|
||||||
swtch.convert(cstate);
|
|
||||||
if (func == FuncVolume || func == FuncBacklight || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
// static
|
||||||
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
QString CustomFunctionData::harpicToString(const int value)
|
||||||
|
{
|
||||||
|
return QString("%1").arg(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QStringList CustomFunctionData::playSoundStringList()
|
||||||
|
{
|
||||||
|
return QStringList({ tr("Beep 1"), tr("Beep 2"), tr("Beep 3"), tr("Warn 1"), tr("Warn 2"), tr("Cheep"), tr("Ratata"), tr("Tick"),
|
||||||
|
tr("Siren"), tr("Ring"), tr("Sci Fi"), tr("Robot"), tr("Chirp"), tr("Tada"), tr("Cricket"), tr("Alarm Clock") });
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CustomFunctionData::playSoundToString() const
|
||||||
|
{
|
||||||
|
return playSoundToString(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString CustomFunctionData::playSoundToString(const int value)
|
||||||
|
{
|
||||||
|
const QStringList strl = playSoundStringList();
|
||||||
|
if (value < strl.count())
|
||||||
|
return strl.at(value);
|
||||||
|
else
|
||||||
|
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CustomFunctionData::gvarAdjustModeToString() const
|
||||||
|
{
|
||||||
|
return gvarAdjustModeToString(adjustMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString CustomFunctionData::gvarAdjustModeToString(const int value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||||
|
return tr("Value");
|
||||||
|
case FUNC_ADJUST_GVAR_SOURCE:
|
||||||
|
return tr("Source");
|
||||||
|
case FUNC_ADJUST_GVAR_GVAR:
|
||||||
|
return tr("Global Variable");
|
||||||
|
case FUNC_ADJUST_GVAR_INCDEC:
|
||||||
|
return tr("Inc/Decrement");
|
||||||
|
default:
|
||||||
|
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * CustomFunctionData::repeatItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName("customfunctiondata.repeat");
|
||||||
|
|
||||||
|
for (int i = -1; i <= 60; i++) {
|
||||||
|
mdl->appendToItemList(repeatToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * CustomFunctionData::playSoundItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName("customfunctiondata.playsound");
|
||||||
|
|
||||||
|
for (int i = 0; i < playSoundStringList().count(); i++) {
|
||||||
|
mdl->appendToItemList(playSoundToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * CustomFunctionData::harpicItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName("customfunctiondata.harpic");
|
||||||
|
|
||||||
|
for (int i = 0; i <= 3; i++) {
|
||||||
|
mdl->appendToItemList(harpicToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * CustomFunctionData::gvarAdjustModeItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName("customfunctiondata.gvaradjustmode");
|
||||||
|
|
||||||
|
for (int i = 0; i < FUNC_ADJUST_GVAR_COUNT; i++) {
|
||||||
|
mdl->appendToItemList(gvarAdjustModeToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CUSTOMFUNCTIONDATA_H
|
#pragma once
|
||||||
#define CUSTOMFUNCTIONDATA_H
|
|
||||||
|
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
@ -32,6 +31,7 @@ class Firmware;
|
||||||
class ModelData;
|
class ModelData;
|
||||||
class GeneralSettings;
|
class GeneralSettings;
|
||||||
class RadioDataConversionState;
|
class RadioDataConversionState;
|
||||||
|
class AbstractStaticItemModel;
|
||||||
|
|
||||||
enum AssignFunc {
|
enum AssignFunc {
|
||||||
FuncOverrideCH1 = 0,
|
FuncOverrideCH1 = 0,
|
||||||
|
@ -78,7 +78,8 @@ enum GVarAdjustModes
|
||||||
FUNC_ADJUST_GVAR_CONSTANT,
|
FUNC_ADJUST_GVAR_CONSTANT,
|
||||||
FUNC_ADJUST_GVAR_SOURCE,
|
FUNC_ADJUST_GVAR_SOURCE,
|
||||||
FUNC_ADJUST_GVAR_GVAR,
|
FUNC_ADJUST_GVAR_GVAR,
|
||||||
FUNC_ADJUST_GVAR_INCDEC
|
FUNC_ADJUST_GVAR_INCDEC,
|
||||||
|
FUNC_ADJUST_GVAR_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
class CustomFunctionData {
|
class CustomFunctionData {
|
||||||
|
@ -102,25 +103,33 @@ class CustomFunctionData {
|
||||||
unsigned int adjustMode;
|
unsigned int adjustMode;
|
||||||
int repeatParam;
|
int repeatParam;
|
||||||
|
|
||||||
void clear();
|
|
||||||
bool isEmpty() const;
|
|
||||||
QString nameToString(int index, bool globalContext = false) const;
|
|
||||||
QString funcToString(const ModelData * model = nullptr) const;
|
|
||||||
QString paramToString(const ModelData * model) const;
|
|
||||||
QString repeatToString() const;
|
|
||||||
QString enabledToString() const;
|
|
||||||
|
|
||||||
static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value);
|
|
||||||
static void populatePlaySoundParams(QStringList & qs);
|
|
||||||
static void populateHapticParams(QStringList & qs);
|
|
||||||
static bool isFuncAvailable(int index);
|
|
||||||
static int funcContext(int index);
|
|
||||||
static int resetParamCount(const ModelData * model);
|
|
||||||
static bool isResetParamAvailable(const ModelData * model, int index);
|
|
||||||
|
|
||||||
void convert(RadioDataConversionState & cstate);
|
void convert(RadioDataConversionState & cstate);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
bool isEmpty() const;
|
||||||
|
QString funcToString(const ModelData * model = nullptr) const;
|
||||||
|
QString paramToString(const ModelData * model = nullptr) const;
|
||||||
|
QString repeatToString() const;
|
||||||
|
QString enabledToString() const;
|
||||||
|
QString playSoundToString() const;
|
||||||
|
QString harpicToString() const;
|
||||||
|
QString gvarAdjustModeToString() const;
|
||||||
|
|
||||||
|
static QString nameToString(const int index, const bool globalContext = false);
|
||||||
|
static QString funcToString(const AssignFunc func, const ModelData * model = nullptr);
|
||||||
|
static bool isFuncAvailable(const int index);
|
||||||
|
static int funcContext(const int index);
|
||||||
|
static QString resetToString(const int value, const ModelData * model = nullptr);
|
||||||
|
static int resetParamCount();
|
||||||
|
static bool isResetParamAvailable(const int index, const ModelData * model = nullptr);
|
||||||
|
static QString repeatToString(const int value);
|
||||||
|
static QStringList playSoundStringList();
|
||||||
|
static QString playSoundToString(const int value);
|
||||||
|
static QString harpicToString(const int value);
|
||||||
|
static QStringList gvarAdjustModeStringList();
|
||||||
|
static QString gvarAdjustModeToString(const int value);
|
||||||
|
static AbstractStaticItemModel * repeatItemModel();
|
||||||
|
static AbstractStaticItemModel * playSoundItemModel();
|
||||||
|
static AbstractStaticItemModel * harpicItemModel();
|
||||||
|
static AbstractStaticItemModel * gvarAdjustModeItemModel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // CUSTOMFUNCTIONDATA_H
|
|
||||||
|
|
70
companion/src/firmwares/datahelpers.cpp
Normal file
70
companion/src/firmwares/datahelpers.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "datahelpers.h"
|
||||||
|
|
||||||
|
QString DataHelpers::boolToString(const bool value, const BoolFormat format)
|
||||||
|
{
|
||||||
|
static const char *strings[] = {
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "Disabled"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "Enabled"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "OFF"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "ON"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "False"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "True"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "N"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "Y"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "No"),
|
||||||
|
QT_TRANSLATE_NOOP("DataHelpers", "Yes")
|
||||||
|
};
|
||||||
|
|
||||||
|
return QCoreApplication::translate("DataHelpers", strings[format * 2 + value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DataHelpers::getElementName(const QString & prefix, const unsigned int index, const char * name, const bool padding)
|
||||||
|
{
|
||||||
|
QString result = prefix;
|
||||||
|
result.append(padding ? QString("%1").arg(index, 2, 10, QChar('0')) : QString("%1").arg(index));
|
||||||
|
if (name && QString(name).trimmed().length() > 0)
|
||||||
|
result.append(":" + QString(name).trimmed());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DataHelpers::timeToString(const int value, const unsigned int mask)
|
||||||
|
{
|
||||||
|
bool negative = value < 0 ? true : false;
|
||||||
|
int val = abs(value);
|
||||||
|
|
||||||
|
QString result = QString("%1").arg(negative ? "-" : ((mask & TIMESTR_MASK_PADSIGN) ? " " : ""));
|
||||||
|
|
||||||
|
if (mask & TIMESTR_MASK_HRSMINS) {
|
||||||
|
int hours = val / 3600;
|
||||||
|
if (hours > 0 || (mask & TIMESTR_MASK_ZEROHRS)) {
|
||||||
|
val -= hours * 3600;
|
||||||
|
result.append(QString("%1:").arg(hours, 2, 10, QLatin1Char('0')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int minutes = val / 60;
|
||||||
|
int seconds = val % 60;
|
||||||
|
result.append(QString("%1:%2").arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -24,8 +24,6 @@
|
||||||
|
|
||||||
class FieldRange
|
class FieldRange
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(FieldRange)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FieldRange():
|
FieldRange():
|
||||||
decimals(0),
|
decimals(0),
|
||||||
|
@ -48,3 +46,24 @@ class FieldRange
|
||||||
QString prefix;
|
QString prefix;
|
||||||
QString unit;
|
QString unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
constexpr unsigned int TIMESTR_MASK_HRSMINS { 1 << 1 };
|
||||||
|
constexpr unsigned int TIMESTR_MASK_ZEROHRS { 1 << 2 };
|
||||||
|
constexpr unsigned int TIMESTR_MASK_PADSIGN { 1 << 3 };
|
||||||
|
|
||||||
|
namespace DataHelpers
|
||||||
|
{
|
||||||
|
enum BoolFormat {
|
||||||
|
BOOL_FMT_ENABLEDISABLE,
|
||||||
|
BOOL_FMT_ONOFF,
|
||||||
|
BOOL_FMT_TRUEFALSE,
|
||||||
|
BOOL_FMT_YN,
|
||||||
|
BOOL_FMT_YESNO
|
||||||
|
};
|
||||||
|
|
||||||
|
QString boolToString(const bool value, const BoolFormat format);
|
||||||
|
QString getElementName(const QString & prefix, const unsigned int index, const char * name = 0, const bool padding = false);
|
||||||
|
QString timeToString(const int value, const unsigned int mask);
|
||||||
|
|
||||||
|
}
|
|
@ -18,121 +18,17 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "io_data.h"
|
#include "flightmodedata.h"
|
||||||
|
#include "radiodata.h"
|
||||||
#include "radiodata.h" // for RadioData::getElementName
|
|
||||||
#include "radiodataconversionstate.h"
|
#include "radiodataconversionstate.h"
|
||||||
|
|
||||||
/*
|
void FlightModeData::convert(RadioDataConversionState & cstate)
|
||||||
* ExpoData
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ExpoData::convert(RadioDataConversionState & cstate)
|
|
||||||
{
|
{
|
||||||
cstate.setComponent(tr("INP"), 3);
|
cstate.setComponent("FMD", 2);
|
||||||
cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
cstate.setSubComp(nameToString(cstate.subCompIdx));
|
||||||
srcRaw.convert(cstate);
|
|
||||||
swtch.convert(cstate);
|
swtch.convert(cstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExpoData::isEmpty() const
|
|
||||||
{
|
|
||||||
return (chn == 0 && mode == INPUT_MODE_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MixData
|
|
||||||
*/
|
|
||||||
|
|
||||||
void MixData::convert(RadioDataConversionState & cstate)
|
|
||||||
{
|
|
||||||
cstate.setComponent(tr("MIX"), 4);
|
|
||||||
cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
|
||||||
srcRaw.convert(cstate);
|
|
||||||
swtch.convert(cstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MixData::isEmpty() const
|
|
||||||
{
|
|
||||||
return (destCh == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LimitData
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString LimitData::minToString() const
|
|
||||||
{
|
|
||||||
return QString::number((qreal)min/10);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LimitData::maxToString() const
|
|
||||||
{
|
|
||||||
return QString::number((qreal)max/10);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LimitData::revertToString() const
|
|
||||||
{
|
|
||||||
return revert ? tr("INV") : tr("NOR");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LimitData::nameToString(int index) const
|
|
||||||
{
|
|
||||||
return RadioData::getElementName(tr("CH"), index + 1, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LimitData::offsetToString() const
|
|
||||||
{
|
|
||||||
return QString::number((qreal)offset/10, 'f', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LimitData::clear()
|
|
||||||
{
|
|
||||||
memset(reinterpret_cast<void *>(this), 0, sizeof(LimitData));
|
|
||||||
min = -1000;
|
|
||||||
max = +1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LimitData::isEmpty() const
|
|
||||||
{
|
|
||||||
return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0' && !curve.isSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CurveData
|
|
||||||
*/
|
|
||||||
|
|
||||||
CurveData::CurveData()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CurveData::clear(int count)
|
|
||||||
{
|
|
||||||
memset(this, 0, sizeof(CurveData));
|
|
||||||
this->count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CurveData::isEmpty() const
|
|
||||||
{
|
|
||||||
for (int i=0; i<count; i++) {
|
|
||||||
if (points[i].y != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CurveData::nameToString(const int idx) const
|
|
||||||
{
|
|
||||||
return RadioData::getElementName(tr("CV"), idx + 1, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FlightModeData
|
|
||||||
*/
|
|
||||||
|
|
||||||
void FlightModeData::clear(const int phaseIdx)
|
void FlightModeData::clear(const int phaseIdx)
|
||||||
{
|
{
|
||||||
memset(reinterpret_cast<void *>(this), 0, sizeof(FlightModeData));
|
memset(reinterpret_cast<void *>(this), 0, sizeof(FlightModeData));
|
||||||
|
@ -149,13 +45,6 @@ QString FlightModeData::nameToString(int phaseIdx) const
|
||||||
return RadioData::getElementName(tr("FM"), phaseIdx, name); // names are zero-based, FM0, FM1, etc
|
return RadioData::getElementName(tr("FM"), phaseIdx, name); // names are zero-based, FM0, FM1, etc
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightModeData::convert(RadioDataConversionState & cstate)
|
|
||||||
{
|
|
||||||
cstate.setComponent("FMD", 2);
|
|
||||||
cstate.setSubComp(nameToString(cstate.subCompIdx));
|
|
||||||
swtch.convert(cstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlightModeData::isEmpty(int phaseIdx) const
|
bool FlightModeData::isEmpty(int phaseIdx) const
|
||||||
{
|
{
|
||||||
if (name[0] != '\0' || swtch.isSet() || fadeIn != 0 || fadeOut != 0)
|
if (name[0] != '\0' || swtch.isSet() || fadeIn != 0 || fadeOut != 0)
|
59
companion/src/firmwares/flightmodedata.h
Normal file
59
companion/src/firmwares/flightmodedata.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
|
#include "rawswitch.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class RadioDataConversionState;
|
||||||
|
|
||||||
|
#define FLIGHTMODE_NAME_LEN 10
|
||||||
|
#define RENC_MAX_VALUE 1024
|
||||||
|
#define RENC_MIN_VALUE -RENC_MAX_VALUE
|
||||||
|
|
||||||
|
class FlightModeData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(FlightModeData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlightModeData() { clear(0); }
|
||||||
|
|
||||||
|
int trimMode[CPN_MAX_TRIMS];
|
||||||
|
int trimRef[CPN_MAX_TRIMS];
|
||||||
|
int trim[CPN_MAX_TRIMS];
|
||||||
|
RawSwitch swtch;
|
||||||
|
char name[FLIGHTMODE_NAME_LEN + 1];
|
||||||
|
unsigned int fadeIn;
|
||||||
|
unsigned int fadeOut;
|
||||||
|
int rotaryEncoders[CPN_MAX_ENCODERS];
|
||||||
|
int gvars[CPN_MAX_GVARS];
|
||||||
|
|
||||||
|
void convert(RadioDataConversionState & cstate);
|
||||||
|
void clear(const int phaseIdx);
|
||||||
|
bool isEmpty(int phaseIdx) const;
|
||||||
|
QString nameToString(int phaseIdx) const;
|
||||||
|
bool isGVarEmpty(int phaseIdx, int gvIdx) const;
|
||||||
|
bool isREncEmpty(int phaseIdx, int reIdx) const;
|
||||||
|
int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const;
|
||||||
|
int linkedGVarFlightModeZero(int phaseIdx) const;
|
||||||
|
int linkedREncFlightModeZero(int phaseIdx) const;
|
||||||
|
};
|
21
companion/src/firmwares/heli_data.cpp
Normal file
21
companion/src/firmwares/heli_data.cpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "heli_data.h"
|
44
companion/src/firmwares/heli_data.h
Normal file
44
companion/src/firmwares/heli_data.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rawsource.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class SwashRingData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(SwashRingData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
SwashRingData() { clear(); }
|
||||||
|
|
||||||
|
int elevatorWeight;
|
||||||
|
int aileronWeight;
|
||||||
|
int collectiveWeight;
|
||||||
|
unsigned int type;
|
||||||
|
RawSource collectiveSource;
|
||||||
|
RawSource aileronSource;
|
||||||
|
RawSource elevatorSource;
|
||||||
|
unsigned int value;
|
||||||
|
|
||||||
|
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(SwashRingData)); }
|
||||||
|
};
|
||||||
|
|
35
companion/src/firmwares/input_data.cpp
Normal file
35
companion/src/firmwares/input_data.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "input_data.h"
|
||||||
|
#include "radiodataconversionstate.h"
|
||||||
|
|
||||||
|
void ExpoData::convert(RadioDataConversionState & cstate)
|
||||||
|
{
|
||||||
|
cstate.setComponent(tr("INP"), 3);
|
||||||
|
cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||||
|
srcRaw.convert(cstate);
|
||||||
|
swtch.convert(cstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpoData::isEmpty() const
|
||||||
|
{
|
||||||
|
return (chn == 0 && mode == INPUT_MODE_NONE);
|
||||||
|
}
|
61
companion/src/firmwares/input_data.h
Normal file
61
companion/src/firmwares/input_data.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "curvereference.h"
|
||||||
|
#include "rawsource.h"
|
||||||
|
#include "rawswitch.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class RadioDataConversionState;
|
||||||
|
|
||||||
|
enum InputMode {
|
||||||
|
INPUT_MODE_NONE,
|
||||||
|
INPUT_MODE_POS,
|
||||||
|
INPUT_MODE_NEG,
|
||||||
|
INPUT_MODE_BOTH
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EXPODATA_NAME_LEN 10
|
||||||
|
|
||||||
|
class ExpoData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(ExpoData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExpoData() { clear(); }
|
||||||
|
|
||||||
|
RawSource srcRaw;
|
||||||
|
unsigned int scale;
|
||||||
|
unsigned int mode; // InputMode
|
||||||
|
unsigned int chn;
|
||||||
|
RawSwitch swtch;
|
||||||
|
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||||
|
int weight;
|
||||||
|
int offset;
|
||||||
|
CurveReference curve;
|
||||||
|
int carryTrim;
|
||||||
|
char name[EXPODATA_NAME_LEN + 1];
|
||||||
|
|
||||||
|
void convert(RadioDataConversionState & cstate);
|
||||||
|
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ExpoData)); }
|
||||||
|
bool isEmpty() const;
|
||||||
|
};
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) OpenTX
|
|
||||||
*
|
|
||||||
* Based on code named
|
|
||||||
* th9x - http://code.google.com/p/th9x
|
|
||||||
* er9x - http://code.google.com/p/er9x
|
|
||||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
|
||||||
*
|
|
||||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IO_DATA_H
|
|
||||||
#define IO_DATA_H
|
|
||||||
|
|
||||||
#include "constants.h"
|
|
||||||
#include "curvereference.h"
|
|
||||||
#include "rawsource.h"
|
|
||||||
#include "rawswitch.h"
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
|
|
||||||
class RadioDataConversionState;
|
|
||||||
|
|
||||||
enum InputMode {
|
|
||||||
INPUT_MODE_NONE,
|
|
||||||
INPUT_MODE_POS,
|
|
||||||
INPUT_MODE_NEG,
|
|
||||||
INPUT_MODE_BOTH
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EXPODATA_NAME_LEN 10
|
|
||||||
|
|
||||||
class ExpoData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(ExpoData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
ExpoData() { clear(); }
|
|
||||||
RawSource srcRaw;
|
|
||||||
unsigned int scale;
|
|
||||||
unsigned int mode; // InputMode
|
|
||||||
unsigned int chn;
|
|
||||||
RawSwitch swtch;
|
|
||||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
|
||||||
int weight;
|
|
||||||
int offset;
|
|
||||||
CurveReference curve;
|
|
||||||
int carryTrim;
|
|
||||||
char name[EXPODATA_NAME_LEN+1];
|
|
||||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ExpoData)); }
|
|
||||||
void convert(RadioDataConversionState & cstate);
|
|
||||||
bool isEmpty() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MltpxValue {
|
|
||||||
MLTPX_ADD=0,
|
|
||||||
MLTPX_MUL=1,
|
|
||||||
MLTPX_REP=2
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MIXDATA_NAME_LEN 10
|
|
||||||
|
|
||||||
class MixData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(MixData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
MixData() { clear(); }
|
|
||||||
void convert(RadioDataConversionState & cstate);
|
|
||||||
|
|
||||||
unsigned int destCh; // 1..CPN_MAX_CHNOUT
|
|
||||||
RawSource srcRaw;
|
|
||||||
int weight;
|
|
||||||
RawSwitch swtch;
|
|
||||||
CurveReference curve; //0=symmetrisch
|
|
||||||
unsigned int delayUp;
|
|
||||||
unsigned int delayDown;
|
|
||||||
unsigned int speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
|
||||||
unsigned int speedDown; // 0 nichts
|
|
||||||
int carryTrim;
|
|
||||||
bool noExpo;
|
|
||||||
MltpxValue mltpx; // multiplex method 0=+ 1=* 2=replace
|
|
||||||
unsigned int mixWarn; // mixer warning
|
|
||||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
|
||||||
int sOffset;
|
|
||||||
char name[MIXDATA_NAME_LEN+1];
|
|
||||||
|
|
||||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(MixData)); }
|
|
||||||
bool isEmpty() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LIMITDATA_NAME_LEN 6
|
|
||||||
|
|
||||||
class LimitData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(LimitData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
LimitData() { clear(); }
|
|
||||||
int min;
|
|
||||||
int max;
|
|
||||||
bool revert;
|
|
||||||
int offset;
|
|
||||||
int ppmCenter;
|
|
||||||
bool symetrical;
|
|
||||||
int failsafe;
|
|
||||||
char name[LIMITDATA_NAME_LEN + 1];
|
|
||||||
CurveReference curve;
|
|
||||||
QString minToString() const;
|
|
||||||
QString maxToString() const;
|
|
||||||
QString offsetToString() const;
|
|
||||||
QString revertToString() const;
|
|
||||||
QString nameToString(int index) const;
|
|
||||||
void clear();
|
|
||||||
bool isEmpty() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CurvePoint {
|
|
||||||
public:
|
|
||||||
int8_t x;
|
|
||||||
int8_t y;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CURVEDATA_NAME_LEN 6
|
|
||||||
|
|
||||||
class CurveData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(CurveData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum CurveType {
|
|
||||||
CURVE_TYPE_STANDARD,
|
|
||||||
CURVE_TYPE_CUSTOM,
|
|
||||||
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
|
||||||
};
|
|
||||||
|
|
||||||
CurveData();
|
|
||||||
void clear(int count = 5);
|
|
||||||
bool isEmpty() const;
|
|
||||||
QString nameToString(const int idx) const;
|
|
||||||
|
|
||||||
CurveType type;
|
|
||||||
bool smooth;
|
|
||||||
int count;
|
|
||||||
CurvePoint points[CPN_MAX_POINTS];
|
|
||||||
char name[CURVEDATA_NAME_LEN+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FLIGHTMODE_NAME_LEN 10
|
|
||||||
#define RENC_MAX_VALUE 1024
|
|
||||||
#define RENC_MIN_VALUE -RENC_MAX_VALUE
|
|
||||||
|
|
||||||
class FlightModeData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(FlightModeData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
FlightModeData() { clear(0); }
|
|
||||||
int trimMode[CPN_MAX_TRIMS];
|
|
||||||
int trimRef[CPN_MAX_TRIMS];
|
|
||||||
int trim[CPN_MAX_TRIMS];
|
|
||||||
RawSwitch swtch;
|
|
||||||
char name[FLIGHTMODE_NAME_LEN+1];
|
|
||||||
unsigned int fadeIn;
|
|
||||||
unsigned int fadeOut;
|
|
||||||
int rotaryEncoders[CPN_MAX_ENCODERS];
|
|
||||||
int gvars[CPN_MAX_GVARS];
|
|
||||||
void clear(const int phaseIdx);
|
|
||||||
QString nameToString(int phaseIdx) const;
|
|
||||||
void convert(RadioDataConversionState & cstate);
|
|
||||||
bool isEmpty(int phaseIdx) const;
|
|
||||||
bool isGVarEmpty(int phaseIdx, int gvIdx) const;
|
|
||||||
bool isREncEmpty(int phaseIdx, int reIdx) const;
|
|
||||||
int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const;
|
|
||||||
int linkedGVarFlightModeZero(int phaseIdx) const;
|
|
||||||
int linkedREncFlightModeZero(int phaseIdx) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SwashRingData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(SwashRingData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
SwashRingData() { clear(); }
|
|
||||||
int elevatorWeight;
|
|
||||||
int aileronWeight;
|
|
||||||
int collectiveWeight;
|
|
||||||
unsigned int type;
|
|
||||||
RawSource collectiveSource;
|
|
||||||
RawSource aileronSource;
|
|
||||||
RawSource elevatorSource;
|
|
||||||
unsigned int value;
|
|
||||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(SwashRingData)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IO_DATA_H
|
|
35
companion/src/firmwares/mixdata.cpp
Normal file
35
companion/src/firmwares/mixdata.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mixdata.h"
|
||||||
|
#include "radiodataconversionstate.h"
|
||||||
|
|
||||||
|
void MixData::convert(RadioDataConversionState & cstate)
|
||||||
|
{
|
||||||
|
cstate.setComponent(tr("MIX"), 4);
|
||||||
|
cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||||
|
srcRaw.convert(cstate);
|
||||||
|
swtch.convert(cstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MixData::isEmpty() const
|
||||||
|
{
|
||||||
|
return (destCh == 0);
|
||||||
|
}
|
65
companion/src/firmwares/mixdata.h
Normal file
65
companion/src/firmwares/mixdata.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "curvereference.h"
|
||||||
|
#include "rawsource.h"
|
||||||
|
#include "rawswitch.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class RadioDataConversionState;
|
||||||
|
|
||||||
|
enum MltpxValue {
|
||||||
|
MLTPX_ADD,
|
||||||
|
MLTPX_MUL,
|
||||||
|
MLTPX_REP
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MIXDATA_NAME_LEN 10
|
||||||
|
|
||||||
|
class MixData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(MixData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
MixData() { clear(); }
|
||||||
|
|
||||||
|
unsigned int destCh; // 1..CPN_MAX_CHNOUT
|
||||||
|
RawSource srcRaw;
|
||||||
|
int weight;
|
||||||
|
RawSwitch swtch;
|
||||||
|
CurveReference curve;
|
||||||
|
unsigned int delayUp;
|
||||||
|
unsigned int delayDown;
|
||||||
|
unsigned int speedUp;
|
||||||
|
unsigned int speedDown;
|
||||||
|
int carryTrim;
|
||||||
|
bool noExpo;
|
||||||
|
MltpxValue mltpx;
|
||||||
|
unsigned int mixWarn;
|
||||||
|
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||||
|
int sOffset;
|
||||||
|
char name[MIXDATA_NAME_LEN + 1];
|
||||||
|
|
||||||
|
void convert(RadioDataConversionState & cstate);
|
||||||
|
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(MixData)); }
|
||||||
|
bool isEmpty() const;
|
||||||
|
};
|
|
@ -27,31 +27,6 @@
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "adjustmentreference.h"
|
#include "adjustmentreference.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* TimerData
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TimerData::convert(RadioDataConversionState & cstate)
|
|
||||||
{
|
|
||||||
cstate.setComponent(tr("TMR"), 1);
|
|
||||||
cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1));
|
|
||||||
mode.convert(cstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerData::isEmpty()
|
|
||||||
{
|
|
||||||
return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWN_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TimerData::nameToString(int index) const
|
|
||||||
{
|
|
||||||
return RadioData::getElementName(tr("TMR", "as in Timer"), index + 1, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ModelData
|
|
||||||
*/
|
|
||||||
|
|
||||||
ModelData::ModelData()
|
ModelData::ModelData()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -678,41 +653,56 @@ int ModelData::updateReference()
|
||||||
LogicalSwitchData *lsd = &logicalSw[i];
|
LogicalSwitchData *lsd = &logicalSw[i];
|
||||||
if (!lsd->isEmpty()) {
|
if (!lsd->isEmpty()) {
|
||||||
bool clearlsd = false;
|
bool clearlsd = false;
|
||||||
|
int oldval1;
|
||||||
|
int oldval2;
|
||||||
CSFunctionFamily family = lsd->getFunctionFamily();
|
CSFunctionFamily family = lsd->getFunctionFamily();
|
||||||
switch(family) {
|
switch(family) {
|
||||||
case LS_FAMILY_VOFS:
|
case LS_FAMILY_VOFS:
|
||||||
updateSourceIntRef(lsd->val1);
|
if (lsd->val1 != 0) {
|
||||||
if (lsd->val1 == 0)
|
updateSourceIntRef(lsd->val1);
|
||||||
clearlsd = true;
|
if (lsd->val1 == 0)
|
||||||
|
clearlsd = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LS_FAMILY_STICKY:
|
case LS_FAMILY_STICKY:
|
||||||
case LS_FAMILY_VBOOL:
|
case LS_FAMILY_VBOOL:
|
||||||
updateSwitchIntRef(lsd->val1);
|
oldval1 = lsd->val1;
|
||||||
updateSwitchIntRef(lsd->val2);
|
oldval2 = lsd->val2;
|
||||||
if (lsd->val1 == 0 && lsd->val2 == 0)
|
if (lsd->val1 != 0)
|
||||||
|
updateSwitchIntRef(lsd->val1);
|
||||||
|
if (lsd->val2 != 0)
|
||||||
|
updateSwitchIntRef(lsd->val2);
|
||||||
|
if (lsd->val1 == 0 && lsd->val2 == 0 && ((lsd->val1 != oldval1 && oldval2 == 0) || (lsd->val2 != oldval2 && oldval1 == 0)))
|
||||||
clearlsd = true;
|
clearlsd = true;
|
||||||
break;
|
break;
|
||||||
case LS_FAMILY_EDGE:
|
case LS_FAMILY_EDGE:
|
||||||
updateSwitchIntRef(lsd->val1);
|
if (lsd->val1 != 0) {
|
||||||
if (lsd->val1 == 0)
|
updateSwitchIntRef(lsd->val1);
|
||||||
clearlsd = true;
|
if (lsd->val1 == 0)
|
||||||
|
clearlsd = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LS_FAMILY_VCOMP:
|
case LS_FAMILY_VCOMP:
|
||||||
updateSourceIntRef(lsd->val1);
|
oldval1 = lsd->val1;
|
||||||
updateSourceIntRef(lsd->val2);
|
oldval2 = lsd->val2;
|
||||||
if (lsd->val1 == 0 && lsd->val2 == 0)
|
if (lsd->val1 != 0)
|
||||||
|
updateSourceIntRef(lsd->val1);
|
||||||
|
if (lsd->val2 != 0)
|
||||||
|
updateSourceIntRef(lsd->val2);
|
||||||
|
if (lsd->val1 == 0 && lsd->val2 == 0 && ((lsd->val1 != oldval1 && oldval2 == 0) || (lsd->val2 != oldval2 && oldval1 == 0)))
|
||||||
clearlsd = true;
|
clearlsd = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (clearlsd) {
|
|
||||||
|
if (lsd->andsw != 0)
|
||||||
|
updateSwitchIntRef(lsd->andsw);
|
||||||
|
|
||||||
|
if (clearlsd && lsd->andsw == 0) {
|
||||||
lsd->clear();
|
lsd->clear();
|
||||||
appendUpdateReferenceParams(REF_UPD_TYPE_LOGICAL_SWITCH, REF_UPD_ACT_CLEAR, i);
|
appendUpdateReferenceParams(REF_UPD_TYPE_LOGICAL_SWITCH, REF_UPD_ACT_CLEAR, i);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
updateSwitchIntRef(lsd->andsw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//s1.report("Logical Switches");
|
//s1.report("Logical Switches");
|
||||||
|
@ -841,6 +831,7 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c
|
||||||
newRef.index = abs(curRef.index);
|
newRef.index = abs(curRef.index);
|
||||||
|
|
||||||
div_t idx = div(newRef.index, updRefInfo.occurences);
|
div_t idx = div(newRef.index, updRefInfo.occurences);
|
||||||
|
div_t newidx;
|
||||||
|
|
||||||
switch (updRefInfo.action)
|
switch (updRefInfo.action)
|
||||||
{
|
{
|
||||||
|
@ -858,9 +849,10 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c
|
||||||
if (idx.quot < (updRefInfo.index1 + idxAdj))
|
if (idx.quot < (updRefInfo.index1 + idxAdj))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
newRef.index += updRefInfo.shift;
|
newRef.index = ((idx.quot + updRefInfo.shift) * updRefInfo.occurences) + idx.rem;
|
||||||
|
newidx = div(newRef.index, updRefInfo.occurences);
|
||||||
|
|
||||||
if (idx.quot < (updRefInfo.index1 + idxAdj) || idx.quot > (updRefInfo.maxindex + idxAdj)) {
|
if (newidx.quot < (updRefInfo.index1 + idxAdj) || newidx.quot > (updRefInfo.maxindex + idxAdj)) {
|
||||||
if (defClear)
|
if (defClear)
|
||||||
newRef.clear();
|
newRef.clear();
|
||||||
else {
|
else {
|
||||||
|
@ -1106,7 +1098,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||||
switch (updRefInfo.action)
|
switch (updRefInfo.action)
|
||||||
{
|
{
|
||||||
case REF_UPD_ACT_CLEAR:
|
case REF_UPD_ACT_CLEAR:
|
||||||
flag[updRefInfo.index1] = false;
|
flag[updRefInfo.index1] = true;
|
||||||
break;
|
break;
|
||||||
case REF_UPD_ACT_SHIFT:
|
case REF_UPD_ACT_SHIFT:
|
||||||
if(updRefInfo.shift < 0) {
|
if(updRefInfo.shift < 0) {
|
||||||
|
@ -1114,7 +1106,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||||
if (i - updRefInfo.shift <= updRefInfo.maxindex)
|
if (i - updRefInfo.shift <= updRefInfo.maxindex)
|
||||||
flag[i] = flag[i - updRefInfo.shift];
|
flag[i] = flag[i - updRefInfo.shift];
|
||||||
else
|
else
|
||||||
flag[i] = false;
|
flag[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1122,7 +1114,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||||
if (i - updRefInfo.shift >= updRefInfo.index1)
|
if (i - updRefInfo.shift >= updRefInfo.index1)
|
||||||
flag[i] = flag[i - updRefInfo.shift];
|
flag[i] = flag[i - updRefInfo.shift];
|
||||||
else
|
else
|
||||||
flag[i] = false;
|
flag[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1381,7 +1373,6 @@ void ModelData::sortMixes()
|
||||||
|
|
||||||
void ModelData::updateResetParam(CustomFunctionData * cfd)
|
void ModelData::updateResetParam(CustomFunctionData * cfd)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (cfd->func != FuncReset)
|
if (cfd->func != FuncReset)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1392,6 +1383,11 @@ void ModelData::updateResetParam(CustomFunctionData * cfd)
|
||||||
|
|
||||||
switch (updRefInfo.type)
|
switch (updRefInfo.type)
|
||||||
{
|
{
|
||||||
|
case REF_UPD_TYPE_TIMER:
|
||||||
|
if (cfd->param < 0 || cfd->param > 2)
|
||||||
|
return;
|
||||||
|
idxAdj = -2; // reverse earlier offset required for rawsource
|
||||||
|
break;
|
||||||
case REF_UPD_TYPE_SENSOR:
|
case REF_UPD_TYPE_SENSOR:
|
||||||
idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders);
|
idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders);
|
||||||
if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors)))
|
if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors)))
|
||||||
|
@ -1478,3 +1474,79 @@ bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings,
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsClear(const int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!limitData[index].isEmpty()) {
|
||||||
|
limitData[index].clear();
|
||||||
|
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_CLEAR, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsClearAll()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < CPN_MAX_CHNOUT; i++) {
|
||||||
|
limitsClear(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsDelete(const int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memmove(&limitData[index], &limitData[index + 1], (CPN_MAX_CHNOUT - (index + 1)) * sizeof(LimitData));
|
||||||
|
limitData[CPN_MAX_CHNOUT - 1].clear();
|
||||||
|
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SHIFT, index, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsGet(const int index, QByteArray & data)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.append((char*)&limitData[index], sizeof(LimitData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsInsert(const int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memmove(&limitData[index + 1], &limitData[index], (CPN_MAX_CHNOUT - (index + 1)) * sizeof(LimitData));
|
||||||
|
limitData[index].clear();
|
||||||
|
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SHIFT, index, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsMove(const int index, const int offset)
|
||||||
|
{
|
||||||
|
if (index + offset < 0 || index + offset >= CPN_MAX_CHNOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int idx1 = index;
|
||||||
|
int idx2;
|
||||||
|
const int direction = offset < 0 ? -1 : 1;
|
||||||
|
const int cnt = abs(offset);
|
||||||
|
|
||||||
|
for (int i = 1; i <= cnt; i++) {
|
||||||
|
idx2 = idx1 + direction;
|
||||||
|
LimitData tmp = limitData[idx2];
|
||||||
|
LimitData *d1 = &limitData[idx1];
|
||||||
|
LimitData *d2 = &limitData[idx2];
|
||||||
|
memcpy(d2, d1, sizeof(LimitData));
|
||||||
|
memcpy(d1, &tmp, sizeof(LimitData));
|
||||||
|
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SWAP, idx1, idx2);
|
||||||
|
idx1 += direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelData::limitsSet(const int index, const QByteArray & data)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CPN_MAX_CHNOUT || data.size() < (int)sizeof(LimitData))
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(&limitData[index], data.constData(), sizeof(LimitData));
|
||||||
|
}
|
||||||
|
|
|
@ -18,17 +18,22 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MODELDATA_H
|
#pragma once
|
||||||
#define MODELDATA_H
|
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "curvedata.h"
|
||||||
#include "customfunctiondata.h"
|
#include "customfunctiondata.h"
|
||||||
#include "gvardata.h"
|
#include "gvardata.h"
|
||||||
#include "io_data.h"
|
#include "flightmodedata.h"
|
||||||
|
#include "heli_data.h"
|
||||||
|
#include "input_data.h"
|
||||||
#include "logicalswitchdata.h"
|
#include "logicalswitchdata.h"
|
||||||
|
#include "mixdata.h"
|
||||||
#include "moduledata.h"
|
#include "moduledata.h"
|
||||||
|
#include "output_data.h"
|
||||||
#include "sensordata.h"
|
#include "sensordata.h"
|
||||||
#include "telem_data.h"
|
#include "telem_data.h"
|
||||||
|
#include "timerdata.h"
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
|
@ -51,35 +56,6 @@ class RSSIAlarmData {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TIMER_NAME_LEN 8
|
|
||||||
|
|
||||||
class TimerData {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(TimerData)
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum CountDownMode {
|
|
||||||
COUNTDOWN_SILENT,
|
|
||||||
COUNTDOWN_BEEPS,
|
|
||||||
COUNTDOWN_VOICE,
|
|
||||||
COUNTDOWN_HAPTIC
|
|
||||||
};
|
|
||||||
TimerData() { clear(); }
|
|
||||||
RawSwitch mode;
|
|
||||||
char name[TIMER_NAME_LEN+1];
|
|
||||||
bool minuteBeep;
|
|
||||||
unsigned int countdownBeep;
|
|
||||||
unsigned int val;
|
|
||||||
unsigned int persistent;
|
|
||||||
int countdownStart;
|
|
||||||
unsigned int direction;
|
|
||||||
int pvalue;
|
|
||||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TimerData)); mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); }
|
|
||||||
void convert(RadioDataConversionState & cstate);
|
|
||||||
bool isEmpty();
|
|
||||||
bool isModeOff() { return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); }
|
|
||||||
QString nameToString(int index) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CPN_MAX_SCRIPTS 9
|
#define CPN_MAX_SCRIPTS 9
|
||||||
#define CPN_MAX_SCRIPT_INPUTS 10
|
#define CPN_MAX_SCRIPT_INPUTS 10
|
||||||
class ScriptData {
|
class ScriptData {
|
||||||
|
@ -290,6 +266,14 @@ class ModelData {
|
||||||
int thrTraceSrcCount() const;
|
int thrTraceSrcCount() const;
|
||||||
bool isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const;
|
bool isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const;
|
||||||
|
|
||||||
|
void limitsClear(const int index);
|
||||||
|
void limitsClearAll();
|
||||||
|
void limitsDelete(const int index);
|
||||||
|
void limitsGet(const int index, QByteArray & data);
|
||||||
|
void limitsInsert(const int index);
|
||||||
|
void limitsMove(const int index, const int offset);
|
||||||
|
void limitsSet(const int index, const QByteArray & data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void removeGlobalVar(int & var);
|
void removeGlobalVar(int & var);
|
||||||
|
|
||||||
|
@ -346,5 +330,3 @@ class ModelData {
|
||||||
void sortMixes();
|
void sortMixes();
|
||||||
void updateResetParam(CustomFunctionData * cfd);
|
void updateResetParam(CustomFunctionData * cfd);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MODELDATA_H
|
|
||||||
|
|
61
companion/src/firmwares/output_data.cpp
Normal file
61
companion/src/firmwares/output_data.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "output_data.h"
|
||||||
|
#include "radiodata.h"
|
||||||
|
#include "radiodataconversionstate.h"
|
||||||
|
|
||||||
|
void LimitData::clear()
|
||||||
|
{
|
||||||
|
memset(reinterpret_cast<void *>(this), 0, sizeof(LimitData));
|
||||||
|
min = -1000;
|
||||||
|
max = +1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LimitData::isEmpty() const
|
||||||
|
{
|
||||||
|
LimitData tmp;
|
||||||
|
return !memcmp(this, &tmp, sizeof(LimitData));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LimitData::minToString() const
|
||||||
|
{
|
||||||
|
return QString::number((qreal)min / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LimitData::maxToString() const
|
||||||
|
{
|
||||||
|
return QString::number((qreal)max / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LimitData::revertToString() const
|
||||||
|
{
|
||||||
|
return revert ? tr("INV") : tr("NOR");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LimitData::nameToString(int index) const
|
||||||
|
{
|
||||||
|
return RadioData::getElementName(tr("CH"), index + 1, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LimitData::offsetToString() const
|
||||||
|
{
|
||||||
|
return QString::number((qreal)offset / 10, 'f', 1);
|
||||||
|
}
|
52
companion/src/firmwares/output_data.h
Normal file
52
companion/src/firmwares/output_data.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "curvereference.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
#define LIMITDATA_NAME_LEN 6
|
||||||
|
|
||||||
|
class LimitData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(LimitData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
LimitData() { clear(); }
|
||||||
|
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
bool revert;
|
||||||
|
int offset;
|
||||||
|
int ppmCenter;
|
||||||
|
bool symetrical;
|
||||||
|
int failsafe;
|
||||||
|
char name[LIMITDATA_NAME_LEN + 1];
|
||||||
|
CurveReference curve;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
bool isEmpty() const;
|
||||||
|
QString minToString() const;
|
||||||
|
QString maxToString() const;
|
||||||
|
QString offsetToString() const;
|
||||||
|
QString revertToString() const;
|
||||||
|
QString nameToString(int index) const;
|
||||||
|
};
|
|
@ -22,23 +22,6 @@
|
||||||
#include "radiodataconversionstate.h"
|
#include "radiodataconversionstate.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
|
|
||||||
// static
|
|
||||||
QString RadioData::getElementName(const QString & prefix, unsigned int index, const char * name, bool padding)
|
|
||||||
{
|
|
||||||
QString result = prefix;
|
|
||||||
if (padding)
|
|
||||||
result += QString("%1").arg(index, 2, 10, QChar('0'));
|
|
||||||
else
|
|
||||||
result += QString("%1").arg(index);
|
|
||||||
if (name) {
|
|
||||||
QString trimmed = QString(name).trimmed();
|
|
||||||
if (trimmed.length() > 0) {
|
|
||||||
result += ":" + QString(name).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
RadioData::RadioData()
|
RadioData::RadioData()
|
||||||
{
|
{
|
||||||
models.resize(getCurrentFirmware()->getCapability(Models));
|
models.resize(getCurrentFirmware()->getCapability(Models));
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#ifndef _RADIODATA_H_
|
#pragma once
|
||||||
#define _RADIODATA_H_
|
|
||||||
|
|
||||||
#include "generalsettings.h"
|
#include "generalsettings.h"
|
||||||
#include "modeldata.h"
|
#include "modeldata.h"
|
||||||
|
|
||||||
|
#include "datahelpers.h" // required for getElementName
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
class RadioDataConversionState;
|
class RadioDataConversionState;
|
||||||
|
@ -32,10 +33,10 @@ class RadioData {
|
||||||
void fixModelFilenames();
|
void fixModelFilenames();
|
||||||
QString getNextModelFilename();
|
QString getNextModelFilename();
|
||||||
|
|
||||||
static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false);
|
// leave here until all calls repointed
|
||||||
|
static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false)
|
||||||
|
{ return DataHelpers::getElementName(prefix, index, name, padding); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void fixModelFilename(unsigned int index);
|
void fixModelFilename(unsigned int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _RADIODATA_H_
|
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sensordata.h"
|
#include "sensordata.h"
|
||||||
|
|
||||||
#include "radiodata.h"
|
|
||||||
#include "modeldata.h"
|
#include "modeldata.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
#include "compounditemmodels.h"
|
#include "compounditemmodels.h"
|
||||||
|
@ -35,7 +33,7 @@ void SensorData::updateUnit()
|
||||||
|
|
||||||
QString SensorData::nameToString(int index) const
|
QString SensorData::nameToString(int index) const
|
||||||
{
|
{
|
||||||
return RadioData::getElementName(tr("TELE"), index + 1, label);
|
return DataHelpers::getElementName(tr("TELE"), index + 1, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SensorData::getOrigin(const ModelData * model) const
|
QString SensorData::getOrigin(const ModelData * model) const
|
||||||
|
@ -171,7 +169,7 @@ QString SensorData::paramsToString(const ModelData * model) const
|
||||||
int precsn = prec == 0 ? 1 : pow(10, prec);
|
int precsn = prec == 0 ? 1 : pow(10, prec);
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Ratio")).arg((float)ratio / 10));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Ratio")).arg((float)ratio / 10));
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Offset")).arg(QString::number((float)offset / precsn, 'f', prec)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Offset")).arg(QString::number((float)offset / precsn, 'f', prec)));
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Auto Offset")).arg(boolToString(autoOffset)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Auto Offset")).arg(DataHelpers::boolToString(autoOffset, DataHelpers::BOOL_FMT_YN)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Blades")).arg(ratio)); // TODO refactor to dedicated RPMS field
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Blades")).arg(ratio)); // TODO refactor to dedicated RPMS field
|
||||||
|
@ -180,15 +178,15 @@ QString SensorData::paramsToString(const ModelData * model) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & SENSOR_ISCONFIGURABLE)
|
if (mask & SENSOR_ISCONFIGURABLE)
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Filter")).arg(boolToString(filter)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Filter")).arg(DataHelpers::boolToString(filter, DataHelpers::BOOL_FMT_YN)));
|
||||||
|
|
||||||
if (type == TELEM_TYPE_CALCULATED)
|
if (type == TELEM_TYPE_CALCULATED)
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Persist")).arg(boolToString(persistent)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Persist")).arg(DataHelpers::boolToString(persistent, DataHelpers::BOOL_FMT_YN)));
|
||||||
|
|
||||||
if (mask & SENSOR_HAS_POSITIVE)
|
if (mask & SENSOR_HAS_POSITIVE)
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Positive")).arg(boolToString(onlyPositive)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Positive")).arg(DataHelpers::boolToString(onlyPositive, DataHelpers::BOOL_FMT_YN)));
|
||||||
|
|
||||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Log")).arg(boolToString(logs)));
|
str.append(QString(FMT_LABEL_VALUE).arg(tr("Log")).arg(DataHelpers::boolToString(logs, DataHelpers::BOOL_FMT_YN)));
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -427,6 +425,28 @@ bool SensorData::isSourceAvailable(const ModelData * model, const int index)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RSSI_ID 0xF101
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool SensorData::isRssiSensorAvailable(const ModelData * model, const int value)
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
return true;
|
||||||
|
else {
|
||||||
|
const SensorData &sensor = model->sensorData[abs(value) - 1];
|
||||||
|
return (sensor.isAvailable() && sensor.id == RSSI_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString SensorData::rssiSensorToString(const ModelData * model, const int value)
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
return tr("(default)");
|
||||||
|
else
|
||||||
|
return sourceToString(model, value);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
AbstractStaticItemModel * SensorData::typeItemModel()
|
AbstractStaticItemModel * SensorData::typeItemModel()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "helpersdata.h"
|
#include "datahelpers.h"
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ class SensorData {
|
||||||
static QString cellIndexToString(const int value);
|
static QString cellIndexToString(const int value);
|
||||||
static QString unitToString(const int value);
|
static QString unitToString(const int value);
|
||||||
static QString precToString(const int value);
|
static QString precToString(const int value);
|
||||||
static QString boolToString(const bool value) { return value ? tr("Y") : tr("N"); }
|
static bool isRssiSensorAvailable(const ModelData * model, const int value);
|
||||||
|
static QString rssiSensorToString(const ModelData * model, const int value);
|
||||||
|
|
||||||
static AbstractStaticItemModel * typeItemModel();
|
static AbstractStaticItemModel * typeItemModel();
|
||||||
static AbstractStaticItemModel * formulaItemModel();
|
static AbstractStaticItemModel * formulaItemModel();
|
||||||
|
|
188
companion/src/firmwares/timerdata.cpp
Normal file
188
companion/src/firmwares/timerdata.cpp
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timerdata.h"
|
||||||
|
#include "radiodataconversionstate.h"
|
||||||
|
#include "compounditemmodels.h"
|
||||||
|
|
||||||
|
void TimerData::convert(RadioDataConversionState & cstate)
|
||||||
|
{
|
||||||
|
cstate.setComponent(tr("TMR"), 1);
|
||||||
|
cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1));
|
||||||
|
mode.convert(cstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerData::clear()
|
||||||
|
{
|
||||||
|
memset(reinterpret_cast<void *>(this), 0, sizeof(TimerData));
|
||||||
|
mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimerData::isEmpty()
|
||||||
|
{
|
||||||
|
return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWNBEEP_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimerData::isModeOff()
|
||||||
|
{
|
||||||
|
return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::nameToString(int index) const
|
||||||
|
{
|
||||||
|
return DataHelpers::getElementName(tr("TMR", "as in Timer"), index + 1, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::countdownBeepToString() const
|
||||||
|
{
|
||||||
|
return countdownBeepToString(countdownBeep);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::countdownStartToString() const
|
||||||
|
{
|
||||||
|
if (countdownBeep == COUNTDOWNBEEP_SILENT)
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return countdownStartToString(countdownStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::persistentToString(const bool verbose) const
|
||||||
|
{
|
||||||
|
return persistentToString(persistent, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::pvalueToString() const
|
||||||
|
{
|
||||||
|
return pvalueToString(pvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TimerData::valToString() const
|
||||||
|
{
|
||||||
|
return valToString(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerData::countdownBeepChanged()
|
||||||
|
{
|
||||||
|
if (countdownBeep == COUNTDOWNBEEP_SILENT)
|
||||||
|
countdownStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString TimerData::countdownBeepToString(const int value)
|
||||||
|
{
|
||||||
|
switch(value) {
|
||||||
|
case COUNTDOWNBEEP_SILENT:
|
||||||
|
return tr("Silent");
|
||||||
|
case COUNTDOWNBEEP_BEEPS:
|
||||||
|
return tr("Beeps");
|
||||||
|
case COUNTDOWNBEEP_VOICE:
|
||||||
|
return tr("Voice");
|
||||||
|
case COUNTDOWNBEEP_HAPTIC:
|
||||||
|
return tr("Haptic");
|
||||||
|
default:
|
||||||
|
return CPN_STR_UNKNOWN_ITEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString TimerData::countdownStartToString(const int value)
|
||||||
|
{
|
||||||
|
switch(value) {
|
||||||
|
case COUNTDOWNSTART_5:
|
||||||
|
return tr("5s");
|
||||||
|
case COUNTDOWNSTART_10:
|
||||||
|
return tr("10s");
|
||||||
|
case COUNTDOWNSTART_20:
|
||||||
|
return tr("20s");
|
||||||
|
case COUNTDOWNSTART_30:
|
||||||
|
return tr("30s");
|
||||||
|
default:
|
||||||
|
return CPN_STR_UNKNOWN_ITEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString TimerData::persistentToString(const int value, const bool verbose)
|
||||||
|
{
|
||||||
|
switch(value) {
|
||||||
|
case PERSISTENT_NOT:
|
||||||
|
return verbose ? tr("Not persistent") : tr("NOT");
|
||||||
|
case PERSISTENT_FLIGHT:
|
||||||
|
return verbose ? tr("Persistent (flight)") : tr("Flight");
|
||||||
|
case PERSISTENT_MANUALRESET:
|
||||||
|
return verbose ? tr("Persistent (manual reset)") : tr("Manual reset");
|
||||||
|
default:
|
||||||
|
return CPN_STR_UNKNOWN_ITEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString TimerData::pvalueToString(const int value)
|
||||||
|
{
|
||||||
|
return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QString TimerData::valToString(const int value)
|
||||||
|
{
|
||||||
|
return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * TimerData::countdownBeepItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName(AIM_TIMER_COUNTDOWNBEEP);
|
||||||
|
|
||||||
|
for (int i = 0; i < COUNTDOWNBEEP_COUNT; i++) {
|
||||||
|
mdl->appendToItemList(countdownBeepToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * TimerData::countdownStartItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName(AIM_TIMER_COUNTDOWNSTART);
|
||||||
|
|
||||||
|
for (int i = COUNTDOWNSTART_LAST; i >= COUNTDOWNSTART_FIRST; i--) {
|
||||||
|
mdl->appendToItemList(countdownStartToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
AbstractStaticItemModel * TimerData::persistentItemModel()
|
||||||
|
{
|
||||||
|
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||||
|
mdl->setName(AIM_TIMER_PERSISTENT);
|
||||||
|
|
||||||
|
for (int i = 0; i < PERSISTENT_COUNT; i++) {
|
||||||
|
mdl->appendToItemList(persistentToString(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdl->loadItemList();
|
||||||
|
return mdl;
|
||||||
|
}
|
98
companion/src/firmwares/timerdata.h
Normal file
98
companion/src/firmwares/timerdata.h
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rawswitch.h"
|
||||||
|
#include "datahelpers.h"
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
class RadioDataConversionState;
|
||||||
|
class AbstractStaticItemModel;
|
||||||
|
|
||||||
|
constexpr char AIM_TIMER_COUNTDOWNBEEP[] {"timerdata.countdownBeep"};
|
||||||
|
constexpr char AIM_TIMER_COUNTDOWNSTART[] {"timerdata.countdownStart"};
|
||||||
|
constexpr char AIM_TIMER_PERSISTENT[] {"timerdata.persistent"};
|
||||||
|
|
||||||
|
constexpr int TIMER_NAME_LEN {8};
|
||||||
|
|
||||||
|
class TimerData {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(TimerData)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum CountDownBeepType {
|
||||||
|
COUNTDOWNBEEP_SILENT,
|
||||||
|
COUNTDOWNBEEP_BEEPS,
|
||||||
|
COUNTDOWNBEEP_VOICE,
|
||||||
|
COUNTDOWNBEEP_HAPTIC,
|
||||||
|
COUNTDOWNBEEP_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CountDownStart {
|
||||||
|
COUNTDOWNSTART_30 = -2,
|
||||||
|
COUNTDOWNSTART_FIRST = COUNTDOWNSTART_30,
|
||||||
|
COUNTDOWNSTART_20,
|
||||||
|
COUNTDOWNSTART_10,
|
||||||
|
COUNTDOWNSTART_5,
|
||||||
|
COUNTDOWNSTART_LAST = COUNTDOWNSTART_5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PersistentType {
|
||||||
|
PERSISTENT_NOT,
|
||||||
|
PERSISTENT_FLIGHT,
|
||||||
|
PERSISTENT_MANUALRESET,
|
||||||
|
PERSISTENT_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
TimerData() { clear(); }
|
||||||
|
|
||||||
|
RawSwitch mode;
|
||||||
|
char name[TIMER_NAME_LEN + 1];
|
||||||
|
bool minuteBeep;
|
||||||
|
unsigned int countdownBeep;
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int persistent;
|
||||||
|
int countdownStart;
|
||||||
|
unsigned int direction;
|
||||||
|
int pvalue;
|
||||||
|
|
||||||
|
void convert(RadioDataConversionState & cstate);
|
||||||
|
void clear();
|
||||||
|
bool isEmpty();
|
||||||
|
bool isModeOff();
|
||||||
|
QString nameToString(int index) const;
|
||||||
|
QString countdownBeepToString() const;
|
||||||
|
QString countdownStartToString() const;
|
||||||
|
QString persistentToString(const bool verbose = true) const;
|
||||||
|
QString pvalueToString() const;
|
||||||
|
QString valToString() const;
|
||||||
|
void countdownBeepChanged();
|
||||||
|
|
||||||
|
static QString countdownBeepToString(const int value);
|
||||||
|
static QString countdownStartToString(const int value);
|
||||||
|
static QString persistentToString(const int value, const bool verbose = true);
|
||||||
|
static QString pvalueToString(const int value);
|
||||||
|
static QString valToString(const int value);
|
||||||
|
static AbstractStaticItemModel * countdownBeepItemModel();
|
||||||
|
static AbstractStaticItemModel * countdownStartItemModel();
|
||||||
|
static AbstractStaticItemModel * persistentItemModel();
|
||||||
|
|
||||||
|
};
|
|
@ -1527,7 +1527,7 @@ Mode 4:
|
||||||
<string>Battery warning voltage.
|
<string>Battery warning voltage.
|
||||||
This is the threashhold where the battery warning sounds.
|
This is the threashhold where the battery warning sounds.
|
||||||
|
|
||||||
Acceptable values are 5v..10v</string>
|
Acceptable values are 3v..12v</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="prefix">
|
<property name="prefix">
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
|
@ -1539,7 +1539,7 @@ Acceptable values are 5v..10v</string>
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>4.000000000000000</double>
|
<double>3.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>12.000000000000000</double>
|
<double>12.000000000000000</double>
|
||||||
|
@ -1679,7 +1679,7 @@ Acceptable values are 5v..10v</string>
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>4.000000000000000</double>
|
<double>3.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>16.000000000000000</double>
|
<double>16.000000000000000</double>
|
||||||
|
@ -1708,7 +1708,7 @@ Acceptable values are 5v..10v</string>
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>4.000000000000000</double>
|
<double>3.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>16.000000000000000</double>
|
<double>16.000000000000000</double>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "simulatorinterface.h"
|
#include "simulatorinterface.h"
|
||||||
#include "simulatormainwindow.h"
|
#include "simulatormainwindow.h"
|
||||||
#include "storage/sdcard.h"
|
#include "storage/sdcard.h"
|
||||||
|
#include "filtereditemmodels.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
@ -117,7 +118,8 @@ void CompanionIcon::addImage(const QString & baseimage, Mode mode, State state)
|
||||||
* GVarGroup
|
* GVarGroup
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars):
|
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model,
|
||||||
|
const int deflt, const int mini, const int maxi, const double step, FilteredItemModel * gvarModel):
|
||||||
QObject(),
|
QObject(),
|
||||||
weightGV(weightGV),
|
weightGV(weightGV),
|
||||||
weightSB(weightSB),
|
weightSB(weightSB),
|
||||||
|
@ -131,8 +133,8 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
|
||||||
step(step),
|
step(step),
|
||||||
lock(true)
|
lock(true)
|
||||||
{
|
{
|
||||||
if (allowGvars && getCurrentFirmware()->getCapability(Gvars)) {
|
if (gvarModel && gvarModel->rowCount() > 0) {
|
||||||
Helpers::populateGVCB(*weightCB, weight, model);
|
weightCB->setModel(gvarModel);
|
||||||
connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
|
connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
|
||||||
connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
|
connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
|
||||||
}
|
}
|
||||||
|
@ -152,12 +154,19 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
|
||||||
|
|
||||||
void GVarGroup::gvarCBChanged(int state)
|
void GVarGroup::gvarCBChanged(int state)
|
||||||
{
|
{
|
||||||
weightCB->setVisible(state);
|
if (!lock) {
|
||||||
if (weightSB)
|
weightCB->setVisible(state);
|
||||||
|
if (weightGV->isChecked()) {
|
||||||
|
// set CB to +GV1
|
||||||
|
int cnt = getCurrentFirmware()->getCapability(Gvars);
|
||||||
|
if (weightCB->count() > cnt)
|
||||||
|
weightCB->setCurrentIndex(cnt);
|
||||||
|
else
|
||||||
|
weightCB->setCurrentIndex(0);
|
||||||
|
}
|
||||||
weightSB->setVisible(!state);
|
weightSB->setVisible(!state);
|
||||||
else
|
valuesChanged();
|
||||||
weightSB->setVisible(!state);
|
}
|
||||||
valuesChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GVarGroup::valuesChanged()
|
void GVarGroup::valuesChanged()
|
||||||
|
@ -168,7 +177,7 @@ void GVarGroup::valuesChanged()
|
||||||
else if (sb)
|
else if (sb)
|
||||||
weight = sb->value();
|
weight = sb->value();
|
||||||
else
|
else
|
||||||
weight = round(dsb->value()/step);
|
weight = round(dsb->value() / step);
|
||||||
|
|
||||||
emit valueChanged();
|
emit valueChanged();
|
||||||
}
|
}
|
||||||
|
@ -180,7 +189,7 @@ void GVarGroup::setWeight(int val)
|
||||||
|
|
||||||
int tval;
|
int tval;
|
||||||
|
|
||||||
if (val>maxi || val<mini) {
|
if (val > maxi || val < mini) {
|
||||||
tval = deflt;
|
tval = deflt;
|
||||||
weightGV->setChecked(true);
|
weightGV->setChecked(true);
|
||||||
weightSB->hide();
|
weightSB->hide();
|
||||||
|
@ -214,27 +223,6 @@ void GVarGroup::setWeight(int val)
|
||||||
* Helpers namespace functions
|
* Helpers namespace functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Helpers::populateGVCB(QComboBox & b, int value, const ModelData & model)
|
|
||||||
{
|
|
||||||
int count = getCurrentFirmware()->getCapability(Gvars);
|
|
||||||
|
|
||||||
b.clear();
|
|
||||||
|
|
||||||
for (int i=-count; i<=-1; i++) {
|
|
||||||
int16_t gval = (int16_t)(-10000+i);
|
|
||||||
b.addItem("-" + RawSource(SOURCE_TYPE_GVAR, abs(i)-1).toString(&model), gval);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=1; i<=count; i++) {
|
|
||||||
int16_t gval = (int16_t)(10000+i);
|
|
||||||
b.addItem(RawSource(SOURCE_TYPE_GVAR, i-1).toString(&model), gval);
|
|
||||||
}
|
|
||||||
|
|
||||||
b.setCurrentIndex(b.findData(value));
|
|
||||||
if (b.currentIndex() == -1)
|
|
||||||
b.setCurrentIndex(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Move lookup to GVarData class (w/out combobox)
|
// TODO: Move lookup to GVarData class (w/out combobox)
|
||||||
void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase)
|
void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _HELPERS_H_
|
#pragma once
|
||||||
#define _HELPERS_H_
|
|
||||||
|
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
@ -60,12 +59,15 @@ class CompanionIcon: public QIcon {
|
||||||
void addImage(const QString &baseimage, Mode mode = Normal, State state = Off);
|
void addImage(const QString &baseimage, Mode mode = Normal, State state = Off);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FilteredItemModel;
|
||||||
|
|
||||||
class GVarGroup: public QObject {
|
class GVarGroup: public QObject {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
|
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model,
|
||||||
|
const int deflt, const int mini, const int maxi, const double step = 1.0, FilteredItemModel * gvarModel = nullptr);
|
||||||
|
|
||||||
void setWeight(int val);
|
void setWeight(int val);
|
||||||
|
|
||||||
|
@ -101,7 +103,6 @@ class GVarGroup: public QObject {
|
||||||
namespace Helpers
|
namespace Helpers
|
||||||
{
|
{
|
||||||
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
||||||
void populateGVCB(QComboBox & b, int value, const ModelData & model);
|
|
||||||
|
|
||||||
void populateFileComboBox(QComboBox * b, const QSet<QString> & set, const QString & current);
|
void populateFileComboBox(QComboBox * b, const QSet<QString> & set, const QString & current);
|
||||||
void getFileComboBoxValue(QComboBox * b, char * dest, int length);
|
void getFileComboBoxValue(QComboBox * b, char * dest, int length);
|
||||||
|
@ -234,5 +235,3 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Stopwatch gStopwatch;
|
extern Stopwatch gStopwatch;
|
||||||
|
|
||||||
#endif // _HELPERS_H_
|
|
||||||
|
|
|
@ -22,42 +22,31 @@
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "filtereditemmodels.h"
|
#include "filtereditemmodels.h"
|
||||||
|
|
||||||
LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel):
|
LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model,
|
||||||
|
int min, int max, int deflt, FilteredItemModel * gvarModel, ModelPanel * panel):
|
||||||
firmware(firmware),
|
firmware(firmware),
|
||||||
spinbox(new QDoubleSpinBox()),
|
spinbox(new QDoubleSpinBox()),
|
||||||
value(value),
|
value(value)
|
||||||
displayStep(0.1)
|
|
||||||
{
|
{
|
||||||
Board::Type board = firmware->getBoard();
|
|
||||||
bool allowGVars = IS_HORUS_OR_TARANIS(board);
|
|
||||||
int internalStep = 1;
|
|
||||||
|
|
||||||
spinbox->setProperty("index", row);
|
spinbox->setProperty("index", row);
|
||||||
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
spinbox->setAccelerated(true);
|
spinbox->setAccelerated(true);
|
||||||
|
spinbox->setDecimals(1);
|
||||||
|
|
||||||
if (firmware->getCapability(PPMUnitMicroseconds)) {
|
if (firmware->getCapability(PPMUnitMicroseconds)) {
|
||||||
displayStep = 0.512;
|
displayStep = 0.512;
|
||||||
spinbox->setDecimals(1);
|
|
||||||
spinbox->setSuffix("us");
|
spinbox->setSuffix("us");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
spinbox->setDecimals(0);
|
displayStep = 0.1;
|
||||||
spinbox->setSuffix("%");
|
spinbox->setSuffix("%");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deflt == 0 /*it's the offset*/) {
|
spinbox->setSingleStep(displayStep);
|
||||||
spinbox->setDecimals(1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
internalStep *= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinbox->setSingleStep(displayStep * internalStep);
|
|
||||||
spinbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
spinbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
|
|
||||||
QHBoxLayout *horizontalLayout = new QHBoxLayout();
|
QHBoxLayout *horizontalLayout = new QHBoxLayout();
|
||||||
QCheckBox *gv = new QCheckBox(tr("GV"));
|
gv = new QCheckBox(tr("GV"));
|
||||||
gv->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
gv->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
horizontalLayout->addWidget(gv);
|
horizontalLayout->addWidget(gv);
|
||||||
QComboBox *cb = new QComboBox();
|
QComboBox *cb = new QComboBox();
|
||||||
|
@ -65,7 +54,7 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row
|
||||||
horizontalLayout->addWidget(cb);
|
horizontalLayout->addWidget(cb);
|
||||||
horizontalLayout->addWidget(spinbox);
|
horizontalLayout->addWidget(spinbox);
|
||||||
tableLayout->addLayout(row, col, horizontalLayout);
|
tableLayout->addLayout(row, col, horizontalLayout);
|
||||||
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars);
|
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, gvarModel);
|
||||||
QObject::connect(gvarGroup, &GVarGroup::valueChanged, panel, &ModelPanel::modified);
|
QObject::connect(gvarGroup, &GVarGroup::valueChanged, panel, &ModelPanel::modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,18 +73,19 @@ void LimitsGroup::updateMinMax(int max)
|
||||||
if (spinbox->maximum() == 0) {
|
if (spinbox->maximum() == 0) {
|
||||||
spinbox->setMinimum(-max * displayStep);
|
spinbox->setMinimum(-max * displayStep);
|
||||||
gvarGroup->setMinimum(-max);
|
gvarGroup->setMinimum(-max);
|
||||||
if (value < -max) {
|
if (!gv->isChecked() && value < -max) {
|
||||||
value = -max;
|
value = -max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spinbox->minimum() == 0) {
|
if (spinbox->minimum() == 0) {
|
||||||
spinbox->setMaximum(max * displayStep);
|
spinbox->setMaximum(max * displayStep);
|
||||||
gvarGroup->setMaximum(max);
|
gvarGroup->setMaximum(max);
|
||||||
if (value > max) {
|
if (!gv->isChecked() && value > max) {
|
||||||
value = max;
|
value = max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
|
ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
|
||||||
ModelPanel(parent, model, generalSettings, firmware),
|
ModelPanel(parent, model, generalSettings, firmware),
|
||||||
sharedItemModels(sharedItemModels)
|
sharedItemModels(sharedItemModels)
|
||||||
|
@ -103,8 +93,12 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting
|
||||||
chnCapability = firmware->getCapability(Outputs);
|
chnCapability = firmware->getCapability(Outputs);
|
||||||
int channelNameMaxLen = firmware->getCapability(ChannelsName);
|
int channelNameMaxLen = firmware->getCapability(ChannelsName);
|
||||||
|
|
||||||
curveFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve));
|
dialogFilteredItemModels = new FilteredItemModelFactory();
|
||||||
connectItemModelEvents(curveFilteredModel);
|
|
||||||
|
int crvid = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve)), "Curve");
|
||||||
|
connectItemModelEvents(dialogFilteredItemModels->getItemModel(crvid));
|
||||||
|
|
||||||
|
int gvid = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef");
|
||||||
|
|
||||||
QStringList headerLabels;
|
QStringList headerLabels;
|
||||||
headerLabels << "#";
|
headerLabels << "#";
|
||||||
|
@ -146,13 +140,13 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channel offset
|
// Channel offset
|
||||||
chnOffset[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, this);
|
chnOffset[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, dialogFilteredItemModels->getItemModel(gvid), this);
|
||||||
|
|
||||||
// Channel min
|
// Channel min
|
||||||
chnMin[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax() * 10, 0, -1000, this);
|
chnMin[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax() * 10, 0, -1000, dialogFilteredItemModels->getItemModel(gvid), this);
|
||||||
|
|
||||||
// Channel max
|
// Channel max
|
||||||
chnMax[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax() * 10, 1000, this);
|
chnMax[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax() * 10, 1000, dialogFilteredItemModels->getItemModel(gvid), this);
|
||||||
|
|
||||||
// Channel inversion
|
// Channel inversion
|
||||||
invCB[i] = new QComboBox(this);
|
invCB[i] = new QComboBox(this);
|
||||||
|
@ -165,7 +159,7 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting
|
||||||
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
|
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
|
||||||
curveCB[i] = new QComboBox(this);
|
curveCB[i] = new QComboBox(this);
|
||||||
curveCB[i]->setProperty("index", i);
|
curveCB[i]->setProperty("index", i);
|
||||||
curveCB[i]->setModel(curveFilteredModel);
|
curveCB[i]->setModel(dialogFilteredItemModels->getItemModel(crvid));
|
||||||
connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
|
connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
|
||||||
tableLayout->addWidget(i, col++, curveCB[i]);
|
tableLayout->addWidget(i, col++, curveCB[i]);
|
||||||
}
|
}
|
||||||
|
@ -213,7 +207,7 @@ ChannelsPanel::~ChannelsPanel()
|
||||||
delete centerSB[i];
|
delete centerSB[i];
|
||||||
delete symlimitsChk[i];
|
delete symlimitsChk[i];
|
||||||
}
|
}
|
||||||
delete curveFilteredModel;
|
delete dialogFilteredItemModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::symlimitsEdited()
|
void ChannelsPanel::symlimitsEdited()
|
||||||
|
@ -241,12 +235,11 @@ void ChannelsPanel::nameEdited()
|
||||||
|
|
||||||
void ChannelsPanel::refreshExtendedLimits()
|
void ChannelsPanel::refreshExtendedLimits()
|
||||||
{
|
{
|
||||||
int channelMax = model->getChannelsMax();
|
int channelMax = model->getChannelsMax() * 10;
|
||||||
|
|
||||||
for (int i = 0 ; i < CPN_MAX_CHNOUT; i++) {
|
for (int i = 0 ; i < CPN_MAX_CHNOUT; i++) {
|
||||||
chnOffset[i]->updateMinMax(10 * channelMax);
|
chnMin[i]->updateMinMax(channelMax);
|
||||||
chnMin[i]->updateMinMax(10 * channelMax);
|
chnMax[i]->updateMinMax(channelMax);
|
||||||
chnMax[i]->updateMinMax(10 * channelMax);
|
|
||||||
}
|
}
|
||||||
emit modified();
|
emit modified();
|
||||||
}
|
}
|
||||||
|
@ -319,10 +312,9 @@ void ChannelsPanel::cmPaste()
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
if (hasClipboardData(&data)) {
|
if (hasClipboardData(&data)) {
|
||||||
memcpy(&model->limitData[selectedIndex], data.constData(), sizeof(LimitData));
|
model->limitsSet(selectedIndex, data);
|
||||||
updateLine(selectedIndex);
|
updateLine(selectedIndex);
|
||||||
updateItemModels();
|
updateItemModels();
|
||||||
emit modified();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,22 +323,18 @@ void ChannelsPanel::cmDelete()
|
||||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memmove(&model->limitData[selectedIndex], &model->limitData[selectedIndex + 1], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData));
|
model->limitsDelete(selectedIndex);
|
||||||
model->limitData[chnCapability - 1].clear();
|
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
|
|
||||||
|
|
||||||
for (int i = selectedIndex; i < chnCapability; i++) {
|
for (int i = selectedIndex; i < chnCapability; i++) {
|
||||||
updateLine(i);
|
updateLine(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateItemModels();
|
updateItemModels();
|
||||||
emit modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::cmCopy()
|
void ChannelsPanel::cmCopy()
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
data.append((char*)&model->limitData[selectedIndex], sizeof(LimitData));
|
model->limitsGet(selectedIndex, data);
|
||||||
QMimeData *mimeData = new QMimeData;
|
QMimeData *mimeData = new QMimeData;
|
||||||
mimeData->setData(MIMETYPE_CHANNEL, data);
|
mimeData->setData(MIMETYPE_CHANNEL, data);
|
||||||
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
|
||||||
|
@ -412,12 +400,18 @@ bool ChannelsPanel::moveUpAllowed() const
|
||||||
|
|
||||||
void ChannelsPanel::cmMoveUp()
|
void ChannelsPanel::cmMoveUp()
|
||||||
{
|
{
|
||||||
swapData(selectedIndex, selectedIndex - 1);
|
model->limitsMove(selectedIndex, -1);
|
||||||
|
updateLine(selectedIndex - 1);
|
||||||
|
updateLine(selectedIndex);
|
||||||
|
updateItemModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::cmMoveDown()
|
void ChannelsPanel::cmMoveDown()
|
||||||
{
|
{
|
||||||
swapData(selectedIndex, selectedIndex + 1);
|
model->limitsMove(selectedIndex, 1);
|
||||||
|
updateLine(selectedIndex);
|
||||||
|
updateLine(selectedIndex + 1);
|
||||||
|
updateItemModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::cmClear(bool prompt)
|
void ChannelsPanel::cmClear(bool prompt)
|
||||||
|
@ -427,11 +421,9 @@ void ChannelsPanel::cmClear(bool prompt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
model->limitData[selectedIndex].clear();
|
model->limitsClear(selectedIndex);
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
|
|
||||||
updateLine(selectedIndex);
|
updateLine(selectedIndex);
|
||||||
updateItemModels();
|
updateItemModels();
|
||||||
emit modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::cmClearAll()
|
void ChannelsPanel::cmClearAll()
|
||||||
|
@ -439,39 +431,19 @@ void ChannelsPanel::cmClearAll()
|
||||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < chnCapability; i++) {
|
model->limitsClearAll();
|
||||||
model->limitData[i].clear();
|
update();
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, i);
|
|
||||||
updateLine(i);
|
|
||||||
}
|
|
||||||
updateItemModels();
|
updateItemModels();
|
||||||
emit modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::cmInsert()
|
void ChannelsPanel::cmInsert()
|
||||||
{
|
{
|
||||||
memmove(&model->limitData[selectedIndex + 1], &model->limitData[selectedIndex], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData));
|
model->limitsInsert(selectedIndex);
|
||||||
model->limitData[selectedIndex].clear();
|
for (int i = selectedIndex; i < chnCapability; i++) {
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
|
updateLine(i);
|
||||||
update();
|
|
||||||
updateItemModels();
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChannelsPanel::swapData(int idx1, int idx2)
|
|
||||||
{
|
|
||||||
if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) {
|
|
||||||
LimitData chntmp = model->limitData[idx2];
|
|
||||||
LimitData *chn1 = &model->limitData[idx1];
|
|
||||||
LimitData *chn2 = &model->limitData[idx2];
|
|
||||||
memcpy(chn2, chn1, sizeof(LimitData));
|
|
||||||
memcpy(chn1, &chntmp, sizeof(LimitData));
|
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
|
|
||||||
updateLine(idx1);
|
|
||||||
updateLine(idx2);
|
|
||||||
updateItemModels();
|
|
||||||
emit modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateItemModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
void ChannelsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
||||||
|
@ -494,4 +466,5 @@ void ChannelsPanel::onItemModelUpdateComplete()
|
||||||
void ChannelsPanel::updateItemModels()
|
void ChannelsPanel::updateItemModels()
|
||||||
{
|
{
|
||||||
sharedItemModels->update(AbstractItemModel::IMUE_Channels);
|
sharedItemModels->update(AbstractItemModel::IMUE_Channels);
|
||||||
|
emit modified();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CHANNELS_H_
|
#pragma once
|
||||||
#define _CHANNELS_H_
|
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "modeledit.h"
|
#include "modeledit.h"
|
||||||
|
@ -27,7 +26,7 @@
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
class CompoundItemModelFactory;
|
class CompoundItemModelFactory;
|
||||||
class FilteredItemModel;
|
class FilteredItemModelFactory;
|
||||||
|
|
||||||
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
|
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
|
||||||
|
|
||||||
|
@ -38,7 +37,8 @@ class LimitsGroup
|
||||||
Q_DECLARE_TR_FUNCTIONS(LimitsGroup)
|
Q_DECLARE_TR_FUNCTIONS(LimitsGroup)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel=NULL);
|
LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model,
|
||||||
|
int min, int max, int deflt, FilteredItemModel * gvarModel, ModelPanel * panel = nullptr);
|
||||||
~LimitsGroup();
|
~LimitsGroup();
|
||||||
|
|
||||||
void setValue(int val);
|
void setValue(int val);
|
||||||
|
@ -50,6 +50,7 @@ class LimitsGroup
|
||||||
GVarGroup *gvarGroup;
|
GVarGroup *gvarGroup;
|
||||||
int &value;
|
int &value;
|
||||||
double displayStep;
|
double displayStep;
|
||||||
|
QCheckBox *gv;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChannelsPanel : public ModelPanel
|
class ChannelsPanel : public ModelPanel
|
||||||
|
@ -57,7 +58,8 @@ class ChannelsPanel : public ModelPanel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
|
ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
|
||||||
|
CompoundItemModelFactory * sharedItemModels);
|
||||||
virtual ~ChannelsPanel();
|
virtual ~ChannelsPanel();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -89,7 +91,6 @@ class ChannelsPanel : public ModelPanel
|
||||||
bool insertAllowed() const;
|
bool insertAllowed() const;
|
||||||
bool moveDownAllowed() const;
|
bool moveDownAllowed() const;
|
||||||
bool moveUpAllowed() const;
|
bool moveUpAllowed() const;
|
||||||
void swapData(int idx1, int idx2);
|
|
||||||
QLineEdit *name[CPN_MAX_CHNOUT];
|
QLineEdit *name[CPN_MAX_CHNOUT];
|
||||||
LimitsGroup *chnOffset[CPN_MAX_CHNOUT];
|
LimitsGroup *chnOffset[CPN_MAX_CHNOUT];
|
||||||
LimitsGroup *chnMin[CPN_MAX_CHNOUT];
|
LimitsGroup *chnMin[CPN_MAX_CHNOUT];
|
||||||
|
@ -101,9 +102,7 @@ class ChannelsPanel : public ModelPanel
|
||||||
int selectedIndex;
|
int selectedIndex;
|
||||||
int chnCapability;
|
int chnCapability;
|
||||||
CompoundItemModelFactory *sharedItemModels;
|
CompoundItemModelFactory *sharedItemModels;
|
||||||
FilteredItemModel *curveFilteredModel;
|
|
||||||
void updateItemModels();
|
void updateItemModels();
|
||||||
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
||||||
|
FilteredItemModelFactory *dialogFilteredItemModels;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CHANNELS_H_
|
|
||||||
|
|
|
@ -19,53 +19,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "customfunctions.h"
|
#include "customfunctions.h"
|
||||||
#include "filtereditemmodels.h"
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "appdata.h"
|
#include "appdata.h"
|
||||||
|
|
||||||
#include <TimerEdit>
|
#include <TimerEdit>
|
||||||
|
|
||||||
RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam):
|
|
||||||
QComboBox(parent),
|
|
||||||
repeatParam(repeatParam)
|
|
||||||
{
|
|
||||||
unsigned int step = 1;
|
|
||||||
int value = repeatParam/step;
|
|
||||||
|
|
||||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
|
|
||||||
|
|
||||||
if (step == 1) {
|
|
||||||
addItem(tr("Played once, not during startup"), -1);
|
|
||||||
value++;
|
|
||||||
}
|
|
||||||
|
|
||||||
addItem(tr("No repeat"), 0);
|
|
||||||
|
|
||||||
for (unsigned int i = step; i <= 60; i += step) {
|
|
||||||
addItem(tr("%1s").arg(i), i);
|
|
||||||
}
|
|
||||||
|
|
||||||
setCurrentIndex(value);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onIndexChanged(int)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepeatComboBox::onIndexChanged(int index)
|
|
||||||
{
|
|
||||||
repeatParam = itemData(index).toInt();
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepeatComboBox::update()
|
|
||||||
{
|
|
||||||
unsigned int step = 1;
|
|
||||||
int value = repeatParam/step;
|
|
||||||
if (step == 1) {
|
|
||||||
value++;
|
|
||||||
}
|
|
||||||
setCurrentIndex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware,
|
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware,
|
||||||
CompoundItemModelFactory * sharedItemModels):
|
CompoundItemModelFactory * sharedItemModels):
|
||||||
GenericPanel(parent, model, generalSettings, firmware),
|
GenericPanel(parent, model, generalSettings, firmware),
|
||||||
|
@ -77,18 +35,41 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
lock = true;
|
lock = true;
|
||||||
fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
|
fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
|
||||||
|
|
||||||
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
|
tabModelFactory = new CompoundItemModelFactory(&generalSettings, model);
|
||||||
model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext);
|
playSoundId = tabModelFactory->registerItemModel(CustomFunctionData::playSoundItemModel());
|
||||||
connectItemModelEvents(rawSwitchFilteredModel);
|
harpicId = tabModelFactory->registerItemModel(CustomFunctionData::harpicItemModel());
|
||||||
|
repeatId = tabModelFactory->registerItemModel(CustomFunctionData::repeatItemModel());
|
||||||
|
gvarAdjustModeId = tabModelFactory->registerItemModel(CustomFunctionData::gvarAdjustModeItemModel());
|
||||||
|
|
||||||
rawSourceAllModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource));
|
tabFilterFactory = new FilteredItemModelFactory();
|
||||||
connectItemModelEvents(rawSourceAllModel);
|
|
||||||
|
|
||||||
rawSourceInputsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups);
|
funcActionsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CustomFuncAction),
|
||||||
connectItemModelEvents(rawSourceInputsModel);
|
model ? CustomFunctionData::AllFunctionContexts : CustomFunctionData::GlobalFunctionsContext),
|
||||||
|
"Function Actions");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(funcActionsId));
|
||||||
|
|
||||||
rawSourceGVarsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::GVarsGroup);
|
funcResetParamId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CustomFuncResetParam)),
|
||||||
connectItemModelEvents(rawSourceGVarsModel);
|
"Reset Params");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(funcResetParamId));
|
||||||
|
|
||||||
|
rawSwitchId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
|
||||||
|
model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext),
|
||||||
|
"RawSwitch");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(rawSwitchId));
|
||||||
|
|
||||||
|
rawSourceAllId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource)),
|
||||||
|
"RawSource All");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceAllId));
|
||||||
|
|
||||||
|
rawSourceInputsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
||||||
|
RawSource::InputSourceGroups),
|
||||||
|
"RawSource Inputs");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceInputsId));
|
||||||
|
|
||||||
|
rawSourceGVarsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
||||||
|
RawSource::GVarsGroup),
|
||||||
|
"RawSource GVars");
|
||||||
|
connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceGVarsId));
|
||||||
|
|
||||||
if (!firmware->getCapability(VoicesAsNumbers)) {
|
if (!firmware->getCapability(VoicesAsNumbers)) {
|
||||||
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
|
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
|
||||||
|
@ -118,7 +99,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
playIcon.addImage("stop.png", QIcon::Normal, QIcon::On);
|
playIcon.addImage("stop.png", QIcon::Normal, QIcon::On);
|
||||||
|
|
||||||
QStringList headerLabels;
|
QStringList headerLabels;
|
||||||
headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Enable");
|
headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << "";
|
||||||
TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels);
|
TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels);
|
||||||
|
|
||||||
for (int i = 0; i < fswCapability; i++) {
|
for (int i = 0; i < fswCapability; i++) {
|
||||||
|
@ -135,32 +116,26 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
|
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||||
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
|
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
|
||||||
tableLayout->addWidget(i, 0, label);
|
tableLayout->addWidget(i, 0, label);
|
||||||
// s1.report("label");
|
|
||||||
|
|
||||||
// The switch
|
// The switch
|
||||||
fswtchSwtch[i] = new QComboBox(this);
|
fswtchSwtch[i] = new QComboBox(this);
|
||||||
fswtchSwtch[i]->setModel(rawSwitchFilteredModel);
|
|
||||||
fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue()));
|
|
||||||
fswtchSwtch[i]->setProperty("index", i);
|
fswtchSwtch[i]->setProperty("index", i);
|
||||||
|
fswtchSwtch[i]->setModel(tabFilterFactory->getItemModel(rawSwitchId));
|
||||||
|
fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue()));
|
||||||
fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
|
fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
|
||||||
|
fswtchSwtch[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
fswtchSwtch[i]->setMaxVisibleItems(10);
|
fswtchSwtch[i]->setMaxVisibleItems(10);
|
||||||
connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
tableLayout->addWidget(i, 1, fswtchSwtch[i]);
|
tableLayout->addWidget(i, 1, fswtchSwtch[i]);
|
||||||
// s1.report("switch");
|
|
||||||
|
|
||||||
// The function
|
// The function
|
||||||
fswtchFunc[i] = new QComboBox(this);
|
fswtchFunc[i] = new QComboBox(this);
|
||||||
if (!i) {
|
|
||||||
populateFuncCB(fswtchFunc[i], functions[i].func);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fswtchFunc[i]->setModel(fswtchFunc[0]->model());
|
|
||||||
fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func));
|
|
||||||
}
|
|
||||||
fswtchFunc[i]->setProperty("index", i);
|
fswtchFunc[i]->setProperty("index", i);
|
||||||
|
fswtchFunc[i]->setModel(tabFilterFactory->getItemModel(funcActionsId));
|
||||||
|
fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func));
|
||||||
|
fswtchFunc[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited()));
|
connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited()));
|
||||||
tableLayout->addWidget(i, 2, fswtchFunc[i]);
|
tableLayout->addWidget(i, 2, fswtchFunc[i]);
|
||||||
// s1.report("func");
|
|
||||||
|
|
||||||
// The parameters
|
// The parameters
|
||||||
QHBoxLayout * paramLayout = new QHBoxLayout();
|
QHBoxLayout * paramLayout = new QHBoxLayout();
|
||||||
|
@ -168,15 +143,15 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
|
|
||||||
fswtchGVmode[i] = new QComboBox(this);
|
fswtchGVmode[i] = new QComboBox(this);
|
||||||
fswtchGVmode[i]->setProperty("index", i);
|
fswtchGVmode[i]->setProperty("index", i);
|
||||||
populateGVmodeCB(fswtchGVmode[i], functions[i].adjustMode);
|
fswtchGVmode[i]->setModel(tabModelFactory->getItemModel(gvarAdjustModeId));
|
||||||
fswtchGVmode[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
fswtchGVmode[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
connect(fswtchGVmode[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
connect(fswtchGVmode[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
paramLayout->addWidget(fswtchGVmode[i]);
|
paramLayout->addWidget(fswtchGVmode[i]);
|
||||||
|
|
||||||
fswtchParamGV[i] = new QCheckBox(this);
|
fswtchParamGV[i] = new QCheckBox(this);
|
||||||
fswtchParamGV[i]->setProperty("index", i);
|
fswtchParamGV[i]->setProperty("index", i);
|
||||||
fswtchParamGV[i]->setText("GV");
|
fswtchParamGV[i]->setText(tr("GV"));
|
||||||
fswtchParamGV[i]->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
|
fswtchParamGV[i]->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
connect(fswtchParamGV[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
|
connect(fswtchParamGV[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
paramLayout->addWidget(fswtchParamGV[i]);
|
paramLayout->addWidget(fswtchParamGV[i]);
|
||||||
|
|
||||||
|
@ -207,15 +182,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited()));
|
connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited()));
|
||||||
|
|
||||||
fswtchBLcolor[i] = new QSlider(this);
|
|
||||||
fswtchBLcolor[i]->setProperty("index", i);
|
|
||||||
fswtchBLcolor[i]->setMinimum(0);
|
|
||||||
fswtchBLcolor[i]->setMaximum(100);
|
|
||||||
fswtchBLcolor[i]->setSingleStep(1);
|
|
||||||
fswtchBLcolor[i]->setOrientation(Qt::Horizontal);
|
|
||||||
paramLayout->addWidget(fswtchBLcolor[i]);
|
|
||||||
connect(fswtchBLcolor[i], SIGNAL(sliderReleased()), this, SLOT(customFunctionEdited()));
|
|
||||||
|
|
||||||
playBT[i] = new QToolButton(this);
|
playBT[i] = new QToolButton(this);
|
||||||
playBT[i]->setProperty("index", i);
|
playBT[i]->setProperty("index", i);
|
||||||
playBT[i]->setIcon(playIcon);
|
playBT[i]->setIcon(playIcon);
|
||||||
|
@ -225,9 +191,13 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||||
|
|
||||||
QHBoxLayout * repeatLayout = new QHBoxLayout();
|
QHBoxLayout * repeatLayout = new QHBoxLayout();
|
||||||
tableLayout->addLayout(i, 4, repeatLayout);
|
tableLayout->addLayout(i, 4, repeatLayout);
|
||||||
fswtchRepeat[i] = new RepeatComboBox(this, functions[i].repeatParam);
|
fswtchRepeat[i] = new QComboBox(this);
|
||||||
|
fswtchRepeat[i]->setProperty("index", i);
|
||||||
|
fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatId));
|
||||||
|
fswtchRepeat[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
|
||||||
|
fswtchRepeat[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
repeatLayout->addWidget(fswtchRepeat[i], i + 1);
|
repeatLayout->addWidget(fswtchRepeat[i], i + 1);
|
||||||
connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onRepeatModified()));
|
connect(fswtchRepeat[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||||
|
|
||||||
fswtchEnable[i] = new QCheckBox(this);
|
fswtchEnable[i] = new QCheckBox(this);
|
||||||
fswtchEnable[i]->setProperty("index", i);
|
fswtchEnable[i]->setProperty("index", i);
|
||||||
|
@ -250,10 +220,8 @@ CustomFunctionsPanel::~CustomFunctionsPanel()
|
||||||
{
|
{
|
||||||
if (mediaPlayer)
|
if (mediaPlayer)
|
||||||
stopSound(mediaPlayerCurrent);
|
stopSound(mediaPlayerCurrent);
|
||||||
delete rawSwitchFilteredModel;
|
delete tabModelFactory;
|
||||||
delete rawSourceAllModel;
|
delete tabFilterFactory;
|
||||||
delete rawSourceInputsModel;
|
|
||||||
delete rawSourceGVarsModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state)
|
void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state)
|
||||||
|
@ -333,7 +301,6 @@ void CustomFunctionsPanel::toggleSound(bool play)
|
||||||
#define CUSTOM_FUNCTION_ENABLE (1<<6)
|
#define CUSTOM_FUNCTION_ENABLE (1<<6)
|
||||||
#define CUSTOM_FUNCTION_REPEAT (1<<7)
|
#define CUSTOM_FUNCTION_REPEAT (1<<7)
|
||||||
#define CUSTOM_FUNCTION_PLAY (1<<8)
|
#define CUSTOM_FUNCTION_PLAY (1<<8)
|
||||||
#define CUSTOM_FUNCTION_BL_COLOR (1<<9)
|
|
||||||
#define CUSTOM_FUNCTION_SHOW_FUNC (1<<10)
|
#define CUSTOM_FUNCTION_SHOW_FUNC (1<<10)
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,11 +330,6 @@ void CustomFunctionsPanel::functionEdited()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionsPanel::onRepeatModified()
|
|
||||||
{
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
{
|
{
|
||||||
CustomFunctionData & cfn = functions[i];
|
CustomFunctionData & cfn = functions[i];
|
||||||
|
@ -414,8 +376,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) {
|
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) {
|
||||||
int gvidx = func - FuncAdjustGV1;
|
int gvidx = func - FuncAdjustGV1;
|
||||||
if (modified)
|
if (modified)
|
||||||
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
|
cfn.adjustMode = fswtchGVmode[i]->currentData().toInt();
|
||||||
fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode);
|
fswtchGVmode[i]->setCurrentIndex(fswtchGVmode[i]->findData(cfn.adjustMode));
|
||||||
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
|
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
|
||||||
if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
|
if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
|
||||||
if (modified)
|
if (modified)
|
||||||
|
@ -468,8 +430,10 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
}
|
}
|
||||||
else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) {
|
else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) {
|
||||||
if (func != FuncBackgroundMusic) {
|
if (func != FuncBackgroundMusic) {
|
||||||
|
if (modified)
|
||||||
|
cfn.repeatParam = fswtchRepeat[i]->currentData().toInt();
|
||||||
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
|
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
|
||||||
fswtchRepeat[i]->update();
|
fswtchRepeat[i]->setCurrentIndex(fswtchRepeat[i]->findData(cfn.repeatParam));
|
||||||
}
|
}
|
||||||
if (func == FuncPlayValue) {
|
if (func == FuncPlayValue) {
|
||||||
if (modified)
|
if (modified)
|
||||||
|
@ -493,7 +457,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
if (modified) {
|
if (modified) {
|
||||||
if (fswtchParamGV[i]->isChecked()) {
|
if (fswtchParamGV[i]->isChecked()) {
|
||||||
fswtchParam[i]->setMinimum(1);
|
fswtchParam[i]->setMinimum(1);
|
||||||
cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
|
cfn.param = std::min(fswtchParam[i]->value(), 5.0) + (fswtchParamGV[i]->isChecked() ? 250 : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cfn.param = fswtchParam[i]->value();
|
cfn.param = fswtchParam[i]->value();
|
||||||
|
@ -577,7 +541,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||||
fswtchEnable[i]->setChecked(false);
|
fswtchEnable[i]->setChecked(false);
|
||||||
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
|
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
|
||||||
fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE);
|
fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE);
|
||||||
fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR);
|
|
||||||
playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY);
|
playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,77 +616,43 @@ void CustomFunctionsPanel::onCustomContextMenuRequested(QPoint pos)
|
||||||
contextMenu.exec(globalPos);
|
contextMenu.exec(globalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
|
|
||||||
{
|
|
||||||
b->clear();
|
|
||||||
for (unsigned int i = 0; i < FuncCount; i++) {
|
|
||||||
if (((i >= FuncOverrideCH1 && i <= FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) ||
|
|
||||||
((i == FuncVolume || i == FuncBackgroundMusic || i == FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) ||
|
|
||||||
((i == FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) ||
|
|
||||||
((i == FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
|
|
||||||
((i == FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
|
|
||||||
((i == FuncLogs) && !firmware->getCapability(HasSDLogs)) ||
|
|
||||||
((i == FuncSetTimer3) && firmware->getCapability(Timers) < 3) ||
|
|
||||||
((i == FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) ||
|
|
||||||
((i >= FuncRangeCheckInternalModule && i <= FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) ||
|
|
||||||
((i >= FuncAdjustGV1 && i <= FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars)))
|
|
||||||
) {
|
|
||||||
// skipped
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(model), i);
|
|
||||||
if (i == value) {
|
|
||||||
b->setCurrentIndex(b->count() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomFunctionsPanel::populateGVmodeCB(QComboBox *b, unsigned int value)
|
|
||||||
{
|
|
||||||
b->clear();
|
|
||||||
b->addItem(tr("Value"));
|
|
||||||
b->addItem(tr("Source"));
|
|
||||||
b->addItem(tr("GVAR"));
|
|
||||||
b->addItem(tr("Increment"));
|
|
||||||
b->setCurrentIndex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode)
|
void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode)
|
||||||
{
|
{
|
||||||
QStringList qs;
|
QStringList qs;
|
||||||
b->setModel(new QStandardItemModel(b)); // clear combo box but not any shared item model
|
b->setModel(new QStandardItemModel(b)); // clear combo box but not any shared item model
|
||||||
if (function == FuncPlaySound) {
|
if (function == FuncPlaySound) {
|
||||||
CustomFunctionData::populatePlaySoundParams(qs);
|
b->setModel(tabModelFactory->getItemModel(playSoundId));
|
||||||
b->addItems(qs);
|
b->setCurrentIndex(b->findData(value));
|
||||||
b->setCurrentIndex(value);
|
|
||||||
}
|
}
|
||||||
else if (function == FuncPlayHaptic) {
|
else if (function == FuncPlayHaptic) {
|
||||||
CustomFunctionData::populateHapticParams(qs);
|
b->setModel(tabModelFactory->getItemModel(harpicId));
|
||||||
b->addItems(qs);
|
b->setCurrentIndex(b->findData(value));
|
||||||
b->setCurrentIndex(value);
|
|
||||||
}
|
}
|
||||||
else if (function == FuncReset) {
|
else if (function == FuncReset) {
|
||||||
CustomFunctionData::populateResetParams(model, b, value);
|
b->setModel(tabFilterFactory->getItemModel(funcResetParamId));
|
||||||
|
b->setCurrentIndex(b->findData(value));
|
||||||
}
|
}
|
||||||
else if (function == FuncVolume || function == FuncBacklight) {
|
else if (function == FuncVolume || function == FuncBacklight) {
|
||||||
b->setModel(rawSourceInputsModel);
|
b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId));
|
||||||
b->setCurrentIndex(b->findData(value));
|
b->setCurrentIndex(b->findData(value));
|
||||||
}
|
}
|
||||||
else if (function == FuncPlayValue) {
|
else if (function == FuncPlayValue) {
|
||||||
b->setModel(rawSourceAllModel);
|
b->setModel(tabFilterFactory->getItemModel(rawSourceAllId));
|
||||||
b->setCurrentIndex(b->findData(value));
|
b->setCurrentIndex(b->findData(value));
|
||||||
}
|
}
|
||||||
else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) {
|
else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) {
|
||||||
switch (adjustmode) {
|
switch (adjustmode) {
|
||||||
case 1:
|
case 1:
|
||||||
b->setModel(rawSourceInputsModel);
|
b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId));
|
||||||
b->setCurrentIndex(b->findData(value));
|
b->setCurrentIndex(b->findData(value));
|
||||||
|
if (b->currentIndex() < 0)
|
||||||
|
b->setCurrentIndex(0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
b->setModel(rawSourceGVarsModel);
|
b->setModel(tabFilterFactory->getItemModel(rawSourceGVarsId));
|
||||||
b->setCurrentIndex(b->findData(value));
|
b->setCurrentIndex(b->findData(value));
|
||||||
|
if (b->currentIndex() < 0)
|
||||||
|
b->setCurrentIndex(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -828,7 +757,7 @@ bool CustomFunctionsPanel::moveUpAllowed() const
|
||||||
return selectedIndex > 0;
|
return selectedIndex > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFunctionsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
void CustomFunctionsPanel::connectItemModelEvents(FilteredItemModel * itemModel)
|
||||||
{
|
{
|
||||||
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &CustomFunctionsPanel::onItemModelAboutToBeUpdated);
|
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &CustomFunctionsPanel::onItemModelAboutToBeUpdated);
|
||||||
connect(itemModel, &FilteredItemModel::updateComplete, this, &CustomFunctionsPanel::onItemModelUpdateComplete);
|
connect(itemModel, &FilteredItemModel::updateComplete, this, &CustomFunctionsPanel::onItemModelUpdateComplete);
|
||||||
|
|
|
@ -18,38 +18,19 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CUSTOMFUNCTIONS_H_
|
#pragma once
|
||||||
#define _CUSTOMFUNCTIONS_H_
|
|
||||||
|
|
||||||
#include "modeledit.h"
|
#include "modeledit.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
|
#include "compounditemmodels.h"
|
||||||
|
#include "filtereditemmodels.h"
|
||||||
|
|
||||||
#include <QMediaPlayer>
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
class CompoundItemModelFactory;
|
|
||||||
class FilteredItemModel;
|
|
||||||
class TimerEdit;
|
class TimerEdit;
|
||||||
|
|
||||||
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
|
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
|
||||||
|
|
||||||
class RepeatComboBox: public QComboBox
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
RepeatComboBox(QWidget * parent, int & repeatParam);
|
|
||||||
void update();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void modified();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onIndexChanged(int);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int & repeatParam;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CustomFunctionsPanel : public GenericPanel
|
class CustomFunctionsPanel : public GenericPanel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -68,7 +49,6 @@ class CustomFunctionsPanel : public GenericPanel
|
||||||
void functionEdited();
|
void functionEdited();
|
||||||
void onCustomContextMenuRequested(QPoint pos);
|
void onCustomContextMenuRequested(QPoint pos);
|
||||||
void refreshCustomFunction(int index, bool modified=false);
|
void refreshCustomFunction(int index, bool modified=false);
|
||||||
void onRepeatModified();
|
|
||||||
bool playSound(int index);
|
bool playSound(int index);
|
||||||
void stopSound(int index);
|
void stopSound(int index);
|
||||||
void toggleSound(bool play);
|
void toggleSound(bool play);
|
||||||
|
@ -87,8 +67,6 @@ class CustomFunctionsPanel : public GenericPanel
|
||||||
void onItemModelUpdateComplete();
|
void onItemModelUpdateComplete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void populateFuncCB(QComboBox *b, unsigned int value);
|
|
||||||
void populateGVmodeCB(QComboBox *b, unsigned int value);
|
|
||||||
void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0);
|
void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0);
|
||||||
bool hasClipboardData(QByteArray * data = nullptr) const;
|
bool hasClipboardData(QByteArray * data = nullptr) const;
|
||||||
bool insertAllowed() const;
|
bool insertAllowed() const;
|
||||||
|
@ -96,12 +74,20 @@ class CustomFunctionsPanel : public GenericPanel
|
||||||
bool moveUpAllowed() const;
|
bool moveUpAllowed() const;
|
||||||
void swapData(int idx1, int idx2);
|
void swapData(int idx1, int idx2);
|
||||||
void resetCBsAndRefresh(int idx);
|
void resetCBsAndRefresh(int idx);
|
||||||
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
void connectItemModelEvents(FilteredItemModel * itemModel);
|
||||||
|
|
||||||
FilteredItemModel * rawSwitchFilteredModel;
|
CompoundItemModelFactory * tabModelFactory;
|
||||||
FilteredItemModel * rawSourceAllModel;
|
FilteredItemModelFactory * tabFilterFactory;
|
||||||
FilteredItemModel * rawSourceInputsModel;
|
int funcActionsId;
|
||||||
FilteredItemModel * rawSourceGVarsModel;
|
int funcResetParamId;
|
||||||
|
int rawSwitchId;
|
||||||
|
int rawSourceAllId;
|
||||||
|
int rawSourceInputsId;
|
||||||
|
int rawSourceGVarsId;
|
||||||
|
int playSoundId;
|
||||||
|
int harpicId;
|
||||||
|
int repeatId;
|
||||||
|
int gvarAdjustModeId;
|
||||||
|
|
||||||
QSet<QString> tracksSet;
|
QSet<QString> tracksSet;
|
||||||
QSet<QString> scriptsSet;
|
QSet<QString> scriptsSet;
|
||||||
|
@ -115,14 +101,11 @@ class CustomFunctionsPanel : public GenericPanel
|
||||||
QComboBox * fswtchParamT[CPN_MAX_SPECIAL_FUNCTIONS];
|
QComboBox * fswtchParamT[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||||
QComboBox * fswtchParamArmT[CPN_MAX_SPECIAL_FUNCTIONS];
|
QComboBox * fswtchParamArmT[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||||
QCheckBox * fswtchEnable[CPN_MAX_SPECIAL_FUNCTIONS];
|
QCheckBox * fswtchEnable[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||||
RepeatComboBox * fswtchRepeat[CPN_MAX_SPECIAL_FUNCTIONS];
|
QComboBox * fswtchRepeat[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||||
QComboBox * fswtchGVmode[CPN_MAX_SPECIAL_FUNCTIONS];
|
QComboBox * fswtchGVmode[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||||
QSlider * fswtchBLcolor[CPN_MAX_SPECIAL_FUNCTIONS];
|
|
||||||
QMediaPlayer * mediaPlayer;
|
QMediaPlayer * mediaPlayer;
|
||||||
|
|
||||||
int selectedIndex;
|
int selectedIndex;
|
||||||
int fswCapability;
|
int fswCapability;
|
||||||
int modelsUpdateCnt;
|
int modelsUpdateCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CUSTOMFUNCTIONS_H_
|
|
||||||
|
|
|
@ -50,8 +50,11 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||||
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
|
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
|
||||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||||
|
|
||||||
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
|
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef");
|
||||||
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
|
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100, 1.0,
|
||||||
|
dialogFilteredItemModels->getItemModel(id));
|
||||||
|
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100, 1.0,
|
||||||
|
dialogFilteredItemModels->getItemModel(id));
|
||||||
|
|
||||||
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
|
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
|
||||||
firmware->getCapability(HasInputDiff) ? 0 : FilteredItemModel::PositiveFilter);
|
firmware->getCapability(HasInputDiff) ? 0 : FilteredItemModel::PositiveFilter);
|
||||||
|
@ -92,7 +95,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||||
if (firmware->getCapability(VirtualInputs)) {
|
if (firmware->getCapability(VirtualInputs)) {
|
||||||
ui->inputName->setMaxLength(firmware->getCapability(InputsLength));
|
ui->inputName->setMaxLength(firmware->getCapability(InputsLength));
|
||||||
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
||||||
(RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup)),
|
(RawSource::InputSourceGroups & ~RawSource::NoneGroup & ~RawSource::InputsGroup) | RawSource::TelemGroup),
|
||||||
"RawSource");
|
"RawSource");
|
||||||
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
|
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
|
||||||
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
|
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
|
||||||
|
|
|
@ -351,6 +351,9 @@ void InputsPanel::expoOpen(QListWidgetItem *item)
|
||||||
if (!item)
|
if (!item)
|
||||||
item = ExposlistWidget->currentItem();
|
item = ExposlistWidget->currentItem();
|
||||||
|
|
||||||
|
if (item == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
int idx = item->data(Qt::UserRole).toByteArray().at(0);
|
int idx = item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
int ch = -idx - 1;
|
int ch = -idx - 1;
|
||||||
|
@ -368,7 +371,11 @@ void InputsPanel::expoOpen(QListWidgetItem *item)
|
||||||
|
|
||||||
void InputsPanel::expoAdd()
|
void InputsPanel::expoAdd()
|
||||||
{
|
{
|
||||||
int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
QListWidgetItem *item = ExposlistWidget->currentItem();
|
||||||
|
if (item == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
|
|
||||||
if (index < 0) { // if empty then return relevant index
|
if (index < 0) { // if empty then return relevant index
|
||||||
expoOpen();
|
expoOpen();
|
||||||
|
@ -573,13 +580,15 @@ bool InputsPanel::cmInputMoveUpAllowed() const
|
||||||
|
|
||||||
void InputsPanel::cmInputClear()
|
void InputsPanel::cmInputClear()
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all lines for the selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all lines for the selected Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = CPN_MAX_EXPOS - 1; i >= 0; i--) {
|
for (int i = CPN_MAX_EXPOS - 1; i >= 0; i--) {
|
||||||
ExpoData *ed = &model->expoData[i];
|
ExpoData *ed = &model->expoData[i];
|
||||||
if ((int)ed->chn == inputIdx)
|
if (!ed->isEmpty()) {
|
||||||
model->removeInput(i);
|
if ((int)ed->chn == inputIdx)
|
||||||
|
model->removeInput(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx);
|
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx);
|
||||||
update();
|
update();
|
||||||
|
@ -589,15 +598,17 @@ void InputsPanel::cmInputClear()
|
||||||
|
|
||||||
void InputsPanel::cmInputDelete()
|
void InputsPanel::cmInputDelete()
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete all lines for the selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete all lines for the selected Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < CPN_MAX_EXPOS; i++) {
|
for (int i = CPN_MAX_EXPOS - 1; i >= 0; i--) {
|
||||||
ExpoData *ed = &model->expoData[i];
|
ExpoData *ed = &model->expoData[i];
|
||||||
if ((int)ed->chn == inputIdx)
|
if (!ed->isEmpty()) {
|
||||||
model->removeInput(i);
|
if ((int)ed->chn == inputIdx)
|
||||||
else if ((int)ed->chn > inputIdx)
|
model->removeInput(i);
|
||||||
ed->chn--;
|
else if ((int)ed->chn > inputIdx)
|
||||||
|
ed->chn--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = inputIdx; i < inputsCount; i++) {
|
for (int i = inputIdx; i < inputsCount; i++) {
|
||||||
|
|
|
@ -49,15 +49,19 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
|
||||||
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings)));
|
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings)));
|
||||||
|
|
||||||
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
|
||||||
((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup)),
|
(RawSource::InputSourceGroups & ~RawSource::NoneGroup) | RawSource::ScriptsGroup),
|
||||||
"RawSource");
|
"RawSource");
|
||||||
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
|
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
|
||||||
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
|
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
|
||||||
|
|
||||||
int limit = firmware->getCapability(OffsetWeight);
|
int limit = firmware->getCapability(OffsetWeight);
|
||||||
|
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef");
|
||||||
|
|
||||||
|
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit, 1.0,
|
||||||
|
dialogFilteredItemModels->getItemModel(id));
|
||||||
|
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit, 1.0,
|
||||||
|
dialogFilteredItemModels->getItemModel(id));
|
||||||
|
|
||||||
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit);
|
|
||||||
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit);
|
|
||||||
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
|
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
|
||||||
firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter);
|
firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter);
|
||||||
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model,
|
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model,
|
||||||
|
|
|
@ -354,7 +354,11 @@ void MixesPanel::mixersDuplicate()
|
||||||
|
|
||||||
void MixesPanel::mixerOpen()
|
void MixesPanel::mixerOpen()
|
||||||
{
|
{
|
||||||
int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
QListWidgetItem *item = mixersListWidget->currentItem();
|
||||||
|
if (item == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int idx = item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
if(idx < 0) {
|
if(idx < 0) {
|
||||||
int i = -idx;
|
int i = -idx;
|
||||||
idx = getMixerIndex(i); //get mixer index to insert
|
idx = getMixerIndex(i); //get mixer index to insert
|
||||||
|
@ -371,7 +375,11 @@ void MixesPanel::mixerOpen()
|
||||||
|
|
||||||
void MixesPanel::mixerHighlight()
|
void MixesPanel::mixerHighlight()
|
||||||
{
|
{
|
||||||
int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
QListWidgetItem *item = mixersListWidget->currentItem();
|
||||||
|
if (item == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int idx = item->data(Qt::UserRole).toByteArray().at(0);
|
||||||
int dest;
|
int dest;
|
||||||
if (idx<0) {
|
if (idx<0) {
|
||||||
dest = -idx;
|
dest = -idx;
|
||||||
|
|
|
@ -62,6 +62,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
|
||||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
|
||||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
|
||||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_TeleSource);
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_TeleSource);
|
||||||
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_RssiSource);
|
||||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefType);
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefType);
|
||||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefFunc);
|
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefFunc);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "ui_setup.h"
|
#include "ui_setup.h"
|
||||||
#include "ui_setup_timer.h"
|
#include "ui_setup_timer.h"
|
||||||
#include "ui_setup_module.h"
|
#include "ui_setup_module.h"
|
||||||
#include "filtereditemmodels.h"
|
|
||||||
#include "appdata.h"
|
#include "appdata.h"
|
||||||
#include "modelprinter.h"
|
#include "modelprinter.h"
|
||||||
#include "multiprotocols.h"
|
#include "multiprotocols.h"
|
||||||
|
@ -31,54 +30,53 @@
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
|
constexpr char FIM_TIMERSWITCH[] {"Timer Switch"};
|
||||||
QWidget * prevFocus, FilteredItemModel * rawSwitchFilteredModel):
|
constexpr char FIM_THRSOURCE[] {"Throttle Source"};
|
||||||
|
|
||||||
|
TimerPanel::TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
|
||||||
|
QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels):
|
||||||
ModelPanel(parent, model, generalSettings, firmware),
|
ModelPanel(parent, model, generalSettings, firmware),
|
||||||
timer(timer),
|
timer(timer),
|
||||||
ui(new Ui::Timer)
|
ui(new Ui::Timer),
|
||||||
|
modelsUpdateCnt(0)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
connectItemModelEvents(rawSwitchFilteredModel);
|
connectItemModelEvents(panelFilteredModels->getItemModel(FIM_TIMERSWITCH));
|
||||||
|
|
||||||
lock = true;
|
lock = true;
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
int length = firmware->getCapability(TimersName);
|
int length = firmware->getCapability(TimersName);
|
||||||
if (length == 0) {
|
if (length == 0)
|
||||||
ui->name->hide();
|
ui->name->hide();
|
||||||
|
else {
|
||||||
|
ui->name->setField(timer.name, length, this);
|
||||||
|
connect(ui->name, SIGNAL(currentDataChanged()), this, SLOT(onNameChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->value->setField(timer.val, this);
|
||||||
|
ui->value->setMaximumTime(firmware->getMaxTimerStart());
|
||||||
|
|
||||||
|
ui->mode->setModel(panelFilteredModels->getItemModel(FIM_TIMERSWITCH));
|
||||||
|
ui->mode->setField(timer.mode, this);
|
||||||
|
|
||||||
|
ui->countdownBeep->setModel(panelItemModels->getItemModel(AIM_TIMER_COUNTDOWNBEEP));
|
||||||
|
ui->countdownBeep->setField(timer.countdownBeep, this);
|
||||||
|
connect(ui->countdownBeep, SIGNAL(currentDataChanged(int)), this, SLOT(onCountdownBeepChanged(int)));
|
||||||
|
|
||||||
|
ui->minuteBeep->setField(timer.minuteBeep, this);
|
||||||
|
|
||||||
|
if (firmware->getCapability(PermTimers)) {
|
||||||
|
ui->persistent->setModel(panelItemModels->getItemModel(AIM_TIMER_PERSISTENT));
|
||||||
|
ui->persistent->setField(timer.persistent, this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui->name->setMaxLength(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode
|
|
||||||
ui->mode->setModel(rawSwitchFilteredModel);
|
|
||||||
ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
|
|
||||||
connect(ui->mode, SIGNAL(activated(int)), this, SLOT(onModeChanged(int)));
|
|
||||||
|
|
||||||
if (!firmware->getCapability(PermTimers)) {
|
|
||||||
ui->persistent->hide();
|
ui->persistent->hide();
|
||||||
ui->persistentValue->hide();
|
ui->persistentValue->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->countdownBeep->setField(timer.countdownBeep, this);
|
ui->countdownStart->setModel(panelItemModels->getItemModel(AIM_TIMER_COUNTDOWNSTART));
|
||||||
ui->countdownBeep->addItem(tr("Silent"), TimerData::COUNTDOWN_SILENT);
|
|
||||||
ui->countdownBeep->addItem(tr("Beeps"), TimerData::COUNTDOWN_BEEPS);
|
|
||||||
ui->countdownBeep->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE);
|
|
||||||
ui->countdownBeep->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC);
|
|
||||||
|
|
||||||
ui->value->setMaximumTime(firmware->getMaxTimerStart());
|
|
||||||
|
|
||||||
ui->persistent->setField(timer.persistent, this);
|
|
||||||
ui->persistent->addItem(tr("Not persistent"), 0);
|
|
||||||
ui->persistent->addItem(tr("Persistent (flight)"), 1);
|
|
||||||
ui->persistent->addItem(tr("Persistent (manual reset)"), 2);
|
|
||||||
|
|
||||||
ui->countdownStart->setField(timer.countdownStart, this);
|
ui->countdownStart->setField(timer.countdownStart, this);
|
||||||
ui->countdownStart->addItem("5s", 1);
|
|
||||||
ui->countdownStart->addItem("10s", 0);
|
|
||||||
ui->countdownStart->addItem("20s", -1);
|
|
||||||
ui->countdownStart->addItem("30s", -2);
|
|
||||||
|
|
||||||
disableMouseScrolling();
|
disableMouseScrolling();
|
||||||
QWidget::setTabOrder(prevFocus, ui->name);
|
QWidget::setTabOrder(prevFocus, ui->name);
|
||||||
|
@ -102,33 +100,27 @@ void TimerPanel::update()
|
||||||
{
|
{
|
||||||
lock = true;
|
lock = true;
|
||||||
|
|
||||||
ui->name->setText(timer.name);
|
ui->name->updateValue();
|
||||||
|
ui->mode->updateValue();
|
||||||
|
ui->value->updateValue();
|
||||||
|
ui->countdownBeep->updateValue();
|
||||||
|
ui->minuteBeep->updateValue();
|
||||||
|
ui->countdownStart->updateValue();
|
||||||
|
|
||||||
int hour = timer.val / 3600;
|
if (timer.countdownBeep == TimerData::COUNTDOWNBEEP_SILENT) {
|
||||||
int min = (timer.val - (hour * 3600)) / 60;
|
ui->countdownStartLabel->setEnabled(false);
|
||||||
int sec = (timer.val - (hour * 3600)) % 60;
|
ui->countdownStart->setEnabled(false);
|
||||||
|
}
|
||||||
ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
|
else {
|
||||||
ui->value->setTime(QTime(hour, min, sec));
|
ui->countdownStartLabel->setEnabled(true);
|
||||||
|
ui->countdownStart->setEnabled(true);
|
||||||
if (firmware->getCapability(PermTimers)) {
|
}
|
||||||
int sign = 1;
|
|
||||||
int pvalue = timer.pvalue;
|
if (firmware->getCapability(PermTimers)) {
|
||||||
if (pvalue < 0) {
|
ui->persistent->updateValue();
|
||||||
pvalue = -pvalue;
|
ui->persistentValue->setText(timer.pvalueToString());
|
||||||
sign = -1;
|
|
||||||
}
|
|
||||||
int hours = pvalue / 3600;
|
|
||||||
pvalue -= hours * 3600;
|
|
||||||
int minutes = pvalue / 60;
|
|
||||||
int seconds = pvalue % 60;
|
|
||||||
ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign < 0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->countdownBeep->updateValue();
|
|
||||||
ui->minuteBeep->setChecked(timer.minuteBeep);
|
|
||||||
ui->persistent->updateValue();
|
|
||||||
ui->countdownStart->updateValue();
|
|
||||||
lock = false;
|
lock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,57 +129,6 @@ QWidget * TimerPanel::getLastFocus()
|
||||||
return ui->persistent;
|
return ui->persistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerPanel::on_countdownBeep_currentIndexChanged(int index)
|
|
||||||
{
|
|
||||||
if(index == TimerData::COUNTDOWN_SILENT)
|
|
||||||
ui->countdownStart->hide();
|
|
||||||
else
|
|
||||||
ui->countdownStart->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerPanel::on_value_editingFinished()
|
|
||||||
{
|
|
||||||
if (!lock) {
|
|
||||||
unsigned val = ui->value->time().hour() * 3600 + ui->value->time().minute() * 60 + ui->value->time().second();
|
|
||||||
if (timer.val != val) {
|
|
||||||
timer.val = val;
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerPanel::onModeChanged(int index)
|
|
||||||
{
|
|
||||||
if (!lock) {
|
|
||||||
bool ok;
|
|
||||||
const RawSwitch rs(ui->mode->itemData(index).toInt(&ok));
|
|
||||||
if (ok && timer.mode.toValue() != rs.toValue()) {
|
|
||||||
timer.mode = rs;
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerPanel::on_minuteBeep_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (!lock) {
|
|
||||||
timer.minuteBeep = checked;
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerPanel::on_name_editingFinished()
|
|
||||||
{
|
|
||||||
if (!lock) {
|
|
||||||
if (QString(timer.name) != ui->name->text()) {
|
|
||||||
int length = ui->name->maxLength();
|
|
||||||
strncpy(timer.name, ui->name->text().toLatin1(), length);
|
|
||||||
emit nameChanged();
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
||||||
{
|
{
|
||||||
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TimerPanel::onItemModelAboutToBeUpdated);
|
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TimerPanel::onItemModelAboutToBeUpdated);
|
||||||
|
@ -197,12 +138,27 @@ void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
|
||||||
void TimerPanel::onItemModelAboutToBeUpdated()
|
void TimerPanel::onItemModelAboutToBeUpdated()
|
||||||
{
|
{
|
||||||
lock = true;
|
lock = true;
|
||||||
|
modelsUpdateCnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerPanel::onItemModelUpdateComplete()
|
void TimerPanel::onItemModelUpdateComplete()
|
||||||
{
|
{
|
||||||
|
modelsUpdateCnt--;
|
||||||
|
if (modelsUpdateCnt < 1) {
|
||||||
|
update();
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerPanel::onNameChanged()
|
||||||
|
{
|
||||||
|
emit nameChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerPanel::onCountdownBeepChanged(int index)
|
||||||
|
{
|
||||||
|
timer.countdownBeepChanged();
|
||||||
update();
|
update();
|
||||||
lock = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -710,6 +666,7 @@ void ModulePanel::onProtocolChanged(int index)
|
||||||
module.protocol = ui->protocol->itemData(index).toInt();
|
module.protocol = ui->protocol->itemData(index).toInt();
|
||||||
module.channelsCount = module.getMaxChannelCount();
|
module.channelsCount = module.getMaxChannelCount();
|
||||||
update();
|
update();
|
||||||
|
emit updateItemModels();
|
||||||
emit modified();
|
emit modified();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,6 +767,7 @@ void ModulePanel::onMultiProtocolChanged(int index)
|
||||||
module.subType = std::min(module.subType, maxSubTypes - 1);
|
module.subType = std::min(module.subType, maxSubTypes - 1);
|
||||||
module.channelsCount = module.getMaxChannelCount();
|
module.channelsCount = module.getMaxChannelCount();
|
||||||
update();
|
update();
|
||||||
|
emit updateItemModels();
|
||||||
emit modified();
|
emit modified();
|
||||||
lock = false;
|
lock = false;
|
||||||
}
|
}
|
||||||
|
@ -1035,16 +993,26 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::TimersContext);
|
lock = true;
|
||||||
connectItemModelEvents(rawSwitchFilteredModel);
|
|
||||||
|
|
||||||
thrSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource));
|
panelFilteredModels = new FilteredItemModelFactory();
|
||||||
connectItemModelEvents(thrSourceFilteredModel);
|
|
||||||
|
panelFilteredModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
|
||||||
|
RawSwitch::TimersContext),
|
||||||
|
FIM_TIMERSWITCH);
|
||||||
|
connectItemModelEvents(panelFilteredModels->getItemModel(FIM_TIMERSWITCH));
|
||||||
|
|
||||||
|
panelFilteredModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource)),
|
||||||
|
FIM_THRSOURCE);
|
||||||
|
connectItemModelEvents(panelFilteredModels->getItemModel(FIM_THRSOURCE));
|
||||||
|
|
||||||
|
panelItemModels = new CompoundItemModelFactory(&generalSettings, &model);
|
||||||
|
panelItemModels->registerItemModel(TimerData::countdownBeepItemModel());
|
||||||
|
panelItemModels->registerItemModel(TimerData::countdownStartItemModel());
|
||||||
|
panelItemModels->registerItemModel(TimerData::persistentItemModel());
|
||||||
|
|
||||||
Board::Type board = firmware->getBoard();
|
Board::Type board = firmware->getBoard();
|
||||||
|
|
||||||
lock = true;
|
|
||||||
|
|
||||||
memset(modules, 0, sizeof(modules));
|
memset(modules, 0, sizeof(modules));
|
||||||
|
|
||||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||||
|
@ -1124,7 +1092,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||||
|
|
||||||
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
|
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
|
||||||
if (i < timersCount) {
|
if (i < timersCount) {
|
||||||
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, rawSwitchFilteredModel);
|
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, panelFilteredModels, panelItemModels);
|
||||||
ui->gridLayout->addWidget(timers[i], 1+i, 1);
|
ui->gridLayout->addWidget(timers[i], 1+i, 1);
|
||||||
connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
|
connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
|
||||||
connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged);
|
connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged);
|
||||||
|
@ -1160,6 +1128,9 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||||
ui->toplcdTimer->hide();
|
ui->toplcdTimer->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui->throttleSource->setModel(panelFilteredModels->getItemModel(FIM_THRSOURCE));
|
||||||
|
ui->throttleSource->setField(model.thrTraceSrc, this);
|
||||||
|
|
||||||
if (!firmware->getCapability(HasDisplayText)) {
|
if (!firmware->getCapability(HasDisplayText)) {
|
||||||
ui->displayText->hide();
|
ui->displayText->hide();
|
||||||
ui->editText->hide();
|
ui->editText->hide();
|
||||||
|
@ -1265,6 +1236,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||||
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
|
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
|
||||||
ui->modulesLayout->addWidget(modules[i]);
|
ui->modulesLayout->addWidget(modules[i]);
|
||||||
connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
|
connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
|
||||||
|
connect(modules[i], &ModulePanel::updateItemModels, this, &SetupPanel::onModuleUpdateItemModels);
|
||||||
connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
|
connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,8 +1262,8 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||||
SetupPanel::~SetupPanel()
|
SetupPanel::~SetupPanel()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
delete rawSwitchFilteredModel;
|
delete panelFilteredModels;
|
||||||
delete thrSourceFilteredModel;
|
delete panelItemModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupPanel::on_extendedLimits_toggled(bool checked)
|
void SetupPanel::on_extendedLimits_toggled(bool checked)
|
||||||
|
@ -1325,14 +1297,6 @@ void SetupPanel::on_trimIncrement_currentIndexChanged(int index)
|
||||||
emit modified();
|
emit modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupPanel::on_throttleSource_currentIndexChanged(int index)
|
|
||||||
{
|
|
||||||
if (!lock) {
|
|
||||||
model->thrTraceSrc = ui->throttleSource->currentData().toUInt();
|
|
||||||
emit modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupPanel::on_throttleTrimSwitch_currentIndexChanged(int index)
|
void SetupPanel::on_throttleTrimSwitch_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (!lock) {
|
if (!lock) {
|
||||||
|
@ -1391,28 +1355,6 @@ void SetupPanel::on_image_currentIndexChanged(int index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupPanel::populateThrottleSourceCB()
|
|
||||||
{
|
|
||||||
Board::Type board = firmware->getBoard();
|
|
||||||
lock = true;
|
|
||||||
ui->throttleSource->clear();
|
|
||||||
ui->throttleSource->addItem(tr("THR"), 0);
|
|
||||||
|
|
||||||
int idx = 1;
|
|
||||||
for (int i = 0; i < getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); i++, idx++) {
|
|
||||||
if (RawSource(SOURCE_TYPE_STICK, 4 + i).isAvailable(model, &generalSettings, board)) {
|
|
||||||
ui->throttleSource->addItem(firmware->getAnalogInputName(4 + i), idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < firmware->getCapability(Outputs); i++, idx++) {
|
|
||||||
ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
int thrTraceSrcIdx = ui->throttleSource->findData(model->thrTraceSrc);
|
|
||||||
ui->throttleSource->setCurrentIndex(thrTraceSrcIdx);
|
|
||||||
lock = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupPanel::populateThrottleTrimSwitchCB()
|
void SetupPanel::populateThrottleTrimSwitchCB()
|
||||||
{
|
{
|
||||||
Board::Type board = firmware->getBoard();
|
Board::Type board = firmware->getBoard();
|
||||||
|
@ -1440,7 +1382,7 @@ void SetupPanel::update()
|
||||||
{
|
{
|
||||||
ui->name->setText(model->name);
|
ui->name->setText(model->name);
|
||||||
ui->throttleReverse->setChecked(model->throttleReversed);
|
ui->throttleReverse->setChecked(model->throttleReversed);
|
||||||
populateThrottleSourceCB();
|
ui->throttleSource->updateValue();
|
||||||
populateThrottleTrimSwitchCB();
|
populateThrottleTrimSwitchCB();
|
||||||
ui->throttleWarning->setChecked(!model->disableThrottleWarning);
|
ui->throttleWarning->setChecked(!model->disableThrottleWarning);
|
||||||
ui->trimIncrement->setCurrentIndex(model->trimInc+2);
|
ui->trimIncrement->setCurrentIndex(model->trimInc+2);
|
||||||
|
@ -1811,4 +1753,10 @@ void SetupPanel::onItemModelUpdateComplete()
|
||||||
void SetupPanel::updateItemModels()
|
void SetupPanel::updateItemModels()
|
||||||
{
|
{
|
||||||
sharedItemModels->update(AbstractItemModel::IMUE_Timers);
|
sharedItemModels->update(AbstractItemModel::IMUE_Timers);
|
||||||
|
emit updated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupPanel::onModuleUpdateItemModels()
|
||||||
|
{
|
||||||
|
sharedItemModels->update(AbstractItemModel::IMUE_Modules);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,15 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SETUP_H_
|
#pragma once
|
||||||
#define _SETUP_H_
|
|
||||||
|
|
||||||
#include "modeledit.h"
|
#include "modeledit.h"
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
|
#include "compounditemmodels.h"
|
||||||
|
#include "filtereditemmodels.h"
|
||||||
|
|
||||||
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
|
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
|
||||||
|
|
||||||
class CompoundItemModelFactory;
|
|
||||||
class FilteredItemModel;
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Setup;
|
class Setup;
|
||||||
class Timer;
|
class Timer;
|
||||||
|
@ -40,21 +38,18 @@ class TimerPanel : public ModelPanel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
|
TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
|
||||||
QWidget *prevFocus, FilteredItemModel * switchModel);
|
QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels);
|
||||||
virtual ~TimerPanel();
|
virtual ~TimerPanel();
|
||||||
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
QWidget * getLastFocus();
|
QWidget * getLastFocus();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onModeChanged(int index);
|
void onNameChanged();
|
||||||
void on_value_editingFinished();
|
|
||||||
void on_minuteBeep_toggled(bool checked);
|
|
||||||
void on_countdownBeep_currentIndexChanged(int index);
|
|
||||||
void on_name_editingFinished();
|
|
||||||
void onItemModelAboutToBeUpdated();
|
void onItemModelAboutToBeUpdated();
|
||||||
void onItemModelUpdateComplete();
|
void onItemModelUpdateComplete();
|
||||||
|
void onCountdownBeepChanged(int index);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
|
@ -63,6 +58,7 @@ class TimerPanel : public ModelPanel
|
||||||
TimerData & timer;
|
TimerData & timer;
|
||||||
Ui::Timer * ui;
|
Ui::Timer * ui;
|
||||||
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
||||||
|
int modelsUpdateCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModulePanel : public ModelPanel
|
class ModulePanel : public ModelPanel
|
||||||
|
@ -81,6 +77,7 @@ class ModulePanel : public ModelPanel
|
||||||
signals:
|
signals:
|
||||||
void channelsRangeChanged();
|
void channelsRangeChanged();
|
||||||
void failsafeModified(unsigned index);
|
void failsafeModified(unsigned index);
|
||||||
|
void updateItemModels();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setupFailsafes();
|
void setupFailsafes();
|
||||||
|
@ -146,7 +143,6 @@ class SetupPanel : public ModelPanel
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_name_editingFinished();
|
void on_name_editingFinished();
|
||||||
void on_throttleSource_currentIndexChanged(int index);
|
|
||||||
void on_throttleTrimSwitch_currentIndexChanged(int index);
|
void on_throttleTrimSwitch_currentIndexChanged(int index);
|
||||||
void on_throttleTrim_toggled(bool checked);
|
void on_throttleTrim_toggled(bool checked);
|
||||||
void on_extendedLimits_toggled(bool checked);
|
void on_extendedLimits_toggled(bool checked);
|
||||||
|
@ -176,6 +172,7 @@ class SetupPanel : public ModelPanel
|
||||||
void onTimerNameChanged();
|
void onTimerNameChanged();
|
||||||
void onItemModelAboutToBeUpdated();
|
void onItemModelAboutToBeUpdated();
|
||||||
void onItemModelUpdateComplete();
|
void onItemModelUpdateComplete();
|
||||||
|
void onModuleUpdateItemModels();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Setup *ui;
|
Ui::Setup *ui;
|
||||||
|
@ -183,12 +180,11 @@ class SetupPanel : public ModelPanel
|
||||||
QVector<QCheckBox *> startupSwitchesCheckboxes;
|
QVector<QCheckBox *> startupSwitchesCheckboxes;
|
||||||
QVector<QCheckBox *> potWarningCheckboxes;
|
QVector<QCheckBox *> potWarningCheckboxes;
|
||||||
QVector<QCheckBox *> centerBeepCheckboxes;
|
QVector<QCheckBox *> centerBeepCheckboxes;
|
||||||
ModulePanel * modules[CPN_MAX_MODULES+1];
|
ModulePanel * modules[CPN_MAX_MODULES + 1];
|
||||||
TimerPanel * timers[CPN_MAX_TIMERS];
|
TimerPanel * timers[CPN_MAX_TIMERS];
|
||||||
void updateStartupSwitches();
|
void updateStartupSwitches();
|
||||||
void updatePotWarnings();
|
void updatePotWarnings();
|
||||||
void updateBeepCenter();
|
void updateBeepCenter();
|
||||||
void populateThrottleSourceCB();
|
|
||||||
void populateThrottleTrimSwitchCB();
|
void populateThrottleTrimSwitchCB();
|
||||||
int timersCount;
|
int timersCount;
|
||||||
int selectedTimerIndex;
|
int selectedTimerIndex;
|
||||||
|
@ -198,10 +194,8 @@ class SetupPanel : public ModelPanel
|
||||||
bool moveTimerUpAllowed() const;
|
bool moveTimerUpAllowed() const;
|
||||||
void swapTimerData(int idx1, int idx2);
|
void swapTimerData(int idx1, int idx2);
|
||||||
CompoundItemModelFactory * sharedItemModels;
|
CompoundItemModelFactory * sharedItemModels;
|
||||||
FilteredItemModel * rawSwitchFilteredModel;
|
|
||||||
FilteredItemModel * thrSourceFilteredModel;
|
|
||||||
void updateItemModels();
|
void updateItemModels();
|
||||||
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
||||||
|
CompoundItemModelFactory * panelItemModels;
|
||||||
|
FilteredItemModelFactory * panelFilteredModels;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _SETUP_H_
|
|
||||||
|
|
|
@ -604,7 +604,7 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QComboBox" name="throttleSource">
|
<widget class="AutoComboBox" name="throttleSource">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>675</width>
|
<width>874</width>
|
||||||
<height>33</height>
|
<height>33</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="name">
|
<widget class="AutoLineEdit" name="name">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>80</width>
|
<width>80</width>
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTimeEdit" name="value">
|
<widget class="AutoTimeEdit" name="value">
|
||||||
<property name="accelerated">
|
<property name="accelerated">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="mode"/>
|
<widget class="AutoComboBox" name="mode"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="countdownBeepLabel">
|
<widget class="QLabel" name="countdownBeepLabel">
|
||||||
|
@ -68,11 +68,18 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="AutoComboBox" name="countdownBeep"/>
|
<widget class="AutoComboBox" name="countdownBeep"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="countdownStartLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Start</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="AutoComboBox" name="countdownStart"/>
|
<widget class="AutoComboBox" name="countdownStart"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="minuteBeep">
|
<widget class="AutoCheckBox" name="minuteBeep">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Minute Call</string>
|
<string>Minute Call</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -109,6 +116,21 @@
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>autocombobox.h</header>
|
<header>autocombobox.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AutoLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>autolineedit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AutoCheckBox</class>
|
||||||
|
<extends>QCheckBox</extends>
|
||||||
|
<header>autocheckbox.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AutoTimeEdit</class>
|
||||||
|
<extends>QTimeEdit</extends>
|
||||||
|
<header>autotimeedit.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -35,6 +35,7 @@ constexpr char FIM_SENSORFORMULA[] {"Sensor.Formula"};
|
||||||
constexpr char FIM_SENSORCELLINDEX[] {"Sensor.CellIndex"};
|
constexpr char FIM_SENSORCELLINDEX[] {"Sensor.CellIndex"};
|
||||||
constexpr char FIM_SENSORUNIT[] {"Sensor.Unit"};
|
constexpr char FIM_SENSORUNIT[] {"Sensor.Unit"};
|
||||||
constexpr char FIM_SENSORPRECISION[] {"Sensor.Precision"};
|
constexpr char FIM_SENSORPRECISION[] {"Sensor.Precision"};
|
||||||
|
constexpr char FIM_RSSISOURCE[] {"Rssi Source"};
|
||||||
|
|
||||||
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings,
|
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings,
|
||||||
Firmware * firmware, const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels):
|
Firmware * firmware, const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels):
|
||||||
|
@ -111,7 +112,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model,
|
||||||
lock = false;
|
lock = false;
|
||||||
|
|
||||||
if (IS_TARANIS(firmware->getBoard())) {
|
if (IS_TARANIS(firmware->getBoard())) {
|
||||||
QSet<QString> scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/TELEMETRY", QStringList() << "*.lua", 8);
|
QSet<QString> scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/TELEMETRY", QStringList() << "*.lua", 6);
|
||||||
Helpers::populateFileComboBox(ui->scriptName, scriptsSet, screen.body.script.filename);
|
Helpers::populateFileComboBox(ui->scriptName, scriptsSet, screen.body.script.filename);
|
||||||
connect(ui->scriptName, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptNameEdited()));
|
connect(ui->scriptName, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptNameEdited()));
|
||||||
connect(ui->scriptName, SIGNAL(editTextChanged ( const QString)), this, SLOT(scriptNameEdited()));
|
connect(ui->scriptName, SIGNAL(editTextChanged ( const QString)), this, SLOT(scriptNameEdited()));
|
||||||
|
@ -696,6 +697,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
|
||||||
FIM_TELEPOSSRC);
|
FIM_TELEPOSSRC);
|
||||||
connectItemModelEvents(id);
|
connectItemModelEvents(id);
|
||||||
|
|
||||||
|
|
||||||
|
id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RssiSource)),
|
||||||
|
FIM_RSSISOURCE);
|
||||||
|
connectItemModelEvents(id);
|
||||||
|
|
||||||
id = panelItemModels->registerItemModel(SensorData::typeItemModel());
|
id = panelItemModels->registerItemModel(SensorData::typeItemModel());
|
||||||
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORTYPE);
|
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORTYPE);
|
||||||
|
|
||||||
|
@ -813,12 +819,14 @@ void TelemetryPanel::setup()
|
||||||
ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this);
|
ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this);
|
||||||
ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled);
|
ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled);
|
||||||
|
|
||||||
|
ui->rssiAlarmWarningSB->setRange(45 - 30, 45 + 30);
|
||||||
ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning);
|
ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning);
|
||||||
|
ui->rssiAlarmCriticalSB->setRange(42 - 30, 42 + 30);
|
||||||
ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical);
|
ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical);
|
||||||
|
|
||||||
ui->rssiSourceLabel->show();
|
ui->rssiSourceLabel->show();
|
||||||
ui->rssiSourceLabel->setText(tr("Source"));
|
ui->rssiSourceLabel->setText(tr("Source"));
|
||||||
ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
|
ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_RSSISOURCE));
|
||||||
ui->rssiSourceCB->setField(model->rssiSource, this);
|
ui->rssiSourceCB->setField(model->rssiSource, this);
|
||||||
ui->rssiSourceCB->show();
|
ui->rssiSourceCB->show();
|
||||||
|
|
||||||
|
|
|
@ -298,27 +298,6 @@ QString ModelPrinter::printCenterBeep()
|
||||||
return (strl.isEmpty() ? tr("None") : strl.join(" "));
|
return (strl.isEmpty() ? tr("None") : strl.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ModelPrinter::printTimer(int idx)
|
|
||||||
{
|
|
||||||
return printTimer(model.timers[idx]);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTimer(const TimerData & timer)
|
|
||||||
{
|
|
||||||
QStringList result;
|
|
||||||
if (firmware->getCapability(TimersName) && timer.name[0])
|
|
||||||
result += tr("Name") + QString("(%1)").arg(timer.name);
|
|
||||||
result += printTimeValue(timer.val, MASK_TIMEVALUE_HRSMINS | MASK_TIMEVALUE_ZEROHRS);
|
|
||||||
result += timer.mode.toString();
|
|
||||||
if (timer.countdownBeep)
|
|
||||||
result += tr("Countdown") + QString("(%1)").arg(printTimerCountdownBeep(timer.countdownBeep));
|
|
||||||
if (timer.minuteBeep)
|
|
||||||
result += tr("Minute call");
|
|
||||||
if (timer.persistent)
|
|
||||||
result += tr("Persistent") + QString("(%1)").arg(printTimerPersistent(timer.persistent));
|
|
||||||
return result.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTrim(int flightModeIndex, int stickIndex)
|
QString ModelPrinter::printTrim(int flightModeIndex, int stickIndex)
|
||||||
{
|
{
|
||||||
const FlightModeData & fm = model.flightModeData[flightModeIndex];
|
const FlightModeData & fm = model.flightModeData[flightModeIndex];
|
||||||
|
@ -938,36 +917,6 @@ QString ModelPrinter::printFailsafeMode(unsigned int fsmode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ModelPrinter::printTimerCountdownBeep(unsigned int countdownBeep)
|
|
||||||
{
|
|
||||||
switch (countdownBeep) {
|
|
||||||
case TimerData::COUNTDOWN_SILENT:
|
|
||||||
return tr("Silent");
|
|
||||||
case TimerData::COUNTDOWN_BEEPS:
|
|
||||||
return tr("Beeps");
|
|
||||||
case TimerData::COUNTDOWN_VOICE:
|
|
||||||
return tr("Voice");
|
|
||||||
case TimerData::COUNTDOWN_HAPTIC:
|
|
||||||
return tr("Haptic");
|
|
||||||
default:
|
|
||||||
return CPN_STR_UNKNOWN_ITEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTimerPersistent(unsigned int persistent)
|
|
||||||
{
|
|
||||||
switch (persistent) {
|
|
||||||
case 0:
|
|
||||||
return tr("OFF");
|
|
||||||
case 1:
|
|
||||||
return tr("Flight");
|
|
||||||
case 2:
|
|
||||||
return tr("Manual reset");
|
|
||||||
default:
|
|
||||||
return CPN_STR_UNKNOWN_ITEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printSettingsTrim()
|
QString ModelPrinter::printSettingsTrim()
|
||||||
{
|
{
|
||||||
QStringList str;
|
QStringList str;
|
||||||
|
@ -1032,26 +981,6 @@ QString ModelPrinter::printPPMFrameLength(int ppmFL)
|
||||||
return QString::number(result);
|
return QString::number(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ModelPrinter::printTimerName(int idx)
|
|
||||||
{
|
|
||||||
QString result;
|
|
||||||
result = tr("Tmr") + QString("%1").arg(idx+1);
|
|
||||||
if (firmware->getCapability(TimersName) && model.timers[idx].name[0])
|
|
||||||
result.append(":" + QString(model.timers[idx].name));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTimerTimeValue(unsigned int val)
|
|
||||||
{
|
|
||||||
return printTimeValue(val, MASK_TIMEVALUE_HRSMINS | MASK_TIMEVALUE_ZEROHRS);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTimerMinuteBeep(bool mb)
|
|
||||||
{
|
|
||||||
return printBoolean(mb, BOOLEAN_YESNO);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ModelPrinter::printTelemetryProtocol(unsigned int val)
|
QString ModelPrinter::printTelemetryProtocol(unsigned int val)
|
||||||
{
|
{
|
||||||
switch (val) {
|
switch (val) {
|
||||||
|
|
|
@ -67,8 +67,6 @@ class ModelPrinter: public QObject
|
||||||
QString printTrim(int flightModeIndex, int stickIndex);
|
QString printTrim(int flightModeIndex, int stickIndex);
|
||||||
QString printGlobalVar(int flightModeIndex, int gvarIndex);
|
QString printGlobalVar(int flightModeIndex, int gvarIndex);
|
||||||
QString printRotaryEncoder(int flightModeIndex, int reIndex);
|
QString printRotaryEncoder(int flightModeIndex, int reIndex);
|
||||||
QString printTimer(int idx);
|
|
||||||
QString printTimer(const TimerData & timer);
|
|
||||||
QString printInputName(int idx);
|
QString printInputName(int idx);
|
||||||
QString printInputLine(int idx);
|
QString printInputLine(int idx);
|
||||||
QString printInputLine(const ExpoData & ed);
|
QString printInputLine(const ExpoData & ed);
|
||||||
|
@ -104,13 +102,8 @@ class ModelPrinter: public QObject
|
||||||
QString printFailsafe(int idx);
|
QString printFailsafe(int idx);
|
||||||
QString printFailsafeMode(unsigned int fsmode);
|
QString printFailsafeMode(unsigned int fsmode);
|
||||||
QString printFailsafeValue(int val);
|
QString printFailsafeValue(int val);
|
||||||
QString printTimerCountdownBeep(unsigned int countdownBeep);
|
|
||||||
QString printTimerPersistent(unsigned int persistent);
|
|
||||||
QString printPPMFrameLength(int ppmFL);
|
QString printPPMFrameLength(int ppmFL);
|
||||||
QString printTimerName(int idx);
|
|
||||||
QString printTimeValue(const int value, const unsigned int mask);
|
QString printTimeValue(const int value, const unsigned int mask);
|
||||||
QString printTimerMinuteBeep(bool mb);
|
|
||||||
QString printTimerTimeValue(unsigned int val);
|
|
||||||
QString printTelemetryProtocol(unsigned int val);
|
QString printTelemetryProtocol(unsigned int val);
|
||||||
QString printLabelValue(const QString & lbl, const QString & val, const bool sep = false);
|
QString printLabelValue(const QString & lbl, const QString & val, const bool sep = false);
|
||||||
QString printLabelValues(const QString & lbl, const QStringList & vals, const bool sep = false);
|
QString printLabelValues(const QString & lbl, const QStringList & vals, const bool sep = false);
|
||||||
|
|
|
@ -334,18 +334,19 @@ QString MultiModelPrinter::printTimers()
|
||||||
QString str;
|
QString str;
|
||||||
MultiColumns columns(modelPrinterMap.size());
|
MultiColumns columns(modelPrinterMap.size());
|
||||||
columns.appendSectionTableStart();
|
columns.appendSectionTableStart();
|
||||||
columns.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Min.call") << tr("Persist"));
|
columns.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Start") << tr("Min.call") << tr("Persist"));
|
||||||
|
|
||||||
for (int i=0; i<firmware->getCapability(Timers); i++) {
|
for (int i=0; i<firmware->getCapability(Timers); i++) {
|
||||||
columns.appendRowStart();
|
columns.appendRowStart();
|
||||||
columns.appendCellStart(20, true);
|
columns.appendCellStart(20, true);
|
||||||
COMPARE(modelPrinter->printTimerName(i));
|
COMPARE(model->timers[i].nameToString(i));
|
||||||
columns.appendCellEnd(true);
|
columns.appendCellEnd(true);
|
||||||
COMPARECELLWIDTH(modelPrinter->printTimerTimeValue(model->timers[i].val), 15);
|
COMPARECELLWIDTH(model->timers[i].valToString(), 10);
|
||||||
COMPARECELLWIDTH(model->timers[i].mode.toString(), 15);
|
COMPARECELLWIDTH(model->timers[i].mode.toString(), 10);
|
||||||
COMPARECELLWIDTH(modelPrinter->printTimerCountdownBeep(model->timers[i].countdownBeep), 15);
|
COMPARECELLWIDTH(model->timers[i].countdownBeepToString(), 10);
|
||||||
COMPARECELLWIDTH(modelPrinter->printTimerMinuteBeep(model->timers[i].minuteBeep), 15);
|
COMPARECELLWIDTH(model->timers[i].countdownStartToString(), 10);
|
||||||
COMPARECELLWIDTH(modelPrinter->printTimerPersistent(model->timers[i].persistent), 20);
|
COMPARECELLWIDTH(DataHelpers::boolToString(model->timers[i].minuteBeep, DataHelpers::BOOL_FMT_YESNO), 10);
|
||||||
|
COMPARECELLWIDTH(model->timers[i].persistentToString(false), 15);
|
||||||
columns.appendRowEnd();
|
columns.appendRowEnd();
|
||||||
}
|
}
|
||||||
columns.appendTableEnd();
|
columns.appendTableEnd();
|
||||||
|
|
|
@ -16,6 +16,7 @@ set(shared_HDRS
|
||||||
genericpanel.h
|
genericpanel.h
|
||||||
hexspinbox.h
|
hexspinbox.h
|
||||||
autoprecisioncombobox.h
|
autoprecisioncombobox.h
|
||||||
|
autotimeedit.h
|
||||||
)
|
)
|
||||||
|
|
||||||
qt5_wrap_cpp(shared_SRCS ${shared_HDRS})
|
qt5_wrap_cpp(shared_SRCS ${shared_HDRS})
|
||||||
|
|
|
@ -34,7 +34,8 @@ class AutoBitsetCheckBox: public QCheckBox
|
||||||
Q_PROPERTY(int toggleMask READ toggleMask WRITE setToggleMask)
|
Q_PROPERTY(int toggleMask READ toggleMask WRITE setToggleMask)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoBitsetCheckBox(QWidget *parent = nullptr) : AutoBitsetCheckBox(QString(), parent) {}
|
explicit AutoBitsetCheckBox(QWidget *parent = nullptr) :
|
||||||
|
AutoBitsetCheckBox(QString(), parent) {}
|
||||||
explicit AutoBitsetCheckBox(const QString &text, QWidget *parent = nullptr) :
|
explicit AutoBitsetCheckBox(const QString &text, QWidget *parent = nullptr) :
|
||||||
QCheckBox(text, parent)
|
QCheckBox(text, parent)
|
||||||
{
|
{
|
||||||
|
@ -42,26 +43,32 @@ class AutoBitsetCheckBox: public QCheckBox
|
||||||
}
|
}
|
||||||
|
|
||||||
// int field constructors
|
// int field constructors
|
||||||
explicit AutoBitsetCheckBox(int & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : AutoBitsetCheckBox(field, bitmask, false, text, parent) {}
|
explicit AutoBitsetCheckBox(int & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
explicit AutoBitsetCheckBox(int & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent)
|
AutoBitsetCheckBox(field, bitmask, false, text, parent) {}
|
||||||
|
explicit AutoBitsetCheckBox(int & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
|
QCheckBox(text, parent)
|
||||||
{
|
{
|
||||||
setField(field, bitmask, invert);
|
setField(field, bitmask, invert);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
explicit AutoBitsetCheckBox(int & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent)
|
explicit AutoBitsetCheckBox(int & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
|
QCheckBox(text, parent)
|
||||||
{
|
{
|
||||||
setField(field, bitmask, false, toggleMask);
|
setField(field, bitmask, false, toggleMask);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsigned field constructors
|
// unsigned field constructors
|
||||||
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : AutoBitsetCheckBox(field, bitmask, false, text, parent) {}
|
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent)
|
AutoBitsetCheckBox(field, bitmask, false, text, parent) {}
|
||||||
|
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
|
QCheckBox(text, parent)
|
||||||
{
|
{
|
||||||
setField(field, bitmask, invert);
|
setField(field, bitmask, invert);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent)
|
explicit AutoBitsetCheckBox(unsigned & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) :
|
||||||
|
QCheckBox(text, parent)
|
||||||
{
|
{
|
||||||
setField(field, bitmask, false, toggleMask);
|
setField(field, bitmask, false, toggleMask);
|
||||||
init();
|
init();
|
||||||
|
@ -104,6 +111,8 @@ class AutoBitsetCheckBox: public QCheckBox
|
||||||
|
|
||||||
void updateValue()
|
void updateValue()
|
||||||
{
|
{
|
||||||
|
if (m_panel && m_panel->lock)
|
||||||
|
return;
|
||||||
if (!m_field)
|
if (!m_field)
|
||||||
return;
|
return;
|
||||||
const bool oldLock = setLocked(true);
|
const bool oldLock = setLocked(true);
|
||||||
|
|
|
@ -21,23 +21,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include "modeledit/modeledit.h"
|
#include "genericpanel.h"
|
||||||
|
|
||||||
class AutoCheckBox: public QCheckBox
|
class AutoCheckBox: public QCheckBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoCheckBox(QWidget *parent = 0):
|
explicit AutoCheckBox(QWidget * parent = nullptr):
|
||||||
QCheckBox(parent),
|
QCheckBox(parent),
|
||||||
field(NULL),
|
field(nullptr),
|
||||||
panel(NULL),
|
panel(nullptr),
|
||||||
lock(false)
|
lock(false)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)));
|
connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(bool & field, ModelPanel * panel=NULL)
|
void setField(bool & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = &field;
|
this->field = &field;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
|
@ -51,26 +51,31 @@ class AutoCheckBox: public QCheckBox
|
||||||
|
|
||||||
void updateValue()
|
void updateValue()
|
||||||
{
|
{
|
||||||
lock = true;
|
|
||||||
if (field) {
|
if (field) {
|
||||||
|
lock = true;
|
||||||
setChecked(*field);
|
setChecked(*field);
|
||||||
|
lock = false;
|
||||||
}
|
}
|
||||||
lock = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentDataChanged(bool value);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onToggled(bool checked)
|
void onToggled(bool checked)
|
||||||
{
|
{
|
||||||
|
if (panel && panel->lock)
|
||||||
|
return;
|
||||||
if (field && !lock) {
|
if (field && !lock) {
|
||||||
*field = checked;
|
*field = checked;
|
||||||
if (panel) {
|
emit currentDataChanged(checked);
|
||||||
|
if (panel)
|
||||||
emit panel->modified();
|
emit panel->modified();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool * field;
|
bool *field = nullptr;
|
||||||
ModelPanel * panel;
|
GenericPanel *panel = nullptr;
|
||||||
bool lock;
|
bool lock = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,14 +22,23 @@
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "genericpanel.h"
|
#include "genericpanel.h"
|
||||||
|
#include "rawsource.h"
|
||||||
|
#include "rawswitch.h"
|
||||||
|
|
||||||
class AutoComboBox: public QComboBox
|
class AutoComboBox: public QComboBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoComboBox(QWidget *parent = nullptr):
|
explicit AutoComboBox(QWidget * parent = nullptr):
|
||||||
QComboBox(parent)
|
QComboBox(parent),
|
||||||
|
field(nullptr),
|
||||||
|
panel(nullptr),
|
||||||
|
next(0),
|
||||||
|
lock(false),
|
||||||
|
hasModel(false),
|
||||||
|
rawSource(nullptr),
|
||||||
|
rawSwitch(nullptr)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
|
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
|
||||||
}
|
}
|
||||||
|
@ -69,16 +78,38 @@ class AutoComboBox: public QComboBox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(unsigned int & field, GenericPanel * panel=nullptr)
|
void setField(unsigned int & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = (int *)&field;
|
this->field = (int *)&field;
|
||||||
|
this->rawSource = nullptr;
|
||||||
|
this->rawSwitch = nullptr;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
updateValue();
|
updateValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(int & field, GenericPanel * panel=nullptr)
|
void setField(int & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = &field;
|
this->field = &field;
|
||||||
|
this->rawSource = nullptr;
|
||||||
|
this->rawSwitch = nullptr;
|
||||||
|
this->panel = panel;
|
||||||
|
updateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setField(RawSource & field, GenericPanel * panel = nullptr)
|
||||||
|
{
|
||||||
|
this->rawSource = &field;
|
||||||
|
this->rawSwitch = nullptr;
|
||||||
|
this->field = nullptr;
|
||||||
|
this->panel = panel;
|
||||||
|
updateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setField(RawSwitch & field, GenericPanel * panel = nullptr)
|
||||||
|
{
|
||||||
|
this->rawSwitch = &field;
|
||||||
|
this->rawSource = nullptr;
|
||||||
|
this->field = nullptr;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
updateValue();
|
updateValue();
|
||||||
}
|
}
|
||||||
|
@ -103,10 +134,18 @@ class AutoComboBox: public QComboBox
|
||||||
|
|
||||||
void updateValue()
|
void updateValue()
|
||||||
{
|
{
|
||||||
if (!field)
|
if (!field && !rawSource && !rawSwitch)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock = true;
|
lock = true;
|
||||||
setCurrentIndex(findData(*field));
|
|
||||||
|
if (field)
|
||||||
|
setCurrentIndex(findData(*field));
|
||||||
|
else if (rawSource)
|
||||||
|
setCurrentIndex(findData(rawSource->toValue()));
|
||||||
|
else if (rawSwitch)
|
||||||
|
setCurrentIndex(findData(rawSwitch->toValue()));
|
||||||
|
|
||||||
lock = false;
|
lock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,21 +157,37 @@ class AutoComboBox: public QComboBox
|
||||||
{
|
{
|
||||||
if (panel && panel->lock)
|
if (panel && panel->lock)
|
||||||
return;
|
return;
|
||||||
if (index > -1) {
|
if (lock || index < 0)
|
||||||
const int val = itemData(index).toInt();
|
return;
|
||||||
if (field && !lock) {
|
|
||||||
*field = val;
|
bool ok;
|
||||||
if (panel)
|
const int val = itemData(index).toInt(&ok);
|
||||||
emit panel->modified();
|
if (!ok)
|
||||||
}
|
return;
|
||||||
emit currentDataChanged(val);
|
|
||||||
|
if (field && *field != val) {
|
||||||
|
*field = val;
|
||||||
}
|
}
|
||||||
|
else if (rawSource && rawSource->toValue() != val) {
|
||||||
|
*rawSource = RawSource(val);
|
||||||
|
}
|
||||||
|
else if (rawSwitch && rawSwitch->toValue() != val) {
|
||||||
|
*rawSwitch = RawSwitch(val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit currentDataChanged(val);
|
||||||
|
if (panel)
|
||||||
|
emit panel->modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int * field = nullptr;
|
int *field = nullptr;
|
||||||
GenericPanel * panel = nullptr;
|
GenericPanel *panel = nullptr;
|
||||||
int next = 0;
|
int next = 0;
|
||||||
bool lock = false;
|
bool lock = false;
|
||||||
bool hasModel = false;
|
bool hasModel = false;
|
||||||
|
RawSource *rawSource = nullptr;
|
||||||
|
RawSwitch *rawSwitch = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include "modeledit/modeledit.h"
|
#include "genericpanel.h"
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,23 +31,23 @@ class AutoDoubleSpinBox: public QDoubleSpinBox
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoDoubleSpinBox(QWidget *parent = 0):
|
explicit AutoDoubleSpinBox(QWidget * parent = nullptr):
|
||||||
QDoubleSpinBox(parent),
|
QDoubleSpinBox(parent),
|
||||||
field(NULL),
|
field(nullptr),
|
||||||
panel(NULL),
|
panel(nullptr),
|
||||||
lock(false)
|
lock(false)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
|
connect(this, SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(int & field, ModelPanel * panel=NULL)
|
void setField(int & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = &field;
|
this->field = &field;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
updateValue();
|
updateValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(unsigned int & field, ModelPanel * panel=NULL)
|
void setField(unsigned int & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = (int *)&field;
|
this->field = (int *)&field;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
|
@ -57,7 +57,9 @@ class AutoDoubleSpinBox: public QDoubleSpinBox
|
||||||
void updateValue()
|
void updateValue()
|
||||||
{
|
{
|
||||||
if (field) {
|
if (field) {
|
||||||
setValue(float(*field)/multiplier());
|
lock = true;
|
||||||
|
setValue(float(*field) / multiplier());
|
||||||
|
lock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +82,17 @@ class AutoDoubleSpinBox: public QDoubleSpinBox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentDataChanged(double value);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onValueChanged(double value)
|
void onValueChanged(double value)
|
||||||
{
|
{
|
||||||
|
if (panel && panel->lock)
|
||||||
|
return;
|
||||||
if (field && !lock) {
|
if (field && !lock) {
|
||||||
*field = round(value * multiplier());
|
*field = round(value * multiplier());
|
||||||
|
emit currentDataChanged(value);
|
||||||
if (panel) {
|
if (panel) {
|
||||||
emit panel->modified();
|
emit panel->modified();
|
||||||
}
|
}
|
||||||
|
@ -92,7 +100,7 @@ class AutoDoubleSpinBox: public QDoubleSpinBox
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int * field;
|
int * field = nullptr;
|
||||||
ModelPanel * panel;
|
GenericPanel * panel = nullptr;
|
||||||
bool lock;
|
bool lock = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,23 +21,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "hexspinbox.h"
|
#include "hexspinbox.h"
|
||||||
#include "modeledit/modeledit.h"
|
#include "genericpanel.h"
|
||||||
|
|
||||||
class AutoHexSpinBox: public HexSpinBox
|
class AutoHexSpinBox: public HexSpinBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoHexSpinBox(QWidget *parent = 0):
|
explicit AutoHexSpinBox(QWidget * parent = nullptr):
|
||||||
HexSpinBox(parent),
|
HexSpinBox(parent),
|
||||||
field(NULL),
|
field(nullptr),
|
||||||
panel(NULL),
|
panel(nullptr),
|
||||||
lock(false)
|
lock(false)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
|
connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setField(unsigned int & field, ModelPanel * panel=NULL)
|
void setField(unsigned int & field, GenericPanel * panel = nullptr)
|
||||||
{
|
{
|
||||||
this->field = &field;
|
this->field = &field;
|
||||||
this->panel = panel;
|
this->panel = panel;
|
||||||
|
@ -47,15 +47,23 @@ class AutoHexSpinBox: public HexSpinBox
|
||||||
void updateValue()
|
void updateValue()
|
||||||
{
|
{
|
||||||
if (field) {
|
if (field) {
|
||||||
|
lock = true;
|
||||||
setValue(*field);
|
setValue(*field);
|
||||||
|
lock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentDataChanged(int value);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onValueChanged(int value)
|
void onValueChanged(int value)
|
||||||
{
|
{
|
||||||
|
if (panel && panel->lock)
|
||||||
|
return;
|
||||||
if (field && !lock) {
|
if (field && !lock) {
|
||||||
*field = value;
|
*field = value;
|
||||||
|
emit currentDataChanged(value);
|
||||||
if (panel) {
|
if (panel) {
|
||||||
emit panel->modified();
|
emit panel->modified();
|
||||||
}
|
}
|
||||||
|
@ -63,7 +71,7 @@ class AutoHexSpinBox: public HexSpinBox
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int * field;
|
unsigned int * field = nullptr;
|
||||||
ModelPanel * panel;
|
GenericPanel * panel = nullptr;
|
||||||
bool lock;
|
bool lock = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,11 +29,11 @@ class AutoLineEdit: public QLineEdit
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoLineEdit(QWidget *parent = nullptr, bool updateOnChange = false):
|
explicit AutoLineEdit(QWidget * parent = nullptr, bool updateOnChange = false):
|
||||||
QLineEdit(parent),
|
QLineEdit(parent),
|
||||||
field(NULL),
|
field(NULL),
|
||||||
strField(NULL),
|
strField(nullptr),
|
||||||
panel(NULL),
|
panel(nullptr),
|
||||||
lock(false)
|
lock(false)
|
||||||
{
|
{
|
||||||
if (updateOnChange)
|
if (updateOnChange)
|
||||||
|
@ -76,7 +76,9 @@ class AutoLineEdit: public QLineEdit
|
||||||
protected slots:
|
protected slots:
|
||||||
void onEdited()
|
void onEdited()
|
||||||
{
|
{
|
||||||
if ((panel && panel->lock) || lock)
|
if (panel && panel->lock)
|
||||||
|
return;
|
||||||
|
if (lock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (field)
|
if (field)
|
||||||
|
@ -86,15 +88,15 @@ class AutoLineEdit: public QLineEdit
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
emit currentDataChanged();
|
||||||
|
|
||||||
if (panel)
|
if (panel)
|
||||||
emit panel->modified();
|
emit panel->modified();
|
||||||
|
|
||||||
emit currentDataChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char * field;
|
char * field;
|
||||||
QString * strField;
|
QString * strField = nullptr;
|
||||||
GenericPanel * panel;
|
GenericPanel * panel = nullptr;
|
||||||
bool lock;
|
bool lock = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -123,7 +123,7 @@ class AutoPrecisionComboBox: public QComboBox
|
||||||
if (*m_field != val) {
|
if (*m_field != val) {
|
||||||
*m_field = rangecheckDecimals(val);
|
*m_field = rangecheckDecimals(val);
|
||||||
updateValue();
|
updateValue();
|
||||||
emit valueChanged();
|
emit currentDataChanged(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ class AutoPrecisionComboBox: public QComboBox
|
||||||
if (*m_field != value) {
|
if (*m_field != value) {
|
||||||
*m_field = rangecheckDecimals(value);
|
*m_field = rangecheckDecimals(value);
|
||||||
updateValue();
|
updateValue();
|
||||||
emit valueChanged();
|
emit currentDataChanged((int)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ class AutoPrecisionComboBox: public QComboBox
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void valueChanged();
|
void currentDataChanged(int index);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void init()
|
void init()
|
||||||
|
@ -203,13 +203,13 @@ class AutoPrecisionComboBox: public QComboBox
|
||||||
|
|
||||||
void onCurrentIndexChanged(int index)
|
void onCurrentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (index < 0)
|
if (index < 0 || (m_panel && m_panel->lock) || m_lock)
|
||||||
return;
|
return;
|
||||||
if (m_field && !m_lock) {
|
if (m_field) {
|
||||||
*m_field = itemData(index).toUInt();
|
*m_field = itemData(index).toUInt();
|
||||||
|
emit currentDataChanged(index);
|
||||||
if (m_panel)
|
if (m_panel)
|
||||||
emit m_panel->modified();
|
emit m_panel->modified();
|
||||||
emit valueChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
99
companion/src/shared/autotimeedit.h
Normal file
99
companion/src/shared/autotimeedit.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QTimeEdit>
|
||||||
|
#include "genericpanel.h"
|
||||||
|
|
||||||
|
class AutoTimeEdit: public QTimeEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AutoTimeEdit(QWidget * parent = nullptr):
|
||||||
|
QTimeEdit(parent),
|
||||||
|
field(nullptr),
|
||||||
|
panel(nullptr),
|
||||||
|
lock(false)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(timeChanged(QTime)), this, SLOT(onTimeChanged(QTime)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setField(unsigned int & field, GenericPanel * panel = nullptr)
|
||||||
|
{
|
||||||
|
this->field = &field;
|
||||||
|
this->panel = panel;
|
||||||
|
updateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMinimumTime(const QTime time)
|
||||||
|
{
|
||||||
|
QTimeEdit::setMinimumTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMaximumTime(const QTime time)
|
||||||
|
{
|
||||||
|
QTimeEdit::setMaximumTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
QTimeEdit::setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateValue()
|
||||||
|
{
|
||||||
|
if (field) {
|
||||||
|
lock = true;
|
||||||
|
int hour = *field / 3600;
|
||||||
|
int min = (*field - (hour * 3600)) / 60;
|
||||||
|
int sec = (*field - (hour * 3600)) % 60;
|
||||||
|
setTime(QTime(hour, min, sec));
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentDataChanged(unsigned int value);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onTimeChanged(QTime time)
|
||||||
|
{
|
||||||
|
if (panel && panel->lock)
|
||||||
|
return;
|
||||||
|
if (!field || lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int val = time.hour() * 3600 + time.minute() * 60 + time.second();
|
||||||
|
if (*field != val) {
|
||||||
|
*field = val;
|
||||||
|
emit currentDataChanged(val);
|
||||||
|
if (panel)
|
||||||
|
emit panel->modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
unsigned int *field = nullptr;
|
||||||
|
GenericPanel *panel = nullptr;
|
||||||
|
bool lock = false;
|
||||||
|
};
|
||||||
|
|
|
@ -39,6 +39,8 @@ class GenericPanel : public QWidget
|
||||||
friend class AutoLineEdit;
|
friend class AutoLineEdit;
|
||||||
friend class GVarGroup;
|
friend class GVarGroup;
|
||||||
friend class AutoPrecisionComboBox;
|
friend class AutoPrecisionComboBox;
|
||||||
|
friend class AutoBitsetCheckBox;
|
||||||
|
friend class AutoTimeEdit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware);
|
GenericPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -382,6 +382,7 @@ set(SRC
|
||||||
strhelpers.cpp
|
strhelpers.cpp
|
||||||
switches.cpp
|
switches.cpp
|
||||||
mixer.cpp
|
mixer.cpp
|
||||||
|
mixer_scheduler.cpp
|
||||||
stamp.cpp
|
stamp.cpp
|
||||||
timers.cpp
|
timers.cpp
|
||||||
trainer.cpp
|
trainer.cpp
|
||||||
|
|
|
@ -161,7 +161,7 @@ const char * const unitsFilenames[] = {
|
||||||
"hertz",
|
"hertz",
|
||||||
"ms",
|
"ms",
|
||||||
"us",
|
"us",
|
||||||
"spare4",
|
"km",
|
||||||
"spare5",
|
"spare5",
|
||||||
"spare6",
|
"spare6",
|
||||||
"spare7",
|
"spare7",
|
||||||
|
|
|
@ -699,11 +699,11 @@ int cliTrace(const char ** argv)
|
||||||
|
|
||||||
int cliStackInfo(const char ** argv)
|
int cliStackInfo(const char ** argv)
|
||||||
{
|
{
|
||||||
serialPrint("[MAIN] %d available / %d", stackAvailable(), stackSize());
|
serialPrint("[MAIN] %d available / %d bytes", stackAvailable()*4, stackSize()*4);
|
||||||
serialPrint("[MENUS] %d available / %d", menusStack.available(), menusStack.size());
|
serialPrint("[MENUS] %d available / %d bytes", menusStack.available()*4, menusStack.size());
|
||||||
serialPrint("[MIXER] %d available / %d", mixerStack.available(), mixerStack.size());
|
serialPrint("[MIXER] %d available / %d bytes", mixerStack.available()*4, mixerStack.size());
|
||||||
serialPrint("[AUDIO] %d available / %d", audioStack.available(), audioStack.size());
|
serialPrint("[AUDIO] %d available / %d bytes", audioStack.available()*4, audioStack.size());
|
||||||
serialPrint("[CLI] %d available / %d", cliStack.available(), cliStack.size());
|
serialPrint("[CLI] %d available / %d bytes", cliStack.available()*4, cliStack.size());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,7 @@ enum TelemetryProtocol
|
||||||
PROTOCOL_TELEMETRY_FLYSKY_IBUS,
|
PROTOCOL_TELEMETRY_FLYSKY_IBUS,
|
||||||
PROTOCOL_TELEMETRY_HITEC,
|
PROTOCOL_TELEMETRY_HITEC,
|
||||||
PROTOCOL_TELEMETRY_HOTT,
|
PROTOCOL_TELEMETRY_HOTT,
|
||||||
|
PROTOCOL_TELEMETRY_MLINK,
|
||||||
PROTOCOL_TELEMETRY_MULTIMODULE,
|
PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||||
PROTOCOL_TELEMETRY_AFHDS3,
|
PROTOCOL_TELEMETRY_AFHDS3,
|
||||||
PROTOCOL_TELEMETRY_GHOST,
|
PROTOCOL_TELEMETRY_GHOST,
|
||||||
|
@ -318,8 +319,8 @@ enum TelemetryUnit {
|
||||||
UNIT_HERTZ,
|
UNIT_HERTZ,
|
||||||
UNIT_MS,
|
UNIT_MS,
|
||||||
UNIT_US,
|
UNIT_US,
|
||||||
UNIT_MAX = UNIT_US,
|
UNIT_KM,
|
||||||
UNIT_SPARE4,
|
UNIT_MAX = UNIT_KM,
|
||||||
UNIT_SPARE5,
|
UNIT_SPARE5,
|
||||||
UNIT_SPARE6,
|
UNIT_SPARE6,
|
||||||
UNIT_SPARE7,
|
UNIT_SPARE7,
|
||||||
|
|
|
@ -130,9 +130,6 @@ enum MenuModelSetupItems {
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM,
|
||||||
#if defined(PCBSKY9X) && defined(REVX)
|
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OUTPUT_TYPE,
|
|
||||||
#endif
|
|
||||||
#if defined(AFHDS3)
|
#if defined(AFHDS3)
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_RX_FREQ,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_RX_FREQ,
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_ACTUAL_POWER,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_ACTUAL_POWER,
|
||||||
|
@ -152,6 +149,9 @@ enum MenuModelSetupItems {
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2,
|
||||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3,
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3,
|
||||||
|
|
||||||
|
#if defined(PCBSKY9X) && defined(REVX)
|
||||||
|
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OUTPUT_TYPE,
|
||||||
|
#endif
|
||||||
#if defined(PCBSKY9X)
|
#if defined(PCBSKY9X)
|
||||||
ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL,
|
ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL,
|
||||||
ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS,
|
ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS,
|
||||||
|
@ -212,8 +212,8 @@ enum MenuModelSetupItems {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PCBSKY9X) && defined(REVX)
|
#if defined(PCBSKY9X) && defined(REVX)
|
||||||
#define OUTPUT_TYPE_ROW (isModulePPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW),
|
#define OUTPUT_TYPE_ROW (isModulePPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW), // Output type (OpenDrain / PushPull)
|
||||||
#elif defined(PCBSKY9X)
|
#else
|
||||||
#define OUTPUT_TYPE_ROW
|
#define OUTPUT_TYPE_ROW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -389,12 +389,22 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
|
||||||
#define EXTERNAL_MODULE_ROWS
|
#define EXTERNAL_MODULE_ROWS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PCBTARANIS)
|
||||||
|
#define WARN_ROWS \
|
||||||
|
SW_WARN_ROWS, /* Switch warning */ \
|
||||||
|
POT_WARN_ROWS, /* Pot warning */
|
||||||
|
#else
|
||||||
|
#define WARN_ROWS \
|
||||||
|
NUM_SWITCHES - 1, /* Switch warning */
|
||||||
|
#endif
|
||||||
|
|
||||||
void menuModelSetup(event_t event)
|
void menuModelSetup(event_t event)
|
||||||
{
|
{
|
||||||
int8_t old_editMode = s_editMode;
|
int8_t old_editMode = s_editMode;
|
||||||
|
|
||||||
#if defined(PCBTARANIS)
|
#if defined(PCBTARANIS)
|
||||||
int8_t old_posHorz = menuHorizontalPosition;
|
int8_t old_posHorz = menuHorizontalPosition;
|
||||||
|
#endif
|
||||||
|
|
||||||
MENU_TAB({
|
MENU_TAB({
|
||||||
HEADER_LINE_COLUMNS
|
HEADER_LINE_COLUMNS
|
||||||
|
@ -412,8 +422,7 @@ void menuModelSetup(event_t event)
|
||||||
LABEL(PreflightCheck),
|
LABEL(PreflightCheck),
|
||||||
0, // Checklist
|
0, // Checklist
|
||||||
0, // Throttle warning
|
0, // Throttle warning
|
||||||
SW_WARN_ROWS, // Switch warning
|
WARN_ROWS
|
||||||
POT_WARN_ROWS, // Pot warning
|
|
||||||
|
|
||||||
NUM_STICKS + NUM_POTS + NUM_SLIDERS - 1, // Center beeps
|
NUM_STICKS + NUM_POTS + NUM_SLIDERS - 1, // Center beeps
|
||||||
0, // Global functions
|
0, // Global functions
|
||||||
|
@ -424,54 +433,12 @@ void menuModelSetup(event_t event)
|
||||||
|
|
||||||
EXTERNAL_MODULE_ROWS
|
EXTERNAL_MODULE_ROWS
|
||||||
|
|
||||||
TRAINER_ROWS
|
OUTPUT_TYPE_ROW
|
||||||
});
|
|
||||||
#else
|
|
||||||
MENU_TAB({
|
|
||||||
HEADER_LINE_COLUMNS
|
|
||||||
0,
|
|
||||||
TIMERS_ROWS,
|
|
||||||
0, // Extended limits
|
|
||||||
1, // Extended trims
|
|
||||||
0, // Show trims
|
|
||||||
0, // Trims step
|
|
||||||
0, // Throttle reverse
|
|
||||||
0, // Throttle trace source
|
|
||||||
0, // Throttle trim
|
|
||||||
0, // Throttle trim switch
|
|
||||||
|
|
||||||
LABEL(PreflightCheck),
|
|
||||||
0, // Checklist
|
|
||||||
0, // Throttle warning
|
|
||||||
NUM_SWITCHES-1, // Switch warning
|
|
||||||
|
|
||||||
NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, // Center beeps
|
|
||||||
0, // Global functions
|
|
||||||
|
|
||||||
LABEL(ExternalModule),
|
|
||||||
MODULE_TYPE_ROWS(EXTERNAL_MODULE),
|
|
||||||
MULTIMODULE_TYPE_ROWS(EXTERNAL_MODULE)
|
|
||||||
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
|
|
||||||
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE)
|
|
||||||
|
|
||||||
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE),
|
|
||||||
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings
|
|
||||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum
|
|
||||||
0, // Output type (OpenDrain / PushPull)
|
|
||||||
MODULE_POWER_ROW(EXTERNAL_MODULE),
|
|
||||||
IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)),
|
|
||||||
MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE)
|
|
||||||
FAILSAFE_ROWS(EXTERNAL_MODULE),
|
|
||||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons
|
|
||||||
IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options
|
|
||||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1
|
|
||||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2
|
|
||||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3
|
|
||||||
|
|
||||||
EXTRA_MODULE_ROWS
|
EXTRA_MODULE_ROWS
|
||||||
|
|
||||||
TRAINER_ROWS
|
TRAINER_ROWS
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
|
|
||||||
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, HEADER_LINE + ITEM_MODEL_SETUP_LINES_COUNT);
|
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, HEADER_LINE + ITEM_MODEL_SETUP_LINES_COUNT);
|
||||||
title(STR_MENUSETUP);
|
title(STR_MENUSETUP);
|
||||||
|
@ -1582,40 +1549,35 @@ void menuModelSetup(event_t event)
|
||||||
{
|
{
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
||||||
|
const char * title = getMultiOptionTitle(moduleIdx);
|
||||||
|
|
||||||
|
lcdDrawText(INDENT_WIDTH, y, title);
|
||||||
|
if (title == STR_MULTI_RFTUNE) {
|
||||||
|
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
||||||
|
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
||||||
|
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||||
|
|
||||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
|
||||||
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||||
|
|
||||||
if (status.isValid()) {
|
|
||||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
|
||||||
lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]);
|
|
||||||
if (attr && status.optionDisp == 2) {
|
|
||||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
|
||||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
|
||||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
|
||||||
if (pdef->optionsstr) {
|
|
||||||
lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr);
|
|
||||||
if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) {
|
|
||||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
|
||||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
|
||||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t min, max;
|
int8_t min, max;
|
||||||
getMultiOptionValues(multi_proto, min, max);
|
getMultiOptionValues(multi_proto, min, max);
|
||||||
|
|
||||||
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
if (title == STR_MULTI_RFPOWER) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
||||||
|
min = 0;
|
||||||
|
max = 15;
|
||||||
|
}
|
||||||
|
else if (title == STR_MULTI_TELEMETRY) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr);
|
||||||
|
}
|
||||||
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
||||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
||||||
}
|
}
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) {
|
else if (title == STR_MULTI_WBUS) {
|
||||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr);
|
||||||
|
min = 0;
|
||||||
|
max = 1;
|
||||||
}
|
}
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||||
optionValue = optionValue & 0x01;
|
optionValue = optionValue & 0x01;
|
||||||
|
|
|
@ -1304,38 +1304,34 @@ void menuModelSetup(event_t event)
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
|
|
||||||
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
||||||
|
const char * title = getMultiOptionTitle(moduleIdx);
|
||||||
|
|
||||||
|
lcdDrawText(INDENT_WIDTH, y, title);
|
||||||
|
if (title == STR_MULTI_RFTUNE) {
|
||||||
|
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
||||||
|
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
||||||
|
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||||
|
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
|
||||||
const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
|
||||||
if (status.isValid()) {
|
|
||||||
lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]);
|
|
||||||
if (attr && status.optionDisp == 2) {
|
|
||||||
lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT);
|
|
||||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
|
||||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
|
||||||
if (pdef->optionsstr)
|
|
||||||
lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr);
|
|
||||||
if (pdef->optionsstr == STR_MULTI_RFTUNE) {
|
|
||||||
lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT);
|
|
||||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
|
||||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t min, max;
|
int8_t min, max;
|
||||||
getMultiOptionValues(multi_proto, min, max);
|
getMultiOptionValues(multi_proto, min, max);
|
||||||
|
|
||||||
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
if (title == STR_MULTI_RFPOWER) {
|
||||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
|
||||||
}
|
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) {
|
|
||||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
||||||
}
|
}
|
||||||
|
else if (title == STR_MULTI_TELEMETRY) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr);
|
||||||
|
}
|
||||||
|
else if (title == STR_MULTI_WBUS) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr);
|
||||||
|
min = 0;
|
||||||
|
max = 1;
|
||||||
|
}
|
||||||
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
||||||
|
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
||||||
|
}
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||||
optionValue = optionValue & 0x01;
|
optionValue = optionValue & 0x01;
|
||||||
editCheckBox(optionValue, MODEL_SETUP_2ND_COLUMN, y, "", LEFT | attr, event);
|
editCheckBox(optionValue, MODEL_SETUP_2ND_COLUMN, y, "", LEFT | attr, event);
|
||||||
|
|
|
@ -1688,34 +1688,33 @@ bool menuModelSetup(event_t event)
|
||||||
{
|
{
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
|
||||||
|
const char * title = getMultiOptionTitle(moduleIdx);
|
||||||
|
|
||||||
|
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, title);
|
||||||
|
if (title == STR_MULTI_RFTUNE) {
|
||||||
|
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
||||||
|
}
|
||||||
|
|
||||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||||
|
|
||||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
|
||||||
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||||
if (status.isValid()) {
|
|
||||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]);
|
|
||||||
if (attr && status.optionDisp == 2) {
|
|
||||||
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
|
||||||
if (pdef->optionsstr) {
|
|
||||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, pdef->optionsstr);
|
|
||||||
if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) {
|
|
||||||
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t min, max;
|
int8_t min, max;
|
||||||
getMultiOptionValues(multi_proto, min, max);
|
getMultiOptionValues(multi_proto, min, max);
|
||||||
|
|
||||||
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
if (title == STR_MULTI_RFPOWER) {
|
||||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
|
||||||
}
|
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) {
|
|
||||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr);
|
||||||
|
min = 0;
|
||||||
|
max = 15;
|
||||||
|
}
|
||||||
|
else if (title == STR_MULTI_TELEMETRY) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr);
|
||||||
|
}
|
||||||
|
else if (title == STR_MULTI_WBUS) {
|
||||||
|
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr);
|
||||||
|
min = 0;
|
||||||
|
max = 1;
|
||||||
|
}
|
||||||
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
|
||||||
|
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr);
|
||||||
}
|
}
|
||||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||||
optionValue = optionValue & 0x01;
|
optionValue = optionValue & 0x01;
|
||||||
|
@ -1727,6 +1726,7 @@ bool menuModelSetup(event_t event)
|
||||||
else
|
else
|
||||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr);
|
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr) {
|
if (attr) {
|
||||||
CHECK_INCDEC_MODELVAR(event, optionValue, min, max);
|
CHECK_INCDEC_MODELVAR(event, optionValue, min, max);
|
||||||
if (checkIncDec_Ret) {
|
if (checkIncDec_Ret) {
|
||||||
|
|
|
@ -145,7 +145,7 @@ void editName(coord_t x, coord_t y, char * name, uint8_t size, event_t event, ui
|
||||||
if (c <= 0) v = -v;
|
if (c <= 0) v = -v;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v = checkIncDec(event, abs(v), '0', 'z', 0);
|
v = checkIncDec(event, abs(v), ' ', 'z', 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -994,9 +994,15 @@ const char* mm_options_strings::options[] = {
|
||||||
STR_MULTI_SERVOFREQ,
|
STR_MULTI_SERVOFREQ,
|
||||||
STR_MULTI_MAX_THROW,
|
STR_MULTI_MAX_THROW,
|
||||||
STR_MULTI_RFCHAN,
|
STR_MULTI_RFCHAN,
|
||||||
STR_MULTI_RFPOWER
|
STR_MULTI_RFPOWER,
|
||||||
|
STR_MULTI_WBUS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t getMaxMultiOptions()
|
||||||
|
{
|
||||||
|
return DIM(mm_options_strings::options);
|
||||||
|
}
|
||||||
|
|
||||||
const mm_protocol_definition multi_protocols[] = {
|
const mm_protocol_definition multi_protocols[] = {
|
||||||
// Protocol as defined in pulses\modules_constants.h, number of sub_protocols - 1, Failsafe supported, Disable channel mapping supported, Subtype string, Option type
|
// Protocol as defined in pulses\modules_constants.h, number of sub_protocols - 1, Failsafe supported, Disable channel mapping supported, Subtype string, Option type
|
||||||
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr},
|
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr},
|
||||||
|
@ -1091,3 +1097,22 @@ void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, Lcd
|
||||||
else
|
else
|
||||||
lcdDrawMMM(x, y, flags);
|
lcdDrawMMM(x, y, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MULTIMODULE)
|
||||||
|
const char * getMultiOptionTitle(uint8_t moduleIdx)
|
||||||
|
{
|
||||||
|
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||||
|
|
||||||
|
if (status.isValid()) {
|
||||||
|
if (status.optionDisp >= getMaxMultiOptions()) {
|
||||||
|
status.optionDisp = 1; // Unknown options are defaulted to type 1 (basic option)
|
||||||
|
}
|
||||||
|
return mm_options_strings::options[status.optionDisp];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||||
|
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
||||||
|
return pdef->optionsstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -306,7 +306,7 @@ inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx)
|
||||||
|
|
||||||
#define MULTIMODULE_MODULE_ROWS(moduleIdx) (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) && !IS_RX_MULTI(moduleIdx)) ? (uint8_t) 0 : HIDDEN_ROW, (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) && !IS_RX_MULTI(moduleIdx)) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP
|
#define MULTIMODULE_MODULE_ROWS(moduleIdx) (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) && !IS_RX_MULTI(moduleIdx)) ? (uint8_t) 0 : HIDDEN_ROW, (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) && !IS_RX_MULTI(moduleIdx)) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP
|
||||||
#define MULTIMODULE_TYPE_ROW(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW,
|
#define MULTIMODULE_TYPE_ROW(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW,
|
||||||
#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW,
|
#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getModuleSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW,
|
||||||
#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 : MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t)2 : (uint8_t)1
|
#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 : MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t)2 : (uint8_t)1
|
||||||
#define MULTIMODULE_TYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW,
|
#define MULTIMODULE_TYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW,
|
||||||
#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW,
|
#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW,
|
||||||
|
@ -346,6 +346,7 @@ inline uint8_t MODULE_OPTION_ROW(uint8_t moduleIdx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags);
|
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags);
|
||||||
|
const char * getMultiOptionTitle(uint8_t moduleIdx);
|
||||||
|
|
||||||
const char * writeScreenshot();
|
const char * writeScreenshot();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ if(PYTHONINTERP_FOUND)
|
||||||
add_lua_export_target(xlite ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITE)
|
add_lua_export_target(xlite ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITE)
|
||||||
add_lua_export_target(xlites ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITES -DPCBXLITE -DGYRO)
|
add_lua_export_target(xlites ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITES -DPCBXLITE -DGYRO)
|
||||||
add_lua_export_target(x9d ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9D -DPCBX9)
|
add_lua_export_target(x9d ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9D -DPCBX9)
|
||||||
|
add_lua_export_target(x9d+2019 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9D -DPCBX9 -DRADIO_X9DP2019)
|
||||||
add_lua_export_target(x9e ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9E -DPCBX9)
|
add_lua_export_target(x9e ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9E -DPCBX9)
|
||||||
add_lua_export_target(x10 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10)
|
add_lua_export_target(x10 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10)
|
||||||
add_lua_export_target(x12s ${LUA_INCLUDES} -DPCBHORUS -DPCBX12S)
|
add_lua_export_target(x12s ${LUA_INCLUDES} -DPCBHORUS -DPCBX12S)
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include "lua/lua_exports_xlites.inc"
|
#include "lua/lua_exports_xlites.inc"
|
||||||
#elif defined(PCBXLITE)
|
#elif defined(PCBXLITE)
|
||||||
#include "lua/lua_exports_xlite.inc"
|
#include "lua/lua_exports_xlite.inc"
|
||||||
|
#elif defined(RADIO_X9DP2019)
|
||||||
|
#include "lua/lua_exports_x9d+2019.inc"
|
||||||
#elif defined(PCBTARANIS)
|
#elif defined(PCBTARANIS)
|
||||||
#include "lua/lua_exports_x9d.inc"
|
#include "lua/lua_exports_x9d.inc"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1409,7 +1411,10 @@ Get RSSI value as well as low and critical RSSI alarm levels (in dB)
|
||||||
*/
|
*/
|
||||||
static int luaGetRSSI(lua_State * L)
|
static int luaGetRSSI(lua_State * L)
|
||||||
{
|
{
|
||||||
lua_pushunsigned(L, min((uint8_t)99, TELEMETRY_RSSI()));
|
if (TELEMETRY_STREAMING())
|
||||||
|
lua_pushunsigned(L, min((uint8_t)99, TELEMETRY_RSSI()));
|
||||||
|
else
|
||||||
|
lua_pushunsigned(L, 0);
|
||||||
lua_pushunsigned(L, g_model.rssiAlarms.getWarningRssi());
|
lua_pushunsigned(L, g_model.rssiAlarms.getWarningRssi());
|
||||||
lua_pushunsigned(L, g_model.rssiAlarms.getCriticalRssi());
|
lua_pushunsigned(L, g_model.rssiAlarms.getCriticalRssi());
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -2036,6 +2041,7 @@ const luaR_value_entry opentxConstants[] = {
|
||||||
{"UNIT_KMH", UNIT_KMH },
|
{"UNIT_KMH", UNIT_KMH },
|
||||||
{"UNIT_MPH", UNIT_MPH },
|
{"UNIT_MPH", UNIT_MPH },
|
||||||
{"UNIT_METERS", UNIT_METERS },
|
{"UNIT_METERS", UNIT_METERS },
|
||||||
|
{"UNIT_KM", UNIT_KM },
|
||||||
{"UNIT_FEET", UNIT_FEET },
|
{"UNIT_FEET", UNIT_FEET },
|
||||||
{"UNIT_CELSIUS", UNIT_CELSIUS },
|
{"UNIT_CELSIUS", UNIT_CELSIUS },
|
||||||
{"UNIT_FAHRENHEIT", UNIT_FAHRENHEIT },
|
{"UNIT_FAHRENHEIT", UNIT_FAHRENHEIT },
|
||||||
|
|
82
radio/src/mixer_scheduler.cpp
Normal file
82
radio/src/mixer_scheduler.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opentx.h"
|
||||||
|
#include "mixer_scheduler.h"
|
||||||
|
|
||||||
|
#if !defined(SIMU)
|
||||||
|
|
||||||
|
// Global trigger flag
|
||||||
|
RTOS_FLAG_HANDLE mixerFlag;
|
||||||
|
|
||||||
|
// Mixer schedule
|
||||||
|
struct MixerSchedule {
|
||||||
|
|
||||||
|
// period in us
|
||||||
|
volatile uint16_t period;
|
||||||
|
};
|
||||||
|
|
||||||
|
static MixerSchedule mixerSchedules[NUM_MODULES];
|
||||||
|
|
||||||
|
uint16_t getMixerSchedulerPeriod()
|
||||||
|
{
|
||||||
|
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||||
|
if (mixerSchedules[INTERNAL_MODULE].period) {
|
||||||
|
return mixerSchedules[INTERNAL_MODULE].period;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||||
|
if (mixerSchedules[EXTERNAL_MODULE].period) {
|
||||||
|
return mixerSchedules[EXTERNAL_MODULE].period;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return MIXER_SCHEDULER_DEFAULT_PERIOD_US;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerInit()
|
||||||
|
{
|
||||||
|
RTOS_CREATE_FLAG(mixerFlag);
|
||||||
|
memset(mixerSchedules, 0, sizeof(mixerSchedules));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerSetPeriod(uint8_t moduleIdx, uint16_t periodUs)
|
||||||
|
{
|
||||||
|
if (periodUs > 0 && periodUs < MIN_REFRESH_RATE) {
|
||||||
|
periodUs = MIN_REFRESH_RATE;
|
||||||
|
}
|
||||||
|
else if (periodUs > 0 && periodUs > MAX_REFRESH_RATE) {
|
||||||
|
periodUs = MAX_REFRESH_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixerSchedules[moduleIdx].period = periodUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mixerSchedulerWaitForTrigger(uint8_t timeoutMs)
|
||||||
|
{
|
||||||
|
RTOS_CLEAR_FLAG(mixerFlag);
|
||||||
|
return RTOS_WAIT_FLAG(mixerFlag, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerISRTrigger()
|
||||||
|
{
|
||||||
|
RTOS_ISR_SET_FLAG(mixerFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
84
radio/src/mixer_scheduler.h
Normal file
84
radio/src/mixer_scheduler.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIXER_SCHEDULER_H_
|
||||||
|
#define _MIXER_SCHEDULER_H_
|
||||||
|
|
||||||
|
#define MIXER_SCHEDULER_DEFAULT_PERIOD_US 4000u // 4ms
|
||||||
|
|
||||||
|
#define MIN_REFRESH_RATE 1750 /* us */
|
||||||
|
#define MAX_REFRESH_RATE 25000 /* us */
|
||||||
|
|
||||||
|
#if !defined(SIMU)
|
||||||
|
|
||||||
|
// Call once to initialize the mixer scheduler
|
||||||
|
void mixerSchedulerInit();
|
||||||
|
|
||||||
|
// Configure and start the scheduler timer
|
||||||
|
void mixerSchedulerStart();
|
||||||
|
|
||||||
|
// Stop the scheduler timer
|
||||||
|
void mixerSchedulerStop();
|
||||||
|
|
||||||
|
// Set the timer counter to 0
|
||||||
|
void mixerSchedulerResetTimer();
|
||||||
|
|
||||||
|
// Set the scheduling period for a given module
|
||||||
|
void mixerSchedulerSetPeriod(uint8_t moduleIdx, uint16_t periodUs);
|
||||||
|
|
||||||
|
// Wait for the scheduler timer to trigger
|
||||||
|
// returns true if timeout, false otherwise
|
||||||
|
bool mixerSchedulerWaitForTrigger(uint8_t timeoutMs);
|
||||||
|
|
||||||
|
// Enable the timer trigger
|
||||||
|
void mixerSchedulerEnableTrigger();
|
||||||
|
|
||||||
|
// Disable the timer trigger
|
||||||
|
void mixerSchedulerDisableTrigger();
|
||||||
|
|
||||||
|
// Fetch the current scheduling period
|
||||||
|
uint16_t getMixerSchedulerPeriod();
|
||||||
|
|
||||||
|
// Trigger mixer from an ISR
|
||||||
|
void mixerSchedulerISRTrigger();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define mixerSchedulerInit()
|
||||||
|
#define mixerSchedulerStart()
|
||||||
|
#define mixerSchedulerStop()
|
||||||
|
#define mixerSchedulerResetTimer()
|
||||||
|
#define mixerSchedulerSetPeriod(m,p)
|
||||||
|
|
||||||
|
static inline bool mixerSchedulerWaitForTrigger(uint8_t timeout)
|
||||||
|
{
|
||||||
|
simuSleep(timeout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mixerSchedulerEnableTrigger()
|
||||||
|
#define mixerSchedulerDisableTrigger()
|
||||||
|
|
||||||
|
#define getMixerSchedulerPeriod() (MIXER_SCHEDULER_DEFAULT_PERIOD_US)
|
||||||
|
#define mixerSchedulerISRTrigger()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1445,6 +1445,19 @@ void doMixerCalculations()
|
||||||
DEBUG_TIMER_START(debugTimerEvalMixes);
|
DEBUG_TIMER_START(debugTimerEvalMixes);
|
||||||
evalMixes(tick10ms);
|
evalMixes(tick10ms);
|
||||||
DEBUG_TIMER_STOP(debugTimerEvalMixes);
|
DEBUG_TIMER_STOP(debugTimerEvalMixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doMixerPeriodicUpdates()
|
||||||
|
{
|
||||||
|
static tmr10ms_t lastTMR = 0;
|
||||||
|
|
||||||
|
tmr10ms_t tmr10ms = get_tmr10ms();
|
||||||
|
|
||||||
|
uint8_t tick10ms = (tmr10ms >= lastTMR ? tmr10ms - lastTMR : 1);
|
||||||
|
// handle tick10ms overrun
|
||||||
|
// correct overflow handling costs a lot of code; happens only each 11 min;
|
||||||
|
// therefore forget the exact calculation and use only 1 instead; good compromise
|
||||||
|
lastTMR = tmr10ms;
|
||||||
|
|
||||||
DEBUG_TIMER_START(debugTimerMixes10ms);
|
DEBUG_TIMER_START(debugTimerMixes10ms);
|
||||||
if (tick10ms) {
|
if (tick10ms) {
|
||||||
|
|
|
@ -320,7 +320,7 @@ void memswap(void * a, void * b, uint8_t size);
|
||||||
#define MASK_CFN_TYPE uint64_t // current max = 64 function switches
|
#define MASK_CFN_TYPE uint64_t // current max = 64 function switches
|
||||||
#define MASK_FUNC_TYPE uint32_t // current max = 32 functions
|
#define MASK_FUNC_TYPE uint32_t // current max = 32 functions
|
||||||
|
|
||||||
typedef struct {
|
struct CustomFunctionsContext {
|
||||||
MASK_FUNC_TYPE activeFunctions;
|
MASK_FUNC_TYPE activeFunctions;
|
||||||
MASK_CFN_TYPE activeSwitches;
|
MASK_CFN_TYPE activeSwitches;
|
||||||
tmr10ms_t lastFunctionTime[MAX_SPECIAL_FUNCTIONS];
|
tmr10ms_t lastFunctionTime[MAX_SPECIAL_FUNCTIONS];
|
||||||
|
@ -334,7 +334,7 @@ typedef struct {
|
||||||
{
|
{
|
||||||
memclear(this, sizeof(*this));
|
memclear(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
} CustomFunctionsContext;
|
};
|
||||||
|
|
||||||
#include "strhelpers.h"
|
#include "strhelpers.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
@ -501,6 +501,7 @@ extern uint32_t nextMixerTime[NUM_MODULES];
|
||||||
void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms);
|
void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms);
|
||||||
void evalMixes(uint8_t tick10ms);
|
void evalMixes(uint8_t tick10ms);
|
||||||
void doMixerCalculations();
|
void doMixerCalculations();
|
||||||
|
void doMixerPeriodicUpdates();
|
||||||
void scheduleNextMixerCalculation(uint8_t module, uint32_t period_ms);
|
void scheduleNextMixerCalculation(uint8_t module, uint32_t period_ms);
|
||||||
|
|
||||||
void checkTrims();
|
void checkTrims();
|
||||||
|
|
|
@ -94,9 +94,6 @@ struct Data
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
#if !(defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO))
|
|
||||||
total = 0;
|
|
||||||
#endif
|
|
||||||
pulsesSize = 0;
|
pulsesSize = 0;
|
||||||
}
|
}
|
||||||
#if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO)
|
#if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO)
|
||||||
|
@ -118,7 +115,6 @@ struct Data
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pulses[pulsesSize++] = v;
|
pulses[pulsesSize++] = v;
|
||||||
total += v;
|
|
||||||
}
|
}
|
||||||
void sendByte(uint8_t b)
|
void sendByte(uint8_t b)
|
||||||
{
|
{
|
||||||
|
@ -149,14 +145,7 @@ struct Data
|
||||||
//add remaining time of frame
|
//add remaining time of frame
|
||||||
void flush()
|
void flush()
|
||||||
{
|
{
|
||||||
uint16_t diff = AFHDS3_FRAME_HALF_US - total;
|
pulses[pulsesSize - 1] = 60000;
|
||||||
pulses[pulsesSize - 1] += diff;
|
|
||||||
//ensure 2 ms break
|
|
||||||
if (pulses[pulsesSize - 1] < 4000)
|
|
||||||
{
|
|
||||||
pulses[pulsesSize - 1] = 4050;
|
|
||||||
}
|
|
||||||
total += diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t* getData()
|
const uint16_t* getData()
|
||||||
|
|
|
@ -76,7 +76,6 @@ void _send_1(uint8_t v)
|
||||||
|
|
||||||
*extmodulePulsesData.dsm2.ptr++ = v - 1;
|
*extmodulePulsesData.dsm2.ptr++ = v - 1;
|
||||||
extmodulePulsesData.dsm2.index += 1;
|
extmodulePulsesData.dsm2.index += 1;
|
||||||
extmodulePulsesData.dsm2.rest -= v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1
|
void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1
|
||||||
|
@ -101,9 +100,9 @@ void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1
|
||||||
void putDsm2Flush()
|
void putDsm2Flush()
|
||||||
{
|
{
|
||||||
if (extmodulePulsesData.dsm2.index & 1)
|
if (extmodulePulsesData.dsm2.index & 1)
|
||||||
*extmodulePulsesData.dsm2.ptr++ = extmodulePulsesData.dsm2.rest;
|
*extmodulePulsesData.dsm2.ptr++ = 60000;
|
||||||
else
|
else
|
||||||
*(extmodulePulsesData.dsm2.ptr - 1) = extmodulePulsesData.dsm2.rest;
|
*(extmodulePulsesData.dsm2.ptr - 1) = 60000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -119,7 +118,6 @@ void setupPulsesDSM2()
|
||||||
extmodulePulsesData.dsm2.serialBitCount = 0 ;
|
extmodulePulsesData.dsm2.serialBitCount = 0 ;
|
||||||
#else
|
#else
|
||||||
extmodulePulsesData.dsm2.index = 0;
|
extmodulePulsesData.dsm2.index = 0;
|
||||||
extmodulePulsesData.dsm2.rest = DSM2_PERIOD * 2000;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses;
|
extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses;
|
||||||
|
|
|
@ -42,6 +42,8 @@ struct mm_options_strings {
|
||||||
static const char* options[];
|
static const char* options[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t getMaxMultiOptions();
|
||||||
|
|
||||||
struct mm_protocol_definition {
|
struct mm_protocol_definition {
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
uint8_t maxSubtype;
|
uint8_t maxSubtype;
|
||||||
|
@ -671,10 +673,6 @@ inline void getMultiOptionValues(int8_t multi_proto, int8_t & min, int8_t & max)
|
||||||
min = -1;
|
min = -1;
|
||||||
max = 84;
|
max = 84;
|
||||||
break;
|
break;
|
||||||
case MODULE_SUBTYPE_MULTI_FRSKY_R9:
|
|
||||||
min = 0; // 10mW
|
|
||||||
max = 5; // 300mW
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
min = -128;
|
min = -128;
|
||||||
max = 127;
|
max = 127;
|
||||||
|
|
|
@ -209,10 +209,8 @@ void setupPulsesMultiExternalModule()
|
||||||
extmodulePulsesData.dsm2.serialByte = 0 ;
|
extmodulePulsesData.dsm2.serialByte = 0 ;
|
||||||
extmodulePulsesData.dsm2.serialBitCount = 0 ;
|
extmodulePulsesData.dsm2.serialBitCount = 0 ;
|
||||||
#else
|
#else
|
||||||
extmodulePulsesData.dsm2.rest = getMultiSyncStatus(EXTERNAL_MODULE).getAdjustedRefreshRate();
|
|
||||||
extmodulePulsesData.dsm2.index = 0;
|
extmodulePulsesData.dsm2.index = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses;
|
extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses;
|
||||||
|
|
||||||
setupPulsesMulti(EXTERNAL_MODULE);
|
setupPulsesMulti(EXTERNAL_MODULE);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "io/frsky_pxx2.h"
|
#include "io/frsky_pxx2.h"
|
||||||
#include "pulses/pxx2.h"
|
#include "pulses/pxx2.h"
|
||||||
|
#include "mixer_scheduler.h"
|
||||||
|
|
||||||
uint8_t s_pulses_paused = 0;
|
uint8_t s_pulses_paused = 0;
|
||||||
ModuleState moduleState[NUM_MODULES];
|
ModuleState moduleState[NUM_MODULES];
|
||||||
|
@ -62,7 +63,7 @@ void getModuleSyncStatusString(uint8_t moduleIdx, char * statusText)
|
||||||
*statusText = 0;
|
*statusText = 0;
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
if (isModuleMultimodule(moduleIdx)) {
|
if (isModuleMultimodule(moduleIdx)) {
|
||||||
getMultiSyncStatus(moduleIdx).getRefreshString(statusText);
|
getModuleSyncStatus(moduleIdx).getRefreshString(statusText);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(AFHDS3)
|
#if defined(AFHDS3)
|
||||||
|
@ -225,12 +226,14 @@ void enablePulsesExternalModule(uint8_t protocol)
|
||||||
#if defined(PXX1)
|
#if defined(PXX1)
|
||||||
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
||||||
extmodulePxx1PulsesStart();
|
extmodulePxx1PulsesStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, PXX_PULSES_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
||||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||||
extmodulePxx1SerialStart();
|
extmodulePxx1SerialStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -238,59 +241,81 @@ void enablePulsesExternalModule(uint8_t protocol)
|
||||||
case PROTOCOL_CHANNELS_DSM2_LP45:
|
case PROTOCOL_CHANNELS_DSM2_LP45:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
extmoduleSerialStart(DSM2_BAUDRATE, DSM2_PERIOD * 2000, false);
|
extmoduleSerialStart(DSM2_BAUDRATE, DSM2_PERIOD * 2000, false);
|
||||||
|
#else
|
||||||
|
extmoduleSerialStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, DSM2_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CROSSFIRE)
|
#if defined(CROSSFIRE)
|
||||||
case PROTOCOL_CHANNELS_CROSSFIRE:
|
case PROTOCOL_CHANNELS_CROSSFIRE:
|
||||||
EXTERNAL_MODULE_ON();
|
EXTERNAL_MODULE_ON();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GHOST)
|
#if defined(GHOST)
|
||||||
case PROTOCOL_CHANNELS_GHOST:
|
case PROTOCOL_CHANNELS_GHOST:
|
||||||
EXTERNAL_MODULE_ON();
|
EXTERNAL_MODULE_ON();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, GHOST_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PXX2) && defined(EXTMODULE_USART)
|
#if defined(PXX2) && defined(EXTMODULE_USART)
|
||||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||||
extmoduleInvertedSerialStart(PXX2_HIGHSPEED_BAUDRATE);
|
extmoduleInvertedSerialStart(PXX2_HIGHSPEED_BAUDRATE);
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, PXX2_PERIOD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROTOCOL_CHANNELS_PXX2_LOWSPEED:
|
case PROTOCOL_CHANNELS_PXX2_LOWSPEED:
|
||||||
extmoduleInvertedSerialStart(PXX2_LOWSPEED_BAUDRATE);
|
extmoduleInvertedSerialStart(PXX2_LOWSPEED_BAUDRATE);
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, PXX2_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
extmoduleSerialStart(MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000, true);
|
extmoduleSerialStart(MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000, true);
|
||||||
|
#else
|
||||||
|
extmoduleSerialStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SBUS)
|
#if defined(SBUS)
|
||||||
case PROTOCOL_CHANNELS_SBUS:
|
case PROTOCOL_CHANNELS_SBUS:
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
extmoduleSerialStart(SBUS_BAUDRATE, SBUS_PERIOD_HALF_US, false);
|
extmoduleSerialStart(SBUS_BAUDRATE, SBUS_PERIOD_HALF_US, false);
|
||||||
|
#else
|
||||||
|
extmoduleSerialStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, SBUS_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PPM)
|
#if defined(PPM)
|
||||||
case PROTOCOL_CHANNELS_PPM:
|
case PROTOCOL_CHANNELS_PPM:
|
||||||
extmodulePpmStart();
|
extmodulePpmStart();
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, PPM_PERIOD(EXTERNAL_MODULE));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AFHDS3)
|
#if defined(AFHDS3)
|
||||||
case PROTOCOL_CHANNELS_AFHDS3:
|
case PROTOCOL_CHANNELS_AFHDS3:
|
||||||
extmodulePulsesData.afhds3.init(EXTERNAL_MODULE);
|
extmodulePulsesData.afhds3.init(EXTERNAL_MODULE);
|
||||||
extmoduleSerialStart(AFHDS3_BAUDRATE, AFHDS3_COMMAND_TIMEOUT * 2000, false);
|
extmoduleSerialStart(/*AFHDS3_BAUDRATE, AFHDS3_COMMAND_TIMEOUT * 2000, false*/);
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, AFHDS3_COMMAND_TIMEOUT * 1000 /* us */);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// external module stopped, set period to 50ms (necessary for USB Joystick, for instance)
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, 50000/*us*/);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,14 +326,18 @@ bool setupPulsesExternalModule(uint8_t protocol)
|
||||||
#if defined(PXX1)
|
#if defined(PXX1)
|
||||||
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
||||||
extmodulePulsesData.pxx.setupFrame(EXTERNAL_MODULE);
|
extmodulePulsesData.pxx.setupFrame(EXTERNAL_MODULE);
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, PXX_PULSES_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, PXX_PULSES_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
||||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||||
extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE);
|
extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE);
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -316,63 +345,102 @@ bool setupPulsesExternalModule(uint8_t protocol)
|
||||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||||
case PROTOCOL_CHANNELS_PXX2_LOWSPEED:
|
case PROTOCOL_CHANNELS_PXX2_LOWSPEED:
|
||||||
extmodulePulsesData.pxx2.setupFrame(EXTERNAL_MODULE);
|
extmodulePulsesData.pxx2.setupFrame(EXTERNAL_MODULE);
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, PXX2_PERIOD);
|
#if defined(PCBSKY9X)
|
||||||
|
sheduleNextMixerCalculation(EXTERNAL_MODULE, PXX2_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SBUS)
|
#if defined(SBUS)
|
||||||
case PROTOCOL_CHANNELS_SBUS:
|
case PROTOCOL_CHANNELS_SBUS:
|
||||||
setupPulsesSbus();
|
setupPulsesSbus();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, SBUS_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, SBUS_PERIOD);
|
||||||
|
#else
|
||||||
|
// SBUS_PERIOD is not a constant! It can be set from UI
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, SBUS_PERIOD);
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(DSM2)
|
#if defined(DSM2)
|
||||||
case PROTOCOL_CHANNELS_DSM2_LP45:
|
case PROTOCOL_CHANNELS_DSM2_LP45:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
||||||
setupPulsesDSM2();
|
setupPulsesDSM2();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, DSM2_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, DSM2_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CROSSFIRE)
|
#if defined(CROSSFIRE)
|
||||||
case PROTOCOL_CHANNELS_CROSSFIRE:
|
case PROTOCOL_CHANNELS_CROSSFIRE:
|
||||||
|
{
|
||||||
|
ModuleSyncStatus& status = getModuleSyncStatus(EXTERNAL_MODULE);
|
||||||
|
if (status.isValid())
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, status.getAdjustedRefreshRate());
|
||||||
|
else
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
|
||||||
setupPulsesCrossfire();
|
setupPulsesCrossfire();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GHOST)
|
#if defined(GHOST)
|
||||||
case PROTOCOL_CHANNELS_GHOST:
|
case PROTOCOL_CHANNELS_GHOST:
|
||||||
|
{
|
||||||
|
ModuleSyncStatus& status = getModuleSyncStatus(EXTERNAL_MODULE);
|
||||||
|
if (status.isValid())
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, status.getAdjustedRefreshRate());
|
||||||
|
else
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, GHOST_PERIOD);
|
||||||
setupPulsesGhost();
|
setupPulsesGhost();
|
||||||
|
#if defined(PCBSKPCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, GHOST_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, GHOST_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||||
|
{
|
||||||
|
ModuleSyncStatus& status = getModuleSyncStatus(EXTERNAL_MODULE);
|
||||||
|
if (status.isValid())
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, status.getAdjustedRefreshRate());
|
||||||
|
else
|
||||||
|
mixerSchedulerSetPeriod(EXTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||||
setupPulsesMultiExternalModule();
|
setupPulsesMultiExternalModule();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, MULTIMODULE_PERIOD);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PPM)
|
#if defined(PPM)
|
||||||
case PROTOCOL_CHANNELS_PPM:
|
case PROTOCOL_CHANNELS_PPM:
|
||||||
setupPulsesPPMExternalModule();
|
setupPulsesPPMExternalModule();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, PPM_PERIOD(EXTERNAL_MODULE));
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, PPM_PERIOD(EXTERNAL_MODULE));
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AFHDS3)
|
#if defined(AFHDS3)
|
||||||
case PROTOCOL_CHANNELS_AFHDS3:
|
case PROTOCOL_CHANNELS_AFHDS3:
|
||||||
extmodulePulsesData.afhds3.setupFrame();
|
extmodulePulsesData.afhds3.setupFrame();
|
||||||
|
#if defined(PCBSKY9X)
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, AFHDS3_COMMAND_TIMEOUT);
|
scheduleNextMixerCalculation(EXTERNAL_MODULE, AFHDS3_COMMAND_TIMEOUT);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, 50/*ms*/);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,12 +454,26 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||||
#if defined(PXX1) && !defined(INTMODULE_USART)
|
#if defined(PXX1) && !defined(INTMODULE_USART)
|
||||||
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
||||||
intmodulePxx1PulsesStart();
|
intmodulePxx1PulsesStart();
|
||||||
|
#if defined(INTMODULE_HEARTBEAT)
|
||||||
|
// use backup trigger (1 ms later)
|
||||||
|
init_intmodule_heartbeat();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD + 1000/*us*/);
|
||||||
|
#else
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PXX1) && defined(INTMODULE_USART)
|
#if defined(PXX1) && defined(INTMODULE_USART)
|
||||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||||
intmodulePxx1SerialStart();
|
intmodulePxx1SerialStart();
|
||||||
|
#if defined(INTMODULE_HEARTBEAT)
|
||||||
|
// use backup trigger (1 ms later)
|
||||||
|
init_intmodule_heartbeat();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD + 1000/*us*/);
|
||||||
|
#else
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -399,6 +481,14 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||||
intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||||
resetAccessAuthenticationCount();
|
resetAccessAuthenticationCount();
|
||||||
|
|
||||||
|
#if defined(INTMODULE_HEARTBEAT)
|
||||||
|
// use backup trigger (1 ms later)
|
||||||
|
init_intmodule_heartbeat();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD + 1000/*us*/);
|
||||||
|
#else
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -406,17 +496,20 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||||
intmodulePulsesData.multi.initFrame();
|
intmodulePulsesData.multi.initFrame();
|
||||||
intmoduleSerialStart(MULTIMODULE_BAUDRATE, true, USART_Parity_Even, USART_StopBits_2, USART_WordLength_9b);
|
intmoduleSerialStart(MULTIMODULE_BAUDRATE, true, USART_Parity_Even, USART_StopBits_2, USART_WordLength_9b);
|
||||||
intmoduleTimerStart(MULTIMODULE_PERIOD);
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(INTERNAL_MODULE_PPM)
|
#if defined(INTERNAL_MODULE_PPM)
|
||||||
case PROTOCOL_CHANNELS_PPM:
|
case PROTOCOL_CHANNELS_PPM:
|
||||||
intmodulePpmStart();
|
intmodulePpmStart();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// internal module stopped, set internal period to 0 and start the scheduler
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,18 +520,18 @@ bool setupPulsesInternalModule(uint8_t protocol)
|
||||||
#if defined(HARDWARE_INTERNAL_MODULE) && defined(PXX1) && !defined(INTMODULE_USART)
|
#if defined(HARDWARE_INTERNAL_MODULE) && defined(PXX1) && !defined(INTMODULE_USART)
|
||||||
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
||||||
intmodulePulsesData.pxx.setupFrame(INTERNAL_MODULE);
|
intmodulePulsesData.pxx.setupFrame(INTERNAL_MODULE);
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD);
|
#if defined(INTMODULE_HEARTBEAT)
|
||||||
|
mixerSchedulerResetTimer();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD + 1000 /* backup */);
|
||||||
|
#else
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PXX1) && defined(INTMODULE_USART)
|
#if defined(PXX1) && defined(INTMODULE_USART)
|
||||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||||
intmodulePulsesData.pxx_uart.setupFrame(INTERNAL_MODULE);
|
intmodulePulsesData.pxx_uart.setupFrame(INTERNAL_MODULE);
|
||||||
#if defined(INTMODULE_HEARTBEAT)
|
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD + 1 /* backup */);
|
|
||||||
#else
|
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD);
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -447,13 +540,14 @@ bool setupPulsesInternalModule(uint8_t protocol)
|
||||||
{
|
{
|
||||||
bool result = intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE);
|
bool result = intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE);
|
||||||
if (moduleState[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleState[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER) {
|
if (moduleState[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleState[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER) {
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_TOOLS_PERIOD);
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_TOOLS_PERIOD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if defined(INTMODULE_HEARTBEAT)
|
#if defined(INTMODULE_HEARTBEAT)
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_PERIOD + 2 /* backup */);
|
mixerSchedulerResetTimer();
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD + 2000 /* backup */);
|
||||||
#else
|
#else
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_PERIOD);
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -463,23 +557,32 @@ bool setupPulsesInternalModule(uint8_t protocol)
|
||||||
#if defined(PCBTARANIS) && defined(INTERNAL_MODULE_PPM)
|
#if defined(PCBTARANIS) && defined(INTERNAL_MODULE_PPM)
|
||||||
case PROTOCOL_CHANNELS_PPM:
|
case PROTOCOL_CHANNELS_PPM:
|
||||||
setupPulsesPPMInternalModule();
|
setupPulsesPPMInternalModule();
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE));
|
// probably useless, as the interval did not change since "enable" function
|
||||||
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE));
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(INTERNAL_MODULE_MULTI)
|
#if defined(INTERNAL_MODULE_MULTI)
|
||||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||||
setupPulsesMultiInternalModule();
|
setupPulsesMultiInternalModule();
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, MULTIMODULE_PERIOD);
|
mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
scheduleNextMixerCalculation(INTERNAL_MODULE, 10 /* ms */); // used for USB sim for example
|
//mixerSchedulerSetPeriod(INTERNAL_MODULE, 10000 /*us*/); // used for USB sim for example
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopPulsesInternalModule()
|
||||||
|
{
|
||||||
|
if (moduleState[INTERNAL_MODULE].protocol != PROTOCOL_CHANNELS_UNINITIALIZED) {
|
||||||
|
intmoduleStop();
|
||||||
|
moduleState[INTERNAL_MODULE].protocol = PROTOCOL_CHANNELS_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool setupPulsesInternalModule()
|
bool setupPulsesInternalModule()
|
||||||
{
|
{
|
||||||
uint8_t protocol = getRequiredProtocol(INTERNAL_MODULE);
|
uint8_t protocol = getRequiredProtocol(INTERNAL_MODULE);
|
||||||
|
@ -498,6 +601,14 @@ bool setupPulsesInternalModule()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void stopPulsesExternalModule()
|
||||||
|
{
|
||||||
|
if (moduleState[EXTERNAL_MODULE].protocol != PROTOCOL_CHANNELS_UNINITIALIZED) {
|
||||||
|
extmoduleStop();
|
||||||
|
moduleState[EXTERNAL_MODULE].protocol = PROTOCOL_CHANNELS_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool setupPulsesExternalModule()
|
bool setupPulsesExternalModule()
|
||||||
{
|
{
|
||||||
uint8_t protocol = getRequiredProtocol(EXTERNAL_MODULE);
|
uint8_t protocol = getRequiredProtocol(EXTERNAL_MODULE);
|
||||||
|
|
|
@ -216,21 +216,20 @@ typedef Dsm2SerialPulsesData Dsm2PulsesData;
|
||||||
PACK(struct Dsm2TimerPulsesData {
|
PACK(struct Dsm2TimerPulsesData {
|
||||||
pulse_duration_t pulses[MAX_PULSES_TRANSITIONS];
|
pulse_duration_t pulses[MAX_PULSES_TRANSITIONS];
|
||||||
pulse_duration_t * ptr;
|
pulse_duration_t * ptr;
|
||||||
uint16_t rest;
|
|
||||||
uint8_t index;
|
uint8_t index;
|
||||||
});
|
});
|
||||||
typedef Dsm2TimerPulsesData Dsm2PulsesData;
|
typedef Dsm2TimerPulsesData Dsm2PulsesData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PPM_PERIOD_HALF_US(module) ((g_model.moduleData[module].ppm.frameLength * 5 + 225) * 200) /*half us*/
|
#define PPM_PERIOD_HALF_US(module) ((g_model.moduleData[module].ppm.frameLength * 5 + 225) * 200) /*half us*/
|
||||||
#define PPM_PERIOD(module) (PPM_PERIOD_HALF_US(module) / 2000) /*ms*/
|
#define PPM_PERIOD(module) (PPM_PERIOD_HALF_US(module) / 2) /*us*/
|
||||||
#define DSM2_BAUDRATE 125000
|
#define DSM2_BAUDRATE 125000
|
||||||
#define DSM2_PERIOD 22 /*ms*/
|
#define DSM2_PERIOD 22000 /*us*/
|
||||||
#define SBUS_BAUDRATE 100000
|
#define SBUS_BAUDRATE 100000
|
||||||
#define SBUS_PERIOD_HALF_US ((g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225) * 200) /*half us*/
|
#define SBUS_PERIOD_HALF_US ((g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225) * 200) /*half us*/
|
||||||
#define SBUS_PERIOD (SBUS_PERIOD_HALF_US / 2000) /*ms*/
|
#define SBUS_PERIOD (SBUS_PERIOD_HALF_US / 2) /*us*/
|
||||||
#define MULTIMODULE_BAUDRATE 100000
|
#define MULTIMODULE_BAUDRATE 100000
|
||||||
#define MULTIMODULE_PERIOD 7 /*ms*/
|
#define MULTIMODULE_PERIOD 7000 /*us*/
|
||||||
|
|
||||||
#define CROSSFIRE_FRAME_MAXLEN 64
|
#define CROSSFIRE_FRAME_MAXLEN 64
|
||||||
PACK(struct CrossfirePulsesData {
|
PACK(struct CrossfirePulsesData {
|
||||||
|
@ -315,8 +314,12 @@ extern TrainerPulsesData trainerPulsesData;
|
||||||
|
|
||||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||||
bool setupPulsesInternalModule();
|
bool setupPulsesInternalModule();
|
||||||
|
void stopPulsesInternalModule();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||||
bool setupPulsesExternalModule();
|
bool setupPulsesExternalModule();
|
||||||
|
void stopPulsesExternalModule();
|
||||||
|
#endif
|
||||||
void setupPulsesDSM2();
|
void setupPulsesDSM2();
|
||||||
void setupPulsesCrossfire();
|
void setupPulsesCrossfire();
|
||||||
void setupPulsesGhost();
|
void setupPulsesGhost();
|
||||||
|
@ -353,7 +356,9 @@ inline void startPulses()
|
||||||
setupPulsesInternalModule();
|
setupPulsesInternalModule();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||||
setupPulsesExternalModule();
|
setupPulsesExternalModule();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HARDWARE_EXTRA_MODULE)
|
#if defined(HARDWARE_EXTRA_MODULE)
|
||||||
extramodulePpmStart();
|
extramodulePpmStart();
|
||||||
|
|
|
@ -29,20 +29,20 @@
|
||||||
|
|
||||||
#define PXX2_LOWSPEED_BAUDRATE 230400
|
#define PXX2_LOWSPEED_BAUDRATE 230400
|
||||||
#define PXX2_HIGHSPEED_BAUDRATE 450000
|
#define PXX2_HIGHSPEED_BAUDRATE 450000
|
||||||
#define PXX2_PERIOD 4 // 4ms
|
#define PXX2_PERIOD 4000/*us*/
|
||||||
#define PXX2_TOOLS_PERIOD 1 // 1ms
|
#define PXX2_TOOLS_PERIOD 1000/*us*/
|
||||||
#define PXX2_FRAME_MAXLENGTH 64
|
#define PXX2_FRAME_MAXLENGTH 64
|
||||||
|
|
||||||
#define PXX_PULSES_PERIOD 9/*ms*/
|
#define PXX_PULSES_PERIOD 9000/*us*/
|
||||||
#define EXTMODULE_PXX1_SERIAL_PERIOD 4/*ms*/
|
#define EXTMODULE_PXX1_SERIAL_PERIOD 4000/*us*/
|
||||||
#define EXTMODULE_PXX1_SERIAL_BAUDRATE 420000
|
#define EXTMODULE_PXX1_SERIAL_BAUDRATE 420000
|
||||||
|
|
||||||
#if defined(PXX_FREQUENCY_HIGH)
|
#if defined(PXX_FREQUENCY_HIGH)
|
||||||
#define INTMODULE_PXX1_SERIAL_BAUDRATE 450000
|
#define INTMODULE_PXX1_SERIAL_BAUDRATE 450000
|
||||||
#define INTMODULE_PXX1_SERIAL_PERIOD 4/*ms*/
|
#define INTMODULE_PXX1_SERIAL_PERIOD 4000/*us*/
|
||||||
#else
|
#else
|
||||||
#define INTMODULE_PXX1_SERIAL_BAUDRATE 115200
|
#define INTMODULE_PXX1_SERIAL_BAUDRATE 115200
|
||||||
#define INTMODULE_PXX1_SERIAL_PERIOD 9/*ms*/
|
#define INTMODULE_PXX1_SERIAL_PERIOD 9000/*us*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Used by the Sky9x family boards
|
// Used by the Sky9x family boards
|
||||||
|
@ -108,7 +108,7 @@ class PwmPxxBitTransport: public PulsesBuffer<pulse_duration_t, 200> {
|
||||||
void addTail()
|
void addTail()
|
||||||
{
|
{
|
||||||
// rest min value is 18000 - 200 * 48 = 8400 (4.2ms)
|
// rest min value is 18000 - 200 * 48 = 8400 (4.2ms)
|
||||||
*(ptr - 1) += rest;
|
*(ptr - 1) = 60000;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ static void _send_level(uint8_t v)
|
||||||
|
|
||||||
*extmodulePulsesData.dsm2.ptr++ = v - 1;
|
*extmodulePulsesData.dsm2.ptr++ = v - 1;
|
||||||
extmodulePulsesData.dsm2.index+=1;
|
extmodulePulsesData.dsm2.index+=1;
|
||||||
extmodulePulsesData.dsm2.rest -=v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendByteSbus(uint8_t b) // max 11 changes 0 10 10 10 10 P 1
|
void sendByteSbus(uint8_t b) // max 11 changes 0 10 10 10 10 P 1
|
||||||
|
@ -113,7 +112,6 @@ void setupPulsesSbus()
|
||||||
extmodulePulsesData.dsm2.serialByte = 0;
|
extmodulePulsesData.dsm2.serialByte = 0;
|
||||||
extmodulePulsesData.dsm2.serialBitCount = 0;
|
extmodulePulsesData.dsm2.serialBitCount = 0;
|
||||||
#else
|
#else
|
||||||
extmodulePulsesData.dsm2.rest = SBUS_PERIOD_HALF_US;
|
|
||||||
extmodulePulsesData.dsm2.index = 0;
|
extmodulePulsesData.dsm2.index = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@ extern "C++" {
|
||||||
|
|
||||||
typedef pthread_t RTOS_TASK_HANDLE;
|
typedef pthread_t RTOS_TASK_HANDLE;
|
||||||
typedef pthread_mutex_t RTOS_MUTEX_HANDLE;
|
typedef pthread_mutex_t RTOS_MUTEX_HANDLE;
|
||||||
|
|
||||||
typedef uint32_t RTOS_FLAG_HANDLE;
|
typedef uint32_t RTOS_FLAG_HANDLE;
|
||||||
|
|
||||||
typedef sem_t * RTOS_EVENT_HANDLE;
|
typedef sem_t * RTOS_EVENT_HANDLE;
|
||||||
|
|
||||||
extern uint64_t simuTimerMicros(void);
|
extern uint64_t simuTimerMicros(void);
|
||||||
|
@ -76,16 +78,26 @@ extern "C++" {
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void RTOS_CREATE_FLAG(uint32_t &flag)
|
static inline void RTOS_CREATE_FLAG(RTOS_FLAG_HANDLE flag)
|
||||||
{
|
{
|
||||||
flag = 0; // TODO: real flags (use semaphores?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void RTOS_SET_FLAG(uint32_t &flag)
|
static inline void RTOS_SET_FLAG(RTOS_FLAG_HANDLE flag)
|
||||||
{
|
{
|
||||||
flag = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void RTOS_CLEAR_FLAG(RTOS_FLAG_HANDLE flag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool RTOS_WAIT_FLAG(RTOS_FLAG_HANDLE flag, uint32_t timeout)
|
||||||
|
{
|
||||||
|
simuSleep(timeout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RTOS_ISR_SET_FLAG RTOS_SET_FLAG
|
||||||
|
|
||||||
template<int SIZE>
|
template<int SIZE>
|
||||||
class FakeTaskStack
|
class FakeTaskStack
|
||||||
{
|
{
|
||||||
|
@ -146,6 +158,7 @@ template<int SIZE>
|
||||||
{
|
{
|
||||||
return (uint32_t)(simuTimerMicros() / 1000);
|
return (uint32_t)(simuTimerMicros() / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(RTOS_COOS)
|
#elif defined(RTOS_COOS)
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -155,7 +168,7 @@ template<int SIZE>
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RTOS_MS_PER_TICK ((CFG_CPU_FREQ / CFG_SYSTICK_FREQ) / (CFG_CPU_FREQ / 1000)) // RTOS timer tick length in ms (currently 2)
|
#define RTOS_MS_PER_TICK (1000 / CFG_SYSTICK_FREQ) // RTOS timer tick length in ms (currently 1 for STM32, 2 for others)
|
||||||
|
|
||||||
typedef OS_TID RTOS_TASK_HANDLE;
|
typedef OS_TID RTOS_TASK_HANDLE;
|
||||||
typedef OS_MutexID RTOS_MUTEX_HANDLE;
|
typedef OS_MutexID RTOS_MUTEX_HANDLE;
|
||||||
|
@ -230,7 +243,18 @@ template<int SIZE>
|
||||||
|
|
||||||
#define RTOS_CREATE_FLAG(flag) flag = CoCreateFlag(false, false)
|
#define RTOS_CREATE_FLAG(flag) flag = CoCreateFlag(false, false)
|
||||||
#define RTOS_SET_FLAG(flag) (void)CoSetFlag(flag)
|
#define RTOS_SET_FLAG(flag) (void)CoSetFlag(flag)
|
||||||
|
#define RTOS_CLEAR_FLAG(flag) (void)CoClearFlag(flag)
|
||||||
|
#define RTOS_WAIT_FLAG(flag,timeout) (CoWaitForSingleFlag(flag,timeout) == E_TIMEOUT)
|
||||||
|
|
||||||
|
static inline void RTOS_ISR_SET_FLAG(RTOS_FLAG_HANDLE flag)
|
||||||
|
{
|
||||||
|
CoEnterISR();
|
||||||
|
CoSchedLock();
|
||||||
|
isr_SetFlag(flag);
|
||||||
|
CoSchedUnlock();
|
||||||
|
CoExitISR();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
template<int SIZE>
|
template<int SIZE>
|
||||||
class TaskStack
|
class TaskStack
|
||||||
|
|
|
@ -53,11 +53,11 @@ void preModelLoad()
|
||||||
}
|
}
|
||||||
pauseMixerCalculations();
|
pauseMixerCalculations();
|
||||||
|
|
||||||
#if defined(INTMODULE_PWR_GPIO)
|
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||||
INTERNAL_MODULE_OFF();
|
stopPulsesInternalModule();
|
||||||
#endif
|
#endif
|
||||||
#if defined(EXTMODULE_PWR_GPIO)
|
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||||
EXTERNAL_MODULE_OFF();
|
stopPulsesExternalModule();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stopTrainer();
|
stopTrainer();
|
||||||
|
|
|
@ -148,7 +148,7 @@ endif()
|
||||||
|
|
||||||
if(MULTIMODULE)
|
if(MULTIMODULE)
|
||||||
add_definitions(-DMULTIMODULE)
|
add_definitions(-DMULTIMODULE)
|
||||||
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/mlink.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CROSSFIRE)
|
if(CROSSFIRE)
|
||||||
|
|
|
@ -124,7 +124,7 @@ void auxSerialInit(unsigned int mode, unsigned int protocol)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UART_MODE_SBUS_TRAINER:
|
case UART_MODE_SBUS_TRAINER:
|
||||||
auxSerialSetup(SBUS_BAUDRATE, true, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // 2 stop bits requires USART_WordLength_9b
|
auxSerialSetup(SBUS_BAUDRATE, true, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // USART_WordLength_9b due to parity bit
|
||||||
AUX_SERIAL_POWER_ON();
|
AUX_SERIAL_POWER_ON();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
|
#include "mixer_scheduler.h"
|
||||||
|
|
||||||
#if defined(INTMODULE_HEARTBEAT_GPIO)
|
#if defined(INTMODULE_HEARTBEAT_GPIO)
|
||||||
volatile HeartbeatCapture heartbeatCapture;
|
volatile HeartbeatCapture heartbeatCapture;
|
||||||
|
@ -77,6 +78,8 @@ void check_intmodule_heartbeat()
|
||||||
heartbeatCapture.count++;
|
heartbeatCapture.count++;
|
||||||
#endif
|
#endif
|
||||||
EXTI_ClearITPendingBit(INTMODULE_HEARTBEAT_EXTI_LINE);
|
EXTI_ClearITPendingBit(INTMODULE_HEARTBEAT_EXTI_LINE);
|
||||||
|
|
||||||
|
mixerSchedulerISRTrigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,12 +45,6 @@ void intmoduleStop()
|
||||||
USART_DeInit(INTMODULE_USART);
|
USART_DeInit(INTMODULE_USART);
|
||||||
|
|
||||||
GPIO_ResetBits(INTMODULE_GPIO, INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN);
|
GPIO_ResetBits(INTMODULE_GPIO, INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN);
|
||||||
|
|
||||||
#if defined(INTERNAL_MODULE_MULTI)
|
|
||||||
// stop pulses timer
|
|
||||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
|
||||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void intmodulePxx1SerialStart()
|
void intmodulePxx1SerialStart()
|
||||||
|
@ -103,28 +97,6 @@ void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERNAL_MODULE_MULTI)
|
|
||||||
void intmoduleTimerStart(uint32_t periodMs)
|
|
||||||
{
|
|
||||||
// Timer
|
|
||||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
|
||||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
|
||||||
INTMODULE_TIMER->ARR = periodMs * 2000;
|
|
||||||
INTMODULE_TIMER->CCR2 = (periodMs - 1) * 2000;
|
|
||||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
|
||||||
INTMODULE_TIMER->CCMR2 = 0;
|
|
||||||
INTMODULE_TIMER->EGR = 1; // Restart
|
|
||||||
|
|
||||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
|
||||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
|
||||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
|
||||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
|
||||||
|
|
||||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn);
|
|
||||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
|
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
|
||||||
extern "C" void INTMODULE_USART_IRQHandler(void)
|
extern "C" void INTMODULE_USART_IRQHandler(void)
|
||||||
{
|
{
|
||||||
|
@ -217,12 +189,3 @@ void intmoduleSendNextFrame()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERNAL_MODULE_MULTI)
|
|
||||||
extern "C" void INTMODULE_TIMER_IRQHandler()
|
|
||||||
{
|
|
||||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag
|
|
||||||
setupPulsesInternalModule();
|
|
||||||
intmoduleSendNextFrame();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opentx.h"
|
||||||
|
#include "mixer_scheduler.h"
|
||||||
|
|
||||||
|
#if !defined(SIMU)
|
||||||
|
|
||||||
|
// Start scheduler with default period
|
||||||
|
void mixerSchedulerStart()
|
||||||
|
{
|
||||||
|
MIXER_SCHEDULER_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||||
|
|
||||||
|
MIXER_SCHEDULER_TIMER->CR1 = TIM_CR1_URS; // do not generate interrupt on soft update
|
||||||
|
MIXER_SCHEDULER_TIMER->PSC = MIXER_SCHEDULER_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||||
|
MIXER_SCHEDULER_TIMER->CCER = 0;
|
||||||
|
MIXER_SCHEDULER_TIMER->CCMR1 = 0;
|
||||||
|
MIXER_SCHEDULER_TIMER->ARR = 2 * getMixerSchedulerPeriod() - 1;
|
||||||
|
MIXER_SCHEDULER_TIMER->EGR = TIM_EGR_UG; // reset timer
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(MIXER_SCHEDULER_TIMER_IRQn);
|
||||||
|
NVIC_SetPriority(MIXER_SCHEDULER_TIMER_IRQn, 8);
|
||||||
|
|
||||||
|
MIXER_SCHEDULER_TIMER->SR &= TIM_SR_UIF; // clear interrupt flag
|
||||||
|
MIXER_SCHEDULER_TIMER->DIER |= TIM_DIER_UIE; // enable interrupt
|
||||||
|
MIXER_SCHEDULER_TIMER->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerStop()
|
||||||
|
{
|
||||||
|
MIXER_SCHEDULER_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||||
|
NVIC_DisableIRQ(MIXER_SCHEDULER_TIMER_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerResetTimer()
|
||||||
|
{
|
||||||
|
mixerSchedulerDisableTrigger();
|
||||||
|
MIXER_SCHEDULER_TIMER->CNT = 0;
|
||||||
|
mixerSchedulerEnableTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerEnableTrigger()
|
||||||
|
{
|
||||||
|
MIXER_SCHEDULER_TIMER->DIER |= TIM_DIER_UIE; // enable interrupt
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixerSchedulerDisableTrigger()
|
||||||
|
{
|
||||||
|
MIXER_SCHEDULER_TIMER->DIER &= ~TIM_DIER_UIE; // disable interrupt
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void MIXER_SCHEDULER_TIMER_IRQHandler(void)
|
||||||
|
{
|
||||||
|
MIXER_SCHEDULER_TIMER->SR &= ~TIM_SR_UIF; // clear flag
|
||||||
|
mixerSchedulerDisableTrigger();
|
||||||
|
|
||||||
|
// set next period
|
||||||
|
MIXER_SCHEDULER_TIMER->ARR = 2 * getMixerSchedulerPeriod() - 1;
|
||||||
|
|
||||||
|
// trigger mixer start
|
||||||
|
mixerSchedulerISRTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1107,7 +1107,9 @@ OPTIMIZE("O0") SD_Error SD_WaitReadOperation(uint32_t timeout)
|
||||||
delay_ms(1);
|
delay_ms(1);
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
|
#if !defined(BOOT)
|
||||||
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_read, (TransferError << 8) + (DMAEndOfTransfer << 1) + TransferEnd);
|
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_read, (TransferError << 8) + (DMAEndOfTransfer << 1) + TransferEnd);
|
||||||
|
#endif
|
||||||
|
|
||||||
DMAEndOfTransfer = 0;
|
DMAEndOfTransfer = 0;
|
||||||
|
|
||||||
|
@ -1117,7 +1119,9 @@ OPTIMIZE("O0") SD_Error SD_WaitReadOperation(uint32_t timeout)
|
||||||
delay_ms(1);
|
delay_ms(1);
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
|
#if !defined(BOOT)
|
||||||
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_read, -1);
|
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_read, -1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (StopCondition == 1) {
|
if (StopCondition == 1) {
|
||||||
errorstatus = SD_StopTransfer();
|
errorstatus = SD_StopTransfer();
|
||||||
|
@ -1332,8 +1336,10 @@ OPTIMIZE("O0") SD_Error SD_WaitWriteOperation(uint32_t timeout)
|
||||||
delay_ms(1);
|
delay_ms(1);
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
|
#if !defined(BOOT)
|
||||||
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_write, (TransferError << 8) + (DMAEndOfTransfer << 1) + TransferEnd);
|
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_write, (TransferError << 8) + (DMAEndOfTransfer << 1) + TransferEnd);
|
||||||
|
#endif
|
||||||
|
|
||||||
DMAEndOfTransfer = 0;
|
DMAEndOfTransfer = 0;
|
||||||
|
|
||||||
timeout = 100;
|
timeout = 100;
|
||||||
|
@ -1342,7 +1348,9 @@ OPTIMIZE("O0") SD_Error SD_WaitWriteOperation(uint32_t timeout)
|
||||||
delay_ms(1);
|
delay_ms(1);
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
|
#if !defined(BOOT)
|
||||||
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_write, -1);
|
TRACE_SD_CARD_EVENT((timeout == 0), sd_wait_write, -1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (StopCondition == 1) {
|
if (StopCondition == 1) {
|
||||||
errorstatus = SD_StopTransfer();
|
errorstatus = SD_StopTransfer();
|
||||||
|
@ -1474,7 +1482,9 @@ OPTIMIZE("O0") void SD_ProcessIRQ(void)
|
||||||
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
|
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
|
||||||
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
|
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
|
||||||
|
|
||||||
|
#if !defined(BOOT)
|
||||||
TRACE_SD_CARD_EVENT((TransferError != SD_OK), sd_irq, TransferError);
|
TRACE_SD_CARD_EVENT((TransferError != SD_OK), sd_irq, TransferError);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -246,6 +246,7 @@ set(TARGET_SRC
|
||||||
led_driver.cpp
|
led_driver.cpp
|
||||||
extmodule_driver.cpp
|
extmodule_driver.cpp
|
||||||
trainer_driver.cpp
|
trainer_driver.cpp
|
||||||
|
../common/arm/stm32/mixer_scheduler_driver.cpp
|
||||||
../common/arm/stm32/heartbeat_driver.cpp
|
../common/arm/stm32/heartbeat_driver.cpp
|
||||||
../common/arm/stm32/timers_driver.cpp
|
../common/arm/stm32/timers_driver.cpp
|
||||||
../common/arm/stm32/intmodule_serial_driver.cpp
|
../common/arm/stm32/intmodule_serial_driver.cpp
|
||||||
|
|
|
@ -137,6 +137,7 @@ void boardInit()
|
||||||
INTMODULE_RCC_APB1Periph |
|
INTMODULE_RCC_APB1Periph |
|
||||||
EXTMODULE_RCC_APB1Periph |
|
EXTMODULE_RCC_APB1Periph |
|
||||||
I2C_RCC_APB1Periph |
|
I2C_RCC_APB1Periph |
|
||||||
|
MIXER_SCHEDULER_TIMER_RCC_APB1Periph |
|
||||||
GPS_RCC_APB1Periph |
|
GPS_RCC_APB1Periph |
|
||||||
BACKLIGHT_RCC_APB1Periph,
|
BACKLIGHT_RCC_APB1Periph,
|
||||||
ENABLE);
|
ENABLE);
|
||||||
|
|
|
@ -180,14 +180,11 @@ void init_intmodule_heartbeat();
|
||||||
void check_intmodule_heartbeat();
|
void check_intmodule_heartbeat();
|
||||||
|
|
||||||
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength);
|
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength);
|
||||||
#if defined(INTERNAL_MODULE_MULTI)
|
|
||||||
void intmoduleTimerStart(uint32_t periodMs);
|
|
||||||
#endif
|
|
||||||
void intmoduleSendByte(uint8_t byte);
|
void intmoduleSendByte(uint8_t byte);
|
||||||
void intmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
void intmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||||
void intmoduleSendNextFrame();
|
void intmoduleSendNextFrame();
|
||||||
|
|
||||||
void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted);
|
void extmoduleSerialStart();
|
||||||
void extmoduleInvertedSerialStart(uint32_t baudrate);
|
void extmoduleInvertedSerialStart(uint32_t baudrate);
|
||||||
void extmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
void extmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||||
void extmoduleSendNextFrame();
|
void extmoduleSendNextFrame();
|
||||||
|
@ -381,7 +378,7 @@ enum Analogs {
|
||||||
SLIDER_LAST = SLIDER_FIRST + NUM_SLIDERS - 1,
|
SLIDER_LAST = SLIDER_FIRST + NUM_SLIDERS - 1,
|
||||||
TX_VOLTAGE,
|
TX_VOLTAGE,
|
||||||
#if defined(PCBX12S)
|
#if defined(PCBX12S)
|
||||||
MOUSE1, // TODO why after voltage?
|
MOUSE1, // after voltage because previous ones come from SPI on X12S
|
||||||
MOUSE2,
|
MOUSE2,
|
||||||
#endif
|
#endif
|
||||||
NUM_ANALOGS
|
NUM_ANALOGS
|
||||||
|
|
|
@ -143,7 +143,7 @@ void extmodulePxx1PulsesStart()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool inverted)
|
void extmoduleSerialStart()
|
||||||
{
|
{
|
||||||
EXTERNAL_MODULE_ON();
|
EXTERNAL_MODULE_ON();
|
||||||
|
|
||||||
|
@ -176,10 +176,9 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool i
|
||||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
|
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTMODULE_TIMER->ARR = period_half_us;
|
EXTMODULE_TIMER->ARR = 40000; // dummy value until the DMA request kicks in
|
||||||
EXTMODULE_TIMER->CCR2 = period_half_us - 4000;
|
|
||||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE;
|
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE;
|
||||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||||
|
|
||||||
NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn);
|
NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn);
|
||||||
|
@ -342,23 +341,36 @@ void extmoduleSendNextFrame()
|
||||||
|
|
||||||
#if defined(DSM2)
|
#if defined(DSM2)
|
||||||
case PROTOCOL_CHANNELS_SBUS:
|
case PROTOCOL_CHANNELS_SBUS:
|
||||||
#if defined(PCBX10) || PCBREV >= 13
|
|
||||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed
|
|
||||||
#else
|
|
||||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed
|
|
||||||
#endif
|
|
||||||
// no break
|
|
||||||
case PROTOCOL_CHANNELS_DSM2_LP45:
|
case PROTOCOL_CHANNELS_DSM2_LP45:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
case PROTOCOL_CHANNELS_DSM2_DSM2:
|
||||||
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
case PROTOCOL_CHANNELS_DSM2_DSMX:
|
||||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||||
EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance
|
|
||||||
|
if (EXTMODULE_TIMER_DMA_STREAM->CR & DMA_SxCR_EN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PROTOCOL_CHANNELS_SBUS == moduleState[EXTERNAL_MODULE].protocol) {
|
||||||
|
#if defined(PCBX10) || PCBREV >= 13
|
||||||
|
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed
|
||||||
|
#else
|
||||||
|
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable timer
|
||||||
|
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||||
|
|
||||||
|
// send DMA request
|
||||||
EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||||
EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||||
EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||||
EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses);
|
EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses);
|
||||||
EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses;
|
EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses;
|
||||||
EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||||
|
|
||||||
|
// re-init timer
|
||||||
|
EXTMODULE_TIMER->EGR = 1;
|
||||||
|
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -419,14 +431,20 @@ extern "C" void EXTMODULE_TIMER_DMA_IRQHandler()
|
||||||
|
|
||||||
DMA_ClearITPendingBit(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC);
|
DMA_ClearITPendingBit(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC);
|
||||||
|
|
||||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
switch (moduleState[EXTERNAL_MODULE].protocol) {
|
||||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
case PROTOCOL_CHANNELS_PXX1_PULSES:
|
||||||
|
case PROTOCOL_CHANNELS_PPM:
|
||||||
|
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||||
|
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void EXTMODULE_TIMER_IRQHandler()
|
extern "C" void EXTMODULE_TIMER_IRQHandler()
|
||||||
{
|
{
|
||||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt
|
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt
|
||||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||||
|
|
||||||
if (setupPulsesExternalModule())
|
if (setupPulsesExternalModule())
|
||||||
extmoduleSendNextFrame();
|
extmoduleSendNextFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,9 +420,9 @@
|
||||||
#define AUX_SERIAL_USART_IRQn USART3_IRQn
|
#define AUX_SERIAL_USART_IRQn USART3_IRQn
|
||||||
#define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1
|
#define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1
|
||||||
#define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4
|
#define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4
|
||||||
#define AUX_SERIAL_PWR_GPIO GPIOA
|
|
||||||
#define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PB.00
|
|
||||||
#if defined(RADIO_TX16S)
|
#if defined(RADIO_TX16S)
|
||||||
|
#define AUX_SERIAL_PWR_GPIO GPIOA
|
||||||
|
#define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PA.15
|
||||||
#define TRAINER_BATTERY_COMPARTMENT // allows serial port TTL trainer
|
#define TRAINER_BATTERY_COMPARTMENT // allows serial port TTL trainer
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -905,6 +905,13 @@
|
||||||
#define TIMER_2MHz_RCC_APB1Periph RCC_APB1Periph_TIM7
|
#define TIMER_2MHz_RCC_APB1Periph RCC_APB1Periph_TIM7
|
||||||
#define TIMER_2MHz_TIMER TIM7
|
#define TIMER_2MHz_TIMER TIM7
|
||||||
|
|
||||||
|
// Mixer scheduler timer
|
||||||
|
#define MIXER_SCHEDULER_TIMER_RCC_APB1Periph RCC_APB1Periph_TIM13
|
||||||
|
#define MIXER_SCHEDULER_TIMER TIM13
|
||||||
|
#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||||
|
#define MIXER_SCHEDULER_TIMER_IRQn TIM8_UP_TIM13_IRQn
|
||||||
|
#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_UP_TIM13_IRQHandler
|
||||||
|
|
||||||
// Bluetooth
|
// Bluetooth
|
||||||
#define STORAGE_BLUETOOTH
|
#define STORAGE_BLUETOOTH
|
||||||
#if defined(BLUETOOTH)
|
#if defined(BLUETOOTH)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue