Merge pull request #6626 from opentx/raphaelcoeffic/companion-access

Companion ACCESS support
This commit is contained in:
Bertrand Songis
2019-08-22 11:55:01 +02:00
committed by GitHub
20 changed files with 1112 additions and 453 deletions
+2 -4
View File
@@ -333,14 +333,12 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
return 8;
else if (IS_JUMPER_T12(board))
return 6;
else if (IS_TARANIS_XLITES(board))
return 6;
else if (IS_TARANIS_XLITE(board))
return 6;
else if (IS_TARANIS(board))
return 8;
else if (board == Board::BOARD_TARANIS_X9DP_2019)
return 9;
else if (IS_TARANIS(board))
return 8;
else if (IS_HORUS(board))
return 10;
else
@@ -585,6 +585,78 @@ class TransformedField: public DataField {
DataField & field;
};
template<class selectorT>
class UnionField: public DataField {
public:
class UnionMember {
public:
virtual ~UnionMember() {}
virtual bool select(const selectorT& attr) const = 0;
virtual DataField* getField() = 0;
};
class TransformedMember: public UnionMember, public TransformedField {
public:
TransformedMember(DataField* parent, DataField& field):
TransformedField(parent, field)
{
}
virtual DataField* getField()
{
return this;
}
};
UnionField(DataField * parent, selectorT& selectField, const char * name="Union"):
DataField(parent, name), selectField(selectField), maxSize(0)
{
}
~UnionField() {
foreach(UnionMember *member, members) {
delete member;
}
}
inline void Append(UnionMember * member) {
members.append(member);
if (member->getField()->size() > maxSize)
maxSize = member->getField()->size();
}
virtual void ExportBits(QBitArray & output)
{
foreach(UnionMember *member, members) {
if (member->select(selectField)) {
member->getField()->ExportBits(output);
break;
}
}
output.resize(maxSize);
}
virtual void ImportBits(const QBitArray & input)
{
foreach(UnionMember *member, members) {
if (member->select(selectField)) {
member->getField()->ImportBits(input);
break;
}
}
}
virtual unsigned int size()
{
return maxSize;
}
protected:
selectorT& selectField;
QList<UnionMember *> members;
unsigned int maxSize;
};
class ConversionTable {
public:
+18 -2
View File
@@ -30,6 +30,20 @@ void ModuleData::convert(RadioDataConversionState & cstate)
}
}
bool ModuleData::isPxx2Module() const
{
switch(protocol){
case PULSES_ACCESS_ISRM:
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
case PULSES_XJT_LITE_X16:
return true;
default:
return false;
}
}
QString ModuleData::rfProtocolToString() const
{
switch (protocol) {
@@ -105,11 +119,13 @@ QString ModuleData::protocolToString(unsigned protocol)
"DIY Multiprotocol Module",
"FrSky PXX R9M",
"FrSky PXX R9M Lite",
"FrSky PXX R9M Lite Pro",
"SBUS output at VBat",
"FrSky ACCESS ISRM",
"FrSky ACCESS ISRM", "FrSky ACCST ISRM D16",
"FrSky ACCESS R9M",
"FrSky ACCESS R9M Lite",
"FrSky ACCESS R9M Lite Pro"
"FrSky ACCESS R9M Lite Pro",
"FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)"
};
return CHECK_IN_ARRAY(strings, protocol);
+19 -9
View File
@@ -48,11 +48,16 @@ enum PulsesProtocol {
PULSES_MULTIMODULE,
PULSES_PXX_R9M,
PULSES_PXX_R9M_LITE,
PULSES_PXX_R9M_LITE_PRO,
PULSES_SBUS,
PULSES_ACCESS_ISRM,
PULSES_ACCST_ISRM_D16,
PULSES_ACCESS_R9M,
PULSES_ACCESS_R9M_LITE,
PULSES_ACCESS_R9M_LITE_PRO,
PULSES_XJT_LITE_X16,
PULSES_XJT_LITE_D8,
PULSES_XJT_LITE_LR12,
PULSES_PROTOCOL_LAST
};
@@ -128,13 +133,18 @@ enum ModuleSubtypeR9M {
MODULE_SUBTYPE_R9M_LAST=MODULE_SUBTYPE_R9M_AUPLUS
};
constexpr int PXX2_MAX_RECEIVERS_PER_MODULE = 3;
constexpr int PXX2_LEN_RX_NAME = 8;
class ModuleData {
Q_DECLARE_TR_FUNCTIONS(ModuleData)
public:
ModuleData() { clear(); }
unsigned int modelId;
int protocol;
unsigned int protocol; // type in datastructs.h
int rfProtocol; // rfProtocol in datastructs.h
unsigned int subType;
bool invertedSerial;
unsigned int channelsStart;
@@ -142,14 +152,14 @@ class ModuleData {
unsigned int failsafeMode;
int failsafeChannels[CPN_MAX_CHNOUT];
struct {
struct PPM {
int delay;
bool pulsePol; // false = positive
bool outputType; // false = open drain, true = push pull
int frameLength;
} ppm;
struct {
struct Multi {
unsigned int rfProtocol;
bool autoBindMode;
bool lowPowerMode;
@@ -157,22 +167,22 @@ class ModuleData {
int optionValue;
} multi;
struct {
int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
struct PXX {
unsigned int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
bool receiver_telem_off; // false = receiver telem enabled
bool receiver_channel_9_16; // false = pwm out 1-8, true 9-16
bool external_antenna; // false = internal antenna, true = external antenna
bool sport_out;
} pxx;
struct {
// unsigned int receivers;
// char receiverName[3][8];
char data[1 + 3 * 8];
struct Access {
unsigned int receivers;
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1];
} access;
void clear() { memset(this, 0, sizeof(ModuleData)); }
void convert(RadioDataConversionState & cstate);
bool isPxx2Module() const;
QString polarityToString() const { return ppm.pulsePol ? tr("Positive") : tr("Negative"); }
QString rfProtocolToString() const;
QString subTypeToString(int type = -1) const;
+245 -87
View File
@@ -1868,7 +1868,8 @@ class SensorField: public TransformedField {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) {
_id = sensor.id;
_subid = sensor.subid;
_instance = sensor.instance;
// keep highest 3 bits from instance (rxIdx & moduleIdx are read-only)
_instance = (sensor.instance & 0x1F) | (_instance & 0xE0);
_ratio = sensor.ratio;
_offset = sensor.offset;
}
@@ -1891,7 +1892,9 @@ class SensorField: public TransformedField {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) {
sensor.id = _id;
sensor.subid = _subid;
sensor.instance = _instance;
sensor.instance = _instance & 0x1F; // 5 bits instance
sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx
sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx
sensor.ratio = _ratio;
sensor.offset = _offset;
}
@@ -1939,14 +1942,238 @@ class SensorField: public TransformedField {
int exportPpmDelay(int delay) { return (delay - 300) / 50; }
int importPpmDelay(int delay) { return 300 + 50 * delay; }
class ModuleUnionField: public UnionField<unsigned int> {
class PPMField: public UnionField::UnionMember, public StructField {
public:
PPMField(DataField * parent, ModuleData::PPM& ppm):
StructField(parent, "PPM")
{
Append(new ConversionField< SignedField<6> >(parent, ppm.delay, exportPpmDelay, importPpmDelay));
Append(new BoolField<1>(parent, ppm.pulsePol));
Append(new BoolField<1>(parent, ppm.outputType));
Append(new SignedField<8>(parent, ppm.frameLength));
}
virtual bool select(const unsigned int& attr) const
{
return true; // take what's left
}
virtual DataField* getField()
{
return this;
}
};
class MultiField: public UnionField::TransformedMember {
public:
MultiField(DataField * parent, ModuleData& module):
UnionField::TransformedMember(parent, internalField),
internalField(this, "Multi"),
module(module),
rfProtExtra(0)
{
ModuleData::Multi& multi = module.multi;
internalField.Append(new UnsignedField<2>(this, rfProtExtra));
internalField.Append(new SpareBitsField<3>(this));
internalField.Append(new BoolField<1>(this, multi.autoBindMode));
internalField.Append(new BoolField<1>(this, multi.lowPowerMode));
internalField.Append(new BoolField<1>(this, multi.customProto));
internalField.Append(new SignedField<8>(this, multi.optionValue));
}
virtual bool select(const unsigned int& attr) const
{
return attr==PULSES_MULTIMODULE;
}
virtual void beforeExport()
{
module.rfProtocol = module.multi.rfProtocol & 0xf;
rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03;
}
virtual void afterImport()
{
module.multi.rfProtocol =
(rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf);
}
private:
StructField internalField;
ModuleData& module;
unsigned int rfProtExtra;
};
class PxxField: public UnionField::TransformedMember {
public:
PxxField(DataField * parent, ModuleData& module):
UnionField::TransformedMember(parent, internalField),
internalField(this, "Pxx"),
module(module)
{
ModuleData::PXX& pxx = module.pxx;
internalField.Append(new UnsignedField<2>(this, pxx.power));
internalField.Append(new SpareBitsField<2>(this));
internalField.Append(new BoolField<1>(this, pxx.receiver_telem_off));
internalField.Append(new BoolField<1>(this, pxx.receiver_channel_9_16));
internalField.Append(new BoolField<1>(this, pxx.external_antenna));
internalField.Append(new BoolField<1>(this, pxx.sport_out));
}
bool select(const unsigned int& attr) const {
return attr==PULSES_PXX_XJT_X16 ||
attr==PULSES_PXX_DJT ||
attr==PULSES_PXX_R9M ||
attr==PULSES_PXX_R9M_LITE;
}
virtual void beforeExport()
{
if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) {
module.subType = module.protocol - PULSES_PXX_XJT_X16;
}
}
virtual void afterImport()
{
if (module.protocol == PULSES_PXX_XJT_X16) {
module.protocol += module.subType;
}
}
private:
StructField internalField;
ModuleData& module;
};
class AccessField: public UnionField::TransformedMember {
public:
AccessField(DataField * parent, ModuleData& module):
UnionField::TransformedMember(parent, internalField),
internalField(this, "Access"),
module(module)
{
internalField.Append(new UnsignedField<3>(this, module.access.receivers));
internalField.Append(new SpareBitsField<5>(this));
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++)
internalField.Append(new CharField<8>(this, receiverName[i]));
}
bool select(const unsigned int& attr) const {
return attr >= PULSES_ACCESS_ISRM && attr <= PULSES_ACCESS_R9M_LITE_PRO;
}
virtual void beforeExport()
{
if (module.protocol == PULSES_ACCST_ISRM_D16 ||
module.protocol == PULSES_ACCESS_ISRM) {
module.subType = module.protocol - PULSES_ACCESS_ISRM;
}
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++) {
for (int pos=0; pos<PXX2_LEN_RX_NAME+1; pos++) {
if (pos == PXX2_LEN_RX_NAME
|| module.access.receiverName[i][pos] == '\0') {
memset(module.access.receiverName[i]+pos,'\0',PXX2_LEN_RX_NAME-pos);
break;
}
receiverName[i][pos] = module.access.receiverName[i][pos];
}
}
}
virtual void afterImport()
{
if (module.protocol == PULSES_ACCESS_ISRM) {
module.protocol += module.subType;
}
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++) {
for (int pos=0; pos<PXX2_LEN_RX_NAME+1; pos++) {
if (pos == PXX2_LEN_RX_NAME || receiverName[i][pos] == ' '
|| receiverName[i][pos] == '\0') {
module.access.receiverName[i][pos] = '\0';
break;
}
module.access.receiverName[i][pos] = receiverName[i][pos];
}
}
}
private:
StructField internalField;
ModuleData& module;
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1];
};
public:
ModuleUnionField(DataField * parent, ModuleData & module):
UnionField<unsigned int>(parent, module.protocol)
{
Append(new AccessField(parent, module));
Append(new PxxField(parent, module));
Append(new MultiField(parent, module));
Append(new PPMField(parent, module.ppm));
}
};
class ModuleField: public TransformedField {
public:
ModuleField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version):
TransformedField(parent, internalField),
internalField(this, "Module"),
module(module),
protocolsConversionTable(board)
{
internalField.Append(new ConversionField<UnsignedField<4> >(this, module.protocol, &protocolsConversionTable, "Protocol", DataField::tr("OpenTX doesn't accept this radio protocol")));
internalField.Append(new SignedField<4>(this, module.rfProtocol));
internalField.Append(new UnsignedField<8>(this, module.channelsStart));
internalField.Append(new ConversionField<SignedField<8> >(this, module.channelsCount, -8));
internalField.Append(new UnsignedField<4>(this, module.failsafeMode));
internalField.Append(new UnsignedField<3>(this, module.subType));
internalField.Append(new BoolField<1>(this, module.invertedSerial));
if (version <= 218) {
for (int i=0; i<32; i++) {
internalField.Append(new SignedField<16>(this, module.failsafeChannels[i]));
}
}
internalField.Append(new ModuleUnionField(parent, module));
}
virtual void beforeExport()
{
if (module.protocol >= PULSES_LP45 && module.protocol <= PULSES_DSMX) {
module.rfProtocol = module.protocol - PULSES_LP45;
}
}
virtual void afterImport()
{
if (module.protocol == PULSES_LP45) {
module.protocol += module.rfProtocol;
}
}
private:
StructField internalField;
ModuleData& module;
ProtocolsConversionTable protocolsConversionTable;
};
OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsigned int version, unsigned int variant):
TransformedField(nullptr, internalField),
internalField(this, "ModelData"),
modelData(modelData),
board(board),
version(version),
variant(variant),
protocolsConversionTable(board)
variant(variant)
{
sprintf(name, "Model %s", modelData.name);
@@ -2094,26 +2321,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
int modulesCount = (version <= 218 ? 3 : 2);
for (int module=0; module<modulesCount; module++) {
internalField.Append(new ConversionField<SignedField<4> >(this, modelData.moduleData[module].protocol, &protocolsConversionTable, "Protocol", DataField::tr("OpenTX doesn't accept this radio protocol")));
internalField.Append(new SignedField<4>(this, subprotocols[module]));
internalField.Append(new UnsignedField<8>(this, modelData.moduleData[module].channelsStart));
internalField.Append(new ConversionField<SignedField<8> >(this, modelData.moduleData[module].channelsCount, -8));
internalField.Append(new UnsignedField<4>(this, modelData.moduleData[module].failsafeMode));
internalField.Append(new UnsignedField<3>(this, modelData.moduleData[module].subType));
internalField.Append(new BoolField<1>(this, modelData.moduleData[module].invertedSerial));
if (version <= 218) {
for (int i=0; i<32; i++) {
internalField.Append(new SignedField<16>(this, modelData.moduleData[module].failsafeChannels[i]));
}
}
internalField.Append(new ConversionField< SignedField<6> >(this, modelData.moduleData[module].ppm.delay, exportPpmDelay, importPpmDelay));
internalField.Append(new BoolField<1>(this, modelData.moduleData[module].ppm.pulsePol));
internalField.Append(new BoolField<1>(this, modelData.moduleData[module].ppm.outputType));
internalField.Append(new SignedField<8>(this, modelData.moduleData[module].ppm.frameLength));
if (version >= 219) {
// TODO ACCESS
internalField.Append(new CharField<1 + 3 * 8 - 2>(this, modelData.moduleData[module].access.data));
}
internalField.Append(new ModuleField(this, modelData.moduleData[module], board, version));
}
if (version >= 219) {
@@ -2221,35 +2430,6 @@ void OpenTxModelData::beforeExport()
// qDebug() << QString("before export model") << modelData.name;
for (int module=0; module<2; module++) {
if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) ||
modelData.moduleData[module].protocol == PULSES_PXX_R9M) {
if (modelData.moduleData[module].protocol != PULSES_PXX_R9M) {
subprotocols[module] = modelData.moduleData[module].protocol - PULSES_PXX_XJT_X16;
}
int pxxByte = (modelData.moduleData[module].pxx.power & 0x03)
| modelData.moduleData[module].pxx.receiver_telem_off << 4
| modelData.moduleData[module].pxx.receiver_channel_9_16 << 5;
modelData.moduleData[module].ppm.delay = 300 + 50 * pxxByte;
modelData.moduleData[module].ppm.pulsePol = modelData.moduleData[module].pxx.external_antenna;
modelData.moduleData[module].ppm.outputType = modelData.moduleData[module].pxx.sport_out;
}
else if (modelData.moduleData[module].protocol >= PULSES_LP45 && modelData.moduleData[module].protocol <= PULSES_DSMX) {
subprotocols[module] = modelData.moduleData[module].protocol - PULSES_LP45;
}
else if (modelData.moduleData[module].protocol == PULSES_MULTIMODULE) {
// copy multi settings to ppm settings to get them written to the eeprom
// (reverse the int => ms logic of the ppm delay) since only ppm is written
subprotocols[module] = modelData.moduleData[module].multi.rfProtocol & (0x1f);
int multiByte = ((modelData.moduleData[module].multi.rfProtocol >> 4) & 0x03) | (modelData.moduleData[module].multi.customProto << 7);
modelData.moduleData[module].ppm.delay = 300 + 50 * multiByte;
modelData.moduleData[module].ppm.frameLength = modelData.moduleData[module].multi.optionValue;
modelData.moduleData[module].ppm.outputType = modelData.moduleData[module].multi.lowPowerMode;
modelData.moduleData[module].ppm.pulsePol = modelData.moduleData[module].multi.autoBindMode;
}
else {
subprotocols[module] = (module == 0 ? -1 : 0);
}
}
if (IS_HORUS(board)) {
@@ -2268,39 +2448,11 @@ void OpenTxModelData::afterImport()
{
qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name;
// ??? what's this ???
if (IS_HORUS(board)) {
modelData.moduleData[0].protocol = PULSES_PXX_XJT_X16;
}
for (int module=0; module<2; module++) {
if (modelData.moduleData[module].protocol == PULSES_PXX_XJT_X16 || modelData.moduleData[module].protocol == PULSES_LP45) {
if (subprotocols[module] >= 0)
modelData.moduleData[module].protocol += subprotocols[module];
else
modelData.moduleData[module].protocol = PULSES_OFF;
}
else if (modelData.moduleData[module].protocol == PULSES_MULTIMODULE) {
// Copy data from ppm struct to multi struct
auto multiByte = (unsigned int)((modelData.moduleData[module].ppm.delay - 300) / 50);
modelData.moduleData[module].multi.rfProtocol = (subprotocols[module] & 0x0f) | ((multiByte & 0x3) << 4);
modelData.moduleData[module].multi.customProto = (multiByte & 0x80) == 0x80;
modelData.moduleData[module].multi.optionValue = modelData.moduleData[module].ppm.frameLength;
modelData.moduleData[module].multi.lowPowerMode = modelData.moduleData[module].ppm.outputType;
modelData.moduleData[module].multi.autoBindMode = modelData.moduleData[module].ppm.pulsePol;
}
if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) ||
modelData.moduleData[module].protocol == PULSES_PXX_R9M) {
// Do the same for pxx
auto pxxByte = (unsigned int)((modelData.moduleData[module].ppm.delay - 300) / 50);
modelData.moduleData[module].pxx.power = pxxByte & 0x03;
modelData.moduleData[module].pxx.receiver_telem_off = static_cast<bool>(pxxByte & (1 << 4));
modelData.moduleData[module].pxx.receiver_channel_9_16 = static_cast<bool>(pxxByte & (1 << 5));
modelData.moduleData[module].pxx.sport_out = modelData.moduleData[module].ppm.outputType;
modelData.moduleData[module].pxx.external_antenna = modelData.moduleData[module].ppm.pulsePol;
}
}
if (IS_HORUS(board)) {
uint32_t newSwitchWarningStates = 0;
for (int i = 0; i < MAX_SWITCHES(board, version); i++) {
@@ -2472,13 +2624,17 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new ArmCustomFunctionField(this, generalData.customFn[i], board, version, variant));
}
}
if (IS_STM32(board)) {
if (version >= 218) {
internalField.Append(new UnsignedField<4>(this, generalData.hw_uartMode));
// not on Horus...
for (uint8_t i=0; i<4; i++) {
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
if (!IS_HORUS(board)) {
for (uint8_t i=0; i<4; i++) {
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
}
}
else {
internalField.Append(new SpareBitsField<4>(this));
}
}
else {
@@ -2536,6 +2692,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
if (IS_TARANIS_X9E(board))
internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates
else if (IS_TARANIS_X9D(board))
internalField.Append(new SpareBitsField<32>(this)); // switchUnlockStates
else if (IS_TARANIS(board))
internalField.Append(new SpareBitsField<16>(this)); // switchUnlockStates
@@ -2590,7 +2748,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new UnsignedField<7>(this, generalData.backlightOffBright));
internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name"));
}
else if (IS_TARANIS_X9E(board) || (version >= 219 && (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_XLITES(board)))) {
else if (IS_TARANIS_X9E(board) || (version >= 219 && (IS_TARANIS_X7(board) || IS_TARANIS_X9D(board) || IS_TARANIS_XLITE(board)))) {
internalField.Append(new SpareBitsField<8>(this));
internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name"));
}
@@ -83,7 +83,8 @@ class ProtocolsConversionTable: public ConversionTable
addConversion(PULSES_PXX_XJT_D8, val);
addConversion(PULSES_PXX_XJT_LR12, val++);
addConversion(PULSES_ACCESS_ISRM, val++);
addConversion(PULSES_ACCESS_ISRM, val);
addConversion(PULSES_ACCST_ISRM_D16, val++);
addConversion(PULSES_LP45, val);
addConversion(PULSES_DSM2, val);
@@ -96,9 +97,14 @@ class ProtocolsConversionTable: public ConversionTable
addConversion(PULSES_ACCESS_R9M, val++);
addConversion(PULSES_PXX_R9M_LITE, val++);
addConversion(PULSES_ACCESS_R9M_LITE, val++);
addConversion(PULSES_PXX_R9M_LITE_PRO, val++);
addConversion(PULSES_ACCESS_R9M_LITE_PRO, val++);
addConversion(PULSES_SBUS, val++);
addConversion(PULSES_XJT_LITE_X16, val);
addConversion(PULSES_XJT_LITE_D8, val);
addConversion(PULSES_XJT_LITE_LR12, val++);
}
};
@@ -141,7 +147,6 @@ class OpenTxModelData: public TransformedField {
unsigned int variant;
char name[256];
int subprotocols[CPN_MAX_MODULES+1/*trainer*/];
ProtocolsConversionTable protocolsConversionTable;
ChannelsConversionTable channelsConversionTable;
QStringList _errors;
};
@@ -772,11 +772,12 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_PPM:
return id.contains("internalppm") ? 1 : 0;
case PULSES_ACCESS_ISRM:
case PULSES_ACCST_ISRM_D16:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0;
default:
return 0;
}
case 1:
switch (proto) {
case PULSES_OFF:
@@ -802,6 +803,10 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0;
case PULSES_XJT_LITE_X16:
case PULSES_XJT_LITE_D8:
case PULSES_XJT_LITE_LR12:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0;
default:
return 0;
}
+23
View File
@@ -21,6 +21,7 @@
#include "sensordata.h"
#include "radiodata.h"
#include "modeldata.h"
void SensorData::updateUnit()
{
@@ -90,3 +91,25 @@ QString SensorData::nameToString(int index) const
{
return RadioData::getElementName(tr("TELE"), index + 1, label);
}
QString SensorData::getRxOrModName(const ModelData* model) const
{
if ((type != TELEM_TYPE_CUSTOM) || (!id && !instance))
return QString();
const ModuleData& module = model->moduleData[moduleIdx];
if (module.isPxx2Module()) {
if (module.access.receivers & (1 << rxIdx)) {
return QString(module.access.receiverName[rxIdx]);
}
// receiver does not seem to be active
return QString();
}
if (moduleIdx)
return tr("Internal");
return tr("External");
}
+5
View File
@@ -25,6 +25,8 @@
constexpr int CPN_MAX_SENSORS = 60;
class ModelData;
class SensorData {
Q_DECLARE_TR_FUNCTIONS(SensorData)
@@ -111,6 +113,8 @@ class SensorData {
unsigned int id;
unsigned int subid;
unsigned int instance;
unsigned int rxIdx;
unsigned int moduleIdx;
unsigned int persistentValue;
unsigned int formula;
char label[4+1];
@@ -144,6 +148,7 @@ class SensorData {
void updateUnit();
QString unitString() const;
QString nameToString(int index) const;
QString getRxOrModName(const ModelData* model) const;
void clear() { memset(this, 0, sizeof(SensorData)); }
};
@@ -455,6 +455,9 @@ void GeneralSetupPanel::setValues()
ui->pwrOnSpeed->setValue(generalSettings.pwrOnSpeed);
ui->pwrOffSpeed->setValue(generalSettings.pwrOffSpeed);
// TODO: only if ACCESS available??
ui->registrationId->setText(generalSettings.registrationId);
}
void GeneralSetupPanel::on_faimode_CB_stateChanged(int)
@@ -747,6 +750,15 @@ void GeneralSetupPanel::on_blAlarm_ChkB_stateChanged()
emit modified();
}
void GeneralSetupPanel::on_ownerID_editingFinished()
{
//copy ownerID back to generalSettings.registrationId
QByteArray array = ui->registrationId->text().toLocal8Bit();
strncpy(generalSettings.registrationId, "pafleraf", 9);
generalSettings.registrationId[8] = '\0';
emit modified();
}
void GeneralSetupPanel::stickReverseEdited()
{
generalSettings.stickReverse = ((int)ui->stickReverse1->isChecked()) | ((int)ui->stickReverse2->isChecked()<<1) | ((int)ui->stickReverse3->isChecked()<<2) | ((int)ui->stickReverse4->isChecked()<<3);
+1
View File
@@ -87,6 +87,7 @@ class GeneralSetupPanel : public GeneralPanel
void on_vBatMinDSB_editingFinished();
void on_vBatMaxDSB_editingFinished();
void on_contrastSB_editingFinished();
void on_ownerID_editingFinished();
void on_pwrOnSpeed_valueChanged();
void on_pwrOffSpeed_valueChanged();
+317 -300
View File
@@ -554,6 +554,33 @@
</item>
<item row="0" column="3">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="0,0">
<item row="2" column="1">
<widget class="QSpinBox" name="volume_SB">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>23</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="re_label">
<property name="text">
<string>RotEnc Navigation</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="blAlarm_ChkB">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="stickReverseLB">
<property name="sizePolicy">
@@ -567,59 +594,89 @@
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="countrycode_label">
<property name="text">
<string>Country Code</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QCheckBox" name="faimode_CB">
<item row="7" column="1">
<widget class="QComboBox" name="backlightswCB">
<property name="toolTip">
<string>If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_faimode">
<property name="text">
<string>FAI Mode</string>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>This is the switch selectrion for turning on the backlight (if installed).
</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
<item row="17" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="timezoneSB">
<property name="minimum">
<number>-14</number>
</property>
<property name="maximum">
<number>12</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="adjustRTC">
<property name="toolTip">
<string>Automatically adjust the radio's clock if a GPS is connected to telemetry.</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Adjust RTC</string>
</property>
</widget>
</item>
</layout>
<item row="9" column="0">
<widget class="QLabel" name="blAlarm_LB">
<property name="text">
<string>Backlight flash on alarm</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Backlight Auto OFF after</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Backlight Switch</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="varioR0_SB">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>200</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="VoiceLang_label">
<property name="text">
<string>Voice Language</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="varioP0_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>300</number>
</property>
<property name="maximum">
<number>1100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>700</number>
</property>
</widget>
</item>
<item row="14" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
@@ -653,94 +710,38 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_volume">
<item row="6" column="0">
<widget class="QLabel" name="varioR0_label">
<property name="text">
<string>Speaker Volume</string>
<string>Vario repeat at zero</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="varioPMax_SB">
<property name="suffix">
<string> Hz</string>
<item row="4" column="0">
<widget class="QLabel" name="varioP0_label">
<property name="text">
<string>Vario pitch at zero</string>
</property>
<property name="minimum">
<number>1300</number>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_faimode">
<property name="text">
<string>FAI Mode</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_OFFBright">
<property name="text">
<string>Backlight OFF Brightness</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="BLBright_SB">
<property name="maximum">
<number>2900</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1700</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="varioPMax_label">
<property name="text">
<string>Vario pitch at max</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Backlight Switch</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="volume_SB">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>23</number>
</property>
</widget>
</item>
<item row="12" column="1">
<layout class="QHBoxLayout" name="backlightColor_Layout">
<item>
<widget class="QLabel" name="backlightColor1_label">
<property name="text">
<string>Color 1</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="backlightColor_SL">
<property name="maximum">
<number>20</number>
</property>
<property name="pageStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="backlightColor2_label">
<property name="text">
<string>Color 2</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_soundMode">
<property name="text">
<string>Sound Mode</string>
<number>100</number>
</property>
</widget>
</item>
@@ -772,17 +773,95 @@
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="backlightColor_label">
<property name="text">
<string>Backlight color</string>
<item row="1" column="1">
<widget class="QSpinBox" name="speakerPitchSB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;LCD Screen Contrast&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Values can be 20-45&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_speakerPitch">
<item row="5" column="1">
<widget class="QSpinBox" name="varioPMax_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>1300</number>
</property>
<property name="maximum">
<number>2900</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1700</number>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_timezone">
<property name="text">
<string>Speaker Pitch (spkr only)</string>
<string>Timeshift from UTC</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSpinBox" name="OFFBright_SB">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QComboBox" name="countrycode_CB">
<item>
<property name="text">
<string>America</string>
</property>
</item>
<item>
<property name="text">
<string>Japan</string>
</property>
</item>
<item>
<property name="text">
<string>Europe</string>
</property>
</item>
</widget>
</item>
<item row="15" column="1">
<widget class="QCheckBox" name="faimode_CB">
<property name="toolTip">
<string>If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
@@ -810,6 +889,13 @@
</item>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_BLBright">
<property name="text">
<string>Backlight Brightness</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_9" columnstretch="1,0,1,0">
<item row="0" column="0">
@@ -906,168 +992,116 @@
</item>
</layout>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="varioR0_SB">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>200</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="varioP0_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>300</number>
</property>
<property name="maximum">
<number>1100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>700</number>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="blAlarm_LB">
<item row="12" column="0">
<widget class="QLabel" name="backlightColor_label">
<property name="text">
<string>Backlight flash on alarm</string>
<string>Backlight color</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="varioP0_label">
<item row="5" column="0">
<widget class="QLabel" name="varioPMax_label">
<property name="text">
<string>Vario pitch at zero</string>
<string>Vario pitch at max</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="varioR0_label">
<item row="1" column="0">
<widget class="QLabel" name="label_speakerPitch">
<property name="text">
<string>Vario repeat at zero</string>
<string>Speaker Pitch (spkr only)</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="BLBright_SB">
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Backlight Auto OFF after</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="backlightswCB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>This is the switch selectrion for turning on the backlight (if installed).
</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="speakerPitchSB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;LCD Screen Contrast&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Values can be 20-45&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="re_label">
<property name="text">
<string>RotEnc Navigation</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="blAlarm_ChkB">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_BLBright">
<property name="text">
<string>Backlight Brightness</string>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QComboBox" name="countrycode_CB">
<item row="12" column="1">
<layout class="QHBoxLayout" name="backlightColor_Layout">
<item>
<property name="text">
<string>America</string>
</property>
<widget class="QLabel" name="backlightColor1_label">
<property name="text">
<string>Color 1</string>
</property>
</widget>
</item>
<item>
<property name="text">
<string>Japan</string>
</property>
<widget class="QSlider" name="backlightColor_SL">
<property name="maximum">
<number>20</number>
</property>
<property name="pageStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<property name="text">
<string>Europe</string>
</property>
<widget class="QLabel" name="backlightColor2_label">
<property name="text">
<string>Color 2</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="16" column="0">
<widget class="QLabel" name="countrycode_label">
<property name="text">
<string>Country Code</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QComboBox" name="re_CB"/>
</item>
<item row="19" column="0">
<item row="0" column="0">
<widget class="QLabel" name="label_soundMode">
<property name="text">
<string>Sound Mode</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_volume">
<property name="text">
<string>Speaker Volume</string>
</property>
</widget>
</item>
<item row="17" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="timezoneSB">
<property name="minimum">
<number>-14</number>
</property>
<property name="maximum">
<number>12</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="adjustRTC">
<property name="toolTip">
<string>Automatically adjust the radio's clock if a GPS is connected to telemetry.</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Adjust RTC</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="18" column="1">
<widget class="QComboBox" name="voiceLang_CB"/>
</item>
<item row="20" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1080,37 +1114,20 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</item>
<item row="18" column="0">
<widget class="QLabel" name="VoiceLang_label">
<item row="19" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Voice Language</string>
<string>Owner Registration ID</string>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_timezone">
<property name="text">
<string>Timeshift from UTC</string>
<item row="19" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string>aaaaaaAA</string>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QComboBox" name="voiceLang_CB"/>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_OFFBright">
<property name="text">
<string>Backlight OFF Brightness</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSpinBox" name="OFFBright_SB">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>100</number>
<property name="maxLength">
<number>8</number>
</property>
</widget>
</item>
+1 -1
View File
@@ -384,7 +384,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt());
cfn.func = func;
cfn.enabled = fswtchEnable[i]->isChecked();
cfn.adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex();
}
if (!cfn.isEmpty()) {
@@ -418,6 +417,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
int gvidx = func - FuncAdjustGV1;
if (modified)
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
if (cfn.adjustMode==FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
if (modified)
+101 -24
View File
@@ -166,19 +166,20 @@ void TimerPanel::on_name_editingFinished()
#define FAILSAFE_CHANNEL_HOLD 2000
#define FAILSAFE_CHANNEL_NOPULSE 2001
#define MASK_PROTOCOL 1
#define MASK_CHANNELS_COUNT 2
#define MASK_RX_NUMBER 4
#define MASK_CHANNELS_RANGE 8
#define MASK_PPM_FIELDS 16
#define MASK_FAILSAFES 32
#define MASK_OPEN_DRAIN 64
#define MASK_MULTIMODULE 128
#define MASK_ANTENNA 256
#define MASK_MULTIOPTION 512
#define MASK_R9M 1024
#define MASK_SBUSPPM_FIELDS 2048
#define MASK_SUBTYPES 4096
#define MASK_PROTOCOL (1<<0)
#define MASK_CHANNELS_COUNT (1<<1)
#define MASK_RX_NUMBER (1<<2)
#define MASK_CHANNELS_RANGE (1<<3)
#define MASK_PPM_FIELDS (1<<4)
#define MASK_FAILSAFES (1<<5)
#define MASK_OPEN_DRAIN (1<<6)
#define MASK_MULTIMODULE (1<<7)
#define MASK_ANTENNA (1<<8)
#define MASK_MULTIOPTION (1<<9)
#define MASK_R9M (1<<10)
#define MASK_SBUSPPM_FIELDS (1<<11)
#define MASK_SUBTYPES (1<<12)
#define MASK_ACCESS (1<<13)
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
@@ -214,7 +215,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
}
// The protocols available on this board
for (int i=0; i<PULSES_PROTOCOL_LAST; i++) {
for (unsigned int i=0; i<PULSES_PROTOCOL_LAST; i++) {
if (firmware->isAvailable((PulsesProtocol) i, moduleIdx)) {
if (IS_TARANIS_XLITE(firmware->getBoard()) && i == PULSES_PXX_R9M) //TODO remove when mini are handled as a different module type
ui->protocol->addItem("FrSky R9M Mini", (QVariant) i);
@@ -232,6 +233,8 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
ui->btnGrpValueType->setId(ui->optUs, FAILSAFE_DISPLAY_USEC);
ui->btnGrpValueType->button(failsafesValueDisplayType)->setChecked(true);
ui->registrationId->setText(model.registrationId);
setupFailsafes();
disableMouseScrolling();
@@ -244,6 +247,10 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes);
connect(ui->btnGrpValueType, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &ModulePanel::onFailsafesDisplayValueTypeChanged);
connect(ui->clearRx1, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
connect(ui->clearRx2, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
connect(ui->clearRx3, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
lock = false;
}
@@ -257,8 +264,13 @@ bool ModulePanel::moduleHasFailsafes()
{
return firmware->getCapability(HasFailsafe) && (
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_ISRM ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCST_ISRM_D16 ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_XJT_X16 ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M);
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE_PRO ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_XJT_LITE_X16);
}
void ModulePanel::setupFailsafes()
@@ -364,18 +376,30 @@ void ModulePanel::update()
if (moduleIdx >= 0) {
mask |= MASK_PROTOCOL;
switch (protocol) {
case PULSES_ACCESS_ISRM:
mask |= MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT | MASK_RX_NUMBER;
break;
case PULSES_PXX_R9M:
mask |= MASK_R9M | MASK_SUBTYPES;
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
case PULSES_ACCESS_ISRM:
case PULSES_ACCST_ISRM_D16:
case PULSES_XJT_LITE_X16:
case PULSES_XJT_LITE_D8:
case PULSES_XJT_LITE_LR12:
case PULSES_PXX_XJT_X16:
case PULSES_PXX_XJT_D8:
case PULSES_PXX_XJT_LR12:
case PULSES_PXX_DJT:
mask |= MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
if (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_LR12 || protocol==PULSES_PXX_R9M)
// ACCST Rx ID
if (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_LR12 ||
protocol==PULSES_PXX_R9M || protocol==PULSES_ACCST_ISRM_D16 ||
protocol==PULSES_XJT_LITE_X16 || protocol==PULSES_XJT_LITE_LR12)
mask |= MASK_RX_NUMBER;
// ACCESS
else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M ||
protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO)
mask |= MASK_RX_NUMBER | MASK_ACCESS;
if ((IS_HORUS(board) || board == Board::BOARD_TARANIS_XLITE) && moduleIdx == 0)
mask |= MASK_ANTENNA;
break;
@@ -492,10 +516,17 @@ void ModulePanel::update()
if (mask & MASK_SUBTYPES) {
unsigned numEntries = 2; // R9M FCC/EU
unsigned i = 0;
if (mask & MASK_MULTIMODULE)
switch(protocol){
case PULSES_MULTIMODULE:
numEntries = (module.multi.customProto ? 8 : pdef.numSubTypes());
else if (firmware->getCapability(HasModuleR9MFlex))
i = 2;
break;
case PULSES_PXX_R9M:
if (firmware->getCapability(HasModuleR9MFlex))
i = 2;
break;
default:
break;
}
numEntries += i;
const QSignalBlocker blocker(ui->multiSubType);
ui->multiSubType->clear();
@@ -525,6 +556,27 @@ void ModulePanel::update()
ui->label_option->setText(qApp->translate("Multiprotocols", qPrintable(pdef.optionsstr)));
}
if (mask & MASK_ACCESS) {
ui->rx1->setText(module.access.receiverName[0]);
ui->rx2->setText(module.access.receiverName[1]);
ui->rx3->setText(module.access.receiverName[2]);
}
ui->registrationIdLabel->setVisible(mask & MASK_ACCESS);
ui->registrationId->setVisible(mask & MASK_ACCESS);
ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
// Failsafes
ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES);
ui->failsafeMode->setVisible(mask & MASK_FAILSAFES);
@@ -575,7 +627,7 @@ void ModulePanel::on_trainerMode_currentIndexChanged(int index)
void ModulePanel::onProtocolChanged(int index)
{
if (!lock && module.protocol != ui->protocol->itemData(index).toInt()) {
if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) {
module.protocol = ui->protocol->itemData(index).toInt();
update();
emit modified();
@@ -600,7 +652,7 @@ void ModulePanel::on_antennaMode_currentIndexChanged(int index)
void ModulePanel::on_r9mPower_currentIndexChanged(int index)
{
if (!lock && module.pxx.power != index) {
if (!lock && module.pxx.power != (unsigned int)index) {
module.pxx.power = index;
emit modified();
}
@@ -827,6 +879,30 @@ void ModulePanel::updateFailsafe(int channel)
setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
}
void ModulePanel::onClearAccessRxClicked()
{
QPushButton *button = qobject_cast<QPushButton *>(sender());
if (button == ui->clearRx1) {
module.access.receivers &= ~(1<<0);
ui->rx1->clear();
update();
emit modified();
}
else if (button == ui->clearRx2) {
module.access.receivers &= ~(1<<1);
ui->rx2->clear();
update();
emit modified();
}
else if (button == ui->clearRx3) {
module.access.receivers &= ~(1<<2);
ui->rx3->clear();
update();
emit modified();
}
}
/******************************************************************************/
SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
@@ -1373,3 +1449,4 @@ void SetupPanel::on_editText_clicked()
g->exec();
}
}
+1
View File
@@ -95,6 +95,7 @@ class ModulePanel : public ModelPanel
void onFailsafesDisplayValueTypeChanged(int type);
void updateFailsafe(int channel);
void on_optionValue_editingFinished();
void onClearAccessRxClicked();
private:
enum FailsafeValueDisplayTypes { FAILSAFE_DISPLAY_PERCENT = 1, FAILSAFE_DISPLAY_USEC = 2 };
+205 -17
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1042</width>
<height>297</height>
<height>375</height>
</rect>
</property>
<property name="windowTitle">
@@ -239,25 +239,136 @@
<item row="3" column="1">
<widget class="QComboBox" name="r9mPower"/>
</item>
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item row="4" column="0">
<widget class="QLabel" name="rx1Label">
<property name="text">
<string>Receiver 1</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="rx1Layout">
<property name="spacing">
<number>-1</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="autoBind">
<widget class="QLineEdit" name="rx1">
<property name="text">
<string>Bind on startup</string>
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lowPower">
<widget class="QPushButton" name="clearRx1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Low Power</string>
<string>X</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0">
<widget class="QLabel" name="rx2Label">
<property name="text">
<string>Receiver 2</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="rx2Layout">
<item>
<widget class="QLineEdit" name="rx2">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearRx2">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>X</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="rx3Label">
<property name="text">
<string>Receiver 3</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="rx3Layout">
<item>
<widget class="QLineEdit" name="rx3">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearRx3">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>X</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="warning_r9mPower">
<property name="palette">
<palette>
@@ -301,6 +412,37 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="autoBind">
<property name="text">
<string>Bind on startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lowPower">
<property name="text">
<string>Low Power</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="9" column="0" colspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="2">
@@ -535,6 +677,19 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
@@ -577,7 +732,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_multiProtocol">
<property name="text">
<string>Multi Radio Protocol</string>
@@ -587,7 +742,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="multiProtocol">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -600,14 +755,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_multiSubType">
<property name="text">
<string>Sub Type</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QComboBox" name="multiSubType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -620,7 +775,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_failsafeMode">
<property name="maximumSize">
<size>
@@ -636,7 +791,7 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QComboBox" name="failsafeMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -674,7 +829,7 @@
</item>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="label_trainerMode">
<property name="maximumSize">
<size>
@@ -690,7 +845,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QComboBox" name="trainerMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -728,7 +883,7 @@
</item>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="warning_r9mFlex">
<property name="palette">
<palette>
@@ -772,6 +927,39 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="registrationIdLabel">
<property name="text">
<string>Registration ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" colspan="3">
+25 -4
View File
@@ -653,6 +653,9 @@ void TelemetrySensorPanel::update()
ui->id->hide();
ui->instanceLabel->hide();
ui->instance->hide();
ui->rxLabel->hide();
ui->moduleLabel->hide();
ui->rxOrMod->hide();
ui->formula->show();
ui->formula->setCurrentIndex(sensor.formula);
isConfigurable = (sensor.formula < SensorData::TELEM_FORMULA_CELL);
@@ -676,6 +679,14 @@ void TelemetrySensorPanel::update()
ui->id->show();
ui->instanceLabel->show();
ui->instance->show();
bool is_pxx2 = model->moduleData[sensor.moduleIdx].isPxx2Module();
ui->rxLabel->setVisible(is_pxx2);
ui->moduleLabel->setVisible(!is_pxx2);
ui->rxOrMod->setText(sensor.getRxOrModName(model));
ui->rxOrMod->show();
ui->formula->hide();
isConfigurable = sensor.unit < SensorData::UNIT_FIRST_VIRTUAL;
ratioFieldsDisplayed = (sensor.unit < SensorData::UNIT_FIRST_VIRTUAL);
@@ -741,14 +752,24 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model
cb->clear();
if (negative) {
for (int i=-CPN_MAX_SENSORS; i<0; ++i) {
if (model->sensorData[-i-1].isAvailable())
cb->addItem(QString("-%1").arg(model->sensorData[-i-1].label), i);
const SensorData& sensor = model->sensorData[-i-1];
if (sensor.isAvailable()) {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i);
else
cb->addItem(QString("-%1").arg(sensor.label), i);
}
}
}
cb->addItem("---", 0);
for (unsigned i=1; i<=CPN_MAX_SENSORS; ++i) {
if (model->sensorData[i-1].isAvailable())
cb->addItem(model->sensorData[i-1].label, i);
const SensorData& sensor = model->sensorData[i-1];
if (sensor.isAvailable()) {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i);
else
cb->addItem(QString("%1").arg(sensor.label), i);
}
}
}
+49 -1
View File
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0,0,1,1,1,1,0,0,1,0,1,0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0">
<property name="leftMargin">
<number>0</number>
</property>
@@ -28,6 +28,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
@@ -114,6 +120,48 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rxLabel">
<property name="text">
<string>Rx</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="moduleLabel">
<property name="text">
<string>Mod.</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="rxOrMod">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="maxLength">
<number>10</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="formula">
<property name="sizePolicy">
+1 -1
View File
@@ -202,7 +202,7 @@ bool menuRadioHardware(event_t event)
lcdDrawMMM(HW_SETTINGS_COLUMN, y, 0);
config = editChoice(HW_SETTINGS_COLUMN+50, y, STR_SWTYPES, config, SWITCH_NONE, SWITCH_TYPE_MAX(index), menuHorizontalPosition == 1 ? attr : 0, event);
if (attr && checkIncDec_Ret) {
g_eeGeneral.switchConfig = bfSet<uint32_t>(g_eeGeneral.switchConfig, config, 2*index, 2);
g_eeGeneral.switchConfig = bfSet<swconfig_t>(g_eeGeneral.switchConfig, config, 2*index, 2);
}
break;
}
@@ -33,7 +33,9 @@
#define MENU_BODY_TOP (FH + 1)
#define MENU_BODY_BOTTOM (LCD_H)
#if defined(PXX2)
constexpr uint8_t COLUMN2_X = 10 * FW;
#endif
void menuRadioFirmwareOptions(event_t event)
{