Merge branch '2.3' of https://github.com/opentx/opentx into 2.3

This commit is contained in:
MRC3742
2019-08-27 13:09:32 -04:00
211 changed files with 5643 additions and 2331 deletions
+12 -1
View File
@@ -6,7 +6,7 @@ set(VERSION_REVISION "0")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
set(SDCARD_REVISION "0019")
set(SDCARD_REVISION "0020")
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8)
@@ -193,4 +193,15 @@ add_subdirectory(${RADIO_SRC_DIRECTORY})
if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)
add_subdirectory(${COMPANION_SRC_DIRECTORY})
add_custom_target(gtests DEPENDS gtests-radio gtests-companion)
add_custom_target(tests
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio && ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion
DEPENDS gtests
)
else()
add_custom_target(gtests DEPENDS gtests-radio)
add_custom_target(tests
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio
DEPENDS gtests
)
endif()
+2
View File
@@ -1533,3 +1533,5 @@ Sascha Heinrich
James Snodgrass
Alain Labonne
Darko Perković
Pierre Malriq
Donald Manson
+6
View File
@@ -326,6 +326,10 @@ set(simu_SRCS simulator.cpp )
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB})
if(NOT MSVC)
add_subdirectory(tests)
endif()
############# Install ####################
# Generate list of simulator plugins, used by all platforms
@@ -341,6 +345,8 @@ if(PCB STREQUAL X7 AND PCBREV STREQUAL T12)
set(FLAVOUR t12)
elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
set(FLAVOUR x9d+2019)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS)
set(FLAVOUR x10express)
else()
string(TOLOWER ${PCB} FLAVOUR)
endif()
+1 -1
View File
@@ -188,7 +188,7 @@ void AppPreferencesDialog::initSettings()
ui->backLightColor->setCurrentIndex(g.backLight());
ui->volumeGain->setValue(profile.volumeGain() / 10.0);
if (IS_TARANIS(getCurrentBoard())) {
if (IS_HORUS_OR_TARANIS(getCurrentBoard())) {
ui->backLightColor->setEnabled(false);
}
+7 -4
View File
@@ -59,6 +59,7 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_X12S:
return 0x3478746F;
case BOARD_X10:
case BOARD_X10_EXPRESS:
return 0x3778746F;
case BOARD_TARANIS_XLITE:
return 0x3978746F;
@@ -122,6 +123,7 @@ const int Boards::getEEpromSize(Board::Type board)
return EESIZE_MAX;
case BOARD_X12S:
case BOARD_X10:
case BOARD_X10_EXPRESS:
return 0;
}
@@ -155,6 +157,7 @@ const int Boards::getFlashSize(Type board)
return FSIZE_TARANIS;
case BOARD_X12S:
case BOARD_X10:
case BOARD_X10_EXPRESS:
return FSIZE_HORUS;
case BOARD_UNKNOWN:
return FSIZE_MAX;
@@ -333,14 +336,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
@@ -524,6 +525,8 @@ const QString Boards::getBoardName(Board::Type board)
return "Horus X12S";
case BOARD_X10:
return "Horus X10/X10S";
case BOARD_X10_EXPRESS:
return "Horus X10 Express";
default:
return tr("Unknown");
}
+2 -2
View File
@@ -46,6 +46,7 @@ namespace Board {
BOARD_TARANIS_X9E,
BOARD_X12S,
BOARD_X10,
BOARD_X10_EXPRESS,
BOARD_TARANIS_XLITE,
BOARD_TARANIS_XLITES,
BOARD_TARANIS_X9LITE,
@@ -206,12 +207,11 @@ class Boards
#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITE(board) || IS_JUMPER_T12(board))
#define IS_TARANIS_SMALL(board) (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_T12(board))
#define IS_HORUS_X12S(board) (board==Board::BOARD_X12S)
#define IS_HORUS_X10(board) (board==Board::BOARD_X10)
#define IS_HORUS_X10(board) (board==Board::BOARD_X10 || board==Board::BOARD_X10_EXPRESS)
#define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board))
#define IS_HORUS_OR_TARANIS(board) (IS_HORUS(board) || IS_TARANIS(board))
#define IS_STM32(board) (IS_TARANIS(board) || IS_HORUS(board))
#define IS_ARM(board) (IS_STM32(board) || IS_SKY9X(board))
#define IS_ACCESS_RADIO(board) (IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITES(board))
#define HAS_LARGE_LCD(board) (IS_HORUS(board) || IS_TARANIS_X9(board))
#endif // _BOARDS_H_
@@ -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:
+8 -10
View File
@@ -103,20 +103,18 @@ void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, co
#endif
// TODO: No GUI here, e.g. return string list instead
void EEPROMInterface::showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound)
QString EEPROMInterface::getEepromWarnings(unsigned long errorsFound)
{
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
QStringList warningsList;
if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
if (errors.test(OLD_VERSION)) { warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); }
if (errors.test(WARNING_WRONG_FIRMWARE)) {
warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used");
}
if (errors.test(OLD_VERSION)) {
warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name.");
}
QMessageBox msgBox(parent);
msgBox.setWindowTitle(title);
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(tr("Warnings!"));
msgBox.setInformativeText(warningsList.join("\n"));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
return warningsList.join("\n");
}
+2 -2
View File
@@ -178,7 +178,7 @@ class EEPROMInterface
virtual int getSize(const GeneralSettings &) = 0;
//static void showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound);
static void showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound);
static QString getEepromWarnings(unsigned long errorsFound);
protected:
@@ -345,7 +345,7 @@ class Firmware
virtual QTime getMaxTimerStart() = 0;
virtual int isAvailable(PulsesProtocol proto, int port=0) = 0;
virtual bool isAvailable(PulsesProtocol proto, int port=0) = 0;
const int getFlashSize();
@@ -203,7 +203,7 @@ int Er9xInterface::getSize(const GeneralSettings &settings)
return 0;
}
int Er9xInterface::isAvailable(PulsesProtocol prot, int port)
bool Er9xInterface::isAvailable(PulsesProtocol prot, int port)
{
switch (prot) {
case PULSES_PPM:
+1 -1
View File
@@ -52,7 +52,7 @@ class Er9xInterface : public EEPROMInterface
virtual int getSize(const GeneralSettings &settings);
virtual int isAvailable(PulsesProtocol proto, int port=0);
virtual bool isAvailable(PulsesProtocol proto, int port=0);
virtual int getCapability(Capability capability);
@@ -251,7 +251,7 @@ int Ersky9xInterface::getSize(const GeneralSettings & settings)
return 0;
}
int Ersky9xInterface::isAvailable(PulsesProtocol prot, int port)
bool Ersky9xInterface::isAvailable(PulsesProtocol prot, int port)
{
switch (prot) {
case PULSES_PPM:
@@ -51,7 +51,7 @@ class Ersky9xInterface : public EEPROMInterface
virtual int getSize(const GeneralSettings & settings);
virtual int isAvailable(PulsesProtocol proto, int port=0);
virtual bool isAvailable(PulsesProtocol proto, int port=0);
virtual int getCapability(Capability capability);
+3 -2
View File
@@ -163,8 +163,9 @@ void ModelData::clear()
moduleData[0].ppm.delay = 300;
moduleData[1].ppm.delay = 300;
moduleData[2].ppm.delay = 300;
int board = getCurrentBoard();
if (IS_ACCESS_RADIO(board)) {
Firmware * firmware = Firmware::getCurrentVariant();
int board = firmware->getBoard();
if (firmware->isAvailable(PULSES_ACCESS_ISRM, 0)) {
moduleData[0].protocol = PULSES_ACCESS_ISRM;
moduleData[1].protocol = PULSES_OFF;
}
+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;
+289 -101
View File
@@ -40,7 +40,13 @@ inline int MAX_SWITCHES(Board::Type board, int version)
return Boards::getCapability(board, Board::Switches);
}
#define MAX_KNOBS(board, version) (IS_HORUS(board) ? 8 : 4)
inline int MAX_KNOBS(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
return 8;
return 4;
}
inline int MAX_POTS(Board::Type board, int version)
{
@@ -56,6 +62,14 @@ inline int MAX_POTS_STORAGE(Board::Type board, int version)
return Boards::getCapability(board, Board::PotsStorage);
}
inline int MAX_SLIDERS_SLOTS(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
return 8;
return 4;
}
// bitsize of swconfig_t / 2 (see radio/src/datastructs.h)
inline int MAX_SWITCH_SLOTS(Board::Type board, int version)
{
@@ -71,7 +85,17 @@ inline int MAX_SWITCH_SLOTS(Board::Type board, int version)
return 8;
}
#define MAX_SWITCHES_POSITION(board, version) (Boards::getCapability(board, Board::SwitchPositions))
inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
{
if (version < 219) {
if (IS_TARANIS_X7(board) || IS_HORUS(board))
return Boards::getCapability(board, Board::SwitchPositions) - 2*3;
}
return Boards::getCapability(board, Board::SwitchPositions);
}
//#define MAX_SWITCHES_POSITION(board, version) (Boards::getCapability(board, Board::SwitchPositions))
#define MAX_ROTARY_ENCODERS(board) (IS_SKY9X(board) ? 1 : 0)
#define MAX_FLIGHT_MODES(board, version) 9
#define MAX_TIMERS(board, version) 3
@@ -244,8 +268,13 @@ class SourcesConversionTable: public ConversionTable {
}
}
for (int i=0; i<CPN_MAX_STICKS+MAX_POTS(board,version)+Boards::getCapability(board, Board::Sliders)+Boards::getCapability(board, Board::MouseAnalogs)+MAX_GYRO_ANALOGS(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_STICK, i), val++);
for (int i=0; i<CPN_MAX_STICKS+MAX_POTS_STORAGE(board, version)+Boards::getCapability(board, Board::SlidersStorage)+Boards::getCapability(board, Board::MouseAnalogs)+MAX_GYRO_ANALOGS(board, version); i++) {
int offset = 0;
if (version <= 218 && IS_HORUS(board) && i>=CPN_MAX_STICKS+MAX_POTS_STORAGE(board, version))
offset += 2;
addConversion(RawSource(SOURCE_TYPE_STICK, i + offset), val++);
}
for (int i=0; i<MAX_ROTARY_ENCODERS(board); i++) {
@@ -1868,7 +1897,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 +1921,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) + (version <= 218 ? -1 : 0); // 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 +1971,239 @@ 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, Board::Type board, unsigned int version):
UnionField<unsigned int>(parent, module.protocol)
{
if (version >= 219)
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, version)
{
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, board, version));
}
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 +2351,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 +2460,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 +2478,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++) {
@@ -2312,6 +2494,9 @@ void OpenTxModelData::afterImport()
}
modelData.switchWarningStates = newSwitchWarningStates;
}
if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3)
modelData.thrTraceSrc += 2;
}
OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant):
@@ -2472,13 +2657,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) || version < 219) {
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 {
@@ -2502,17 +2691,18 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
for (int i=0; i<MAX_KNOBS(board, version); i++) {
int offset = 0;
// 2 new pots for Horus from 219 on
if (version <= 218 && IS_HORUS(board) && (i == 3))
i += 2;
if (version <= 218 && IS_HORUS(board) && (i >= 3))
offset += 2;
if (i < Boards::getCapability(board, Board::PotsStorage))
internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i]));
internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i+offset]));
else
internalField.Append(new SpareBitsField<2>(this));
}
if (IS_HORUS(board)) {
for (int i=0; i<8; i++) {
if (IS_HORUS(board) && version >= 219) {
for (int i=0; i<MAX_SLIDERS_SLOTS(board,version); i++) {
if (i < Boards::getCapability(board, Board::SlidersStorage))
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
else
@@ -2536,6 +2726,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
if (IS_TARANIS_X9E(board))
internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates
else if (version >= 219 && IS_TARANIS_X9D(board))
internalField.Append(new SpareBitsField<32>(this)); // switchUnlockStates
else if (IS_TARANIS(board))
internalField.Append(new SpareBitsField<16>(this)); // switchUnlockStates
@@ -2552,11 +2744,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
for (int i=0; i<CPN_MAX_STICKS; ++i) {
internalField.Append(new ZCharField<3>(this, generalData.stickName[i], "Stick name"));
}
for (int i=0; i<Boards::getCapability(board, Board::PotsStorage); ++i) {
if (version <= 218 && IS_HORUS(board) && (i == 3)) {
// skip not yet existing pots (EXT1 / EXT2 for X10)
i += 2;
}
for (int i=0; i<MAX_POTS_STORAGE(board, version); ++i) {
internalField.Append(new ZCharField<3>(this, generalData.potName[i], "Pot name"));
}
for (int i=0; i<Boards::getCapability(board, Board::SlidersStorage); ++i) {
@@ -2590,7 +2778,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"));
}
+10 -3
View File
@@ -73,7 +73,7 @@ class OpenTxGeneralData: public TransformedField {
class ProtocolsConversionTable: public ConversionTable
{
public:
ProtocolsConversionTable(Board::Type board)
ProtocolsConversionTable(Board::Type board, int version)
{
int val = 0;
addConversion(PULSES_OFF, val++);
@@ -83,7 +83,10 @@ class ProtocolsConversionTable: public ConversionTable
addConversion(PULSES_PXX_XJT_D8, val);
addConversion(PULSES_PXX_XJT_LR12, val++);
addConversion(PULSES_ACCESS_ISRM, val++);
if (version >= 219) {
addConversion(PULSES_ACCESS_ISRM, val);
addConversion(PULSES_ACCST_ISRM_D16, val++);
}
addConversion(PULSES_LP45, val);
addConversion(PULSES_DSM2, val);
@@ -96,9 +99,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 +149,6 @@ class OpenTxModelData: public TransformedField {
unsigned int variant;
char name[256];
int subprotocols[CPN_MAX_MODULES+1/*trainer*/];
ProtocolsConversionTable protocolsConversionTable;
ChannelsConversionTable channelsConversionTable;
QStringList _errors;
};
@@ -94,6 +94,8 @@ const char * OpenTxEepromInterface::getName()
return "OpenTX for FrSky Horus";
case BOARD_X10:
return "OpenTX for FrSky X10";
case BOARD_X10_EXPRESS:
return "OpenTX for FrSky X10 Express";
default:
return "OpenTX for an unknown board";
}
@@ -756,66 +758,67 @@ QTime OpenTxFirmware::getMaxTimerStart()
return QTime(0, 59, 59);
}
int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
{
if (IS_HORUS_OR_TARANIS(board)) {
switch (port) {
case 0:
switch (proto) {
case PULSES_OFF:
return 1;
return true;
case PULSES_PXX_XJT_X16:
case PULSES_PXX_XJT_LR12:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 0 : 1;
return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
case PULSES_PXX_XJT_D8:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || id.contains("eu")) ? 0 : 1;
return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || id.contains("eu"));
case PULSES_PPM:
return id.contains("internalppm") ? 1 : 0;
return id.contains("internalppm");
case PULSES_ACCESS_ISRM:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0;
return IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess"));
case PULSES_ACCST_ISRM_D16:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
default:
return 0;
return false;
}
case 1:
switch (proto) {
case PULSES_OFF:
case PULSES_PPM:
return 1;
return true;
case PULSES_PXX_XJT_X16:
case PULSES_PXX_XJT_D8:
case PULSES_PXX_XJT_LR12:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 0 : 1;
return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
case PULSES_PXX_R9M:
case PULSES_LP45:
case PULSES_DSM2:
case PULSES_DSMX:
case PULSES_SBUS:
return 1;
case PULSES_MULTIMODULE:
if(IS_JUMPER_T12(board))
return 1;
else
return id.contains("multimodule") ? 1 : 0;
case PULSES_CROSSFIRE:
return id.contains("crossfire") ? 1 : 0;
return true;
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0;
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
case PULSES_XJT_LITE_X16:
case PULSES_XJT_LITE_D8:
case PULSES_XJT_LITE_LR12:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
default:
return 0;
return false;
}
case -1:
switch (proto) {
case PULSES_PPM:
return 1;
return true;
default:
return 0;
return false;
}
default:
return 0;
return false;
}
}
else if (IS_SKY9X(board)) {
@@ -831,23 +834,22 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_DSM2:
case PULSES_DSMX:
case PULSES_SBUS:
return 1;
case PULSES_MULTIMODULE:
return id.contains("multimodule") ? 1 : 0;
return true;
default:
return 0;
return false;
}
break;
case 1:
switch (proto) {
case PULSES_PPM:
return 1;
return true;
default:
return 0;
return false;
}
break;
default:
return 0;
return false;
}
}
else {
@@ -859,9 +861,9 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
// case PULSES_PXX_DJT: // Unavailable for now
case PULSES_PPM16:
case PULSES_PPMSIM:
return 1;
return true;
default:
return 0;
return false;
}
}
}
@@ -1150,7 +1152,6 @@ void addOpenTxRfOptions(OpenTxFirmware * firmware, bool flex = true)
{
static const Firmware::Option opt_eu("eu", Firmware::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015"));
static const Firmware::Option opt_fl("flexr9m", Firmware::tr("Enable non certified firmwares"));
firmware->addOption("multimodule", Firmware::tr("Support for the DIY-Multiprotocol-TX-Module"));
if (flex)
firmware->addOptionsGroup({opt_eu, opt_fl});
else
@@ -1168,8 +1169,6 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware)
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
firmware->addOption("luac", Firmware::tr("Enable Lua compiler"));
firmware->addOption("crossfire", Firmware::tr("Support for Crossfire TX Module"));
addOpenTxRfOptions(firmware);
}
@@ -1260,23 +1259,28 @@ void registerOpenTxFirmwares()
/* FrSky X10 board */
firmware = new OpenTxFirmware("opentx-x10", Firmware::tr("FrSky Horus X10 / X10S"), BOARD_X10);
addOpenTxFrskyOptions(firmware);
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
registerOpenTxFirmware(firmware);
/* FrSky X10 Express board */
firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express"), BOARD_X10_EXPRESS);
addOpenTxFrskyOptions(firmware);
registerOpenTxFirmware(firmware);
/* FrSky X12 (Horus) board */
firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_X12S);
addOpenTxFrskyOptions(firmware);
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version"));
registerOpenTxFirmware(firmware);
/* Jumper T12 board */
firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12"), BOARD_JUMPER_T12);
addOpenTxCommonOptions(firmware);
firmware->addOption("multimodule", Firmware::tr("Support for the DIY-Multiprotocol-TX-Module"));
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
firmware->addOption("luac", Firmware::tr("Enable Lua compiler"));
firmware->addOption("crossfire", Firmware::tr("Support for Crossfire TX Module"));
firmware->addOption("flexr9m", Firmware::tr("Enable non certified R9M firmwares"));
addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware);
@@ -122,7 +122,7 @@ class OpenTxFirmware: public Firmware
virtual QTime getMaxTimerStart();
virtual int isAvailable(PulsesProtocol proto, int port=0);
virtual bool isAvailable(PulsesProtocol proto, int port=0);
protected:
+2 -2
View File
@@ -259,11 +259,11 @@ class RawSource {
bool isTimeBased(Board::Type board = Board::BOARD_UNKNOWN) const;
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
bool operator == ( const RawSource & other) {
bool operator == ( const RawSource & other) const {
return (this->type == other.type) && (this->index == other.index);
}
bool operator != ( const RawSource & other) {
bool operator != ( const RawSource & other) const {
return (this->type != other.type) || (this->index != other.index);
}
+2 -2
View File
@@ -91,11 +91,11 @@ class RawSwitch {
QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL) const;
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
bool operator== ( const RawSwitch& other) {
bool operator== ( const RawSwitch& other) const {
return (this->type == other.type) && (this->index == other.index);
}
bool operator!= ( const RawSwitch& other) {
bool operator!= ( const RawSwitch& other) const {
return (this->type != other.type) || (this->index != other.index);
}
+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
@@ -1334,7 +1334,7 @@ bool MdiChild::loadFile(const QString & filename, bool resetCurrentFile)
QString warning = storage.warning();
if (!warning.isEmpty()) {
// TODO EEPROMInterface::showEepromWarnings(this, CPN_STR_TTL_WARNING, warning);
QMessageBox::warning(this, CPN_STR_TTL_WARNING, warning);
}
if (resetCurrentFile) {
+6 -6
View File
@@ -162,11 +162,6 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
curveCB[i] = new QComboBox(this);
curveCB[i]->setProperty("index", i);
int numcurves = firmware->getCapability(NumCurves);
for (int j=-numcurves; j<=numcurves; j++) {
curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(&model, false), j);
}
curveCB[i]->setCurrentIndex(model.limitData[i].curve.value+numcurves);
connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
tableLayout->addWidget(i, col++, curveCB[i]);
}
@@ -298,7 +293,12 @@ void Channels::updateLine(int i)
chnMax[i]->setValue(model->limitData[i].max);
invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0);
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + firmware->getCapability(NumCurves));
int numcurves = firmware->getCapability(NumCurves);
curveCB[i]->clear();
for (int j=-numcurves; j<=numcurves; j++) {
curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j);
}
curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves);
}
if (firmware->getCapability(PPMCenter)) {
centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500);
+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)
+114 -31
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):
@@ -1108,7 +1184,7 @@ void SetupPanel::on_trimIncrement_currentIndexChanged(int index)
void SetupPanel::on_throttleSource_currentIndexChanged(int index)
{
if (!lock) {
model->thrTraceSrc = index;
model->thrTraceSrc = ui->throttleSource->currentData().toUInt();
emit modified();
}
}
@@ -1168,14 +1244,20 @@ void SetupPanel::populateThrottleSourceCB()
Board::Type board = firmware->getBoard();
lock = true;
ui->throttleSource->clear();
ui->throttleSource->addItem(tr("THR"));
for (int i=0; i<getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders); i++) {
ui->throttleSource->addItem(firmware->getAnalogInputName(4+i), i);
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++) {
ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings));
for (int i=0; i<firmware->getCapability(Outputs); i++, idx++) {
ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx);
}
ui->throttleSource->setCurrentIndex(model->thrTraceSrc);
int thrTraceSrcIdx = ui->throttleSource->findData(model->thrTraceSrc);
ui->throttleSource->setCurrentIndex(thrTraceSrcIdx);
lock = false;
}
@@ -1373,3 +1455,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">
@@ -90,6 +90,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
radioUiWidget = new SimulatedUIWidgetX12(simulator, this);
break;
case Board::BOARD_X10:
case Board::BOARD_X10_EXPRESS:
radioUiWidget = new SimulatedUIWidgetX10(simulator, this);
break;
case Board::BOARD_JUMPER_T12:
@@ -42,7 +42,7 @@ class RadioSwitchWidget : public RadioWidget
init();
}
explicit RadioSwitchWidget(Board::SwitchType type, const QString & labelText, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
explicit RadioSwitchWidget(Board::SwitchType type, const QString & labelText, int value = -1, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
RadioWidget(labelText, value, parent, f),
swType(type)
{
@@ -127,7 +127,7 @@ class RadioSwitchWidget : public RadioWidget
void resetToggle()
{
setValue(0);
setValue(-1);
}
private slots:
+2 -1
View File
@@ -43,6 +43,7 @@ bool BinEepromFormat::load(RadioData & radioData)
return false;
}
//TODO: show warnings if any
return extract(radioData, eeprom);
}
@@ -94,7 +95,7 @@ bool BinEepromFormat::extract(RadioData & radioData, const QByteArray & eeprom)
std::bitset<NUM_ERRORS> result((unsigned long long)eepromInterface->load(radioData, (uint8_t *)eeprom.data(), eeprom.size()));
if (result.test(ALL_OK)) {
if (errors.test(HAS_WARNINGS)) {
EEPROMInterface::showEepromWarnings(NULL, CPN_STR_TTL_WARNING, errors.to_ulong());
setWarning(EEPROMInterface::getEepromWarnings(errors.to_ulong()));
}
board = eepromInterface->getBoard();
return true;
+34
View File
@@ -0,0 +1,34 @@
set(GTEST_ROOT /usr CACHE STRING "Base path to Google Test headers and source.")
find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').")
find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.")
if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND)
add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc )
target_include_directories(gtests-companion-lib PUBLIC ${GTEST_INCDIR} ${GTEST_INCDIR}/gtest ${GTEST_SRCDIR})
add_definitions(-DGTESTS)
set(TESTS_PATH ${COMPANION_SRC_DIRECTORY}/tests)
set(RADIO_TESTS_PATH ${RADIO_SRC_DIRECTORY}/tests)
configure_file(${TESTS_PATH}/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(WIN32)
target_include_directories(gtests-companion-lib PUBLIC ${WIN_INCLUDE_DIRS})
target_link_libraries(gtests-companion-lib PRIVATE ${WIN_LINK_LIBRARIES})
endif(WIN32)
file(GLOB TEST_SRC_FILES ${TESTS_PATH}/*.cpp)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${WARNING_FLAGS}")
use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
add_executable(gtests-companion EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h)
add_dependencies(gtests-companion gtests-companion-lib)
target_link_libraries(gtests-companion gtests-companion-lib simulation firmwares storage common)
message(STATUS "Added optional gtests-companion target")
else()
message(WARNING "WARNING: gtests target will not be available (check that GTEST_INCDIR, GTEST_SRCDIR, and Qt5Widgets are configured).")
endif()
+188
View File
@@ -0,0 +1,188 @@
#include "gtests.h"
#include "location.h"
#include "storage/otx.h"
#include "storage/storage.h"
#include "firmwares/opentx/opentxinterface.h"
#include "firmwares/customfunctiondata.h"
TEST(Conversions, ConversionX9DPFrom22)
{
RadioData radioData;
Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x9d+.bin");
ASSERT_EQ(true, store.load(radioData));
ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
const ModelData& model = radioData.models[0];
EXPECT_STREQ("Test", model.name);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH,SWITCH_SA0), model.timers[0].mode);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name);
EXPECT_EQ(PULSES_PXX_XJT_X16, model.moduleData[0].protocol);
EXPECT_EQ(0, model.moduleData[0].subType);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_FCC, model.moduleData[1].subType);
EXPECT_STREQ("Thr", model.inputNames[0]);
EXPECT_STREQ("Tes", model.sensorData[0].label);
EXPECT_EQ(10, model.sensorData[0].id);
EXPECT_EQ(9, model.sensorData[0].instance);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model.logicalSw[0].val1);
}
TEST(Conversions, ConversionX7From22)
{
RadioData radioData;
Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x7.bin");
ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
const ModelData& model = radioData.models[0];
EXPECT_STREQ("Test", model.name);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[4].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[4].swtch);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Thr", model.inputNames[0]);
EXPECT_STREQ("Tes", model.sensorData[0].label);
EXPECT_EQ(10, model.sensorData[0].id);
EXPECT_EQ(9, model.sensorData[0].instance);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("FMtest", model.flightModeData[1].name);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1), model.flightModeData[1].swtch);
EXPECT_STREQ("Tes", model.gvarData[0].name);
EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1);
EXPECT_EQ(0, model.logicalSw[0].val2);
const FrSkyScreenData& screen = model.frsky.screens[0];
EXPECT_EQ(TELEMETRY_SCREEN_NUMBERS, screen.type);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), screen.body.lines[0].source[0]);
EXPECT_EQ(RawSource(SOURCE_TYPE_SPECIAL,4), screen.body.lines[0].source[1]);
}
bool loadFile(QByteArray & filedata, const QString & filename)
{
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
qDebug() << QString("Error opening file %1:\n%2.").arg(filename).arg(file.errorString());
return false;
}
filedata = file.readAll();
qDebug() << "File" << filename << "read, size:" << filedata.size();
return true;
}
TEST(Conversions, ConversionX10From22)
{
QByteArray byteBuffer;
#define USE_OTX
#if defined(USE_OTX)
OtxFormat otx(RADIO_TESTS_PATH "/model_22_x10.otx");
RadioData radio;
EXPECT_EQ(true, otx.load(radio));
const GeneralSettings& settings = radio.generalSettings;
const ModelData& model = radio.models[0];
#else
ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x10/RADIO/radio.bin"));
GeneralSettings settings;
EXPECT_NE(nullptr, loadRadioSettingsFromByteArray(settings, byteBuffer));
#endif
EXPECT_EQ(100, settings.calibSpanNeg[9]);
EXPECT_EQ(500, settings.calibMid[9]);
EXPECT_EQ(900, settings.calibSpanPos[9]);
EXPECT_EQ(200, settings.calibSpanNeg[10]);
EXPECT_EQ(400, settings.calibMid[10]);
EXPECT_EQ(600, settings.calibSpanPos[10]);
EXPECT_EQ(-23, settings.vBatMin);
EXPECT_EQ(20, settings.speakerVolume);
EXPECT_STREQ("en", settings.ttsLanguage);
EXPECT_STREQ("model1.bin", settings.currModelFilename);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch);
EXPECT_EQ(FuncVolume, settings.customFn[1].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK,4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
EXPECT_STREQ("BT_X10", settings.bluetoothName);
EXPECT_STREQ("Default", settings.themeName);
#if !defined(USE_OTX)
byteBuffer.clear();
ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x10/MODELS/model1.bin"));
ModelData model;
ASSERT_NE(nullptr, loadModelFromByteArray(model, byteBuffer));
#endif
EXPECT_STREQ("Test", model.name);
EXPECT_EQ(0, model.noGlobalFunctions);
EXPECT_EQ(0, model.beepANACenter);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK,4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[5].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[5].swtch);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); // TR1
EXPECT_EQ(0, model.logicalSw[0].val2);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,19*3).toValue(), model.logicalSw[1].val1); // TELE:20
EXPECT_EQ(20, model.logicalSw[1].val2);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1).toValue(), model.logicalSw[1].andsw);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Tes", model.flightModeData[0].name);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_STREQ("Rud", model.inputNames[0]);
EXPECT_STREQ("Tes", model.sensorData[0].label);
EXPECT_EQ(10, model.sensorData[0].id);
EXPECT_EQ(9, model.sensorData[0].instance);
EXPECT_EQ(5 + 2 + 3, model.thrTraceSrc); // CH3
}
+149
View File
@@ -0,0 +1,149 @@
/*
* 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 <QApplication>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory>
#include "gtests.h"
#include "storage.h"
#include "opentxinterface.h"
#include "customdebug.h"
using ::testing::TestEventListener;
using ::testing::EmptyTestEventListener;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;
using ::testing::InitGoogleTest;
namespace {
void printColorCode(int color)
{
#if !GTEST_OS_WINDOWS
if (isatty(fileno(stdout)))
fprintf(stdout, "\033[0;%dm", color);
#endif
}
/**
* Replaces gtest's PrettyUnitTestResultPrinter with something less verbose.
* Uses the default printer if/when the messages might be interesting,
* e.g. for full error info or tests summary.
*/
class TersePrinter : public EmptyTestEventListener {
public:
explicit TersePrinter(TestEventListener * prettyPrinter)
: prettyPrinter(prettyPrinter), currentTestInfo(NULL)
{
}
void OnTestProgramStart(const UnitTest & unit_test)
{
prettyPrinter->OnTestProgramStart(unit_test);
}
void OnTestIterationStart(const UnitTest & unit_test, int iteration)
{
printColorCode(36);
fprintf(stdout, "############ ");
fprintf(stdout, "Running %d test(s) from %d test case(s), iteration: %d.\n", unit_test.test_to_run_count(), unit_test.test_case_to_run_count(), iteration + 1);
printColorCode(0);
fflush(stdout);
}
void OnTestCaseStart(const TestCase & test_case)
{
prettyPrinter->OnTestCaseStart(test_case);
}
void OnTestStart(const TestInfo & test_info)
{
currentTestInfo = &test_info;
}
void OnTestPartResult(const TestPartResult & test_part_result)
{
if (test_part_result.failed()) {
prettyPrinter->OnTestStart(*currentTestInfo);
prettyPrinter->OnTestPartResult(test_part_result);
}
}
void OnTestEnd(const TestInfo & test_info)
{
currentTestInfo = NULL;
if (test_info.result()->Failed()) {
prettyPrinter->OnTestEnd(test_info);
}
else {
printColorCode(32);
fprintf(stdout, "+");
printColorCode(0);
fflush(stdout);
}
}
void OnTestCaseEnd(const TestCase & test_case)
{
fprintf(stdout, "\n");
fflush(stdout);
}
void OnTestIterationEnd(const UnitTest & unit_test, int iteration)
{
prettyPrinter->OnTestIterationEnd(unit_test, iteration);
}
void OnTestProgramEnd(const UnitTest & unit_test)
{
prettyPrinter->OnTestProgramEnd(unit_test);
}
private:
// gtest's default unit test result printer.
std::unique_ptr<TestEventListener> prettyPrinter;
// The currently running TestInfo, if any.
const TestInfo * currentTestInfo;
};
} // anonymous namespace
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
CustomDebug::setFilterRules();
registerStorageFactories();
registerOpenTxFirmwares();
InitGoogleTest(&argc, argv);
// use --verbose option to revert to gtest's default output format
bool verbose = false;
if (argc > 1 && !strcmp(argv[1], "--verbose"))
verbose = true;
if (!verbose) {
TestEventListeners & listeners = UnitTest::GetInstance()->listeners();
TestEventListener * defaultPrinter = listeners.Release(listeners.default_result_printer());
listeners.Append(new TersePrinter(defaultPrinter));
}
return RUN_ALL_TESTS();
}
+41
View File
@@ -0,0 +1,41 @@
/*
* 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 _GTESTS_H_
#define _GTESTS_H_
#include <QtCore/QString>
#include <math.h>
#include <gtest/gtest.h>
class OpenTxTest : public testing::Test
{
protected: // You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp()
{
}
};
#endif // _GTESTS_H_
+2
View File
@@ -0,0 +1,2 @@
#define TESTS_PATH "@TESTS_PATH@"
#define RADIO_TESTS_PATH "@RADIO_TESTS_PATH@"
Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

-3
View File
@@ -600,11 +600,8 @@ enum {
CMD_RET_SUCCESS = 0x40,
};
constexpr uint32_t CC26XX_FLASH_SIZE = 0x00020000;
constexpr uint32_t CC26XX_BOOTLOADER_SIZE = 0x00001000;
constexpr uint32_t CC26XX_DATA_SIZE = 0x00001000;
constexpr uint32_t CC26XX_FIRMWARE_BASE = CC26XX_BOOTLOADER_SIZE;
constexpr uint32_t CC26XX_FIRMWARE_SIZE = CC26XX_FLASH_SIZE - CC26XX_DATA_SIZE - CC26XX_BOOTLOADER_SIZE;
constexpr uint32_t CC26XX_PAGE_ERASE_SIZE = 0x1000;
constexpr uint32_t CC26XX_MAX_BYTES_PER_TRANSFER = 252;
-4
View File
@@ -828,9 +828,7 @@ enum Functions {
FUNC_HAPTIC,
FUNC_LOGS,
FUNC_BACKLIGHT,
#if defined(PCBTARANIS)
FUNC_SCREENSHOT,
#endif
#if defined(DEBUG)
FUNC_TEST, // should remain the last before MAX as not added in Companion
#endif
@@ -861,9 +859,7 @@ enum ResetFunctionParam {
FUNC_RESET_TIMER2,
FUNC_RESET_TIMER3,
FUNC_RESET_FLIGHT,
#if defined(TELEMETRY_FRSKY)
FUNC_RESET_TELEMETRY,
#endif
FUNC_RESET_PARAM_FIRST_TELEM,
FUNC_RESET_PARAM_LAST_TELEM = FUNC_RESET_PARAM_FIRST_TELEM + MAX_TELEMETRY_SENSORS,
FUNC_RESET_PARAMS_COUNT,
+1 -5
View File
@@ -194,11 +194,9 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
mainRequestFlags |= (1 << REQUEST_FLIGHT_RESET); // on systems with threads flightReset() must not be called from the mixers thread!
}
break;
#if defined(TELEMETRY_FRSKY)
case FUNC_RESET_TELEMETRY:
telemetryReset();
break;
#endif
}
if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) {
uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM;
@@ -338,7 +336,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
}
#endif
#if defined(TELEMETRY_FRSKY) && defined(VARIO)
#if defined(VARIO)
case FUNC_VARIO:
newActiveFunctions |= (1 << FUNCTION_VARIO);
break;
@@ -358,13 +356,11 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
newActiveFunctions |= (1 << FUNCTION_BACKLIGHT);
break;
#if defined(PCBTARANIS)
case FUNC_SCREENSHOT:
if (!(functionsContext.activeSwitches & switch_mask)) {
mainRequestFlags |= (1 << REQUEST_SCREENSHOT);
}
break;
#endif
#if defined(DEBUG)
case FUNC_TEST:
-4
View File
@@ -309,11 +309,7 @@ void showAlertBox(const char * title, const char * text, const char * action , u
#define LOAD_MODEL_BITMAP()
#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
#if defined(TELEMETRY_FRSKY)
#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky
#else
#define IS_TELEMETRY_VIEW_DISPLAYED() false
#endif
#define IS_OTHER_VIEW_DISPLAYED() false
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags);
-2
View File
@@ -197,8 +197,6 @@ inline display_t getPixel(uint8_t x, uint8_t y)
return ((pixel & mask) ? 0xf : 0);
}
const char * writeScreenshot();
uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0);
#endif // _LCD_H_
-1
View File
@@ -20,7 +20,6 @@
#include "opentx.h"
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay)
{
lcdDrawTextAlignedLeft(y, str);
+3 -3
View File
@@ -101,7 +101,7 @@ enum MenuModelIndexes {
#if defined(LUA_MODEL_SCRIPTS)
MENU_MODEL_CUSTOM_SCRIPTS,
#endif
CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY)
MENU_MODEL_TELEMETRY,
MENU_MODEL_DISPLAY,
MENU_MODEL_PAGES_COUNT
};
@@ -124,7 +124,7 @@ void menuModelGVars(event_t event);
void menuModelLogicalSwitches(event_t event);
void menuModelSpecialFunctions(event_t event);
void menuModelCustomScripts(event_t event);
void menuModelTelemetryFrsky(event_t event);
void menuModelTelemetry(event_t event);
void menuModelSensor(event_t event);
void menuModelDisplay(event_t event);
void menuModelTemplates(event_t event);
@@ -144,7 +144,7 @@ static const MenuHandlerFunc menuTabModel[] = {
#if defined(LUA_MODEL_SCRIPTS)
menuModelCustomScripts,
#endif
CASE_FRSKY(menuModelTelemetryFrsky)
menuModelTelemetry,
menuModelDisplay,
};
+1 -1
View File
@@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
extern uint8_t g_moduleIdx;
@@ -154,7 +154,6 @@ void menuModelLogicalSwitchOne(event_t event)
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
#if defined(TELEMETRY_FRSKY)
if (v1_val >= MIXSRC_FIRST_TELEM) {
drawSourceCustomValue(CSWONE_2ND_COLUMN, y, v1_val, convertLswTelemValue(cs), attr|LEFT);
v2_max = maxTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1);
@@ -171,7 +170,6 @@ void menuModelLogicalSwitchOne(event_t event)
}
}
else
#endif // TELEMETRY_FRSKY
{
LcdFlags lf = attr | LEFT;
getMixSrcRange(v1_val, v2_min, v2_max, &lf);
+22 -27
View File
@@ -192,7 +192,19 @@ enum MenuModelSetupItems {
#endif
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0)
#define EXTERNAL_MODULE_TYPE_ROWS (isModulePXX1(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
{
if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE))
return 1;
#if defined(MULTIMODULE)
else if (isModuleMultimodule(EXTERNAL_MODULE)) {
return 1;
}
#endif
else
return 0;
}
#define POT_WARN_ROWS ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0)
#define TIMER_ROWS 2, 0, 0, 0, 0
@@ -315,7 +327,7 @@ void menuModelSetup(event_t event)
INTERNAL_MODULE_ROWS
LABEL(ExternalModule),
EXTERNAL_MODULE_TYPE_ROWS,
EXTERNAL_MODULE_TYPE_ROW(),
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
EXTERNAL_MODULE_POWER_ROW,
MULTIMODULE_STATUS_ROWS
@@ -336,7 +348,7 @@ void menuModelSetup(event_t event)
#else
MENU_TAB({ HEADER_LINE_COLUMNS 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, LABEL(PreflightCheck), 0, 0, NUM_SWITCHES-1, NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, 0,
LABEL(ExternalModule),
EXTERNAL_MODULE_TYPE_ROWS,
EXTERNAL_MODULE_TYPE_ROW(),
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS,
@@ -764,10 +776,7 @@ void menuModelSetup(event_t event)
if (menuHorizontalPosition == 0) {
uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable);
if (checkIncDec_Ret) {
// TODO this code should be common, in module.h (X10_new_UI branch)
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
g_model.moduleData[INTERNAL_MODULE].type = moduleType;
g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);
setModuleType(INTERNAL_MODULE, moduleType);
}
}
else if (isModuleXJT(INTERNAL_MODULE)) {
@@ -837,22 +846,9 @@ void menuModelSetup(event_t event)
switch (menuHorizontalPosition) {
case 0:
{
uint8_t moduleType = checkIncDec(event,
g_model.moduleData[EXTERNAL_MODULE].type,
MODULE_TYPE_NONE,
IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE :
MODULE_TYPE_COUNT - 1,
EE_MODEL,
isExternalModuleAvailable);
uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable);
if (checkIncDec_Ret) {
// TODO this code should be common, in module.h (X10_new_UI branch)
memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData));
g_model.moduleData[EXTERNAL_MODULE].type = moduleType;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE);
if (isModuleSBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
if (isModulePPM(EXTERNAL_MODULE))
SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE);
setModuleType(EXTERNAL_MODULE, moduleType);
}
}
break;
@@ -1078,7 +1074,7 @@ void menuModelSetup(event_t event)
case 1:
CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr);
if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) {
SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
setDefaultPpmFrameLength(moduleIdx);
}
break;
}
@@ -1538,7 +1534,6 @@ void menuModelSetup(event_t event)
}
#endif
#if 0
case ITEM_MODEL_SETUP_PPM2_PROTOCOL:
lcdDrawTextAlignedLeft(y, "Port2");
@@ -1551,11 +1546,11 @@ void menuModelSetup(event_t event)
switch (menuHorizontalPosition) {
case 0:
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[1].channelsStart, 32-8-g_model.moduleData[1].channelsCount);
SET_DEFAULT_PPM_FRAME_LENGTH(1);
setDefaultPpmFrameLength(1);
break;
case 1:
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[1].channelsCount, -4, min<int8_t>(8, 32-8-g_model.moduleData[1].channelsStart));
SET_DEFAULT_PPM_FRAME_LENGTH(1);
setDefaultPpmFrameLength(1);
break;
}
}
@@ -1588,7 +1583,7 @@ void menuModelSetup(event_t event)
}
#if defined(PXX)
if (IS_RANGECHECK_ENABLE()) {
if (isModuleInRangeCheckMode()) {
showMessageBox("RSSI: ");
lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD);
}
+19 -23
View File
@@ -54,28 +54,25 @@ enum MenuModelTelemetryFrskyItems {
#define TELEM_COL3 (17 * FW)
#define CHANNELS_ROWS
#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW)
#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), 0, 0, 0, 0,
#define USRDATA_ROWS
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 1,
#define SCREEN_TYPE_ROWS 0
#define VARIO_ROWS LABEL(Vario), 0, 1, 2,
#if defined (PCBTARANIS)
#define TELEMETRY_TYPE_SHOW_TELEMETRY (! IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0,
#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW)
#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), 0, 0, 0, 0,
#if defined(VARIO)
#define VARIO_ROWS LABEL(Vario), 0, 1, 2,
#else
#define TELEMETRY_TYPE_SHOW_TELEMETRY (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW
#define VARIO_ROWS
#endif
#if defined(PCBTARANIS)
#define TELEMETRY_TYPE_ROW (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW
#else
#define TELEMETRY_TYPE_ROW (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW
#endif
#if defined(REVX)
#define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_SHOW_TELEMETRY, TELEMETRY_TYPE_SHOW_TELEMETRY,
#define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_ROW, TELEMETRY_TYPE_ROW,
#else
#define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_SHOW_TELEMETRY,
#define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_ROW,
#endif
void onSensorMenu(const char * result)
@@ -121,13 +118,13 @@ void onDeleteAllSensorsConfirm(const char * result)
}
}
void menuModelTelemetryFrsky(event_t event)
void menuModelTelemetry(event_t event)
{
MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS VARIO_ROWS});
MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS });
uint8_t sub = menuVerticalPosition - HEADER_LINE;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i + menuVerticalOffset;
for (int j=0; j<=k; j++) {
@@ -200,7 +197,7 @@ void menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DISCOVER_SENSORS:
lcdDrawText(0, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr);
lcdDrawText(INDENT_WIDTH, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr);
if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
allowNewSensors = !allowNewSensors;
@@ -223,7 +220,7 @@ void menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DELETE_ALL_SENSORS:
lcdDrawText(0, y, STR_DELETE_ALL_SENSORS, attr);
lcdDrawText(INDENT_WIDTH, y, STR_DELETE_ALL_SENSORS, attr);
if (attr) {
s_editMode = 0;
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
@@ -237,7 +234,6 @@ void menuModelTelemetryFrsky(event_t event)
ON_OFF_MENU_ITEM(g_model.ignoreSensorIds, TELEM_COL2, y, STR_IGNORE_INSTANCE, attr, event);
break;
case ITEM_TELEMETRY_RSSI_LABEL:
#if defined(MULTIMODULE)
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
+1 -1
View File
@@ -529,7 +529,7 @@ void menuRadioSetup(event_t event)
break;
#endif
#if defined(TELEMETRY_FRSKY) && defined(GPS)
#if defined(GPS)
case ITEM_RADIO_SETUP_TIMEZONE:
lcdDrawTextAlignedLeft(y, STR_TIMEZONE);
lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT);
-14
View File
@@ -47,15 +47,12 @@
#define TRIM_LH_POS (TRIM_LH_X-4*FW)
#define TRIM_RH_NEG (TRIM_RH_X+1*FW)
#define TRIM_RH_POS (TRIM_RH_X-4*FW)
#if defined(TELEMETRY_FRSKY)
#define RSSSI_X (30)
#define RSSSI_Y (31)
#define RSSI_MAX 105
#endif
#define TRIM_LEN 23
#if defined(TELEMETRY_FRSKY)
void drawRSSIGauge()
{
uint8_t bar = (RSSI_MAX - g_model.rssiAlarms.getWarningRssi()) / 4;
@@ -66,7 +63,6 @@ void drawRSSIGauge()
}
}
}
#endif
void drawPotsBars()
{
@@ -276,15 +272,11 @@ void onMainViewMenu(const char *result)
POPUP_MENU_ADD_ITEM(STR_RESET_TIMER1);
POPUP_MENU_ADD_ITEM(STR_RESET_TIMER2);
POPUP_MENU_ADD_ITEM(STR_RESET_TIMER3);
#if defined(TELEMETRY_FRSKY)
POPUP_MENU_ADD_ITEM(STR_RESET_TELEMETRY);
#endif
}
#if defined(TELEMETRY_FRSKY)
else if (result == STR_RESET_TELEMETRY) {
telemetryReset();
}
#endif
else if (result == STR_RESET_FLIGHT) {
flightReset();
}
@@ -385,11 +377,7 @@ void menuMainView(event_t event)
#endif
case EVT_KEY_TELEMETRY:
#if defined(TELEMETRY_FRSKY)
chainMenu(menuViewTelemetryFrsky);
#else
chainMenu(menuStatisticsDebug);
#endif
killEvents(event);
break;
@@ -419,12 +407,10 @@ void menuMainView(event_t event)
// Trims sliders
displayTrims(mode);
#if defined(TELEMETRY_FRSKY)
// RSSI gauge
if (TELEMETRY_RSSI() > 0) {
drawRSSIGauge();
}
#endif
}
if (view_base < VIEW_INPUTS) {
+5 -5
View File
@@ -184,18 +184,18 @@ void menuStatisticsDebug(event_t event)
#if defined(COPROCESSOR)
lcdDrawTextAlignedLeft(y, STR_COPROC_TEMP);
if (Coproc_read==0) {
if (coprocData.read==0) {
lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Co Proc NACK",INVERS);
}
else if (Coproc_read==0x81) {
else if (coprocData.read==0x81) {
lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Inst.TinyApp",INVERS);
}
else if (Coproc_read<3) {
else if (coprocData.read<3) {
lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Upgr.TinyApp",INVERS);
}
else {
drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, Coproc_temp, UNIT_TEMPERATURE, LEFT);
drawValueWithUnit(MENU_DEBUG_COL2_OFS, y, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, coprocData.temp, UNIT_TEMPERATURE, LEFT);
drawValueWithUnit(MENU_DEBUG_COL2_OFS, y, coprocData.maxtemp, UNIT_TEMPERATURE, LEFT);
}
y += FH;
#endif
-1
View File
@@ -170,7 +170,6 @@ void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0,
void lcdClear();
uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height);
const char * writeScreenshot();
#if defined(BOOT)
#define BLINK_ON_PHASE (0)
+1 -1
View File
@@ -37,7 +37,7 @@ const MenuHandlerFunc menuTabModel[] = {
#if defined(LUA_MODEL_SCRIPTS)
menuModelCustomScripts,
#endif
CASE_FRSKY(menuModelTelemetryFrsky)
menuModelTelemetry,
menuModelDisplay
};
+2 -2
View File
@@ -94,7 +94,7 @@ enum MenuModelIndexes {
#if defined(LUA_MODEL_SCRIPTS)
MENU_MODEL_CUSTOM_SCRIPTS,
#endif
MENU_MODEL_TELEMETRY_FRSKY,
MENU_MODEL_TELEMETRY,
MENU_MODEL_DISPLAY,
MENU_MODEL_PAGES_COUNT
};
@@ -117,7 +117,7 @@ void menuModelGVars(event_t event);
void menuModelLogicalSwitches(event_t event);
void menuModelSpecialFunctions(event_t event);
void menuModelCustomScripts(event_t event);
void menuModelTelemetryFrsky(event_t event);
void menuModelTelemetry(event_t event);
void menuModelSensor(event_t event);
void menuModelDisplay(event_t event);
+1 -1
View File
@@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
extern uint8_t g_moduleIdx;
+15 -23
View File
@@ -246,7 +246,7 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
#define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0
inline uint8_t EXTERNAL_MODULE_MODE_ROW()
inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
{
if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE))
return 1;
@@ -363,7 +363,7 @@ void menuModelSetup(event_t event)
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3
LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROW(),
EXTERNAL_MODULE_TYPE_ROW(),
MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS,
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS),
@@ -763,10 +763,7 @@ void menuModelSetup(event_t event)
if (menuHorizontalPosition == 0) {
uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable);
if (checkIncDec_Ret) {
// TODO this code should be common, in module.h (X10_new_UI branch)
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
g_model.moduleData[INTERNAL_MODULE].type = moduleType;
g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);
setModuleType(INTERNAL_MODULE, moduleType);
}
}
else if (isModuleXJT(INTERNAL_MODULE)) {
@@ -821,15 +818,15 @@ void menuModelSetup(event_t event)
// Do not use MODEL_SETUP_3RD_COLUMN here since some the protocol string are so long that we cannot afford the 2 spaces (+6) here
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) {
lcdDrawText(lcdNextPos + FW, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0);
lcdDrawNumber(lcdNextPos + FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2);
lcdDrawNumber(lcdNextPos + FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2);
lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0);
lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2);
lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2);
}
else {
lcdDrawTextAtIndex(lcdNextPos + FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto);
if (pdef->subTypeString) {
lcdDrawTextAtIndex(lcdNextPos + FW, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
lcdDrawTextAtIndex(lcdNextPos + 3, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
}
}
}
@@ -838,19 +835,14 @@ void menuModelSetup(event_t event)
if (s_editMode > 0) {
switch (menuHorizontalPosition) {
case 0:
g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE,
IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : MODULE_TYPE_COUNT - 1, EE_MODEL,
isExternalModuleAvailable);
{
uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE);
if (isModuleSBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
if (isModulePPM(EXTERNAL_MODULE))
SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE);
setModuleType(EXTERNAL_MODULE, moduleType);
}
break;
}
case 1:
if (isModuleDSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
@@ -1041,7 +1033,7 @@ void menuModelSetup(event_t event)
case 1:
CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr);
if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) {
SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
setDefaultPpmFrameLength(moduleIdx);
}
break;
}
@@ -1409,7 +1401,7 @@ void menuModelSetup(event_t event)
}
#if defined(PXX)
if (IS_RANGECHECK_ENABLE()) {
if (isModuleInRangeCheckMode()) {
showMessageBox("RSSI: ");
lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD | LEFT);
}
+55 -26
View File
@@ -23,6 +23,7 @@
enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_PROTOCOL_TYPE,
ITEM_TELEMETRY_RSSI_LABEL,
ITEM_TELEMETRY_RSSI_SOURCE,
ITEM_TELEMETRY_RSSI_ALARM1,
ITEM_TELEMETRY_RSSI_ALARM2,
ITEM_TELEMETRY_DISABLE_ALARMS,
@@ -45,6 +46,7 @@ enum MenuModelTelemetryFrskyItems {
#define TELEM_COL2 (16*FW)
#define TELEM_COL3 (30*FW+2)
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0,
#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW)
#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40), SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50), SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59), 0, 0, 0, 0,
#if defined(VARIO)
@@ -52,12 +54,11 @@ enum MenuModelTelemetryFrskyItems {
#else
#define VARIO_ROWS
#endif
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0,
#define TELEMETRY_TYPE_ROWS (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW,
void onSensorMenu(const char * result)
{
uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR_FIRST;
uint8_t index = menuVerticalPosition - HEADER_LINE - ITEM_TELEMETRY_SENSOR_FIRST;
if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) {
@@ -69,11 +70,10 @@ void onSensorMenu(const char * result)
if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1;
else
menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR;
menuVerticalPosition = HEADER_LINE + ITEM_TELEMETRY_NEW_SENSOR;
}
else if (result == STR_COPY) {
int newIndex = availableTelemetryIndex();
if (newIndex >= 0) {
TelemetrySensor & sourceSensor = g_model.telemetrySensors[index];
TelemetrySensor & newSensor = g_model.telemetrySensors[newIndex];
@@ -90,27 +90,35 @@ void onSensorMenu(const char * result)
}
}
void menuModelTelemetryFrsky(event_t event)
void onDeleteAllSensorsConfirm(const char * result)
{
if (warningResult) {
warningResult = 0;
if (result == STR_OK) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
}
}
MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, ITEM_TELEMETRY_MAX, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS });
void menuModelTelemetry(event_t event)
{
MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS });
uint8_t sub = menuVerticalPosition - HEADER_LINE;
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
int k = i + menuVerticalOffset;
uint8_t k = i + menuVerticalOffset;
for (int j=0; j<=k; j++) {
if (mstate_tab[j] == HIDDEN_ROW)
k++;
if (mstate_tab[j+HEADER_LINE] == HIDDEN_ROW) {
if (++k >= (int)DIM(mstate_tab)) {
return;
}
}
}
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
LcdFlags attr = (sub == k ? blink : 0);
if (k >= ITEM_TELEMETRY_SENSOR_FIRST && k <= ITEM_TELEMETRY_SENSOR_LAST) {
int index = k - ITEM_TELEMETRY_SENSOR_FIRST;
@@ -124,9 +132,11 @@ void menuModelTelemetryFrsky(event_t event)
if (telemetryItem.isAvailable()) {
bool isOld = telemetryItem.isOld();
lcdNextPos = TELEM_COL2;
if (isOld) lcdDrawChar(lcdNextPos, y, '[');
if (isOld)
lcdDrawChar(lcdNextPos, y, '[');
drawSensorCustomValue(lcdNextPos, y, index, getValue(MIXSRC_FIRST_TELEM+3*index), LEFT);
if (isOld) lcdDrawChar(lcdLastRightPos, y, ']');
if (isOld)
lcdDrawChar(lcdLastRightPos, y, ']');
}
else {
lcdDrawText(TELEM_COL2, y, "---", 0); // TODO shortcut
@@ -164,7 +174,9 @@ void menuModelTelemetryFrsky(event_t event)
case ITEM_TELEMETRY_PROTOCOL_TYPE:
lcdDrawTextAlignedLeft(y, STR_TELEMETRY_TYPE);
lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr);
g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable);
if (attr) {
g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable);
}
break;
case ITEM_TELEMETRY_SENSORS_LABEL:
@@ -176,7 +188,7 @@ void menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DISCOVER_SENSORS:
lcdDrawText(0, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr);
lcdDrawText(INDENT_WIDTH, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr);
if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
allowNewSensors = !allowNewSensors;
@@ -199,12 +211,13 @@ void menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DELETE_ALL_SENSORS:
lcdDrawText(0, y, STR_DELETE_ALL_SENSORS, attr);
if (attr)
lcdDrawText(INDENT_WIDTH, y, STR_DELETE_ALL_SENSORS, attr);
if (attr) {
s_editMode = 0;
if (attr && event==EVT_KEY_LONG(KEY_ENTER)) {
killEvents(KEY_ENTER);
POPUP_CONFIRMATION(STR_CONFIRMDELETE, nullptr);
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
killEvents(KEY_ENTER);
POPUP_CONFIRMATION(STR_CONFIRMDELETE, onDeleteAllSensorsConfirm);
}
}
break;
@@ -214,17 +227,32 @@ void menuModelTelemetryFrsky(event_t event)
case ITEM_TELEMETRY_RSSI_LABEL:
#if defined(MULTIMODULE)
if (g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_XJT_PXX1 &&
g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE &&
g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
lcdDrawTextAlignedLeft(y, "RSNR");
else
#endif
lcdDrawTextAlignedLeft(y, "RSSI");
#else
lcdDrawTextAlignedLeft(y, "RSSI");
#endif
break;
case ITEM_TELEMETRY_RSSI_SOURCE: {
lcdDrawTextAlignedLeft(y, INDENT TR_SOURCE);
drawSource(TELEM_COL2, y, g_model.rssiSource ? MIXSRC_FIRST_TELEM + 3 * (g_model.rssiSource - 1) : 0, attr);
if (g_model.rssiSource) {
TelemetrySensor * sensor = &g_model.telemetrySensors[g_model.rssiSource - 1];
lcdDrawText(lcdNextPos, y, " ", attr);
drawReceiverName(lcdNextPos, y, sensor->frskyInstance.rxIndex >> 2, sensor->frskyInstance.rxIndex & 0x03, attr);
}
if (attr) {
g_model.rssiSource = checkIncDec(event, g_model.rssiSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL | NO_INCDEC_MARKS, isRssiSensorAvailable);
}
break;
}
case ITEM_TELEMETRY_RSSI_ALARM1:
case ITEM_TELEMETRY_RSSI_ALARM2: {
case ITEM_TELEMETRY_RSSI_ALARM2:
{
bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1);
lcdDrawTextAlignedLeft(y, (warning ? STR_LOWALARM : STR_CRITICALALARM));
lcdDrawNumber(TELEM_COL2, y, warning? g_model.rssiAlarms.getWarningRssi() : g_model.rssiAlarms.getCriticalRssi(), LEFT|attr, 3);
@@ -236,6 +264,7 @@ void menuModelTelemetryFrsky(event_t event)
}
break;
}
case ITEM_TELEMETRY_DISABLE_ALARMS:
g_model.rssiAlarms.disabled = editCheckBox(g_model.rssiAlarms.disabled, TELEM_COL3, y, STR_DISABLE_ALARM, attr, event);
break;
+4 -4
View File
@@ -159,13 +159,13 @@ void menuRadioSetup(event_t event)
CASE_SPLASH_PARAM(0) // disable splash
CASE_PWR_BUTTON_PRESS(0) // pwr on speed
CASE_PWR_BUTTON_PRESS(0) // pwr off speed
CASE_PXX2(0)
CASE_PXX2(0) // owner registration ID
CASE_GPS(LABEL(GPS))
CASE_GPS(0) // timezone
CASE_GPS(0) // adjust RTC
CASE_GPS(0) // GPS format
CASE_PXX1(0) // country code
0, // language
CASE_PXX1(0) // country code
0, // voice language
0, // imperial
IF_FAI_CHOICE(0)
0, // switches delay
@@ -484,7 +484,7 @@ void menuRadioSetup(event_t event)
break;
#endif
#if defined(TELEMETRY_FRSKY) && defined(GPS)
#if defined(GPS)
case ITEM_RADIO_SETUP_LABEL_GPS:
lcdDrawTextAlignedLeft(y, STR_GPS);
break;
+1 -1
View File
@@ -36,7 +36,7 @@ const MenuHandlerFunc menuTabModel[] = {
#if defined(LUA_MODEL_SCRIPTS)
menuModelCustomScripts,
#endif
CASE_FRSKY(menuModelTelemetryFrsky)
menuModelTelemetry
};
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags attr);
+86 -19
View File
@@ -22,6 +22,7 @@
#define _MENUS_H_
#include "keys.h"
#include "audio.h"
#define MENU_COLUMN2_X 280
#define MIXES_2ND_COLUMN 140
@@ -106,6 +107,7 @@ enum MenuIcons {
ICON_MONITOR_CHANNELS3,
ICON_MONITOR_CHANNELS4,
ICON_MONITOR_LOGICAL_SWITCHES,
ICON_RADIO_SPECTRUM_ANALYSER,
MENUS_ICONS_COUNT
};
@@ -123,7 +125,7 @@ enum EnumTabModel {
#if defined(LUA_MODEL_SCRIPTS)
MENU_MODEL_CUSTOM_SCRIPTS,
#endif
CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY)
MENU_MODEL_TELEMETRY,
MENU_MODEL_PAGES_COUNT
};
@@ -177,7 +179,7 @@ bool menuModelGVars(event_t event);
bool menuModelLogicalSwitches(event_t event);
bool menuModelSpecialFunctions(event_t event);
bool menuModelCustomScripts(event_t event);
bool menuModelTelemetryFrsky(event_t event);
bool menuModelTelemetry(event_t event);
bool menuModelSensor(event_t event);
bool menuModelExpoOne(event_t event);
bool menuModelModuleOptions(event_t event);
@@ -330,7 +332,7 @@ extern const CheckIncDecStops &stopsSwitch;
(val), (val+1)
int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100);
swsrc_t checkIncDecMovedSwitch(swsrc_t val);
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
#define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
#define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
@@ -438,11 +440,15 @@ void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlag
extern uint8_t s_curveChan;
#define WARNING_TYPE_ALERT 0
#define WARNING_TYPE_ASTERISK 1
#define WARNING_TYPE_CONFIRM 2
#define WARNING_TYPE_INPUT 3
#define WARNING_TYPE_INFO 4
enum
{
WARNING_TYPE_WAIT,
WARNING_TYPE_INFO,
WARNING_TYPE_ASTERISK,
WARNING_TYPE_CONFIRM,
WARNING_TYPE_INPUT,
WARNING_TYPE_ALERT
};
extern const char * warningText;
extern const char * warningInfoText;
@@ -480,23 +486,20 @@ void insertMix(uint8_t idx);
#define WARNING_INFOLINE_Y (WARNING_LINE_Y+68)
void copySelection(char * dst, const char * src, uint8_t size);
void drawPopupBackgroundAndBorder(coord_t x, coord_t y, coord_t w, coord_t h);
void showMessageBox(const char * title);
void runPopupWarning(event_t event);
extern void (* popupFunc)(event_t event);
typedef void (* PopupFunc)(event_t event);
extern PopupFunc popupFunc;
extern uint8_t warningInfoFlags;
#define DISPLAY_WARNING(evt) (*popupFunc)(evt)
#define POPUP_INFORMATION(s) (warningText = s, warningType = WARNING_TYPE_INFO, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_WARNING(s) (warningType = WARNING_TYPE_ASTERISK, warningText = s, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_INPUT(s, func) (warningText = s, popupFunc = func)
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
inline void DISPLAY_WARNING(event_t event)
{
(*popupFunc)(event);
}
#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuItemsCount++] = s; } while (0)
#define POPUP_MENU_SELECT_ITEM(s) popupMenuSelectedItem = (s > 0 ? (s < popupMenuItemsCount ? s : popupMenuItemsCount - 1) : 0)
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while(0)
#define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 9
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
@@ -511,7 +514,71 @@ enum {
extern uint8_t popupMenuOffsetType;
extern uint8_t popupMenuSelectedItem;
const char * runPopupMenu(event_t event);
extern void (*popupMenuHandler)(const char * result);
typedef void (* PopupMenuHandler)(const char * result);
extern PopupMenuHandler popupMenuHandler;
inline void POPUP_INPUT(const char * s, PopupFunc func)
{
warningText = s;
warningInfoText = nullptr;
warningType = WARNING_TYPE_INPUT;
popupFunc = func;
}
inline void SET_WARNING_INFO(const char * info, uint8_t length, uint8_t flags)
{
warningInfoText = info;
warningInfoLength = length;
warningInfoFlags = flags;
}
inline void POPUP_MENU_ADD_ITEM(const char * s)
{
popupMenuOffsetType = MENU_OFFSET_INTERNAL;
if (popupMenuItemsCount < POPUP_MENU_MAX_LINES)
popupMenuItems[popupMenuItemsCount++] = s;
}
inline void POPUP_MENU_SELECT_ITEM(uint8_t index)
{
popupMenuSelectedItem = (index > 0 ? (index < popupMenuItemsCount ? index : popupMenuItemsCount - 1) : 0);
}
inline void POPUP_MENU_START(PopupMenuHandler handler)
{
popupMenuHandler = handler;
AUDIO_KEY_PRESS();
}
inline void CLEAR_POPUP()
{
warningText = nullptr;
}
inline void POPUP_WAIT(const char * s)
{
warningText = s;
warningInfoText = nullptr;
warningType = WARNING_TYPE_WAIT;
popupFunc = runPopupWarning;
}
inline void POPUP_INFORMATION(const char * s)
{
warningText = s;
warningInfoText = nullptr;
warningType = WARNING_TYPE_INFO;
popupFunc = runPopupWarning;
}
inline void POPUP_WARNING(const char * s)
{
warningText = s;
warningInfoText = nullptr;
warningType = WARNING_TYPE_ASTERISK;
popupFunc = runPopupWarning;
}
inline void POPUP_CONFIRMATION(const char *s, void (* confirmHandler)(const char *) = nullptr)
{
+1 -1
View File
@@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
extern uint8_t g_moduleIdx;
+2 -2
View File
@@ -178,7 +178,6 @@ bool menuModelExpoOne(event_t event)
SUBMENU_WITH_OPTIONS(STR_MENUINPUTS, ICON_MODEL_INPUTS, EXPO_FIELD_MAX, OPTION_MENU_NO_FOOTER|OPTION_MENU_NO_SCROLLBAR, { 0, 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW), 0, 0, CURVE_ROWS, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
lcdDrawSizedText(50, 3+FH, g_model.inputNames[ed->chn], LEN_INPUT_NAME, ZCHAR|MENU_TITLE_COLOR);
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, 230, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
int sub = menuVerticalPosition;
@@ -241,7 +240,8 @@ bool menuModelExpoOne(event_t event)
case EXPO_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SOURCE);
drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, menuHorizontalPosition==0 ? attr : 0);
if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
if (attr && menuHorizontalPosition==0)
ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+75, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0));
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
@@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
#include <math.h>
#define RECEIVER_OPTIONS_2ND_COLUMN 200
+69 -100
View File
@@ -122,47 +122,22 @@ enum MenuModelSetupItems {
#define MODEL_SETUP_SLIDPOT_SPACING 45
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? k : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1))
#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1 : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1))
#include "common/stdlcd/model_setup_pxx1.cpp"
bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx)
{
return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
}
void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx)
{
memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx);
storageDirty(EE_MODEL);
}
void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx)
{
if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) {
removePXX2Receiver(moduleIdx, receiverIdx);
}
}
const char * STR_BIND_8CH_WITH_TELEM = TR("8CH with telem.", "8CH with telemetry");
const char * STR_BIND_16CH_WITH_TELEM = TR("16CH with telem.", "16CH with telemetry");
const char * STR_BIND_16CH_WITHOUT_TELEM = TR("16CH without telem.", "16CH without telemetry");
const char * STR_BIND_FLEX_868 = "Flex 868MHz";
const char * STR_BIND_FLEX_915 = "Flex 915MHz";
void onPXX2R9MBindModeMenu(const char * result)
{
if (result == STR_BIND_16CH_WITH_TELEM) {
if (result == STR_16CH_WITH_TELEMETRY) {
reusableBuffer.moduleSetup.bindInformation.lbtMode = 1;
}
else if (result == STR_BIND_16CH_WITHOUT_TELEM) {
else if (result == STR_16CH_WITHOUT_TELEMETRY) {
reusableBuffer.moduleSetup.bindInformation.lbtMode = 2;
}
else if (result == STR_BIND_FLEX_868) {
else if (result == STR_FLEX_915) {
reusableBuffer.moduleSetup.bindInformation.flexMode = 0;
}
else if (result == STR_BIND_FLEX_915) {
else if (result == STR_FLEX_868) {
reusableBuffer.moduleSetup.bindInformation.flexMode = 1;
}
else {
@@ -170,6 +145,7 @@ void onPXX2R9MBindModeMenu(const char * result)
uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition);
moduleState[moduleIdx].mode = MODULE_MODE_NORMAL;
reusableBuffer.moduleSetup.bindInformation.step = 0;
removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx);
return;
}
@@ -498,7 +474,7 @@ int getSwitchWarningsCount()
#define TIMER_ROWS(x) NAVIGATION_LINE_BY_LINE|1, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 : (uint8_t)0
inline uint8_t EXTERNAL_MODULE_MODE_ROW()
inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
{
if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE))
return 1;
@@ -533,24 +509,6 @@ inline uint8_t EXTERNAL_MODULE_MODE_ROW()
#define REGISTRATION_ID_ROWS
#endif
void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags)
{
if (isModulePXX2(moduleIdx)) {
if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0')
lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags);
else
lcdDrawText(x, y, "---", flags);
}
#if defined(HARDWARE_INTERNAL_MODULE)
else if (moduleIdx == INTERNAL_MODULE) {
lcdDrawText(x, y, "Internal", flags);
}
#endif
else {
lcdDrawText(x, y, "External", flags);
}
}
#if defined(EXTERNAL_ANTENNA)
#define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), // Antenna
void onAntennaSwitchConfirm(const char * result)
@@ -610,7 +568,7 @@ bool menuModelSetup(event_t event)
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */
LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROW(),
EXTERNAL_MODULE_TYPE_ROW(),
MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS,
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS),
@@ -790,7 +748,8 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_SETUP_THROTTLE_TRACE:
{
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS);
// check if source is available (EXT1 & EXT2 on X10)
if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS, isThrottleSourceAvailable);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr)
idx += 1;
@@ -992,10 +951,7 @@ bool menuModelSetup(event_t event)
if (menuHorizontalPosition == 0) {
uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable);
if (checkIncDec_Ret) {
// TODO this code should be common, in module.h (X10_new_UI branch)
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
g_model.moduleData[INTERNAL_MODULE].type = moduleType;
g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);
setModuleType(INTERNAL_MODULE, moduleType);
}
}
else if (isModuleXJT(INTERNAL_MODULE)) {
@@ -1062,19 +1018,14 @@ bool menuModelSetup(event_t event)
if (s_editMode > 0) {
switch (menuHorizontalPosition) {
case 0:
g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type,
MODULE_TYPE_NONE, MODULE_TYPE_COUNT - 1, EE_MODEL,
isExternalModuleAvailable);
{
uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE);
if (isModuleSBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
if (isModulePPM(EXTERNAL_MODULE))
SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE);
setModuleType(EXTERNAL_MODULE, moduleType);
}
break;
}
case 1:
if (isModuleDSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
@@ -1110,6 +1061,7 @@ bool menuModelSetup(event_t event)
g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE);
}
break;
#if defined(MULTIMODULE)
case 2:
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) {
@@ -1172,7 +1124,7 @@ bool menuModelSetup(event_t event)
case 1:
CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr);
if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) {
SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
setDefaultPpmFrameLength(moduleIdx);
}
break;
}
@@ -1282,6 +1234,7 @@ bool menuModelSetup(event_t event)
#endif
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER_NUM);
@@ -1301,6 +1254,7 @@ bool menuModelSetup(event_t event)
break;
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODULE);
@@ -1339,6 +1293,9 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1:
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2:
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
@@ -1346,60 +1303,72 @@ bool menuModelSetup(event_t event)
drawStringWithIndex(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER, receiverIdx + 1);
if (!(g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx))) {
if (!isPXX2ReceiverUsed(moduleIdx, receiverIdx)) {
drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, attr);
if (attr && s_editMode > 0) {
s_editMode = 0;
killEvents(event);
g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx);
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
setPXX2ReceiverUsed(moduleIdx, receiverIdx);
memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
storageDirty(EE_MODEL);
}
else {
break;
onPXX2ReceiverMenu(STR_BIND);
}
break;
}
drawReceiverName(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, receiverIdx, attr);
if (s_editMode && isModuleR9MAccess(moduleIdx) && moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && moduleInformation.information.modelID) {
moduleInformation.information.modelID = 0;
moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation);
if (s_editMode && isModuleR9MAccess(moduleIdx) && moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && reusableBuffer.moduleSetup.bindInformation.step < 0) {
if (reusableBuffer.moduleSetup.bindInformation.step == BIND_MODULE_TX_INFORMATION_REQUEST && moduleInformation.information.modelID) {
// For R9M ACCESS the module information has been requested to know if we are in EU mode. We just receive it here and continue
if (moduleInformation.information.variant == PXX2_VARIANT_EU) {
// In EU mode we will need the power of the module to know if telemetry can be proposed
reusableBuffer.moduleSetup.bindInformation.step = BIND_MODULE_TX_SETTINGS_REQUEST;
#if defined(SIMU)
reusableBuffer.moduleSetup.pxx2.moduleSettings.txPower = 14;
break;
#else
moduleState[moduleIdx].readModuleSettings(&reusableBuffer.moduleSetup.pxx2.moduleSettings);
#endif
}
else {
reusableBuffer.moduleSetup.bindInformation.step = 0;
moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation);
}
}
else if (reusableBuffer.moduleSetup.bindInformation.step == BIND_MODULE_TX_SETTINGS_REQUEST && reusableBuffer.moduleSetup.pxx2.moduleSettings.txPower > 0) {
// We just receive the module settings (for TX power)
reusableBuffer.moduleSetup.bindInformation.step = 0;
moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation);
}
}
if (attr && (moduleState[moduleIdx].mode == 0 || s_editMode == 0)) {
else if (attr && (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL || s_editMode == 0)) {
if (moduleState[moduleIdx].mode) {
moduleState[moduleIdx].mode = 0;
removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx);
killEvents(event); // we stopped BIND / SHARE, we don't want to re-open the menu
event = 0;
CLEAR_POPUP();
}
s_editMode = 0;
}
if (moduleState[moduleIdx].mode == MODULE_MODE_BIND) {
if (reusableBuffer.moduleSetup.bindInformation.step == BIND_INIT && reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount > 0) {
popupMenuItemsCount = min<uint8_t>(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE);
for (uint8_t i=0; i<popupMenuItemsCount; i++) {
popupMenuItems[i] = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[i];
if (reusableBuffer.moduleSetup.bindInformation.step == BIND_INIT) {
if (reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount > 0) {
popupMenuItemsCount = min<uint8_t>(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE);
for (auto rx = 0; rx < popupMenuItemsCount; rx++) {
popupMenuItems[rx] = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[rx];
}
// popupMenuTitle = STR_PXX2_SELECT_RX;
POPUP_MENU_START(onPXX2BindMenu);
}
//popupMenuTitle = STR_PXX2_SELECT_RX; // TODO : fix
POPUP_MENU_START(onPXX2BindMenu);
}
}
if (attr && EVT_KEY_MASK(event) == KEY_ENTER) {
killEvents(event);
if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) {
onPXX2ReceiverMenu(STR_BIND);
}
else {
POPUP_MENU_ADD_ITEM(STR_BIND);
POPUP_MENU_ADD_ITEM(STR_OPTIONS);
POPUP_MENU_ADD_ITEM(STR_SHARE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
POPUP_MENU_ADD_ITEM(STR_RESET);
}
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
POPUP_MENU_ADD_ITEM(STR_BIND);
POPUP_MENU_ADD_ITEM(STR_OPTIONS);
POPUP_MENU_ADD_ITEM(STR_SHARE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
POPUP_MENU_ADD_ITEM(STR_RESET);
POPUP_MENU_START(onPXX2ReceiverMenu);
}
}
@@ -1664,7 +1633,7 @@ bool menuModelSetup(event_t event)
}
}
if (IS_RANGECHECK_ENABLE()) {
if (isModuleInRangeCheckMode()) {
theme->drawMessageBox("RSSI :", NULL, NULL, WARNING_TYPE_INFO);
lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, TELEMETRY_RSSI(), DBLSIZE|LEFT);
}
@@ -1698,4 +1667,4 @@ bool menuModelSetup(event_t event)
}
return true;
}
}
+32 -73
View File
@@ -23,70 +23,13 @@
enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_PROTOCOL_TYPE,
ITEM_TELEMETRY_RSSI_LABEL,
ITEM_TELEMETRY_RSSI_SOURCE,
ITEM_TELEMETRY_RSSI_ALARM1,
ITEM_TELEMETRY_RSSI_ALARM2,
ITEM_TELEMETRY_DISABLE_ALARMS,
ITEM_TELEMETRY_SENSORS_LABEL,
ITEM_TELEMETRY_SENSOR1,
ITEM_TELEMETRY_SENSOR2,
ITEM_TELEMETRY_SENSOR3,
ITEM_TELEMETRY_SENSOR4,
ITEM_TELEMETRY_SENSOR5,
ITEM_TELEMETRY_SENSOR6,
ITEM_TELEMETRY_SENSOR7,
ITEM_TELEMETRY_SENSOR8,
ITEM_TELEMETRY_SENSOR9,
ITEM_TELEMETRY_SENSOR10,
ITEM_TELEMETRY_SENSOR11,
ITEM_TELEMETRY_SENSOR12,
ITEM_TELEMETRY_SENSOR13,
ITEM_TELEMETRY_SENSOR14,
ITEM_TELEMETRY_SENSOR15,
ITEM_TELEMETRY_SENSOR16,
ITEM_TELEMETRY_SENSOR17,
ITEM_TELEMETRY_SENSOR18,
ITEM_TELEMETRY_SENSOR19,
ITEM_TELEMETRY_SENSOR20,
ITEM_TELEMETRY_SENSOR21,
ITEM_TELEMETRY_SENSOR22,
ITEM_TELEMETRY_SENSOR23,
ITEM_TELEMETRY_SENSOR24,
ITEM_TELEMETRY_SENSOR25,
ITEM_TELEMETRY_SENSOR26,
ITEM_TELEMETRY_SENSOR27,
ITEM_TELEMETRY_SENSOR28,
ITEM_TELEMETRY_SENSOR29,
ITEM_TELEMETRY_SENSOR30,
ITEM_TELEMETRY_SENSOR31,
ITEM_TELEMETRY_SENSOR32,
ITEM_TELEMETRY_SENSOR33,
ITEM_TELEMETRY_SENSOR34,
ITEM_TELEMETRY_SENSOR35,
ITEM_TELEMETRY_SENSOR36,
ITEM_TELEMETRY_SENSOR37,
ITEM_TELEMETRY_SENSOR38,
ITEM_TELEMETRY_SENSOR39,
ITEM_TELEMETRY_SENSOR40,
ITEM_TELEMETRY_SENSOR41,
ITEM_TELEMETRY_SENSOR42,
ITEM_TELEMETRY_SENSOR43,
ITEM_TELEMETRY_SENSOR44,
ITEM_TELEMETRY_SENSOR45,
ITEM_TELEMETRY_SENSOR46,
ITEM_TELEMETRY_SENSOR47,
ITEM_TELEMETRY_SENSOR48,
ITEM_TELEMETRY_SENSOR49,
ITEM_TELEMETRY_SENSOR50,
ITEM_TELEMETRY_SENSOR51,
ITEM_TELEMETRY_SENSOR52,
ITEM_TELEMETRY_SENSOR53,
ITEM_TELEMETRY_SENSOR54,
ITEM_TELEMETRY_SENSOR55,
ITEM_TELEMETRY_SENSOR56,
ITEM_TELEMETRY_SENSOR57,
ITEM_TELEMETRY_SENSOR58,
ITEM_TELEMETRY_SENSOR59,
ITEM_TELEMETRY_SENSOR60,
ITEM_TELEMETRY_SENSOR_FIRST,
ITEM_TELEMETRY_SENSOR_LAST = ITEM_TELEMETRY_SENSOR_FIRST + MAX_TELEMETRY_SENSORS - 1,
ITEM_TELEMETRY_DISCOVER_SENSORS,
ITEM_TELEMETRY_NEW_SENSOR,
ITEM_TELEMETRY_DELETE_ALL_SENSORS,
@@ -105,6 +48,7 @@ enum MenuModelTelemetryFrskyItems {
#define TELEM_COL4 350
#define TELEM_COL5 425
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0,
#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW)
#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), \
SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40),SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50),SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59), 0, 0, 0, 0,
@@ -113,12 +57,11 @@ enum MenuModelTelemetryFrskyItems {
#else
#define VARIO_ROWS
#endif
#define RSSI_ROWS LABEL(RSSI), 0, 0, 0,
#define TELEMETRY_TYPE_ROWS (g_model.moduleData[INTERNAL_MODULE].rfProtocol == MODULE_SUBTYPE_PXX1_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW,
#define TELEMETRY_TYPE_ROWS (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW,
void onSensorMenu(const char * result)
{
uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1;
uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR_FIRST;
if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) {
@@ -151,16 +94,18 @@ void onSensorMenu(const char * result)
}
}
bool menuModelTelemetryFrsky(event_t event)
void onDeleteAllSensorsConfirm(const char * result)
{
if (warningResult) {
warningResult = 0;
if (result == STR_OK) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
}
}
MENU(STR_MENUTELEMETRY, MODEL_ICONS, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, ITEM_TELEMETRY_MAX, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS });
bool menuModelTelemetry(event_t event)
{
MENU(STR_MENUTELEMETRY, MODEL_ICONS, menuTabModel, MENU_MODEL_TELEMETRY, ITEM_TELEMETRY_MAX, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS });
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_CONTENT_TOP + i*FH;
@@ -173,8 +118,8 @@ bool menuModelTelemetryFrsky(event_t event)
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_TELEMETRY_SENSORS) {
int index = k-ITEM_TELEMETRY_SENSOR1;
if (k >= ITEM_TELEMETRY_SENSOR_FIRST && k <= ITEM_TELEMETRY_SENSOR_LAST) {
int index = k - ITEM_TELEMETRY_SENSOR_FIRST;
lcdDrawNumber(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, index+1, LEFT|attr, 0, NULL, ":");
lcdDrawSizedText(60, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR);
TelemetryItem & telemetryItem = telemetryItems[index];
@@ -233,7 +178,7 @@ bool menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DISCOVER_SENSORS:
lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, allowNewSensors ? NO_INDENT(STR_STOP_DISCOVER_SENSORS) : NO_INDENT(STR_DISCOVER_SENSORS), attr);
lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr);
if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
allowNewSensors = !allowNewSensors;
@@ -256,12 +201,12 @@ bool menuModelTelemetryFrsky(event_t event)
break;
case ITEM_TELEMETRY_DELETE_ALL_SENSORS:
lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, NO_INDENT(STR_DELETE_ALL_SENSORS), attr);
lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, STR_DELETE_ALL_SENSORS, attr);
if (attr)
s_editMode = 0;
if (attr && event==EVT_KEY_LONG(KEY_ENTER)) {
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
killEvents(KEY_ENTER);
POPUP_CONFIRMATION(STR_CONFIRMDELETE);
POPUP_CONFIRMATION(STR_CONFIRMDELETE, onDeleteAllSensorsConfirm);
}
break;
@@ -281,6 +226,20 @@ bool menuModelTelemetryFrsky(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT, y, "RSSI");
break;
case ITEM_TELEMETRY_RSSI_SOURCE: {
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_SOURCE);
drawSource(TELEM_COL2, y, g_model.rssiSource ? MIXSRC_FIRST_TELEM + 3 * (g_model.rssiSource - 1) : 0, attr);
if (g_model.rssiSource) {
TelemetrySensor * sensor = &g_model.telemetrySensors[g_model.rssiSource - 1];
lcdDrawText(lcdNextPos, y, " ", attr);
drawReceiverName(lcdNextPos, y, sensor->frskyInstance.rxIndex >> 2, sensor->frskyInstance.rxIndex & 0x03, attr);
}
if (attr) {
g_model.rssiSource = checkIncDec(event, g_model.rssiSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL | NO_INCDEC_MARKS, isRssiSensorAvailable);
}
break;
}
case ITEM_TELEMETRY_RSSI_ALARM1:
case ITEM_TELEMETRY_RSSI_ALARM2: {
bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1);
+18 -20
View File
@@ -20,13 +20,13 @@
#include "opentx.h"
const char *warningText = NULL;
const char *warningText = nullptr;
const char *warningInfoText;
uint8_t warningInfoLength;
uint8_t warningType;
uint8_t warningResult = 0;
uint8_t warningInfoFlags = ZCHAR;
void (*popupFunc)(event_t event) = NULL;
PopupFunc popupFunc = nullptr;
const char *popupMenuItems[POPUP_MENU_MAX_LINES];
uint8_t popupMenuSelectedItem = 0;
uint16_t popupMenuItemsCount = 0;
@@ -34,22 +34,6 @@ uint16_t popupMenuOffset = 0;
uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL;
void (*popupMenuHandler)(const char * result);
void runPopupWarningBox()
{
// theme->drawMessageBox("", "", "", MESSAGEBOX_TYPE_WARNING);
// lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR);
// lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, ALARM_COLOR);
// lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_WARNING);
}
void drawMessageBox()
{
// theme->drawMessageBox("", "", "", MESSAGEBOX_TYPE_INFO);
// lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR);
// lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, WARNING_COLOR);
// lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_MESSAGE);
}
void drawAlertBox(const char * title, const char * text, const char * action)
{
theme->drawMessageBox(title, text, action, WARNING_TYPE_ALERT);
@@ -83,7 +67,21 @@ void runPopupWarning(event_t event)
{
warningResult = false;
theme->drawMessageBox(warningText, warningInfoText, warningType == WARNING_TYPE_INFO ? STR_OK : (warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS_ENTER_EXIT), warningType);
const char * action;
switch (warningType) {
case WARNING_TYPE_INFO:
action = STR_OK;
break;
case WARNING_TYPE_ASTERISK:
case WARNING_TYPE_WAIT:
action = STR_EXIT;
break;
default:
action = STR_POPUPS_ENTER_EXIT;
break;
}
theme->drawMessageBox(warningText, warningInfoText, action, warningType);
switch (event) {
case EVT_KEY_BREAK(KEY_ENTER):
@@ -115,7 +113,7 @@ void runPopupWarning(event_t event)
const char * runPopupMenu(event_t event)
{
const char * result = NULL;
const char * result = nullptr;
uint8_t display_count = min<unsigned int>(popupMenuItemsCount, MENU_MAX_DISPLAY_LINES);
+39 -9
View File
@@ -52,6 +52,8 @@ enum MenuRadioHardwareItems {
ITEM_RADIO_HARDWARE_SH,
ITEM_RADIO_HARDWARE_SI, // Gimbal switch left
ITEM_RADIO_HARDWARE_SJ, // Gimbal switch right
ITEM_RADIO_HARDWARE_BATTERY_CALIB,
ITEM_RADIO_HARDWARE_RTC_BATTERY,
ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE,
ITEM_RADIO_HARDWARE_BLUETOOTH_MODE,
ITEM_RADIO_HARDWARE_BLUETOOTH_PAIRING_CODE,
@@ -60,7 +62,6 @@ enum MenuRadioHardwareItems {
ITEM_RADIO_HARDWARE_AUX_SERIAL_MODE,
#endif
ITEM_RADIO_HARDWARE_JITTER_FILTER,
ITEM_RADIO_HARDWARE_BAT_CAL,
ITEM_RADIO_HARDWARE_MAX
};
@@ -77,7 +78,31 @@ enum MenuRadioHardwareItems {
bool menuRadioHardware(event_t event)
{
MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { 0, LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, 0, BLUETOOTH_ROWS, 0, 0, 0 });
MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, {
0 /* calibration button */,
LABEL(Sticks),
0 /* stick 1 */,
0 /* stick 2 */,
0 /* stick 3 */,
0 /* stick 4 */,
LABEL(Pots),
POTS_ROWS,
LABEL(Switches),
SWITCHES_ROWS,
0, /* battery */
READONLY_ROW, /* RTC */
0, /* max baudrate */
BLUETOOTH_ROWS,
0, /* aux serial mode */
0, /* ADC filter */
});
uint8_t sub = menuVerticalPosition;
@@ -177,11 +202,22 @@ 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;
}
case ITEM_RADIO_HARDWARE_BATTERY_CALIB:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATT_CALIB);
lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getBatteryVoltage(), attr|PREC2, 0, NULL, "V");
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
break;
case ITEM_RADIO_HARDWARE_RTC_BATTERY:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RTC_BATT);
lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getRTCBatteryVoltage(), attr|PREC2, 0, NULL, "V");
break;
case ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MAXBAUDRATE);
lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate], attr|LEFT);
@@ -232,12 +268,6 @@ bool menuRadioHardware(event_t event)
g_eeGeneral.jitterFilter = 1 - editCheckBox(b, HW_SETTINGS_COLUMN+50, y, attr, event);
break;
}
case ITEM_RADIO_HARDWARE_BAT_CAL:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATT_CALIB);
lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getBatteryVoltage(), attr|LEFT|PREC2, 0, NULL, "V");
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
break;
}
}
+19 -16
View File
@@ -18,7 +18,6 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
extern uint8_t g_moduleIdx;
@@ -32,11 +31,11 @@ enum PowerMeterFields {
POWER_METER_FIELDS_MAX
};
#define POWER_METER_MARGIN_2ND_COLUMN 180
constexpr coord_t POWER_METER_2ND_COLUMN = 100;
bool menuRadioPowerMeter(event_t event)
{
SIMPLE_SUBMENU(STR_MENU_POWER_METER, ICON_RADIO, POWER_METER_FIELDS_MAX-1);
SUBMENU(STR_MENU_POWER_METER, ICON_RADIO_SPECTRUM_ANALYSER, POWER_METER_FIELDS_MAX-1, {0, 0, READONLY_ROW, READONLY_ROW, READONLY_ROW});
if (TELEMETRY_STREAMING()) {
lcdDrawCenteredText(LCD_H/2, STR_TURN_OFF_RECEIVER);
@@ -44,51 +43,54 @@ bool menuRadioPowerMeter(event_t event)
killEvents(event);
popMenu();
}
return true;
return false;
}
if (menuEvent) {
lcdDrawCenteredText(LCD_H/2, STR_STOPPING);
lcdRefresh();
moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL;
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
/* wait 1s to resume normal operation before leaving */
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
return true;
return false;
}
if (moduleState[g_moduleIdx].mode != MODULE_MODE_POWER_METER) {
memclear(&reusableBuffer.powerMeter, sizeof(reusableBuffer.powerMeter));
reusableBuffer.powerMeter.freq = 2400000000;
reusableBuffer.powerMeter.attn = 4;
reusableBuffer.powerMeter.dirty = true;
moduleState[g_moduleIdx].mode = MODULE_MODE_POWER_METER;
}
// The warning
if (reusableBuffer.powerMeter.attn != 0)
lcdDrawCenteredText(MENU_CONTENT_TOP, STR_POWERMETER_ATTN_NEEDED, BOLD);
if (reusableBuffer.powerMeter.attn != 0) {
lcdDrawCenteredText(MENU_BODY_TOP, STR_POWERMETER_ATTN_NEEDED, BOLD | INVERS);
}
for (uint8_t i=0; i<POWER_METER_FIELDS_MAX; i++) {
LcdFlags attr = (menuVerticalPosition == i ? (s_editMode > 0 ? INVERS | BLINK : INVERS) : 0);
coord_t y = MENU_CONTENT_TOP + 30 + i * FH;
coord_t y = MENU_BODY_TOP + 2 * FH + i * FH;
switch (i) {
case POWER_METER_FREQ_RANGE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_FREQ);
lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.freq / 1000000, LEFT | attr);
lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.freq / 1000000, LEFT | attr);
lcdDrawText(lcdNextPos, y, " MHz band");
if (attr) {
reusableBuffer.powerMeter.freq = checkIncDec(event, reusableBuffer.powerMeter.freq == 900000000, 0, 1) ? 900000000 : 2400000000;
if (checkIncDec_Ret) {
reusableBuffer.powerMeter.power = 0;
reusableBuffer.powerMeter.peak = 0;
reusableBuffer.powerMeter.dirty = true;
}
}
break;
case POWER_METER_ATTENUATOR:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_ATTN);
lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, -10 * reusableBuffer.powerMeter.attn, LEFT | attr);
lcdDrawNumber(POWER_METER_2ND_COLUMN, y, -10 * reusableBuffer.powerMeter.attn, LEFT | attr);
lcdDrawText(lcdNextPos, y, " dB");
if (attr) {
reusableBuffer.powerMeter.attn = checkIncDec(event, reusableBuffer.powerMeter.attn, 0, 5, 0);
@@ -97,9 +99,9 @@ bool menuRadioPowerMeter(event_t event)
case POWER_METER_MAX:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MAX);
lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, -10 + 10 * reusableBuffer.powerMeter.attn);
lcdDrawText(lcdNextPos, y, "dBm/ ");
drawPower(lcdNextPos, y, -10 + 10 * reusableBuffer.powerMeter.attn, 0);
lcdDrawNumber(POWER_METER_2ND_COLUMN, y, -10 + 10 * reusableBuffer.powerMeter.attn);
lcdDrawText(lcdNextPos + 3, y, "dBm/ ");
drawPower(lcdNextPos + 3, y, -10 + 10 * reusableBuffer.powerMeter.attn, 0);
if (attr) {
reusableBuffer.powerMeter.attn = checkIncDec(event, reusableBuffer.powerMeter.attn, 0, 5, 0);
}
@@ -108,7 +110,7 @@ bool menuRadioPowerMeter(event_t event)
case POWER_METER_POWER:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_POWER);
if (reusableBuffer.powerMeter.power) {
lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.power + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2);
lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.power + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2);
lcdDrawText(lcdNextPos, y, "dBm");
}
break;
@@ -116,11 +118,12 @@ bool menuRadioPowerMeter(event_t event)
case POWER_METER_PEAK:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_PEAK);
if (reusableBuffer.powerMeter.peak) {
lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.peak + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2);
lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.peak + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2);
lcdDrawText(lcdNextPos, y, "dBm");
}
break;
}
}
return true;
}
+23
View File
@@ -248,6 +248,29 @@ bool menuRadioSdManager(event_t _event)
POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE);
POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE);
}
else if (!READ_ONLY() && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) {
FrSkyFirmwareInformation information;
if (readFirmwareInformation(line, information) == nullptr) {
if (information.productFamily == FIRMWARE_FAMILY_INTERNAL_MODULE)
POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE);
if (information.productFamily == FIRMWARE_FAMILY_EXTERNAL_MODULE)
POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE);
if (HAS_SPORT_UPDATE_CONNECTOR() && (information.productFamily == FIRMWARE_FAMILY_RECEIVER || information.productFamily == FIRMWARE_FAMILY_SENSOR))
POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE);
#if defined(PXX2)
if (information.productFamily == FIRMWARE_FAMILY_RECEIVER)
POPUP_MENU_ADD_ITEM(STR_FLASH_RECEIVER_OTA);
#endif
#if defined(BLUETOOTH)
if (information.productFamily == FIRMWARE_FAMILY_BLUETOOTH_CHIP)
POPUP_MENU_ADD_ITEM(STR_FLASH_BLUETOOTH_MODULE);
#endif
#if defined(HARDWARE_POWER_MANAGEMENT_UNIT)
if (information.productFamily == FIRMWARE_FAMILY_POWER_MANAGEMENT_UNIT)
POPUP_MENU_ADD_ITEM(STR_FLASH_POWER_MANAGEMENT_UNIT);
#endif
}
}
else if (isExtensionMatching(ext, SCRIPTS_EXT)) {
POPUP_MENU_ADD_ITEM(STR_EXECUTE_FILE);
}
+25 -2
View File
@@ -67,6 +67,9 @@ enum menuRadioSetupItems {
ITEM_SETUP_DIM_LEVEL,
ITEM_SETUP_FLASH_BEEP,
CASE_PWR_BUTTON_PRESS(ITEM_SETUP_PWR_OFF_SPEED)
#if defined(PXX2)
ITEM_RADIO_SETUP_OWNER_ID,
#endif
CASE_GPS(ITEM_SETUP_LABEL_GPS)
CASE_GPS(ITEM_SETUP_TIMEZONE)
CASE_GPS(ITEM_SETUP_ADJUST_RTC)
@@ -116,8 +119,21 @@ bool menuRadioSetup(event_t event)
LABEL(ALARMS), 0, 0, 0, 0,
LABEL(BACKLIGHT), 0, 0, 0, 0, 0,
CASE_PWR_BUTTON_PRESS(0)
CASE_GPS(LABEL(GPS)) CASE_GPS(0) CASE_GPS(0) CASE_GPS(0)
CASE_PXX1(0) 0, 0, FAI_CHOICE_ROW 0, 0, 0, 0, 1/*to force edit mode*/ }); // Country code - Voice Language - Units - Fai choice - Play delay - USB mode - Chan order - Mode (1 to 4)
CASE_PXX2(0) // owner registration ID
CASE_GPS(LABEL(GPS))
CASE_GPS(0) // timezone
CASE_GPS(0) // adjust RTC
CASE_GPS(0) // GPS format
CASE_PXX1(0) // country code
0, // voice language
0, // imperial
FAI_CHOICE_ROW
0, // switches delay
0, // USB mode
0, // RX channels order
0, // sticks mode
1 /*to force edit mode*/
}); // Units - Fai choice - Play delay - USB mode - Chan order - Mode (1 to 4)
if (event == EVT_ENTRY) {
reusableBuffer.generalSettings.stickMode = g_eeGeneral.stickMode;
@@ -366,6 +382,13 @@ bool menuRadioSetup(event_t event)
g_eeGeneral.alarmsFlash = editCheckBox(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, attr, event ) ;
break;
#if defined(PXX2)
case ITEM_RADIO_SETUP_OWNER_ID:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_OWNER_ID);
editName(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID, event, attr);
break;
#endif
case ITEM_SETUP_BACKLIGHT_DELAY:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BLDELAY);
lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT, 0, NULL, "s");
@@ -30,7 +30,7 @@ enum SpectrumFields {
bool menuRadioSpectrumAnalyser(event_t event)
{
SUBMENU(STR_MENU_SPECTRUM_ANALYSER, ICON_RADIO, 1, {1});
SUBMENU(STR_MENU_SPECTRUM_ANALYSER, ICON_RADIO_SPECTRUM_ANALYSER, 1, {1});
if (menuEvent) {
lcdDrawCenteredText(LCD_H/2, STR_STOPPING);
+4 -4
View File
@@ -89,14 +89,14 @@ bool menuRadioTools(event_t event)
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE);
// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
// addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE);
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE);
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE);
// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
// addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE);
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE);
#endif
#if defined(LUA)
+174 -22
View File
@@ -21,22 +21,171 @@
#include "opentx.h"
#include "options.h"
#if defined(PXX2)
constexpr coord_t COLUMN2_X = 200;
void drawPXX2Version(coord_t x, coord_t y, PXX2Version version)
{
if (version.major == 0xFF && version.minor == 0x0F && version.revision == 0x0F) {
lcdDrawText(x, y, "---");
}
else {
lcdDrawNumber(x, y, 1 + version.major, LEFT);
lcdDrawChar(lcdNextPos, y, '.');
lcdDrawNumber(lcdNextPos, y, version.minor, LEFT);
lcdDrawChar(lcdNextPos, y, '.');
lcdDrawNumber(lcdNextPos, y, version.revision, LEFT);
}
}
void drawPXX2FullVersion(coord_t x, coord_t y, PXX2Version hwVersion, PXX2Version swVersion)
{
drawPXX2Version(x, y, hwVersion);
lcdDrawText(lcdNextPos, y, "/");
drawPXX2Version(lcdNextPos, y, swVersion);
}
bool menuRadioModulesVersion(event_t event)
{
if (menuEvent) {
moduleState[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL;
moduleState[EXTERNAL_MODULE].mode = MODULE_MODE_NORMAL;
return false;
}
drawMenuTemplate(STR_MENU_MODULES_RX_VERSION, 0, RADIO_ICONS, OPTION_MENU_TITLE_BAR);
if (event == EVT_ENTRY) {
memclear(&reusableBuffer.hardwareAndSettings.modules, sizeof(reusableBuffer.hardwareAndSettings.modules));
}
if (event == EVT_ENTRY || get_tmr10ms() >= reusableBuffer.hardwareAndSettings.updateTime) {
if (isModulePXX2(INTERNAL_MODULE) && IS_INTERNAL_MODULE_ON()) {
moduleState[INTERNAL_MODULE].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE], PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1);
}
if (isModulePXX2(EXTERNAL_MODULE) && IS_EXTERNAL_MODULE_ON()) {
moduleState[EXTERNAL_MODULE].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE], PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1);
}
reusableBuffer.hardwareAndSettings.updateTime = get_tmr10ms() + 1000 /* 10s*/;
}
coord_t y = MENU_BODY_TOP - menuVerticalOffset * FH;
for (uint8_t module=0; module<NUM_MODULES; module++) {
// Label
if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) {
if (module == INTERNAL_MODULE)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_INTERNAL_MODULE);
else if (module == EXTERNAL_MODULE)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXTERNAL_MODULE);
}
y += FH;
// Module model
if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) {
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODULE);
if (module == INTERNAL_MODULE) {
if (!IS_INTERNAL_MODULE_ON()) {
lcdDrawText(COLUMN2_X, y, STR_OFF);
y += FH;
continue;
}
if (!isModulePXX2(INTERNAL_MODULE)) {
lcdDrawText(COLUMN2_X, y, STR_NO_INFORMATION);
y += FH;
continue;
}
}
else if (module == EXTERNAL_MODULE) {
if (!IS_EXTERNAL_MODULE_ON()) {
lcdDrawText(COLUMN2_X, y, STR_OFF);
y += FH;
continue;
}
if (!isModulePXX2(EXTERNAL_MODULE)) {
lcdDrawText(COLUMN2_X, y, STR_NO_INFORMATION);
y += FH;
continue;
}
}
uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].information.modelID;
lcdDrawText(COLUMN2_X, y, getPXX2ModuleName(modelId));
}
y += FH;
// Module version
if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) {
if (reusableBuffer.hardwareAndSettings.modules[module].information.modelID) {
drawPXX2FullVersion(COLUMN2_X, y, reusableBuffer.hardwareAndSettings.modules[module].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].information.swVersion);
static const char * variants[] = {"FCC", "EU", "FLEX"};
uint8_t variant = reusableBuffer.hardwareAndSettings.modules[module].information.variant - 1;
if (variant < DIM(variants)) {
lcdDrawText(lcdNextPos + 1, y, variants[variant]);
}
}
}
y += FH;
for (uint8_t receiver=0; receiver<PXX2_MAX_RECEIVERS_PER_MODULE; receiver++) {
if (reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.modelID && reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].timestamp < get_tmr10ms() + 2000) {
// Receiver model
if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) {
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER);
lcdDrawNumber(lcdNextPos + 2, y, receiver + 1);
uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.modelID;
lcdDrawText(COLUMN2_X, y, getPXX2ReceiverName(modelId));
}
y += FH;
// Receiver version
if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) {
drawPXX2FullVersion(COLUMN2_X, y, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.swVersion);
}
y += FH;
}
}
}
uint8_t lines = (y - (FH + 1)) / FH + menuVerticalOffset;
if (lines > NUM_BODY_LINES) {
drawVerticalScrollbar(LCD_W-1, FH, LCD_H-FH, menuVerticalOffset, lines, NUM_BODY_LINES);
}
switch(event) {
case EVT_ROTARY_LEFT:
if (lines > NUM_BODY_LINES) {
if (menuVerticalOffset-- == 0)
menuVerticalOffset = lines - 1;
}
break;
case EVT_ROTARY_RIGHT:
if (lines > NUM_BODY_LINES) {
if (++menuVerticalOffset + NUM_BODY_LINES > lines)
menuVerticalOffset = 0;
}
break;
case EVT_KEY_BREAK(KEY_EXIT):
if (menuVerticalOffset != 0)
menuVerticalOffset = 0;
else
popMenu();
break;
}
return true;
}
#endif
bool menuRadioVersion(event_t event)
{
char id[27];
#if 0
if (warningResult) {
warningResult = 0;
showMessageBox(STR_STORAGE_FORMAT);
storageEraseAll(false);
NVIC_SystemReset();
}
#endif
getCPUUniqueID(id);
SIMPLE_MENU(STR_MENUVERSION, RADIO_ICONS, menuTabGeneral, MENU_RADIO_VERSION, 0);
SIMPLE_MENU(STR_MENUVERSION, RADIO_ICONS, menuTabGeneral, MENU_RADIO_VERSION, 1);
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP, vers_stamp);
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + FH, date_stamp);
@@ -45,15 +194,6 @@ bool menuRadioVersion(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + 4*FH, "UID:");
lcdDrawText(MENUS_MARGIN_LEFT + 64, MENU_CONTENT_TOP + 4*FH, id);
#if 0
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
// POPUP_MENU_ADD_ITEM(STR_EEBACKUP);
POPUP_MENU_ADD_ITEM(STR_FACTORYRESET);
POPUP_MENU_START(onVersionMenu);
}
#endif
coord_t y = MENU_CONTENT_TOP + 5*FH;
lcdDrawText(MENUS_MARGIN_LEFT, y, "OPTS:");
lcdNextPos = MENUS_MARGIN_LEFT + 64;
@@ -62,15 +202,27 @@ bool menuRadioVersion(event_t event)
const char * option = options[i];
coord_t width = getTextWidth(option);
if((lcdNextPos + 5 + width) > LCD_W) {
if ((lcdNextPos + 5 + width) > LCD_W) {
lcdDrawText(lcdNextPos, y, ",");
lcdNextPos = MENUS_MARGIN_LEFT;
y += FH;
}
if (i > 0 && lcdNextPos !=MENUS_MARGIN_LEFT)
if (i > 0 && lcdNextPos !=MENUS_MARGIN_LEFT) {
lcdDrawText(lcdNextPos, y, ", ");
}
lcdDrawText(lcdNextPos, y, option);
}
#if defined(PXX2)
y += FH + FH / 2;
lcdDrawText(MENUS_MARGIN_LEFT, y, BUTTON(TR_MODULES_RX_VERSION), menuVerticalPosition == 0 ? INVERS : 0);
y += FH;
if (menuVerticalPosition == 0 && event == EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = EDIT_SELECT_FIELD;
pushMenu(menuRadioModulesVersion);
}
#endif
return true;
}
+2 -2
View File
@@ -90,10 +90,10 @@ void Theme::drawBackground() const
void Theme::drawMessageBox(const char * title, const char * text, const char * action, uint32_t type) const
{
//if (flags & MESSAGEBOX_TYPE_ALERT) {
// if (type == WARNING_TYPE_ALERT) {
drawBackground();
lcdDrawFilledRect(0, POPUP_Y, LCD_W, POPUP_H, SOLID, TEXT_INVERTED_COLOR | OPACITY(8));
//}
// }
if (type == WARNING_TYPE_ALERT || type == WARNING_TYPE_ASTERISK)
lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, asterisk);
@@ -85,6 +85,7 @@ class DarkblueTheme: public Theme
loadMenuIcon(ICON_RADIO_SETUP, "mask_radio_setup.png");
loadMenuIcon(ICON_RADIO_SD_MANAGER, "mask_radio_sd_browser.png");
loadMenuIcon(ICON_RADIO_TOOLS, "mask_radio_tools.png");
loadMenuIcon(ICON_RADIO_SPECTRUM_ANALYSER, "/mask_radio_spectrum_analyser.png");
loadMenuIcon(ICON_RADIO_GLOBAL_FUNCTIONS, "mask_radio_global_functions.png");
loadMenuIcon(ICON_RADIO_TRAINER, "mask_radio_trainer.png");
loadMenuIcon(ICON_RADIO_HARDWARE, "mask_radio_hardware.png");
+1
View File
@@ -100,6 +100,7 @@ class DefaultTheme: public Theme
loadMenuIcon(ICON_RADIO_SETUP, "mask_radio_setup.png");
loadMenuIcon(ICON_RADIO_SD_MANAGER, "mask_radio_sd_browser.png");
loadMenuIcon(ICON_RADIO_TOOLS, "mask_radio_tools.png");
loadMenuIcon(ICON_RADIO_SPECTRUM_ANALYSER, "/mask_radio_spectrum_analyser.png");
loadMenuIcon(ICON_RADIO_GLOBAL_FUNCTIONS, "mask_radio_global_functions.png");
loadMenuIcon(ICON_RADIO_TRAINER, "mask_radio_trainer.png");
loadMenuIcon(ICON_RADIO_HARDWARE, "mask_radio_hardware.png");
@@ -154,12 +154,6 @@ bool menuStatsDebug(event_t event)
lcdDrawNumber(lcdNextPos+5, y, audioStack.available(), LEFT);
y += FH;
#if defined(STM32)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RTC_BATT);
drawValueWithUnit(MENU_STATS_COLUMN1, y, getRTCBatteryVoltage(), UNIT_VOLTS, PREC2|LEFT);
y += FH;
#endif
#if defined(DISK_CACHE) && defined(DEBUG)
lcdDrawText(MENUS_MARGIN_LEFT, y, "SD cache hits");
lcdDrawNumber(MENU_STATS_COLUMN1, y, diskCache.getHitRate(), PREC1|LEFT, 0, NULL, "%");
+18
View File
@@ -427,3 +427,21 @@ void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration, const char
lcdRefresh();
lastDuration = duration;
}
void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags)
{
if (isModulePXX2(moduleIdx)) {
if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0')
lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags);
else
lcdDrawText(x, y, "---", flags);
}
#if defined(HARDWARE_INTERNAL_MODULE)
else if (moduleIdx == INTERNAL_MODULE) {
lcdDrawText(x, y, "Internal", flags);
}
#endif
else {
lcdDrawText(x, y, "External", flags);
}
}
+2
View File
@@ -76,4 +76,6 @@ void drawTopBar();
void drawMainPots();
void drawTrims(uint8_t flightMode);
void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags);
#endif // _WIDGETS_H_
+1
View File
@@ -5,6 +5,7 @@ set(SRC
${SRC}
gui/navigation/common.cpp
gui/navigation/navigation_${NAVIGATION_TYPE}.cpp
gui/screenshot.cpp
)
string(TOUPPER ${NAVIGATION_TYPE} NAVIGATION_TYPE)
@@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
#include <math.h>
#define RECEIVER_OPTIONS_2ND_COLUMN (11*FW)
@@ -75,7 +75,6 @@ void startBindMenu(uint8_t moduleIdx)
if (isTelemAllowedOnBind(moduleIdx) && g_model.moduleData[moduleIdx].pxx.receiver_telem_off)
selection += 1;
POPUP_MENU_SELECT_ITEM(selection);
POPUP_MENU_START(onBindMenu);
}
@@ -20,35 +20,6 @@
#include "opentx.h"
bool isPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx)
{
return g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx);
}
void setPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx)
{
g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx);
}
bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx)
{
return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
}
void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx)
{
memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx);
storageDirty(EE_MODEL);
}
void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx)
{
if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) {
removePXX2Receiver(moduleIdx, receiverIdx);
}
}
void onPXX2R9MBindModeMenu(const char * result)
{
if (result == STR_16CH_WITH_TELEMETRY) {
@@ -68,6 +39,7 @@ void onPXX2R9MBindModeMenu(const char * result)
uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE);
moduleState[moduleIdx].mode = MODULE_MODE_NORMAL;
reusableBuffer.moduleSetup.bindInformation.step = 0;
removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx);
return;
}
@@ -279,8 +251,7 @@ void modelSetupModulePxx2ReceiverLine(uint8_t moduleIdx, uint8_t receiverIdx, co
if (!isPXX2ReceiverUsed(moduleIdx, receiverIdx)) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, attr);
if (attr && s_editMode > 0) {
killEvents(event);
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
setPXX2ReceiverUsed(moduleIdx, receiverIdx);
memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME);
onPXX2ReceiverMenu(STR_BIND);
@@ -341,8 +312,7 @@ void modelSetupModulePxx2ReceiverLine(uint8_t moduleIdx, uint8_t receiverIdx, co
}
}
if (attr && EVT_KEY_MASK(event) == KEY_ENTER) {
killEvents(event);
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
POPUP_MENU_ADD_ITEM(STR_BIND);
POPUP_MENU_ADD_ITEM(STR_OPTIONS);
POPUP_MENU_ADD_ITEM(STR_SHARE);
@@ -581,7 +581,7 @@ void menuRadioHardware(event_t event)
lcdDrawTextAlignedLeft(y, STR_DEBUG);
lcdDrawText(HW_SETTINGS_COLUMN2, y, STR_ANALOGS_BTN, menuHorizontalPosition == 0 ? attr : 0);
lcdDrawText(lcdLastRightPos + 2, y, STR_KEYS_BTN, menuHorizontalPosition == 1 ? attr : 0);
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
if (menuHorizontalPosition == 0)
pushMenu(menuRadioDiagAnalogs);
else
@@ -591,7 +591,7 @@ void menuRadioHardware(event_t event)
case ITEM_RADIO_BACKUP_EEPROM:
lcdDrawText(LCD_W / 2, y, BUTTON(STR_EEBACKUP), attr | CENTERED);
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = EDIT_SELECT_FIELD;
eepromBackup();
}
@@ -599,7 +599,7 @@ void menuRadioHardware(event_t event)
case ITEM_RADIO_FACTORY_RESET:
lcdDrawText(LCD_W / 2, y, BUTTON(STR_FACTORYRESET), attr | CENTERED);
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = EDIT_SELECT_FIELD;
POPUP_CONFIRMATION(STR_CONFIRMRESET, onFactoryResetConfirm);
}
@@ -18,7 +18,6 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
extern uint8_t g_moduleIdx;
@@ -33,8 +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)
{
@@ -240,13 +241,15 @@ void menuRadioVersion(event_t event)
#if defined(COPROCESSOR)
lcdDrawText(FW, y, "COPR\037\033: ", SMLSIZE);
if (Coproc_valid == 1)
lcdDrawNumber(lcdNextPos, y, Coproc_read, SMLSIZE);
if (coprocData.valid == 1)
lcdDrawNumber(lcdNextPos, y, coprocData.read, SMLSIZE);
else
lcdDrawText(lcdNextPos, y, "---", SMLSIZE);
y += FH - 1;
#endif
y += 2;
#if defined(PCBTARANIS) || defined(PCBHORUS)
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_FIRMWARE_OPTIONS), menuVerticalPosition == ITEM_RADIO_FIRMWARE_OPTIONS ? INVERS : 0);
y += FH;
@@ -255,6 +258,7 @@ void menuRadioVersion(event_t event)
pushMenu(menuRadioFirmwareOptions);
}
#endif
#if defined(PXX2)
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_MODULES_RX_VERSION), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0);
y += FH;
+1 -3
View File
@@ -233,12 +233,10 @@ bool isSourceAvailableInCustomSwitches(int source)
{
bool result = isSourceAvailable(source);
#if defined(TELEMETRY_FRSKY)
if (result && source >= MIXSRC_FIRST_TELEM && source <= MIXSRC_LAST_TELEM) {
div_t qr = div(source - MIXSRC_FIRST_TELEM, 3);
result = isTelemetryFieldComparisonAvailable(qr.quot);
}
#endif
return result;
}
@@ -617,7 +615,7 @@ bool isExternalModuleAvailable(int moduleType)
if (moduleType == MODULE_TYPE_ISRM_PXX2)
return false; // doesn't exist for now
#if !defined(PXX2)
#if !defined(PXX2) || !defined(EXTMODULE_USART)
if (moduleType == MODULE_TYPE_XJT_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX2) {
return false;
}
+4 -2
View File
@@ -39,7 +39,7 @@
typedef bool (*IsValueAvailable)(int);
int circularIncDec(int current, int inc, int min, int max, IsValueAvailable isValueAvailable=NULL);
int circularIncDec(int current, int inc, int min, int max, IsValueAvailable isValueAvailable=nullptr);
int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable);
bool isTrimModeAvailable(int mode);
@@ -108,7 +108,7 @@ void drawSourceValue(coord_t x, coord_t y, source_t channel, LcdFlags flags=0);
void drawCurve(coord_t offset=0);
#if defined(COLORLCD)
void drawStringWithIndex(coord_t x, coord_t y, const char * str, int idx, LcdFlags flags=0, const char * prefix=NULL, const char * suffix=NULL);
void drawStringWithIndex(coord_t x, coord_t y, const char * str, int idx, LcdFlags flags=0, const char * prefix=nullptr, const char * suffix=nullptr);
int editChoice(coord_t x, coord_t y, const char * values, int value, int min, int max, LcdFlags flags, event_t event);
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags flags, event_t event);
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags flags, event_t event);
@@ -163,4 +163,6 @@ inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx)
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags);
const char * writeScreenshot();
#endif // _GUI_COMMON_H_
+3 -3
View File
@@ -242,8 +242,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
}
switch (event)
{
switch (event) {
case EVT_ENTRY:
menuEntryTime = get_tmr10ms();
l_posVert = 0;
@@ -271,7 +270,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
case EVT_KEY_FIRST(KEY_ENTER):
if (!menuTab || l_posVert>0) {
if (READ_ONLY_UNLOCKED()) {
s_editMode = (s_editMode<=0);
s_editMode = (s_editMode <= 0);
}
}
break;
@@ -287,6 +286,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
}
// no break
#endif
case EVT_KEY_LONG(KEY_EXIT):
s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same
popMenu();
+2 -1
View File
@@ -262,7 +262,8 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
break;
case EVT_ROTARY_BREAK:
if (s_editMode > 1) break;
if (s_editMode > 1)
break;
if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) {
l_posHorz = 0;
AUDIO_KEY_PRESS();
+2 -1
View File
@@ -373,7 +373,8 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
break;
case EVT_KEY_BREAK(KEY_ENTER):
if (s_editMode > 1) break;
if (s_editMode > 1)
break;
if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) {
l_posHorz = 0;
AUDIO_KEY_PRESS();
@@ -145,7 +145,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla
}
}
if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER))) {
if (!READ_ONLY() && i_min == 0 && i_max == 1 && event == EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
newval = !val;
}
@@ -318,8 +318,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
drawScreenIndex(curr, menuTabSize, attr);
}
switch (event)
{
switch (event) {
case EVT_ENTRY:
menuEntryTime = get_tmr10ms();
l_posVert = 0;

Some files were not shown because too many files have changed in this diff Show More