Compare commits

...

45 Commits

Author SHA1 Message Date
Andre Bernet a7a9b61234 Typo in release notes 2014-09-08 23:01:04 +02:00
bsongis 5ee95673d1 Release notes updated 2014-09-08 22:25:10 +02:00
bsongis 98c5b5e7bd Little display bug in DEBUG page 2014-09-08 22:25:10 +02:00
Bertrand Songis 6d434c0bf9 Update DONATIONS.txt 2014-09-07 21:52:42 +02:00
Bertrand Songis ade7151796 Update DONATIONS.txt 2014-09-07 20:35:50 +02:00
Bertrand Songis a7cd1f9aa0 Update DONATIONS.txt 2014-09-07 11:24:59 +02:00
bsongis cb2c922542 DONATIONS.txt updated 2014-09-05 17:58:40 +02:00
bsongis 8159a559da Release notes updated 2014-09-05 17:20:24 +02:00
bsongis ed826d8c62 [Sky9x] Linker error (no newlib-nano needed, no _sbrk) 2014-09-05 17:17:43 +02:00
bsongis b57f5ab2ce Added DEBUG information (thanks again projectkk2glider!) 2014-09-05 17:03:01 +02:00
bsongis 8fbafa6f05 Fixes #1643 - Thanks to projectkk2glider for his help on this one 2014-09-05 16:23:55 +02:00
Damjan Adamic 9243a59426 Removed lua_fields.txt 2014-09-03 23:33:59 +02:00
Damjan Adamic ccf66831c7 Fixes #1666: fixed bootloader 2014-09-03 23:32:03 +02:00
Damjan Adamic 06792b5696 Fixes #1666: Missing constructor calls for static objects 2014-09-03 23:03:25 +02:00
bsongis 6d4d871849 Various Lua fixes (thanks projectkk2glider!) 2014-09-02 20:53:19 +02:00
bsongis 5a634a7991 Fixes #1656 2014-09-01 09:43:02 +02:00
bsongis 69e504212e Copy/Paste error on second serial port Rx 2014-08-31 22:45:36 +02:00
bsongis 03e049c360 Fixes #1658 2014-08-29 23:05:24 +02:00
bsongis 4ca893da1f Fixes #1655 2014-08-29 15:54:28 +02:00
bsongis 66670cf713 Fixes #1646 2014-08-29 11:53:20 +02:00
bsongis 271bb4a82e Version and release notes updated 2014-08-29 11:46:20 +02:00
bsongis e0eab648ef Fixes #1651 2014-08-28 21:54:33 +02:00
bsongis 3235f43db9 Companion part for #1646
Conflicts:
	companion/src/modeledit/logicalswitches.cpp
2014-08-28 16:42:31 +02:00
bsongis c12b0cfebe Fixes #1650 2014-08-28 15:26:08 +02:00
bsongis 3e590d44f0 Fixes #1646 2014-08-28 15:16:20 +02:00
bsongis 1f6d1799af Fixes #1643 - no more freeze but now I have to understand why we go over
4k there
2014-08-27 23:44:07 +02:00
bsongis 8c813a87c9 Fixes #1635 2014-08-27 23:14:59 +02:00
bsongis 5bdeedbd0e [9X] Display problem of the battery range 2014-08-27 20:44:38 +02:00
bsongis e33f4cf415 Compilation error 2014-08-27 20:44:22 +02:00
bsongis 61d745011a [9XR-PRO] Telemetry fix 2014-08-27 20:44:11 +02:00
bsongis 3e269a04ae lua_fields.txt removed from git as it is automatically generated 2014-08-27 12:25:43 +02:00
bsongis 341feaf78f Fixes #1621 2014-08-27 10:21:55 +02:00
bsongis 19ddf6fc23 [Companion] Servos limits are displayed in us if ppmus option selected 2014-08-26 16:55:58 +02:00
bsongis 9b4b0d3c83 Fixes #1596 2014-08-26 09:01:19 +02:00
bsongis dc1eebf40d RSSI initialization added in google tests 2014-08-25 11:51:15 +02:00
bsongis 752e13b9ab Fixes #1617 2014-08-25 11:39:34 +02:00
bsongis b988bec5bd Fixes #1636 2014-08-25 11:27:46 +02:00
Damjan Adamic 3c72afed20 Fixes #1622: Lua function script not called for SF >= 8 2014-08-25 11:11:06 +02:00
Damjan Adamic e7586f47c3 Re #1547: commit 5949be30fa disabled delay for STICKY (which was wrong) now disabled for EDGE 2014-08-25 10:45:40 +02:00
Bertrand Songis f126b149f0 Merge pull request #1642 from opentx/1641_rx_number_with_DSM
Receiver number wasn't showing up for DSM (Fix #1641)
2014-08-24 23:45:50 +02:00
Andre Bernet 6b15c0c985 Receiver number wasn't showing up for DSM (Fix #1641) 2014-08-24 10:29:36 +02:00
Damjan Adamic db85f39ebc Added generation of Lua fields documentation file: lua_fields.txt 2014-08-21 10:07:39 +02:00
bsongis dee1e4ce8d Fixes #1612 2014-08-16 11:17:45 +02:00
bsongis df96504a85 SWR hidden on Taranis+ 2014-08-15 17:20:35 +02:00
Kjell Kernen 0112a1e3e9 Changed description of the master branch. The text from the next branch had ended up here. 2014-08-14 10:44:04 +02:00
55 changed files with 1223 additions and 782 deletions
+23
View File
@@ -566,3 +566,26 @@ Bertrand Condevaux Lanloy
Henri Mirra
Aurélien Planiol
Kevin Caldwell
Andrew Garello
Tomasz Maziarz
Russell Flack
Fernando Rimoldi
Greg Reid
Dietmar Drees
Holger Landwehr
Arno Loehdorf
Boon Sripattha
Patrik Åkerfeldt
Alonzo Fretwell
Renjith Chandrasekharan
Ruben Gomez Hernandez
Michael Gardner
Judith Green
Timo Ruppell
John Lipscomb
Norbert Wenke
Erik Frieberg
Raimo Ruotsalainen
Brian Harris
Sebastian Blüml
Efisio Maxia
+3 -4
View File
@@ -1,8 +1,7 @@
##OpenTX Next Branch
##OpenTX Master Branch
You have found your way to the GitHub repository site for the OpenTX Next Branch. This code branch holds the source code for the ongoing development.
You have found your way to the GitHub repository site for the OpenTX Master Branch. This code branch holds the source code for the latest stable release.
The stable release code is not here, it is in the master branch.
Under no circumstances build and use software from this branch for real world application. At times you will be more or less guaranteed to crash your plane and destroy all your model settings.
The ongoing development is not done in this branch. It is performed in the branch called next.
Refer to the opentx.wiki for information about setting up the tool chains for building OpenTX and OpenTX Companion as well as other development related issues.
+3 -1
View File
@@ -1,6 +1,8 @@
<h2>Version 2.0.9</h2>
<h2>Version 2.0.10</h2>
<ul>
<li>Taranis is now the default board in General Settings</li>
<li>GVARS allowed in Limits min/max/offset</li>
<li>Limits displayed in us when ppmus option selected
</ul>
<h2>Version 2.0.8</h2>
+1 -1
View File
@@ -2,7 +2,7 @@ PROJECT( companion )
SET( C9X_VERSION_MAJOR "2" )
SET( C9X_VERSION_MINOR "0" )
SET( C9X_VERSION_REVISION "9" )
SET( C9X_VERSION_REVISION "10" )
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
+3
View File
@@ -526,6 +526,8 @@ class GeneralSettings {
int temperatureCalib;
int temperatureWarn;
unsigned int mAhWarn;
unsigned int mAhUsed;
unsigned int globalTimer;
unsigned int btBaudrate;
unsigned int sticksGain;
unsigned int rotarySteps;
@@ -1129,6 +1131,7 @@ enum Capability {
HasSoundMixer,
NumModules,
PPMCenter,
PPMUnitMicroseconds,
SYMLimits,
HasCurrentCalibration,
HasVolume,
@@ -1151,7 +1151,7 @@ class InputField: public TransformedField {
virtual void beforeExport()
{
_weight = smallGvarToEEPROM(expo.weight);
_weight = smallGvarToEEPROM(expo.weight);
if (!IS_TARANIS(board) || version < 216) {
if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) {
@@ -1206,19 +1206,43 @@ class InputField: public TransformedField {
class LimitField: public StructField {
public:
template <int shift>
static int exportLimitValue(int value)
{
if (value > 10000)
return 4095 + value - 10000;
else if (value < -10000)
return -4096 + value + 10000;
else
return value + shift;
}
template <int shift>
static int importLimitValue(int value)
{
if (value > 4095)
return 10000 + value - 4095;
else if (value < -4096)
return -10000 + value + 4096;
else
return value - shift;
}
LimitField(LimitData & limit, BoardEnum board, unsigned int version):
StructField("Limit")
{
if (IS_TARANIS(board) && version >= 216) {
Append(new ConversionField< SignedField<16> >(limit.min, +1000));
Append(new ConversionField< SignedField<16> >(limit.max, -1000));
Append(new ConversionField< SignedField<16> >(limit.min, exportLimitValue<1000>, importLimitValue<1000>));
Append(new ConversionField< SignedField<16> >(limit.max, exportLimitValue<-1000>, importLimitValue<-1000>));
Append(new SignedField<8>(limit.ppmCenter));
Append(new ConversionField< SignedField<14> >(limit.offset, exportLimitValue<0>, importLimitValue<0>));
}
else {
Append(new ConversionField< SignedField<8> >(limit.min, +100, 10));
Append(new ConversionField< SignedField<8> >(limit.max, -100, 10));
Append(new SignedField<8>(limit.ppmCenter));
Append(new SignedField<14>(limit.offset));
}
Append(new SignedField<8>(limit.ppmCenter));
Append(new SignedField<14>(limit.offset));
Append(new BoolField<1>(limit.symetrical));
Append(new BoolField<1>(limit.revert));
if (HAS_LARGE_LCD(board)) {
@@ -2790,8 +2814,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
if (version >= 213) {
internalField.Append(new SignedField<8>(generalData.temperatureWarn)); // TODO
internalField.Append(new UnsignedField<8>(generalData.mAhWarn));
internalField.Append(new SpareBitsField<16>()); // mAhUsed
internalField.Append(new SpareBitsField<32>()); // globalTimer
internalField.Append(new UnsignedField<16>(generalData.mAhUsed));
internalField.Append(new UnsignedField<32>(generalData.globalTimer));
internalField.Append(new SignedField<8>(generalData.temperatureCalib)); // TODO
internalField.Append(new UnsignedField<8>(generalData.btBaudrate)); // TODO
internalField.Append(new BoolField<8>(generalData.optrexDisplay)); //TODO
@@ -663,7 +663,9 @@ int OpenTxFirmware::getCapability(const Capability capability)
case TelemetryMaxMultiplier:
return (IS_ARM(board) ? 32 : 8);
case PPMCenter:
return 1;
return (IS_TARANIS(board) || id.contains("ppmca")) ? 1 : 0;
case PPMUnitMicroseconds:
return id.contains("ppmus") ? 1 : 0;
case SYMLimits:
return 1;
case OptrexDisplay:
+1 -1
View File
@@ -275,7 +275,7 @@ These will be relevant for all models in the same EEPROM.</string>
<item>
<widget class="QSlider" name="backlightColor_SL">
<property name="maximum">
<number>17</number>
<number>20</number>
</property>
<property name="pageStep">
<number>5</number>
+32 -14
View File
@@ -147,18 +147,18 @@ void populatePhasesCB(QComboBox *b, int value)
b->setCurrentIndex(value + GetCurrentFirmware()->getCapability(FlightModes));
}
GVarGroup::GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const unsigned int flags):
GVarGroup::GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step, bool allowGvars):
QObject(),
weightGV(weightGV),
weightSB(weightSB),
sb(dynamic_cast<QSpinBox *>(weightSB)),
dsb(dynamic_cast<QDoubleSpinBox *>(weightSB)),
weightCB(weightCB),
weight(weight),
flags(flags),
lock(false)
step(step),
lock(true)
{
lock = true;
if (GetCurrentFirmware()->getCapability(Gvars)) {
if (allowGvars && GetCurrentFirmware()->getCapability(Gvars)) {
populateGVCB(weightCB, weight);
connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
@@ -170,21 +170,32 @@ GVarGroup::GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightC
}
}
weightSB->setMinimum(mini);
weightSB->setMaximum(maxi);
int val;
if (weight>maxi || weight<mini) {
val = deflt;
weightGV->setChecked(true);
weightSB->hide();
weightCB->show();
}
else {
val = weight;
weightGV->setChecked(false);
weightSB->setValue(weight);
weightSB->show();
weightCB->hide();
}
if (sb) {
sb->setMinimum(step*mini);
sb->setMaximum(step*maxi);
sb->setValue(step*val);
}
else {
dsb->setMinimum(step*mini);
dsb->setMaximum(step*maxi);
dsb->setValue(step*val);
}
connect(weightSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged()));
lock = false;
@@ -193,16 +204,23 @@ GVarGroup::GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightC
void GVarGroup::gvarCBChanged(int state)
{
weightCB->setVisible(state);
weightSB->setVisible(!state);
if (weightSB)
weightSB->setVisible(!state);
else
weightSB->setVisible(!state);
valuesChanged();
}
void GVarGroup::valuesChanged()
{
if (weightGV->isChecked())
weight = weightCB->itemData(weightCB->currentIndex()).toInt();
else
weight = weightSB->value();
if (!lock) {
if (weightGV->isChecked())
weight = weightCB->itemData(weightCB->currentIndex()).toInt();
else if (sb)
weight = sb->value()/step;
else
weight = dsb->value()/step;
}
}
CurveGroup::CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags):
+6 -4
View File
@@ -37,12 +37,12 @@ class CompanionIcon: public QIcon {
CompanionIcon(QString baseimage);
};
class GVarGroup : public QObject {
class GVarGroup: public QObject {
Q_OBJECT
public:
GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const unsigned int flags=0);
GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step=1, bool allowGVars=true);
protected slots:
void gvarCBChanged(int);
@@ -50,10 +50,12 @@ class GVarGroup : public QObject {
protected:
QCheckBox *weightGV;
QSpinBox *weightSB;
QAbstractSpinBox *weightSB;
QSpinBox *sb;
QDoubleSpinBox *dsb;
QComboBox *weightCB;
int & weight;
const unsigned int flags;
double step;
bool lock;
};
+81 -71
View File
@@ -1,4 +1,5 @@
#include "channels.h"
#include "helpers.h"
#include <QLabel>
#include <QLineEdit>
#include <QSpinBox>
@@ -6,6 +7,74 @@
#include <QCheckBox>
#include <QDoubleSpinBox>
LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt):
firmware(firmware),
spinbox(new QDoubleSpinBox()),
value(value),
step(1.0)
{
bool allowGVars = false;
spinbox->setProperty("index", row);
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
spinbox->setAccelerated(true);
if (firmware->getCapability(PPMUnitMicroseconds)) {
step = 5.12;
spinbox->setDecimals(1);
spinbox->setSuffix("us");
}
else {
spinbox->setDecimals(0);
spinbox->setSuffix("%");
}
if (IS_TARANIS(firmware->getBoard()) || deflt == 0 /*it's the offset*/) {
min *= 10;
max *= 10;
deflt *= 10;
step /= 10;
spinbox->setDecimals(1);
allowGVars = true;
}
spinbox->setSingleStep(step);
QHBoxLayout * horizontalLayout = new QHBoxLayout();
QCheckBox * gv = new QCheckBox(QObject::tr("GV"));
horizontalLayout->addWidget(gv);
QComboBox * cb = new QComboBox();
horizontalLayout->addWidget(cb);
horizontalLayout->addWidget(spinbox);
gridLayout->addLayout(horizontalLayout, row, col, 1, 1);
gvarGroup = new GVarGroup(gv, spinbox, cb, value, deflt, min, max, step, allowGVars);
}
LimitsGroup::~LimitsGroup()
{
delete gvarGroup;
}
void LimitsGroup::updateMinMax(int max)
{
if (IS_TARANIS(firmware->getBoard())) {
max *= 10;
}
if (spinbox->maximum() == 0) {
spinbox->setMinimum(-step*max);
if (value < -max) {
value = -max;
}
}
if (spinbox->minimum() == 0) {
spinbox->setMaximum(step*max);
if (value > max) {
value = max;
}
}
}
Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware):
ModelPanel(parent, model, generalSettings, firmware)
{
@@ -13,8 +82,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
bool minimize = false;
int col = 1;
if (firmware->getCapability(ChannelsName))
{
if (firmware->getCapability(ChannelsName)) {
minimize=true;
addLabel(gridLayout, tr("Name"), col++);
}
@@ -52,44 +120,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
}
// Channel offset
QDoubleSpinBox * offset = new QDoubleSpinBox(this);
offset->setProperty("index", i);
offset->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
offset->setAccelerated(true);
offset->setDecimals(1);
offset->setMinimum(-100);
offset->setSingleStep(0.1);
offset->setValue(float(model.limitData[i].offset) / 10);
connect(offset, SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
gridLayout->addWidget(offset, i+1, col++, 1, 1);
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].offset, -100, 100, 0);
// Channel min
QDoubleSpinBox * minSB = new QDoubleSpinBox(this);
minSB->setProperty("index", i);
minSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
minSB->setAccelerated(true);
minSB->setDecimals(1);
minSB->setMinimum(-model.getChannelsMax());
minSB->setSingleStep(0.1);
minSB->setMaximum(0);
minSB->setValue(float(model.limitData[i].min) / 10);
connect(minSB, SIGNAL(editingFinished()), this, SLOT(minEdited()));
gridLayout->addWidget(minSB, i+1, col++, 1, 1);
minSpins << minSB;
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].min, -model.getChannelsMax(), 0, -100);
// Channel max
QDoubleSpinBox * maxSB = new QDoubleSpinBox(this);
maxSB->setProperty("index", i);
maxSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
maxSB->setAccelerated(true);
maxSB->setDecimals(1);
maxSB->setMinimum(0);
maxSB->setSingleStep(0.1);
maxSB->setMaximum(model.getChannelsMax());
maxSB->setValue(float(model.limitData[i].max) / 10);
connect(maxSB, SIGNAL(editingFinished()), this, SLOT(maxEdited()));
gridLayout->addWidget(maxSB, i+1, col++, 1, 1);
maxSpins << maxSB;
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].max, 0, model.getChannelsMax(), 100);
// Channel inversion
QComboBox * invCB = new QComboBox(this);
@@ -117,6 +154,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
QSpinBox * center = new QSpinBox(this);
center->setProperty("index", i);
center->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
center->setSuffix("us");
center->setMinimum(1375);
center->setMaximum(1625);
center->setValue(1500);
@@ -134,6 +172,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
gridLayout->addWidget(symlimits, i+1, col++, 1, 1);
}
}
// Push the rows up
addVSpring(gridLayout, 0,firmware->getCapability(Outputs)+1);
@@ -142,6 +181,9 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
Channels::~Channels()
{
foreach(LimitsGroup *group, limitsGroups) {
delete group;
}
}
void Channels::symlimitsEdited()
@@ -164,46 +206,14 @@ void Channels::nameEdited()
}
}
void Channels::offsetEdited()
{
QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(sender());
int index = dsb->property("index").toInt();
model.limitData[index].offset = round(dsb->value() * 10);
emit modified();
}
void Channels::minEdited()
{
QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(sender());
int index = sb->property("index").toInt();
model.limitData[index].min = round(sb->value() * 10);
emit modified();
}
void Channels::maxEdited()
{
QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(sender());
int index = sb->property("index").toInt();
model.limitData[index].max = round(sb->value() * 10);
emit modified();
}
void Channels::refreshExtendedLimits()
{
int channelMax = model.getChannelsMax();
int channelMaxValue = channelMax * 10;
for (int i=0; i<firmware->getCapability(Outputs); i++) {
QDoubleSpinBox * minDSB = minSpins[i];
QDoubleSpinBox * maxDSB = maxSpins[i];
minDSB->setMinimum(-channelMax);
maxDSB->setMaximum(+channelMax);
//reset any limit that is bigger than current maximum (dependent on extended limits setting)
if ( model.limitData[i].min < -channelMaxValue ) model.limitData[i].min = -channelMaxValue;
if ( model.limitData[i].max > +channelMaxValue ) model.limitData[i].max = +channelMaxValue;
foreach(LimitsGroup *group, limitsGroups) {
group->updateMinMax(channelMax);
}
emit modified();
}
+19 -5
View File
@@ -4,6 +4,24 @@
#include "modelpanel.h"
#include <QSpinBox>
class GVarGroup;
class LimitsGroup
{
public:
LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt);
~LimitsGroup();
void updateMinMax(int max);
protected:
FirmwareInterface * firmware;
QDoubleSpinBox * spinbox;
GVarGroup * gvarGroup;
int & value;
double step;
};
class Channels : public ModelPanel
{
Q_OBJECT
@@ -13,8 +31,7 @@ class Channels : public ModelPanel
~Channels();
private:
QVector<QDoubleSpinBox *> minSpins;
QVector<QDoubleSpinBox *> maxSpins;
QVector<LimitsGroup *> limitsGroups;
public slots:
void refreshExtendedLimits();
@@ -22,9 +39,6 @@ class Channels : public ModelPanel
private slots:
void symlimitsEdited();
void nameEdited();
void offsetEdited();
void minEdited();
void maxEdited();
void invEdited();
void curveEdited();
void ppmcenterEdited();
+12 -7
View File
@@ -239,6 +239,7 @@ void LogicalSwitchesPanel::edited()
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
break;
case LS_FAMILY_STAY:
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
if (sender() == cswitchOffset[i]) {
model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value());
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
@@ -246,10 +247,12 @@ void LogicalSwitchesPanel::edited()
else {
model.customSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.customSw[i].val2;
}
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value());
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
if (model.customSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
cswitchOffset2[i]->clear();
cswitchOffset2[i]->setSuffix("(infinite)");
}
else {
cswitchOffset2[i]->setSuffix("");
}
break;
default:
@@ -274,7 +277,6 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl
else
sb->setSingleStep(0.1);
sb->setValue(value);
sb->setSuffix("");
}
#define SOURCE1_VISIBLE 0x1
@@ -320,7 +322,6 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
}
break;
case LS_FAMILY_STICKY:
mask &= ~DELAY_ENABLED;
// no break
case LS_FAMILY_VBOOL:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
@@ -329,12 +330,16 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
break;
case LS_FAMILY_STAY:
mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE;
mask &= ~DELAY_ENABLED;
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value());
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
if (model.customSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
cswitchOffset2[i]->clear();
}
else {
cswitchOffset2[i]->setSuffix("");
}
break;
case LS_FAMILY_VCOMP:
+2 -2
View File
@@ -210,8 +210,8 @@ void ModulePanel::update()
ui->label_protocol->setVisible(mask & MASK_PROTOCOL);
ui->protocol->setVisible(mask & MASK_PROTOCOL);
ui->label_rxNumber->setVisible(mask & MASK_FAILSAFES);
ui->rxNumber->setVisible(mask & MASK_FAILSAFES);
ui->label_rxNumber->setVisible(mask & MASK_RX_NUMBER);
ui->rxNumber->setVisible(mask & MASK_RX_NUMBER);
ui->rxNumber->setValue(model.modelId);
ui->label_channelsStart->setVisible(mask & MASK_CHANNELS_RANGE);
ui->channelsStart->setVisible(mask & MASK_CHANNELS_RANGE);
+60 -60
View File
@@ -11,22 +11,22 @@
<message>
<location filename="../wizarddialog.cpp" line="418"/>
<source>Yes, controlled by a single channel</source>
<translation>Oui, contrôlés par un seul canal</translation>
<translation>Oui, contrôlés par une seule voie</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="419"/>
<source>Yes, controlled by two channels</source>
<translation>Oui, contrôlés par 2 canaux</translation>
<translation>Oui, contrôlés par 2 voies</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="431"/>
<source>&lt;br&gt;First Aileron Channel:</source>
<translation>&lt;br&gt;Premier canal d&apos;ailerons:</translation>
<translation>&lt;br&gt;Première voie d&apos;ailerons:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="433"/>
<source>Second Aileron Channel:</source>
<translation>Deuxième canal d&apos;ailerons:</translation>
<translation>Deuxième voie d&apos;ailerons:</translation>
</message>
</context>
<context>
@@ -39,22 +39,22 @@
<message>
<location filename="../wizarddialog.cpp" line="547"/>
<source>Yes, controlled by a single channel</source>
<translation>Oui, contrôlés par un seul canal</translation>
<translation>Oui, contrôlés par une seule voie</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="548"/>
<source>Yes, controlled by two channels</source>
<translation>Oui, contrôlés par 2 canaux</translation>
<translation>Oui, contrôlés par 2 voies</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="560"/>
<source>&lt;br&gt;First Airbrake Channel:</source>
<translation>&lt;br&gt;Premier canal de volets:</translation>
<translation>&lt;br&gt;Première voie de volets:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="562"/>
<source>Second Airbrake Channel:</source>
<translation>Deuxième canal de volets:</translation>
<translation>Deuxième voie de volets:</translation>
</message>
</context>
<context>
@@ -573,11 +573,11 @@ Peut être différente de la langue du firmware</translation>
</message>
<message>
<source>&lt;br&gt;First Elevon Channel:</source>
<translation type="obsolete">&lt;br&gt;Premier canal d&apos;élevons:</translation>
<translation type="obsolete">&lt;br&gt;Première voie d&apos;élevons:</translation>
</message>
<message>
<source>Second Elevon Channel:</source>
<translation type="obsolete">Deuxième canal d&apos;élevons:</translation>
<translation type="obsolete">Deuxième voie d&apos;élevons:</translation>
</message>
</context>
<context>
@@ -625,7 +625,7 @@ Peut être différente de la langue du firmware</translation>
<message>
<location filename="../modeledit/channels.cpp" line="37"/>
<source>Channel %1</source>
<translation>Canal %1</translation>
<translation>Voie %1</translation>
</message>
<message>
<location filename="../modeledit/channels.cpp" line="96"/>
@@ -1423,12 +1423,12 @@ Peut être différente de la langue du firmware</translation>
<message>
<location filename="../wizarddialog.cpp" line="615"/>
<source>&lt;br&gt;First Elevon Channel:</source>
<translation>&lt;br&gt;Premier canal d&apos;élevons:</translation>
<translation>&lt;br&gt;Première voie d&apos;élevons:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="617"/>
<source>Second Elevon Channel:</source>
<translation>Deuxième canal d&apos;élevons:</translation>
<translation>Deuxième voie d&apos;élevons:</translation>
</message>
</context>
<context>
@@ -1436,7 +1436,7 @@ Peut être différente de la langue du firmware</translation>
<message>
<location filename="../modeledit/templates.cpp" line="39"/>
<source>Simple 4-CH</source>
<translation>4 canaux simple</translation>
<translation>4 voies simple</translation>
</message>
<message>
<location filename="../modeledit/templates.cpp" line="40"/>
@@ -1476,17 +1476,17 @@ Peut être différente de la langue du firmware</translation>
<message>
<location filename="../modeledit/templates.cpp" line="47"/>
<source>Heli Setup (Futaba&apos;s channel assignment style)</source>
<translation>Configuration hélico (canaux Futaba)</translation>
<translation>Configuration hélico (config Futaba)</translation>
</message>
<message>
<location filename="../modeledit/templates.cpp" line="48"/>
<source>Heli Setup with gyro gain control (Futaba&apos;s channel assignment style)</source>
<translation>Configuration hélico avec gain du gyro (canaux Futaba)</translation>
<translation>Configuration hélico avec gain du gyro (config Futaba)</translation>
</message>
<message>
<location filename="../modeledit/templates.cpp" line="49"/>
<source>Gyro gain control (Futaba&apos;s channel assignment style)</source>
<translation>Gain de gyro (canaux Futaba)</translation>
<translation>Gain de gyro (config Futaba)</translation>
</message>
<message>
<location filename="../modeledit/templates.cpp" line="50"/>
@@ -1790,22 +1790,22 @@ Si vide, la ligne est toujours active.</translation>
<message>
<location filename="../wizarddialog.cpp" line="814"/>
<source>Throttle Channel:</source>
<translation>Canal des gaz:</translation>
<translation>Voie des gaz:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="816"/>
<source>Yaw Channel:</source>
<translation>Canal du lacet:</translation>
<translation>Voie du lacet:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="818"/>
<source>Pitch Channel:</source>
<translation>Canal du tangage:</translation>
<translation>Voie du tangage:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="820"/>
<source>Roll Channel:</source>
<translation>Canal du roulis:</translation>
<translation>Voie du roulis:</translation>
</message>
</context>
<context>
@@ -1863,22 +1863,22 @@ Peut être différente de la langue du firmware</translation>
<message>
<location filename="../wizarddialog.cpp" line="483"/>
<source>Yes, controlled by a single channel</source>
<translation>Oui, contrôlés par un seul canal</translation>
<translation>Oui, contrôlés par une seule voie</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="484"/>
<source>Yes, controlled by two channels</source>
<translation>Oui, contrôlés par 2 canaux</translation>
<translation>Oui, contrôlés par 2 voies</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="496"/>
<source>&lt;br&gt;First Flap Channel:</source>
<translation>&lt;br&gt;Premier canal de volets:</translation>
<translation>&lt;br&gt;Première voie de volets:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="498"/>
<source>Second Flap Channel:</source>
<translation>Deuxième canal de volets:</translation>
<translation>Deuxième voie de volets:</translation>
</message>
</context>
<context>
@@ -3215,22 +3215,22 @@ Are you sure ?</source>
<message>
<location filename="../wizarddialog.cpp" line="851"/>
<source>Throttle Channel:</source>
<translation>Canal des gaz:</translation>
<translation>Voie des gaz:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="853"/>
<source>Yaw Channel:</source>
<translation>Canal du lacet:</translation>
<translation>Voie du lacet:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="855"/>
<source>Pitch Channel:</source>
<translation>Canal du tangage:</translation>
<translation>Voie du tangage:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="857"/>
<source>Roll Channel:</source>
<translation>Canal du roulis:</translation>
<translation>Voie du roulis:</translation>
</message>
</context>
<context>
@@ -5315,7 +5315,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../modeledit/setup_module.ui" line="153"/>
<source>Start</source>
<translation>1er canal</translation>
<translation>1ère voie</translation>
</message>
<message>
<location filename="../modeledit/setup_module.ui" line="179"/>
@@ -5375,7 +5375,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../modeledit/setup_module.ui" line="391"/>
<source>Channels</source>
<translation>Nb de canaux</translation>
<translation>Nb de voies</translation>
</message>
<message>
<location filename="../modeledit/setup_module.ui" line="414"/>
@@ -5447,22 +5447,22 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../wizarddialog.cpp" line="888"/>
<source>Throttle Channel:</source>
<translation>Canal des gaz:</translation>
<translation>Voie des gaz:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="890"/>
<source>Yaw Channel:</source>
<translation>Canal du lacet:</translation>
<translation>Voie du lacet:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="892"/>
<source>Pitch Channel:</source>
<translation>Canal du tangage:</translation>
<translation>Voie du tangage:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="894"/>
<source>Roll Channel:</source>
<translation>Canal du roulis:</translation>
<translation>Voie du roulis:</translation>
</message>
</context>
<context>
@@ -7661,7 +7661,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../firmwares/opentx/opentxinterface.cpp" line="1052"/>
<source>Channel values displayed in us</source>
<translation>Positions de canaux affichées en us</translation>
<translation>Positions de voies affichées en us</translation>
</message>
<message>
<location filename="../firmwares/opentx/opentxinterface.cpp" line="1089"/>
@@ -8107,7 +8107,7 @@ La taille de l&apos;EEPROM est de 4096, mais seulement les 2048 premiers sont ut
<message>
<location filename="../firmwares/opentx/opentxeeprom.cpp" line="2440"/>
<source>OpenTX doesn&apos;t allow this number of channels</source>
<translation>OpenTX ne supporte pas ce nombre de canaux</translation>
<translation>OpenTX ne supporte pas ce nombre de voies</translation>
</message>
<message>
<location filename="../modeledit/flightmodes.cpp" line="74"/>
@@ -8202,7 +8202,7 @@ L&apos;équipe OpenTX.</translation>
<message>
<location filename="../wizarddialog.cpp" line="648"/>
<source>&lt;br&gt;Rudder Channel:</source>
<translation>&lt;br&gt;Canal de dérive:</translation>
<translation>&lt;br&gt;Voie de dérive:</translation>
</message>
</context>
<context>
@@ -8348,7 +8348,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="738"/>
<source>Elevator Channel:</source>
<translation>Canal de profondeur:</translation>
<translation>Voie de profondeur:</translation>
</message>
</context>
<context>
@@ -8516,7 +8516,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="191"/>
<source>Channel %1</source>
<translation>Canal %1</translation>
<translation>Voie %1</translation>
</message>
</context>
<context>
@@ -8524,12 +8524,12 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="712"/>
<source>Rudder Channel:</source>
<translation>Canal de dérive:</translation>
<translation>Voie de dérive:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="714"/>
<source>Elevator Channel:</source>
<translation>Canal de profondeur:</translation>
<translation>Voie de profondeur:</translation>
</message>
</context>
<context>
@@ -9066,7 +9066,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="388"/>
<source>&lt;br&gt;Throttle Channel:</source>
<translation>&lt;br&gt;Canal des gaz:</translation>
<translation>&lt;br&gt;Voie des gaz:</translation>
</message>
</context>
<context>
@@ -9124,12 +9124,12 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="685"/>
<source>First Tail Channel:</source>
<translation>Premier canal d&apos;empennage:</translation>
<translation>Première voie d&apos;empennage:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="687"/>
<source>Second Tail Channel:</source>
<translation>Deuxième canal d&apos;empennage:</translation>
<translation>Deuxième voie d&apos;empennage:</translation>
</message>
</context>
<context>
@@ -9219,12 +9219,12 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
</message>
<message>
<source>Are the elevons controlled by servos connected to separate channels or by a single servo channel?</source>
<translation type="obsolete">Les élevons sont-ils commandés par des servos connectés à des canaux différents, ou à un seul canal ?</translation>
<translation type="obsolete">Les élevons sont-ils commandés par des servos connectés à des voies différentes, ou à une seule voie ?</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="34"/>
<source>Select the elevons channels</source>
<translation>Sélectionner les canaux d&apos;élevons</translation>
<translation>Sélectionner les voies d&apos;élevons</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="35"/>
@@ -9256,7 +9256,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<location filename="../wizarddialog.cpp" line="37"/>
<location filename="../wizarddialog.cpp" line="38"/>
<source>Select channels for tail control.</source>
<translation>Sélectionner les canaux à utiliser pour l&apos;empennage.</translation>
<translation>Sélectionner les voies à utiliser pour l&apos;empennage.</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="38"/>
@@ -9266,7 +9266,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="39"/>
<source>Select elevator channel.</source>
<translation>Sélectionner le canal de profondeur.</translation>
<translation>Sélectionner la voie de profondeur.</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="40"/>
@@ -9338,7 +9338,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="47"/>
<source>Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. Remove the propeller/propellers before you try to control your model for the first time.&lt;br&gt;Please note that continuing removes all old model settings!</source>
<translation>Vérifiez manuellement le sens de chaque commande, et inversez les canaux de celles qui répondent dans le mauvais sens. Attention à bien enlever les hélices du modèle avant de l&apos;alimenter la première fois !&lt;br&gt;Veuillez noter que tous les réglages existants du modèle courant seront écrasés.</translation>
<translation>Vérifiez manuellement le sens de chaque commande, et inversez les voies de celles qui répondent dans le mauvais sens. Attention à bien enlever les hélices du modèle avant de l&apos;alimenter la première fois !&lt;br&gt;Veuillez noter que tous les réglages existants du modèle courant seront écrasés.</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="70"/>
@@ -9348,7 +9348,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="73"/>
<source>Select the receiver channel that is connected to your ESC or throttle servo.&lt;br&gt;&lt;br&gt;Throttle - Spektrum: CH1, Futaba: CH3</source>
<translation>Sélectionnez le canal du récepteur auquel le contrôleur/servo de gaz est connecté.&lt;br&gt;&lt;br&gt;Gaz - Spektrum : CH1, Futaba : CH3</translation>
<translation>Sélectionnez la voie du récepteur auquel le contrôleur/servo de gaz est connecté.&lt;br&gt;&lt;br&gt;Gaz - Spektrum : CH1, Futaba : CH3</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="77"/>
@@ -9358,11 +9358,11 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="82"/>
<source>Models use one or two channels to control the ailerons.&lt;br&gt;A so called Y-cable can be used to connect a single receiver channel to two separate aileron servos. If your servos are connected by a Y-cable you should select the single-servo option.&lt;br&gt;&lt;br&gt;Aileron - Spektrum: CH2, Futaba: CH1</source>
<translation>On utilise en général soit 1, soit 2 canaux pour contrôler les ailerons. Un câble en Y peut être utilisé pour connecter 2 servos à un seul canal, auquel cas il convient de choisir l&apos;option &quot;un seul canal&quot;.&lt;br&gt;&lt;br&gt;Ailerons - Spektrum : CH2, Futaba : CH1</translation>
<translation>On utilise en général soit 1, soit 2 voies pour contrôler les ailerons. Un câble en Y peut être utilisé pour connecter 2 servos à une seule voie, auquel cas il convient de choisir l&apos;option &quot;une seule voie&quot;.&lt;br&gt;&lt;br&gt;Ailerons - Spektrum : CH2, Futaba : CH1</translation>
</message>
<message>
<source>Models use one or two channels to control the elevons.&lt;br&gt;A so called Y-cable can be used to connect single a receiver channel to two separate elevon servos. If your servos are connected by a Y-cable you should select the single-servo option.</source>
<translation type="obsolete">On utilise en général soit un, soit 2 canaux pour contrôler les élevons. Un câble en Y peut être utilisé pour connecter 2 servos à un seul canal, auquel cas il convient de choisir l&apos;option &quot;un seul canal&quot;.</translation>
<translation type="obsolete">On utilise en général soit un, soit 2 voies pour contrôler les élevons. Un câble en Y peut être utilisé pour connecter 2 servos à une seule voie, auquel cas il convient de choisir l&apos;option &quot;une seule voie&quot;.</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="88"/>
@@ -9377,12 +9377,12 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="96"/>
<source>Models use two channels to control the elevons.&lt;br&gt;Select these two channels</source>
<translation>Un modéle utilise 2 canaux pour commanderles élevons.&lt;br&gt;Sélectionnez-les ici:</translation>
<translation>Un modéle utilise 2 voies pour commanderles élevons.&lt;br&gt;Sélectionnez-les ici:</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="100"/>
<source>Select the receiver channel that is connected to your rudder.&lt;br&gt;&lt;br&gt;Rudder - Spektrum: CH4, Futaba: CH4</source>
<translation>Sélectionnez le canal du récepteur auquel le servo de dérive est connecté.&lt;br&gt;&lt;br&gt;Dérive - Spektrum : CH4, Futaba : CH4</translation>
<translation>Sélectionnez la voie du récepteur auquel le servo de dérive est connecté.&lt;br&gt;&lt;br&gt;Dérive - Spektrum : CH4, Futaba : CH4</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="104"/>
@@ -9393,12 +9393,12 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<location filename="../wizarddialog.cpp" line="107"/>
<location filename="../wizarddialog.cpp" line="112"/>
<source>Select the Rudder and Elevator channels.&lt;br&gt;&lt;br&gt;Rudder - Spektrum: CH4, Futaba: CH4&lt;br&gt;Elevator - Spektrum: CH3, Futaba: CH2</source>
<translation>Sélectionnez les canaux du récepteur auquel les servos de profondeur et dérive sont connectés.&lt;br&gt;&lt;br&gt;Dérive - Spektrum : CH4, Futaba : CH4&lt;br&gt;Profondeur - Spektrum : CH3, Futaba : CH2</translation>
<translation>Sélectionnez les voies du récepteur auquel les servos de profondeur et dérive sont connectés.&lt;br&gt;&lt;br&gt;Dérive - Spektrum : CH4, Futaba : CH4&lt;br&gt;Profondeur - Spektrum : CH3, Futaba : CH2</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="117"/>
<source>Select the Elevator channel.&lt;br&gt;&lt;br&gt;Elevator - Spektrum: CH3, Futaba: CH2</source>
<translation>Sélectionnez le canal du récepteur auquel le servo de profondeur est connecté.&lt;br&gt;&lt;br&gt;Profondeur - Spektrum : CH3, Futaba : CH2</translation>
<translation>Sélectionnez la voie du récepteur auquel le servo de profondeur est connecté.&lt;br&gt;&lt;br&gt;Profondeur - Spektrum : CH3, Futaba : CH2</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="121"/>
@@ -9414,7 +9414,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="136"/>
<source>Select the control channels for your multirotor.&lt;br&gt;&lt;br&gt;Throttle - Spektrum: CH1, Futaba: CH3&lt;br&gt;Yaw - Spektrum: CH4, Futaba: CH4&lt;br&gt;Pitch - Spektrum: CH3, Futaba: CH2&lt;br&gt;Roll - Spektrum: CH2, Futaba: CH1</source>
<translation>Sélectionnez les canaux de votre multirotor.&lt;br&gt;&lt;br&gt;Gaz - Spektrum: CH1, Futaba: CH3&lt;br&gt;Lacet - Spektrum: CH4, Futaba : CH4&lt;br&gt;Tangage - Spektrum : CH3, Futaba: CH2&lt;br&gt;Roulis - Spektrum : CH2, Futaba: CH1</translation>
<translation>Sélectionnez les voies de votre multirotor.&lt;br&gt;&lt;br&gt;Gaz - Spektrum: CH1, Futaba: CH3&lt;br&gt;Lacet - Spektrum: CH4, Futaba : CH4&lt;br&gt;Tangage - Spektrum : CH3, Futaba: CH2&lt;br&gt;Roulis - Spektrum : CH2, Futaba: CH1</translation>
</message>
<message>
<location filename="../wizarddialog.cpp" line="149"/>
@@ -9462,7 +9462,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo
<message>
<location filename="../wizarddialog.cpp" line="1031"/>
<source>Channel %1: </source>
<translation>Canal %1: </translation>
<translation>Voie %1: </translation>
</message>
</context>
<context>
@@ -11034,7 +11034,7 @@ Peut être différente de la langue du firmware</translation>
This is used by the templated to determine which channel goes to what number output.</source>
<translation>Ordre des voies
Indique l&apos;affectation voie / numéro de canal par défaut utilisée lors de la création d&apos;un modèle.</translation>
Indique l&apos;affectation voie / numéro de voie par défaut utilisée lors de la création d&apos;un modèle.</translation>
</message>
<message>
<location filename="../preferencesdialog.ui" line="859"/>
+17 -3
View File
@@ -1,8 +1,22 @@
<h2>Version 2.0.9 / 2014-07-28</h2>
<h2>Version 2.0.10 / 2014-09-08</h2>
[All]
<ul>
<li>Duration and AND fixed on Sticky and Edge logical switches
[Taranis]
<ul>
<li>CPPM issue on Helis when cross trims used
<li>Taranis+ LCD color range adjusted
<li>CCPM issue on Helis when cross trims used
<li>Taranis+ LCD color range and brightness adjusted
<li>Taranis+ SWR removed
<li>Lua small enhancements (TIMEHOUR constant, GVARS over 500)
<li>Lua hardening, use of newlib-nano (optimizes RAM usage)
<li>Incoming telemetry rejected if RSSI=0
<li>Assign Bitmap impossible if filename length too big
<li>
[9XR-PRO]
<ul>
<li>Telemetry enabled
<h2>Version 2.0.8 / 2014-07-23</h2>
[Taranis]
+1
View File
@@ -26,3 +26,4 @@
/gtests.d
/lua_exports.cpp
/lua_exports.txt
/lua_fields.txt
+17 -6
View File
@@ -289,6 +289,10 @@ USB = JOYSTICK
# NO - normal behaviour, show real channel values
CHANNELS_MONITOR_INV_HIDE = NO
# Use newlib-nano
# Values = NO, YES
NANO = YES
#------- END BUILD OPTIONS ---------------------------
# Define programs and commands.
@@ -296,7 +300,7 @@ SHELL = sh
IMG2LBM = -python ../util/img2lbm.py
BIN2LBM = -python ../util/bin2lbm.py
TRANSLATE = -python ../util/translate.py
VERSION = 2.0.9
VERSION = 2.0.10
SRC =
CPPSRC =
@@ -718,6 +722,12 @@ ifeq ($(PCB), TARANIS)
EXTRABOARDSRC += targets/taranis/usbd_storage_msd.cpp
endif
ifeq ($(NANO), YES)
# use newlib-nano for linking
NEWLIB_NANO_FLAGS = --specs=nano.specs -u _printf_float
CPPDEFS += -DNANO
endif
ifneq ($(LUA), NO)
ifeq ($(LUA), YES)
CPPDEFS += -DLUA_MODEL_SCRIPTS
@@ -1278,9 +1288,10 @@ bitmaps/sticks.lbm: bitmaps/sticks_4x1.xbm bitmaps/splash_9x.xbm bitmaps/splash_
lua_exports.cpp: myeeprom.h ../util/luaexport.py
@echo "Generating a list of Lua exported constants in lua_exports.txt"
@$(CPP) -DPCBTARANIS -DCPUARM -DLUA -DEXPORT myeeprom.h | grep LEXP > lua_exports.txt
@$(CPP) -DPCBTARANIS -DCPUARM -DLUA -DEXPORT myeeprom.h | grep LEXP > lua_exports.txt
@echo "Parsing and generating C Lua exports in lua_exports.cpp"
@python ../util/luaexport.py lua_exports.txt lua_exports.cpp
@python ../util/luaexport.py $(VERSION) lua_exports.txt lua_exports.cpp lua_fields.txt
@rm lua_exports.txt
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
@@ -1323,7 +1334,7 @@ FOXLIB=-L/usr/local/lib \
-Wl,-rpath,$(FOXPATH)/src/.libs
simu: $(LUADEP) stamp_header $(BOARDSRC) $(CPPSRC) Makefile simu.cpp targets/simu/simpgmspace.cpp *.h tra lbm eeprom.bin
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -DLUA_USE_APICHECK -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions
eeprom.bin:
dd if=/dev/zero of=$@ bs=1 count=2048
@@ -1389,7 +1400,7 @@ OBJS = $(TMP:.s=.o)
@echo
@echo $(MSG_COMPILING) $@
$(CC) $(ARMCPPFLAGS) $< -o allsrc.o
$(CC) $(OBJS) allsrc.o -mcpu=cortex-m3 -mthumb -nostartfiles -lm -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch,--gc-sections -o $@
$(CC) $(OBJS) allsrc.o -mcpu=cortex-m3 -mthumb -nostartfiles -lm -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch,--gc-sections $(NEWLIB_NANO_FLAGS) -o $@
endif
# Target: clean project.
@@ -1419,7 +1430,7 @@ clean_list :
$(REMOVE) stamp-opentx.h
$(REMOVE) bitmaps/*.lbm
$(REMOVE) fonts/*/*.lbm
$(REMOVE) lua_exports.txt lua_exports.cpp
$(REMOVE) lua_exports.txt lua_exports.cpp lua_fields.txt
$(MAKE) -C bootloader clean
#### Install
+9 -4
View File
@@ -607,7 +607,6 @@ int WavContext::mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade)
}
}
clear();
return -result;
}
#else
@@ -719,12 +718,18 @@ void AudioQueue::wakeup()
}
// mix the normal context (tones and wavs)
if (normalContext.fragment.type == FRAGMENT_TONE)
if (normalContext.fragment.type == FRAGMENT_TONE) {
result = normalContext.tone.mixBuffer(buffer, g_eeGeneral.beepVolume, fade);
else if (normalContext.fragment.type == FRAGMENT_FILE)
}
else if (normalContext.fragment.type == FRAGMENT_FILE) {
result = normalContext.wav.mixBuffer(buffer, g_eeGeneral.wavVolume, fade);
else
if (result < 0) {
normalContext.wav.clear();
}
}
else {
result = 0;
}
if (result > 0) {
size = max(size, result);
fade += 1;
+2 -1
View File
@@ -160,7 +160,8 @@ SRC = ../targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/
../targets/taranis/aspi.c \
../targets/taranis/usb_bsp.c \
../targets/taranis/usb_driver.c \
../targets/taranis/pwr_driver.c
../targets/taranis/pwr_driver.c \
init.c
CPPSRC = ../targets/taranis/lcd_driver.cpp \
../targets/taranis/configure_pins.cpp \
+4
View File
@@ -0,0 +1,4 @@
void _init (void)
{
}
+5 -1
View File
@@ -47,6 +47,10 @@ class Fifo
{
}
bool empty() {
return (ridx == widx);
}
void push(uint8_t byte) {
uint32_t next = (widx+1) & (N-1);
if (next != ridx) {
@@ -56,7 +60,7 @@ class Fifo
}
bool pop(uint8_t & byte) {
if (ridx == widx) {
if (empty()) {
return false;
}
else {
+10 -14
View File
@@ -106,7 +106,7 @@ const MenuFuncP_PROGMEM menuTabDiag[] PROGMEM = {
#define RADIO_SETUP_DATE_COLUMN RADIO_SETUP_2ND_COLUMN + 4*FWNUM
#define RADIO_SETUP_TIME_COLUMN RADIO_SETUP_2ND_COLUMN + 2*FWNUM
#else
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-1-MENUS_SCROLLBAR_WIDTH)
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#define RADIO_SETUP_DATE_COLUMN (FW*15+5)
#endif
@@ -292,9 +292,9 @@ void menuGeneralSetup(uint8_t event)
#if defined(BATTGRAPH) || defined(PCBTARANIS)
case ITEM_SETUP_BATT_RANGE:
lcd_putsLeft(y, STR_BATTERY_RANGE);
lcd_putc(g_eeGeneral.vBatMin >= 10 ? RADIO_SETUP_2ND_COLUMN+2*FW+FWNUM-1 : RADIO_SETUP_2ND_COLUMN+2*FW+FWNUM-FW/2, y, '-');
putsVolts(RADIO_SETUP_2ND_COLUMN, y, 90+g_eeGeneral.vBatMin, (m_posHorz==0 ? attr : 0)|LEFT|NO_UNIT);
putsVolts(RADIO_SETUP_2ND_COLUMN+4*FW-2, y, 120+g_eeGeneral.vBatMax, (m_posHorz>0 ? attr : 0)|LEFT|NO_UNIT);
lcd_putc(lcdLastPos, y, '-');
putsVolts(lcdLastPos+FW, y, 120+g_eeGeneral.vBatMax, (m_posHorz>0 ? attr : 0)|LEFT|NO_UNIT);
#if defined(PCBTARANIS)
if (attr && m_posHorz < 0) lcd_filled_rect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
#endif
@@ -531,8 +531,8 @@ void menuGeneralSetup(uint8_t event)
#if defined(PCBTARANIS) && defined(REVPLUS)
case ITEM_SETUP_BACKLIGHT_COLOR:
lcd_putsLeft(y, STR_BLCOLOR);
displaySlider(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.backlightColor, 17, attr);
if (attr) g_eeGeneral.backlightColor = checkIncDec(event, g_eeGeneral.backlightColor, 0, 17, EE_GENERAL | NO_INCDEC_MARKS);
displaySlider(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.backlightColor, 20, attr);
if (attr) g_eeGeneral.backlightColor = checkIncDec(event, g_eeGeneral.backlightColor, 0, 20, EE_GENERAL | NO_INCDEC_MARKS);
break;
#endif
@@ -859,12 +859,7 @@ void onSdManagerMenu(const char *result)
#endif
#if defined(PCBTARANIS)
else if (result == STR_ASSIGN_BITMAP) {
strcpy(lfn, reusableBuffer.sdmanager.lines[index]);
// TODO duplicated code for finding extension
uint8_t len = strlen(lfn) - 4;
memset(lfn+len, 0, sizeof(g_model.header.bitmap)-len);
// TODO duplicated code
memcpy(g_model.header.bitmap, lfn, sizeof(g_model.header.bitmap));
strAppendFilename(g_model.header.bitmap, reusableBuffer.sdmanager.lines[index], sizeof(g_model.header.bitmap));
LOAD_MODEL_BITMAP();
memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap));
eeDirty(EE_MODEL);
@@ -983,7 +978,8 @@ void menuGeneralSdManager(uint8_t _event)
uint8_t index = m_posVert-1-s_pgOfs;
// TODO duplicated code for finding extension
char * ext = reusableBuffer.sdmanager.lines[index];
ext += strlen(ext) - 4;
int len = strlen(ext) - 4;
ext += len;
/* TODO if (!strcasecmp(ext, MODELS_EXT)) {
s_menu[s_menu_count++] = STR_LOAD_FILE;
}
@@ -992,7 +988,7 @@ void menuGeneralSdManager(uint8_t _event)
}
#endif
#if defined(PCBTARANIS)
else if (!strcasecmp(ext, BITMAPS_EXT) && !READ_ONLY()) {
else if (!strcasecmp(ext, BITMAPS_EXT) && !READ_ONLY() && len <= (int)sizeof(g_model.header.bitmap)) {
MENU_ADD_ITEM(STR_ASSIGN_BITMAP);
}
else if (!strcasecmp(ext, TEXT_EXT)) {
@@ -1397,7 +1393,7 @@ void menuGeneralHardware(uint8_t event)
case ITEM_SETUP_HW_UART3_MODE:
g_eeGeneral.uart3Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.uart3Mode, 0, UART_MODE_MAX, attr, event);
if (checkIncDec_Ret) {
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL);
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL());
}
break;
}
+25 -28
View File
@@ -3097,12 +3097,13 @@ void menuModelExpoOne(uint8_t event)
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannel(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x512, 0);
if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
x512 = limit(-1024, x512, 1024);
}
else {
lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1);
}
x512 = limit(-1024, x512, 1024);
int y512 = expoFn(x512);
y512 = limit(-1024, y512, 1024);
lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1);
#else
int16_t x512 = calibratedStick[ed->chn];
@@ -3111,10 +3112,11 @@ void menuModelExpoOne(uint8_t event)
lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0);
#endif
x512 = X0+x512/(RESXu/WCHART);
#if defined(CPUARM)
x512 = X0+x512/(RESX/WCHART);
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
#else
x512 = X0+x512/(RESXu/WCHART);
y512 = (LCD_H-1) - (uint16_t)((y512+RESX)/2) * (LCD_H-1) / RESX;
#endif
@@ -4359,6 +4361,22 @@ enum LogicalSwitchFields {
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
#endif
#if defined(CPUARM)
void putsEdgeDelayParam(xcoord_t x, uint8_t y, LogicalSwitchData *cs, uint8_t lattr, uint8_t rattr)
{
lcd_putc(x-4, y, '[');
lcd_outdezAtt(x, y, lswTimerValue(cs->v2), LEFT|PREC1|lattr);
lcd_putc(lcdLastPos, y, ':');
if (cs->v3 < 0)
lcd_putsAtt(lcdLastPos+3, y, "<<", rattr);
else if (cs->v3 == 0)
lcd_putsAtt(lcdLastPos+3, y, "--", rattr);
else
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|rattr);
lcd_putc(lcdLastPos, y, ']');
}
#endif
#if defined(CPUARM) && LCD_W < 212
#define CSWONE_2ND_COLUMN (11*FW)
@@ -4440,17 +4458,10 @@ void menuModelLogicalSwitchOne(uint8_t event)
v2_max = 99;
}
else if (cstate == LS_FAMILY_STAY) {
lcd_putc(CSWONE_2ND_COLUMN-4, y, '[');
lcd_outdezAtt(CSWONE_2ND_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|(m_posHorz==0 ? attr : 0));
lcd_putc(lcdLastPos, y, ':');
if (cs->v3 == 0)
lcd_putsAtt(lcdLastPos+3, y, "--", (m_posHorz==1 ? attr : 0));
else
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(m_posHorz==1 ? attr : 0));
lcd_putc(lcdLastPos, y, ']');
putsEdgeDelayParam(CSWONE_2ND_COLUMN, y, cs, m_posHorz==0 ? attr : 0, m_posHorz==1 ? attr : 0);
if (s_editMode <= 0) continue;
if (attr && m_posHorz==1) {
CHECK_INCDEC_MODELVAR(event, cs->v3, 0, 222 - cs->v2);
CHECK_INCDEC_MODELVAR(event, cs->v3, -1, 222 - cs->v2);
break;
}
v2_min = -129; v2_max = 122;
@@ -4563,14 +4574,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
else if (cstate == LS_FAMILY_STAY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0);
lcd_putc(CSW_3RD_COLUMN-4, y, '[');
lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1);
lcd_putc(lcdLastPos, y, ':');
if (cs->v3 == 0)
lcd_puts(lcdLastPos+3, y, "--");
else
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1);
lcd_putc(lcdLastPos-1, y, ']');
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, 0, 0);
}
else if (cstate == LS_FAMILY_TIMER) {
lcd_outdezAtt(CSW_2ND_COLUMN, y, cs->v1+1, LEFT);
@@ -4682,7 +4686,7 @@ void menuModelLogicalSwitches(uint8_t event)
uint8_t cstate = lswFamily(cs->func);
#if defined(CPUARM)
int16_t v1_val=cs->v1, v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM;
int16_t v3_min=0, v3_max=100;
int16_t v3_min=-1, v3_max=100;
#else
int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM;
#define v1_val cs->v1
@@ -4699,14 +4703,7 @@ void menuModelLogicalSwitches(uint8_t event)
#if defined(CPUARM)
else if (cstate == LS_FAMILY_STAY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1);
lcd_putc(CSW_3RD_COLUMN-4, y, '[');
lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|attr2);
lcd_putc(lcdLastPos, y, ':');
if (cs->v3 == 0)
lcd_putsAtt(lcdLastPos+3, y, "--", (horz==LS_FIELD_V3 ? attr : 0));
else
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(horz==LS_FIELD_V3 ? attr : 0));
lcd_putc(lcdLastPos, y, ']');
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, horz==LS_FIELD_V3 ? attr : 0);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122;
v3_max = 222 - cs->v2;
+6
View File
@@ -1433,6 +1433,12 @@ bool isTelemetrySourceAvailable(int source)
return false;
#endif
#if defined(PCBTARANIS) && defined(REVPLUS)
// on Taranis+ we also hide the SWR
if (source == TELEM_SWR)
return false;
#endif
if (source >= TELEM_A1 && source <= TELEM_A4) {
return g_model.frsky.channels[source-TELEM_A1].ratio != 0;
}
+63 -42
View File
@@ -92,9 +92,20 @@ void menuStatisticsView(uint8_t event)
#if defined(PCBTARANIS)
#define MENU_DEBUG_COL1_OFS (11*FW-2)
#define MENU_DEBUG_Y_MIXMAX (2*FH-3)
#define MENU_DEBUG_Y_LUA (3*FH-2)
#define MENU_DEBUG_Y_FREE_RAM (4*FH-1)
#define MENU_DEBUG_Y_STACK (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
#elif defined(PCBSKY9X)
#define MENU_DEBUG_COL1_OFS (11*FW-3)
#define MENU_DEBUG_COL2_OFS (17*FW)
#define MENU_DEBUG_Y_CURRENT (1*FH)
#define MENU_DEBUG_Y_MAH (2*FH)
#define MENU_DEBUG_Y_CPU_TEMP (3*FH)
#define MENU_DEBUG_Y_COPROC (4*FH)
#define MENU_DEBUG_Y_MIXMAX (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
#else
#define MENU_DEBUG_COL1_OFS (14*FW)
#endif
@@ -149,76 +160,86 @@ void menuStatisticsDebug(uint8_t event)
#if defined(PCBSKY9X) && !defined(REVA)
// current
lcd_putsLeft(1*FH, STR_CPU_CURRENT);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 1*FH, getCurrent(), UNIT_MILLIAMPS, LEFT);
lcd_putsLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT);
uint32_t current_scale = 488 + g_eeGeneral.currentCalib;
lcd_putc(MENU_DEBUG_COL2_OFS, 1*FH, '>');
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, 1*FH, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>');
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
// consumption
lcd_putsLeft(2*FH, STR_CPU_MAH);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 2*FH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
lcd_putsLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(3*FH, STR_CPU_TEMP);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 3*FH, getTemperature(), UNIT_TEMPERATURE, LEFT);
lcd_putc(MENU_DEBUG_COL2_OFS, 3*FH, '>');
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, 3*FH, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
lcd_putsLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT);
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>');
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
#endif
#if defined(COPROCESSOR)
lcd_putsLeft(4*FH, STR_COPROC_TEMP);
lcd_putsLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP);
if (Coproc_read==0) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Co Proc NACK"),INVERS);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Co Proc NACK"),INVERS);
}
else if (Coproc_read==0x81) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Inst.TinyApp"),INVERS);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Inst.TinyApp"),INVERS);
}
else if (Coproc_read<3) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Upgr.TinyApp"),INVERS);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Upgr.TinyApp"),INVERS);
}
else {
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 4*FH, Coproc_temp, UNIT_TEMPERATURE, LEFT);
putsTelemetryValue(MENU_DEBUG_COL2_OFS, 4*FH, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT);
putsTelemetryValue(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
}
#endif
#if defined(PCBTARANIS) && !defined(SIMU)
lcd_putsLeft(3*FH, "Free Mem");
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 3*FH, getAvailableMemory(), LEFT);
lcd_putsLeft(MENU_DEBUG_Y_FREE_RAM, "Free Mem");
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_FREE_RAM, getAvailableMemory(), LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_FREE_RAM, "b");
#endif
#if defined(LUA)
lcd_putsLeft(4*FH, "Lua scripts");
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH+1, "[Duration]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, 4*FH, 10*maxLuaDuration, LEFT);
lcd_putsAtt(lcdLastPos+2, 4*FH+1, "[Interval]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, 4*FH, 10*maxLuaInterval, LEFT);
lcd_putsLeft(MENU_DEBUG_Y_LUA, "Lua scripts");
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_LUA+1, "[Duration]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaDuration, LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_LUA+1, "[Interval]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaInterval, LEFT);
#endif
#if defined(CPUARM)
lcd_putsLeft(5*FH, STR_TMIXMAXMS);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 5*FH, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, 5*FH, "ms");
lcd_putsLeft(6*FH, STR_FREESTACKMINB);
#if LCD_W >= 212
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 6*FH+1, "[Main]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(0), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, 6*FH+1, "[Mix]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(1), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, 6*FH+1, "[Audio]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(2), UNSIGN|LEFT);
#else
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 6*FH, stack_free(0), UNSIGN|LEFT);
lcd_puts(lcdLastPos, 6*FH, "/");
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(1), UNSIGN|LEFT);
lcd_puts(lcdLastPos, 6*FH, "/");
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(2), UNSIGN|LEFT);
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
#endif
#else
#if defined(PCBTARANIS)
lcd_putsLeft(MENU_DEBUG_Y_STACK, STR_FREESTACKMINB);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_STACK, stack_free(255), UNSIGN|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_STACK, "b");
#endif
#if defined(PCBTARANIS)
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS+1, "[Main]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Mix]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Audio]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
#endif
#if !defined(CPUARM)
lcd_putsLeft(1*FH, STR_TMR1LATMAXUS);
lcd_outdez8(MENU_DEBUG_COL1_OFS , 1*FH, g_tmr1Latency_max/2 );
lcd_putsLeft(2*FH, STR_TMR1LATMINUS);
+1
View File
@@ -299,5 +299,6 @@ void lcdSetContrast();
char * strAppend(char * dest, const char * source);
char * strAppendDate(char * str, bool time=false);
char * strAppendFilename(char * dest, const char * filename, const int size);
#endif
+6 -2
View File
@@ -115,7 +115,9 @@ const pm_char * openLogs()
f_puts("Time,", &g_oLogFile);
#endif
#if defined(CPUARM) && defined(FRSKY)
#if defined(PCBTARANIS) && defined(REVPLUS)
f_puts("RSSI,A1,A2,A3,A4,", &g_oLogFile);
#elif defined(CPUARM) && defined(FRSKY)
f_puts("SWR,RSSI,A1,A2,A3,A4,", &g_oLogFile);
#elif defined(FRSKY)
f_puts("Buffer,RX,TX,A1,A2,", &g_oLogFile);
@@ -198,7 +200,9 @@ void writeLogs()
#endif
#if defined(FRSKY)
#if defined(CPUARM)
#if defined(PCBTARANIS) && defined(REVPLUS)
f_printf(&g_oLogFile, "%d,", RAW_FRSKY_MINMAX(frskyData.rssi[0]));
#elif defined(CPUARM)
f_printf(&g_oLogFile, "%d,%d,", RAW_FRSKY_MINMAX(frskyData.swr), RAW_FRSKY_MINMAX(frskyData.rssi[0]));
#else
f_printf(&g_oLogFile, "%d,%d,%d,", frskyStreaming, RAW_FRSKY_MINMAX(frskyData.rssi[0]), RAW_FRSKY_MINMAX(frskyData.rssi[1]));
+318 -201
View File
@@ -76,6 +76,19 @@ uint16_t maxLuaDuration = 0;
#define SCRIPTS_MAX_HEAP 50
#define SET_LUA_INSTRUCTIONS_COUNT(x) (instructionsPercent=0, lua_sethook(L, hook, LUA_MASKCOUNT, x))
struct our_longjmp * global_lj = 0;
/* custom panic handler */
static int custom_lua_atpanic(lua_State *lua)
{
TRACE("PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1));
if (global_lj) {
longjmp(global_lj->b, 1);
/* will never return */
}
return 0;
}
static int instructionsPercent = 0;
void hook(lua_State* L, lua_Debug *ar)
{
@@ -1044,7 +1057,7 @@ static int luaModelSetGlobalVariable(lua_State *L)
int idx = luaL_checkunsigned(L, 1);
int phase = luaL_checkunsigned(L, 2);
int value = luaL_checkinteger(L, 3);
if (phase < MAX_FLIGHT_MODES && idx < MAX_GVARS && value >= -GVAR_LIMIT && value <= GVAR_LIMIT) {
if (phase < MAX_FLIGHT_MODES && idx < MAX_GVARS && value >= -GVAR_MAX && value <= GVAR_MAX) {
g_model.flightModeData[phase].gvars[idx] = value;
eeDirty(EE_MODEL);
}
@@ -1330,14 +1343,29 @@ static const luaL_Reg lcdLib[] = {
{ NULL, NULL } /* sentinel */
};
void luaInit()
void luaDisable()
{
POPUP_WARNING("Lua disabled!");
luaState = INTERPRETER_PANIC;
}
void luaClose()
{
if (L) {
lua_close(L);
PROTECT_LUA() {
lua_close(L); // this should not panic, but we make sure anyway
}
else {
// we can only disable Lua for the rest of the session
luaDisable();
}
UNPROTECT_LUA();
L = NULL;
}
}
L = luaL_newstate();
void luaRegisterAll()
{
// Init lua
luaL_openlibs(L);
@@ -1406,15 +1434,53 @@ void luaInit()
lua_registerint(L, "DOTTED", DOTTED);
lua_registerint(L, "LCD_W", LCD_W);
lua_registerint(L, "LCD_H", LCD_H);
lua_registerint(L, "TIMEHOUR", TIMEHOUR);
}
void luaInit()
{
luaClose();
if (luaState != INTERPRETER_PANIC) {
L = luaL_newstate();
if (L) {
// install our panic handler
lua_atpanic(L, &custom_lua_atpanic);
// protect libs and constants registration
PROTECT_LUA() {
luaRegisterAll();
}
else {
// if we got panic during registration
// we disable Lua for this session
luaDisable();
}
UNPROTECT_LUA();
}
else {
/* log error and return */
luaDisable();
}
}
}
void luaFree(ScriptInternalData & sid)
{
if (sid.run) {
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
sid.run = 0;
PROTECT_LUA() {
if (sid.run) {
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
sid.run = 0;
}
if (sid.background) {
luaL_unref(L, LUA_REGISTRYINDEX, sid.background);
sid.background = 0;
}
lua_gc(L, LUA_GCCOLLECT, 0);
}
else {
luaDisable();
}
UNPROTECT_LUA();
}
int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs * sio=NULL)
@@ -1428,47 +1494,55 @@ int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
if (luaL_loadfile(L, filename) == 0 &&
lua_pcall(L, 0, 1, 0) == 0 &&
lua_istable(L, -1)) {
PROTECT_LUA() {
if (luaL_loadfile(L, filename) == 0 &&
lua_pcall(L, 0, 1, 0) == 0 &&
lua_istable(L, -1)) {
luaL_checktype(L, -1, LUA_TTABLE);
luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
const char *key = lua_tostring(L, -2);
if (!strcmp(key, "init")) {
init = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
const char *key = lua_tostring(L, -2);
if (!strcmp(key, "init")) {
init = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
}
else if (!strcmp(key, "run")) {
sid.run = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
}
else if (!strcmp(key, "background")) {
sid.background = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
}
else if (sio && !strcmp(key, "input")) {
luaGetInputs(*sio);
}
else if (sio && !strcmp(key, "output")) {
luaGetOutputs(*sio);
}
}
else if (!strcmp(key, "run")) {
sid.run = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
}
else if (!strcmp(key, "background")) {
sid.background = luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
}
else if (sio && !strcmp(key, "input")) {
luaGetInputs(*sio);
}
else if (sio && !strcmp(key, "output")) {
luaGetOutputs(*sio);
if (init) {
lua_rawgeti(L, LUA_REGISTRYINDEX, init);
if (lua_pcall(L, 0, 0, 0) != 0) {
TRACE("Error in script %s init: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
}
luaL_unref(L, LUA_REGISTRYINDEX, init);
lua_gc(L, LUA_GCCOLLECT, 0);
}
}
if (init) {
lua_rawgeti(L, LUA_REGISTRYINDEX, init);
luaL_unref(L, LUA_REGISTRYINDEX, init);
if (lua_pcall(L, 0, 0, 0) != 0) {
TRACE("Error in script %s init: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
}
else {
TRACE("Error in script %s: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
}
}
else {
TRACE("Error in script %s: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
TRACE("Panic in script %s: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_PANIC;
}
UNPROTECT_LUA();
if (sid.state != SCRIPT_OK) {
luaFree(sid);
@@ -1630,6 +1704,9 @@ void luaError(uint8_t error)
case SCRIPT_KILLED:
msg = "Script killed";
break;
case SCRIPT_PANIC:
msg = "Script panic";
break;
}
POPUP_WARNING(msg);
}
@@ -1637,22 +1714,198 @@ void luaError(uint8_t error)
void luaExec(const char *filename)
{
LUA_RESET();
luaInit();
standaloneScript.state = SCRIPT_NOFILE;
int result = luaLoad(filename, standaloneScript);
// TODO the same with run ...
if (result == SCRIPT_OK) {
luaState = LUASTATE_STANDALONE_SCRIPT_RUNNING;
luaState = INTERPRETER_RUNNING_STANDALONE_SCRIPT;
}
else {
luaError(result);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
}
void luaDoOneRunStandalone(uint8_t evt)
{
static uint8_t luaDisplayStatistics = false;
if (standaloneScript.state == SCRIPT_OK && standaloneScript.run) {
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
lua_rawgeti(L, LUA_REGISTRYINDEX, standaloneScript.run);
lua_pushinteger(L, evt);
if (lua_pcall(L, 1, 1, 0) == 0) {
if (!lua_isnumber(L, -1)) {
if (instructionsPercent > 100) {
TRACE("Script killed");
standaloneScript.state = SCRIPT_KILLED;
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
else if (lua_isstring(L, -1)) {
char nextScript[_MAX_LFN+1];
strncpy(nextScript, lua_tostring(L, -1), _MAX_LFN);
nextScript[_MAX_LFN] = '\0';
luaExec(nextScript);
}
else {
TRACE("Script error");
standaloneScript.state = SCRIPT_SYNTAX_ERROR;
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
}
else {
int scriptResult = lua_tointeger(L, -1);
lua_pop(L, 1); /* pop returned value */
if (scriptResult != 0) {
TRACE("Script finished with status %d", scriptResult);
standaloneScript.state = SCRIPT_NOFILE;
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
else if (luaDisplayStatistics) {
lcd_hline(0, 7*FH-1, lcdLastPos+FW, ERASE);
lcd_puts(0, 7*FH, "GV Use: ");
lcd_outdezAtt(lcdLastPos, 7*FH, luaGetMemUsed(), LEFT);
lcd_putc(lcdLastPos, 7*FH, 'b');
lcd_hline(0, 7*FH-2, lcdLastPos+FW, FORCE);
lcd_vlineStip(lcdLastPos+FW, 7*FH-2, FH+2, SOLID, FORCE);
}
}
}
else {
TRACE("Script error: %s", lua_tostring(L, -1));
standaloneScript.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
if (standaloneScript.state != SCRIPT_OK) {
luaError(standaloneScript.state);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
TRACE("Script force exit");
killEvents(evt);
standaloneScript.state = SCRIPT_NOFILE;
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
else if (evt == EVT_KEY_LONG(KEY_MENU)) {
killEvents(evt);
luaDisplayStatistics = !luaDisplayStatistics;
}
}
}
void luaDoOneRunPermanentScript(uint8_t evt, int i)
{
ScriptInternalData & sid = scriptInternalData[i];
if (sid.state == SCRIPT_OK) {
SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
int inputsCount = 0;
#if defined(SIMU) || defined(DEBUG)
const char *filename;
#endif
ScriptInputsOutputs * sio = NULL;
if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) {
ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST];
sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST];
inputsCount = sio->inputsCount;
#if defined(SIMU) || defined(DEBUG)
filename = sd.file;
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
for (int j=0; j<sio->inputsCount; j++) {
if (sio->inputs[j].type == 1)
luaGetValueAndPush((uint8_t)sd.inputs[j]);
else
lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def);
}
}
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
if (!getSwitch(fn.swtch)) {
return;
}
#if defined(SIMU) || defined(DEBUG)
filename = fn.play.name;
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
}
else {
#if defined(SIMU) || defined(DEBUG)
filename = "[telem]";
#endif
if (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) {
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
lua_pushinteger(L, evt);
inputsCount = 1;
}
else if (sid.background) {
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background);
}
else {
return;
}
}
if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) {
if (sio) {
for (int j=sio->outputsCount-1; j>=0; j--) {
if (!lua_isnumber(L, -1)) {
sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
TRACE("Script %8s disabled", filename);
break;
}
sio->outputs[j].value = lua_tointeger(L, -1);
lua_pop(L, 1);
}
}
}
else {
if (instructionsPercent > 100) {
TRACE("Script %8s killed", filename);
sid.state = SCRIPT_KILLED;
}
else {
TRACE("Script %8s error: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
}
}
if (sid.state != SCRIPT_OK) {
luaFree(sid);
}
else {
if (instructionsPercent > sid.instructions) {
sid.instructions = instructionsPercent;
}
}
}
}
void luaDoGc()
{
PROTECT_LUA() {
lua_gc(L, LUA_GCSTEP /*LUA_GCCOLLECT*/, 0); // LUA_GCSTEP is enough
#if defined(SIMU) || defined(DEBUG)
static int lastgc = 0;
int gc = luaGetMemUsed();
if (gc != lastgc) {
lastgc = gc;
TRACE("GC Use: %dbytes", gc);
}
#endif
}
else {
// we disable Lua for the rest of the session
luaDisable();
}
UNPROTECT_LUA();
}
void luaTask(uint8_t evt)
{
lcd_locked = false;
static uint8_t luaDisplayStatistics = false;
uint32_t t0 = get_tmr10ms();
static uint32_t lastLuaTime = 0;
@@ -1662,176 +1915,40 @@ void luaTask(uint8_t evt)
maxLuaInterval = interval;
}
if (luaState & LUASTATE_STANDALONE_SCRIPT_RUNNING) {
// standalone script
if (standaloneScript.state == SCRIPT_OK && standaloneScript.run) {
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
lua_rawgeti(L, LUA_REGISTRYINDEX, standaloneScript.run);
lua_pushinteger(L, evt);
if (lua_pcall(L, 1, 1, 0) == 0) {
if (!lua_isnumber(L, -1)) {
if (instructionsPercent > 100) {
TRACE("Script killed");
standaloneScript.state = SCRIPT_KILLED;
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
}
else if (lua_isstring(L, -1)) {
char nextScript[_MAX_LFN+1];
strncpy(nextScript, lua_tostring(L, -1), _MAX_LFN);
nextScript[_MAX_LFN] = '\0';
luaExec(nextScript);
}
else {
TRACE("Script error");
standaloneScript.state = SCRIPT_SYNTAX_ERROR;
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
}
}
else {
int scriptResult = lua_tointeger(L, -1);
lua_pop(L, 1); /* pop returned value */
if (scriptResult != 0) {
TRACE("Script finished with status %d", scriptResult);
standaloneScript.state = SCRIPT_NOFILE;
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
}
else if (luaDisplayStatistics) {
int gc = 1000*lua_gc(L, LUA_GCCOUNT, 0) + lua_gc(L, LUA_GCCOUNTB, 0);
lcd_hline(0, 7*FH-1, lcdLastPos+FW, ERASE);
lcd_puts(0, 7*FH, "GV Use: ");
lcd_outdezAtt(lcdLastPos, 7*FH, gc, LEFT);
lcd_putc(lcdLastPos, 7*FH, 'b');
lcd_hline(0, 7*FH-2, lcdLastPos+FW, FORCE);
lcd_vlineStip(lcdLastPos+FW, 7*FH-2, FH+2, SOLID, FORCE);
}
}
}
else {
TRACE("Script error: %s", lua_tostring(L, -1));
standaloneScript.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
}
if (standaloneScript.state != SCRIPT_OK) {
luaError(standaloneScript.state);
}
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
TRACE("Script force exit");
killEvents(evt);
standaloneScript.state = SCRIPT_NOFILE;
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
}
else if (evt == EVT_KEY_LONG(KEY_MENU)) {
killEvents(evt);
luaDisplayStatistics = !luaDisplayStatistics;
}
if (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) {
PROTECT_LUA() {
luaDoOneRunStandalone(evt);
}
else {
POPUP_WARNING("Script Panic!");
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
UNPROTECT_LUA();
}
else {
// model scripts
if (luaState & LUASTATE_RELOAD_MODEL_SCRIPTS) {
if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) {
luaState = 0;
LUA_RESET();
luaInit();
if (!L) return;
luaLoadPermanentScripts();
}
for (int i=0; i<luaScriptsCount; i++) {
ScriptInternalData & sid = scriptInternalData[i];
if (sid.state == SCRIPT_OK) {
SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
int inputsCount = 0;
#if defined(SIMU) || defined(DEBUG)
const char *filename;
#endif
ScriptInputsOutputs * sio = NULL;
if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) {
ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST];
sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST];
inputsCount = sio->inputsCount;
#if defined(SIMU) || defined(DEBUG)
filename = sd.file;
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
for (int j=0; j<sio->inputsCount; j++) {
if (sio->inputs[j].type == 1)
luaGetValueAndPush((uint8_t)sd.inputs[j]);
else
lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def);
}
}
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
if (!getSwitch(fn.swtch)) {
continue;
}
#if defined(SIMU) || defined(DEBUG)
filename = fn.play.name;
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
}
else {
#if defined(SIMU) || defined(DEBUG)
filename = "[telem]";
#endif
if (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) {
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
lua_pushinteger(L, evt);
inputsCount = 1;
}
else if (sid.background) {
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background);
}
else {
continue;
}
}
if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) {
if (sio) {
for (int j=sio->outputsCount-1; j>=0; j--) {
if (!lua_isnumber(L, -1)) {
sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
TRACE("Script %8s disabled", filename);
break;
}
sio->outputs[j].value = lua_tointeger(L, -1);
lua_pop(L, 1);
}
}
}
else {
if (instructionsPercent > 100) {
TRACE("Script %8s killed", filename);
sid.state = SCRIPT_KILLED;
}
else {
TRACE("Script %8s error: %s", filename, lua_tostring(L, -1));
sid.state = SCRIPT_SYNTAX_ERROR;
}
}
if (sid.state != SCRIPT_OK) {
luaFree(sid);
}
else {
if (instructionsPercent > sid.instructions) {
sid.instructions = instructionsPercent;
}
}
PROTECT_LUA() {
luaDoOneRunPermanentScript(evt, i);
}
else {
// we disable this script for the rest of the session
ScriptInternalData & sid = scriptInternalData[i];
sid.state = SCRIPT_PANIC;
luaFree(sid);
}
UNPROTECT_LUA();
}
}
lua_gc(L, LUA_GCCOLLECT, 0);
#if defined(SIMU) || defined(DEBUG)
static int lastgc = 0;
int gc = luaGetMemUsed();
if (gc != lastgc) {
lastgc = gc;
TRACE("GC Use: %dbytes", gc);
}
#endif
luaDoGc();
t0 = get_tmr10ms() - t0;
if (t0 > maxLuaDuration) {
@@ -1841,5 +1958,5 @@ void luaTask(uint8_t evt)
int luaGetMemUsed()
{
return 1000*lua_gc(L, LUA_GCCOUNT, 0) + lua_gc(L, LUA_GCCOUNTB, 0);
return (lua_gc(L, LUA_GCCOUNT, 0) << 10) + lua_gc(L, LUA_GCCOUNTB, 0);
}
+2 -1
View File
@@ -106,8 +106,9 @@ void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS)
else {
v = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM && ed->scale > 0) {
v = limit(-1024, int((v * 1024) / convertTelemValue(ed->srcRaw-MIXSRC_FIRST_TELEM+1, ed->scale)), 1024);
v = (v * 1024) / convertTelemValue(ed->srcRaw-MIXSRC_FIRST_TELEM+1, ed->scale);
}
v = limit(-1024, v, 1024);
}
#else
int16_t v = anas2[ed->chn];
+37 -5
View File
@@ -441,6 +441,10 @@ void modelDefault(uint8_t id)
}
#endif
#if defined(CPUARM) && !defined(PCBTARANIS)
g_model.externalModule = MODULE_TYPE_PPM;
#endif
#if defined(PXX) && defined(CPUARM)
modelHeaders[id].modelId = g_model.header.modelId = id+1;
checkModelIdUnique(id);
@@ -463,6 +467,23 @@ void modelDefault(uint8_t id)
g_model.mavlink.pc_rssi_en = 1;
#endif
}
#if defined(PCBTARANIS)
bool isInputRecursive(int index)
{
ExpoData * line = expoAddress(0);
for (int i=0; i<MAX_EXPOS; i++, line++) {
if (line->chn > index)
break;
else if (line->chn < index)
continue;
else if (line->srcRaw >= MIXSRC_FIRST_LOGICAL_SWITCH)
return true;
}
return false;
}
#endif
#if defined(AUTOSOURCE)
int8_t getMovedSource(GET_MOVED_SOURCE_PARAMS)
{
@@ -474,8 +495,10 @@ int8_t getMovedSource(GET_MOVED_SOURCE_PARAMS)
if (min <= MIXSRC_FIRST_INPUT) {
for (uint8_t i=0; i<MAX_INPUTS; i++) {
if (abs(anas[i] - inputsStates[i]) > 512) {
result = MIXSRC_FIRST_INPUT+i;
break;
if (!isInputRecursive(i)) {
result = MIXSRC_FIRST_INPUT+i;
break;
}
}
}
}
@@ -2511,6 +2534,10 @@ void opentxClose()
// TODO needed? telemetryEnd();
#endif
#if defined(LUA)
luaClose();
#endif
#if defined(SDCARD)
closeLogs();
sdDone();
@@ -3300,6 +3327,13 @@ uint16_t stack_free(uint8_t tid)
stack = audioStack;
size = AUDIO_STACK_SIZE;
break;
#if defined(PCBTARANIS)
case 255:
// main stack
stack = (OS_STK *)&_main_stack_start;
size = ((unsigned char *)&_estack - (unsigned char *)&_main_stack_start) / 4;
break;
#endif
default:
return 0;
}
@@ -3392,8 +3426,6 @@ inline void opentxInit(OPENTX_INIT_ARGS)
rtcInit();
#endif
LUA_INIT();
if (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on
if (UNEXPECTED_SHUTDOWN()) {
@@ -3420,7 +3452,7 @@ inline void opentxInit(OPENTX_INIT_ARGS)
backlightOn();
#if defined(PCBTARANIS)
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL);
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL());
#endif
#if defined(CPUARM)
+28 -11
View File
@@ -693,7 +693,8 @@ extern uint8_t flightModeTransitionLast;
#if defined(CPUARM) && !defined(SIMU)
extern unsigned char *heap;
extern int _end;
extern unsigned char *_estack;
extern int _estack;
extern int _main_stack_start;
#define getAvailableMemory() ((unsigned int)((unsigned char *)&_estack - heap))
#endif
@@ -1465,13 +1466,14 @@ enum AUDIO_SOUNDS {
SCRIPT_OK,
SCRIPT_NOFILE,
SCRIPT_SYNTAX_ERROR,
SCRIPT_KILLED
SCRIPT_PANIC,
SCRIPT_KILLED,
};
enum ScriptReference {
SCRIPT_MIX_FIRST,
SCRIPT_MIX_LAST=SCRIPT_MIX_FIRST+MAX_SCRIPTS-1,
SCRIPT_FUNC_FIRST,
SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+MAX_SCRIPTS-1,
SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+NUM_CFN-1,
SCRIPT_TELEMETRY_FIRST,
SCRIPT_TELEMETRY_LAST=SCRIPT_TELEMETRY_FIRST+MAX_SCRIPTS, // telem0 and telem1 .. telem7
};
@@ -1488,13 +1490,18 @@ enum AUDIO_SOUNDS {
uint8_t outputsCount;
ScriptOutput outputs[MAX_SCRIPT_OUTPUTS];
};
#define LUASTATE_STANDALONE_SCRIPT_RUNNING 1
#define LUASTATE_RELOAD_MODEL_SCRIPTS 2
enum InterpreterState {
INTERPRETER_RUNNING_PERMANENT_SCRIPTS,
INTERPRETER_RUNNING_STANDALONE_SCRIPT,
INTERPRETER_RELOAD_PERMANENT_SCRIPTS,
INTERPRETER_PANIC,
};
extern uint8_t luaState;
extern uint8_t luaScriptsCount;
extern ScriptInternalData standaloneScript;
extern ScriptInternalData scriptInternalData[MAX_SCRIPTS];
extern ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS];
void luaClose();
void luaInit();
void luaTask(uint8_t evt);
void luaExec(const char *filename);
@@ -1503,13 +1510,23 @@ enum AUDIO_SOUNDS {
int luaGetMemUsed();
#define luaGetCpuUsed(idx) scriptInternalData[idx].instructions
bool isTelemetryScriptAvailable(uint8_t index);
#define LUA_INIT()
#define LUA_RESET() luaInit()
#define LUA_LOAD_MODEL_SCRIPTS() luaState |= LUASTATE_RELOAD_MODEL_SCRIPTS
#define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= LUASTATE_RELOAD_MODEL_SCRIPTS
#define LUA_LOAD_MODEL_SCRIPTS() luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS
#define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS
// Lua PROTECT/UNPROTECT
#include <setjmp.h>
struct our_longjmp {
struct our_longjmp *previous;
jmp_buf b;
volatile int status; /* error code */
};
extern struct our_longjmp * global_lj;
#define PROTECT_LUA() { struct our_longjmp lj; \
lj.previous = global_lj; /* chain new error handler */ \
global_lj = &lj; \
if (setjmp(lj.b) == 0)
#define UNPROTECT_LUA() global_lj = lj.previous; } /* restore old error handler */
#else
#define LUA_INIT()
#define LUA_RESET()
#define LUA_LOAD_MODEL_SCRIPTS()
#define LUA_LOAD_MODEL_SCRIPT(idx)
#endif
+12
View File
@@ -151,6 +151,18 @@ char * strAppend(char * dest, const char * source)
return dest - 1;
}
char * strAppendFilename(char * dest, const char * filename, const int size)
{
memset(dest, 0, size);
for (int i=0; i<size; i++) {
char c = *filename++;
if (c == '\0' || c == '.')
break;
*dest++ = c;
}
return dest;
}
#if defined(RTCLOCK)
#include "rtc.h"
+19 -12
View File
@@ -191,6 +191,16 @@ getvalue_t getValueForLogicalSwitch(uint8_t i)
#define getValueForLogicalSwitch(i) getValue(i)
#endif
PACK(typedef struct {
uint8_t state;
uint8_t last;
}) ls_sticky_struct;
PACK(typedef struct {
uint16_t state:1;
uint16_t duration:15;
}) ls_stay_struct;
bool getLogicalSwitch(uint8_t idx)
{
LogicalSwitchData * ls = lswAddress(idx);
@@ -206,7 +216,9 @@ bool getLogicalSwitch(uint8_t idx)
#endif
if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) {
LS_LAST_VALUE(mixerCurrentFlightMode, idx) = CS_LAST_VALUE_INIT;
if (ls->func != LS_FUNC_STICKY) {
LS_LAST_VALUE(mixerCurrentFlightMode, idx) = CS_LAST_VALUE_INIT;
}
result = false;
}
else if ((s=lswFamily(ls->func)) == LS_FAMILY_BOOL) {
@@ -379,6 +391,10 @@ DurationAndDelayProcessing:
if (context.timerState == SWITCH_ENABLE) {
result = (ls->duration==0 || context.timer>0); // return false after duration timer runs out
if (!result && ls->func == LS_FUNC_STICKY) {
ls_sticky_struct & lastValue = (ls_sticky_struct &)context.lastValue;
lastValue.state = 0;
}
}
}
else if (context.timerState == SWITCH_ENABLE && ls->duration > 0 && context.timer > 0) {
@@ -733,10 +749,6 @@ void logicalSwitchesTimerTick()
}
}
else if (ls->func == LS_FUNC_STICKY) {
PACK(typedef struct {
uint8_t state;
uint8_t last;
}) ls_sticky_struct;
ls_sticky_struct & lastValue = (ls_sticky_struct &)LS_LAST_VALUE(fm, i);
bool before = lastValue.last & 0x01;
if (lastValue.state) {
@@ -760,22 +772,17 @@ void logicalSwitchesTimerTick()
}
#if defined(CPUARM)
else if (ls->func == LS_FUNC_STAY) {
PACK(typedef struct {
uint16_t state:1;
uint16_t duration:15;
}) ls_stay_struct;
ls_stay_struct & lastValue = (ls_stay_struct &)LS_LAST_VALUE(fm, i);
lastValue.state = false;
bool state = getSwitch(ls->v1);
if (state) {
if (ls->v3 == 0 && lastValue.duration == lswTimerValue(ls->v2))
if (ls->v3 == -1 && lastValue.duration == lswTimerValue(ls->v2))
lastValue.state = true;
if (lastValue.duration < 1000)
lastValue.duration++;
}
else {
if (lastValue.duration > lswTimerValue(ls->v2) && lastValue.duration <= lswTimerValue(ls->v2+ls->v3))
if (lastValue.duration > lswTimerValue(ls->v2) && (ls->v3 == 0 || lastValue.duration <= lswTimerValue(ls->v2+ls->v3)))
lastValue.state = true;
lastValue.duration = 0;
}
-2
View File
@@ -309,8 +309,6 @@ void *main_thread(void *)
if (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on
LUA_INIT();
if (main_thread_running == 1) {
opentxStart();
}
+1 -1
View File
@@ -293,6 +293,6 @@ void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size);
// Second UART driver
void telemetrySecondPortInit(unsigned int protocol);
uint16_t telemetrySecondPortReceive();
bool telemetrySecondPortReceive(uint8_t & data);
#endif
@@ -44,10 +44,9 @@
/** Pins description corresponding to Rxd,Txd, (UART pins) */
#define SECOND_SERIAL_PINS {PINS_UART}
Fifo<512> serial2RxFifo;
#if !defined(SIMU)
extern Fifo<512> debugRxFifo;
/*
* Outputs a character on the UART line.
*
@@ -99,10 +98,8 @@ void SECOND_UART_Configure(uint32_t baudrate, uint32_t masterClock)
/* Enable receiver and transmitter */
pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
#if defined(DEBUG)
pUart->UART_IER = UART_IER_RXRDY;
NVIC_EnableIRQ(UART0_IRQn);
#endif
}
void SECOND_UART_Stop()
@@ -113,9 +110,7 @@ void SECOND_UART_Stop()
extern "C" void UART0_IRQHandler()
{
#if defined(DEBUG)
debugRxFifo.push(SECOND_SERIAL_UART->UART_RHR);
#endif
serial2RxFifo.push(SECOND_SERIAL_UART->UART_RHR);
}
#else
#define SECOND_UART_Configure(...)
@@ -125,17 +120,11 @@ extern "C" void UART0_IRQHandler()
void telemetrySecondPortInit(unsigned int /*protocol*/)
{
SECOND_UART_Configure(FRSKY_D_BAUDRATE, Master_frequency);
startPdcUsartReceive();
// startPdcUsartReceive();
}
uint16_t telemetrySecondPortReceive()
bool telemetrySecondPortReceive(uint8_t & data)
{
Uart *pUart = SECOND_SERIAL_UART;
if (pUart->UART_SR & UART_SR_RXRDY) {
return pUart->UART_RHR ;
}
return 0xFFFF ;
return serial2RxFifo.pop(data);
}
#endif
+10 -6
View File
@@ -46,6 +46,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "debug.h"
/*----------------------------------------------------------------------------
* Exported variables
@@ -53,10 +54,8 @@
#undef errno
extern int errno;
extern int _end;
extern int _estack;
#define RAM_END (unsigned char *)&_estack
extern int _end;
extern int _main_stack_start;
/*----------------------------------------------------------------------------
* Exported functions
@@ -68,7 +67,7 @@ extern int _getpid ( void ) ;
unsigned char *heap = (unsigned char *)&_end;
extern caddr_t _sbrk(int nbytes)
{
if (heap + nbytes < RAM_END-4096) {
if (heap + nbytes < (unsigned char *)&_main_stack_start) {
unsigned char *prev_heap = heap;
heap += nbytes;
return (caddr_t) prev_heap;
@@ -142,7 +141,7 @@ extern int _write( int file, char *ptr, int len )
extern void _exit( int status )
{
printf( "Exiting with status %d.\n", status ) ;
TRACE( "Exiting with status %d.\n", status ) ;
for ( ; ; ) ;
}
@@ -156,3 +155,8 @@ extern int _getpid ( void )
{
return -1 ;
}
void _init (void)
{
}
+19 -29
View File
@@ -36,7 +36,7 @@
#include "../../opentx.h"
#define RX_UART_BUFFER_SIZE 32
#define RX_UART_BUFFER_SIZE 128
struct t_rxUartBuffer
{
@@ -44,8 +44,7 @@ struct t_rxUartBuffer
uint8_t *outPtr ;
};
struct t_rxUartBuffer TelemetryInBuffer[2] ;
uint32_t TelemetryActiveBuffer;
struct t_rxUartBuffer TelemetryInBuffer ;
uint16_t DsmRxTimeout;
// USART0 configuration
@@ -106,18 +105,14 @@ extern "C" void USART0_IRQHandler()
void startPdcUsartReceive()
{
register Usart *pUsart = SECOND_USART;
TelemetryInBuffer[0].outPtr = TelemetryInBuffer[0].fifo ;
TelemetryInBuffer[1].outPtr = TelemetryInBuffer[1].fifo ;
TelemetryInBuffer.outPtr = TelemetryInBuffer.fifo ;
#ifndef SIMU
// TODO because of the 64bits cast ...
pUsart->US_RPR = (uint32_t)TelemetryInBuffer[0].fifo ;
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer[1].fifo ;
pUsart->US_RPR = (uint32_t)TelemetryInBuffer.fifo ;
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ;
#endif
pUsart->US_RCR = RX_UART_BUFFER_SIZE ;
pUsart->US_RNCR = RX_UART_BUFFER_SIZE ;
pUsart->US_PTCR = US_PTCR_RXTEN ;
TelemetryActiveBuffer = 0;
}
void rxPdcUsart( void (*pChProcess)(uint8_t x) )
@@ -126,34 +121,29 @@ void rxPdcUsart( void (*pChProcess)(uint8_t x) )
register Usart *pUsart = SECOND_USART;
uint8_t *ptr ;
uint8_t *endPtr ;
uint32_t j ;
// Find out where the DMA has got to
__disable_irq() ;
pUsart->US_PTCR = US_PTCR_RXTDIS ; // Freeze DMA
ptr = (uint8_t *)pUsart->US_RPR ;
j = pUsart->US_RNCR ;
pUsart->US_PTCR = US_PTCR_RXTEN ; // DMA active again
__enable_irq() ;
endPtr = ptr - 1 ;
ptr = TelemetryInBuffer[TelemetryActiveBuffer].outPtr ;
if ( j == 0 ) // First buf is full
endPtr = (uint8_t *)pUsart->US_RPR ;
// Check for DMA passed end of buffer
if ( endPtr > &TelemetryInBuffer.fifo[RX_UART_BUFFER_SIZE-1] )
{
endPtr = &TelemetryInBuffer[TelemetryActiveBuffer].fifo[RX_UART_BUFFER_SIZE-1] ; // last byte
endPtr = TelemetryInBuffer.fifo ;
}
while ( ptr <= endPtr )
ptr = TelemetryInBuffer.outPtr ;
while ( ptr != endPtr )
{
(*pChProcess)(*ptr++) ;
if ( ptr > &TelemetryInBuffer.fifo[RX_UART_BUFFER_SIZE-1] ) // last byte
{
ptr = TelemetryInBuffer.fifo ;
}
}
TelemetryInBuffer[TelemetryActiveBuffer].outPtr = ptr ;
if ( j == 0 ) // First buf is full
TelemetryInBuffer.outPtr = ptr ;
if ( pUsart->US_RNCR == 0 )
{
TelemetryInBuffer[TelemetryActiveBuffer].outPtr = TelemetryInBuffer[TelemetryActiveBuffer].fifo ;
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer[TelemetryActiveBuffer].fifo ;
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ;
pUsart->US_RNCR = RX_UART_BUFFER_SIZE ;
TelemetryActiveBuffer ^= 1 ; // Other buffer is active
rxPdcUsart( pChProcess ) ; // Get any chars from second buffer
}
#endif
}
@@ -98,8 +98,23 @@ LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/*Paint Main Stack */
ldr r2, = _main_stack_start
PaintMainStack:
movs r3, #0x55555555
str r3, [r2], #4
LoopPaintMainStack:
ldr r3, = _estack
cmp r2, r3
bcc PaintMainStack
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call C++ constructors for static objects */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
bx lr
+2 -5
View File
@@ -338,11 +338,8 @@ void lcdSetRefVolt(uint8_t val)
#if defined(REVPLUS)
void turnBacklightOn(uint8_t level, uint8_t color)
{
if (color >= 9 && color <= 17) {
color += 83;
}
TIM4->CCR4 = (100-level)*color;
TIM4->CCR2 = (100-level)*(100-color);
TIM4->CCR4 = ((100-level)*(20-color))/20;
TIM4->CCR2 = ((100-level)*color)/20;
}
void turnBacklightOff(void)
@@ -34,6 +34,8 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of 128K SRAM */
_main_stack_size = 0x1000; /*size of main stack*/
_main_stack_start = _estack - _main_stack_size;
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
@@ -21,6 +21,8 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of 128K SRAM */
_main_stack_size = 0x1000; /*size of main stack*/
_main_stack_start = _estack - _main_stack_size;
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
+3 -3
View File
@@ -131,15 +131,15 @@ extern "C" void USART3_IRQHandler(void)
}
// Receive
uint32_t status = SPORT->SR;
uint32_t status = USART3->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
uint8_t data = SPORT->DR;
uint8_t data = USART3->DR;
if (uart3Telemetry && !(status & USART_FLAG_ERRORS)) {
telemetryFifo.push(data);
}
status = SPORT->SR;
status = USART3->SR;
}
}
+4 -4
View File
@@ -277,7 +277,7 @@ enum AlarmsCheckSteps {
void telemetryWakeup()
{
#if defined(CPUARM)
uint8_t requiredTelemetryProtocol = MODEL_TELEMETRY_PROTOCOL;
uint8_t requiredTelemetryProtocol = MODEL_TELEMETRY_PROTOCOL();
if (telemetryProtocol != requiredTelemetryProtocol) {
telemetryProtocol = requiredTelemetryProtocol;
telemetryInit();
@@ -307,8 +307,8 @@ void telemetryWakeup()
}
#elif defined(PCBSKY9X)
if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) {
uint16_t data ;
while ((data=telemetrySecondPortReceive()) != 0xFFFF) {
uint8_t data;
while (telemetrySecondPortReceive(data)) {
processSerialData(data);
}
}
@@ -347,7 +347,7 @@ void telemetryWakeup()
alarmsCheckTime = get_tmr10ms() + 100; /* next check in 1 second */
if (alarmsCheckStep == ALARM_SWR_STEP) {
#if defined(PCBTARANIS)
#if defined(PCBTARANIS) && !defined(REVPLUS)
if (IS_FRSKY_SPORT_PROTOCOL() && frskyData.swr.value > 0x33) {
AUDIO_SWR_RED();
POPUP_WARNING(STR_ANTENNAPROBLEM);
+2 -2
View File
@@ -477,9 +477,9 @@ void frskyUpdateCells(void);
#endif
#if defined(PCBTARANIS)
#define MODEL_TELEMETRY_PROTOCOL ((g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.externalModule == MODULE_TYPE_PPM) ? g_model.telemetryProtocol : PROTOCOL_FRSKY_SPORT)
#define MODEL_TELEMETRY_PROTOCOL() ((g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.externalModule == MODULE_TYPE_PPM) ? g_model.telemetryProtocol : PROTOCOL_FRSKY_SPORT)
#elif defined(CPUARM)
#define MODEL_TELEMETRY_PROTOCOL g_model.telemetryProtocol
#define MODEL_TELEMETRY_PROTOCOL() g_model.telemetryProtocol
#endif
#endif
+6 -3
View File
@@ -290,8 +290,9 @@ void frskyDProcessPacket(uint8_t *packet)
link_counter += 256 / FRSKY_D_AVERAGING;
#if defined(VARIO)
uint8_t varioSource = g_model.frsky.varioSource - VARIO_SOURCE_A1;
if (varioSource < 2)
if (varioSource < 2) {
frskyData.hub.varioSpeed = applyChannelRatio(varioSource, frskyData.analog[varioSource].value);
}
#endif
break;
}
@@ -300,12 +301,14 @@ void frskyDProcessPacket(uint8_t *packet)
uint8_t numBytes = 3 + (packet[1] & 0x07); // sanitize in case of data corruption leading to buffer overflow
for (uint8_t i=3; i<numBytes; i++) {
#if defined(FRSKY_HUB)
if (IS_USR_PROTO_FRSKY_HUB())
if (IS_USR_PROTO_FRSKY_HUB()) {
parseTelemHubByte(packet[i]);
}
#endif
#if defined(WS_HOW_HIGH)
if (IS_USR_PROTO_WS_HOW_HIGH())
if (IS_USR_PROTO_WS_HOW_HIGH()) {
parseTelemWSHowHighByte(packet[i]);
}
#endif
}
break;
+180 -178
View File
@@ -301,191 +301,193 @@ void frskySportProcessPacket(uint8_t *packet)
if (appId == SWR_ID) {
frskyData.swr.set(SPORT_DATA_U8(packet));
}
else if (appId == ADC1_ID || appId == ADC2_ID) {
// A1/A2 of DxR receivers
uint8_t idx = appId - ADC1_ID;
frskyData.analog[idx].set(SPORT_DATA_U8(packet), g_model.frsky.channels[idx].type);
#if defined(VARIO)
uint8_t varioSource = g_model.frsky.varioSource - VARIO_SOURCE_A1;
if (varioSource == appId-ADC1_ID) {
frskyData.hub.varioSpeed = applyChannelRatio(varioSource, frskyData.analog[varioSource].value);
}
#endif
}
else if (appId == BATT_ID) {
frskyData.analog[TELEM_ANA_A1].set(SPORT_DATA_U8(packet), UNIT_VOLTS);
}
else if ((appId >> 8) == 0) {
// The old FrSky IDs
uint8_t id = (uint8_t)appId;
uint16_t value = HUB_DATA_U16(packet);
processHubPacket(id, value);
}
else if (appId >= T1_FIRST_ID && appId <= T1_LAST_ID) {
frskyData.hub.temperature1 = SPORT_DATA_S32(packet);
if (frskyData.hub.temperature1 > frskyData.hub.maxTemperature1)
frskyData.hub.maxTemperature1 = frskyData.hub.temperature1;
}
else if (appId >= T2_FIRST_ID && appId <= T2_LAST_ID) {
frskyData.hub.temperature2 = SPORT_DATA_S32(packet);
if (frskyData.hub.temperature2 > frskyData.hub.maxTemperature2)
frskyData.hub.maxTemperature2 = frskyData.hub.temperature2;
}
else if (appId >= RPM_FIRST_ID && appId <= RPM_LAST_ID) {
frskyData.hub.rpm = SPORT_DATA_U32(packet) / (g_model.frsky.blades+2);
if (frskyData.hub.rpm > frskyData.hub.maxRpm)
frskyData.hub.maxRpm = frskyData.hub.rpm;
}
else if (appId >= FUEL_FIRST_ID && appId <= FUEL_LAST_ID) {
frskyData.hub.fuelLevel = SPORT_DATA_U32(packet);
}
else if (appId >= ALT_FIRST_ID && appId <= ALT_LAST_ID) {
setBaroAltitude(SPORT_DATA_S32(packet));
}
else if (appId >= VARIO_FIRST_ID && appId <= VARIO_LAST_ID) {
frskyData.hub.varioSpeed = SPORT_DATA_S32(packet);
}
else if (appId >= ACCX_FIRST_ID && appId <= ACCX_LAST_ID) {
frskyData.hub.accelX = SPORT_DATA_S32(packet);
}
else if (appId >= ACCY_FIRST_ID && appId <= ACCY_LAST_ID) {
frskyData.hub.accelY = SPORT_DATA_S32(packet);
}
else if (appId >= ACCZ_FIRST_ID && appId <= ACCZ_LAST_ID) {
frskyData.hub.accelZ = SPORT_DATA_S32(packet);
}
else if (appId >= CURR_FIRST_ID && appId <= CURR_LAST_ID) {
frskyData.hub.current = SPORT_DATA_U32(packet);
if (((int16_t)frskyData.hub.current + g_model.frsky.fasOffset)>0)
frskyData.hub.current += g_model.frsky.fasOffset;
else
frskyData.hub.current = 0;
if (frskyData.hub.current > frskyData.hub.maxCurrent)
frskyData.hub.maxCurrent = frskyData.hub.current;
}
else if (appId >= VFAS_FIRST_ID && appId <= VFAS_LAST_ID) {
frskyData.hub.vfas = SPORT_DATA_U32(packet)/10; //TODO: remove /10 and display with PREC2 when using SPORT
if (!frskyData.hub.minVfas || frskyData.hub.vfas < frskyData.hub.minVfas)
frskyData.hub.minVfas = frskyData.hub.vfas;
}
else if (appId >= AIR_SPEED_FIRST_ID && appId <= AIR_SPEED_LAST_ID) {
frskyData.hub.airSpeed = SPORT_DATA_U32(packet);
if (frskyData.hub.airSpeed > frskyData.hub.maxAirSpeed)
frskyData.hub.maxAirSpeed = frskyData.hub.airSpeed;
}
else if (appId >= GPS_SPEED_FIRST_ID && appId <= GPS_SPEED_LAST_ID) {
frskyData.hub.gpsSpeed_bp = (uint16_t) (SPORT_DATA_U32(packet)/1000);
if (frskyData.hub.gpsSpeed_bp > frskyData.hub.maxGpsSpeed)
frskyData.hub.maxGpsSpeed = frskyData.hub.gpsSpeed_bp;
}
else if (appId >= GPS_TIME_DATE_FIRST_ID && appId <= GPS_TIME_DATE_LAST_ID) {
uint32_t gps_time_date = SPORT_DATA_U32(packet);
if (gps_time_date & 0x000000ff) {
frskyData.hub.year = (uint16_t) ((gps_time_date & 0xff000000) >> 24);
frskyData.hub.month = (uint8_t) ((gps_time_date & 0x00ff0000) >> 16);
frskyData.hub.day = (uint8_t) ((gps_time_date & 0x0000ff00) >> 8);
}
else {
frskyData.hub.hour = (uint8_t) ((gps_time_date & 0xff000000) >> 24);
frskyData.hub.min = (uint8_t) ((gps_time_date & 0x00ff0000) >> 16);
frskyData.hub.sec = (uint16_t) ((gps_time_date & 0x0000ff00) >> 8);
frskyData.hub.hour = ((uint8_t) (frskyData.hub.hour + g_eeGeneral.timezone + 24)) % 24;
}
}
else if (appId >= GPS_COURS_FIRST_ID && appId <= GPS_COURS_LAST_ID) {
uint32_t course = SPORT_DATA_U32(packet);
frskyData.hub.gpsCourse_bp = course / 100;
frskyData.hub.gpsCourse_ap = course % 100;
}
else if (appId >= GPS_ALT_FIRST_ID && appId <= GPS_ALT_LAST_ID) {
frskyData.hub.gpsAltitude = SPORT_DATA_S32(packet);
if (!frskyData.hub.gpsAltitudeOffset)
frskyData.hub.gpsAltitudeOffset = -frskyData.hub.gpsAltitude;
if (!frskyData.hub.baroAltitudeOffset) {
int altitude = TELEMETRY_RELATIVE_GPS_ALT_BP;
if (altitude > frskyData.hub.maxAltitude)
frskyData.hub.maxAltitude = altitude;
if (altitude < frskyData.hub.minAltitude)
frskyData.hub.minAltitude = altitude;
}
if (frskyData.hub.gpsFix > 0) {
if (!frskyData.hub.pilotLatitude && !frskyData.hub.pilotLongitude) {
// First received GPS position => Pilot GPS position
getGpsPilotPosition();
else if (frskyData.rssi[0].value > 0) {
if (appId == ADC1_ID || appId == ADC2_ID) {
// A1/A2 of DxR receivers
uint8_t idx = appId - ADC1_ID;
frskyData.analog[idx].set(SPORT_DATA_U8(packet), g_model.frsky.channels[idx].type);
#if defined(VARIO)
uint8_t varioSource = g_model.frsky.varioSource - VARIO_SOURCE_A1;
if (varioSource == appId-ADC1_ID) {
frskyData.hub.varioSpeed = applyChannelRatio(varioSource, frskyData.analog[varioSource].value);
}
else if (frskyData.hub.gpsDistNeeded || g_menuStack[g_menuStackPtr] == menuTelemetryFrsky) {
getGpsDistance();
#endif
}
else if (appId == BATT_ID) {
frskyData.analog[TELEM_ANA_A1].set(SPORT_DATA_U8(packet), UNIT_VOLTS);
}
else if ((appId >> 8) == 0) {
// The old FrSky IDs
uint8_t id = (uint8_t)appId;
uint16_t value = HUB_DATA_U16(packet);
processHubPacket(id, value);
}
else if (appId >= T1_FIRST_ID && appId <= T1_LAST_ID) {
frskyData.hub.temperature1 = SPORT_DATA_S32(packet);
if (frskyData.hub.temperature1 > frskyData.hub.maxTemperature1)
frskyData.hub.maxTemperature1 = frskyData.hub.temperature1;
}
else if (appId >= T2_FIRST_ID && appId <= T2_LAST_ID) {
frskyData.hub.temperature2 = SPORT_DATA_S32(packet);
if (frskyData.hub.temperature2 > frskyData.hub.maxTemperature2)
frskyData.hub.maxTemperature2 = frskyData.hub.temperature2;
}
else if (appId >= RPM_FIRST_ID && appId <= RPM_LAST_ID) {
frskyData.hub.rpm = SPORT_DATA_U32(packet) / (g_model.frsky.blades+2);
if (frskyData.hub.rpm > frskyData.hub.maxRpm)
frskyData.hub.maxRpm = frskyData.hub.rpm;
}
else if (appId >= FUEL_FIRST_ID && appId <= FUEL_LAST_ID) {
frskyData.hub.fuelLevel = SPORT_DATA_U32(packet);
}
else if (appId >= ALT_FIRST_ID && appId <= ALT_LAST_ID) {
setBaroAltitude(SPORT_DATA_S32(packet));
}
else if (appId >= VARIO_FIRST_ID && appId <= VARIO_LAST_ID) {
frskyData.hub.varioSpeed = SPORT_DATA_S32(packet);
}
else if (appId >= ACCX_FIRST_ID && appId <= ACCX_LAST_ID) {
frskyData.hub.accelX = SPORT_DATA_S32(packet);
}
else if (appId >= ACCY_FIRST_ID && appId <= ACCY_LAST_ID) {
frskyData.hub.accelY = SPORT_DATA_S32(packet);
}
else if (appId >= ACCZ_FIRST_ID && appId <= ACCZ_LAST_ID) {
frskyData.hub.accelZ = SPORT_DATA_S32(packet);
}
else if (appId >= CURR_FIRST_ID && appId <= CURR_LAST_ID) {
frskyData.hub.current = SPORT_DATA_U32(packet);
if (((int16_t)frskyData.hub.current + g_model.frsky.fasOffset)>0)
frskyData.hub.current += g_model.frsky.fasOffset;
else
frskyData.hub.current = 0;
if (frskyData.hub.current > frskyData.hub.maxCurrent)
frskyData.hub.maxCurrent = frskyData.hub.current;
}
else if (appId >= VFAS_FIRST_ID && appId <= VFAS_LAST_ID) {
frskyData.hub.vfas = SPORT_DATA_U32(packet)/10; //TODO: remove /10 and display with PREC2 when using SPORT
if (!frskyData.hub.minVfas || frskyData.hub.vfas < frskyData.hub.minVfas)
frskyData.hub.minVfas = frskyData.hub.vfas;
}
else if (appId >= AIR_SPEED_FIRST_ID && appId <= AIR_SPEED_LAST_ID) {
frskyData.hub.airSpeed = SPORT_DATA_U32(packet);
if (frskyData.hub.airSpeed > frskyData.hub.maxAirSpeed)
frskyData.hub.maxAirSpeed = frskyData.hub.airSpeed;
}
else if (appId >= GPS_SPEED_FIRST_ID && appId <= GPS_SPEED_LAST_ID) {
frskyData.hub.gpsSpeed_bp = (uint16_t) (SPORT_DATA_U32(packet)/1000);
if (frskyData.hub.gpsSpeed_bp > frskyData.hub.maxGpsSpeed)
frskyData.hub.maxGpsSpeed = frskyData.hub.gpsSpeed_bp;
}
else if (appId >= GPS_TIME_DATE_FIRST_ID && appId <= GPS_TIME_DATE_LAST_ID) {
uint32_t gps_time_date = SPORT_DATA_U32(packet);
if (gps_time_date & 0x000000ff) {
frskyData.hub.year = (uint16_t) ((gps_time_date & 0xff000000) >> 24);
frskyData.hub.month = (uint8_t) ((gps_time_date & 0x00ff0000) >> 16);
frskyData.hub.day = (uint8_t) ((gps_time_date & 0x0000ff00) >> 8);
}
else {
frskyData.hub.hour = (uint8_t) ((gps_time_date & 0xff000000) >> 24);
frskyData.hub.min = (uint8_t) ((gps_time_date & 0x00ff0000) >> 16);
frskyData.hub.sec = (uint16_t) ((gps_time_date & 0x0000ff00) >> 8);
frskyData.hub.hour = ((uint8_t) (frskyData.hub.hour + g_eeGeneral.timezone + 24)) % 24;
}
}
}
else if (appId >= GPS_LONG_LATI_FIRST_ID && appId <= GPS_LONG_LATI_LAST_ID) {
uint32_t gps_long_lati_data = SPORT_DATA_U32(packet);
uint32_t gps_long_lati_b1w, gps_long_lati_a1w;
gps_long_lati_b1w = (gps_long_lati_data & 0x3fffffff) / 10000;
gps_long_lati_a1w = (gps_long_lati_data & 0x3fffffff) % 10000;
switch ((gps_long_lati_data & 0xc0000000) >> 30) {
case 0:
frskyData.hub.gpsLatitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLatitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLatitudeNS = 'N';
break;
case 1:
frskyData.hub.gpsLatitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLatitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLatitudeNS = 'S';
break;
case 2:
frskyData.hub.gpsLongitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLongitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLongitudeEW = 'E';
break;
case 3:
frskyData.hub.gpsLongitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLongitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLongitudeEW = 'W';
break;
else if (appId >= GPS_COURS_FIRST_ID && appId <= GPS_COURS_LAST_ID) {
uint32_t course = SPORT_DATA_U32(packet);
frskyData.hub.gpsCourse_bp = course / 100;
frskyData.hub.gpsCourse_ap = course % 100;
}
if (frskyData.hub.gpsLongitudeEW && frskyData.hub.gpsLatitudeNS) {
frskyData.hub.gpsFix = 1;
}
else if (frskyData.hub.gpsFix > 0) {
frskyData.hub.gpsFix = 0;
}
}
else if (appId >= A3_FIRST_ID && appId <= A3_LAST_ID) {
frskyData.analog[TELEM_ANA_A3].set((SPORT_DATA_U32(packet)*255+165)/330, UNIT_VOLTS);
}
else if (appId >= A4_FIRST_ID && appId <= A4_LAST_ID) {
frskyData.analog[TELEM_ANA_A4].set((SPORT_DATA_U32(packet)*255+165)/330, UNIT_VOLTS);
}
else if (appId >= CELLS_FIRST_ID && appId <= CELLS_LAST_ID) {
uint32_t data = SPORT_DATA_U32(packet);
uint8_t battnumber = data & 0xF;
uint8_t cells = (data & 0xF0) >> 4;
bool useSecondCell = (battnumber+1 < cells);
else if (appId >= GPS_ALT_FIRST_ID && appId <= GPS_ALT_LAST_ID) {
frskyData.hub.gpsAltitude = SPORT_DATA_S32(packet);
if (dataId == DATA_ID_FLVSS) {
// first sensor, remember its cell count
frskyData.hub.sensorCellsCount[0] = cells;
cells += frskyData.hub.sensorCellsCount[1];
}
else {
// second sensor connected
frskyData.hub.sensorCellsCount[1] = cells;
cells += frskyData.hub.sensorCellsCount[0];
battnumber += frskyData.hub.sensorCellsCount[0];
}
if (!frskyData.hub.gpsAltitudeOffset)
frskyData.hub.gpsAltitudeOffset = -frskyData.hub.gpsAltitude;
if (cells != frskyData.hub.cellsCount) {
frskySetCellsCount(cells);
}
if (!frskyData.hub.baroAltitudeOffset) {
int altitude = TELEMETRY_RELATIVE_GPS_ALT_BP;
if (altitude > frskyData.hub.maxAltitude)
frskyData.hub.maxAltitude = altitude;
if (altitude < frskyData.hub.minAltitude)
frskyData.hub.minAltitude = altitude;
}
frskySetCellVoltage(battnumber, (frskyCellVoltage_t) ((data & 0x000FFF00) >> 8) / 5);
if (useSecondCell) {
frskySetCellVoltage(battnumber+1, (frskyCellVoltage_t) ((data & 0xFFF00000) >> 20) / 5);
if (frskyData.hub.gpsFix > 0) {
if (!frskyData.hub.pilotLatitude && !frskyData.hub.pilotLongitude) {
// First received GPS position => Pilot GPS position
getGpsPilotPosition();
}
else if (frskyData.hub.gpsDistNeeded || g_menuStack[g_menuStackPtr] == menuTelemetryFrsky) {
getGpsDistance();
}
}
}
else if (appId >= GPS_LONG_LATI_FIRST_ID && appId <= GPS_LONG_LATI_LAST_ID) {
uint32_t gps_long_lati_data = SPORT_DATA_U32(packet);
uint32_t gps_long_lati_b1w, gps_long_lati_a1w;
gps_long_lati_b1w = (gps_long_lati_data & 0x3fffffff) / 10000;
gps_long_lati_a1w = (gps_long_lati_data & 0x3fffffff) % 10000;
switch ((gps_long_lati_data & 0xc0000000) >> 30) {
case 0:
frskyData.hub.gpsLatitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLatitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLatitudeNS = 'N';
break;
case 1:
frskyData.hub.gpsLatitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLatitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLatitudeNS = 'S';
break;
case 2:
frskyData.hub.gpsLongitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLongitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLongitudeEW = 'E';
break;
case 3:
frskyData.hub.gpsLongitude_bp = (gps_long_lati_b1w / 60 * 100) + (gps_long_lati_b1w % 60);
frskyData.hub.gpsLongitude_ap = gps_long_lati_a1w;
frskyData.hub.gpsLongitudeEW = 'W';
break;
}
if (frskyData.hub.gpsLongitudeEW && frskyData.hub.gpsLatitudeNS) {
frskyData.hub.gpsFix = 1;
}
else if (frskyData.hub.gpsFix > 0) {
frskyData.hub.gpsFix = 0;
}
}
else if (appId >= A3_FIRST_ID && appId <= A3_LAST_ID) {
frskyData.analog[TELEM_ANA_A3].set((SPORT_DATA_U32(packet)*255+165)/330, UNIT_VOLTS);
}
else if (appId >= A4_FIRST_ID && appId <= A4_LAST_ID) {
frskyData.analog[TELEM_ANA_A4].set((SPORT_DATA_U32(packet)*255+165)/330, UNIT_VOLTS);
}
else if (appId >= CELLS_FIRST_ID && appId <= CELLS_LAST_ID) {
uint32_t data = SPORT_DATA_U32(packet);
uint8_t battnumber = data & 0xF;
uint8_t cells = (data & 0xF0) >> 4;
bool useSecondCell = (battnumber+1 < cells);
if (dataId == DATA_ID_FLVSS) {
// first sensor, remember its cell count
frskyData.hub.sensorCellsCount[0] = cells;
cells += frskyData.hub.sensorCellsCount[1];
}
else {
// second sensor connected
frskyData.hub.sensorCellsCount[1] = cells;
cells += frskyData.hub.sensorCellsCount[0];
battnumber += frskyData.hub.sensorCellsCount[0];
}
if (cells != frskyData.hub.cellsCount) {
frskySetCellsCount(cells);
}
frskySetCellVoltage(battnumber, (frskyCellVoltage_t) ((data & 0x000FFF00) >> 8) / 5);
if (useSecondCell) {
frskySetCellVoltage(battnumber+1, (frskyCellVoltage_t) ((data & 0xFFF00000) >> 20) / 5);
}
}
}
break;
+15 -12
View File
@@ -41,6 +41,10 @@
#define SWAP_DEFINED
#include "opentx.h"
#define TELEMETRY_RESET() \
memclear(&frskyData, sizeof(frskyData)); \
frskyData.rssi[0].value = 100
extern bool checkScreenshot(QString test);
#if defined(FRSKY) && !defined(FRSKY_SPORT)
@@ -175,10 +179,11 @@ void generateSportCellPacket(uint8_t * packet, uint8_t cells, uint8_t battnumber
TEST(FrSkySPORT, frskySetCellVoltage)
{
memclear(&frskyData, sizeof(frskyData));
uint8_t packet[FRSKY_SPORT_PACKET_SIZE];
//test that simulates 3 cell battery
TELEMETRY_RESET();
// test that simulates 3 cell battery
generateSportCellPacket(packet, 3, 0, _V(410), _V(420)); frskySportProcessPacket(packet);
EXPECT_EQ(checkSportPacket(packet), true) << "Bad CRC generation in setSportPacketCrc()";
generateSportCellPacket(packet, 3, 2, _V(430), _V( 0)); frskySportProcessPacket(packet);
@@ -272,7 +277,7 @@ TEST(FrSkySPORT, frskySetCellVoltage)
TEST(FrSkySPORT, StrangeCellsBug)
{
memclear(&frskyData, sizeof(frskyData));
TELEMETRY_RESET();
uint8_t pkt[] = { 0x7E, 0x48, 0x10, 0x00, 0x03, 0x30, 0x15, 0x50, 0x81, 0xD5 };
EXPECT_EQ(checkSportPacket(pkt+1), true);
frskySportProcessPacket(pkt+1);
@@ -283,10 +288,10 @@ TEST(FrSkySPORT, StrangeCellsBug)
TEST(FrSkySPORT, frskySetCellVoltageTwoSensors)
{
//telemetryReset();
memclear(&frskyData, sizeof(frskyData));
uint8_t packet[FRSKY_SPORT_PACKET_SIZE];
TELEMETRY_RESET();
//sensor 1: 3 cell battery
generateSportCellPacket(packet, 3, 0, _V(418), _V(416)); frskySportProcessPacket(packet);
generateSportCellPacket(packet, 3, 2, _V(415), _V( 0)); frskySportProcessPacket(packet);
@@ -366,7 +371,7 @@ TEST(FrSkySPORT, frskyVfas)
uint8_t packet[FRSKY_SPORT_PACKET_SIZE];
//telemetryReset();
memclear(&frskyData, sizeof(frskyData));
TELEMETRY_RESET();
// tests for Vfas
generateSportFasVoltagePacket(packet, 5000); frskySportProcessPacket(packet);
@@ -399,8 +404,7 @@ TEST(FrSkySPORT, frskyCurrent)
{
uint8_t packet[FRSKY_SPORT_PACKET_SIZE];
//telemetryReset();
memclear(&frskyData, sizeof(frskyData));
TELEMETRY_RESET();
g_model.frsky.fasOffset = -5; /* unit: 1/10 amps */
// tests for Curr
@@ -408,7 +412,7 @@ TEST(FrSkySPORT, frskyCurrent)
EXPECT_EQ(frskyData.hub.current, 0);
EXPECT_EQ(frskyData.hub.maxCurrent, 0);
//measured current less then offset - value should be zero
// measured current less then offset - value should be zero
generateSportFasCurrentPacket(packet, 4); frskySportProcessPacket(packet);
EXPECT_EQ(frskyData.hub.current, 0);
EXPECT_EQ(frskyData.hub.maxCurrent, 0);
@@ -425,9 +429,8 @@ TEST(FrSkySPORT, frskyCurrent)
EXPECT_EQ(frskyData.hub.current, 195);
EXPECT_EQ(frskyData.hub.maxCurrent, 495);
//test with positive offset
//telemetryReset();
memclear(&frskyData, sizeof(frskyData));
// test with positive offset
TELEMETRY_RESET();
g_model.frsky.fasOffset = 5; /* unit: 1/10 amps */
generateSportFasCurrentPacket(packet, 0); frskySportProcessPacket(packet);
-1
View File
@@ -183,7 +183,6 @@ int main(int argc, char **argv)
StartEepromThread(NULL);
g_menuStackPtr = 0;
g_menuStack[0] = menuMainView;
LUA_RESET();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+49
View File
@@ -52,6 +52,8 @@ extern const char * zchar2string(const char * zstring, int size);
void luaExecStr(const char * str)
{
extern lua_State * L;
if (!L) luaInit();
if (!L) FAIL() << "No Lua state!";
if (luaL_dostring(L, str)) {
FAIL() << "lua error: " << lua_tostring(L, -1);
}
@@ -98,4 +100,51 @@ TEST(Lua, testSetTelemetryChannel)
}
TEST(Lua, testPanicProtection)
{
bool passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
//simulate panic
longjmp(global_lj->b, 1);
}
else {
//we should come here
passed = true;
}
UNPROTECT_LUA();
}
else {
// an not here
// TRACE("testLuaProtection: test 1 FAILED");
FAIL() << "Failed test 1";
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
int a = 5;
a = a; // avoids the warning
}
else {
//we should not come here
// TRACE("testLuaProtection: test 2 FAILED");
FAIL() << "Failed test 2";
}
UNPROTECT_LUA()
//simulate panic
longjmp(global_lj->b, 1);
}
else {
// we should come here
passed = true;
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
}
#endif
Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 980 B

+2 -2
View File
@@ -516,7 +516,7 @@
#define TR_ELIMITS TR("Limites ét", "Limites étendues")
#define TR_ETRIMS TR("Trims ét.", "Trims étendus")
#define TR_TRIMINC TR("Pas Trim", "Pas des trims")
#define TR_TTRACE TR("Source gaz", INDENT "Source gaz")
#define TR_TTRACE TR("Src\001chrnos", INDENT "Source chronos")
#define TR_TTRIM TR("Trim gaz", INDENT "Trim ralenti uniq.")
#define TR_BEEPCTR TR("Bips centr", "Bips centrage")
#define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole")
@@ -613,7 +613,7 @@
#define OFS_RX 4
#define TR_ACCEL "Acc:"
#define TR_NODATA "NO DATA"
#define TR_TOTTM1TM2THRTHP "\037\146TOT\036TM1\037\146TM2\036THR\037\146TH%"
#define TR_TOTTM1TM2THRTHP "\037\146TOT\036TM1\037\146TM2\036000GAZ\037\146GZ%"
#define TR_TMR1LATMAXUS "Tmr1Lat max\037\124us"
#define STR_US (STR_TMR1LATMAXUS+13)
#define TR_TMR1LATMINUS "Tmr1Lat min\037\124us"
+43 -8
View File
@@ -6,6 +6,7 @@ import sys
import os
import traceback
import time
import re
PREC1 = 10
PREC2 = 100
@@ -57,11 +58,22 @@ def LEXP_EXTRA(name, description, value, condition = "true"):
# extra also added to normal items to enable searching
exports.append( (CONSTANT_VALUE, name, description) )
if len(sys.argv) < 3:
print "Error: not enough arguments!"
print "Usage:"
print " luaexport.py <version> <input txt> <output cpp> [<doc output>]"
inputFile = sys.argv[1]
outputFile = sys.argv[2]
version = sys.argv[1]
inputFile = sys.argv[2]
outputFile = sys.argv[3]
docFile = None
if len(sys.argv) >= 4:
docFile = sys.argv[4]
print "Version %s" % version
print "Input file %s" % inputFile
print "Output file %s" % outputFile
if docFile:
print "Documentation file %s" % docFile
inp = open(inputFile, "r")
@@ -102,7 +114,8 @@ inp.close()
out = open(outputFile, "w")
out.write("//This file was generated by luaexport.py script on %s\n\n\n" % time.asctime())
out.write("//This file was generated by luaexport.py script on %s for OpenTX version %s\n\n\n"
% ( time.asctime(), version))
header = """
struct LuaSingleField {
@@ -153,8 +166,8 @@ case_body = "\n".join(case_clauses)
func_body = """
extern lua_State *L;
// The handling of extra Lua fileds that are not
// accesible by the getValue()
// The handling of extra Lua fields that are not
// accessible by the getValue()
static int luaGetExtraValue(int src)
{
switch (src) {
@@ -165,11 +178,33 @@ static int luaGetExtraValue(int src)
""" % case_body
out.write(func_body)
print "Generated %d condtions in luaGetExtraValue()" % len(exports_extra)
print "Generated %d conditions in luaGetExtraValue()" % len(exports_extra)
out.close()
if docFile:
#prepare fields
all_exports = [(name, desc) for (id, name, desc) in exports]
for (id, nameFormat, descriptionFormat, valuesCount) in exports_multiple:
for v in range(valuesCount):
name = nameFormat + str(v)
desc = descriptionFormat % v
all_exports.append( (name, desc) )
#natural sort by field name
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key[0]) ]
all_exports.sort(key = alphanum_key)
out = open(docFile, "w")
out.write("Alphabetical list of Lua fields for OpenTX version %s\n\n\n" % version)
FIELD_NAME_WIDTH = 25
out.write("Field name%sField description\n" % (' '*(FIELD_NAME_WIDTH-len('Field name'))))
out.write("----------------------------------------------\n")
data = ["%s%s%s" % (name, ' '*(FIELD_NAME_WIDTH-len(name)) , desc) for (name, desc) in all_exports]
out.write("\n".join(data))
out.write("\n")
out.close()
if warning:
sys.exit(1)
elif error: