Merge with latest 2.3
This commit is contained in:
+1
-1
@@ -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 "0028")
|
||||
set(SDCARD_REVISION "0029")
|
||||
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
+28
@@ -1733,3 +1733,31 @@ MeCodeGoodSomeday
|
||||
Timothy Fry
|
||||
John Beech
|
||||
Wojciech Winiarski
|
||||
Armin Kuepfer
|
||||
Alain Bregand
|
||||
James Thompson
|
||||
Dautremépuis Benoit
|
||||
Adriano Emanuele Figliola
|
||||
Stefano Bortolotti
|
||||
Gerald Zierer
|
||||
Alessio Noto
|
||||
Walter Fowler
|
||||
Robert Black
|
||||
Klaus Kernstock
|
||||
Michael Wittich
|
||||
AG-Software
|
||||
Dietmar Drees
|
||||
Winfried Goers
|
||||
Steve Schoonover
|
||||
N. Haasnoot (monthly)
|
||||
Wolfram Bahmann
|
||||
Florian Reck
|
||||
Gary Bancroft
|
||||
Karl-Heinz Behn
|
||||
Stuart Godsmark
|
||||
Josko Povse
|
||||
David Reese
|
||||
Paul Pearson
|
||||
Stuart Olson
|
||||
Pierre Connan
|
||||
Henk Eeltink
|
||||
|
||||
@@ -54,7 +54,7 @@ DownloadDialog::DownloadDialog(QWidget *parent, QString src, QString tgt):
|
||||
reply = qnam.get(QNetworkRequest(QUrl(src)));
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
|
||||
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
|
||||
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64)));
|
||||
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(updateDataReadProgress(qint64, qint64)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ void DownloadDialog::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
|
||||
void DownloadDialog::fileError()
|
||||
{
|
||||
delete file;
|
||||
file = NULL;
|
||||
file = nullptr;
|
||||
reject();
|
||||
}
|
||||
|
||||
|
||||
@@ -45,15 +45,12 @@ AdjustmentReference::AdjustmentReference(AdjustRefType type, int value)
|
||||
|
||||
bool AdjustmentReference::isValid(const int value) const
|
||||
{
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case ADJUST_REF_VALUE:
|
||||
if (abs(value) < ADJUST_REF_GVAR_BASE)
|
||||
return true;
|
||||
break;
|
||||
return abs(value) < ADJUST_REF_GVAR_BASE;
|
||||
|
||||
case ADJUST_REF_GVAR:
|
||||
if (abs(value) > 0 && abs(value) <= CPN_MAX_GVARS);
|
||||
return true;
|
||||
break;
|
||||
return abs(value) > 0 && abs(value) <= CPN_MAX_GVARS;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ class LimitData {
|
||||
int offset;
|
||||
int ppmCenter;
|
||||
bool symetrical;
|
||||
char name[LIMITDATA_NAME_LEN+1];
|
||||
int failsafe;
|
||||
char name[LIMITDATA_NAME_LEN + 1];
|
||||
CurveReference curve;
|
||||
QString minToString() const;
|
||||
QString maxToString() const;
|
||||
|
||||
@@ -1174,8 +1174,7 @@ void ModelData::updateModuleFailsafes(ModuleData * md)
|
||||
|
||||
bool updated = false;
|
||||
|
||||
switch (updRefInfo.action)
|
||||
{
|
||||
switch (updRefInfo.action) {
|
||||
case REF_UPD_ACT_CLEAR:
|
||||
break;
|
||||
case REF_UPD_ACT_SHIFT:
|
||||
@@ -1183,16 +1182,16 @@ void ModelData::updateModuleFailsafes(ModuleData * md)
|
||||
return;
|
||||
|
||||
if (updRefInfo.shift > 0) {
|
||||
for (int i = (CPN_MAX_CHNOUT - 1); i > updRefInfo.index1; i--) {
|
||||
md->failsafeChannels[i] = md->failsafeChannels[i - 1];
|
||||
for (int i = CPN_MAX_CHNOUT - 1; i > updRefInfo.index1; i--) {
|
||||
limitData[i].failsafe = limitData[i - 1].failsafe;
|
||||
}
|
||||
md->failsafeChannels[updRefInfo.index1] = 0;
|
||||
limitData[updRefInfo.index1].failsafe = 0;
|
||||
}
|
||||
else {
|
||||
for (int i = (updRefInfo.index1 + 1); i < (CPN_MAX_CHNOUT - 1); i++) {
|
||||
md->failsafeChannels[i - 1] = md->failsafeChannels[i];
|
||||
for (int i = updRefInfo.index1 + 1; i < CPN_MAX_CHNOUT - 1; i++) {
|
||||
limitData[i - 1].failsafe = limitData[i].failsafe;
|
||||
}
|
||||
md->failsafeChannels[CPN_MAX_CHNOUT - 1] = 0;
|
||||
limitData[CPN_MAX_CHNOUT - 1].failsafe = 0;
|
||||
}
|
||||
updated = true;
|
||||
break;
|
||||
@@ -1200,17 +1199,18 @@ void ModelData::updateModuleFailsafes(ModuleData * md)
|
||||
int tmp;
|
||||
if (updRefInfo.index1 >= 0 && updRefInfo.index1 < CPN_MAX_CHNOUT) {
|
||||
updated = true;
|
||||
tmp = md->failsafeChannels[updRefInfo.index1];
|
||||
tmp = limitData[updRefInfo.index1].failsafe;
|
||||
if (updRefInfo.index2 >= 0 && updRefInfo.index2 < CPN_MAX_CHNOUT)
|
||||
md->failsafeChannels[updRefInfo.index1] = md->failsafeChannels[updRefInfo.index2];
|
||||
limitData[updRefInfo.index1].failsafe = limitData[updRefInfo.index2].failsafe;
|
||||
else
|
||||
md->failsafeChannels[updRefInfo.index1] = 0;
|
||||
limitData[updRefInfo.index1].failsafe = 0;
|
||||
}
|
||||
else
|
||||
tmp = 0;
|
||||
if (updRefInfo.index2 >= 0 && updRefInfo.index2 < CPN_MAX_CHNOUT)
|
||||
if (updRefInfo.index2 >= 0 && updRefInfo.index2 < CPN_MAX_CHNOUT) {
|
||||
updated = true;
|
||||
md->failsafeChannels[updRefInfo.index2] = tmp;
|
||||
limitData[updRefInfo.index2].failsafe = tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Error - unhandled action:" << updRefInfo.action;
|
||||
|
||||
@@ -132,7 +132,8 @@ enum MultiModuleRFProtocols {
|
||||
MODULE_SUBTYPE_MULTI_ESKY150V2,
|
||||
MODULE_SUBTYPE_MULTI_DSM_RX,
|
||||
MODULE_SUBTYPE_MULTI_JJRC345,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_JJRC345
|
||||
MODULE_SUBTYPE_MULTI_Q90C,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C
|
||||
};
|
||||
|
||||
enum TrainerProtocol {
|
||||
@@ -158,7 +159,11 @@ class ModuleData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ModuleData)
|
||||
|
||||
public:
|
||||
ModuleData() { clear(); }
|
||||
ModuleData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
unsigned int modelId;
|
||||
unsigned int protocol; // type in datastructs.h
|
||||
int rfProtocol; // rfProtocol in datastructs.h
|
||||
@@ -168,7 +173,6 @@ class ModuleData {
|
||||
unsigned int channelsStart;
|
||||
int channelsCount; // 0=8 channels
|
||||
unsigned int failsafeMode;
|
||||
int failsafeChannels[CPN_MAX_CHNOUT];
|
||||
|
||||
struct PPM {
|
||||
int delay;
|
||||
|
||||
@@ -50,7 +50,7 @@ static const QStringList STR_SUBTYPE_SYMAX {"Standard", "Syma X5C"};
|
||||
static const QStringList STR_SUBTYPE_SLT {"V1 (6 Channel)", "V2 (8 Channel)", "Q100", "Q200", "MR100"};
|
||||
static const QStringList STR_SUBTYPE_CX10 {"Green", "Blue", "DM007", "-", "JC3015a", "JC3015b", "MK33041"};
|
||||
static const QStringList STR_SUBTYPE_CG023 {"Standard", "YD829"};
|
||||
static const QStringList STR_SUBTYPE_BAYANG {"Standard", "H8S3D", "X16 AH", "IRDRONE", "DHD D4"};
|
||||
static const QStringList STR_SUBTYPE_BAYANG {"Standard", "H8S3D", "X16 AH", "IRDRONE", "DHD D4", "QX100"};
|
||||
static const QStringList STR_SUBTYPE_ESky {"Standard", "ET4"};
|
||||
static const QStringList STR_SUBTYPE_MT99 {"MT99", "H7", "YZ", "LS", "FY805"};
|
||||
static const QStringList STR_SUBTYPE_MJXQ {"WLH08", "X600", "X800", "H26D", "E010", "H26WH", "Phoenix"};
|
||||
@@ -76,7 +76,9 @@ static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly"};
|
||||
static const QStringList STR_SUBTYPE_ZSX {"JJRC ZSX-280"};
|
||||
static const QStringList STR_SUBTYPE_FLYZONE {"FZ-410 TX"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYX_RX {"RX", "Clone TX"};
|
||||
static const QStringList STR_SUBTYPE_HOTT {"Sync", "No_Sync"};
|
||||
static const QStringList STR_SUBTYPE_FX816 {"P38"};
|
||||
static const QStringList STR_SUBTYPE_PELIKAN {"Pro", "Lite"};
|
||||
static const QStringList STR_SUBTYPE_XK {"X450", "X420"};
|
||||
static const QStringList STR_SUBTYPE_XN297DUMP {"250K", "1M", "2M", "AUTO"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYX2 {"D16", "D16 8ch", "D16 EU-LBT", "D16 EU-LBT 8ch", "D16 Cloned"};
|
||||
@@ -104,7 +106,7 @@ const Multiprotocols multiProtocols {
|
||||
{MODULE_SUBTYPE_MULTI_SLT, 4, false, STR_SUBTYPE_SLT, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_CX10, 6, false, STR_SUBTYPE_CX10, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CG023, 1, false, STR_SUBTYPE_CG023, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 4, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 5, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_ESky, 1, false, STR_SUBTYPE_ESky, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MJXQ, 6, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE},
|
||||
@@ -134,8 +136,9 @@ const Multiprotocols multiProtocols {
|
||||
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HOTT, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HOTT, 1, true, STR_SUBTYPE_HOTT, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FX816, 0, false, STR_SUBTYPE_FX816, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, STR_SUBTYPE_PELIKAN, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_XK, 1, false, STR_SUBTYPE_XK, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_XN297DUMP, 3, false, STR_SUBTYPE_XN297DUMP, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX2, 4, true, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE},
|
||||
@@ -144,6 +147,7 @@ const Multiprotocols multiProtocols {
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_Q90C, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION},
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
@@ -188,7 +192,7 @@ QString Multiprotocols::protocolToString(int protocol, bool custom)
|
||||
"Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761",
|
||||
"KFPlan KF606", "Redpine", "Potensic", "ZSX", "FlyZone", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816",
|
||||
"Bayang RX", "Pelikan", "Tiger", "XK", "XN297 Dump", "FrSky X 2.1", "FrSky R9", "Propel", "FrSky L", "Skyartec",
|
||||
"ESky 150v2", "DSM RX", "JJRC345"
|
||||
"ESky 150v2", "DSM RX", "JJRC345", "Q90C"
|
||||
});
|
||||
|
||||
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);
|
||||
|
||||
@@ -128,7 +128,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
|
||||
return 16;
|
||||
}
|
||||
|
||||
#define MAX_ROTARY_ENCODERS(board) (IS_SKY9X(board) ? 1 : 0)
|
||||
#define MAX_ROTARY_ENCODERS(board) 0
|
||||
#define MAX_FLIGHT_MODES(board, version) 9
|
||||
#define MAX_TIMERS(board, version) 3
|
||||
#define MAX_MIXERS(board, version) 64
|
||||
@@ -1880,7 +1880,7 @@ class CustomScreenField: public StructField {
|
||||
|
||||
class SensorField: public TransformedField {
|
||||
public:
|
||||
SensorField(DataField * parent, const ModelData& model, SensorData & sensor, Board::Type board, unsigned int version):
|
||||
SensorField(DataField * parent, const ModelData & model, SensorData & sensor, Board::Type board, unsigned int version):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, "Sensor"),
|
||||
sensor(sensor),
|
||||
@@ -1948,16 +1948,9 @@ class SensorField: public TransformedField {
|
||||
else {
|
||||
sensor.id = _id;
|
||||
sensor.subid = _subid;
|
||||
if (model.moduleData[0].isPxx1Module() || model.moduleData[1].isPxx1Module()) {
|
||||
sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 5 bits instance
|
||||
sensor.rxIdx = 0x03; // 2 bits Rx idx
|
||||
sensor.moduleIdx = 0x01; // 1 bit module idx
|
||||
}
|
||||
else {
|
||||
sensor.instance = (_instance & 0x1F) + 1;
|
||||
sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx
|
||||
sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx
|
||||
}
|
||||
sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 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;
|
||||
}
|
||||
@@ -1983,6 +1976,12 @@ class SensorField: public TransformedField {
|
||||
sensor.unit++;
|
||||
}
|
||||
|
||||
if (version < 219) {
|
||||
if (sensor.unit > SensorData::UNIT_FLOZ) {
|
||||
sensor.unit += 11;
|
||||
}
|
||||
}
|
||||
|
||||
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
|
||||
}
|
||||
|
||||
@@ -2185,7 +2184,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
|
||||
|
||||
class ModuleField: public TransformedField {
|
||||
public:
|
||||
ModuleField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version):
|
||||
ModuleField(DataField * parent, ModuleData & module, ModelData & model, Board::Type board, unsigned int version):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, "Module"),
|
||||
module(module),
|
||||
@@ -2199,8 +2198,8 @@ class ModuleField: public TransformedField {
|
||||
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]));
|
||||
for (int i = 0; i < 32; i++) {
|
||||
internalField.Append(new SignedField<16>(this, model.limitData[i].failsafe));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2394,12 +2393,12 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
|
||||
int modulesCount = (version <= 218 ? 3 : 2);
|
||||
for (int module = 0; module < modulesCount; module++) {
|
||||
internalField.Append(new ModuleField(this, modelData.moduleData[module], board, version));
|
||||
internalField.Append(new ModuleField(this, modelData.moduleData[module], modelData, board, version));
|
||||
}
|
||||
|
||||
if (version >= 219) {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
internalField.Append(new SignedField<16>(this, modelData.moduleData[0].failsafeChannels[i]));
|
||||
internalField.Append(new SignedField<16>(this, modelData.limitData[i].failsafe));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1218,11 +1218,6 @@ void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
|
||||
addOpenTxFontOptions(firmware);
|
||||
}
|
||||
|
||||
void addPPMInternalModuleHack(OpenTxFirmware * firmware)
|
||||
{
|
||||
firmware->addOption("internalppm", Firmware::tr("Support for PPM internal module hack"));
|
||||
}
|
||||
|
||||
void addOpenTxArm9xOptions(OpenTxFirmware * firmware, bool dblkeys = true)
|
||||
{
|
||||
addOpenTxCommonOptions(firmware);
|
||||
@@ -1249,7 +1244,6 @@ void registerOpenTxFirmwares()
|
||||
firmware = new OpenTxFirmware("opentx-x9d+", Firmware::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP);
|
||||
firmware->addOption("noras", Firmware::tr("Disable RAS (SWR)"));
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
addPPMInternalModuleHack(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
|
||||
@@ -1264,7 +1258,6 @@ void registerOpenTxFirmwares()
|
||||
firmware->addOption("noras", Firmware::tr("Disable RAS (SWR)"));
|
||||
firmware->addOption("haptic", Firmware::tr("Haptic module installed"));
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
addPPMInternalModuleHack(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
|
||||
@@ -1273,7 +1266,6 @@ void registerOpenTxFirmwares()
|
||||
firmware->addOption("shutdownconfirm", Firmware::tr("Confirmation before radio shutdown"));
|
||||
firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)"));
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
addPPMInternalModuleHack(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
|
||||
|
||||
@@ -74,10 +74,13 @@ class SensorData {
|
||||
UNIT_METERS_PER_SECOND,
|
||||
UNIT_FEET_PER_SECOND,
|
||||
UNIT_KMH,
|
||||
UNIT_SPEED = UNIT_KMH,
|
||||
UNIT_MPH,
|
||||
UNIT_METERS,
|
||||
UNIT_DIST = UNIT_METERS,
|
||||
UNIT_FEET,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_TEMPERATURE = UNIT_CELSIUS,
|
||||
UNIT_FAHRENHEIT,
|
||||
UNIT_PERCENT,
|
||||
UNIT_MAH,
|
||||
@@ -91,18 +94,30 @@ class SensorData {
|
||||
UNIT_MILLILITERS,
|
||||
UNIT_FLOZ,
|
||||
UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_MAX = UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_SPARE1,
|
||||
UNIT_SPARE2,
|
||||
UNIT_SPARE3,
|
||||
UNIT_SPARE4,
|
||||
UNIT_SPARE5,
|
||||
UNIT_SPARE6,
|
||||
UNIT_SPARE7,
|
||||
UNIT_SPARE8,
|
||||
UNIT_SPARE9,
|
||||
UNIT_SPARE10,
|
||||
UNIT_HOURS,
|
||||
UNIT_MINUTES,
|
||||
UNIT_SECONDS,
|
||||
// FrSky format used for these fields, could be another format in the future
|
||||
UNIT_FIRST_VIRTUAL,
|
||||
UNIT_FIRST_VIRTUAL,
|
||||
UNIT_CELLS = UNIT_FIRST_VIRTUAL,
|
||||
UNIT_DATETIME,
|
||||
UNIT_GPS,
|
||||
UNIT_BITFIELD,
|
||||
UNIT_TEXT,
|
||||
// Internal units (not stored in sensor unit)
|
||||
UNIT_GPS_LONGITUDE,
|
||||
UNIT_GPS_LATITUDE,
|
||||
UNIT_GPS_LONGITUDE_EW,
|
||||
UNIT_GPS_LATITUDE_NS,
|
||||
UNIT_DATETIME_YEAR,
|
||||
UNIT_DATETIME_DAY_MONTH,
|
||||
UNIT_DATETIME_HOUR_MIN,
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "flashfirmwaredialog.h"
|
||||
#include "ui_flashfirmwaredialog.h"
|
||||
#include "appdata.h"
|
||||
#include "process_flash.h"
|
||||
#include "helpers.h"
|
||||
#include "progressdialog.h"
|
||||
#include "radiointerface.h"
|
||||
@@ -112,7 +111,7 @@ void FlashFirmwareDialog::updateUI()
|
||||
}
|
||||
|
||||
QImage image;
|
||||
switch(imageSource) {
|
||||
switch (imageSource) {
|
||||
case FIRMWARE:
|
||||
ui->useFirmwareSplash->setChecked(true);
|
||||
image = firmware.getSplash();
|
||||
@@ -202,7 +201,7 @@ void FlashFirmwareDialog::on_useExternalSplash_clicked()
|
||||
void FlashFirmwareDialog::on_useLibrarySplash_clicked()
|
||||
{
|
||||
QString fileName;
|
||||
SplashLibraryDialog *ld = new SplashLibraryDialog(this, &fileName);
|
||||
auto ld = new SplashLibraryDialog(this, &fileName);
|
||||
ld->exec();
|
||||
if (!fileName.isEmpty()) {
|
||||
QImage image(fileName);
|
||||
|
||||
@@ -565,7 +565,6 @@ QPixmap makePixMap(const QImage & image)
|
||||
return QPixmap::fromImage(result);
|
||||
}
|
||||
|
||||
|
||||
int version2index(const QString & version)
|
||||
{
|
||||
int result = 999;
|
||||
@@ -581,6 +580,10 @@ int version2index(const QString & version)
|
||||
result = parts[1].toInt(); // nightly build up to 899
|
||||
mainVersion = parts[0];
|
||||
}
|
||||
else if (version.contains("-")) {
|
||||
parts = version.split("-");
|
||||
mainVersion = parts[0];
|
||||
}
|
||||
parts = mainVersion.split('.');
|
||||
if (parts.size() > 2)
|
||||
result += 1000 * parts[2].toInt();
|
||||
|
||||
@@ -360,7 +360,6 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
return onUpdatesError(tr("Companion update check failed, new version information not found."));
|
||||
|
||||
int webVersion = version2index(version);
|
||||
|
||||
int ownVersion = version2index(VERSION);
|
||||
|
||||
if (ownVersion < webVersion) {
|
||||
|
||||
@@ -643,7 +643,7 @@ void InputsPanel::cmInputSwapData(int idx1, int idx2)
|
||||
}
|
||||
// move expos up
|
||||
const int offset = i - expoidx;
|
||||
int expocnt;
|
||||
int expocnt = 0;
|
||||
for (int j = i; j < CPN_MAX_EXPOS; j++) {
|
||||
ExpoData *ed = &model->expoData[j];
|
||||
if ((int)ed->chn == idx2) {
|
||||
|
||||
@@ -792,18 +792,22 @@ void ModulePanel::on_lowPower_stateChanged(int state)
|
||||
module.multi.lowPowerMode = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
// updtSb (update spin box(es)): 0=none or bitmask of FailsafeValueDisplayTypes
|
||||
void ModulePanel::setChannelFailsafeValue(const int channel, const int value, quint8 updtSb)
|
||||
void ModulePanel::onFailsafeModified(unsigned channel)
|
||||
{
|
||||
if (channel < 0 || channel >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
updateFailsafeUI(channel, FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC);
|
||||
}
|
||||
|
||||
module.failsafeChannels[channel] = value;
|
||||
void ModulePanel::updateFailsafeUI(unsigned channel, quint8 updtSb)
|
||||
{
|
||||
int value = model->limitData[channel].failsafe;
|
||||
double pctVal = divRoundClosest(value * 1000, 1024) / 10.0;
|
||||
// qDebug() << value << pctVal;
|
||||
|
||||
if (failsafeGroupsMap.contains(channel)) {
|
||||
const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
|
||||
bool disable = (value == FAILSAFE_CHANNEL_HOLD || value == FAILSAFE_CHANNEL_NOPULSE);
|
||||
if (grp.combo) {
|
||||
grp.combo->setCurrentIndex(grp.combo->findData(disable ? value : 0));
|
||||
}
|
||||
if ((updtSb & FAILSAFE_DISPLAY_PERCENT) && grp.sbPercent) {
|
||||
grp.sbPercent->blockSignals(true);
|
||||
grp.sbPercent->setValue(pctVal);
|
||||
@@ -815,8 +819,21 @@ void ModulePanel::setChannelFailsafeValue(const int channel, const int value, qu
|
||||
grp.sbUsec->blockSignals(false);
|
||||
}
|
||||
}
|
||||
if (!lock)
|
||||
}
|
||||
|
||||
// updtSb (update spin box(es)): 0=none or bitmask of FailsafeValueDisplayTypes
|
||||
void ModulePanel::setChannelFailsafeValue(const int channel, const int value, quint8 updtSb)
|
||||
{
|
||||
if (channel < 0 || channel >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
model->limitData[channel].failsafe = value;
|
||||
updateFailsafeUI(channel, updtSb);
|
||||
|
||||
if (!lock) {
|
||||
emit failsafeModified(channel);
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void ModulePanel::onFailsafeUsecChanged(int value)
|
||||
@@ -853,8 +870,9 @@ void ModulePanel::onFailsafeComboIndexChanged(int index)
|
||||
bool ok = false;
|
||||
int channel = sender()->property("index").toInt(&ok);
|
||||
if (ok) {
|
||||
module.failsafeChannels[channel] = cb->itemData(index).toInt();
|
||||
model->limitData[channel].failsafe = cb->itemData(index).toInt();
|
||||
updateFailsafe(channel);
|
||||
emit failsafeModified(channel);
|
||||
emit modified();
|
||||
}
|
||||
lock = false;
|
||||
@@ -886,12 +904,12 @@ void ModulePanel::onExtendedLimitsToggled()
|
||||
}
|
||||
}
|
||||
|
||||
void ModulePanel::updateFailsafe(int channel)
|
||||
void ModulePanel::updateFailsafe(unsigned channel)
|
||||
{
|
||||
if (channel >= CPN_MAX_CHNOUT || !failsafeGroupsMap.contains(channel))
|
||||
return;
|
||||
|
||||
const int failsafeValue = module.failsafeChannels[channel];
|
||||
const int failsafeValue = model->limitData[channel].failsafe;
|
||||
const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
|
||||
const bool valDisable = (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE);
|
||||
|
||||
@@ -903,7 +921,7 @@ void ModulePanel::updateFailsafe(int channel)
|
||||
grp.sbUsec->setDisabled(valDisable);
|
||||
|
||||
if (!valDisable)
|
||||
setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
|
||||
setChannelFailsafeValue(channel, failsafeValue, FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC);
|
||||
}
|
||||
|
||||
void ModulePanel::onClearAccessRxClicked()
|
||||
@@ -1166,13 +1184,21 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
ui->trimsDisplay->hide();
|
||||
}
|
||||
|
||||
for (int i=firmware->getCapability(NumFirstUsableModule); i<firmware->getCapability(NumModules); i++) {
|
||||
for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) {
|
||||
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
|
||||
ui->modulesLayout->addWidget(modules[i]);
|
||||
connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
|
||||
connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
|
||||
}
|
||||
|
||||
for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) {
|
||||
for (int j = firmware->getCapability(NumFirstUsableModule); j < firmware->getCapability(NumModules); j++) {
|
||||
if (i != j) {
|
||||
connect(modules[i], SIGNAL(failsafeModified(unsigned)), modules[j], SLOT(onFailsafeModified(unsigned)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firmware->getCapability(ModelTrainerEnable)) {
|
||||
modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1);
|
||||
ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]);
|
||||
|
||||
@@ -61,15 +61,17 @@ class ModulePanel : public ModelPanel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
|
||||
ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
|
||||
virtual ~ModulePanel();
|
||||
virtual void update();
|
||||
|
||||
public slots:
|
||||
void onExtendedLimitsToggled();
|
||||
void onFailsafeModified(unsigned index);
|
||||
|
||||
signals:
|
||||
void channelsRangeChanged();
|
||||
void failsafeModified(unsigned index);
|
||||
|
||||
private slots:
|
||||
void setupFailsafes();
|
||||
@@ -95,7 +97,7 @@ class ModulePanel : public ModelPanel
|
||||
void onFailsafeUsecChanged(int value);
|
||||
void onFailsafePercentChanged(double value);
|
||||
void onFailsafesDisplayValueTypeChanged(int type);
|
||||
void updateFailsafe(int channel);
|
||||
void updateFailsafe(unsigned channel);
|
||||
void on_optionValue_editingFinished();
|
||||
void onClearAccessRxClicked();
|
||||
|
||||
@@ -114,6 +116,7 @@ class ModulePanel : public ModelPanel
|
||||
Ui::Module *ui;
|
||||
QMap<int, ChannelFailsafeWidgetsGroup> failsafeGroupsMap;
|
||||
static quint8 failsafesValueDisplayType; // FailsafeValueDisplayTypes
|
||||
void updateFailsafeUI(unsigned channel, quint8 updtSb);
|
||||
};
|
||||
|
||||
class SetupPanel : public ModelPanel
|
||||
|
||||
@@ -897,9 +897,8 @@ QString ModelPrinter::printFailsafe(int idx)
|
||||
ModuleData module = model.moduleData[idx];
|
||||
strl << printLabelValue(tr("Failsafe Mode"), printFailsafeMode(module.failsafeMode));
|
||||
if (module.failsafeMode == FAILSAFE_CUSTOM) {
|
||||
for (int i=0; i<module.channelsCount; i++) {
|
||||
//strl << QString("%1(%2)").arg(printChannelName(module.channelsStart + i).trimmed()).arg(printFailsafeValue(module.failsafeChannels[i]));
|
||||
strl << printLabelValue(printChannelName(module.channelsStart + i).trimmed(), printFailsafeValue(module.failsafeChannels[i]));
|
||||
for (int i = 0; i < module.channelsCount; i++) {
|
||||
strl << printLabelValue(printChannelName(module.channelsStart + i).trimmed(), printFailsafeValue(model.limitData[i].failsafe));
|
||||
}
|
||||
}
|
||||
return strl.join(" ");
|
||||
|
||||
@@ -134,27 +134,30 @@ void FlashProcess::onKillTimerElapsed()
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlashProcess::analyseStandardOutput(const QString &text)
|
||||
void FlashProcess::analyseStandardOutput(const QString & text)
|
||||
{
|
||||
currStdoutLine.append(text);
|
||||
|
||||
if (currStdoutLine.contains("size = ")) {
|
||||
int pos = currStdoutLine.lastIndexOf("size = ");
|
||||
QString temp = currStdoutLine.mid(pos+7);
|
||||
pos = temp.lastIndexOf("\n");
|
||||
int size = temp.left(pos).toInt();
|
||||
progress->setMaximum(size/2048);
|
||||
progress->setMaximum(size / 2048);
|
||||
}
|
||||
|
||||
if (currStdoutLine.contains("\n")) {
|
||||
int nlPos = currStdoutLine.lastIndexOf("\n");
|
||||
currStdoutLine = currStdoutLine.mid(nlPos+1);
|
||||
}
|
||||
|
||||
if (!currStdoutLine.isEmpty()) {
|
||||
if (currStdoutLine.at(0) == QChar('.')) {
|
||||
int pos = currStdoutLine.lastIndexOf(".");
|
||||
progress->setValue(pos);
|
||||
}
|
||||
else if (currStdoutLine.startsWith("Starting upload: [")) {
|
||||
int pos = (currStdoutLine.lastIndexOf("#")-19)*100/256;
|
||||
int pos = (currStdoutLine.lastIndexOf("#") - 19) * 100 / 256;
|
||||
progress->setValue(pos);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +171,15 @@ void FlashProcess::analyseStandardOutput(const QString &text)
|
||||
int end = text.indexOf("%");
|
||||
if (start > 0) {
|
||||
start += 9;
|
||||
int value = text.mid(start, end-start).toInt();
|
||||
int value = text.mid(start, end - start).toInt();
|
||||
progress->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (text.contains("Upload\t[") || text.contains("Download\t[")) {
|
||||
int end = text.indexOf("%");
|
||||
if (end > 0) {
|
||||
int value = text.mid(end - 3, 3).toInt();
|
||||
progress->setValue(value);
|
||||
}
|
||||
}
|
||||
@@ -277,7 +288,7 @@ void FlashProcess::errorWizard()
|
||||
DeviceStr = "Atmega 2561";
|
||||
}
|
||||
}
|
||||
if (fwexist==false) {
|
||||
if (!fwexist) {
|
||||
QMessageBox::warning(nullptr, "Companion - Tip of the day", tr("Your radio uses a %1 CPU!!!\n\nPlease check advanced burn options to set the correct cpu type.").arg(DeviceStr));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -53,10 +53,10 @@ protected:
|
||||
void analyseStandardError(const QString &text);
|
||||
void errorWizard();
|
||||
void addReadFuses();
|
||||
ProgressWidget *progress;
|
||||
ProgressWidget * progress;
|
||||
const QString cmd;
|
||||
const QStringList args;
|
||||
QProcess *process;
|
||||
QProcess * process;
|
||||
bool hasErrors;
|
||||
QString currStdoutLine;
|
||||
QString currStderrLine;
|
||||
|
||||
@@ -253,7 +253,6 @@ void resetAvrdudeFuses(bool eepromProtect, ProgressWidget * progress)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool readFirmware(const QString & filename, ProgressWidget * progress)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -274,7 +273,7 @@ bool readFirmware(const QString & filename, ProgressWidget * progress)
|
||||
}
|
||||
}
|
||||
|
||||
if (result == false) {
|
||||
if (!result) {
|
||||
qDebug() << "readFirmware: reading" << filename << "with" << getRadioInterfaceCmd() << getReadFirmwareArgs(filename);
|
||||
FlashProcess flashProcess(getRadioInterfaceCmd(), getReadFirmwareArgs(filename), progress);
|
||||
result = flashProcess.run();
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
FirmwareInterface::FirmwareInterface(const QString & filename):
|
||||
flash(FSIZE_MAX, 0),
|
||||
flashSize(0),
|
||||
versionId(0),
|
||||
eepromVersion(0),
|
||||
eepromVariant(0),
|
||||
splashOffset(0),
|
||||
@@ -65,7 +64,7 @@ FirmwareInterface::FirmwareInterface(const QString & filename):
|
||||
// old version format
|
||||
int index = version.lastIndexOf('-');
|
||||
flavour = version.mid(0, index);
|
||||
version = version.mid(index+1);
|
||||
version = version.mid(index + 1);
|
||||
}
|
||||
date = seekLabel(DATE_MARK);
|
||||
time = seekLabel(TIME_MARK);
|
||||
@@ -80,7 +79,6 @@ FirmwareInterface::FirmwareInterface(const QString & filename):
|
||||
eepromVersion = eepromId.toInt();
|
||||
}
|
||||
|
||||
versionId = version2index(version);
|
||||
seekSplash();
|
||||
isValidFlag = !version.isEmpty();
|
||||
}
|
||||
|
||||
@@ -39,14 +39,13 @@
|
||||
class FirmwareInterface
|
||||
{
|
||||
public:
|
||||
FirmwareInterface(const QString &filename);
|
||||
FirmwareInterface(const QString & filename);
|
||||
inline QString getDate() { return date; }
|
||||
inline QString getTime() { return time; }
|
||||
int getSize() { return flashSize; }
|
||||
QString getFlavour() const;
|
||||
bool isHardwareCompatible(const FirmwareInterface &previousFirmware) const;
|
||||
inline QString getVersion() { return version; }
|
||||
unsigned int getVersionId() { return versionId; }
|
||||
inline int getEEpromVersion() { return eepromVersion; }
|
||||
inline int getEEpromVariant() { return eepromVariant; }
|
||||
inline QString getEEpromId() { return eepromId; }
|
||||
@@ -72,7 +71,6 @@ class FirmwareInterface
|
||||
QString time;
|
||||
QString flavour;
|
||||
QString version;
|
||||
int versionId;
|
||||
QString eepromId;
|
||||
int eepromVersion;
|
||||
int eepromVariant;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -21,19 +21,41 @@
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Write 0x0F at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 5 sends an order to the RX: 0xXF=start, 0xX7=prev page,
|
||||
-- 0xXE=next page, 0xX9=enter, 0xXD=next or 0xXB=prev with X being the sensor
|
||||
-- to request data from 8=RX only, 9=Vario, A=GPS, B=Cust, C=ESC, D=GAM, E=EAM
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
HoTT_Sensor = 0
|
||||
Timer_128 = 100
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Send(button)
|
||||
multiBuffer( 5, 0x80+(HoTT_Sensor*16) + button)
|
||||
end
|
||||
|
||||
local function HoTT_Sensor_Inc()
|
||||
local detected_sensors=multiBuffer( 4 )
|
||||
local a
|
||||
if detected_sensors ~= 0xFF then
|
||||
repeat
|
||||
HoTT_Sensor=(HoTT_Sensor+1)%7 -- Switch to next sensor
|
||||
if HoTT_Sensor ~= 0 then
|
||||
a = math.floor(detected_sensors/ (2^(HoTT_Sensor-1))) -- shift right
|
||||
end
|
||||
until HoTT_Sensor==0 or a % 2 == 1
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
@@ -41,12 +63,14 @@ local function HoTT_Draw_LCD()
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
local sensor_name = { "", "+Vario", "+GPS", "+Cust", "+ESC", "+GAM", "+EAM" }
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT: config RX" .. sensor_name[HoTT_Sensor+1] .. " - Menu cycle Sensors", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
@@ -56,9 +80,9 @@ local function HoTT_Draw_LCD()
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -68,14 +92,23 @@ local function HoTT_Draw_LCD()
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
if Timer_128 ~= 0 then
|
||||
--Intro page
|
||||
Timer_128 = Timer_128 - 1
|
||||
lcd.drawScreenTitle("Graupner Hott",0,0)
|
||||
lcd.drawText(2,17,"Configuration of RX" .. sensor_name[HoTT_Sensor+1] ,SMLSIZE)
|
||||
lcd.drawText(2,37,"Press menu to cycle Sensors" ,SMLSIZE)
|
||||
else
|
||||
--Menu page
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -98,7 +131,10 @@ local function HoTT_Init()
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
HoTT_Sensor = 0;
|
||||
HoTT_Detected_Sensors=0;
|
||||
Timer_128 = 100
|
||||
end
|
||||
|
||||
-- Main
|
||||
@@ -111,18 +147,21 @@ local function HoTT_Run(event)
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
killEvents(event)
|
||||
HoTT_Send( 0x07 )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
HoTT_Send( 0x09 )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
HoTT_Send( 0x0B )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
HoTT_Send( 0x0D )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
HoTT_Send( 0x0E )
|
||||
elseif event == EVT_VIRTUAL_MENU then
|
||||
Timer_128 = 100
|
||||
HoTT_Sensor_Inc()
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
|
||||
@@ -149,14 +149,13 @@ local function runMotorConfig(event)
|
||||
lcd.drawBitmap(BackgroundImg, 0, 0)
|
||||
lcd.drawBitmap(ImgPageDn, 455, 95)
|
||||
lcd.drawBitmap(ImgEngine, 310, 50)
|
||||
lcd.setColor(CUSTOM_COLOR, lcd.RGB(255, 255, 255))
|
||||
fields = MotorFields
|
||||
lcd.drawText(40, 20, "Does your model have a motor ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 200, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 200, 30, TEXT_BGCOLOR)
|
||||
fields[2][4]=0
|
||||
if fields[1][5] == 1 then
|
||||
lcd.drawText(40, 100, "What channel is it on ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
fields[2][4]=1
|
||||
end
|
||||
local result = runFieldsPage(event)
|
||||
@@ -190,7 +189,7 @@ local function runAilConfig(event)
|
||||
lcd.drawBitmap(ImgAilL, 395, 235)
|
||||
drawMark(308, 115, "A")
|
||||
drawMark(422, 220, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0)
|
||||
elseif fields[1][5] == 2 then
|
||||
@@ -198,16 +197,16 @@ local function runAilConfig(event)
|
||||
lcd.drawBitmap(ImgAilL, 395, 235)
|
||||
drawMark(308, 115, "A")
|
||||
drawMark(422, 220, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1)
|
||||
else
|
||||
setFieldsVisible(0, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Number of ailerons on your model ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
@@ -235,7 +234,7 @@ local function runFlapsConfig(event)
|
||||
lcd.drawBitmap(ImgFlp, 358, 202)
|
||||
drawMark(332, 132, "A")
|
||||
drawMark(412, 215, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0)
|
||||
elseif fields[1][5] == 2 then
|
||||
@@ -243,16 +242,16 @@ local function runFlapsConfig(event)
|
||||
lcd.drawBitmap(ImgFlp, 358, 202)
|
||||
drawMark(332, 132, "A")
|
||||
drawMark(412, 215, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1)
|
||||
else
|
||||
setFieldsVisible(0, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Does your model have flaps ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
@@ -283,7 +282,7 @@ local function runTailConfig(event)
|
||||
lcd.drawBitmap(ImgTail, 252, 100)
|
||||
drawMark(360, 125, "A")
|
||||
drawMark(390, 155, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0, 0)
|
||||
end
|
||||
@@ -293,9 +292,9 @@ local function runTailConfig(event)
|
||||
drawMark(415, 150, "A")
|
||||
drawMark(380, 120, "A")
|
||||
drawMark(390, 185, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1, 0)
|
||||
end
|
||||
@@ -305,11 +304,11 @@ local function runTailConfig(event)
|
||||
drawMark(415, 150, "C")
|
||||
drawMark(380, 120, "A")
|
||||
drawMark(390, 185, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
lcd.drawFilledRectangle(40, 202, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 202, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 204, "C")
|
||||
setFieldsVisible(1, 1, 1)
|
||||
end
|
||||
@@ -317,14 +316,14 @@ local function runTailConfig(event)
|
||||
lcd.drawBitmap(ImgVTail, 252, 100)
|
||||
drawMark(315, 110, "A")
|
||||
drawMark(382, 120, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Pick the tail config of your model", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -144,19 +144,18 @@ local ImgEngine
|
||||
local function runMotorConfig(event)
|
||||
lcd.clear()
|
||||
if ImgEngine == nil then
|
||||
ImgEngine = Bitmap.open("img/prop.png")
|
||||
ImgEngine = Bitmap.open("img/prop.png")
|
||||
end
|
||||
lcd.drawBitmap(BackgroundImg, 0, 0)
|
||||
lcd.drawBitmap(ImgPageDn, 455, 95)
|
||||
lcd.drawBitmap(ImgEngine, 310, 50)
|
||||
lcd.setColor(CUSTOM_COLOR, lcd.RGB(255, 255, 255))
|
||||
fields = MotorFields
|
||||
lcd.drawText(40, 20, "Does your model have a motor ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 200, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 200, 30, TEXT_BGCOLOR)
|
||||
fields[2][4]=0
|
||||
if fields[1][5] == 1 then
|
||||
lcd.drawText(40, 100, "What channel is it on ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
fields[2][4]=1
|
||||
end
|
||||
local result = runFieldsPage(event)
|
||||
@@ -190,7 +189,7 @@ local function runAilConfig(event)
|
||||
lcd.drawBitmap(ImgAilL, 275, 210)
|
||||
drawMark(362, 132, "A")
|
||||
drawMark(302, 227, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0)
|
||||
elseif fields[1][5] == 2 then
|
||||
@@ -198,16 +197,16 @@ local function runAilConfig(event)
|
||||
lcd.drawBitmap(ImgAilL, 275, 210)
|
||||
drawMark(362, 132, "A")
|
||||
drawMark(302, 227, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1)
|
||||
else
|
||||
setFieldsVisible(0, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Number of ailerons on your model ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
@@ -235,7 +234,7 @@ local function runFlapsConfig(event)
|
||||
lcd.drawBitmap(ImgFlp, 285, 191)
|
||||
drawMark(362, 132, "A")
|
||||
drawMark(302, 227, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0)
|
||||
elseif fields[1][5] == 2 then
|
||||
@@ -243,16 +242,16 @@ local function runFlapsConfig(event)
|
||||
lcd.drawBitmap(ImgFlp, 285, 191)
|
||||
drawMark(362, 132, "A")
|
||||
drawMark(302, 227, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1)
|
||||
else
|
||||
setFieldsVisible(0, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Does your model have flaps ?", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
@@ -283,7 +282,7 @@ local function runTailConfig(event)
|
||||
lcd.drawBitmap(ImgTail, 252, 100)
|
||||
drawMark(275, 120, "A")
|
||||
drawMark(390, 155, "A")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
setFieldsVisible(1, 0, 0)
|
||||
end
|
||||
@@ -293,9 +292,9 @@ local function runTailConfig(event)
|
||||
drawMark(275, 120, "A")
|
||||
drawMark(390, 155, "A")
|
||||
drawMark(370, 112, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1, 0)
|
||||
end
|
||||
@@ -305,11 +304,11 @@ local function runTailConfig(event)
|
||||
drawMark(275, 120, "A")
|
||||
drawMark(390, 155, "C")
|
||||
drawMark(370, 112, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
lcd.drawFilledRectangle(40, 202, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 202, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 204, "C")
|
||||
setFieldsVisible(1, 1, 1)
|
||||
end
|
||||
@@ -317,14 +316,14 @@ local function runTailConfig(event)
|
||||
lcd.drawBitmap(ImgVTail, 252, 100)
|
||||
drawMark(315, 110, "A")
|
||||
drawMark(382, 120, "B")
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 122, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 124, "A")
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 162, 100, 30, TEXT_BGCOLOR)
|
||||
drawMark(152, 164, "B")
|
||||
setFieldsVisible(1, 1, 0)
|
||||
end
|
||||
lcd.drawText(40, 20, "Pick the tail config of your model", DEFAULT_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, CUSTOM_COLOR)
|
||||
lcd.drawFilledRectangle(40, 45, 400, 30, TEXT_BGCOLOR)
|
||||
local result = runFieldsPage(event)
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -21,19 +21,41 @@
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Write 0x0F at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 5 sends an order to the RX: 0xXF=start, 0xX7=prev page,
|
||||
-- 0xXE=next page, 0xX9=enter, 0xXD=next or 0xXB=prev with X being the sensor
|
||||
-- to request data from 8=RX only, 9=Vario, A=GPS, B=Cust, C=ESC, D=GAM, E=EAM
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
HoTT_Sensor = 0
|
||||
Timer_128 = 100
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Send(button)
|
||||
multiBuffer( 5, 0x80+(HoTT_Sensor*16) + button)
|
||||
end
|
||||
|
||||
local function HoTT_Sensor_Inc()
|
||||
local detected_sensors=multiBuffer( 4 )
|
||||
local a
|
||||
if detected_sensors ~= 0xFF then
|
||||
repeat
|
||||
HoTT_Sensor=(HoTT_Sensor+1)%7 -- Switch to next sensor
|
||||
if HoTT_Sensor ~= 0 then
|
||||
a = math.floor(detected_sensors/ (2^(HoTT_Sensor-1))) -- shift right
|
||||
end
|
||||
until HoTT_Sensor==0 or a % 2 == 1
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
@@ -41,12 +63,14 @@ local function HoTT_Draw_LCD()
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
local sensor_name = { "", "+Vario", "+GPS", "+Cust", "+ESC", "+GAM", "+EAM" }
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT: config RX" .. sensor_name[HoTT_Sensor+1] .. " - Menu cycle Sensors", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
@@ -56,9 +80,9 @@ local function HoTT_Draw_LCD()
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -68,14 +92,23 @@ local function HoTT_Draw_LCD()
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
if Timer_128 ~= 0 then
|
||||
--Intro page
|
||||
Timer_128 = Timer_128 - 1
|
||||
lcd.drawScreenTitle("Graupner Hott",0,0)
|
||||
lcd.drawText(2,17,"Configuration of RX" .. sensor_name[HoTT_Sensor+1] ,SMLSIZE)
|
||||
lcd.drawText(2,37,"Press menu to cycle Sensors" ,SMLSIZE)
|
||||
else
|
||||
--Menu page
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -98,7 +131,10 @@ local function HoTT_Init()
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
HoTT_Sensor = 0;
|
||||
HoTT_Detected_Sensors=0;
|
||||
Timer_128 = 100
|
||||
end
|
||||
|
||||
-- Main
|
||||
@@ -111,18 +147,21 @@ local function HoTT_Run(event)
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
killEvents(event)
|
||||
HoTT_Send( 0x07 )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
HoTT_Send( 0x09 )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
HoTT_Send( 0x0B )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
HoTT_Send( 0x0D )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
HoTT_Send( 0x0E )
|
||||
elseif event == EVT_VIRTUAL_MENU then
|
||||
Timer_128 = 100
|
||||
HoTT_Sensor_Inc()
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
|
||||
@@ -165,8 +165,8 @@ end
|
||||
-- Init function
|
||||
local function init()
|
||||
thrCH1 = defaultChannel(2)
|
||||
rollCH1 = defaultChannel(0)
|
||||
yawCH1 = defaultChannel(3)
|
||||
rollCH1 = defaultChannel(3)
|
||||
yawCH1 = defaultChannel(0)
|
||||
pitchCH1 = defaultChannel(1)
|
||||
local ver, radio, maj, minor, rev = getVersion()
|
||||
if string.match(radio, "x7") then
|
||||
|
||||
@@ -21,19 +21,41 @@
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Write 0x0F at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 5 sends an order to the RX: 0xXF=start, 0xX7=prev page,
|
||||
-- 0xXE=next page, 0xX9=enter, 0xXD=next or 0xXB=prev with X being the sensor
|
||||
-- to request data from 8=RX only, 9=Vario, A=GPS, B=Cust, C=ESC, D=GAM, E=EAM
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
HoTT_Sensor = 0
|
||||
Timer_128 = 100
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Send(button)
|
||||
multiBuffer( 5, 0x80+(HoTT_Sensor*16) + button)
|
||||
end
|
||||
|
||||
local function HoTT_Sensor_Inc()
|
||||
local detected_sensors=multiBuffer( 4 )
|
||||
local a
|
||||
if detected_sensors ~= 0xFF then
|
||||
repeat
|
||||
HoTT_Sensor=(HoTT_Sensor+1)%7 -- Switch to next sensor
|
||||
if HoTT_Sensor ~= 0 then
|
||||
a = math.floor(detected_sensors/ (2^(HoTT_Sensor-1))) -- shift right
|
||||
end
|
||||
until HoTT_Sensor==0 or a % 2 == 1
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
@@ -41,12 +63,14 @@ local function HoTT_Draw_LCD()
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
local sensor_name = { "", "+Vario", "+GPS", "+Cust", "+ESC", "+GAM", "+EAM" }
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT: config RX" .. sensor_name[HoTT_Sensor+1] .. " - Menu cycle Sensors", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
@@ -56,9 +80,9 @@ local function HoTT_Draw_LCD()
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
lcd.drawText(10+i*16,32+20*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -68,14 +92,23 @@ local function HoTT_Draw_LCD()
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
if Timer_128 ~= 0 then
|
||||
--Intro page
|
||||
Timer_128 = Timer_128 - 1
|
||||
lcd.drawScreenTitle("Graupner Hott",0,0)
|
||||
lcd.drawText(2,17,"Configuration of RX" .. sensor_name[HoTT_Sensor+1] ,SMLSIZE)
|
||||
lcd.drawText(2,37,"Press menu to cycle Sensors" ,SMLSIZE)
|
||||
else
|
||||
--Menu page
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -98,7 +131,10 @@ local function HoTT_Init()
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
HoTT_Sensor = 0;
|
||||
HoTT_Detected_Sensors=0;
|
||||
Timer_128 = 100
|
||||
end
|
||||
|
||||
-- Main
|
||||
@@ -111,18 +147,21 @@ local function HoTT_Run(event)
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
killEvents(event)
|
||||
HoTT_Send( 0x07 )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
HoTT_Send( 0x09 )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
HoTT_Send( 0x0B )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
HoTT_Send( 0x0D )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
HoTT_Send( 0x0E )
|
||||
elseif event == EVT_VIRTUAL_MENU then
|
||||
Timer_128 = 100
|
||||
HoTT_Sensor_Inc()
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
HoTT_Send( 0x0F )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
|
||||
@@ -164,8 +164,8 @@ end
|
||||
-- Init function
|
||||
local function init()
|
||||
thrCH1 = defaultChannel(2)
|
||||
rollCH1 = defaultChannel(0)
|
||||
yawCH1 = defaultChannel(3)
|
||||
rollCH1 = defaultChannel(3)
|
||||
yawCH1 = defaultChannel(0)
|
||||
pitchCH1 = defaultChannel(1)
|
||||
local ver, radio, maj, minor, rev = getVersion()
|
||||
-- if string.match(radio, "x7") then
|
||||
|
||||
+7
-6
@@ -18,8 +18,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_ARM_H_
|
||||
#define _AUDIO_ARM_H_
|
||||
#ifndef _AUDIO_H_
|
||||
#define _AUDIO_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
@@ -66,8 +66,11 @@ template <unsigned int NUM_BITS> class BitField {
|
||||
#define INDEX_LOGICAL_SWITCH_AUDIO_FILE(index, event) (2*(index)+(event))
|
||||
#define INDEX_PHASE_AUDIO_FILE(index, event) (2*(index)+(event))
|
||||
|
||||
// max length (example: /SOUNDS/fr/123456789012/1234567890-off.wav)
|
||||
constexpr uint8_t AUDIO_MODEL_FILENAME_MAXLEN = (sizeof("/SOUNDS/fr/") - 1) + LEN_MODEL_NAME + 1 + LEN_FLIGHT_MODE_NAME + (sizeof("-off.wav") - 1);
|
||||
constexpr uint8_t AUDIO_LUA_FILENAME_MAXLEN = 42; // Some scripts use long audio paths, even on 128x64 boards
|
||||
constexpr uint8_t AUDIO_FILENAME_MAXLEN = (AUDIO_LUA_FILENAME_MAXLEN > AUDIO_MODEL_FILENAME_MAXLEN ? AUDIO_LUA_FILENAME_MAXLEN : AUDIO_MODEL_FILENAME_MAXLEN);
|
||||
|
||||
#define AUDIO_FILENAME_MAXLEN (42) // max length (example: /SOUNDS/fr/123456789012/1234567890-off.wav)
|
||||
#define AUDIO_QUEUE_LENGTH (16) // must be a power of 2!
|
||||
|
||||
#define AUDIO_SAMPLE_RATE (32000)
|
||||
@@ -85,8 +88,6 @@ template <unsigned int NUM_BITS> class BitField {
|
||||
#define BEEP_MIN_FREQ (150)
|
||||
#define BEEP_MAX_FREQ (15000)
|
||||
#define BEEP_DEFAULT_FREQ (2250)
|
||||
#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+150)
|
||||
#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-150)
|
||||
|
||||
#if defined(AUDIO_DUAL_BUFFER)
|
||||
enum AudioBufferState
|
||||
@@ -655,4 +656,4 @@ void referenceModelAudioFiles();
|
||||
|
||||
bool isAudioFileReferenced(uint32_t i, char * filename/*at least AUDIO_FILENAME_MAXLEN+1 long*/);
|
||||
|
||||
#endif // _AUDIO_ARM_H_
|
||||
#endif // _AUDIO_H_
|
||||
|
||||
+12
-11
@@ -48,17 +48,18 @@ Bluetooth bluetooth;
|
||||
|
||||
void Bluetooth::write(const uint8_t * data, uint8_t length)
|
||||
{
|
||||
BLUETOOTH_TRACE("BT>");
|
||||
for (int i=0; i<length; i++) {
|
||||
BLUETOOTH_TRACE(" %02X", data[i]);
|
||||
while (btTxFifo.isFull()) {
|
||||
if (!bluetoothIsWriting())
|
||||
bluetoothWriteWakeup();
|
||||
RTOS_WAIT_MS(1);
|
||||
if (btTxFifo.hasSpace(length)) {
|
||||
BLUETOOTH_TRACE("BT>");
|
||||
for (int i = 0; i < length; i++) {
|
||||
BLUETOOTH_TRACE(" %02X", data[i]);
|
||||
btTxFifo.push(data[i]);
|
||||
}
|
||||
btTxFifo.push(data[i]);
|
||||
BLUETOOTH_TRACE(CRLF);
|
||||
}
|
||||
BLUETOOTH_TRACE(CRLF);
|
||||
else {
|
||||
BLUETOOTH_TRACE("[BT] TX fifo full!" CRLF);
|
||||
}
|
||||
|
||||
bluetoothWriteWakeup();
|
||||
}
|
||||
|
||||
@@ -175,7 +176,7 @@ void Bluetooth::processTrainerByte(uint8_t data)
|
||||
switch (dataState) {
|
||||
case STATE_DATA_START:
|
||||
if (data == START_STOP) {
|
||||
dataState = STATE_DATA_IN_FRAME ;
|
||||
dataState = STATE_DATA_IN_FRAME;
|
||||
bufferIndex = 0;
|
||||
}
|
||||
else {
|
||||
@@ -188,7 +189,7 @@ void Bluetooth::processTrainerByte(uint8_t data)
|
||||
dataState = STATE_DATA_XOR; // XOR next byte
|
||||
}
|
||||
else if (data == START_STOP) {
|
||||
dataState = STATE_DATA_IN_FRAME ;
|
||||
dataState = STATE_DATA_IN_FRAME;
|
||||
bufferIndex = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
+3
-16
@@ -384,20 +384,7 @@ PACK(struct TelemetrySensor {
|
||||
bool isPrecConfigurable() const;
|
||||
int32_t getPrecMultiplier() const;
|
||||
int32_t getPrecDivisor() const;
|
||||
bool isSameInstance(TelemetryProtocol protocol, uint8_t instance)
|
||||
{
|
||||
if (this->instance == instance)
|
||||
return true;
|
||||
|
||||
if (protocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) {
|
||||
if (((this->instance ^ instance) & 0x9F) == 0 && (this->instance >> 5) != TELEMETRY_ENDPOINT_SPORT && (instance >> 5) != TELEMETRY_ENDPOINT_SPORT) {
|
||||
this->instance = instance; // update the instance in case we had telemetry switching
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool isSameInstance(TelemetryProtocol protocol, uint8_t instance);
|
||||
);
|
||||
});
|
||||
|
||||
@@ -501,11 +488,11 @@ PACK(struct ModuleData {
|
||||
|
||||
// Helper functions to set both of the rfProto protocol at the same time
|
||||
NOBACKUP(inline uint8_t getMultiProtocol() {
|
||||
return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4);
|
||||
return ((uint8_t) (rfProtocol & 0x0F)) + (multi.rfProtocolExtra << 4);
|
||||
})
|
||||
|
||||
NOBACKUP(inline void setMultiProtocol(uint8_t proto) {
|
||||
rfProtocol = (uint8_t) (proto & 0x0f);
|
||||
rfProtocol = (uint8_t) (proto & 0x0F);
|
||||
multi.rfProtocolExtra = (proto & 0x70) >> 4;
|
||||
})
|
||||
});
|
||||
|
||||
+3
-3
@@ -71,7 +71,7 @@ class Fifo
|
||||
return (ridx == widx);
|
||||
}
|
||||
|
||||
bool isFull()
|
||||
bool isFull() const
|
||||
{
|
||||
uint32_t next = nextIndex(widx);
|
||||
return (next == ridx);
|
||||
@@ -82,7 +82,7 @@ class Fifo
|
||||
return (N + widx - ridx) & (N - 1);
|
||||
}
|
||||
|
||||
uint32_t hasSpace(uint32_t n) const
|
||||
bool hasSpace(uint32_t n) const
|
||||
{
|
||||
return (N > (size() + n));
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class Fifo
|
||||
volatile uint32_t widx;
|
||||
volatile uint32_t ridx;
|
||||
|
||||
inline uint32_t nextIndex(uint32_t idx)
|
||||
static inline uint32_t nextIndex(uint32_t idx)
|
||||
{
|
||||
return (idx + 1) & (N - 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
set(FONT "Roboto/Roboto-Regular")
|
||||
set(FONT_BOLD "Roboto/Roboto-Bold")
|
||||
set(FONT_OFFSET 1)
|
||||
|
||||
#set(FONT "Kanit/Kanit-Regular")
|
||||
#set(FONT_BOLD "Kanit/Kanit-Bold")
|
||||
#set(FONT_OFFSET -2)
|
||||
|
||||
#set(FONT "Ubuntu/Ubuntu-Regular")
|
||||
#set(FONT_BOLD "Ubuntu/Ubuntu-Bold")
|
||||
#set(FONT_OFFSET 1)
|
||||
|
||||
add_truetype_font_target(480x272 tinsize ${FONT} 9 0)
|
||||
add_truetype_font_target(480x272 smlsize ${FONT} 13 0)
|
||||
add_truetype_font_target(480x272 stdsize ${FONT} 16 1)
|
||||
add_truetype_font_target(480x272 stdsizebold ${FONT_BOLD} 16 1)
|
||||
add_truetype_font_target(480x272 midsize ${FONT} 24 0)
|
||||
add_truetype_font_target(480x272 dblsize ${FONT_BOLD} 32 0)
|
||||
add_truetype_font_target(480x272 xxlsize ${FONT_BOLD} 64 0)
|
||||
|
||||
add_custom_target(ttf_horus_fonts DEPENDS ${ttf_480x272_fonts_targets})
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -117,7 +117,6 @@ void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
struct PatternData
|
||||
{
|
||||
uint8_t width;
|
||||
@@ -144,10 +143,11 @@ uint8_t getPatternWidth(const PatternData * pattern)
|
||||
|
||||
void getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
unsigned char c_remapped = 0;
|
||||
|
||||
if (fontsize == DBLSIZE || (flags&BOLD)) {
|
||||
if (fontsize == DBLSIZE || (flags & BOLD)) {
|
||||
// To save space only some DBLSIZE and BOLD chars are available
|
||||
// c has to be remapped. All non existing chars mapped to 0 (space)
|
||||
if (c>=',' && c<=':')
|
||||
@@ -204,6 +204,11 @@ void getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
pattern->height = 7;
|
||||
pattern->data = (c < 0xC0) ? &font_5x7[(c-0x20)*5] : &font_5x7_extra[(c-0xC0)*5];
|
||||
}
|
||||
#else
|
||||
pattern->width = 5;
|
||||
pattern->height = 7;
|
||||
pattern->data = &font_5x7[(c-0x20)*5];
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
@@ -212,7 +217,6 @@ uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
getCharPattern(&pattern, c, flags);
|
||||
return getPatternWidth(&pattern);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, char c, LcdFlags flags)
|
||||
{
|
||||
@@ -287,12 +291,15 @@ void lcdDrawChar(coord_t x, coord_t y, char c)
|
||||
lcdDrawChar(x, y, c, 0);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
uint8_t width = 0;
|
||||
for (int i=0; len==0 || i<len; ++i) {
|
||||
for (int i = 0; len == 0 || i < len; ++i) {
|
||||
#if !defined(BOOT)
|
||||
unsigned char c = *s;
|
||||
#else
|
||||
unsigned char c = *s;
|
||||
#endif
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
@@ -301,7 +308,6 @@ uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
}
|
||||
return width;
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
@@ -310,7 +316,6 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
const uint8_t orig_len = len;
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
|
||||
#if !defined(BOOT)
|
||||
uint8_t width = 0;
|
||||
if (flags & RIGHT) {
|
||||
width = getTextWidth(s, len, flags);
|
||||
@@ -320,7 +325,6 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
width = getTextWidth(s, len, flags);
|
||||
x -= width / 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool setx = false;
|
||||
while (len--) {
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef uint8_t pixel_t;
|
||||
#define FIXEDWIDTH 0x10
|
||||
/* no 0x80 here because of "GV"1 which is aligned LEFT */
|
||||
/* no 0x10 here because of "MODEL"01 which uses LEADING0 */
|
||||
#define ZCHAR 0x80
|
||||
#define ZCHAR 0x80u
|
||||
|
||||
/* lcdDrawNumber additional flags */
|
||||
#define LEADING0 0x10
|
||||
|
||||
@@ -125,6 +125,9 @@ void menuModelCurveOne(event_t event)
|
||||
lcdDrawNumber(INDENT_WIDTH, 6*FH+1, 5+crv.points, LEFT|attr);
|
||||
lcdDrawText(lcdLastRightPos, 6*FH+1, STR_PTS, attr);
|
||||
if (attr) {
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
#endif
|
||||
int8_t count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
|
||||
if (checkIncDec_Ret) {
|
||||
int8_t newPoints[MAX_POINTS_PER_CURVE];
|
||||
|
||||
@@ -254,12 +254,13 @@ void menuModelLogicalSwitches(event_t event)
|
||||
uint8_t k = 0;
|
||||
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||
|
||||
if (event==EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
LogicalSwitchData * cs = lswAddress(sub);
|
||||
if (cs->func)
|
||||
s_currIdx = sub;
|
||||
POPUP_MENU_ADD_ITEM(STR_EDIT);
|
||||
if (sub >= 0)
|
||||
POPUP_MENU_ADD_ITEM(STR_EDIT);
|
||||
if (cs->func || cs->v1 || cs->v2 || cs->delay || cs->duration || cs->andsw)
|
||||
POPUP_MENU_ADD_ITEM(STR_COPY);
|
||||
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_SWITCH)
|
||||
|
||||
@@ -119,8 +119,6 @@ enum MenuModelSetupItems {
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PROTOCOL,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE,
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS,
|
||||
#endif
|
||||
@@ -163,8 +161,6 @@ enum MenuModelSetupItems {
|
||||
};
|
||||
|
||||
#define MODEL_SETUP_2ND_COLUMN (LCD_W-11*FW)
|
||||
#define MODEL_SETUP_BIND_OFS 2*FW+1
|
||||
#define MODEL_SETUP_RANGE_OFS 4*FW+3
|
||||
#define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2
|
||||
|
||||
#define IF_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? (uint8_t)(xxx) : HIDDEN_ROW)
|
||||
@@ -316,7 +312,7 @@ void onBluetoothConnectMenu(const char * result)
|
||||
MULTIMODULE_SUBTYPE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE */ \
|
||||
MULTIMODULE_STATUS_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS */ \
|
||||
MODULE_CHANNELS_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS */ \
|
||||
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(IF_INTERNAL_MODULE_ON(MODULE_BIND_ROWS(INTERNAL_MODULE)))), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
|
||||
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, MODULE_BIND_ROWS(INTERNAL_MODULE)), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM */ \
|
||||
MODULE_OPTION_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS */ \
|
||||
MULTIMODULE_MODULE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND */ \
|
||||
@@ -409,18 +405,19 @@ void menuModelSetup(event_t event)
|
||||
NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, // Center beeps
|
||||
0, // Global functions
|
||||
|
||||
LABEL(ExternalModule),
|
||||
LABEL(ExternalModule),
|
||||
MODULE_TYPE_ROWS(EXTERNAL_MODULE),
|
||||
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
|
||||
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE)
|
||||
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE),
|
||||
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum
|
||||
0, // Output type (OpenDrain / PushPull)
|
||||
MODULE_POWER_ROW(EXTERNAL_MODULE),
|
||||
IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)),
|
||||
MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE)
|
||||
FAILSAFE_ROWS(EXTERNAL_MODULE),
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons
|
||||
IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2
|
||||
@@ -590,7 +587,7 @@ void menuModelSetup(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_THROTTLE_REVERSED:
|
||||
g_model.throttleReversed = editCheckBox(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ;
|
||||
g_model.throttleReversed = editCheckBox(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event );
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_THROTTLE_TRACE:
|
||||
@@ -736,24 +733,24 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i<NUM_SWITCHES-1/*not on TRN switch*/; i++) {
|
||||
uint8_t swactive = !(g_model.switchWarningEnable & 1 << i);
|
||||
attr = 0;
|
||||
for (uint8_t i = 0; i < NUM_SWITCHES-1/*not on TRN switch*/; i++) {
|
||||
uint8_t swactive = !(g_model.switchWarningEnable & (1u << i));
|
||||
uint8_t swattr = 0;
|
||||
|
||||
if (IS_3POS(i)) {
|
||||
c = '0'+(states & 0x03);
|
||||
states >>= 2;
|
||||
c = '0' + (states & 0x03);
|
||||
states >>= 2u;
|
||||
}
|
||||
else {
|
||||
if ((states & 0x01) && swactive)
|
||||
attr = INVERS;
|
||||
swattr = INVERS;
|
||||
c = *(STR_VSWITCHES - 2 + 9 + (3*(i+1)));
|
||||
states >>= 1;
|
||||
states >>= 1u;
|
||||
}
|
||||
if (attr && (menuHorizontalPosition == i)) {
|
||||
attr = BLINK | INVERS;
|
||||
swattr = BLINK | INVERS;
|
||||
}
|
||||
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+i*FW, y, (swactive) ? c : '-', attr);
|
||||
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+i*FW, y, swactive ? c : '-', swattr);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+(NUM_SWITCHES*FW), y, "<]", (menuHorizontalPosition == NUM_SWITCHES-1 && !NO_HIGHLIGHT()) ? attr : 0);
|
||||
}
|
||||
#endif
|
||||
@@ -811,10 +808,9 @@ void menuModelSetup(event_t event)
|
||||
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER:
|
||||
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
// TODO flash saving, \001 not needed in STR_RETA123
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN+i*FW;
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) );
|
||||
for (uint8_t i = 0; i < NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN + i*FW;
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK | INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) );
|
||||
}
|
||||
if (attr) {
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
@@ -1110,7 +1106,7 @@ void menuModelSetup(event_t event)
|
||||
for (uint8_t i=0; i<popupMenuItemsCount; i++) {
|
||||
popupMenuItems[i] = reusableBuffer.moduleSetup.bt.devices[i];
|
||||
}
|
||||
popupMenuTitle = STR_BT_SELECT_DEVICE;
|
||||
POPUP_MENU_TITLE(STR_BT_SELECT_DEVICE);
|
||||
POPUP_MENU_START(onBluetoothConnectMenu);
|
||||
}
|
||||
}
|
||||
@@ -1306,8 +1302,7 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, STR_MS);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+5*FW+2, y, moduleData.sbus.noninverted ? STR_NOT_INVERTED : STR_NORMAL, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
|
||||
|
||||
if (attr && s_editMode>0) {
|
||||
if (attr && s_editMode > 0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35);
|
||||
@@ -1319,19 +1314,17 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
else {
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER);
|
||||
horzpos_t l_posHorz = menuHorizontalPosition;
|
||||
coord_t xOffsetBind = MODEL_SETUP_BIND_OFS;
|
||||
if (!isModuleRxNumAvailable(moduleIdx)) {
|
||||
xOffsetBind = 0;
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER);
|
||||
if (attr) l_posHorz += 1;
|
||||
coord_t bindButtonPos = MODEL_SETUP_2ND_COLUMN;
|
||||
if (isModuleRxNumAvailable(moduleIdx)) {
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
|
||||
bindButtonPos = lcdNextPos + 2;
|
||||
}
|
||||
else {
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER_NUM);
|
||||
else if (attr) {
|
||||
l_posHorz += 1;
|
||||
}
|
||||
if (isModuleBindRangeAvailable(moduleIdx)) {
|
||||
if (xOffsetBind)
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
|
||||
if (attr && l_posHorz == 0) {
|
||||
if (s_editMode > 0) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], getMaxRxNum(moduleIdx));
|
||||
@@ -1348,9 +1341,10 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
}
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, l_posHorz==1 ? attr : 0);
|
||||
if (!IS_RX_MULTI(moduleIdx))
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0);
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (isModuleRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(lcdNextPos + 2, y, STR_MODULE_RANGE, l_posHorz == 2 ? attr : 0);
|
||||
}
|
||||
uint8_t newFlag = 0;
|
||||
#if defined(MULTIMODULE)
|
||||
if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) {
|
||||
@@ -1393,7 +1387,7 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (attr && l_posHorz>0 && s_editMode>0) {
|
||||
if (attr && l_posHorz > 0 && s_editMode > 0) {
|
||||
if (l_posHorz == 1)
|
||||
newFlag = MODULE_MODE_BIND;
|
||||
else if (l_posHorz == 2)
|
||||
@@ -1425,7 +1419,8 @@ void menuModelSetup(event_t event)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE:
|
||||
#endif
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE: {
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE:
|
||||
{
|
||||
ModuleData &moduleData = g_model.moduleData[moduleIdx];
|
||||
lcdDrawTextAlignedLeft(y, STR_FAILSAFE);
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition == 0 ? attr : 0);
|
||||
|
||||
@@ -147,7 +147,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#if defined(PCBXLITE)
|
||||
// ENT LONG on xlite brings up switch type menu, so this menu is activated with SHIT + ENT LONG
|
||||
// ENT LONG on xlite brings up switch type menu, so this menu is activated with SHIFT + ENT LONG
|
||||
if (menuHorizontalPosition==0 && event==EVT_KEY_LONG(KEY_ENTER) && IS_SHIFT_PRESSED() && !READ_ONLY()) {
|
||||
#else
|
||||
if (menuHorizontalPosition<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
|
||||
|
||||
@@ -24,7 +24,7 @@ enum SensorFields {
|
||||
SENSOR_FIELD_NAME,
|
||||
SENSOR_FIELD_TYPE,
|
||||
SENSOR_FIELD_ID,
|
||||
SENSOR_FIELD_FORMULA=SENSOR_FIELD_ID,
|
||||
SENSOR_FIELD_FORMULA = SENSOR_FIELD_ID,
|
||||
SENSOR_FILED_RECEIVER_NAME,
|
||||
SENSOR_FIELD_UNIT,
|
||||
SENSOR_FIELD_PRECISION,
|
||||
|
||||
@@ -153,9 +153,9 @@ void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
unsigned char c_remapped = 0;
|
||||
|
||||
@@ -216,6 +216,11 @@ void getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
pattern->height = 7;
|
||||
pattern->data = (c < 0x80) ? &font_5x7[(c-0x20)*5] : &font_5x7_extra[(c-0x80)*5];
|
||||
}
|
||||
#else
|
||||
pattern->width = 5;
|
||||
pattern->height = 7;
|
||||
pattern->data = &font_5x7[(c-0x20) * 5];
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
@@ -224,7 +229,6 @@ uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
getCharPattern(&pattern, c, flags);
|
||||
return getPatternWidth(&pattern);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, char c, LcdFlags flags)
|
||||
{
|
||||
@@ -244,12 +248,15 @@ void lcdDrawChar(coord_t x, coord_t y, char c)
|
||||
lcdDrawChar(x, y, c, 0);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
uint8_t width = 0;
|
||||
for (int i=0; len==0 || i<len; ++i) {
|
||||
for (int i = 0; len == 0 || i < len; ++i) {
|
||||
#if !defined(BOOT)
|
||||
unsigned char c = *s;
|
||||
#else
|
||||
unsigned char c = *s;
|
||||
#endif
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
@@ -258,7 +265,6 @@ uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
}
|
||||
return width;
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
@@ -268,7 +274,6 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
bool setx = false;
|
||||
uint8_t width = 0;
|
||||
|
||||
#if !defined(BOOT)
|
||||
if (flags & RIGHT) {
|
||||
width = getTextWidth(s, len, flags);
|
||||
x -= width;
|
||||
@@ -277,7 +282,6 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
width = getTextWidth(s, len, flags);
|
||||
x -= width / 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (len--) {
|
||||
unsigned char c = *s;
|
||||
|
||||
@@ -168,10 +168,10 @@ void lcdClear();
|
||||
uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height);
|
||||
|
||||
#if defined(BOOT)
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 6))
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 7))
|
||||
#endif
|
||||
|
||||
inline pixel_t getPixel(unsigned int x, unsigned int y)
|
||||
|
||||
@@ -131,6 +131,9 @@ void menuModelCurveOne(event_t event)
|
||||
lcdDrawNumber(INDENT_WIDTH, 6*FH+1, 5+crv.points, LEFT|attr);
|
||||
lcdDrawText(lcdLastRightPos, 6*FH+1, STR_PTS, attr);
|
||||
if (attr) {
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
#endif
|
||||
int8_t count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
|
||||
if (checkIncDec_Ret) {
|
||||
int8_t newPoints[MAX_POINTS_PER_CURVE];
|
||||
|
||||
@@ -86,7 +86,7 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_LABEL,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE,
|
||||
@@ -103,7 +103,7 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
|
||||
#if defined(MULTIMODULE)
|
||||
@@ -347,10 +347,10 @@ void menuModelSetup(event_t event)
|
||||
LABEL(InternalModule),
|
||||
INTERNAL_MODULE_TYPE_ROWS,
|
||||
MODULE_CHANNELS_ROWS(INTERNAL_MODULE),
|
||||
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleBindRangeAvailable(INTERNAL_MODULE)? (uint8_t)2 : (uint8_t)1)), // RxNum, Range check and Register buttons
|
||||
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, MODULE_BIND_ROWS(INTERNAL_MODULE)), // RxNum, [Bind] and [Range] buttons
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // RxNum for ACCESS
|
||||
IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), // Failsafe
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), // Range check and Register buttons
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), // [Range] and [Register] buttons
|
||||
IF_PXX2_MODULE(INTERNAL_MODULE, 0), // Module options
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 1
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 2
|
||||
@@ -536,7 +536,7 @@ void menuModelSetup(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_THROTTLE_REVERSED:
|
||||
g_model.throttleReversed = editCheckBox(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ;
|
||||
g_model.throttleReversed = editCheckBox(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event );
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_THROTTLE_TRACE:
|
||||
@@ -1000,7 +1000,7 @@ void menuModelSetup(event_t event)
|
||||
for (uint8_t i=0; i<popupMenuItemsCount; i++) {
|
||||
popupMenuItems[i] = reusableBuffer.moduleSetup.bt.devices[i];
|
||||
}
|
||||
popupMenuTitle = STR_BT_SELECT_DEVICE;
|
||||
POPUP_MENU_TITLE(STR_BT_SELECT_DEVICE);
|
||||
POPUP_MENU_START(onBluetoothConnectMenu);
|
||||
}
|
||||
}
|
||||
@@ -1086,8 +1086,8 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND:
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND:
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
|
||||
{
|
||||
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
|
||||
ModuleData & moduleData = g_model.moduleData[moduleIdx];
|
||||
@@ -1098,8 +1098,7 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+6*FW, y, (moduleData.ppm.delay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
|
||||
lcdDrawChar(lcdLastRightPos, y, 'u');
|
||||
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+12*FW, y, moduleData.ppm.pulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0);
|
||||
|
||||
if (attr && s_editMode>0) {
|
||||
if (attr && s_editMode > 0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -20, 35);
|
||||
@@ -1117,9 +1116,8 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawTextAlignedLeft(y, STR_REFRESHRATE);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, STR_MS);
|
||||
lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? "not inverted" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
|
||||
|
||||
if (attr && s_editMode>0) {
|
||||
lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? STR_NOT_INVERTED : STR_NORMAL, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
|
||||
if (attr && s_editMode > 0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35);
|
||||
@@ -1131,25 +1129,19 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
else {
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER);
|
||||
horzpos_t l_posHorz = menuHorizontalPosition;
|
||||
coord_t bindButtonPos = MODEL_SETUP_2ND_COLUMN;
|
||||
if (!isModuleRxNumAvailable(moduleIdx)) {
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER);
|
||||
if (attr) l_posHorz += 1;
|
||||
if (isModuleRxNumAvailable(moduleIdx)) {
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz == 0 ? attr : 0) | LEADING0 | LEFT, 2);
|
||||
bindButtonPos = lcdNextPos + FW;
|
||||
}
|
||||
else {
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_RECEIVER_NUM);
|
||||
else if (attr) {
|
||||
l_posHorz += 1;
|
||||
}
|
||||
if (isModuleBindRangeAvailable(moduleIdx)) {
|
||||
if (!IS_RX_MULTI(moduleIdx)) {
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz == 0 ? attr : 0) | LEADING0 | LEFT, 2);
|
||||
bindButtonPos = lcdNextPos + FW;
|
||||
}
|
||||
else {
|
||||
bindButtonPos = MODEL_SETUP_2ND_COLUMN;
|
||||
}
|
||||
if (attr && l_posHorz==0) {
|
||||
if (s_editMode>0) {
|
||||
if (attr && l_posHorz == 0) {
|
||||
if (s_editMode > 0) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], getMaxRxNum(moduleIdx));
|
||||
if (checkIncDec_Ret) {
|
||||
modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx];
|
||||
@@ -1164,9 +1156,10 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
}
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz==1 ? attr : 0);
|
||||
if (!IS_RX_MULTI(moduleIdx))
|
||||
lcdDrawText(lcdNextPos + FW, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0);
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (isModuleRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(lcdNextPos + FW, y, STR_MODULE_RANGE, l_posHorz == 2 ? attr : 0);
|
||||
}
|
||||
uint8_t newFlag = 0;
|
||||
#if defined(MULTIMODULE)
|
||||
if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) {
|
||||
@@ -1174,8 +1167,8 @@ void menuModelSetup(event_t event)
|
||||
s_editMode = 0;
|
||||
}
|
||||
#endif
|
||||
if (attr && l_posHorz>0) {
|
||||
if (s_editMode>0) {
|
||||
if (attr && l_posHorz > 0) {
|
||||
if (s_editMode > 0) {
|
||||
if (l_posHorz == 1) {
|
||||
if (isModuleR9MNonAccess(moduleIdx) || isModuleD16(moduleIdx)) {
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
@@ -1202,8 +1195,9 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
moduleState[moduleIdx].mode = newFlag;
|
||||
#if defined(MULTIMODULE)
|
||||
if (newFlag == MODULE_MODE_BIND)
|
||||
if (newFlag == MODULE_MODE_BIND) {
|
||||
setMultiBindStatus(moduleIdx, MULTI_BIND_INITIATED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1453,12 +1447,12 @@ void menuModelSetup(event_t event)
|
||||
|
||||
if (old_editMode > 0 && s_editMode == 0) {
|
||||
switch(menuVerticalPosition) {
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND:
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
|
||||
if (menuHorizontalPosition == 0)
|
||||
checkModelIdUnique(g_eeGeneral.currModel, INTERNAL_MODULE);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND:
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
|
||||
if (menuHorizontalPosition == 0)
|
||||
checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE);
|
||||
break;
|
||||
|
||||
@@ -99,7 +99,6 @@ void setCurrentCategory(unsigned int index)
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
|
||||
#define MAX_WIZARD_NAME_LEN (sizeof(WIZARD_PATH)+20)
|
||||
#define WIZARD_SPACING 40
|
||||
#define WIZARD_LEFT_SPACING 30
|
||||
@@ -248,6 +247,7 @@ void onModelSelectMenu(const char * result)
|
||||
storageCheck(true);
|
||||
memcpy(g_eeGeneral.currModelFilename, currentModel->modelFilename, LEN_MODEL_FILENAME);
|
||||
modelslist.setCurrentModel(currentModel);
|
||||
modelslist.setCurrentCategory(currentCategory);
|
||||
loadModel(g_eeGeneral.currModelFilename, true);
|
||||
storageDirty(EE_GENERAL);
|
||||
storageCheck(true);
|
||||
@@ -264,6 +264,7 @@ void onModelSelectMenu(const char * result)
|
||||
selectMode = MODE_SELECT_MODEL;
|
||||
setCurrentModel(currentCategory->size() - 1);
|
||||
modelslist.setCurrentModel(currentModel);
|
||||
modelslist.setCurrentCategory(currentCategory);
|
||||
modelslist.onNewModelCreated(currentModel, &g_model);
|
||||
#if defined(LUA)
|
||||
chainMenu(menuModelWizard);
|
||||
@@ -274,7 +275,7 @@ void onModelSelectMenu(const char * result)
|
||||
memcpy(duplicatedFilename, currentModel->modelFilename, sizeof(duplicatedFilename));
|
||||
if (findNextFileIndex(duplicatedFilename, LEN_MODEL_FILENAME, MODELS_PATH)) {
|
||||
sdCopyFile(currentModel->modelFilename, MODELS_PATH, duplicatedFilename, MODELS_PATH);
|
||||
ModelCell* dup_model = modelslist.addModel(currentCategory, duplicatedFilename);
|
||||
ModelCell * dup_model = modelslist.addModel(currentCategory, duplicatedFilename);
|
||||
dup_model->fetchRfData();
|
||||
setCurrentModel(currentCategory->size() - 1);
|
||||
}
|
||||
@@ -344,7 +345,7 @@ void initModelsList()
|
||||
bool menuModelSelect(event_t event)
|
||||
{
|
||||
const std::list<ModelsCategory*>& cats = modelslist.getCategories();
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
case 0:
|
||||
// no need to refresh the screen
|
||||
return false;
|
||||
@@ -387,7 +388,7 @@ bool menuModelSelect(event_t event)
|
||||
categoriesVerticalPosition -= 1;
|
||||
setCurrentCategory(categoriesVerticalPosition);
|
||||
modelslist.moveModel(model, previous_category, currentCategory);
|
||||
setCurrentModel(currentCategory->size()-1);
|
||||
setCurrentModel(currentCategory->size() - 1);
|
||||
}
|
||||
killEvents(event);
|
||||
break;
|
||||
|
||||
@@ -63,7 +63,7 @@ class ModelBitmapWidget: public Widget
|
||||
}
|
||||
}
|
||||
|
||||
virtual void refresh()
|
||||
void refresh() override
|
||||
{
|
||||
uint32_t new_hash = hash(g_model.header.bitmap, sizeof(g_model.header.bitmap));
|
||||
new_hash ^= hash(g_model.header.name, sizeof(g_model.header.name));
|
||||
|
||||
@@ -33,7 +33,7 @@ class OutputsWidget: public Widget
|
||||
{
|
||||
}
|
||||
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
uint8_t drawChannels(const uint16_t & x, const uint16_t & y, const uint16_t & w, const uint16_t & h, const uint8_t & firstChan, const bool & bg_shown, const uint16_t & bg_color)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ class TextWidget: public Widget
|
||||
{
|
||||
}
|
||||
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ class TimerWidget: public Widget
|
||||
{
|
||||
}
|
||||
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ class ValueWidget: public Widget
|
||||
{
|
||||
}
|
||||
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
uint8_t getExposCount()
|
||||
{
|
||||
uint8_t count = 0;
|
||||
uint8_t ch ;
|
||||
uint8_t ch;
|
||||
|
||||
for (int i=MAX_EXPOS-1 ; i>=0; i--) {
|
||||
ch = EXPO_VALID(expoAddress(i));
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
uint8_t getMixesCount()
|
||||
{
|
||||
uint8_t count = 0;
|
||||
uint8_t ch ;
|
||||
uint8_t ch;
|
||||
|
||||
for (int i=MAX_MIXERS-1; i>=0; i--) {
|
||||
ch = mixAddress(i)->srcRaw;
|
||||
|
||||
@@ -80,5 +80,6 @@ void startBindMenu(uint8_t moduleIdx)
|
||||
selection += 1;
|
||||
|
||||
POPUP_MENU_SELECT_ITEM(selection);
|
||||
POPUP_MENU_TITLE(STR_SELECT_MODE);
|
||||
POPUP_MENU_START(onBindMenu);
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ void modelSetupModulePxx2ReceiverLine(uint8_t moduleIdx, uint8_t receiverIdx, co
|
||||
for (auto rx = 0; rx < popupMenuItemsCount; rx++) {
|
||||
popupMenuItems[rx] = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[rx];
|
||||
}
|
||||
popupMenuTitle = STR_PXX2_SELECT_RX;
|
||||
POPUP_MENU_TITLE(STR_PXX2_SELECT_RX);
|
||||
POPUP_MENU_START(onPXX2BindMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ enum
|
||||
{
|
||||
warningText = nullptr;
|
||||
warningInfoText = nullptr;
|
||||
popupMenuTitle = nullptr;
|
||||
popupMenuHandler = nullptr;
|
||||
popupMenuItemsCount = 0;
|
||||
}
|
||||
@@ -171,6 +172,11 @@ inline void POPUP_MENU_SELECT_ITEM(uint8_t index)
|
||||
popupMenuSelectedItem = (index > 0 ? (index < popupMenuItemsCount ? index : popupMenuItemsCount) : 0);
|
||||
}
|
||||
|
||||
inline void POPUP_MENU_TITLE(const char * s)
|
||||
{
|
||||
popupMenuTitle = s;
|
||||
}
|
||||
|
||||
inline void POPUP_MENU_START(PopupMenuHandler handler)
|
||||
{
|
||||
if (handler != popupMenuHandler) {
|
||||
|
||||
@@ -585,7 +585,7 @@ void menuRadioSdManager(event_t _event)
|
||||
for (auto rx = 0; rx < popupMenuItemsCount; rx++) {
|
||||
popupMenuItems[rx] = reusableBuffer.sdManager.otaUpdateInformation.candidateReceiversNames[rx];
|
||||
}
|
||||
popupMenuTitle = STR_PXX2_SELECT_RX;
|
||||
POPUP_MENU_TITLE(STR_PXX2_SELECT_RX);
|
||||
POPUP_MENU_START(onUpdateReceiverSelection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
#include "opentx.h"
|
||||
|
||||
#if LCD_W >= 212
|
||||
#define TRAINER_CALIB_COLUMN_WIDTH 12
|
||||
#define TRAINER_CALIB_COLUMN_WIDTH (6 * FW)
|
||||
#else
|
||||
#define TRAINER_CALIB_COLUMN_WIDTH 8
|
||||
#define TRAINER_CALIB_COLUMN_WIDTH (4 * FW + 2)
|
||||
#endif
|
||||
|
||||
void menuRadioTrainer(event_t event)
|
||||
@@ -86,8 +86,8 @@ void menuRadioTrainer(event_t event)
|
||||
if (attr)
|
||||
s_editMode = 0;
|
||||
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr);
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
uint8_t x = (i*TRAINER_CALIB_COLUMN_WIDTH + 16) * FW/2;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint8_t x = 8*FW + (i * TRAINER_CALIB_COLUMN_WIDTH);
|
||||
int32_t chVal = ppmInput[i] - g_eeGeneral.trainer.calib[i];
|
||||
chVal *= g_eeGeneral.trainer.mix[i].studWeight * 10;
|
||||
chVal /= 512;
|
||||
|
||||
@@ -883,7 +883,7 @@ const char STR_SUBTYPE_SYMAX[] = "\003""Std""X5C";
|
||||
const char STR_SUBTYPE_SLT[] = "\006""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0";
|
||||
const char STR_SUBTYPE_CX10[] = "\007""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
|
||||
const char STR_SUBTYPE_CG023[] = "\005""Std\0 ""YD829";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
|
||||
const char STR_SUBTYPE_ESky[] = "\003""Std""ET4";
|
||||
const char STR_SUBTYPE_MT99[] = "\006""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805";
|
||||
const char STR_SUBTYPE_MJXQ[] = "\007""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
|
||||
@@ -909,7 +909,9 @@ const char STR_SUBTYPE_POTENSIC[] = "\003""A20";
|
||||
const char STR_SUBTYPE_ZSX[] = "\007""280JJRC";
|
||||
const char STR_SUBTYPE_FLYZONE[] = "\005""FZ410";
|
||||
const char STR_SUBTYPE_FRSKYX_RX[] = "\007""RX\0 ""CloneTX";
|
||||
const char STR_SUBTYPE_HOTT[] = "\007""Sync\0 ""No_Sync";
|
||||
const char STR_SUBTYPE_FX816[] = "\003""P38";
|
||||
const char STR_SUBTYPE_PELIKAN[] = "\004""Pro\0""Lite";
|
||||
const char STR_SUBTYPE_XK[] = "\004""X450""X420";
|
||||
const char STR_SUBTYPE_XN297DUMP[] = "\004""250K""1M\0 ""2M\0 ""AUTO";
|
||||
const char STR_SUBTYPE_FRSKYX2[] = "\011""D16\0 ""D16 8ch\0 ""LBT(EU)\0 ""LBT 8ch\0 ""D16Cloned";
|
||||
@@ -945,7 +947,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{MODULE_SUBTYPE_MULTI_SLT, 4, false, true, STR_SUBTYPE_SLT, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_CX10, 6, false, false, STR_SUBTYPE_CX10, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CG023, 1, false, false, STR_SUBTYPE_CG023, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 4, false, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 5, false, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_ESky, 1, false, true, STR_SUBTYPE_ESky, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MT99XX, 4, false, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MJXQ, 6, false, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE},
|
||||
@@ -975,8 +977,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, false, STR_SUBTYPE_ZSX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, false, STR_SUBTYPE_FLYZONE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HOTT, 0, true, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HOTT, 1, true, false, STR_SUBTYPE_HOTT, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FX816, 0, false, false, STR_SUBTYPE_FX816, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, false, STR_SUBTYPE_PELIKAN, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_XK, 1, false, false, STR_SUBTYPE_XK, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_XN297DUMP, 3, false, false, STR_SUBTYPE_XN297DUMP, STR_MULTI_RFCHAN},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX2, 4, true, false, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE},
|
||||
@@ -985,6 +988,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, true, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_Q90C, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, true, NO_SUBTYPE, STR_MULTI_OPTION},
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
|
||||
@@ -147,27 +147,44 @@ void drawCurve(coord_t offset=0);
|
||||
|
||||
inline uint8_t MODULE_BIND_ROWS(int moduleIdx)
|
||||
{
|
||||
if (isModuleXJTD8(moduleIdx) || isModuleSBUS(moduleIdx) || IS_RX_MULTI(moduleIdx))
|
||||
if (isModuleMultimodule(moduleIdx)) {
|
||||
if (IS_RX_MULTI(moduleIdx))
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
else if (isModuleXJTD8(moduleIdx) || isModuleSBUS(moduleIdx)) {
|
||||
return 1;
|
||||
|
||||
if (isModulePPM(moduleIdx) || isModulePXX1(moduleIdx) || isModulePXX2(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx))
|
||||
}
|
||||
else if (isModulePPM(moduleIdx) || isModulePXX1(moduleIdx) || isModulePXX2(moduleIdx) || isModuleDSM2(moduleIdx)) {
|
||||
return 2;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return HIDDEN_ROW;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx)
|
||||
{
|
||||
if (!IS_MODULE_ENABLED(moduleIdx) || IS_RX_MULTI(moduleIdx))
|
||||
if (!IS_MODULE_ENABLED(moduleIdx)) {
|
||||
return HIDDEN_ROW;
|
||||
|
||||
if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol() != MODULE_SUBTYPE_MULTI_DSM2))
|
||||
}
|
||||
else if (isModuleMultimodule(moduleIdx)) {
|
||||
if (IS_RX_MULTI(moduleIdx))
|
||||
return HIDDEN_ROW;
|
||||
else if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx)) {
|
||||
return 0;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx)
|
||||
{
|
||||
@@ -270,7 +287,9 @@ inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx)
|
||||
#else
|
||||
#define MULTIMODULE_STATUS_ROWS(moduleIdx)
|
||||
#define MULTIMODULE_MODULE_ROWS(moduleIdx)
|
||||
#define MULTIMODULE_TYPE_ROW(moduleIdx)
|
||||
#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx)
|
||||
#define MULTIMODULE_TYPE_ROWS(moduleIdx)
|
||||
#define MULTIMODULE_MODE_ROWS(moduleIdx) (uint8_t)0
|
||||
#define MULTIMODULE_OPTIONS_ROW(moduleIdx) HIDDEN_ROW
|
||||
#define MODULE_POWER_ROW(moduleIdx) isModuleR9MNonAccess(moduleIdx) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW
|
||||
|
||||
@@ -265,7 +265,7 @@ class LuaWidget: public Widget
|
||||
|
||||
virtual void update();
|
||||
|
||||
virtual void refresh();
|
||||
void refresh() override;
|
||||
|
||||
virtual void background();
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ void openUsbMenu()
|
||||
#if defined(DEBUG)
|
||||
POPUP_MENU_ADD_ITEM(STR_USB_SERIAL);
|
||||
#endif
|
||||
POPUP_MENU_TITLE(STR_SELECT_MODE);
|
||||
POPUP_MENU_START(onUSBConnectMenu);
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -939,7 +939,7 @@ void evalMixes(uint8_t tick10ms)
|
||||
mixerCurrentFlightMode = p;
|
||||
evalFlightModeMixes(p==fm ? e_perout_mode_normal : e_perout_mode_inactive_flight_mode, p==fm ? tick10ms : 0);
|
||||
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++)
|
||||
sum_chans512[i] += (chans[i] >> 4) * fp_act[p];
|
||||
sum_chans512[i] += limit<int32_t>(-0x6fff, chans[i] >> 4, 0x6fff) * fp_act[p];
|
||||
weight += fp_act[p];
|
||||
}
|
||||
}
|
||||
@@ -1003,5 +1003,4 @@ void evalMixes(uint8_t tick10ms)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -771,7 +771,7 @@ void doSplash()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FRSKY_RELEASE)
|
||||
#if defined(FRSKY_RELEASE) && !defined(COLORLCD)
|
||||
static uint8_t secondSplash = false;
|
||||
if (!secondSplash && get_tmr10ms() >= tgtime-200) {
|
||||
secondSplash = true;
|
||||
|
||||
+1
-1
@@ -698,7 +698,7 @@ extern const char vers_stamp[];
|
||||
* @param buffer If non-null find the firmware version in the buffer instead
|
||||
* @return The opentx version string starting with "opentx-" or "no version found" if the version string is not found
|
||||
*/
|
||||
const char * getOtherVersion(char * buffer);
|
||||
const char * getFirmwareVersion(const char * buffer = nullptr);
|
||||
|
||||
#define g_blinkTmr10ms (*(uint8_t*)&g_tmr10ms)
|
||||
|
||||
|
||||
@@ -167,11 +167,12 @@ enum ModuleSubtypeMulti {
|
||||
MODULE_SUBTYPE_MULTI_FRSKY_R9,
|
||||
MODULE_SUBTYPE_MULTI_PROPEL,
|
||||
MODULE_SUBTYPE_MULTI_FRSKYL,
|
||||
MODULE_SUBTYPE_MULTI_SKYARTEC,
|
||||
MODULE_SUBTYPE_MULTI_SKYARTEC, //65
|
||||
MODULE_SUBTYPE_MULTI_ESKY150V2,
|
||||
MODULE_SUBTYPE_MULTI_DSM_RX,
|
||||
MODULE_SUBTYPE_MULTI_JJRC345,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_JJRC345
|
||||
MODULE_SUBTYPE_MULTI_Q90C,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C
|
||||
};
|
||||
#define MODULE_SUBTYPE_MULTI_XN297DP 63-3
|
||||
|
||||
|
||||
@@ -474,6 +474,11 @@ inline bool isModuleBindRangeAvailable(uint8_t moduleIdx)
|
||||
return isModulePXX2(moduleIdx) || isModulePXX1(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx);
|
||||
}
|
||||
|
||||
inline bool isModuleRangeAvailable(uint8_t moduleIdx)
|
||||
{
|
||||
return isModuleBindRangeAvailable(moduleIdx) && !IS_RX_MULTI(moduleIdx);
|
||||
}
|
||||
|
||||
constexpr uint8_t MAX_RXNUM = 63;
|
||||
|
||||
inline uint8_t getMaxRxNum(uint8_t idx)
|
||||
|
||||
@@ -393,7 +393,7 @@ void sendSport(uint8_t moduleIdx)
|
||||
|
||||
void sendHott(uint8_t moduleIdx)
|
||||
{
|
||||
if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0 && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) {
|
||||
if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0 && (Multi_Buffer[5] & 0x80) && (Multi_Buffer[5] & 0x0F) >= 0x07) {
|
||||
// HoTT Lua script is running
|
||||
sendMulti(moduleIdx, Multi_Buffer[5]);
|
||||
}
|
||||
|
||||
@@ -319,6 +319,13 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||
intmoduleTimerStart(MULTIMODULE_PERIOD);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_PPM)
|
||||
case PROTOCOL_CHANNELS_PPM:
|
||||
intmodulePpmStart();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -352,6 +352,7 @@ void sendByteDsm2(uint8_t b);
|
||||
void putDsm2Flush();
|
||||
void putDsm2SerialBit(uint8_t bit);
|
||||
void sendByteSbus(uint8_t b);
|
||||
void intmodulePpmStart();
|
||||
void intmodulePxx1PulsesStart();
|
||||
void intmodulePxx1SerialStart();
|
||||
void extmodulePxx1PulsesStart();
|
||||
@@ -359,6 +360,7 @@ void extmodulePxx1SerialStart();
|
||||
void extmodulePpmStart();
|
||||
void intmoduleStop();
|
||||
void extmoduleStop();
|
||||
void extramodulePpmStart();
|
||||
|
||||
inline void startPulses()
|
||||
{
|
||||
|
||||
+22
-28
@@ -29,26 +29,26 @@
|
||||
#define TAB "\037\033"
|
||||
|
||||
#if defined(FRSKY_RELEASE)
|
||||
#define DISPLAY_VERSION "FrSky"
|
||||
#define DISPLAY_VERSION "-frsky"
|
||||
#elif defined(JUMPER_RELEASE)
|
||||
#define DISPLAY_VERSION "JumperRC"
|
||||
#define DISPLAY_VERSION "-jumper"
|
||||
#elif defined(RADIOMASTER_RELEASE)
|
||||
#define DISPLAY_VERSION "Radiomaster"
|
||||
#define DISPLAY_VERSION "-radiomaster"
|
||||
#elif defined(TBS_RELEASE)
|
||||
#define DISPLAY_VERSION "TBS"
|
||||
#define DISPLAY_VERSION "-tbs"
|
||||
#else
|
||||
#define DISPLAY_VERSION VERSION
|
||||
#define DISPLAY_VERSION
|
||||
#endif
|
||||
|
||||
#if defined(COLORLCD)
|
||||
const char vers_stamp[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")";
|
||||
const char date_stamp[] = DATE;
|
||||
const char time_stamp[] = TIME;
|
||||
const char eeprom_stamp[] = EEPROM_STR;
|
||||
const char vers_stamp[] = "VERS" TAB ": " VERSION DISPLAY_VERSION " (" GIT_STR ")";
|
||||
const char date_stamp[] = "DATE" TAB ": " DATE;
|
||||
const char time_stamp[] = "TIME" TAB ": " TIME;
|
||||
const char eeprom_stamp[] = "EEPR" TAB ": " EEPROM_STR;
|
||||
#elif defined(BOARD_NAME)
|
||||
const char vers_stamp[] = "FW" TAB ": opentx-" BOARD_NAME "\036VERS" TAB ": " DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR;
|
||||
const char vers_stamp[] = "FW" TAB ": opentx-" BOARD_NAME "\036VERS" TAB ": " VERSION DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR;
|
||||
#else
|
||||
const char vers_stamp[] = "FW" TAB ": opentx-" FLAVOUR "\036VERS" TAB ": " DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR;
|
||||
const char vers_stamp[] = "FW" TAB ": opentx-" FLAVOUR "\036VERS" TAB ": " VERSION DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -56,35 +56,29 @@
|
||||
* @return
|
||||
*/
|
||||
#if defined(STM32) && !defined(SIMU)
|
||||
|
||||
__SECTION_USED(".fwversiondata") const char firmware_version[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")";
|
||||
__SECTION_USED(".bootversiondata") const char boot_version[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")";
|
||||
__SECTION_USED(".fwversiondata") const char firmware_version[] = "opentx-" FLAVOUR "-" VERSION DISPLAY_VERSION " (" GIT_STR ")";
|
||||
__SECTION_USED(".bootversiondata") const char boot_version[] = "opentx-" FLAVOUR "-" VERSION DISPLAY_VERSION " (" GIT_STR ")";
|
||||
|
||||
/**
|
||||
* Tries to find opentx version in the first 1024 byte of either firmware/bootloader (the one not running) or the buffer
|
||||
* @param buffer If non-null find the firmware version in the buffer instead
|
||||
*/
|
||||
const char * getOtherVersion(char* buffer)
|
||||
const char * getFirmwareVersion(const char * buffer)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
#if defined(BOOT)
|
||||
const char * startother = (char*)(FIRMWARE_ADDRESS+BOOTLOADER_SIZE);
|
||||
buffer = (const char *)(FIRMWARE_ADDRESS + BOOTLOADER_SIZE);
|
||||
#else
|
||||
const char * startother = (char*)(FIRMWARE_ADDRESS);
|
||||
buffer = (const char *)FIRMWARE_ADDRESS;
|
||||
#endif
|
||||
if (buffer != nullptr)
|
||||
startother = buffer;
|
||||
}
|
||||
|
||||
const char * other_str = nullptr;
|
||||
for (int i=0; i<1024;i++) {
|
||||
if (memcmp(startother+i, "opentx-", 7) == 0) {
|
||||
other_str = startother + i;
|
||||
break;
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
if (memcmp(buffer + i, "opentx-", 7) == 0) {
|
||||
return buffer + i;
|
||||
}
|
||||
}
|
||||
|
||||
if (other_str != nullptr)
|
||||
return other_str;
|
||||
else
|
||||
return "no version found";
|
||||
return "no version found";
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -475,12 +475,12 @@ void ModelsList::save()
|
||||
f_close(&file);
|
||||
}
|
||||
|
||||
void ModelsList::setCurrentCategorie(ModelsCategory* cat)
|
||||
void ModelsList::setCurrentCategory(ModelsCategory * cat)
|
||||
{
|
||||
currentCategory = cat;
|
||||
}
|
||||
|
||||
void ModelsList::setCurrentModel(ModelCell* cell)
|
||||
void ModelsList::setCurrentModel(ModelCell * cell)
|
||||
{
|
||||
currentModel = cell;
|
||||
if (!currentModel->valid_rfData)
|
||||
|
||||
@@ -44,8 +44,8 @@ struct SimpleModuleData
|
||||
class ModelCell
|
||||
{
|
||||
public:
|
||||
char modelFilename[LEN_MODEL_FILENAME+1];
|
||||
char modelName[LEN_MODEL_NAME+1] = {};
|
||||
char modelFilename[LEN_MODEL_FILENAME + 1];
|
||||
char modelName[LEN_MODEL_NAME + 1] = {};
|
||||
|
||||
bool valid_rfData;
|
||||
uint8_t modelId[NUM_MODULES];
|
||||
@@ -55,11 +55,11 @@ class ModelCell
|
||||
explicit ModelCell(const char * name, uint8_t len);
|
||||
~ModelCell();
|
||||
|
||||
void save(FIL* file);
|
||||
void save(FIL * file);
|
||||
|
||||
void setModelName(char* name);
|
||||
void setModelName(char * name);
|
||||
void setModelName(char* name, uint8_t len);
|
||||
void setRfData(ModelData* model);
|
||||
void setRfData(ModelData * model);
|
||||
|
||||
void setModelId(uint8_t moduleIdx, uint8_t id);
|
||||
void setRfModuleData(uint8_t moduleIdx, ModuleData* modData);
|
||||
@@ -72,7 +72,7 @@ class ModelCell
|
||||
class ModelsCategory: public std::list<ModelCell *>
|
||||
{
|
||||
public:
|
||||
char name[LEN_MODEL_FILENAME+1];
|
||||
char name[LEN_MODEL_FILENAME + 1];
|
||||
|
||||
explicit ModelsCategory(const char * name);
|
||||
explicit ModelsCategory(const char * name, uint8_t len);
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
return categories;
|
||||
}
|
||||
|
||||
void setCurrentCategorie(ModelsCategory * cat);
|
||||
void setCurrentCategory(ModelsCategory * cat);
|
||||
|
||||
ModelsCategory * getCurrentCategory() const
|
||||
{
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
void incModelsCount() {
|
||||
modelsCount++;
|
||||
}
|
||||
|
||||
|
||||
unsigned int getModelsCount() const
|
||||
{
|
||||
return modelsCount;
|
||||
@@ -155,7 +155,6 @@ public:
|
||||
|
||||
protected:
|
||||
FIL file;
|
||||
|
||||
};
|
||||
|
||||
extern ModelsList modelslist;
|
||||
|
||||
@@ -117,10 +117,10 @@ FRESULT openBinFile(MemoryType mt, unsigned int index)
|
||||
|
||||
void extractFirmwareVersion(VersionTag* tag)
|
||||
{
|
||||
const char* vers = getOtherVersion((char*)Block_buffer);
|
||||
const char * vers = getFirmwareVersion((const char *)Block_buffer);
|
||||
if (!vers || (vers[0] == 'n' && vers[1] == 'o')) { // "no version found"
|
||||
memcpy(tag->flavour, "unknown", sizeof("unknown"));
|
||||
tag->version = "unknown";
|
||||
memcpy(tag->flavour, "unknown", sizeof("unknown"));
|
||||
tag->version = "unknown";
|
||||
}
|
||||
|
||||
// skip "opentx-"
|
||||
|
||||
@@ -210,21 +210,6 @@ int main()
|
||||
pwrInit();
|
||||
keysInit();
|
||||
|
||||
// USB charger handling
|
||||
#if defined(USB_CHARGER)
|
||||
if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() && !pwrPressed()) {
|
||||
ledInit();
|
||||
usbChargerInit();
|
||||
ledOff();
|
||||
while (!pwrPressed()) {
|
||||
if(usbChargerLed())
|
||||
GPIO_SetBits(LED_GPIO, LED_GREEN_GPIO_PIN);
|
||||
else
|
||||
ledOff();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait a bit for the inputs to stabilize...
|
||||
if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
for (uint32_t i = 0; i < 150000; i++) {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "stamp.h"
|
||||
|
||||
#if LCD_W < 212
|
||||
#define BOOTLOADER_TITLE " OTX Bootloader - " VERSION
|
||||
#define BOOTLOADER_TITLE " Bootloader - " VERSION
|
||||
#else
|
||||
#define BOOTLOADER_TITLE " OpenTX Bootloader - " VERSION
|
||||
#endif
|
||||
@@ -34,12 +34,12 @@
|
||||
#if LCD_W >= 480
|
||||
#define STR_INVALID_FIRMWARE "Not a valid firmware file"
|
||||
#elif LCD_W >= 212
|
||||
#define STR_OR_PLUGIN_USB_CABLE INDENT "Or plug in a USB cable for mass storage"
|
||||
#define STR_OR_PLUGIN_USB_CABLE "Or plug in a USB cable for mass storage"
|
||||
#define STR_HOLD_ENTER_TO_START "\012Hold [ENT] to start writing"
|
||||
#define STR_INVALID_FIRMWARE "\011Not a valid firmware file! "
|
||||
#define STR_INVALID_EEPROM "\011Not a valid EEPROM file! "
|
||||
#else
|
||||
#define STR_OR_PLUGIN_USB_CABLE INDENT "Or plug in a USB cable"
|
||||
#define STR_OR_PLUGIN_USB_CABLE "Or plug in a USB cable"
|
||||
#define STR_HOLD_ENTER_TO_START "\006Hold [ENT] to start"
|
||||
#define STR_INVALID_FIRMWARE "\004Not a valid firmware! "
|
||||
#define STR_INVALID_EEPROM "\004Not a valid EEPROM! "
|
||||
|
||||
@@ -408,7 +408,7 @@ const FATDirEntry_t g_DIRroot[] =
|
||||
0xA302,
|
||||
0x3D55,
|
||||
0x0002,
|
||||
sizeof(firmware_txt) + strlen(getOtherVersion(nullptr))
|
||||
sizeof(firmware_txt) + strlen(getFirmwareVersion())
|
||||
},
|
||||
{
|
||||
{ 'F', 'I', 'R', 'M', 'W', 'A', 'R', 'E'},
|
||||
@@ -512,13 +512,11 @@ int32_t fat12Read(uint8_t * buffer, uint16_t sector, uint16_t count)
|
||||
else if (sector == 3) {
|
||||
memcpy(buffer, g_DIRroot, sizeof(g_DIRroot) ) ;
|
||||
}
|
||||
else if (sector == 4)
|
||||
{
|
||||
else if (sector == 4) {
|
||||
memcpy(buffer, firmware_txt, sizeof(firmware_txt));
|
||||
memcpy(buffer + sizeof(firmware_txt), getOtherVersion(nullptr), strlen(getOtherVersion(nullptr)));
|
||||
strcpy((char *)(buffer + sizeof(firmware_txt)), getFirmwareVersion());
|
||||
}
|
||||
else if (sector < RESERVED_SECTORS)
|
||||
{
|
||||
else if (sector < RESERVED_SECTORS) {
|
||||
// allocated to firmware.txt
|
||||
}
|
||||
else if (sector < RESERVED_SECTORS + (FLASHSIZE/BLOCK_SIZE )) {
|
||||
|
||||
@@ -672,7 +672,7 @@ void gpsSendByte(uint8_t byte);
|
||||
|
||||
// BT driver
|
||||
#define BT_TX_FIFO_SIZE 64
|
||||
#define BT_RX_FIFO_SIZE 128
|
||||
#define BT_RX_FIFO_SIZE 256
|
||||
#define BLUETOOTH_BOOTLOADER_BAUDRATE 230400
|
||||
#define BLUETOOTH_FACTORY_BAUDRATE 57600
|
||||
#define BLUETOOTH_DEFAULT_BAUDRATE 115200
|
||||
|
||||
@@ -74,22 +74,21 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
|
||||
if (st == ST_START) {
|
||||
bootloaderDrawTitle(88, BOOTLOADER_TITLE);
|
||||
|
||||
|
||||
lcd->drawBitmapPattern(90, 72, LBM_FLASH, DEFAULT_COLOR);
|
||||
lcd->drawText(124, 75, "Write Firmware");
|
||||
lcd->drawText(124, 75, "Write Firmware");
|
||||
|
||||
lcd->drawBitmapPattern(90, 107, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcd->drawText(124, 110, "Exit");
|
||||
lcd->drawBitmapPattern(90, 107, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcd->drawText(124, 110, "Exit");
|
||||
|
||||
lcd->drawSolidRect(119, (opt == 0) ? 72 : 107, 270, 26, 2, LINE_COLOR);
|
||||
|
||||
lcd->drawBitmap(60, 166, &BMP_PLUG_USB);
|
||||
lcd->drawText(195, 175, "Or plug in a USB cable");
|
||||
lcd->drawText(195, 200, "for mass storage");
|
||||
lcd->drawSolidRect(119, (opt == 0) ? 72 : 107, 270, 26, 2, LINE_COLOR);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
lcd->drawText( 36, 242, "Current Firmware:");
|
||||
lcd->drawText(200, 242, getOtherVersion(nullptr));
|
||||
lcd->drawBitmap(60, 166, &BMP_PLUG_USB);
|
||||
lcd->drawText(195, 175, "Or plug in a USB cable");
|
||||
lcd->drawText(195, 200, "for mass storage");
|
||||
|
||||
bootloaderDrawFooter();
|
||||
lcdDrawText(LCD_W / 2, 242, getFirmwareVersion(), CENTERED);
|
||||
}
|
||||
else if (st == ST_USB) {
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ void extmoduleSendInvertedByte(uint8_t byte)
|
||||
// wait
|
||||
}
|
||||
time += 34;
|
||||
for (i = 0 ; i < 8 ; i += 1) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (byte & 1) {
|
||||
GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
}
|
||||
@@ -376,7 +376,7 @@ void extmoduleSendInvertedByte(uint8_t byte)
|
||||
time += 35 ;
|
||||
}
|
||||
GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
__enable_irq() ; // No need to wait for the stop bit to complete
|
||||
__enable_irq(); // No need to wait for the stop bit to complete
|
||||
while ((uint16_t) (getTmr2MHz() - time) < 34) {
|
||||
// wait
|
||||
}
|
||||
|
||||
@@ -51,7 +51,12 @@ inline void LCD_NRST_HIGH()
|
||||
LCD_GPIO_NRST->BSRRL = LCD_GPIO_PIN_NRST;
|
||||
}
|
||||
|
||||
static void LCD_AF_GPIOConfig(void)
|
||||
inline bool coordsWithinScreen(coord_t x, coord_t y, coord_t w, coord_t h)
|
||||
{
|
||||
return x >= 0 && y >= 0 && x + w <= LCD_W && y + h <= LCD_H;
|
||||
}
|
||||
|
||||
static void LCD_AF_GPIOConfig()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
@@ -362,6 +367,9 @@ void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, ui
|
||||
y = desth - (y + h);
|
||||
#endif
|
||||
|
||||
if (dest == displayBuf && !coordsWithinScreen(x, y, w, h))
|
||||
return;
|
||||
|
||||
DMA2D_DeInit();
|
||||
|
||||
DMA2D_InitTypeDef DMA2D_InitStruct;
|
||||
@@ -393,6 +401,9 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x,
|
||||
srcy = srch - (srcy + h);
|
||||
#endif
|
||||
|
||||
if (dest == displayBuf && !coordsWithinScreen(x, y, w, h))
|
||||
return;
|
||||
|
||||
DMA2D_DeInit();
|
||||
|
||||
DMA2D_InitTypeDef DMA2D_InitStruct;
|
||||
@@ -433,6 +444,9 @@ void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_
|
||||
srcy = srch - (srcy + h);
|
||||
#endif
|
||||
|
||||
if (dest == displayBuf && !coordsWithinScreen(x, y, w, h))
|
||||
return;
|
||||
|
||||
DMA2D_DeInit();
|
||||
|
||||
DMA2D_InitTypeDef DMA2D_InitStruct;
|
||||
|
||||
@@ -23,11 +23,16 @@
|
||||
|
||||
#ifndef __GNUC__
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#define sleep(x) Sleep(x)
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _tcsnicmp
|
||||
#define chdir _chdir
|
||||
#define getcwd _getcwd
|
||||
inline int __builtin_clz(unsigned x)
|
||||
{
|
||||
return (int)__lzcnt(x);
|
||||
}
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define sleep(x) usleep(1000*x)
|
||||
|
||||
@@ -414,4 +414,7 @@ bool telemetrySecondPortReceive(uint8_t & data);
|
||||
|
||||
extern const uint8_t BootCode[];
|
||||
|
||||
// Pulses driver
|
||||
#define HARDWARE_EXTRA_MODULE
|
||||
|
||||
#endif // _BOARD_SKY9X_H_
|
||||
|
||||
@@ -808,7 +808,7 @@ void auxSerialStop();
|
||||
#define BLUETOOTH_FACTORY_BAUDRATE 57600
|
||||
#endif
|
||||
#define BT_TX_FIFO_SIZE 64
|
||||
#define BT_RX_FIFO_SIZE 128
|
||||
#define BT_RX_FIFO_SIZE 256
|
||||
void bluetoothInit(uint32_t baudrate, bool enable);
|
||||
void bluetoothWriteWakeup();
|
||||
uint8_t bluetoothIsWriting();
|
||||
|
||||
@@ -21,28 +21,24 @@ void bootloaderDrawFilename(const char *str, uint8_t line, bool selected)
|
||||
void bootloaderDrawScreen(BootloaderState st, int opt, const char *str)
|
||||
{
|
||||
lcdClear();
|
||||
lcdDrawText(0, 0, BOOTLOADER_TITLE, INVERS);
|
||||
lcdDrawText(LCD_W / 2, 0, BOOTLOADER_TITLE, CENTERED);
|
||||
lcdInvertLine(0);
|
||||
|
||||
if (st == ST_START) {
|
||||
lcdDrawTextAlignedLeft(2*FH, "\010Write Firmware");
|
||||
lcdDrawTextAlignedLeft(3*FH, "\010Restore EEPROM");
|
||||
lcdDrawTextAlignedLeft(4*FH, "\010Exit");
|
||||
lcdDrawText(3*FW, 2*FH, "Write Firmware", opt == 0 ? INVERS : 0);
|
||||
lcdDrawText(3*FW, 3*FH, "Restore EEPROM", opt == 1 ? INVERS : 0);
|
||||
lcdDrawText(3*FW, 4*FH, "Exit", opt == 2 ? INVERS : 0);
|
||||
|
||||
#if LCD_W >= 212
|
||||
lcdDrawTextAlignedLeft(6*FH, "\001Curr FW:");
|
||||
lcdDrawText(50, 6*FH, getOtherVersion(nullptr));
|
||||
#else
|
||||
lcdDrawTextAlignedLeft(6 * FH, "\001FW:");
|
||||
lcdDrawText(LCD_W / 2, 5 * FH + FH / 2, STR_OR_PLUGIN_USB_CABLE, CENTERED);
|
||||
|
||||
// Remove opentx- from string
|
||||
const char *other_ver = getOtherVersion(nullptr);
|
||||
if (strstr(other_ver, "opentx-"))
|
||||
other_ver = other_ver + 7;
|
||||
lcdDrawText(20, 6 * FH, other_ver);
|
||||
// Remove "opentx-" from string
|
||||
const char * vers = getFirmwareVersion();
|
||||
#if LCD_W < 212
|
||||
if (strncmp(vers, "opentx-", 7) == 0)
|
||||
vers += 7;
|
||||
#endif
|
||||
|
||||
lcdInvertLine(2 + opt);
|
||||
lcdDrawTextAlignedLeft(7 * FH, STR_OR_PLUGIN_USB_CABLE);
|
||||
lcdDrawText(LCD_W / 2, 7 * FH, vers, CENTERED);
|
||||
lcdInvertLine(7);
|
||||
}
|
||||
else if (st == ST_USB) {
|
||||
lcdDrawTextAlignedLeft(4 * FH, STR_USB_CONNECTED);
|
||||
@@ -65,11 +61,11 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char *str)
|
||||
}
|
||||
else if (opt == FC_OK) {
|
||||
if (memoryType == MEM_FLASH) {
|
||||
const char * vers = getOtherVersion((char *) Block_buffer);
|
||||
const char * vers = getFirmwareVersion((const char *)Block_buffer);
|
||||
#if LCD_W < 212
|
||||
// Remove opentx- from string
|
||||
if (strstr(vers, "opentx-"))
|
||||
vers = vers + 7;
|
||||
// Remove "opentx-" from string
|
||||
if (strncmp(vers, "opentx-", 7) == 0)
|
||||
vers += 7;
|
||||
#endif
|
||||
bootloaderDrawMsg(INDENT_WIDTH, vers, 0, false);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ const CrossfireSensor & getCrossfireSensor(uint8_t id, uint8_t subId)
|
||||
|
||||
void processCrossfireTelemetryValue(uint8_t index, int32_t value)
|
||||
{
|
||||
if(!TELEMETRY_STREAMING())
|
||||
if (!TELEMETRY_STREAMING())
|
||||
return;
|
||||
|
||||
const CrossfireSensor & sensor = crossfireSensors[index];
|
||||
@@ -201,6 +201,7 @@ void processCrossfireTelemetryData(uint8_t data)
|
||||
auxSerialPutc(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AUX2_SERIAL)
|
||||
if (g_eeGeneral.aux2SerialMode == UART_MODE_TELEMETRY_MIRROR) {
|
||||
aux2SerialPutc(data);
|
||||
|
||||
@@ -192,7 +192,7 @@ enum FrSkyDataState {
|
||||
#define DIY_STREAM_FIRST_ID 0x5000
|
||||
#define DIY_STREAM_LAST_ID 0x50FF
|
||||
#define FACT_TEST_ID 0xF000
|
||||
#define FRAME_LOSS_RATE_ID 0xF010
|
||||
#define VALID_FRAME_RATE_ID 0xF010
|
||||
#define RSSI_ID 0xF101
|
||||
#define ADC1_ID 0xF102
|
||||
#define ADC2_ID 0xF103
|
||||
|
||||
@@ -227,6 +227,8 @@ void processHubPacket(uint8_t id, int16_t value)
|
||||
else if (id == VOLTS_ID) {
|
||||
unit = UNIT_CELLS;
|
||||
uint32_t cellData = (uint32_t)data;
|
||||
if (((cellData & 0x00F0) >> 4) >= MAX_CELLS)
|
||||
return;
|
||||
data = ((cellData & 0x00F0) << 12) + (((((cellData & 0xFF00) >> 8) + ((cellData & 0x000F) << 8))) / 5);
|
||||
}
|
||||
else if (id == GPS_DAY_MONTH_ID) {
|
||||
@@ -264,7 +266,7 @@ void processHubPacket(uint8_t id, int16_t value)
|
||||
data *= 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_D, id, 0, 0, data, unit, precision);
|
||||
}
|
||||
|
||||
@@ -326,4 +328,4 @@ void frskyDSetDefault(int index, uint16_t id)
|
||||
}
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ struct FrSkySportSensor {
|
||||
};
|
||||
|
||||
const FrSkySportSensor sportSensors[] = {
|
||||
{ FRAME_LOSS_RATE_ID, FRAME_LOSS_RATE_ID, 0, ZSTR_FLR, UNIT_PERCENT, 0 },
|
||||
{ VALID_FRAME_RATE_ID, VALID_FRAME_RATE_ID, 0, ZSTR_VFR, UNIT_PERCENT, 0 },
|
||||
{ RSSI_ID, RSSI_ID, 0, STR_SENSOR_RSSI, UNIT_DB, 0 },
|
||||
#if defined(MULTIMODULE)
|
||||
{ TX_RSSI_ID, TX_RSSI_ID, 0, STR_SENSOR_TX_RSSI , UNIT_DB , 0 },
|
||||
@@ -139,6 +139,8 @@ void sportProcessTelemetryPacket(uint16_t id, uint8_t subId, uint8_t instance, u
|
||||
if (unit == UNIT_CELLS) {
|
||||
uint8_t cellsCount = (data & 0xF0) >> 4;
|
||||
uint8_t cellIndex = (data & 0x0F);
|
||||
if (cellIndex >= MAX_CELLS)
|
||||
return;
|
||||
uint32_t mask = (cellsCount << 24) + (cellIndex << 16);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_FRSKY_SPORT, id, subId, instance, mask + (((data & 0x000FFF00) >> 8) / 5), unit, precision);
|
||||
if (cellIndex+1 < cellsCount) {
|
||||
@@ -222,9 +224,19 @@ void sportProcessTelemetryPacketWithoutCrc(uint8_t origin, const uint8_t * packe
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (dataId == VALID_FRAME_RATE_ID) {
|
||||
data = 100 - SPORT_DATA_U8(packet);
|
||||
}
|
||||
else if (dataId == R9_PWR_ID) {
|
||||
uint32_t r9pwr[] = {100, 200, 500, 1000};
|
||||
data = r9pwr[SPORT_DATA_U8(packet) & 0x03];
|
||||
// convert 'dBm' to 'mW'
|
||||
static const uint32_t r9pwrs[][2] = {{0, 1}, {5, 3}, {10, 10}, {13, 20}, {14, 25}, {20, 100}, {23, 200}, {27, 500}, {30, 1000}};
|
||||
uint32_t dBm = SPORT_DATA_U8(packet);
|
||||
for (auto & r9pwr : r9pwrs) {
|
||||
if (dBm == r9pwr[0]) {
|
||||
data = r9pwr[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dataId == XJT_VERSION_ID) {
|
||||
telemetryData.xjtVersion = HUB_DATA_U16(packet);
|
||||
|
||||
+540
-56
@@ -16,26 +16,27 @@
|
||||
#include "opentx.h"
|
||||
|
||||
/* Telemetry
|
||||
packet[0] = TX RSSI value
|
||||
packet[1] = TX LQI value
|
||||
packet[2] = frame number
|
||||
packet[3-12] telemetry data
|
||||
packet[0] = TX RSSI value
|
||||
packet[1] = TX LQI value
|
||||
packet[2] = Telemetry type
|
||||
packet[3] = Telemetry page
|
||||
packet[4-13] = Telemetry data
|
||||
|
||||
The frame number takes the following values: 0x00, 0x01, 0x02, 0x03 and 0x04. The frames can be present or not, they also do not have to follow each others.
|
||||
Here is a description of the telemetry data for each frame number:
|
||||
- frame 0x00
|
||||
[3] = [12] = ??
|
||||
[4] = RX_Voltage*10 in V
|
||||
[5] = Temperature-20 in °C
|
||||
[6] = RX_RSSI
|
||||
[7] = RX_LQI ??
|
||||
[8] = RX_STR ??
|
||||
[9,10] = [10]*256+[9]=max lost packet time in ms, max value seems 2s=0x7D0
|
||||
[11] = 0x00 ??
|
||||
- frame 0x01 Unknown
|
||||
- frame 0x02 Unknown
|
||||
- frame 0x03 Unknown
|
||||
- frame 0x04 Unknown
|
||||
Telemetry type: 0x00 RX, 0x09 Vario, 0x0A GPS, 0x0B not seen, 0x0C ESC, 0x0D GAM, 0x0E EAM, 0x80 Text config mode
|
||||
Telemetry page: 0x00..0x04 for all telemetry except Text config mode which is 0x00..0x12. The pages can be present or not, they also do not have to follow each others.
|
||||
|
||||
Here is a description of the RX telemetry:
|
||||
[2] = 0x00 -> Telemetry type RX
|
||||
[3] = 0x00 -> Telemetry page 0
|
||||
[4] = ?? looks to be a copy of [7]
|
||||
[5] = RX_Voltage*10 in V
|
||||
[6] = Temperature-20 in °C
|
||||
[7] = RX_RSSI CC2500 formated (a<128:a/2-71dBm, a>=128:(a-256)/2-71dBm)
|
||||
[8] = RX_LQI in %
|
||||
[9] = RX_MIN_Voltage*10 in V
|
||||
[10,11] = [11]*256+[10]=max lost packet time in ms, max value seems 2s=0x7D0
|
||||
[12] = 0x00 ??
|
||||
[13] = ?? looks to be a copy of [7]
|
||||
*/
|
||||
|
||||
struct HottSensor
|
||||
@@ -49,22 +50,54 @@ struct HottSensor
|
||||
// telemetry frames
|
||||
enum
|
||||
{
|
||||
HOTT_FRAME_00 = 0x00,
|
||||
HOTT_FRAME_01 = 0x01,
|
||||
HOTT_FRAME_02 = 0x02,
|
||||
HOTT_FRAME_03 = 0x03,
|
||||
HOTT_FRAME_04 = 0x04,
|
||||
HOTT_PAGE_00 = 0x00,
|
||||
HOTT_PAGE_01 = 0x01,
|
||||
HOTT_PAGE_02 = 0x02,
|
||||
HOTT_PAGE_03 = 0x03,
|
||||
HOTT_PAGE_04 = 0x04,
|
||||
};
|
||||
|
||||
#define HOTT_TELEM_NORMAL 0x00
|
||||
#define HOTT_TELEM_BIND 0x40
|
||||
#define HOTT_TELEM_MENU 0x80
|
||||
enum
|
||||
{
|
||||
HOTT_TELEM_RX = 0x00,
|
||||
HOTT_TELEM_VARIO = 0x09,
|
||||
HOTT_TELEM_GPS = 0x0A,
|
||||
HOTT_TELEM_ESC = 0x0C,
|
||||
HOTT_TELEM_GAM = 0x0D,
|
||||
HOTT_TELEM_EAM = 0x0E,
|
||||
HOTT_TELEM_TEXT = 0x80,
|
||||
};
|
||||
|
||||
// telemetry sensors ID
|
||||
enum
|
||||
{
|
||||
HOTT_ID_RX_VOLTAGE = 0x0004, // RX_Batt Voltage
|
||||
HOTT_ID_TEMP1 = 0x0005, // RX Temperature sensor
|
||||
HOTT_ID_VARIO = 0x0006, // Vario sensor
|
||||
HOTT_ID_ALT = 0x0007, // Alt sensor
|
||||
HOTT_ID_HDG = 0x0008, // Heading sensor
|
||||
HOTT_ID_GSPD = 0x0008, // Ground speed sensor
|
||||
HOTT_ID_GPS_LAT_LONG = 0x0009, // GPS sensor
|
||||
HOTT_ID_GPS_COUNT = 0x000A, // GPS sat count
|
||||
HOTT_ID_CELS = 0x000B, // Cels L sensor
|
||||
HOTT_ID_CELS_H = 0x000C, // Cels H sensor
|
||||
HOTT_ID_VOLT1 = 0x000D, // Voltage sensor
|
||||
HOTT_ID_VOLT2 = 0x000E, // Voltage sensor
|
||||
HOTT_ID_AMP1 = 0x000F, // Amp sensor
|
||||
HOTT_ID_AMP2 = 0x0010, // Amp sensor
|
||||
HOTT_ID_RPM1 = 0x0011, // RPM sensor
|
||||
HOTT_ID_RPM2 = 0x0012, // RPM sensor
|
||||
HOTT_ID_ESC_VIN = 0x0013, // ESC Volt
|
||||
HOTT_ID_ESC_CUR = 0x0014, // ESC Amp
|
||||
HOTT_ID_ESC_TBEC = 0x0015, // BEC Temp
|
||||
HOTT_ID_ESC_BCUR = 0x0016, // BEC Cur
|
||||
HOTT_ID_ESC_VBEC = 0x0017, // BEC Volt
|
||||
HOTT_ID_BCAPA = 0x0018, // Batt capacity
|
||||
HOTT_ID_TEMP2 = 0x0019, // Temperature sensor 2
|
||||
HOTT_ID_AIR_SPEED = 0x001A,
|
||||
HOTT_ID_VOLT3 = 0x001B, // Voltage sensor
|
||||
HOTT_ID_FUEL = 0x001C, // Fuel percentage
|
||||
|
||||
HOTT_TX_RSSI_ID = 0xFF00, // Pseudo id outside 1 byte range of Hott sensors
|
||||
HOTT_TX_LQI_ID = 0xFF01, // Pseudo id outside 1 byte range of Hott sensors
|
||||
HOTT_RX_RSSI_ID = 0xFF02, // Pseudo id outside 1 byte range of Hott sensors
|
||||
@@ -72,18 +105,39 @@ enum
|
||||
};
|
||||
|
||||
const HottSensor hottSensors[] = {
|
||||
//frame 00
|
||||
{HOTT_ID_RX_VOLTAGE, STR_SENSOR_BATT, UNIT_VOLTS, 1}, // RX_Batt Voltage
|
||||
{HOTT_ID_TEMP1, STR_SENSOR_TEMP1, UNIT_CELSIUS, 0}, // RX Temperature sensor
|
||||
//frame 01
|
||||
//frame 02
|
||||
//frame 03
|
||||
//frame 04
|
||||
{HOTT_TX_RSSI_ID, STR_SENSOR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{HOTT_TX_LQI_ID, STR_SENSOR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{HOTT_RX_RSSI_ID, STR_SENSOR_RSSI, UNIT_DB, 0}, // RX RSSI
|
||||
{HOTT_RX_LQI_ID, STR_SENSOR_RX_QUALITY, UNIT_RAW, 0}, // RX LQI
|
||||
{0x00, NULL, UNIT_RAW, 0}, // sentinel
|
||||
//HOTT_TELEM_RX
|
||||
{HOTT_ID_RX_VOLTAGE, STR_SENSOR_BATT, UNIT_VOLTS, 1}, // RX_Batt Voltage
|
||||
{HOTT_ID_TEMP1, STR_SENSOR_TEMP1, UNIT_CELSIUS, 0}, // Temperature sensor 1
|
||||
{HOTT_ID_TEMP2, ZSTR_TEMP2, UNIT_CELSIUS, 0}, // Temperature sensor 2
|
||||
{HOTT_ID_VARIO, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 2}, // Vario sensor
|
||||
{HOTT_ID_ALT, ZSTR_ALT, UNIT_METERS, 0}, // Alt sensor
|
||||
{HOTT_ID_HDG, ZSTR_HDG, UNIT_DEGREE, 0}, // Heading sensor
|
||||
{HOTT_ID_GSPD, ZSTR_GSPD, UNIT_KMH, 0}, // Ground speed sensor
|
||||
{HOTT_ID_GPS_LAT_LONG, ZSTR_GPS, UNIT_GPS, 0}, // GPS position
|
||||
{HOTT_ID_GPS_COUNT, ZSTR_SATELLITES, UNIT_RAW, 0}, // GPS sat count
|
||||
{HOTT_ID_VOLT1, ZSTR_A1, UNIT_VOLTS, 1}, // Voltage sensor 1
|
||||
{HOTT_ID_VOLT2, ZSTR_A2, UNIT_VOLTS, 1}, // Voltage sensor 2
|
||||
{HOTT_ID_VOLT3, ZSTR_A3, UNIT_VOLTS, 1}, // Voltage sensor 3
|
||||
{HOTT_ID_AMP1, ZSTR_CURR, UNIT_AMPS, 1}, // Amp sensor 1
|
||||
{HOTT_ID_AMP2, ZSTR_CURR, UNIT_AMPS, 1}, // Amp sensor 2
|
||||
{HOTT_ID_RPM1, ZSTR_RPM, UNIT_RPMS, 0}, // RPM1
|
||||
{HOTT_ID_RPM2, ZSTR_RPM2, UNIT_RPMS, 0}, // RPM2
|
||||
{HOTT_ID_ESC_VIN, ZSTR_ESC_VIN, UNIT_VOLTS, 1}, // ESC VIN
|
||||
{HOTT_ID_BCAPA, ZSTR_SMART_BAT_CAPACITY, UNIT_MAH, 0}, // Batt Capa
|
||||
{HOTT_ID_ESC_CUR, ZSTR_ESC_CUR, UNIT_AMPS, 1}, // ESC Amp
|
||||
{HOTT_ID_ESC_TBEC, ZSTR_ESC_TBEC, UNIT_CELSIUS, 0}, // ESC BEC Temp
|
||||
{HOTT_ID_ESC_BCUR, ZSTR_ESC_BCUR, UNIT_AMPS, 1}, // ESC BEC Amp
|
||||
{HOTT_ID_ESC_VBEC, ZSTR_ESC_VBEC, UNIT_VOLTS, 1}, // ESC BEC Volt
|
||||
{HOTT_ID_CELS, ZSTR_CELLS, UNIT_CELLS, 2}, // Batt cells
|
||||
{HOTT_ID_CELS_H, ZSTR_CELLS, UNIT_CELLS, 2}, // Batt H cells
|
||||
{HOTT_ID_AIR_SPEED, ZSTR_ASPD, UNIT_KMH, 0}, // Air speed
|
||||
{HOTT_ID_FUEL, ZSTR_FUEL, UNIT_PERCENT, 0}, // Fuel
|
||||
|
||||
{HOTT_TX_RSSI_ID, STR_SENSOR_TX_RSSI, UNIT_DB, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{HOTT_TX_LQI_ID, STR_SENSOR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{HOTT_RX_RSSI_ID, STR_SENSOR_RSSI, UNIT_DB, 0}, // RX RSSI
|
||||
{HOTT_RX_LQI_ID, STR_SENSOR_RX_QUALITY, UNIT_RAW, 0}, // RX LQI
|
||||
{0x00, NULL, UNIT_RAW, 0}, // sentinel
|
||||
};
|
||||
|
||||
const HottSensor * getHottSensor(uint16_t id)
|
||||
@@ -95,22 +149,30 @@ const HottSensor * getHottSensor(uint16_t id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int16_t processHoTTdBm(uint8_t value)
|
||||
{
|
||||
if (value >= 128) {
|
||||
value = 256 - value;
|
||||
}
|
||||
return value / 2 -71;
|
||||
}
|
||||
|
||||
void processHottPacket(const uint8_t * packet)
|
||||
{
|
||||
// Set TX RSSI Value
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_TX_RSSI_ID, 0, 0, packet[0]>>1, UNIT_RAW, 0);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_TX_RSSI_ID, 0, 0, processHoTTdBm(packet[0]), UNIT_RAW, 0);
|
||||
// Set TX LQI Value
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_TX_LQI_ID, 0, 0, packet[1], UNIT_RAW, 0);
|
||||
|
||||
#if defined(LUA)
|
||||
#define HOTT_MENU_NBR_PAGE 0x13
|
||||
#define HOTT_MENU_NBR_PAGE 0x13
|
||||
// Config menu consists of the different telem pages put all together
|
||||
// [3] = config mennu page 0x00 to 0x12.
|
||||
// Page X [4] = seems like all the telem pages with the same value are going together to make the full config menu text. Seen so far 'a', 'b', 'c', 'd'
|
||||
// Page X [5..13] = 9 ascii chars to be displayed, char is highlighted when ascii|0x80
|
||||
// Screen display is 21 characters large which means that once the first 21 chars are filled go to the begining of the next line
|
||||
// Menu commands are sent through TX packets:
|
||||
// packet[28]= 0xXF=>no key press, 0xXD=>down, 0xXB=>up, 0xX9=>enter, 0xXE=>right, 0xX7=>left with X=0 or D
|
||||
// packet[28]= 0xXF=>no key press, 0xXD=>down, 0xXB=>up, 0xX9=>enter, 0xXE=>right, 0xX7=>left with X=0, 9=Vario, A=GPS, B=Unknown, C=ESC, D=GAM, or E=EAM
|
||||
// packet[29]= 0xX1/0xX9 with X=0 or X counting 0,1,1,2,2,..,9,9
|
||||
if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0) {
|
||||
// HoTT Lua script is running
|
||||
@@ -118,21 +180,31 @@ void processHottPacket(const uint8_t * packet)
|
||||
// Init
|
||||
memset(&Multi_Buffer[6], ' ', HOTT_MENU_NBR_PAGE * 9); // Clear text buffer
|
||||
}
|
||||
|
||||
if (packet[3] < HOTT_MENU_NBR_PAGE && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) {
|
||||
Multi_Buffer[4] = packet[4]; // Store current menu being received
|
||||
|
||||
if (packet[2] == HOTT_TELEM_TEXT && packet[3] < HOTT_MENU_NBR_PAGE && (Multi_Buffer[5] & 0x80) && (Multi_Buffer[5] & 0x0F) >= 0x07) {
|
||||
Multi_Buffer[4] = packet[4]; // Store detected sensors
|
||||
memcpy(&Multi_Buffer[6 + packet[3] * 9], &packet[5], 9); // Store the received page in the buffer
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct HottGPSMinutes
|
||||
{
|
||||
uint16_t value: 14;
|
||||
uint16_t isNegative: 1;
|
||||
uint16_t spare: 1;
|
||||
};
|
||||
|
||||
const HottSensor * sensor;
|
||||
int32_t value;
|
||||
static uint8_t prev_page = 0, prev_value = 0;
|
||||
static HottGPSMinutes min = {};
|
||||
int16_t deg = 0, sec = 0;
|
||||
|
||||
if (packet[2] == HOTT_TELEM_NORMAL) {
|
||||
switch (packet[3]) {
|
||||
case HOTT_FRAME_00:
|
||||
switch (packet[2]) { // Telemetry type
|
||||
case HOTT_TELEM_RX:
|
||||
if (packet[3] == 0) { // Telemetry page: only page 0 is for RX
|
||||
// RX_VOLT
|
||||
value = packet[5];
|
||||
sensor = getHottSensor(HOTT_ID_RX_VOLTAGE);
|
||||
@@ -142,21 +214,433 @@ void processHottPacket(const uint8_t * packet)
|
||||
sensor = getHottSensor(HOTT_ID_TEMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, 0, value, sensor->unit, sensor->precision);
|
||||
// RX_RSSI
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_RX_RSSI_ID, 0, 0, packet[7], UNIT_DB, 0);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_RX_RSSI_ID, 0, 0, processHoTTdBm(packet[7]), UNIT_DB, 0);
|
||||
// RX_LQI
|
||||
telemetryData.rssi.set(packet[8]);
|
||||
if (packet[8] > 0)
|
||||
telemetryStreaming = TELEMETRY_TIMEOUT10ms;
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_RX_LQI_ID, 0, 0, packet[8], UNIT_RAW, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown
|
||||
value = (packet[7] << 24) | (packet[6] << 16) | (packet[5] << 8) | packet[4];
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, 0xFE00 | packet[3], 0, 0, value, UNIT_RAW, 0);
|
||||
break;
|
||||
}
|
||||
case HOTT_TELEM_VARIO:
|
||||
// https://github.com/betaflight/betaflight/blob/1d8a0e9fd61cf01df7b34805e84365df72d9d68d/src/main/telemetry/hott.h#L240
|
||||
switch (packet[3]) { // Telemetry page 1,2,3,4
|
||||
case HOTT_PAGE_01:
|
||||
// packet[6 ] uint8_t altitude_L; //#06 Altitude low uint8_t. In meters. A value of 500 means 0m
|
||||
// packet[7 ] uint8_t altitude_H; //#07 Altitude high uint8_t
|
||||
value = packet[6] + (packet[7] << 8) - 500;
|
||||
sensor = getHottSensor(HOTT_ID_ALT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ALT, 0, HOTT_TELEM_VARIO, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[12] uint8_t climbrate_L; //#12 Climb rate in m/s. Steps of 0.01m/s. Value of 30000 = 0.00 m/s
|
||||
// packet[13] uint8_t climbrate_H; //#13 Climb rate in m/s
|
||||
value = packet[12] + (packet[13] << 8) - 30000;
|
||||
sensor = getHottSensor(HOTT_ID_VARIO);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VARIO, 0, HOTT_TELEM_VARIO, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
case HOTT_PAGE_02:
|
||||
// packet[12] uint8_t compass_direction; //#42 Compass heading in 2� steps. 1 = 2�
|
||||
value = packet[12] * 2;
|
||||
sensor = getHottSensor(HOTT_ID_HDG);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_HDG, 0, HOTT_TELEM_VARIO, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
case HOTT_PAGE_03:
|
||||
break;
|
||||
case HOTT_PAGE_04:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTT_TELEM_GPS:
|
||||
// https://github.com/betaflight/betaflight/blob/1d8a0e9fd61cf01df7b34805e84365df72d9d68d/src/main/telemetry/hott.h#L378
|
||||
switch (packet[3]) { // Telemetry page 1,2,3,4
|
||||
case HOTT_PAGE_01:
|
||||
// packet[7 ] uint8_t flight_direction; //#07 flight direction in 2 degreees/step (1 = 2degrees);
|
||||
value = packet[7] * 2;
|
||||
sensor = getHottSensor(HOTT_ID_HDG);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_HDG, 0, HOTT_TELEM_GPS, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[8 ] uint8_t gps_speed_L; //08 km/h
|
||||
// packet[9 ] uint8_t gps_speed_H; //#09
|
||||
value = packet[8] + (packet[9] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_GSPD);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_GSPD, 0, HOTT_TELEM_GPS, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[10] uint8_t pos_NS; //#10 north = 0, south = 1
|
||||
// packet[11] uint8_t pos_NS_dm_L; //#11 degree minutes ie N48�39�988
|
||||
// packet[12] uint8_t pos_NS_dm_H; //#12
|
||||
// packet[13] uint8_t pos_NS_sec_L; //#13 position seconds
|
||||
min.value = (int16_t) (packet[11] + (packet[12] << 8));
|
||||
if (packet[10] == 1) {
|
||||
min.isNegative = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_02:
|
||||
if (prev_page == ((HOTT_TELEM_GPS << 4) | HOTT_PAGE_01)) {
|
||||
// packet[4 ] uint8_t pos_NS_sec_H; //#14
|
||||
deg = min.value / 100;
|
||||
min.value = min.value - deg * 100;
|
||||
sec = prev_value + (packet[4] << 8);
|
||||
value = deg * 1000000 + (min.value * 1000000 + sec * 100) / 60;
|
||||
if (min.isNegative) {
|
||||
value = -value;
|
||||
}
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_GPS_LAT_LONG, 0, HOTT_TELEM_GPS, value, UNIT_GPS_LATITUDE, 0);
|
||||
}
|
||||
|
||||
// packet[5 ] uint8_t pos_EW; //#15 east = 0, west = 1
|
||||
// packet[6 ] uint8_t pos_EW_dm_L; //#16 degree minutes ie. E9�25�9360
|
||||
// packet[7 ] uint8_t pos_EW_dm_H; //#17
|
||||
// packet[8 ] uint8_t pos_EW_sec_L; //#18 position seconds
|
||||
// packet[9 ] uint8_t pos_EW_sec_H; //#19
|
||||
min.value = (int16_t) (packet[6] + (packet[7] << 8));
|
||||
sec = (int16_t) (packet[8] + (packet[9] << 8));
|
||||
deg = min.value / 100;
|
||||
min.value = min.value - deg * 100;
|
||||
value = deg * 1000000 + (min.value * 1000000 + sec * 100) / 60;
|
||||
if (packet[5] == 1) {
|
||||
value = -value;
|
||||
}
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_GPS_LAT_LONG, 0, HOTT_TELEM_GPS, value, UNIT_GPS_LONGITUDE, 0);
|
||||
// packet[10] uint8_t home_distance_L; //#20 meters
|
||||
// packet[11] uint8_t home_distance_H; //#21
|
||||
|
||||
// packet[12] uint8_t altitude_L; //#22 meters. Value of 500 = 0m
|
||||
// packet[13] uint8_t altitude_H; //#23
|
||||
value = packet[12] + (packet[13] << 8) - 500;
|
||||
sensor = getHottSensor(HOTT_ID_ALT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ALT, 0, HOTT_TELEM_GPS, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_03:
|
||||
// packet[4 ] uint8_t climbrate_L; //#24 m/s 0.01m/s resolution. Value of 30000 = 0.00 m/s
|
||||
// packet[5 ] uint8_t climbrate_H; //#25
|
||||
value = packet[4] + (packet[5] << 8) - 30000;
|
||||
sensor = getHottSensor(HOTT_ID_VARIO);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VARIO, 0, HOTT_TELEM_GPS, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[6 ] uint8_t climbrate3s; //#26 climbrate in m/3s resolution, value of 120 = 0 m/3s
|
||||
// packet[7 ] uint8_t gps_satelites; //#27 sat count
|
||||
sensor = getHottSensor(HOTT_ID_GPS_COUNT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_GPS_COUNT, 0, HOTT_TELEM_GPS, packet[7], sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t gps_fix_char; //#28 GPS fix character. display, 'D' = DGPS, '2' = 2D, '3' = 3D, '-' = no fix. Where appears this char???
|
||||
// packet[9 ] uint8_t home_direction;//#29 direction from starting point to Model position (2 degree steps)
|
||||
// packet[10] uint8_t angle_roll; //#30 angle roll in 2 degree steps
|
||||
// packet[11] uint8_t angle_nick; //#31 angle in 2degree steps
|
||||
// packet[12] uint8_t angle_compass; //#32 angle in 2degree steps. 1 = 2�, 255 = - 2� (1 uint8_t) North = 0�
|
||||
// packet[13] uint8_t gps_time_h; //#33 UTC time hours
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_04:
|
||||
// packet[4 ] uint8_t gps_time_m; //#34 UTC time minutes
|
||||
// packet[5 ] uint8_t gps_time_s; //#35 UTC time seconds
|
||||
// packet[6 ] uint8_t gps_time_sss; //#36 UTC time milliseconds
|
||||
// packet[7 ] uint8_t msl_altitude_L;//#37 mean sea level altitude
|
||||
// packet[8 ] uint8_t msl_altitude_H;//#38
|
||||
// packet[9 ] uint8_t vibration; //#39 vibrations level in %
|
||||
// packet[10] uint8_t free_char1; //#40 appears right to home distance
|
||||
// packet[11] uint8_t free_char2; //#41 appears right to home direction
|
||||
// packet[12] uint8_t free_char3; //#42 GPS ASCII D=DGPS 2=2D 3=3D -=No Fix
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTT_TELEM_ESC:
|
||||
// https://github.com/betaflight/betaflight/blob/1d8a0e9fd61cf01df7b34805e84365df72d9d68d/src/main/telemetry/hott.h#L454
|
||||
switch (packet[3]) { // Telemetry page 1,2,3,4
|
||||
case HOTT_PAGE_01:
|
||||
// packet[7 ] uint8_t input_v_L; //#07 Input voltage low byte
|
||||
// packet[8 ] uint8_t input_v_H; //#08
|
||||
value = packet[7] + (packet[8] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_ESC_VIN);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ESC_VIN, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t batt_cap_L; //#11 battery capacity in 10mAh steps
|
||||
// packet[12] uint8_t batt_cap_H; //#12
|
||||
value = (packet[11] + (packet[12] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_BCAPA);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_BCAPA, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
// packet[13] uint8_t esc_temp; //#13 ESC temperature
|
||||
value = packet[13] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_02:
|
||||
// packet[5 ] uint8_t current_L; //#15 Current in 0.1 steps
|
||||
// packet[6 ] uint8_t current_H; //#16
|
||||
value = packet[5] + (packet[6] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_ESC_CUR);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ESC_CUR, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
// packet[9 ] uint8_t rpm_L; //#19 RPM in 10U/min steps
|
||||
// packet[10] uint8_t rpm_H; //#20
|
||||
value = (packet[9] + (packet[10] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_RPM1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RPM1, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_03:
|
||||
// packet[8 ] uint8_t bec_v; //#28 BEC voltage
|
||||
value = packet[8];
|
||||
sensor = getHottSensor(HOTT_ID_ESC_VBEC);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ESC_VBEC, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t bec_current; //#30 BEC current
|
||||
value = packet[10];
|
||||
sensor = getHottSensor(HOTT_ID_ESC_BCUR);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ESC_BCUR, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_04:
|
||||
// packet[4 ] uint8_t bec_temp; //#34 BEC temperature
|
||||
value = packet[4] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_ESC_TBEC);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ESC_TBEC, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
// packet[6 ] uint8_t motor_temp; //#36 Motor or external sensor temperature
|
||||
value = packet[6] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP2, 0, HOTT_TELEM_ESC, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTT_TELEM_GAM:
|
||||
// https://github.com/betaflight/betaflight/blob/1d8a0e9fd61cf01df7b34805e84365df72d9d68d/src/main/telemetry/hott.h#L151
|
||||
switch (packet[3]) { // Telemetry page 1,2,3,4
|
||||
case HOTT_PAGE_01:
|
||||
sensor = getHottSensor(HOTT_ID_CELS);
|
||||
// packet[7 ] uint8_t cell1_L; //#07 cell 1 voltage lower value. 0.02V steps, 124=2.48V
|
||||
value = packet[7] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 0 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t cell2_L; //#08
|
||||
value = packet[8] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 1 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[9 ] uint8_t cell3_L; //#09
|
||||
value = packet[9] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 2 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t cell4_L; //#10
|
||||
value = packet[10] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 3 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t cell5_L; //#11
|
||||
value = packet[11] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 4 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[12] uint8_t cell6_L; //#12
|
||||
value = packet[12] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 5 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[13] uint8_t batt1_L; //#13 battery 1 voltage LSB value. 0.1V steps. 50 = 5.5V
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_02:
|
||||
if (prev_page == ((HOTT_TELEM_GAM << 4) | HOTT_PAGE_01)) {
|
||||
// packet[4 ] uint8_t batt1_H; //#14
|
||||
value = prev_value + (packet[4] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT2, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
}
|
||||
// packet[5 ] uint8_t batt2_L; //#15 battery 2 voltage LSB value. 0.1V steps. 50 = 5.5V
|
||||
// packet[6 ] uint8_t batt2_H; //#16
|
||||
value = packet[5] + (packet[6] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT3);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT3, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[7 ] uint8_t temperature1; //#17 temperature 1. offset of 20. a value of 20 = 0�C
|
||||
value = packet[7] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t temperature2; //#18 temperature 2. offset of 20. a value of 20 = 0�C
|
||||
value = packet[8] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP2, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[9 ] uint8_t fuel_procent; //#19 Fuel capacity in %. Values 0--100, graphical display ranges: 0-25% 50% 75% 100%
|
||||
value = packet[9];
|
||||
sensor = getHottSensor(HOTT_ID_FUEL);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_FUEL, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t fuel_ml_L; //#20 Fuel in ml scale. Full = 65535!
|
||||
// packet[11] uint8_t fuel_ml_H; //#21
|
||||
// packet[12] uint8_t rpm_L; //#22 RPM in 10 RPM steps. 300 = 3000rpm
|
||||
// packet[13] uint8_t rpm_H; //#23
|
||||
value = (packet[12] + (packet[13] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_RPM1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RPM1, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_03:
|
||||
// packet[4 ] uint8_t altitude_L; //#24 altitude in meters. offset of 500, 500 = 0m
|
||||
// packet[5 ] uint8_t altitude_H; //#25
|
||||
value = packet[4] + (packet[5] << 8) - 500;
|
||||
sensor = getHottSensor(HOTT_ID_ALT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ALT, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[6 ] uint8_t climbrate_L; //#26 climb rate in 0.01m/s. Value of 30000 = 0.00 m/s
|
||||
// packet[7 ] uint8_t climbrate_H; //#27
|
||||
value = packet[6] + (packet[7] << 8) - 30000;
|
||||
sensor = getHottSensor(HOTT_ID_VARIO);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VARIO, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t climbrate3s; //#28 climb rate in m/3sec. Value of 120 = 0m/3sec
|
||||
// packet[9 ] uint8_t current_L; //#29 current in 0.1A steps
|
||||
// packet[10] uint8_t current_H; //#30
|
||||
value = packet[9] + (packet[10] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_AMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_AMP1, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t main_voltage_L; //#31 Main power voltage using 0.1V steps
|
||||
// packet[12] uint8_t main_voltage_H; //#32
|
||||
value = packet[11] + (packet[12] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT1, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[13] uint8_t batt_cap_L; //#33 used battery capacity in 10mAh steps
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_04:
|
||||
// packet[4 ] uint8_t batt_cap_H; //#34
|
||||
if (prev_page == ((HOTT_TELEM_GAM << 4) | HOTT_PAGE_03)) {
|
||||
value = (prev_value + (packet[4] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_BCAPA);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_BCAPA, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
}
|
||||
// packet[5 ] uint8_t speed_L; //#35 (air?) speed in km/h(?) we are using ground speed here per default
|
||||
// packet[6 ] uint8_t speed_H; //#36
|
||||
value = packet[5] + (packet[6] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_AIR_SPEED);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_AIR_SPEED, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[7 ] uint8_t min_cell_volt; //#37 minimum cell voltage in 2mV steps. 124 = 2,48V
|
||||
// packet[8 ] uint8_t min_cell_volt_num; //#38 number of the cell with the lowest voltage
|
||||
// packet[9 ] uint8_t rpm2_L; //#39 RPM in 10 RPM steps. 300 = 3000rpm
|
||||
// packet[10] uint8_t rpm2_H; //#40
|
||||
value = (packet[9] + (packet[10] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_RPM2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RPM2, 0, HOTT_TELEM_GAM, value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t general_error_number;//#41 Voice error == 12. TODO: more docu
|
||||
// packet[12] uint8_t pressure; //#42 Pressure up to 16bar. 0,1bar scale. 20 = 2bar
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTT_TELEM_EAM:
|
||||
// https://github.com/betaflight/betaflight/blob/1d8a0e9fd61cf01df7b34805e84365df72d9d68d/src/main/telemetry/hott.h#L288
|
||||
switch (packet[3]) { // Telemetry page 1,2,3,4
|
||||
case HOTT_PAGE_01:
|
||||
sensor = getHottSensor(HOTT_ID_CELS);
|
||||
// packet[7 ] uint8_t cell1_L; //#07 cell 1 voltage lower value. 0.02V steps, 124=2.48V
|
||||
value = packet[7] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 0 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t cell2_L; //#08
|
||||
value = packet[8] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 1 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[9 ] uint8_t cell3_L; //#09
|
||||
value = packet[9] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 2 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t cell4_L; //#10
|
||||
value = packet[10] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 3 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t cell5_L; //#11
|
||||
value = packet[11] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 4 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[12] uint8_t cell6_L; //#12
|
||||
value = packet[12] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 5 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[13] uint8_t cell7_L; //#13
|
||||
// value = packet[13] << 1;
|
||||
// if(value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 6 << 16 | value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_02:
|
||||
sensor = getHottSensor(HOTT_ID_CELS);
|
||||
// packet[4 ] uint8_t cell1_H; //#14 cell 1 voltage high value. 0.02V steps, 124=2.48V
|
||||
value = packet[4] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 0 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[5 ] uint8_t cell2_H; //#15
|
||||
value = packet[5] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 1 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[6 ] uint8_t cell3_H; //#16
|
||||
value = packet[6] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 2 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[7 ] uint8_t cell4_H; //#17
|
||||
value = packet[7] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 3 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[8 ] uint8_t cell5_H; //#18
|
||||
value = packet[8] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 4 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[9 ] uint8_t cell6_H; //#19
|
||||
value = packet[9] << 1;
|
||||
if (value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS_H, 0, HOTT_TELEM_EAM, 5 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t cell7_H; //#20
|
||||
//value = packet[10] << 1;
|
||||
//if(value) setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_CELS, 0, HOTT_TELEM_EAM, 13 << 16 | value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t batt1_voltage_L; //#21 battery 1 voltage lower value in 100mv steps, 50=5V. optionally cell8_L value 0.02V steps
|
||||
// packet[12] uint8_t batt1_voltage_H; //#22
|
||||
value = packet[11] + (packet[12] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT2, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[13] uint8_t batt2_voltage_L; //#23 battery 2 voltage lower value in 100mv steps, 50=5V. optionally cell8_H value. 0.02V steps
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_03:
|
||||
if (prev_page == ((HOTT_TELEM_EAM << 4) | HOTT_PAGE_02)) {
|
||||
// packet[4 ] uint8_t batt2_voltage_H; //#24
|
||||
value = prev_value + (packet[4] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT3);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT3, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
}
|
||||
// packet[5 ] uint8_t temp1; //#25 Temperature sensor 1. 20=0�, 46=26� - offset of 20.
|
||||
value = packet[5] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
// packet[6 ] uint8_t temp2; //#26 temperature sensor 2
|
||||
value = packet[6] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP2);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP2, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[7 ] uint8_t altitude_L; //#27 Attitude lower value. unit: meters. Value of 500 = 0m
|
||||
// packet[8 ] uint8_t altitude_H; //#28
|
||||
value = packet[7] + (packet[8] << 8) - 500;
|
||||
sensor = getHottSensor(HOTT_ID_ALT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_ALT, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[9 ] uint8_t current_L; //#29 Current in 0.1 steps
|
||||
// packet[10] uint8_t current_H; //#30
|
||||
value = packet[9] + (packet[10] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_AMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_AMP1, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
// packet[11] uint8_t main_voltage_L; //#31 Main power voltage (drive) in 0.1V steps
|
||||
// packet[12] uint8_t main_voltage_H; //#32
|
||||
value = packet[11] + (packet[12] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_VOLT1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VOLT1, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
// packet[13] uint8_t batt_cap_L; //#33 used battery capacity in 10mAh steps
|
||||
break;
|
||||
|
||||
case HOTT_PAGE_04:
|
||||
// packet[4 ] uint8_t batt_cap_H; //#34
|
||||
if (prev_page == ((HOTT_TELEM_EAM << 4) | HOTT_PAGE_03)) {
|
||||
value = (prev_value + (packet[4] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_BCAPA);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_BCAPA, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
}
|
||||
|
||||
// packet[5 ] uint8_t climbrate_L; //#35 climb rate in 0.01m/s. Value of 30000 = 0.00 m/s
|
||||
// packet[6 ] uint8_t climbrate_H; //#36
|
||||
value = packet[5] + (packet[6] << 8) - 30000;
|
||||
sensor = getHottSensor(HOTT_ID_VARIO);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_VARIO, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
|
||||
// packet[7 ] uint8_t climbrate3s; //#37 climbrate in m/3sec. Value of 120 = 0m/3sec
|
||||
// packet[8 ] uint8_t rpm_L; //#38 RPM. Steps: 10 U/min
|
||||
// packet[9 ] uint8_t rpm_H; //#39
|
||||
value = (packet[8] + (packet[9] << 8)) * 10;
|
||||
sensor = getHottSensor(HOTT_ID_RPM1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RPM1, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
// packet[10] uint8_t electric_min; //#40 Electric minutes. Time does start, when motor current is > 3 A
|
||||
// packet[11] uint8_t electric_sec; //#41
|
||||
// packet[12] uint8_t speed_L; //#42 (air?) speed in km/h. Steps 1km/h
|
||||
// packet[13] uint8_t speed_H; //#43
|
||||
value = packet[12] + (packet[13] << 8);
|
||||
sensor = getHottSensor(HOTT_ID_AIR_SPEED);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_AIR_SPEED, 0, HOTT_TELEM_EAM, value, sensor->unit, sensor->precision);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev_page = (packet[2] << 4) | packet[3]; // concatenate telemetry type and page
|
||||
prev_value = packet[13]; // page overflow
|
||||
}
|
||||
|
||||
void hottSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "telemetry.h"
|
||||
#include "multi.h"
|
||||
|
||||
constexpr int32_t MULTI_DESIRED_VERSION = (1 << 24) | (3 << 16) | (1 << 8) | 1;
|
||||
#define MULTI_CHAN_BITS 11
|
||||
|
||||
extern uint8_t g_moduleIdx;
|
||||
@@ -561,7 +562,7 @@ void MultiModuleStatus::getStatusString(char * statusText) const
|
||||
return;
|
||||
}
|
||||
|
||||
if (major <= 1 && minor <= 3 && revision <= 0 && patch < 91 && SLOW_BLINK_ON_PHASE) {
|
||||
if ((((major << 24) | (minor << 16) | (revision << 8) | patch) < MULTI_DESIRED_VERSION) && SLOW_BLINK_ON_PHASE) {
|
||||
strcpy(statusText, STR_MODULE_UPGRADE);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#define TELEMETRY_AVERAGE_COUNT 3 // we actually average one more reading!
|
||||
#define RAW_FRSKY_MINMAX(v) v.values[TELEMETRY_AVERAGE_COUNT-1]
|
||||
#define MAX_CELLS 6
|
||||
|
||||
class TelemetryValue {
|
||||
public:
|
||||
|
||||
@@ -90,6 +90,8 @@ void TelemetryItem::setValue(const TelemetrySensor & sensor, int32_t val, uint32
|
||||
uint32_t data = uint32_t(newVal);
|
||||
uint8_t cellsCount = (data >> 24);
|
||||
uint8_t cellIndex = ((data >> 16) & 0x0F);
|
||||
if (cellIndex >= MAX_CELLS)
|
||||
return;
|
||||
uint16_t cellValue = (data & 0xFFFF);
|
||||
if (cellsCount == 0) {
|
||||
cellsCount = (cellIndex >= cells.count ? cellIndex + 1 : cells.count);
|
||||
@@ -497,7 +499,7 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui
|
||||
{
|
||||
bool sensorFound = false;
|
||||
|
||||
for (int index=0; index<MAX_TELEMETRY_SENSORS; index++) {
|
||||
for (int index = 0; index < MAX_TELEMETRY_SENSORS; index++) {
|
||||
TelemetrySensor & telemetrySensor = g_model.telemetrySensors[index];
|
||||
if (telemetrySensor.type == TELEM_TYPE_CUSTOM && telemetrySensor.id == id && telemetrySensor.subId == subId && (telemetrySensor.isSameInstance(protocol, instance) || g_model.ignoreSensorIds)) {
|
||||
telemetryItems[index].setValue(telemetrySensor, value, unit, prec);
|
||||
@@ -718,3 +720,23 @@ int32_t TelemetrySensor::getPrecDivisor() const
|
||||
if (prec == 1) return 10;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool TelemetrySensor::isSameInstance(TelemetryProtocol protocol, uint8_t instance)
|
||||
{
|
||||
if (this->instance == instance)
|
||||
return true;
|
||||
|
||||
if (protocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) {
|
||||
#if defined(SIMU)
|
||||
if (((this->instance ^ instance) & 0x1F) == 0)
|
||||
return true;
|
||||
#else
|
||||
if (((this->instance ^ instance) & 0x9F) == 0 && (this->instance >> 5) != TELEMETRY_ENDPOINT_SPORT && (instance >> 5) != TELEMETRY_ENDPOINT_SPORT) {
|
||||
this->instance = instance; // update the instance in case we had telemetry switching
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class TelemetryItem
|
||||
} consumption;
|
||||
struct {
|
||||
uint8_t count;
|
||||
CellValue values[6];
|
||||
CellValue values[MAX_CELLS];
|
||||
} cells;
|
||||
struct {
|
||||
uint16_t year; // full year (4 digits)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -65,6 +65,7 @@ inline void MODEL_RESET()
|
||||
memset(&anaInValues, 0, sizeof(anaInValues));
|
||||
extern uint8_t s_mixer_first_run_done;
|
||||
s_mixer_first_run_done = false;
|
||||
evalMixes(1); // this is needed to reset fp_act
|
||||
lastFlightMode = 255;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user