Merge with latest 2.3

This commit is contained in:
Bertrand Songis
2020-06-18 11:14:07 +02:00
121 changed files with 3269 additions and 1775 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ set(VERSION_REVISION "0")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
set(SDCARD_REVISION "0028")
set(SDCARD_REVISION "0029")
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8)
+28
View File
@@ -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
+2 -2
View File
@@ -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;
}
+2 -1
View File
@@ -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;
+13 -13
View File
@@ -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;
+7 -3
View File
@@ -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;
+8 -4
View File
@@ -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);
+16 -17
View File
@@ -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);
+18 -3
View File
@@ -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,
+2 -3
View File
@@ -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);
+4 -1
View File
@@ -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();
-1
View File
@@ -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) {
+1 -1
View File
@@ -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) {
+38 -12
View File
@@ -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]);
+5 -2
View File
@@ -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
+2 -3
View File
@@ -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(" ");
+16 -5
View File
@@ -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 {
+2 -2
View File
@@ -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;
+1 -2
View File
@@ -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();
+1 -3
View File
@@ -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();
}
+1 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+21
View File
@@ -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

+12 -8
View File
@@ -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--) {
+1 -1
View File
@@ -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)
+33 -38
View File
@@ -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,
+11 -7
View File
@@ -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;
+3 -3
View File
@@ -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];
+29 -35
View File
@@ -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;
+5 -4
View File
@@ -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;
+1 -1
View File
@@ -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));
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -30,7 +30,7 @@ class TextWidget: public Widget
{
}
virtual void refresh();
void refresh() override;
static const ZoneOption options[];
};
+1 -1
View File
@@ -28,7 +28,7 @@ class TimerWidget: public Widget
{
}
virtual void refresh();
void refresh() override;
static const ZoneOption options[];
};
+1 -1
View File
@@ -28,7 +28,7 @@ class ValueWidget: public Widget
{
}
virtual void refresh();
void refresh() override;
static const ZoneOption options[];
};
+1 -1
View File
@@ -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));
+1 -1
View File
@@ -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);
}
}
+6
View File
@@ -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;
+7 -3
View File
@@ -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)
+28 -9
View File
@@ -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
+1 -1
View File
@@ -265,7 +265,7 @@ class LuaWidget: public Widget
virtual void update();
virtual void refresh();
void refresh() override;
virtual void background();
+1
View File
@@ -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
View File
@@ -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)
}
}
}
}
+1 -1
View File
@@ -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
View File
@@ -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)
+3 -2
View File
@@ -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
+5
View File
@@ -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)
+1 -1
View File
@@ -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]);
}
+7
View File
@@ -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;
}
+2
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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)
+8 -9
View File
@@ -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 )) {
+1 -1
View File
@@ -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) {
+2 -2
View File
@@ -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
}
+15 -1
View File
@@ -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;
+5
View File
@@ -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)
+3
View File
@@ -414,4 +414,7 @@ bool telemetrySecondPortReceive(uint8_t & data);
extern const uint8_t BootCode[];
// Pulses driver
#define HARDWARE_EXTRA_MODULE
#endif // _BOARD_SKY9X_H_
+1 -1
View File
@@ -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);
}
+2 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+4 -2
View File
@@ -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);
}
}
+15 -3
View File
@@ -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
View File
@@ -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)
+2 -1
View File
@@ -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 {
+1
View File
@@ -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:
+23 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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

+1
View File
@@ -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