Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6114245229 | |||
| e76880cf26 | |||
| f30dfa3365 | |||
| f4aa92ec20 | |||
| 2640ca9fea | |||
| f6a1420ce3 | |||
| 6c0f65411a | |||
| a7f1ace55b | |||
| b8dedd7940 | |||
| 2703118c56 | |||
| 8bfc7a497a | |||
| 87870c24a5 | |||
| 7610fb43d5 | |||
| 0263784e65 | |||
| 6f74624371 | |||
| 1c721b3817 | |||
| 67d97046bb | |||
| 19d9e6ab19 | |||
| 5d9883d47f | |||
| bb5f1d7d79 | |||
| 30087b4a3a | |||
| 61aa01b9b3 | |||
| 16e06cff70 | |||
| 2073a1f033 | |||
| 563b817b46 | |||
| 8b540a66f6 | |||
| b0b7657756 | |||
| 74d22b623f | |||
| bee01d9999 | |||
| d2055edf62 | |||
| c926ac557b | |||
| 3e2092e32f | |||
| 21054ffc54 | |||
| 350ece0b60 | |||
| 01a103f2e6 | |||
| 2e8e439d27 | |||
| 98e6a3dc21 | |||
| 3b324d076a | |||
| 91c922d5fb | |||
| eac918c2da | |||
| b5f9c0ec84 | |||
| d1f54b099b | |||
| 7b98ad55c0 | |||
| d2cb7cb3dd | |||
| be190b8bb1 | |||
| 4b2c02b2c5 | |||
| 142d3fee1a | |||
| 6a5e938ead | |||
| 2d9ae108ff | |||
| bae84e4e8c | |||
| f4944eefdb | |||
| 5d598cc6a1 | |||
| 945808d69b | |||
| dbe512e45a | |||
| 11efb5121e | |||
| f6274f38aa | |||
| cd1f20b8a0 | |||
| e61b931ddb | |||
| a7a9b61234 | |||
| 5ee95673d1 | |||
| 98c5b5e7bd | |||
| 6d434c0bf9 | |||
| ade7151796 | |||
| a7cd1f9aa0 | |||
| cb2c922542 | |||
| 8159a559da | |||
| ed826d8c62 | |||
| b57f5ab2ce | |||
| 8fbafa6f05 | |||
| 9243a59426 | |||
| ccf66831c7 | |||
| 06792b5696 | |||
| 6d4d871849 | |||
| 5a634a7991 | |||
| 69e504212e | |||
| 03e049c360 | |||
| 4ca893da1f | |||
| 66670cf713 | |||
| 271bb4a82e | |||
| e0eab648ef | |||
| 3235f43db9 | |||
| c12b0cfebe | |||
| 3e590d44f0 | |||
| 1f6d1799af | |||
| 8c813a87c9 | |||
| 5bdeedbd0e | |||
| e33f4cf415 | |||
| 61d745011a | |||
| 3e269a04ae | |||
| 341feaf78f | |||
| 19ddf6fc23 | |||
| 9b4b0d3c83 | |||
| dc1eebf40d | |||
| 752e13b9ab | |||
| b988bec5bd | |||
| 3c72afed20 | |||
| e7586f47c3 | |||
| f126b149f0 | |||
| 6b15c0c985 | |||
| db85f39ebc | |||
| dee1e4ce8d | |||
| df96504a85 | |||
| 0112a1e3e9 |
@@ -566,3 +566,39 @@ 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
|
||||
Jeff Theobald
|
||||
Anthony Rizzo
|
||||
Rodney Huddleston
|
||||
Dietmar Drees
|
||||
Jürgen Monden
|
||||
David Morgan
|
||||
Andrew Fernie
|
||||
Michel Baily
|
||||
Donald Burke
|
||||
Ronald Donker
|
||||
Fredie Singh
|
||||
Patrizio Simoncini (monthly)
|
||||
Harald Gabler
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
<h2>Version 2.0.9</h2>
|
||||
<h2>Version 2.0.12 / 2014-09-15</h2>
|
||||
<ul>
|
||||
<li>Taranis is now the default board in General Settings</li>
|
||||
<li>Typos & Translations updated</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.8</h2>
|
||||
<h2>Version 2.0.11 / 2014-09-10</h2>
|
||||
<ul>
|
||||
<li>Limits EEPROM export was broken (all boards except Taranis)</li>
|
||||
<li>Fix issue when a GVAR was used as Offset</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.10 / 2014-09-08</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 / 2014-07-23</h2>
|
||||
<ul>
|
||||
<li>Compare dialog bugfixes</li>
|
||||
<li>Curve index correctly resetted when type changed</li>
|
||||
|
||||
@@ -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 "12" )
|
||||
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
|
||||
@@ -301,7 +301,7 @@ RawSourceRange RawSource::getRange(const ModelData & model, const GeneralSetting
|
||||
break;
|
||||
|
||||
default:
|
||||
result.max = (model.extendedLimits ? 125 : 100);
|
||||
result.max = model.getChannelsMax(true);
|
||||
result.min = -result.max;
|
||||
break;
|
||||
}
|
||||
@@ -460,7 +460,7 @@ QString RawSwitch::toString()
|
||||
};
|
||||
|
||||
static const QString timerModes[] = {
|
||||
QObject::tr("OFF"), QObject::tr("ABS"),
|
||||
QObject::tr("OFF"), QObject::tr("ON"),
|
||||
QObject::tr("THs"), QObject::tr("TH%"), QObject::tr("THt")
|
||||
};
|
||||
|
||||
@@ -723,7 +723,7 @@ void FuncSwData::clear()
|
||||
QString FuncSwData::funcToString()
|
||||
{
|
||||
ModelData model;
|
||||
if (func >= FuncSafetyCh1 && func <= FuncSafetyCh32)
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
|
||||
return QObject::tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return QObject::tr("Trainer");
|
||||
@@ -1309,9 +1309,9 @@ ModelData ModelData::removeGlobalVars()
|
||||
return result;
|
||||
}
|
||||
|
||||
int ModelData::getChannelsMax()
|
||||
int ModelData::getChannelsMax(bool forceExtendedLimits) const
|
||||
{
|
||||
if (extendedLimits)
|
||||
if (forceExtendedLimits || extendedLimits)
|
||||
return IS_TARANIS(GetCurrentFirmware()->getBoard()) ? 150 : 125;
|
||||
else
|
||||
return 100;
|
||||
|
||||
@@ -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;
|
||||
@@ -725,8 +727,8 @@ class LogicalSwitchData { // Logical Switches data
|
||||
};
|
||||
|
||||
enum AssignFunc {
|
||||
FuncSafetyCh1 = 0,
|
||||
FuncSafetyCh32 = FuncSafetyCh1+C9X_NUM_CHNOUT-1,
|
||||
FuncOverrideCH1 = 0,
|
||||
FuncOverrideCH32 = FuncOverrideCH1+C9X_NUM_CHNOUT-1,
|
||||
FuncTrainer,
|
||||
FuncTrainerRUD,
|
||||
FuncTrainerELE,
|
||||
@@ -755,7 +757,7 @@ enum AssignFunc {
|
||||
|
||||
class FuncSwData { // Function Switches data
|
||||
public:
|
||||
FuncSwData(AssignFunc func=FuncSafetyCh1) { clear(); this->func = func; }
|
||||
FuncSwData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
|
||||
RawSwitch swtch;
|
||||
AssignFunc func;
|
||||
int param;
|
||||
@@ -1043,7 +1045,7 @@ class ModelData {
|
||||
void clearMixes();
|
||||
void clearInputs();
|
||||
|
||||
int getChannelsMax();
|
||||
int getChannelsMax(bool forceExtendedLimits=false) const;
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
@@ -1129,6 +1131,7 @@ enum Capability {
|
||||
HasSoundMixer,
|
||||
NumModules,
|
||||
PPMCenter,
|
||||
PPMUnitMicroseconds,
|
||||
SYMLimits,
|
||||
HasCurrentCalibration,
|
||||
HasVolume,
|
||||
|
||||
@@ -576,7 +576,7 @@ t_Open9xArmFuncSwData_v208::operator FuncSwData ()
|
||||
FuncSwData c9x;
|
||||
c9x.swtch = open9xArmToSwitch(swtch);
|
||||
c9x.func = (AssignFunc)(func);
|
||||
if (c9x.func <= FuncSafetyCh32) {
|
||||
if (c9x.func <= FuncOverrideCH32) {
|
||||
c9x.enabled=param & 0x01;
|
||||
c9x.param = (param>>1)<<1;
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ inline int geteepromsize() {
|
||||
#include "radio/src/lua/src/lstate.c"
|
||||
#include "radio/src/lua/src/lstring.c"
|
||||
#include "radio/src/lua/src/ltable.c"
|
||||
#include "radio/src/lua/src/lrotable.c"
|
||||
#include "radio/src/lua/src/ltm.c"
|
||||
#include "radio/src/lua/src/lundump.c"
|
||||
#include "radio/src/lua/src/lvm.c"
|
||||
@@ -156,6 +157,7 @@ inline int geteepromsize() {
|
||||
#include "radio/src/lua/src/lbaselib.c"
|
||||
#include "radio/src/lua/src/linit.c"
|
||||
#include "radio/src/lua/src/lmathlib.c"
|
||||
#include "radio/src/lua/src/lbitlib.c"
|
||||
#include "radio/src/lua/src/loadlib.c"
|
||||
#include "radio/src/lua/src/lauxlib.c"
|
||||
#include "radio/src/lua/src/ltablib.c"
|
||||
|
||||
@@ -1039,6 +1039,8 @@ class MixField: public TransformedField {
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarToC9x(_curveParam));
|
||||
else if (_curveParam > 6)
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6);
|
||||
else if (_curveParam < 0)
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam);
|
||||
else
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam);
|
||||
}
|
||||
@@ -1098,7 +1100,7 @@ class InputField: public TransformedField {
|
||||
internalField.Append(new SignedField<6>(expo.carryTrim, "CarryTrim"));
|
||||
internalField.Append(new UnsignedField<2>(expo.mode, "Mode"));
|
||||
internalField.Append(new ZCharField<8>(expo.name));
|
||||
internalField.Append(new SignedField<8>(expo.offset, "Offset"));
|
||||
internalField.Append(new SignedField<8>(_offset, "Offset"));
|
||||
internalField.Append(new CurveReferenceField(expo.curve, board, version));
|
||||
internalField.Append(new SpareBitsField<8>());
|
||||
}
|
||||
@@ -1151,7 +1153,11 @@ class InputField: public TransformedField {
|
||||
|
||||
virtual void beforeExport()
|
||||
{
|
||||
_weight = smallGvarToEEPROM(expo.weight);
|
||||
_weight = smallGvarToEEPROM(expo.weight);
|
||||
|
||||
if (IS_TARANIS(board) && version >= 216) {
|
||||
_offset = smallGvarToEEPROM(expo.offset);
|
||||
}
|
||||
|
||||
if (!IS_TARANIS(board) || version < 216) {
|
||||
if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) {
|
||||
@@ -1184,6 +1190,10 @@ class InputField: public TransformedField {
|
||||
|
||||
expo.weight = smallGvarToC9x(_weight);
|
||||
|
||||
if (IS_TARANIS(board) && version >= 216) {
|
||||
expo.offset = smallGvarToC9x(_offset);
|
||||
}
|
||||
|
||||
if (!IS_TARANIS(board) || version < 216) {
|
||||
if (!_curveMode)
|
||||
expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarToC9x(_curveParam));
|
||||
@@ -1201,24 +1211,49 @@ class InputField: public TransformedField {
|
||||
unsigned int version;
|
||||
bool _curveMode;
|
||||
int _weight;
|
||||
int _offset;
|
||||
int _curveParam;
|
||||
};
|
||||
|
||||
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)) {
|
||||
@@ -1833,10 +1868,10 @@ class ArmCustomFunctionField: public TransformedField {
|
||||
else
|
||||
_active = (fn.enabled ? 1 : 0);
|
||||
|
||||
if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) {
|
||||
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
|
||||
if (version >= 216) {
|
||||
*((uint16_t *)_param) = fn.param;
|
||||
*((uint8_t *)(_param+3)) = fn.func - FuncSafetyCh1;
|
||||
*((uint8_t *)(_param+3)) = fn.func - FuncOverrideCH1;
|
||||
}
|
||||
else {
|
||||
*((uint32_t *)_param) = fn.param;
|
||||
@@ -1915,7 +1950,7 @@ class ArmCustomFunctionField: public TransformedField {
|
||||
value = *((uint32_t *)_param);
|
||||
}
|
||||
|
||||
if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) {
|
||||
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
|
||||
fn.func = AssignFunc(fn.func + index);
|
||||
fn.param = (int8_t)value;
|
||||
}
|
||||
@@ -2020,9 +2055,9 @@ class AvrCustomFunctionField: public TransformedField {
|
||||
_param = fn.param;
|
||||
_active = (fn.enabled ? 1 : 0);
|
||||
|
||||
if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) {
|
||||
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
|
||||
if (version >= 216)
|
||||
_union_param = fn.func - FuncSafetyCh1;
|
||||
_union_param = fn.func - FuncOverrideCH1;
|
||||
else if (version >= 213)
|
||||
_active += ((fn.func % 4) << 1);
|
||||
}
|
||||
@@ -2080,7 +2115,7 @@ class AvrCustomFunctionField: public TransformedField {
|
||||
fn.enabled = (_active & 0x01);
|
||||
}
|
||||
|
||||
if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) {
|
||||
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
|
||||
if (version >= 216)
|
||||
fn.func = AssignFunc(fn.func + _union_param);
|
||||
else if (version >= 213)
|
||||
@@ -2790,8 +2825,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:
|
||||
|
||||
@@ -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
-15
@@ -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(mini);
|
||||
sb->setMaximum(maxi);
|
||||
sb->setValue(val);
|
||||
}
|
||||
else {
|
||||
dsb->setMinimum(mini*step);
|
||||
dsb->setMaximum(maxi*step);
|
||||
dsb->setValue(val*step);
|
||||
}
|
||||
|
||||
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();
|
||||
else
|
||||
weight = dsb->value()/step;
|
||||
}
|
||||
}
|
||||
|
||||
CurveGroup::CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags):
|
||||
@@ -1004,7 +1022,6 @@ QString index2version(int index)
|
||||
|
||||
int qunlink(const QString & fileName)
|
||||
{
|
||||
qDebug() << "unlinking "<< fileName;
|
||||
QByteArray ba = fileName.toLatin1();
|
||||
return unlink(ba.constData());
|
||||
}
|
||||
|
||||
@@ -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.0, 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "channels.h"
|
||||
#include "helpers.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
@@ -6,6 +7,70 @@
|
||||
#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),
|
||||
displayStep(0.1)
|
||||
{
|
||||
bool allowGVars = false;
|
||||
int internalStep = 1;
|
||||
|
||||
spinbox->setProperty("index", row);
|
||||
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
spinbox->setAccelerated(true);
|
||||
|
||||
if (firmware->getCapability(PPMUnitMicroseconds)) {
|
||||
displayStep = 0.512;
|
||||
spinbox->setDecimals(1);
|
||||
spinbox->setSuffix("us");
|
||||
}
|
||||
else {
|
||||
spinbox->setDecimals(0);
|
||||
spinbox->setSuffix("%");
|
||||
}
|
||||
|
||||
if (IS_TARANIS(firmware->getBoard()) || deflt == 0 /*it's the offset*/) {
|
||||
spinbox->setDecimals(1);
|
||||
allowGVars = true;
|
||||
}
|
||||
else {
|
||||
internalStep *= 10;
|
||||
}
|
||||
|
||||
spinbox->setSingleStep(displayStep*internalStep);
|
||||
|
||||
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, displayStep, allowGVars);
|
||||
}
|
||||
|
||||
LimitsGroup::~LimitsGroup()
|
||||
{
|
||||
delete gvarGroup;
|
||||
}
|
||||
|
||||
void LimitsGroup::updateMinMax(int max)
|
||||
{
|
||||
if (spinbox->maximum() == 0) {
|
||||
spinbox->setMinimum(-max*displayStep);
|
||||
if (value < -max) {
|
||||
value = -max;
|
||||
}
|
||||
}
|
||||
if (spinbox->minimum() == 0) {
|
||||
spinbox->setMaximum(max*displayStep);
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware):
|
||||
ModelPanel(parent, model, generalSettings, firmware)
|
||||
{
|
||||
@@ -13,8 +78,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 +116,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, -1000, 1000, 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()*10, 0, -1000);
|
||||
|
||||
// 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()*10, 1000);
|
||||
|
||||
// Channel inversion
|
||||
QComboBox * invCB = new QComboBox(this);
|
||||
@@ -117,6 +150,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 +168,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 +177,9 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
|
||||
Channels::~Channels()
|
||||
{
|
||||
foreach(LimitsGroup *group, limitsGroups) {
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
|
||||
void Channels::symlimitsEdited()
|
||||
@@ -164,46 +202,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(10*channelMax);
|
||||
}
|
||||
|
||||
emit modified();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 displayStep;
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
@@ -318,11 +318,12 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
|
||||
int index = fswtchFunc[i]->currentIndex();
|
||||
|
||||
if (index>=FuncSafetyCh1 && index<=FuncSafetyCh32) {
|
||||
if (index>=FuncOverrideCH1 && index<=FuncOverrideCH32) {
|
||||
int channelsMax = model.getChannelsMax(true);
|
||||
fswtchParam[i]->setDecimals(0);
|
||||
fswtchParam[i]->setSingleStep(1);
|
||||
fswtchParam[i]->setMinimum(-125);
|
||||
fswtchParam[i]->setMaximum(125);
|
||||
fswtchParam[i]->setMinimum(-channelsMax);
|
||||
fswtchParam[i]->setMaximum(channelsMax);
|
||||
if (modified) {
|
||||
model.funcSw[i].param = fswtchParam[i]->value();
|
||||
}
|
||||
@@ -590,7 +591,7 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
|
||||
b->clear();
|
||||
for (unsigned int i=0; i<FuncCount; i++) {
|
||||
b->addItem(FuncSwData(AssignFunc(i)).funcToString());
|
||||
if (((i>=FuncSafetyCh1 && i<=FuncSafetyCh32) && !firmware->getCapability(SafetyChannelCustomFunction)) ||
|
||||
if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && !firmware->getCapability(SafetyChannelCustomFunction)) ||
|
||||
((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) ||
|
||||
((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
|
||||
((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
|
||||
|
||||
@@ -11,6 +11,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
ModelPanel(parent, model, generalSettings, firmware),
|
||||
selectedSwitch(0)
|
||||
{
|
||||
int channelsMax = model.getChannelsMax(true);
|
||||
|
||||
QGridLayout * gridLayout = new QGridLayout(this);
|
||||
|
||||
int col = 1;
|
||||
@@ -48,8 +50,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
gridLayout->addWidget(cswitchSource1[i], i+1, 2);
|
||||
cswitchSource1[i]->setVisible(false);
|
||||
cswitchValue[i] = new QDoubleSpinBox(this);
|
||||
cswitchValue[i]->setMaximum(125);
|
||||
cswitchValue[i]->setMinimum(-125);
|
||||
cswitchValue[i]->setMaximum(channelsMax);
|
||||
cswitchValue[i]->setMinimum(-channelsMax);
|
||||
cswitchValue[i]->setAccelerated(true);
|
||||
cswitchValue[i]->setDecimals(0);
|
||||
cswitchValue[i]->setProperty("index", i);
|
||||
@@ -66,8 +68,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
cswitchSource2[i]->setVisible(false);
|
||||
cswitchOffset[i] = new QDoubleSpinBox(this);
|
||||
cswitchOffset[i]->setProperty("index",i);
|
||||
cswitchOffset[i]->setMaximum(125);
|
||||
cswitchOffset[i]->setMinimum(-125);
|
||||
cswitchOffset[i]->setMaximum(channelsMax);
|
||||
cswitchOffset[i]->setMinimum(-channelsMax);
|
||||
cswitchOffset[i]->setAccelerated(true);
|
||||
cswitchOffset[i]->setDecimals(0);
|
||||
connect(cswitchOffset[i], SIGNAL(valueChanged(double)), this, SLOT(edited()));
|
||||
@@ -75,8 +77,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
v2Layout->addWidget(cswitchOffset[i]);
|
||||
cswitchOffset2[i] = new QDoubleSpinBox(this);
|
||||
cswitchOffset2[i]->setProperty("index",i);
|
||||
cswitchOffset2[i]->setMaximum(125);
|
||||
cswitchOffset2[i]->setMinimum(-125);
|
||||
cswitchOffset2[i]->setMaximum(channelsMax);
|
||||
cswitchOffset2[i]->setMinimum(-channelsMax);
|
||||
cswitchOffset2[i]->setAccelerated(true);
|
||||
cswitchOffset2[i]->setDecimals(0);
|
||||
connect(cswitchOffset2[i], SIGNAL(valueChanged(double)), this, SLOT(edited()));
|
||||
@@ -239,6 +241,7 @@ void LogicalSwitchesPanel::edited()
|
||||
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
|
||||
break;
|
||||
case LS_FAMILY_STAY:
|
||||
cswitchOffset2[i]->setSpecialValueText(tr("(instant)"));
|
||||
if (sender() == cswitchOffset[i]) {
|
||||
model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value());
|
||||
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
|
||||
@@ -246,10 +249,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("(release)");
|
||||
}
|
||||
else {
|
||||
cswitchOffset2[i]->setSuffix("");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -274,7 +279,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 +324,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 +332,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("(instant)"));
|
||||
if (model.customSw[i].val3 == 0) {
|
||||
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
|
||||
cswitchOffset2[i]->clear();
|
||||
cswitchOffset2[i]->setSuffix(tr("(release)"));
|
||||
}
|
||||
else {
|
||||
cswitchOffset2[i]->setSuffix("");
|
||||
}
|
||||
break;
|
||||
case LS_FAMILY_VCOMP:
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1186
-1339
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+152
-111
@@ -1,206 +1,247 @@
|
||||
<h2>Version 2.0.9 / 2014-07-28</h2>
|
||||
<h2>Version 2.0.12 / 2014-09-16</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>CPPM issue on Helis when cross trims used
|
||||
<li>Taranis+ LCD color range adjusted
|
||||
<li>LTR patch (modified) applied to the Lua code. Saves around 8-10k RAM</li>
|
||||
<li>Lua hardening again!</li>
|
||||
<li>bit32 lib added to the Lua interpreter</li>
|
||||
<li>Audio tones distorsion (just after playing a wav file)</li>
|
||||
<li>ABS changed to ON in Timers modes</li>
|
||||
<li>S2 and S3 pots inverted on Taranis+</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.11 / 2014-09-10</h2>
|
||||
[9XR-PRO]
|
||||
<ul>
|
||||
<li>Audio broken (since we changed the ARM GCC compiler)</li>
|
||||
</ul>
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Switch warning didn't allow access to SG</li>
|
||||
<li>Pot warning would show S3 when the cursor wasn't on the Pot Warning line</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.10 / 2014-09-08</h2>
|
||||
[All]
|
||||
<ul>
|
||||
<li>Duration and AND fixed on Sticky and Edge logical switches</li>
|
||||
</ul>
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>CCPM issue on Helis when cross trims used</li>
|
||||
<li>Taranis+ LCD color range and brightness adjusted</li>
|
||||
<li>Taranis+ SWR removed</li>
|
||||
<li>Lua small enhancements (TIMEHOUR constant, GVARS over 500)</li>
|
||||
<li>Lua hardening, use of newlib-nano (optimizes RAM usage)</li>
|
||||
<li>Incoming telemetry rejected if RSSI=0</li>
|
||||
<li>Assign Bitmap impossible if filename length too big</li>
|
||||
</ul>
|
||||
|
||||
[9XR-PRO]
|
||||
<ul>
|
||||
<li>Telemetry enabled</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.8 / 2014-07-23</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Curve wrongly displayed when used in an Input with a positive offset
|
||||
<li>Telemetry Channels are now accessible through Lua
|
||||
<li>New string Lua fields added for accessing sources
|
||||
<li>Trims now applied on Inputs when used in Logical Switches
|
||||
<li>Option "nojoystick" added
|
||||
<li>Curve wrongly displayed when used in an Input with a positive offset</li>
|
||||
<li>Telemetry Channels are now accessible through Lua</li>
|
||||
<li>New string Lua fields added for accessing sources</li>
|
||||
<li>Trims now applied on Inputs when used in Logical Switches</li>
|
||||
<li>Option "nojoystick" added</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.7 / 2014-07-15</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Instant Trim problem when using a negative curve
|
||||
<li>Instant Trim problem when using a negative curve</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>SafetyCH function was missing on the compilation server
|
||||
<li>SafetyCH function was missing on the compilation server</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.6 / 2014-07-13</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Telemetry Type field is hidden when only S.PORT is available
|
||||
<li>Permanent timers may be not resetted on Flight Reset
|
||||
<li>Instant Trim bugfix
|
||||
<li>No sound on trim press when trim option disabled
|
||||
<li>[Page] / [Page Long] allowed to change Telemetry screen
|
||||
<li>XXL font added for Lua telemetry screens
|
||||
<li>
|
||||
<li>Telemetry Type field is hidden when only S.PORT is available</li>
|
||||
<li>Permanent timers may be not resetted on Flight Reset</li>
|
||||
<li>Instant Trim bugfix</li>
|
||||
<li>No sound on trim press when trim option disabled</li>
|
||||
<li>[Page] / [Page Long] allowed to change Telemetry screen</li>
|
||||
<li>XXL font added for Lua telemetry screens</li>
|
||||
</ul>
|
||||
|
||||
[9XR-PRO / Sky9x]
|
||||
<ul>
|
||||
<li>RTC time was not stored correctly
|
||||
<li>PPM polarity fix
|
||||
<li>RTC time was not stored correctly</li>
|
||||
<li>PPM polarity fix</li>
|
||||
</ul>
|
||||
|
||||
[Gruvin9x, 9X128, 9XR128]
|
||||
<ul>
|
||||
<li>12 logical switches instead of 15 (the extra ones were not accessible in custom functions)
|
||||
<li>12 logical switches instead of 15 (the extra ones were not accessible in custom functions)</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Logical switches were not resetted on Model load
|
||||
<li>SafetyCH function can be hidden (depending on Companion options)
|
||||
<li>MPH to km/h conversion improved
|
||||
<li>Logical switches were not resetted on Model load</li>
|
||||
<li>SafetyCH function can be hidden (depending on Companion options)</li>
|
||||
<li>MPH to km/h conversion improved</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.5 / 2014-06-26</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Add Flight Mode indication to the mixer/inputs screens
|
||||
<li>Joystick emulation fixed
|
||||
<li>Fixed float number display in Lua
|
||||
<li>Fixed telemetry screens page order (Lua, custom, voltage, GPS)
|
||||
<li>Fixed unability to disable switch warning for SG
|
||||
<li>Lua bugfixes in getCustomFunction/setCustomFunction and getLogicalSwitch/setLogicalSwitch
|
||||
<li>Add Flight Mode indication to the mixer/inputs screens</li>
|
||||
<li>Joystick emulation fixed</li>
|
||||
<li>Fixed float number display in Lua</li>
|
||||
<li>Fixed telemetry screens page order (Lua, custom, voltage, GPS)</li>
|
||||
<li>Fixed unability to disable switch warning for SG</li>
|
||||
<li>Lua bugfixes in getCustomFunction/setCustomFunction and getLogicalSwitch/setLogicalSwitch</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.4 / 2014-06-24</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Lua Telemetry custom screens added
|
||||
<li>Lua wrong memory used indication
|
||||
<li>Telemetry on the serial port in the battery bay
|
||||
<li>
|
||||
<li>Lua Telemetry custom screens added</li>
|
||||
<li>Lua wrong memory used indication</li>
|
||||
<li>Telemetry on the serial port in the battery bay</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Air Speed added in Logs
|
||||
<li>|d|>x bug fix
|
||||
<li>Air Speed added in Logs</li>
|
||||
<li>|d|>x bug fix</li>
|
||||
<li>Timers played even if 00:00
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.3 / 2014-06-17</h2>
|
||||
<ul>
|
||||
<li>Bugfix on Reset Flight function (possible freeze of the menus)
|
||||
<li>Imperial units bug (on altitude)
|
||||
<li>FIRMWARE.BIN and EEPROM.BIN are not anymore marked as system files
|
||||
<li>Bugfix on Reset Flight function (possible freeze of the menus)</li>
|
||||
<li>Imperial units bug (on altitude)</li>
|
||||
<li>FIRMWARE.BIN and EEPROM.BIN are not anymore marked as system files</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.2 / 2014-06-12</h2>
|
||||
<ul>
|
||||
<li>RxBatt removed (merged with A1 as before)
|
||||
<li>Bootloader accessible through the 2 trims (as 2.0.0)
|
||||
<li>Delay on switches middle position only applied to Play functions
|
||||
<li>Delay for Play functions is configurable (0-300ms)
|
||||
<li>SWR, A3 and A4 now recorded in SD logs
|
||||
<li>Persistent mAh was not correctly stored in EEPROM
|
||||
<li>A lot of small bug fixes
|
||||
<li>RxBatt removed (merged with A1 as before)</li>
|
||||
<li>Bootloader accessible through the 2 trims (as 2.0.0)</li>
|
||||
<li>Delay on switches middle position only applied to Play functions</li>
|
||||
<li>Delay for Play functions is configurable (0-300ms)</li>
|
||||
<li>SWR, A3 and A4 now recorded in SD logs</li>
|
||||
<li>Persistent mAh was not correctly stored in EEPROM</li>
|
||||
<li>A lot of small bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>OpenTX 2.0.1 / 2014-02-05</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>S.PORT / D protocol choice added in TELEMETRY menu
|
||||
<li>Heli mixer fix (stick modes 2/3/4)
|
||||
<li>Multipos switch fix
|
||||
<li>Italian translations updated
|
||||
<li>French translations fixes
|
||||
<li>Multis Wizard added
|
||||
<li>Bootloader now needs only one trim pressed
|
||||
<li>S3 warning hidden (no S3 on Taranis)
|
||||
<li>Persistent mAh was broken
|
||||
<li>S.PORT / D protocol choice added in TELEMETRY menu</li>
|
||||
<li>Heli mixer fix (stick modes 2/3/4)</li>
|
||||
<li>Multipos switch fix</li>
|
||||
<li>Italian translations updated</li>
|
||||
<li>French translations fixes</li>
|
||||
<li>Multis Wizard added</li>
|
||||
<li>Bootloader now needs only one trim pressed</li>
|
||||
<li>S3 warning hidden (no S3 on Taranis)</li>
|
||||
<li>Persistent mAh was broken</li>
|
||||
</ul>
|
||||
|
||||
[Stock]
|
||||
<ul>
|
||||
<li>Fix for LS used as source
|
||||
<li>Fix for LS used as source</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Fix on d>=x logical switches
|
||||
<li>Fix on d>=x logical switches</li>
|
||||
</ul>
|
||||
|
||||
<h2>OpenTX 2.0.0 / 2014-06-02</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Inputs layer with support for all physical inputs and telemetry
|
||||
<li>Lua interpreter for runtime scripts and one-time configuration assistants
|
||||
<li>GVARs useable for offsets and limits
|
||||
<li>GVAR modification popup on home screen can be enabled/disabled for each GVAR
|
||||
<li>Output curve assignable to each servo on the SERVOS page
|
||||
<li>32 curves instead of 16, with smoothing, and any number of points between 2 and 17
|
||||
<li>Pot position memory for the 4 pots, with startup warning
|
||||
<li>Copy/paste/insert/delete of custom function lines
|
||||
<li>Altitude can be displayed in the top bar
|
||||
<li>FrSky Taranis will run at 120MHz instead of 60MHz
|
||||
<li>New trim system (a mode's trims can be relative to that of another mode's)
|
||||
<li>SPORT data form internal module available on the UART connector in the battery compartment in the Taranis
|
||||
<li>Support for 6-position pots, with individual positions available in the switch selection list
|
||||
<li>Taranis will be useable as a standard PC joystick through USB, 8 analogs and 8 buttons mapped to CH1-8 and 9-16 respectively
|
||||
<li>Inputs layer with support for all physical inputs and telemetry</li>
|
||||
<li>Lua interpreter for runtime scripts and one-time configuration assistants</li>
|
||||
<li>GVARs useable for offsets and limits</li>
|
||||
<li>GVAR modification popup on home screen can be enabled/disabled for each GVAR</li>
|
||||
<li>Output curve assignable to each servo on the SERVOS page</li>
|
||||
<li>32 curves instead of 16, with smoothing, and any number of points between 2 and 17</li>
|
||||
<li>Pot position memory for the 4 pots, with startup warning</li>
|
||||
<li>Copy/paste/insert/delete of custom function lines</li>
|
||||
<li>Altitude can be displayed in the top bar</li>
|
||||
<li>FrSky Taranis will run at 120MHz instead of 60MHz</li>
|
||||
<li>New trim system (a mode's trims can be relative to that of another mode's)</li>
|
||||
<li>SPORT data form internal module available on the UART connector in the battery compartment in the Taranis</li>
|
||||
<li>Support for 6-position pots, with individual positions available in the switch selection list</li>
|
||||
<li>Taranis will be useable as a standard PC joystick through USB, 8 analogs and 8 buttons mapped to CH1-8 and 9-16 respectively</li>
|
||||
</ul>
|
||||
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Measured consumption (mAh) can be stored on power off
|
||||
<li>0.1% resolution for limits
|
||||
<li>Sound repeat time settable in multiples of 1sec, call at model load can be disabled
|
||||
<li>3 options for timer countdown voice output
|
||||
<li>9 GVARS instead of 5 (ARM boards only)
|
||||
<li>64 custom functions instead of 32
|
||||
<li>Ability to read text files from the SD card. A file with the name of a model will be linked to it and easily accessible as "model notes". Can be displayed automatically at model load for use as a checklist
|
||||
<li>Bootloader added, removes the need to install computer drivers to flash new firmware
|
||||
<li>Radio can handle EEPROM conversion by itself (no need for companion)
|
||||
<li>Improved vario sounds
|
||||
<li>Default audio files can be placed on the SD card for each model for all switch positions (both for physical and logical switches).
|
||||
<li>Support for up to 16 channels on trainer input
|
||||
<li>Measured consumption (mAh) can be stored on power off</li>
|
||||
<li>0.1% resolution for limits</li>
|
||||
<li>Sound repeat time settable in multiples of 1sec, call at model load can be disabled</li>
|
||||
<li>3 options for timer countdown voice output</li>
|
||||
<li>9 GVARS instead of 5 (ARM boards only)</li>
|
||||
<li>64 custom functions instead of 32</li>
|
||||
<li>Ability to read text files from the SD card. A file with the name of a model will be linked to it and easily accessible as "model notes". Can be displayed automatically at model load for use as a checklist</li>
|
||||
<li>Bootloader added, removes the need to install computer drivers to flash new firmware</li>
|
||||
<li>Radio can handle EEPROM conversion by itself (no need for companion)</li>
|
||||
<li>Improved vario sounds</li>
|
||||
<li>Default audio files can be placed on the SD card for each model for all switch positions (both for physical and logical switches)</li>
|
||||
<li>Support for up to 16 channels on trainer input</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Proportional fonts
|
||||
<li>Switch warnings can be disabled for switches you don't use on a given model
|
||||
<li>Compensation for offset error of FrSky FAS-xx current sensors (option on m64)
|
||||
<li>Companion merged into OpenTX
|
||||
<li>Companion major code / graphics refactoring
|
||||
<li>Sticky Logical Switches
|
||||
<li>ASpd, dTE, Cel-, Vfas- added to Telemetry values
|
||||
<li>Workaround for newer bogus FlySky modules that send out servo centers on powerup (9x only)
|
||||
<li>Finnish language support
|
||||
<li>Proportional fonts</li>
|
||||
<li>Switch warnings can be disabled for switches you don't use on a given model</li>
|
||||
<li>Compensation for offset error of FrSky FAS-xx current sensors (option on m64)</li>
|
||||
<li>Companion merged into OpenTX</li>
|
||||
<li>Companion major code / graphics refactoring</li>
|
||||
<li>Sticky Logical Switches</li>
|
||||
<li>ASpd, dTE, Cel-, Vfas- added to Telemetry values</li>
|
||||
<li>Workaround for newer bogus FlySky modules that send out servo centers on powerup (9x only)</li>
|
||||
<li>Finnish language support</li>
|
||||
</ul>
|
||||
|
||||
<h2>2940 / 2014-02-02</h2>
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Wav files played even in silent mode
|
||||
<li>GPS support had broken VFAS
|
||||
<li>Wav files played even in silent mode</li>
|
||||
<li>GPS support had broken VFAS</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Custom function triggered by a CSW based on analog triggering erroneously at powerup
|
||||
<li>Problem with mixer weight field when !GVARS
|
||||
<li>PPM5 was broken
|
||||
<li>Custom function triggered by a CSW based on analog triggering erroneously at powerup</li>
|
||||
<li>Problem with mixer weight field when !GVARS</li>
|
||||
<li>PPM5 was broken</li>
|
||||
</ul>
|
||||
|
||||
<h2>2923 / 2014-01-08</h2>
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Audio freeze bug fixed
|
||||
<li>Aurora gimbals support
|
||||
<li>Audio freeze bug fixed</li>
|
||||
<li>Aurora gimbals support</li>
|
||||
</ul>
|
||||
|
||||
<h2>2834 / 2013-10-29</h2>
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Altitude played without decimal when >= 10m
|
||||
<li>Check to avoid too long paths when playing SD files
|
||||
<li>Altitude played without decimal when >= 10m</li>
|
||||
<li>Check to avoid too long paths when playing SD files</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Mixer bug when a MULTIPLY mix used with a slow
|
||||
<li>GVAR popup removed
|
||||
<li>Sticky virtual switches are reset when ResetFlight function is called
|
||||
<li>Mixer bug when a MULTIPLY mix used with a slow</li>
|
||||
<li>GVAR popup removed</li>
|
||||
<li>Sticky virtual switches are reset when ResetFlight function is called </li>
|
||||
</ul>
|
||||
|
||||
<h2>2768 / 2013-09-20</h2>
|
||||
@@ -284,26 +325,26 @@
|
||||
<ul>
|
||||
<li>Flash savings</li>
|
||||
<li>Vario sink tones removed</li>
|
||||
<li>Audio files renumbered (see here) </li>
|
||||
<li>Audio files renumbered (see here)</li>
|
||||
</ul>
|
||||
|
||||
[Sky9x]
|
||||
<ul>
|
||||
<li>Audio mixer: several sounds can now be played simulataneously, and beeps won't interrupt and clear voice alerts anymore. Note that sound files now need to have sampling rates of either 8, 16 or 32kHz and may need to be replaced. </li>
|
||||
<li>Audio mixer: several sounds can now be played simulataneously, and beeps won't interrupt and clear voice alerts anymore. Note that sound files now need to have sampling rates of either 8, 16 or 32kHz and may need to be replaced</li>
|
||||
</ul>
|
||||
|
||||
<h2>2413 / 2013-05-22</h2>
|
||||
[All]
|
||||
<ul>
|
||||
<li>Calibration screen automatically appears following an EEPROM format</li>
|
||||
<li>Wraparound in popup menus </li>
|
||||
<li>Wraparound in popup menus</li>
|
||||
</ul>
|
||||
|
||||
[9X Stock]
|
||||
<ul>
|
||||
<li>More options supported (novario / nogps / nogauges)</li>
|
||||
<li>Flash savings</li>
|
||||
<li>Mavlink huge rework by Rienk! </li>
|
||||
<li>Mavlink huge rework by Rienk!</li>
|
||||
</ul>
|
||||
|
||||
[Sky9x]
|
||||
@@ -315,17 +356,17 @@
|
||||
<h2>2215 / 2013-04-05</h2>
|
||||
[All]
|
||||
<ul>
|
||||
<li>New option AUTOSOURCE to automatically select the stick / pot / switch which is moved when editing a Mix source </li>
|
||||
<li>New option AUTOSOURCE to automatically select the stick / pot / switch which is moved when editing a Mix source</li>
|
||||
</ul>
|
||||
|
||||
[9X Stock]
|
||||
<ul>
|
||||
<li>All prompts renumbered to have the "custom" prompts starting at 0 and to be able to use PlayTrack?(GVAR) with Adjust(GVAR) to play tracks sequences </li>
|
||||
<li>All prompts renumbered to have the "custom" prompts starting at 0 and to be able to use PlayTrack?(GVAR) with Adjust(GVAR) to play tracks sequences</li>
|
||||
</ul>
|
||||
|
||||
[Gruvin9x]
|
||||
<ul>
|
||||
<li>Possibility to have both BEEPER and SPEAKER enable in the same time </li>
|
||||
<li>Possibility to have both BEEPER and SPEAKER enable in the same time</li>
|
||||
</ul>
|
||||
|
||||
[Sky9x]
|
||||
@@ -335,5 +376,5 @@
|
||||
<li>Possibility to have both BEEPER and SPEAKER enable in the same time</li>
|
||||
<li>New menu in Main Views / Telemetry Views</li>
|
||||
<li>Vario sounds improved!</li>
|
||||
<li>SD Folders renamed. "9XSOUNDS" becomes "SOUNDS", don't forget to updateyour cards!</li>
|
||||
<li>SD Folders renamed. "9XSOUNDS" becomes "SOUNDS", don't forget to update your SD card!</li>
|
||||
</ul>
|
||||
@@ -26,3 +26,4 @@
|
||||
/gtests.d
|
||||
/lua_exports.cpp
|
||||
/lua_exports.txt
|
||||
/lua_fields.txt
|
||||
|
||||
+33
-23
@@ -69,7 +69,7 @@ FAI = NO
|
||||
|
||||
# the latests deliveries for Turnigy 9x transmitters (since 2 years now, 2014) do not stop sending if no pulses are generated.
|
||||
# This fact totally breaks the nice throttle and switch warning concept, because even we prevent sending pulses the
|
||||
# transmitter modul ignores this, and continous to send the last value or 0 at beginning. And 0 means in the middle of throttle -> 50%.
|
||||
# transmitter module ignores this, and continues to send the last value or 0 at beginning. And 0 means in the middle of throttle -> 50%.
|
||||
# To cope with this situation, we need a new concept how to handle throttle and switch warnings.
|
||||
# if you have a 0 value (50% ) for throttle, while throttle warning is active, you should activate this switch
|
||||
# Values = YES, NO
|
||||
@@ -126,7 +126,7 @@ CORRECT_NEGATIVE_VALUES = YES
|
||||
ARITHMETIC_OVERFLOW_CHECK = NO
|
||||
|
||||
# increases resolution for throttle statistics and throttle counting, in very rare cases.
|
||||
# this will be only true if an output channel is used for throttle calculation, and this chanenel has changed limits, e.g. -90% to +80%
|
||||
# this will be only true if an output channel is used for throttle calculation, and this channel has changed limits, e.g. -90% to +80%
|
||||
# if you use standard limits for throttle or directly the throttle stick you do not need to bother about this option
|
||||
# not valid for ARM based transmitters like Taranis, They do not have this rounding issue at all
|
||||
# Values = YES, NO
|
||||
@@ -161,7 +161,7 @@ FONT = STD
|
||||
# Values = YES, NO
|
||||
PPM_CENTER_ADJUSTABLE = NO
|
||||
|
||||
# PPM symetrical limits
|
||||
# PPM symmetrical limits
|
||||
# Values = YES, NO
|
||||
PPM_LIMITS_SYMETRICAL = NO
|
||||
|
||||
@@ -247,7 +247,7 @@ EEPROM_PROGRESS_BAR = NO
|
||||
|
||||
# Activates the DEBUG Mode (all boards)
|
||||
# On G9X V4 board, when VOICE=NO:
|
||||
# PORTH:7 --> Transistion LOW to HIGH = start of setupPulses(). Transistion HIGH to LOW = end of setupPulses().
|
||||
# PORTH:7 --> Transition LOW to HIGH = start of setupPulses(). Transition HIGH to LOW = end of setupPulses().
|
||||
# PORTH:6 --> LOW->HIGH = start of mixer calcs. HIGH->LOW, end of mixer calcs.
|
||||
# Values = YES, NO
|
||||
DEBUG = NO
|
||||
@@ -282,13 +282,17 @@ MENUS_LOCK = NO
|
||||
# MASSSTORAGE: The TX will appear as a drive
|
||||
USB = JOYSTICK
|
||||
|
||||
# Channel monitor display behaviour
|
||||
# Channel monitor display behavior
|
||||
# Values = NO, YES
|
||||
# YES - hide the fact that channel is inverted in limits tab
|
||||
# and show inverted channel value with oposite sign
|
||||
# NO - normal behaviour, show real channel values
|
||||
# and show inverted channel value with opposite sign
|
||||
# NO - normal behavior, show real channel values
|
||||
CHANNELS_MONITOR_INV_HIDE = NO
|
||||
|
||||
# Use newlib-nano
|
||||
# Values = NO, YES
|
||||
NANO = NO
|
||||
|
||||
#------- 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.12
|
||||
|
||||
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
|
||||
@@ -726,9 +736,8 @@ ifeq ($(PCB), TARANIS)
|
||||
INCDIRS += lua/src
|
||||
CPPSRC += lua.cpp
|
||||
LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/ldump.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \
|
||||
lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \
|
||||
lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c
|
||||
# lua/src/loslib.c lua/src/lbitlib.c lua/src/lstrlib.c lua/src/liolib.c lua/src/ldblib.c
|
||||
lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/lrotable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \
|
||||
lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/lbitlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c
|
||||
SRC += $(LUASRC)
|
||||
LUADEP = lua_exports.cpp
|
||||
endif
|
||||
@@ -1278,9 +1287,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 +1333,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
|
||||
@@ -1339,7 +1349,7 @@ else
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O ihex opentx.elf opentx.hex
|
||||
$(OBJCOPY) -O ihex opentx.elf opentx.hex
|
||||
endif
|
||||
|
||||
%.bin: %.elf
|
||||
@@ -1389,7 +1399,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 +1429,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
|
||||
@@ -1429,12 +1439,12 @@ AVRCOMMAND = $(AVRDUDE) $(AVRDEVICE)
|
||||
|
||||
WRITE_COMMAND = $(AVRCOMMAND) -U flash:w:opentx.hex:i
|
||||
ifeq ($(RESTORE_EEPROM), YES)
|
||||
BACKUP_EEPROM = YES
|
||||
ifeq ($(DOUBLE_WRITE_OK), YES)
|
||||
WRITE_COMMAND += -U eeprom:w:$(DATA_DIR)/eeprom-$(DATE).hex:i
|
||||
else
|
||||
SECOND_WRITE_COMMAND = -U eeprom:w:$(DATA_DIR)/eeprom-$(DATE).hex:i
|
||||
endif
|
||||
BACKUP_EEPROM = YES
|
||||
ifeq ($(DOUBLE_WRITE_OK), YES)
|
||||
WRITE_COMMAND += -U eeprom:w:$(DATA_DIR)/eeprom-$(DATE).hex:i
|
||||
else
|
||||
SECOND_WRITE_COMMAND = -U eeprom:w:$(DATA_DIR)/eeprom-$(DATE).hex:i
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BACKUP_FLASH), YES)
|
||||
|
||||
+21
-6
@@ -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;
|
||||
@@ -732,7 +737,7 @@ void AudioQueue::wakeup()
|
||||
else {
|
||||
CoEnterMutexSection(audioMutex);
|
||||
if (ridx != widx) {
|
||||
normalContext.fragment = fragments[ridx];
|
||||
normalContext.tone.setFragment(fragments[ridx]);
|
||||
if (!fragments[ridx].repeat--) {
|
||||
ridx = (ridx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
}
|
||||
@@ -799,8 +804,9 @@ void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t f
|
||||
{
|
||||
CoEnterMutexSection(audioMutex);
|
||||
|
||||
if (freq && freq < BEEP_MIN_FREQ)
|
||||
if (freq && freq < BEEP_MIN_FREQ) {
|
||||
freq = BEEP_MIN_FREQ;
|
||||
}
|
||||
|
||||
if (flags & PLAY_BACKGROUND) {
|
||||
AudioFragment & fragment = varioContext.fragment;
|
||||
@@ -923,6 +929,15 @@ void AudioQueue::stopAll()
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
}
|
||||
|
||||
void AudioQueue::flush()
|
||||
{
|
||||
CoEnterMutexSection(audioMutex);
|
||||
widx = ridx; // clean the queue
|
||||
varioContext.clear();
|
||||
backgroundContext.clear();
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
}
|
||||
|
||||
void audioEvent(uint8_t e, uint16_t f)
|
||||
{
|
||||
#if defined(HAPTIC)
|
||||
|
||||
@@ -103,6 +103,12 @@ class ToneContext {
|
||||
uint16_t pause;
|
||||
} state;
|
||||
|
||||
inline void setFragment(AudioFragment & fragment)
|
||||
{
|
||||
this->fragment = fragment;
|
||||
memset(&state, 0, sizeof(state));
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
memset(this, 0, sizeof(ToneContext));
|
||||
@@ -163,6 +169,8 @@ class AudioQueue {
|
||||
|
||||
void stopAll();
|
||||
|
||||
void flush();
|
||||
|
||||
void pause(uint16_t tLen);
|
||||
|
||||
void stopSD();
|
||||
@@ -328,6 +336,7 @@ void pushPrompt(uint16_t prompt, uint8_t id=0);
|
||||
#define PLAY_FILE(f, flags, id) audioQueue.playFile((f), (flags), (id))
|
||||
#define STOP_PLAY(id) audioQueue.stopPlay((id))
|
||||
#define AUDIO_RESET() audioQueue.stopAll()
|
||||
#define AUDIO_FLUSH() audioQueue.flush()
|
||||
|
||||
#if defined(SDCARD)
|
||||
extern tmr10ms_t timeAutomaticPromptsSilence;
|
||||
|
||||
@@ -154,6 +154,7 @@ void audioDefevent(uint8_t e);
|
||||
#define AUDIO_HEARTBEAT() audio.heartbeat()
|
||||
#define IS_AUDIO_BUSY() audio.busy()
|
||||
#define AUDIO_RESET()
|
||||
#define AUDIO_FLUSH()
|
||||
|
||||
#define PLAY_PHASE_OFF(phase)
|
||||
#define PLAY_PHASE_ON(phase)
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
void _init (void)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -99,6 +99,7 @@ void beep(uint8_t val);
|
||||
|
||||
#define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn)
|
||||
#define AUDIO_RESET()
|
||||
#define AUDIO_FLUSH()
|
||||
|
||||
#define PLAY_PHASE_OFF(phase)
|
||||
#define PLAY_PHASE_ON(phase)
|
||||
|
||||
@@ -385,6 +385,7 @@ void eeLoadModel(uint8_t id)
|
||||
read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&g_model, size) ;
|
||||
}
|
||||
|
||||
AUDIO_FLUSH();
|
||||
flightReset();
|
||||
logicalSwitchesReset();
|
||||
|
||||
|
||||
@@ -964,16 +964,22 @@ void eeLoadModel(uint8_t id)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool newModel = false;
|
||||
|
||||
if (sz < 256) {
|
||||
modelDefault(id);
|
||||
eeCheck(true);
|
||||
newModel = true;
|
||||
}
|
||||
|
||||
AUDIO_FLUSH();
|
||||
flightReset();
|
||||
logicalSwitchesReset();
|
||||
|
||||
if (pulsesStarted()) {
|
||||
checkAll();
|
||||
if (!newModel) {
|
||||
checkAll();
|
||||
}
|
||||
resumePulses();
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1325,8 +1325,8 @@ void menuModelSetup(uint8_t event)
|
||||
uint8_t x = MODEL_SETUP_2ND_COLUMN+5*FW;
|
||||
for (uint8_t i=0; i<NUM_POTS ; i++) {
|
||||
#if !defined(REVPLUS)
|
||||
if (attr && i == POT3-POT1) {
|
||||
if (m_posHorz==i+1) REPEAT_LAST_CURSOR_MOVE();
|
||||
if (i == POT3-POT1) {
|
||||
if (attr && (m_posHorz==i+1)) REPEAT_LAST_CURSOR_MOVE();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -1353,7 +1353,7 @@ void menuModelSetup(uint8_t event)
|
||||
uint8_t x = MODEL_SETUP_2ND_COLUMN+i*FW;
|
||||
#if defined(PCBTARANIS) && !defined(REVPLUS)
|
||||
if (i == POT3) {
|
||||
if (m_posHorz == POT3) REPEAT_LAST_CURSOR_MOVE();
|
||||
if (attr && m_posHorz == POT3) REPEAT_LAST_CURSOR_MOVE();
|
||||
continue;
|
||||
}
|
||||
else if (i > POT3) {
|
||||
@@ -1621,7 +1621,7 @@ void menuModelSetup(uint8_t event)
|
||||
if (IS_PPM_PROTOCOL(protocol)) {
|
||||
lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+7*FW, y, STR_NCHANNELS, g_model.ppmNCH+2, m_posHorz!=0 ? attr : 0);
|
||||
}
|
||||
else if (attr) {
|
||||
else if (m_posHorz>0 && attr) {
|
||||
MOVE_CURSOR_FROM_HERE();
|
||||
}
|
||||
if (attr && (editMode>0 || p1valdiff || (!IS_PPM_PROTOCOL(protocol) && !IS_DSM2_PROTOCOL(protocol)))) {
|
||||
@@ -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;
|
||||
@@ -4480,7 +4491,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
v2_min = -125; v2_max = 125;
|
||||
v2_min = -LIMIT_EXT_PERCENT; v2_max = +LIMIT_EXT_PERCENT;
|
||||
lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cs->v2, LEFT|attr);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -4791,7 +4788,7 @@ void menuModelLogicalSwitches(uint8_t event)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
v2_min = -125; v2_max = +125;
|
||||
v2_min = -LIMIT_EXT_PERCENT; v2_max = +LIMIT_EXT_PERCENT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -4801,7 +4798,7 @@ void menuModelLogicalSwitches(uint8_t event)
|
||||
}
|
||||
else {
|
||||
lcd_outdezAtt(CSW_3RD_COLUMN, y, cs->v2, LEFT|attr2);
|
||||
v2_min = -125; v2_max = 125;
|
||||
v2_min = -LIMIT_EXT_PERCENT; v2_max = +LIMIT_EXT_PERCENT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -5122,8 +5119,10 @@ void menuModelCustomFunctions(uint8_t event)
|
||||
}
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
else if (func == FUNC_OVERRIDE_CHANNEL) {
|
||||
#if !defined(CPUARM)
|
||||
val_displayed = (int8_t)CFN_PARAM(sd);
|
||||
val_min = -125; val_max = 125;
|
||||
#endif
|
||||
val_min = -LIMIT_EXT_PERCENT; val_max = +LIMIT_EXT_PERCENT;
|
||||
lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ void displayTrims(uint8_t phase)
|
||||
uint8_t att = ROUND;
|
||||
int16_t val = getTrimValue(phase, i);
|
||||
|
||||
if (val < -125 || val > 125)
|
||||
if (val < TRIM_MIN || val > TRIM_MAX)
|
||||
att = BLINK|INVERS|ROUND;
|
||||
|
||||
if (val < -(TRIM_LEN+1)*4)
|
||||
|
||||
@@ -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,87 @@ 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 0
|
||||
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_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
|
||||
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);
|
||||
|
||||
@@ -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
@@ -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]));
|
||||
|
||||
+479
-283
@@ -45,6 +45,7 @@ extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include <lrotable.h>
|
||||
#if !defined(SIMU)
|
||||
}
|
||||
#endif
|
||||
@@ -73,9 +74,21 @@ uint16_t maxLuaDuration = 0;
|
||||
|
||||
#define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS (10000/100)
|
||||
#define MANUAL_SCRIPTS_MAX_INSTRUCTIONS (20000/100)
|
||||
#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)
|
||||
{
|
||||
@@ -514,6 +527,7 @@ static int luaModelGetInfo(lua_State *L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
lua_pushtablezstring(L, "name", g_model.header.name);
|
||||
lua_pushtablenzstring(L, "bitmap", g_model.header.bitmap);
|
||||
lua_pushtableinteger(L, "id", g_model.header.modelId);
|
||||
return 1;
|
||||
}
|
||||
@@ -529,6 +543,10 @@ static int luaModelSetInfo(lua_State *L)
|
||||
str2zchar(g_model.header.name, name, sizeof(g_model.header.name));
|
||||
memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name));
|
||||
}
|
||||
else if (!strcmp(key, "bitmap")) {
|
||||
const char * name = luaL_checkstring(L, -1);
|
||||
strncpy(g_model.header.bitmap, name, sizeof(g_model.header.bitmap));
|
||||
}
|
||||
else if (!strcmp(key, "id")) {
|
||||
g_model.header.modelId = luaL_checkinteger(L, -1);
|
||||
modelHeaders[g_eeGeneral.currModel].modelId = g_model.header.modelId;
|
||||
@@ -768,6 +786,8 @@ static int luaModelGetMix(lua_State *L)
|
||||
lua_pushtableinteger(L, "weight", mix->weight);
|
||||
lua_pushtableinteger(L, "offset", mix->offset);
|
||||
lua_pushtableinteger(L, "switch", mix->swtch);
|
||||
lua_pushtableinteger(L, "curveType", mix->curve.type);
|
||||
lua_pushtableinteger(L, "curveValue", mix->curve.value);
|
||||
lua_pushtableinteger(L, "multiplex", mix->mltpx);
|
||||
}
|
||||
else {
|
||||
@@ -809,6 +829,12 @@ static int luaModelInsertMix(lua_State *L)
|
||||
else if (!strcmp(key, "switch")) {
|
||||
mix->swtch = luaL_checkinteger(L, -1);
|
||||
}
|
||||
else if (!strcmp(key, "curveType")) {
|
||||
mix->curve.type = luaL_checkinteger(L, -1);
|
||||
}
|
||||
else if (!strcmp(key, "curveValue")) {
|
||||
mix->curve.value = luaL_checkinteger(L, -1);
|
||||
}
|
||||
else if (!strcmp(key, "multiplex")) {
|
||||
mix->mltpx = luaL_checkinteger(L, -1);
|
||||
}
|
||||
@@ -897,6 +923,48 @@ static int luaModelSetLogicalSwitch(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaModelGetCurve(lua_State *L)
|
||||
{
|
||||
int idx = luaL_checkunsigned(L, 1);
|
||||
if (idx < MAX_CURVES) {
|
||||
CurveInfo & curveInfo = g_model.curves[idx];
|
||||
lua_newtable(L);
|
||||
lua_pushtablezstring(L, "name", g_model.curveNames[idx]);
|
||||
lua_pushtableinteger(L, "type", curveInfo.type);
|
||||
lua_pushtableboolean(L, "smooth", curveInfo.smooth);
|
||||
lua_pushtableinteger(L, "points", curveInfo.points+5);
|
||||
lua_pushstring(L, "y");
|
||||
lua_newtable(L);
|
||||
int8_t * point = curveAddress(idx);
|
||||
for (int i=0; i<curveInfo.points+5; i++) {
|
||||
lua_pushinteger(L, i);
|
||||
lua_pushinteger(L, *point++);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
if (curveInfo.type == CURVE_TYPE_CUSTOM) {
|
||||
lua_pushstring(L, "x");
|
||||
lua_newtable(L);
|
||||
lua_pushinteger(L, 0);
|
||||
lua_pushinteger(L, 0);
|
||||
lua_settable(L, -3);
|
||||
for (int i=0; i<curveInfo.points+3; i++) {
|
||||
lua_pushinteger(L, i+1);
|
||||
lua_pushinteger(L, *point++);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
lua_pushinteger(L, curveInfo.points+4);
|
||||
lua_pushinteger(L, 100);
|
||||
lua_settable(L, -3);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaModelGetCustomFunction(lua_State *L)
|
||||
{
|
||||
int idx = luaL_checkunsigned(L, 1);
|
||||
@@ -1044,7 +1112,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);
|
||||
}
|
||||
@@ -1280,7 +1348,77 @@ int luaGetOutputs(ScriptInputsOutputs & sid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg modelLib[] = {
|
||||
const luaL_Reg opentxLib[] = {
|
||||
{ "getTime", luaGetTime },
|
||||
{ "getVersion", luaGetVersion },
|
||||
{ "getGeneralSettings", luaGetGeneralSettings },
|
||||
{ "getValue", luaGetValue },
|
||||
{ "getFieldInfo", luaGetFieldInfo },
|
||||
{ "playFile", luaPlayFile },
|
||||
{ "playNumber", luaPlayNumber },
|
||||
// { "playDuration", luaPlayDuration },
|
||||
// { "playTone", luaPlayTone },
|
||||
{ "popupInput", luaPopupInput },
|
||||
{ "defaultStick", luaDefaultStick },
|
||||
{ "defaultChannel", luaDefaultChannel },
|
||||
{ "killEvents", luaKillEvents },
|
||||
{ NULL, NULL } /* sentinel */
|
||||
};
|
||||
|
||||
const luaR_value_entry opentxConstants[] = {
|
||||
{ "FULLSCALE", RESX },
|
||||
{ "XXLSIZE", XXLSIZE },
|
||||
{ "DBLSIZE", DBLSIZE },
|
||||
{ "MIDSIZE", MIDSIZE },
|
||||
{ "SMLSIZE", SMLSIZE },
|
||||
{ "INVERS", INVERS },
|
||||
{ "LEFT", LEFT },
|
||||
{ "PREC1", PREC1 },
|
||||
{ "PREC2", PREC2 },
|
||||
{ "BLINK", BLINK },
|
||||
{ "VALUE", 0 },
|
||||
{ "SOURCE", 1 },
|
||||
{ "REPLACE", MLTPX_REP },
|
||||
{ "MIXSRC_FIRST_INPUT", MIXSRC_FIRST_INPUT },
|
||||
{ "MIXSRC_Rud", MIXSRC_Rud },
|
||||
{ "MIXSRC_Ele", MIXSRC_Ele },
|
||||
{ "MIXSRC_Thr", MIXSRC_Thr },
|
||||
{ "MIXSRC_Ail", MIXSRC_Ail },
|
||||
{ "MIXSRC_SA", MIXSRC_SA },
|
||||
{ "MIXSRC_SB", MIXSRC_SB },
|
||||
{ "MIXSRC_SC", MIXSRC_SC },
|
||||
{ "MIXSRC_SD", MIXSRC_SD },
|
||||
{ "MIXSRC_SE", MIXSRC_SE },
|
||||
{ "MIXSRC_SF", MIXSRC_SF },
|
||||
{ "MIXSRC_SG", MIXSRC_SG },
|
||||
{ "MIXSRC_SH", MIXSRC_SH },
|
||||
{ "MIXSRC_CH1", MIXSRC_CH1 },
|
||||
{ "SWSRC_LAST", SWSRC_LAST_LOGICAL_SWITCH },
|
||||
{ "EVT_MENU_BREAK", EVT_KEY_BREAK(KEY_MENU) },
|
||||
{ "EVT_PAGE_BREAK", EVT_KEY_BREAK(KEY_PAGE) },
|
||||
{ "EVT_PAGE_LONG", EVT_KEY_LONG(KEY_PAGE) },
|
||||
{ "EVT_ENTER_BREAK", EVT_KEY_BREAK(KEY_ENTER) },
|
||||
{ "EVT_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) },
|
||||
{ "EVT_EXIT_BREAK", EVT_KEY_BREAK(KEY_EXIT) },
|
||||
{ "EVT_PLUS_BREAK", EVT_KEY_BREAK(KEY_PLUS) },
|
||||
{ "EVT_MINUS_BREAK", EVT_KEY_BREAK(KEY_MINUS) },
|
||||
{ "EVT_PLUS_FIRST", EVT_KEY_FIRST(KEY_PLUS) },
|
||||
{ "EVT_MINUS_FIRST", EVT_KEY_FIRST(KEY_MINUS) },
|
||||
{ "EVT_PLUS_REPT", EVT_KEY_REPT(KEY_PLUS) },
|
||||
{ "EVT_MINUS_REPT", EVT_KEY_REPT(KEY_MINUS) },
|
||||
{ "FILL_WHITE", FILL_WHITE },
|
||||
{ "GREY_DEFAULT", GREY_DEFAULT },
|
||||
{ "SOLID", SOLID },
|
||||
{ "DOTTED", DOTTED },
|
||||
{ "LCD_W", LCD_W },
|
||||
{ "LCD_H", LCD_H },
|
||||
{ "PLAY_NOW", PLAY_NOW },
|
||||
{ "PLAY_BACKGROUND", PLAY_BACKGROUND },
|
||||
{ "TIMEHOUR", TIMEHOUR },
|
||||
{ NULL, 0 } /* sentinel */
|
||||
};
|
||||
|
||||
const luaL_Reg modelLib[] = {
|
||||
{ "getInfo", luaModelGetInfo },
|
||||
{ "setInfo", luaModelSetInfo },
|
||||
{ "getTimer", luaModelGetTimer },
|
||||
@@ -1300,6 +1438,7 @@ static const luaL_Reg modelLib[] = {
|
||||
{ "setLogicalSwitch", luaModelSetLogicalSwitch },
|
||||
{ "getCustomFunction", luaModelGetCustomFunction },
|
||||
{ "setCustomFunction", luaModelSetCustomFunction },
|
||||
{ "getCurve", luaModelGetCurve },
|
||||
{ "getOutput", luaModelGetOutput },
|
||||
{ "setOutput", luaModelSetOutput },
|
||||
{ "getGlobalVariable", luaModelGetGlobalVariable },
|
||||
@@ -1309,7 +1448,7 @@ static const luaL_Reg modelLib[] = {
|
||||
{ NULL, NULL } /* sentinel */
|
||||
};
|
||||
|
||||
static const luaL_Reg lcdLib[] = {
|
||||
const luaL_Reg lcdLib[] = {
|
||||
{ "lock", luaLcdLock },
|
||||
{ "clear", luaLcdClear },
|
||||
{ "getLastPos", luaLcdGetLastPos },
|
||||
@@ -1330,91 +1469,77 @@ 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);
|
||||
}
|
||||
|
||||
// Push OpenTX libs
|
||||
lua_registerlib(L, "model", modelLib);
|
||||
lua_registerlib(L, "lcd", lcdLib);
|
||||
void luaInit()
|
||||
{
|
||||
luaClose();
|
||||
if (luaState != INTERPRETER_PANIC) {
|
||||
L = luaL_newstate();
|
||||
if (L) {
|
||||
// install our panic handler
|
||||
lua_atpanic(L, &custom_lua_atpanic);
|
||||
|
||||
// Push OpenTX functions
|
||||
lua_register(L, "getTime", luaGetTime);
|
||||
lua_register(L, "getVersion", luaGetVersion);
|
||||
lua_register(L, "getGeneralSettings", luaGetGeneralSettings);
|
||||
lua_register(L, "getValue", luaGetValue);
|
||||
lua_register(L, "getFieldInfo", luaGetFieldInfo);
|
||||
|
||||
lua_register(L, "playFile", luaPlayFile);
|
||||
lua_register(L, "playNumber", luaPlayNumber);
|
||||
lua_register(L, "popupInput", luaPopupInput);
|
||||
lua_register(L, "defaultStick", luaDefaultStick);
|
||||
lua_register(L, "defaultChannel", luaDefaultChannel);
|
||||
lua_register(L, "killEvents", luaKillEvents);
|
||||
|
||||
// Push OpenTX constants
|
||||
lua_registerint(L, "FULLSCALE", RESX);
|
||||
lua_registerint(L, "XXLSIZE", XXLSIZE);
|
||||
lua_registerint(L, "DBLSIZE", DBLSIZE);
|
||||
lua_registerint(L, "MIDSIZE", MIDSIZE);
|
||||
lua_registerint(L, "SMLSIZE", SMLSIZE);
|
||||
lua_registerint(L, "INVERS", INVERS);
|
||||
lua_registerint(L, "LEFT", LEFT);
|
||||
lua_registerint(L, "PREC1", PREC1);
|
||||
lua_registerint(L, "PREC2", PREC2);
|
||||
lua_registerint(L, "BLINK", BLINK);
|
||||
lua_registerint(L, "VALUE", 0);
|
||||
lua_registerint(L, "SOURCE", 1);
|
||||
lua_registerint(L, "REPLACE", MLTPX_REP);
|
||||
lua_registerint(L, "MIXSRC_FIRST_INPUT", MIXSRC_FIRST_INPUT);
|
||||
lua_registerint(L, "MIXSRC_Rud", MIXSRC_Rud);
|
||||
lua_registerint(L, "MIXSRC_Ele", MIXSRC_Ele);
|
||||
lua_registerint(L, "MIXSRC_Thr", MIXSRC_Thr);
|
||||
lua_registerint(L, "MIXSRC_Ail", MIXSRC_Ail);
|
||||
lua_registerint(L, "MIXSRC_SA", MIXSRC_SA);
|
||||
lua_registerint(L, "MIXSRC_SB", MIXSRC_SB);
|
||||
lua_registerint(L, "MIXSRC_SC", MIXSRC_SC);
|
||||
lua_registerint(L, "MIXSRC_SD", MIXSRC_SD);
|
||||
lua_registerint(L, "MIXSRC_SE", MIXSRC_SE);
|
||||
lua_registerint(L, "MIXSRC_SF", MIXSRC_SF);
|
||||
lua_registerint(L, "MIXSRC_SG", MIXSRC_SG);
|
||||
lua_registerint(L, "MIXSRC_SH", MIXSRC_SH);
|
||||
lua_registerint(L, "MIXSRC_CH1", MIXSRC_CH1);
|
||||
lua_registerint(L, "SWSRC_LAST", SWSRC_LAST_LOGICAL_SWITCH);
|
||||
lua_registerint(L, "EVT_MENU_BREAK", EVT_KEY_BREAK(KEY_MENU));
|
||||
lua_registerint(L, "EVT_PAGE_BREAK", EVT_KEY_BREAK(KEY_PAGE));
|
||||
lua_registerint(L, "EVT_PAGE_LONG", EVT_KEY_LONG(KEY_PAGE));
|
||||
lua_registerint(L, "EVT_ENTER_BREAK", EVT_KEY_BREAK(KEY_ENTER));
|
||||
lua_registerint(L, "EVT_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER));
|
||||
lua_registerint(L, "EVT_EXIT_BREAK", EVT_KEY_BREAK(KEY_EXIT));
|
||||
lua_registerint(L, "EVT_PLUS_BREAK", EVT_KEY_BREAK(KEY_PLUS));
|
||||
lua_registerint(L, "EVT_MINUS_BREAK", EVT_KEY_BREAK(KEY_MINUS));
|
||||
lua_registerint(L, "EVT_PLUS_FIRST", EVT_KEY_FIRST(KEY_PLUS));
|
||||
lua_registerint(L, "EVT_MINUS_FIRST", EVT_KEY_FIRST(KEY_MINUS));
|
||||
lua_registerint(L, "EVT_PLUS_REPT", EVT_KEY_REPT(KEY_PLUS));
|
||||
lua_registerint(L, "EVT_MINUS_REPT", EVT_KEY_REPT(KEY_MINUS));
|
||||
lua_registerint(L, "FILL_WHITE", FILL_WHITE);
|
||||
lua_registerint(L, "GREY_DEFAULT", GREY_DEFAULT);
|
||||
lua_registerint(L, "SOLID", SOLID);
|
||||
lua_registerint(L, "DOTTED", DOTTED);
|
||||
lua_registerint(L, "LCD_W", LCD_W);
|
||||
lua_registerint(L, "LCD_H", LCD_H);
|
||||
// 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)
|
||||
@@ -1424,51 +1549,66 @@ int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs
|
||||
sid.instructions = 0;
|
||||
sid.state = SCRIPT_OK;
|
||||
|
||||
#if 0
|
||||
// not needed, we just called luaInit
|
||||
luaFree(sid);
|
||||
#endif
|
||||
|
||||
if (luaState == INTERPRETER_PANIC) {
|
||||
return SCRIPT_PANIC;
|
||||
}
|
||||
|
||||
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;
|
||||
luaDisable();
|
||||
return SCRIPT_PANIC;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
|
||||
if (sid.state != SCRIPT_OK) {
|
||||
luaFree(sid);
|
||||
@@ -1477,7 +1617,7 @@ int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs
|
||||
return sid.state;
|
||||
}
|
||||
|
||||
void luaLoadMixScript(uint8_t index)
|
||||
bool luaLoadMixScript(uint8_t index)
|
||||
{
|
||||
ScriptData & sd = g_model.scriptsData[index];
|
||||
|
||||
@@ -1490,8 +1630,11 @@ void luaLoadMixScript(uint8_t index)
|
||||
strncpy(filename+sizeof(SCRIPTS_MIXES_PATH), sd.file, sizeof(sd.file));
|
||||
filename[sizeof(SCRIPTS_MIXES_PATH)+sizeof(sd.file)] = '\0';
|
||||
strcat(filename+sizeof(SCRIPTS_MIXES_PATH), SCRIPTS_EXT);
|
||||
luaLoad(filename, sid, sio);
|
||||
if (luaLoad(filename, sid, sio) == SCRIPT_PANIC) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool luaLoadFunctionScript(uint8_t index)
|
||||
@@ -1507,13 +1650,15 @@ bool luaLoadFunctionScript(uint8_t index)
|
||||
strncpy(filename+sizeof(SCRIPTS_FUNCS_PATH), fn.play.name, sizeof(fn.play.name));
|
||||
filename[sizeof(SCRIPTS_FUNCS_PATH)+sizeof(fn.play.name)] = '\0';
|
||||
strcat(filename+sizeof(SCRIPTS_FUNCS_PATH), SCRIPTS_EXT);
|
||||
luaLoad(filename, sid);
|
||||
if (luaLoad(filename, sid) == SCRIPT_PANIC) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1542,9 +1687,12 @@ bool luaLoadTelemetryScript(uint8_t index)
|
||||
ScriptInternalData & sid = scriptInternalData[luaScriptsCount++];
|
||||
sid.reference = SCRIPT_TELEMETRY_FIRST+index;
|
||||
sid.state = SCRIPT_NOFILE;
|
||||
luaLoad(path, sid);
|
||||
if (luaLoad(path, sid) == SCRIPT_PANIC) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1570,13 +1718,14 @@ void luaLoadPermanentScripts()
|
||||
|
||||
// Load model scripts
|
||||
for (int i=0; i<MAX_SCRIPTS; i++) {
|
||||
luaLoadMixScript(i);
|
||||
if (!luaLoadMixScript(i)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load custom function scripts
|
||||
for (int i=0; i<NUM_CFN; i++) {
|
||||
if (!luaLoadFunctionScript(i)) {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1584,16 +1733,13 @@ void luaLoadPermanentScripts()
|
||||
// Load custom telemetry scripts
|
||||
for (int i=0; i<MAX_SCRIPTS; i++) {
|
||||
if (!luaLoadTelemetryScript(i)) {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!luaLoadTelemetryScript(TELEMETRY_VOLTAGES_SCREEN)) {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return;
|
||||
}
|
||||
if (!luaLoadTelemetryScript(TELEMETRY_AFTER_FLIGHT_SCREEN)) {
|
||||
POPUP_WARNING(STR_TOO_MANY_LUA_SCRIPTS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1630,6 +1776,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 +1786,202 @@ void luaError(uint8_t error)
|
||||
|
||||
void luaExec(const char *filename)
|
||||
{
|
||||
LUA_RESET();
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
int result = luaLoad(filename, standaloneScript);
|
||||
// TODO the same with run ...
|
||||
if (result == SCRIPT_OK) {
|
||||
luaState = LUASTATE_STANDALONE_SCRIPT_RUNNING;
|
||||
luaInit();
|
||||
if (luaState != INTERPRETER_PANIC) {
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
int result = luaLoad(filename, standaloneScript);
|
||||
// TODO the same with run ...
|
||||
if (result == SCRIPT_OK) {
|
||||
luaState = INTERPRETER_RUNNING_STANDALONE_SCRIPT;
|
||||
}
|
||||
else {
|
||||
luaError(result);
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
luaError(result);
|
||||
}
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
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()
|
||||
{
|
||||
if (L) {
|
||||
PROTECT_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
|
||||
}
|
||||
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 +1991,43 @@ 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 (luaState == INTERPRETER_PANIC) {
|
||||
return;
|
||||
}
|
||||
|
||||
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 {
|
||||
luaDisable();
|
||||
return;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
else {
|
||||
// model scripts
|
||||
if (luaState & LUASTATE_RELOAD_MODEL_SCRIPTS) {
|
||||
if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) {
|
||||
luaState = 0;
|
||||
LUA_RESET();
|
||||
luaInit();
|
||||
if (luaState == INTERPRETER_PANIC) return;
|
||||
luaLoadPermanentScripts();
|
||||
if (luaState == INTERPRETER_PANIC) return;
|
||||
}
|
||||
|
||||
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 {
|
||||
luaDisable();
|
||||
return;
|
||||
}
|
||||
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 +2037,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);
|
||||
}
|
||||
|
||||
+34
-12
@@ -23,6 +23,7 @@
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "lrotable.h"
|
||||
#include "ltm.h"
|
||||
#include "lundump.h"
|
||||
#include "lvm.h"
|
||||
@@ -260,7 +261,7 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||
|
||||
LUA_API int lua_iscfunction (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
return (ttislcf(o) || (ttisCclosure(o)));
|
||||
return (ttislcf(o) || ttislightfunction(o) || (ttisCclosure(o)));
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +418,7 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
||||
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
if (ttislcf(o)) return fvalue(o);
|
||||
if (ttislcf(o)) return lcfvalue(o);
|
||||
else if (ttisCclosure(o))
|
||||
return clCvalue(o)->f;
|
||||
else return NULL; /* not a C function */
|
||||
@@ -446,11 +447,14 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
||||
case LUA_TTABLE: return hvalue(o);
|
||||
case LUA_TLCL: return clLvalue(o);
|
||||
case LUA_TCCL: return clCvalue(o);
|
||||
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
|
||||
case LUA_TLCF: return cast(void *, cast(size_t, lcfvalue(o)));
|
||||
case LUA_TTHREAD: return thvalue(o);
|
||||
case LUA_TUSERDATA:
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return lua_touserdata(L, idx);
|
||||
case LUA_TROTABLE:
|
||||
case LUA_TLIGHTFUNCTION:
|
||||
return pvalue(o);
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -551,11 +555,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
lua_lock(L);
|
||||
if (n == 0) {
|
||||
setfvalue(L->top, fn);
|
||||
setlcfvalue(L->top, fn);
|
||||
}
|
||||
else {
|
||||
Closure *cl;
|
||||
@@ -573,7 +576,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushboolean (lua_State *L, int b) {
|
||||
lua_lock(L);
|
||||
setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
|
||||
@@ -589,6 +591,19 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
LUA_API void lua_pushrotable (lua_State *L, void *p) {
|
||||
lua_lock(L);
|
||||
setrvalue(L->top, p);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
LUA_API void lua_pushlightfunction(lua_State *L, void *p) {
|
||||
lua_lock(L);
|
||||
setlfvalue(L->top, p);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
LUA_API int lua_pushthread (lua_State *L) {
|
||||
lua_lock(L);
|
||||
@@ -598,8 +613,6 @@ LUA_API int lua_pushthread (lua_State *L) {
|
||||
return (G(L)->mainthread == L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
@@ -609,9 +622,19 @@ LUA_API void lua_getglobal (lua_State *L, const char *var) {
|
||||
Table *reg = hvalue(&G(L)->l_registry);
|
||||
const TValue *gt; /* global table */
|
||||
lua_lock(L);
|
||||
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||
setsvalue2s(L, L->top++, luaS_new(L, var));
|
||||
luaV_gettable(L, gt, L->top - 1, L->top - 1);
|
||||
|
||||
lu_byte keytype;
|
||||
luaR_result res = luaR_findglobal(var, &keytype);
|
||||
if (res != 0) {
|
||||
setsvalue2s(L, L->top++, luaS_new(L, var));
|
||||
setlfvalue(L->top - 1, (void*)(size_t)res)
|
||||
}
|
||||
else {
|
||||
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||
setsvalue2s(L, L->top++, luaS_new(L, var));
|
||||
luaV_gettable(L, gt, L->top - 1, L->top - 1);
|
||||
}
|
||||
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
@@ -1008,7 +1031,6 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_status (lua_State *L) {
|
||||
return L->status;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ typedef struct luaL_Reg {
|
||||
lua_CFunction func;
|
||||
} luaL_Reg;
|
||||
|
||||
extern const luaL_Reg baselib[];
|
||||
extern const luaL_Reg mathlib[];
|
||||
extern const luaL_Reg opentxLib[];
|
||||
extern const luaL_Reg bitlib[];
|
||||
extern const luaL_Reg lcdLib[];
|
||||
extern const luaL_Reg modelLib[];
|
||||
|
||||
LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
|
||||
#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lrotable.h"
|
||||
|
||||
static int luaB_print (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
@@ -411,8 +411,7 @@ static int luaB_tostring (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_Reg base_funcs[] = {
|
||||
const luaL_Reg baselib[] = {
|
||||
{"assert", luaB_assert},
|
||||
{"collectgarbage", luaB_collectgarbage},
|
||||
{"dofile", luaB_dofile},
|
||||
@@ -441,16 +440,10 @@ static const luaL_Reg base_funcs[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
LUAMOD_API int luaopen_base (lua_State *L) {
|
||||
/* set global _G */
|
||||
lua_pushglobaltable(L);
|
||||
lua_pushglobaltable(L);
|
||||
lua_setfield(L, -2, "_G");
|
||||
/* open lib into global table */
|
||||
luaL_setfuncs(L, base_funcs, 0);
|
||||
lua_pushliteral(L, LUA_VERSION);
|
||||
lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO
|
||||
const luaR_value_entry baselib_vals[] = {
|
||||
{"_VERSION", LUA_VERSION},
|
||||
{NULL, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lrotable.h"
|
||||
|
||||
/* number of bits to consider in a number */
|
||||
#if !defined(LUA_NBITS)
|
||||
@@ -185,7 +186,7 @@ static int b_replace (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static const luaL_Reg bitlib[] = {
|
||||
const luaL_Reg bitlib[] = {
|
||||
{"arshift", b_arshift},
|
||||
{"band", b_and},
|
||||
{"bnot", b_not},
|
||||
@@ -201,10 +202,11 @@ static const luaL_Reg bitlib[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
const luaR_value_entry bitlib_vals[] = {
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
LUAMOD_API int luaopen_bit32 (lua_State *L) {
|
||||
luaL_newlib(L, bitlib);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
ptrdiff_t funcr = savestack(L, func);
|
||||
switch (ttype(func)) {
|
||||
case LUA_TLCF: /* light C function */
|
||||
f = fvalue(func);
|
||||
f = lcfvalue(func);
|
||||
goto Cfunc;
|
||||
case LUA_TLIGHTFUNCTION:
|
||||
f = check_exp(ttislightfunction(func), val_(func).f);
|
||||
goto Cfunc;
|
||||
case LUA_TCCL: { /* C closure */
|
||||
f = clCvalue(func)->f;
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "lrotable.h"
|
||||
|
||||
/*
|
||||
** these libs are loaded by lua.c and are readily available to any Lua
|
||||
** program
|
||||
*/
|
||||
static const luaL_Reg loadedlibs[] = {
|
||||
{"_G", luaopen_base},
|
||||
// {"_G", luaopen_base},
|
||||
// {LUA_LOADLIBNAME, luaopen_package},
|
||||
// {LUA_COLIBNAME, luaopen_coroutine},
|
||||
// {LUA_TABLIBNAME, luaopen_table},
|
||||
@@ -34,11 +35,22 @@ static const luaL_Reg loadedlibs[] = {
|
||||
// {LUA_OSLIBNAME, luaopen_os},
|
||||
// {LUA_STRLIBNAME, luaopen_string},
|
||||
// {LUA_BITLIBNAME, luaopen_bit32},
|
||||
{LUA_MATHLIBNAME, luaopen_math},
|
||||
// {LUA_MATHLIBNAME, luaopen_math},
|
||||
// {LUA_DBLIBNAME, luaopen_debug},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* The read-only tables are defined here */
|
||||
const luaR_table lua_rotable[] =
|
||||
{
|
||||
{LUA_MATHLIBNAME, mathlib, mathlib_vals},
|
||||
{LUA_BITLIBNAME, bitlib, NULL},
|
||||
{"lcd", lcdLib, NULL},
|
||||
{"model", modelLib, NULL},
|
||||
{"__baselib", baselib, NULL},
|
||||
{"__opentx", opentxLib, opentxConstants},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
** these libs are preloaded and must be required before used
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lrotable.h"
|
||||
|
||||
#undef PI
|
||||
#define PI ((lua_Number)(3.1415926535897932384626433832795))
|
||||
@@ -228,20 +229,19 @@ static int math_randomseed (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_Reg mathlib[] = {
|
||||
const luaL_Reg mathlib[] = {
|
||||
{"abs", math_abs},
|
||||
{"acos", math_acos},
|
||||
{"asin", math_asin},
|
||||
{"atan2", math_atan2},
|
||||
{"atan", math_atan},
|
||||
{"ceil", math_ceil},
|
||||
{"cosh", math_cosh},
|
||||
{"cosh", math_cosh},
|
||||
{"cos", math_cos},
|
||||
{"deg", math_deg},
|
||||
{"exp", math_exp},
|
||||
{"floor", math_floor},
|
||||
{"fmod", math_fmod},
|
||||
{"fmod", math_fmod},
|
||||
{"frexp", math_frexp},
|
||||
{"ldexp", math_ldexp},
|
||||
#if defined(LUA_COMPAT_LOG10)
|
||||
@@ -263,16 +263,16 @@ static const luaL_Reg mathlib[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
const luaR_value_entry mathlib_vals[] = {
|
||||
{"pi", PI},
|
||||
{"huge", HUGE_VAL},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
** Open math library
|
||||
*/
|
||||
LUAMOD_API int luaopen_math (lua_State *L) {
|
||||
luaL_newlib(L, mathlib);
|
||||
lua_pushnumber(L, PI);
|
||||
lua_setfield(L, -2, "pi");
|
||||
lua_pushnumber(L, HUGE_VAL);
|
||||
lua_setfield(L, -2, "huge");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,8 @@ typedef union Value Value;
|
||||
#define ttisnil(o) checktag((o), LUA_TNIL)
|
||||
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
|
||||
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
|
||||
#define ttisrotable(o) checktag((o), LUA_TROTABLE)
|
||||
#define ttislightfunction(o) checktag((o), LUA_TLIGHTFUNCTION)
|
||||
#define ttisstring(o) checktype((o), LUA_TSTRING)
|
||||
#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
|
||||
#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
|
||||
@@ -156,6 +158,8 @@ typedef union Value Value;
|
||||
#define nvalue(o) check_exp(ttisnumber(o), num_(o))
|
||||
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
|
||||
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
||||
#define rvalue(o) check_exp(ttisrotable(o), val_(o).p)
|
||||
#define lfvalue(o) check_exp(ttislightfunction(o), val_(o).p)
|
||||
#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)
|
||||
#define tsvalue(o) (&rawtsvalue(o)->tsv)
|
||||
#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
|
||||
@@ -163,7 +167,7 @@ typedef union Value Value;
|
||||
#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
|
||||
#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
|
||||
#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
|
||||
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
|
||||
#define lcfvalue(o) check_exp(ttislcf(o), val_(o).f)
|
||||
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
|
||||
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
|
||||
#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th)
|
||||
@@ -192,12 +196,18 @@ typedef union Value Value;
|
||||
|
||||
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
|
||||
|
||||
#define setfvalue(obj,x) \
|
||||
#define setlcfvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
|
||||
|
||||
#define setpvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
|
||||
|
||||
#define setrvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TROTABLE); }
|
||||
|
||||
#define setlfvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTFUNCTION); }
|
||||
|
||||
#define setbvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Read-only tables for Lua */
|
||||
|
||||
#include <string.h>
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lrotable.h"
|
||||
|
||||
/* Local defines */
|
||||
#define LUAR_FINDFUNCTION 0
|
||||
#define LUAR_FINDVALUE 1
|
||||
|
||||
/* Utility function: find a key in a given table (of functions or constants) */
|
||||
static luaR_result luaR_findkey(const void *where, const char *key, int type, int *found) {
|
||||
const char *pname;
|
||||
const luaL_Reg *pf = (luaL_Reg*)where;
|
||||
const luaR_value_entry *pv = (luaR_value_entry*)where;
|
||||
int isfunction = type == LUAR_FINDFUNCTION;
|
||||
*found = 0;
|
||||
if(!where)
|
||||
return 0;
|
||||
while(1) {
|
||||
if (!(pname = isfunction ? pf->name : pv->name))
|
||||
break;
|
||||
if (!strcmp(pname, key)) {
|
||||
*found = 1;
|
||||
return isfunction ? (luaR_result)(size_t)pf->func : (luaR_result)pv->value;
|
||||
}
|
||||
pf ++; pv ++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find a global "read only table" in the constant lua_rotable array */
|
||||
luaR_result luaR_findglobal(const char *name, lu_byte *ptype) {
|
||||
unsigned i;
|
||||
*ptype = LUA_TNIL;
|
||||
if (strlen(name) > LUA_MAX_ROTABLE_NAME)
|
||||
return 0;
|
||||
for (i=0; lua_rotable[i].name; i++) {
|
||||
if (!strcmp(lua_rotable[i].name, name)) {
|
||||
*ptype = LUA_TROTABLE;
|
||||
return i+1;
|
||||
}
|
||||
if (!strncmp(lua_rotable[i].name, "__", 2)) {
|
||||
int result = luaR_findentry((void *)(size_t)(i+1), name, ptype);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int luaR_findfunction(lua_State *L, const luaL_Reg *ptable) {
|
||||
int found;
|
||||
const char *key = luaL_checkstring(L, 2);
|
||||
luaR_result res = luaR_findkey(ptable, key, LUAR_FINDFUNCTION, &found);
|
||||
if (found)
|
||||
lua_pushlightfunction(L, (void*)(size_t)res);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
luaR_result luaR_findentry(void *data, const char *key, lu_byte *ptype) {
|
||||
int found;
|
||||
unsigned idx = (unsigned)(size_t)data - 1;
|
||||
luaR_result res;
|
||||
*ptype = LUA_TNIL;
|
||||
/* First look at the functions */
|
||||
res = luaR_findkey(lua_rotable[idx].pfuncs, key, LUAR_FINDFUNCTION, &found);
|
||||
if (found) {
|
||||
*ptype = LUA_TLIGHTFUNCTION;
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
/* Then at the values */
|
||||
res = luaR_findkey(lua_rotable[idx].pvalues, key, LUAR_FINDVALUE, &found);
|
||||
if(found) {
|
||||
*ptype = LUA_TNUMBER;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Read-only tables for Lua
|
||||
|
||||
#ifndef lrotable_h
|
||||
#define lrotable_h
|
||||
|
||||
#include "lua.h"
|
||||
#include "llimits.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
typedef lua_Number luaR_result;
|
||||
|
||||
// A number entry in the read only table
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
lua_Number value;
|
||||
} luaR_value_entry;
|
||||
|
||||
extern const luaR_value_entry baselib_vals[];
|
||||
extern const luaR_value_entry mathlib_vals[];
|
||||
extern const luaR_value_entry opentxConstants[];
|
||||
|
||||
// A mapping between table name and its entries
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
const luaL_Reg *pfuncs;
|
||||
const luaR_value_entry *pvalues;
|
||||
} luaR_table;
|
||||
|
||||
extern const luaR_table lua_rotable[];
|
||||
|
||||
luaR_result luaR_findglobal(const char *key, lu_byte *ptype);
|
||||
int luaR_findfunction(lua_State *L, const luaL_Reg *ptable);
|
||||
luaR_result luaR_findentry(void *data, const char *key, lu_byte *ptype);
|
||||
|
||||
#endif
|
||||
@@ -113,7 +113,7 @@ static Node *mainposition (const Table *t, const TValue *key) {
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return hashpointer(t, pvalue(key));
|
||||
case LUA_TLCF:
|
||||
return hashpointer(t, fvalue(key));
|
||||
return hashpointer(t, lcfvalue(key));
|
||||
default:
|
||||
return hashpointer(t, gcvalue(key));
|
||||
}
|
||||
|
||||
@@ -23,12 +23,11 @@ static const char udatatypename[] = "userdata";
|
||||
|
||||
LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
|
||||
"no value",
|
||||
"nil", "boolean", udatatypename, "number",
|
||||
"nil", "boolean", "rotable", "lightfunction", udatatypename, "number",
|
||||
"string", "table", "function", udatatypename, "thread",
|
||||
"proto", "upval" /* these last two cases are used for tests only */
|
||||
};
|
||||
|
||||
|
||||
void luaT_init (lua_State *L) {
|
||||
static const char *const luaT_eventname[] = { /* ORDER TM */
|
||||
"__index", "__newindex",
|
||||
|
||||
+12
-8
@@ -77,15 +77,17 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
#define LUA_TNIL 0
|
||||
#define LUA_TBOOLEAN 1
|
||||
#define LUA_TLIGHTUSERDATA 2
|
||||
#define LUA_TNUMBER 3
|
||||
#define LUA_TSTRING 4
|
||||
#define LUA_TTABLE 5
|
||||
#define LUA_TFUNCTION 6
|
||||
#define LUA_TUSERDATA 7
|
||||
#define LUA_TTHREAD 8
|
||||
#define LUA_TROTABLE 2
|
||||
#define LUA_TLIGHTFUNCTION 3
|
||||
#define LUA_TLIGHTUSERDATA 4
|
||||
#define LUA_TNUMBER 5
|
||||
#define LUA_TSTRING 6
|
||||
#define LUA_TTABLE 7
|
||||
#define LUA_TFUNCTION 8
|
||||
#define LUA_TUSERDATA 9
|
||||
#define LUA_TTHREAD 10
|
||||
|
||||
#define LUA_NUMTAGS 9
|
||||
#define LUA_NUMTAGS 11
|
||||
|
||||
|
||||
|
||||
@@ -214,6 +216,8 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
|
||||
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
|
||||
LUA_API void (lua_pushboolean) (lua_State *L, int b);
|
||||
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
|
||||
LUA_API void (lua_pushlightfunction) (lua_State *L, void *p);
|
||||
LUA_API void (lua_pushrotable) (lua_State *L, void *p);
|
||||
LUA_API int (lua_pushthread) (lua_State *L);
|
||||
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@
|
||||
** without modifying the main part of the file.
|
||||
*/
|
||||
|
||||
|
||||
#define LUA_MAX_ROTABLE_NAME 20
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+149
-51
@@ -25,7 +25,7 @@
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
#include "lvm.h"
|
||||
|
||||
#include "lrotable.h"
|
||||
|
||||
|
||||
/* limit for table tag-method chains (to avoid loops) */
|
||||
@@ -106,9 +106,31 @@ static void callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||
}
|
||||
}
|
||||
|
||||
static void lua_getcstr(char *dest, const TString *src, size_t maxsize) {
|
||||
if (src->tsv.len+1 > maxsize)
|
||||
dest[0] = '\0';
|
||||
else {
|
||||
memcpy(dest, getstr(src), src->tsv.len);
|
||||
dest[src->tsv.len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
||||
int loop;
|
||||
if (ttisrotable(t)) {
|
||||
setnilvalue(val);
|
||||
if (ttisstring(key)) {
|
||||
char keyname[LUA_MAX_ROTABLE_NAME + 1];
|
||||
lu_byte keytype;
|
||||
lua_getcstr(keyname, rawtsvalue(key), LUA_MAX_ROTABLE_NAME);
|
||||
luaR_result res = luaR_findentry(rvalue(t), keyname, &keytype);
|
||||
if (keytype == LUA_TLIGHTFUNCTION)
|
||||
setlfvalue(val, (void*)(size_t)res)
|
||||
else if (keytype == LUA_TNUMBER)
|
||||
setnvalue(val, (lua_Number)res)
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||
const TValue *tm;
|
||||
if (ttistable(t)) { /* `t' is a table? */
|
||||
@@ -123,7 +145,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
||||
}
|
||||
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
|
||||
luaG_typeerror(L, t, "index");
|
||||
if (ttisfunction(tm)) {
|
||||
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
||||
callTM(L, tm, t, key, val, 1);
|
||||
return;
|
||||
}
|
||||
@@ -264,8 +286,11 @@ int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
|
||||
case LUA_TNIL: return 1;
|
||||
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
|
||||
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
|
||||
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
|
||||
case LUA_TLCF: return fvalue(t1) == fvalue(t2);
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TROTABLE:
|
||||
case LUA_TLIGHTFUNCTION:
|
||||
return pvalue(t1) == pvalue(t2);
|
||||
case LUA_TLCF: return lcfvalue(t1) == lcfvalue(t2);
|
||||
case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
|
||||
case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
|
||||
case LUA_TUSERDATA: {
|
||||
@@ -554,53 +579,97 @@ void luaV_execute (lua_State *L) {
|
||||
lua_assert(base == ci->u.l.base);
|
||||
lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
|
||||
vmdispatch (GET_OPCODE(i)) {
|
||||
vmcase(OP_MOVE,
|
||||
case OP_MOVE:
|
||||
setobjs2s(L, ra, RB(i));
|
||||
)
|
||||
vmcase(OP_LOADK,
|
||||
break;
|
||||
|
||||
case OP_LOADK:
|
||||
{
|
||||
TValue *rb = k + GETARG_Bx(i);
|
||||
setobj2s(L, ra, rb);
|
||||
)
|
||||
vmcase(OP_LOADKX,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_LOADKX:
|
||||
{
|
||||
TValue *rb;
|
||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
|
||||
rb = k + GETARG_Ax(*ci->u.l.savedpc++);
|
||||
setobj2s(L, ra, rb);
|
||||
)
|
||||
vmcase(OP_LOADBOOL,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_LOADBOOL:
|
||||
setbvalue(ra, GETARG_B(i));
|
||||
if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
|
||||
)
|
||||
vmcase(OP_LOADNIL,
|
||||
break;
|
||||
|
||||
case OP_LOADNIL:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
do {
|
||||
setnilvalue(ra++);
|
||||
} while (b--);
|
||||
)
|
||||
vmcase(OP_GETUPVAL,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_GETUPVAL:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
setobj2s(L, ra, cl->upvals[b]->v);
|
||||
)
|
||||
vmcase(OP_GETTABUP,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_GETTABUP:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
|
||||
)
|
||||
vmcase(OP_GETTABLE,
|
||||
if (ttisstring(RKC(i))) {
|
||||
char keyname[LUA_MAX_ROTABLE_NAME + 1];
|
||||
lu_byte keytype;
|
||||
lua_getcstr(keyname, rawtsvalue(RKC(i)), LUA_MAX_ROTABLE_NAME);
|
||||
luaR_result res = luaR_findglobal(keyname, &keytype);
|
||||
if (keytype == LUA_TROTABLE) {
|
||||
setrvalue(ra, (void*)(size_t)res)
|
||||
}
|
||||
else if (keytype == LUA_TLIGHTFUNCTION)
|
||||
setlfvalue(ra, (void*)(size_t)res)
|
||||
else if (keytype == LUA_TNUMBER)
|
||||
setnvalue(ra, (lua_Number)res)
|
||||
else
|
||||
Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
|
||||
}
|
||||
else {
|
||||
Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_GETTABLE:
|
||||
/* First try to look for a rotable with this name */
|
||||
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
|
||||
)
|
||||
vmcase(OP_SETTABUP,
|
||||
break;
|
||||
|
||||
case OP_SETTABUP:
|
||||
{
|
||||
int a = GETARG_A(i);
|
||||
Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
|
||||
)
|
||||
vmcase(OP_SETUPVAL,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SETUPVAL:
|
||||
{
|
||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||
setobj(L, uv->v, ra);
|
||||
luaC_barrier(L, uv, ra);
|
||||
)
|
||||
vmcase(OP_SETTABLE,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SETTABLE:
|
||||
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
|
||||
)
|
||||
vmcase(OP_NEWTABLE,
|
||||
break;
|
||||
|
||||
case OP_NEWTABLE:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
int c = GETARG_C(i);
|
||||
Table *t = luaH_new(L);
|
||||
@@ -608,31 +677,43 @@ void luaV_execute (lua_State *L) {
|
||||
if (b != 0 || c != 0)
|
||||
luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
|
||||
checkGC(L, ra + 1);
|
||||
)
|
||||
vmcase(OP_SELF,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SELF:
|
||||
{
|
||||
StkId rb = RB(i);
|
||||
setobjs2s(L, ra+1, rb);
|
||||
Protect(luaV_gettable(L, rb, RKC(i), ra));
|
||||
)
|
||||
vmcase(OP_ADD,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_ADD:
|
||||
arith_op(luai_numadd, TM_ADD);
|
||||
)
|
||||
vmcase(OP_SUB,
|
||||
break;
|
||||
|
||||
case OP_SUB:
|
||||
arith_op(luai_numsub, TM_SUB);
|
||||
)
|
||||
vmcase(OP_MUL,
|
||||
break;
|
||||
|
||||
case OP_MUL:
|
||||
arith_op(luai_nummul, TM_MUL);
|
||||
)
|
||||
vmcase(OP_DIV,
|
||||
break;
|
||||
|
||||
case OP_DIV:
|
||||
arith_op(luai_numdiv, TM_DIV);
|
||||
)
|
||||
vmcase(OP_MOD,
|
||||
break;
|
||||
|
||||
case OP_MOD:
|
||||
arith_op(luai_nummod, TM_MOD);
|
||||
)
|
||||
vmcase(OP_POW,
|
||||
break;
|
||||
|
||||
case OP_POW:
|
||||
arith_op(luai_numpow, TM_POW);
|
||||
)
|
||||
vmcase(OP_UNM,
|
||||
break;
|
||||
|
||||
case OP_UNM:
|
||||
{
|
||||
TValue *rb = RB(i);
|
||||
if (ttisnumber(rb)) {
|
||||
lua_Number nb = nvalue(rb);
|
||||
@@ -641,15 +722,19 @@ void luaV_execute (lua_State *L) {
|
||||
else {
|
||||
Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
|
||||
}
|
||||
)
|
||||
}
|
||||
break;
|
||||
|
||||
vmcase(OP_NOT,
|
||||
TValue *rb = RB(i);
|
||||
int res = l_isfalse(rb); /* next assignment may change this value */
|
||||
setbvalue(ra, res);
|
||||
)
|
||||
|
||||
vmcase(OP_LEN,
|
||||
Protect(luaV_objlen(L, ra, RB(i)));
|
||||
)
|
||||
|
||||
vmcase(OP_CONCAT,
|
||||
int b = GETARG_B(i);
|
||||
int c = GETARG_C(i);
|
||||
@@ -662,9 +747,11 @@ void luaV_execute (lua_State *L) {
|
||||
checkGC(L, (ra >= rb ? ra + 1 : rb));
|
||||
L->top = ci->top; /* restore top */
|
||||
)
|
||||
|
||||
vmcase(OP_JMP,
|
||||
dojump(ci, i, 0);
|
||||
)
|
||||
|
||||
vmcase(OP_EQ,
|
||||
TValue *rb = RKB(i);
|
||||
TValue *rc = RKC(i);
|
||||
@@ -675,6 +762,7 @@ void luaV_execute (lua_State *L) {
|
||||
donextjump(ci);
|
||||
)
|
||||
)
|
||||
|
||||
vmcase(OP_LT,
|
||||
Protect(
|
||||
if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
|
||||
@@ -706,7 +794,9 @@ void luaV_execute (lua_State *L) {
|
||||
donextjump(ci);
|
||||
}
|
||||
)
|
||||
vmcase(OP_CALL,
|
||||
|
||||
case OP_CALL:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
int nresults = GETARG_C(i) - 1;
|
||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||
@@ -719,8 +809,11 @@ void luaV_execute (lua_State *L) {
|
||||
ci->callstatus |= CIST_REENTRY;
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
)
|
||||
vmcase(OP_TAILCALL,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_TAILCALL:
|
||||
{
|
||||
int b = GETARG_B(i);
|
||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
||||
@@ -748,7 +841,8 @@ void luaV_execute (lua_State *L) {
|
||||
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
vmcasenb(OP_RETURN,
|
||||
int b = GETARG_B(i);
|
||||
if (b != 0) L->top = ra+b-1;
|
||||
@@ -764,7 +858,9 @@ void luaV_execute (lua_State *L) {
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
)
|
||||
vmcase(OP_FORLOOP,
|
||||
|
||||
case OP_FORLOOP:
|
||||
{
|
||||
lua_Number step = nvalue(ra+2);
|
||||
lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
|
||||
lua_Number limit = nvalue(ra+1);
|
||||
@@ -774,7 +870,9 @@ void luaV_execute (lua_State *L) {
|
||||
setnvalue(ra, idx); /* update internal index... */
|
||||
setnvalue(ra+3, idx); /* ...and external index */
|
||||
}
|
||||
)
|
||||
}
|
||||
break;
|
||||
|
||||
vmcase(OP_FORPREP,
|
||||
const TValue *init = ra;
|
||||
const TValue *plimit = ra+1;
|
||||
|
||||
+5
-2
@@ -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];
|
||||
@@ -251,8 +252,10 @@ int16_t applyLimits(uint8_t channel, int32_t value)
|
||||
if (lim->revert) ofs = -ofs; // finally do the reverse.
|
||||
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
if (safetyCh[channel] != -128) // if safety channel available for channel check
|
||||
if (safetyCh[channel] != OVERRIDE_CHANNEL_UNDEFINED) {
|
||||
// safety channel available for channel check
|
||||
ofs = calc100toRESX(safetyCh[channel]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ofs;
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
CURVE_TYPE_CUSTOM,
|
||||
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
||||
};
|
||||
PACK(typedef struct t_CurveInfo {
|
||||
PACK(typedef struct {
|
||||
uint8_t type:3;
|
||||
uint8_t smooth:1;
|
||||
uint8_t spare:4;
|
||||
@@ -473,7 +473,7 @@ enum CurveRefType {
|
||||
CURVE_REF_FUNC,
|
||||
CURVE_REF_CUSTOM
|
||||
};
|
||||
PACK(typedef struct t_CurveRef {
|
||||
PACK(typedef struct {
|
||||
uint8_t type;
|
||||
int8_t value;
|
||||
}) CurveRef;
|
||||
|
||||
+39
-7
@@ -148,7 +148,7 @@ uint8_t heartbeat;
|
||||
uint8_t stickMode;
|
||||
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
int8_t safetyCh[NUM_CHNOUT];
|
||||
safetych_t safetyCh[NUM_CHNOUT];
|
||||
#endif
|
||||
|
||||
union ReusableBuffer reusableBuffer;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1881,7 +1904,7 @@ void evalFunctions()
|
||||
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
safetyCh[i] = -128; // not defined
|
||||
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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 0 // 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)
|
||||
|
||||
+37
-13
@@ -621,7 +621,12 @@ extern uint8_t pxxFlag[NUM_MODULES];
|
||||
#define PXX_SEND_RANGECHECK (1 << 5)
|
||||
|
||||
#define LEN_STD_CHARS 40
|
||||
|
||||
#if defined(TRANSLATIONS_CZ)
|
||||
#define ZCHAR_MAX (LEN_STD_CHARS)
|
||||
#else
|
||||
#define ZCHAR_MAX (LEN_STD_CHARS + LEN_SPECIAL_CHARS)
|
||||
#endif
|
||||
|
||||
char idx2char(int8_t idx);
|
||||
#if defined(CPUARM) || defined(SIMU)
|
||||
@@ -693,7 +698,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
|
||||
|
||||
@@ -851,7 +857,14 @@ struct TimerState {
|
||||
extern TimerState timersStates[MAX_TIMERS];
|
||||
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
extern int8_t safetyCh[NUM_CHNOUT];
|
||||
#if defined(CPUARM)
|
||||
typedef int16_t safetych_t;
|
||||
#define OVERRIDE_CHANNEL_UNDEFINED -4096
|
||||
#else
|
||||
typedef int8_t safetych_t;
|
||||
#define OVERRIDE_CHANNEL_UNDEFINED -128
|
||||
#endif
|
||||
extern safetych_t safetyCh[NUM_CHNOUT];
|
||||
#endif
|
||||
|
||||
extern uint8_t trimsCheckTimer;
|
||||
@@ -1465,13 +1478,14 @@ enum AUDIO_SOUNDS {
|
||||
SCRIPT_OK,
|
||||
SCRIPT_NOFILE,
|
||||
SCRIPT_SYNTAX_ERROR,
|
||||
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,28 +1502,38 @@ enum AUDIO_SOUNDS {
|
||||
uint8_t outputsCount;
|
||||
ScriptOutput outputs[MAX_SCRIPT_OUTPUTS];
|
||||
};
|
||||
#define LUASTATE_STANDALONE_SCRIPT_RUNNING 1
|
||||
#define LUASTATE_RELOAD_MODEL_SCRIPTS 2
|
||||
#define INTERPRETER_RUNNING_STANDALONE_SCRIPT 1
|
||||
#define INTERPRETER_RELOAD_PERMANENT_SCRIPTS 2
|
||||
#define INTERPRETER_PANIC 255
|
||||
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);
|
||||
void luaLoadMixScript(uint8_t index);
|
||||
void luaLoadMixScripts();
|
||||
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
|
||||
|
||||
@@ -308,9 +308,10 @@ void putPcmHead()
|
||||
putPcmPart( 0xC0 ) ;
|
||||
}
|
||||
|
||||
uint16_t scaleForPXX(uint8_t i)
|
||||
uint16_t scaleForPXX( uint8_t i )
|
||||
{
|
||||
return channelOutputs[i] * 3 / 4 + 2250 ;
|
||||
int16_t value = ( ( i < 16 ) ? channelOutputs[i] * 3 / 4 : 0 ) + 1024;
|
||||
return limit<uint16_t>(1, value, 2046);
|
||||
}
|
||||
|
||||
void setupPulsesPXX()
|
||||
|
||||
@@ -49,7 +49,7 @@ char idx2char(int8_t idx)
|
||||
if (idx < 37) return '0' + idx - 27;
|
||||
if (idx <= 40) return pgm_read_byte(s_charTab+idx-37);
|
||||
#if LEN_SPECIAL_CHARS > 0
|
||||
if (idx <= ZCHAR_MAX) return 'z' + 5 + idx - 40;
|
||||
if (idx <= (LEN_STD_CHARS + LEN_SPECIAL_CHARS)) return 'z' + 5 + idx - 40;
|
||||
#endif
|
||||
return ' ';
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,6 @@ FORCEINLINE void readKeysAndTrims()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ROTARY_ENCODERS <= 2
|
||||
ISR(INT2_vect)
|
||||
{
|
||||
uint8_t input = (PIND & 0x0C);
|
||||
@@ -313,7 +312,6 @@ ISR(INT3_vect)
|
||||
uint8_t input = (PIND & 0x0C);
|
||||
if (input == 0 || input == 0x0C) incRotaryEncoder(0, +1);
|
||||
}
|
||||
#endif
|
||||
|
||||
ISR(INT5_vect)
|
||||
{
|
||||
|
||||
@@ -82,14 +82,12 @@
|
||||
#define JACK_PPM_OUT() PORTG |= (1<<OUT_G_SIM_CTL)
|
||||
#define JACK_PPM_IN() PORTG &= ~(1<<OUT_G_SIM_CTL)
|
||||
|
||||
#define sdDone()
|
||||
|
||||
// SD driver
|
||||
#define sdDone()
|
||||
#if !defined(SIMU)
|
||||
bool sdMounted();
|
||||
void sdMountPoll();
|
||||
void sdPoll10ms();
|
||||
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_BLOCKNR() (0)
|
||||
#define SD_GET_SIZE_MB() (0)
|
||||
@@ -193,13 +191,8 @@ void pwrOff();
|
||||
#define HAPTIC_OFF() PORTD |= (1 << OUT_D_HAPTIC)
|
||||
|
||||
// Rotary encoder driver
|
||||
#if ROTARY_ENCODERS <= 2
|
||||
#define REA_DOWN() (~PIND & 0x20)
|
||||
#define REB_DOWN() (~PIND & 0x10)
|
||||
#else
|
||||
#define REA_DOWN() (0)
|
||||
#define REB_DOWN() (0)
|
||||
#endif
|
||||
#define REA_DOWN() (~PIND & 0x20)
|
||||
#define REB_DOWN() (~PIND & 0x10)
|
||||
#define ROTENC_DOWN() (REA_DOWN() || REB_DOWN())
|
||||
|
||||
#endif
|
||||
|
||||
@@ -116,12 +116,6 @@ void pwrOff()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ROTARY_ENCODERS <= 2
|
||||
#define ROTENC_DOWN() ((~PIND & 0x20) || (~PIND & 0x10))
|
||||
#else
|
||||
#define ROTENC_DOWN() (0)
|
||||
#endif
|
||||
|
||||
FORCEINLINE uint8_t keyDown()
|
||||
{
|
||||
return ((~PINL) & 0x3F) || ROTENC_DOWN();
|
||||
@@ -196,6 +190,24 @@ bool switchState(EnumKeys enuk)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Trim switches ...
|
||||
static const pm_uchar crossTrim[] PROGMEM ={
|
||||
1<<INP_F_TRM_LH_DWN,
|
||||
1<<INP_F_TRM_LH_UP,
|
||||
1<<INP_F_TRM_LV_DWN,
|
||||
1<<INP_F_TRM_LV_UP,
|
||||
1<<INP_F_TRM_RV_DWN,
|
||||
1<<INP_F_TRM_RV_UP,
|
||||
1<<INP_F_TRM_RH_DWN,
|
||||
1<<INP_F_TRM_RH_UP
|
||||
};
|
||||
|
||||
uint8_t trimDown(uint8_t idx)
|
||||
{
|
||||
uint8_t in = ~PIND;
|
||||
return (in & pgm_read_byte(crossTrim+idx));
|
||||
}
|
||||
|
||||
FORCEINLINE void readKeysAndTrims()
|
||||
{
|
||||
/* Original keys were connected to PORTB as follows:
|
||||
@@ -213,40 +225,28 @@ FORCEINLINE void readKeysAndTrims()
|
||||
|
||||
uint8_t enuk = KEY_MENU;
|
||||
|
||||
keys[BTN_REa].input(~PIND & 0x20, BTN_REa);
|
||||
keys[BTN_REb].input(~PIND & 0x10, BTN_REb);
|
||||
|
||||
// User buttons ...
|
||||
uint8_t tin = ~PINL;
|
||||
uint8_t in;
|
||||
in = (tin & 0x0f) << 3;
|
||||
in |= (tin & 0x30) >> 3;
|
||||
|
||||
for (int i=1; i<7; i++)
|
||||
{
|
||||
for (int i=1; i<7; i++) {
|
||||
//INP_B_KEY_MEN 1 .. INP_B_KEY_LFT 6
|
||||
keys[enuk].input(in & (1<<i),(EnumKeys)enuk);
|
||||
++enuk;
|
||||
}
|
||||
|
||||
// Trim switches ...
|
||||
static const pm_uchar crossTrim[] PROGMEM ={
|
||||
1<<INP_F_TRM_LH_DWN,
|
||||
1<<INP_F_TRM_LH_UP,
|
||||
1<<INP_F_TRM_LV_DWN,
|
||||
1<<INP_F_TRM_LV_UP,
|
||||
1<<INP_F_TRM_RV_DWN,
|
||||
1<<INP_F_TRM_RV_UP,
|
||||
1<<INP_F_TRM_RH_DWN,
|
||||
1<<INP_F_TRM_RH_UP
|
||||
};
|
||||
|
||||
// Trims ...
|
||||
in = ~PINF;
|
||||
|
||||
for (int i=0; i<8; i++) {
|
||||
// INP_D_TRM_RH_UP 0 .. INP_D_TRM_LH_UP 7
|
||||
keys[enuk].input(in & pgm_read_byte(crossTrim+i),(EnumKeys)enuk);
|
||||
++enuk;
|
||||
}
|
||||
|
||||
keys[BTN_REa].input(REA_DOWN(), BTN_REa);
|
||||
keys[BTN_REb].input(REB_DOWN(), BTN_REb);
|
||||
}
|
||||
|
||||
ISR(INT2_vect)
|
||||
|
||||
@@ -83,12 +83,11 @@
|
||||
#define JACK_PPM_IN() PORTG &= ~(1<<OUT_G_SIM_CTL)
|
||||
|
||||
// SD driver
|
||||
#define sdDone()
|
||||
#if !defined(SIMU)
|
||||
bool sdMounted();
|
||||
void sdMountPoll();
|
||||
void sdPoll10ms();
|
||||
#define sdDone()
|
||||
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_BLOCKNR() (0)
|
||||
#define SD_GET_SIZE_MB() (0)
|
||||
@@ -143,6 +142,7 @@ void sdPoll10ms();
|
||||
# define OUT_G_SIM_CTL 4 //1 : phone-jack=ppm_in
|
||||
|
||||
# define INP_C_ID1 0
|
||||
# define INP_C_ID2 1
|
||||
|
||||
# define INP_G_RF_POW 1
|
||||
# define INP_G_RuddDR 0
|
||||
@@ -155,8 +155,6 @@ void sdPoll10ms();
|
||||
# define OUT_B_PPM 6
|
||||
# define INP_B_Trainer 5
|
||||
|
||||
# define INP_C_ID2 1
|
||||
|
||||
#if defined(VOICE)
|
||||
# define OUT_H_14DRESET 3
|
||||
# define OUT_H_14DCLK 4
|
||||
@@ -194,4 +192,9 @@ void pwrOff();
|
||||
#define HAPTIC_ON() PORTD &= ~(1 << OUT_D_HAPTIC)
|
||||
#define HAPTIC_OFF() PORTD |= (1 << OUT_D_HAPTIC)
|
||||
|
||||
// Rotary encoder driver
|
||||
#define REA_DOWN() (~PIND & 0x20)
|
||||
#define REB_DOWN() (~PIND & 0x10)
|
||||
#define ROTENC_DOWN() (REA_DOWN() || REB_DOWN())
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
volatile uint8_t pina=0xff, pinb=0xff, pinc=0xff, pind, pine=0xff, ping=0xff, pinh=0xff, pinj=0xff, pinl=0;
|
||||
volatile uint8_t pina=0xff, pinb=0xff, pinc=0xff, pind, pine=0xff, pinf=0xff, ping=0xff, pinh=0xff, pinj=0xff, pinl=0;
|
||||
uint8_t portb, portc, porth=0, dummyport;
|
||||
uint16_t dummyport16;
|
||||
const char *eepromFile = NULL;
|
||||
@@ -158,7 +158,7 @@ void simuSetKey(uint8_t key, bool state)
|
||||
#endif
|
||||
#if defined(PCBSKY9X) && !defined(REVX)
|
||||
KEY_CASE(BTN_REa, PIOB->PIO_PDSR, 0x40)
|
||||
#elif defined(PCBGRUVIN9X)
|
||||
#elif defined(PCBGRUVIN9X) || defined(PCBMEGA2560)
|
||||
KEY_CASE(BTN_REa, pind, 0x20)
|
||||
#elif defined(ROTARY_ENCODER_NAVIGATION)
|
||||
KEY_CASE(BTN_REa, RotEncoder, 0x20)
|
||||
@@ -212,7 +212,15 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
|
||||
SWITCH_CASE(4, pinc, 1<<INP_C_AileDR)
|
||||
SWITCH_CASE(5, ping, 1<<INP_G_Gear)
|
||||
SWITCH_CASE(6, pinb, 1<<INP_B_Trainer)
|
||||
#else // STOCK
|
||||
#elif defined(PCBMEGA2560)
|
||||
SWITCH_CASE(0, ping, 1<<INP_G_ThrCt)
|
||||
SWITCH_CASE(1, ping, 1<<INP_G_RuddDR)
|
||||
SWITCH_CASE(2, pinc, 1<<INP_C_ElevDR)
|
||||
SWITCH_3_CASE(3, pinc, pinc, (1<<INP_C_ID1), (1<<INP_C_ID2))
|
||||
SWITCH_CASE(4, pinc, 1<<INP_C_AileDR)
|
||||
SWITCH_CASE(5, ping, 1<<INP_G_Gear)
|
||||
SWITCH_CASE(6, pinb, 1<<INP_B_Trainer)
|
||||
#else // PCB9X
|
||||
#if defined(JETI) || defined(FRSKY) || defined(NMEA) || defined(ARDUPILOT)
|
||||
SWITCH_CASE(0, pinc, 1<<INP_C_ThrCt)
|
||||
SWITCH_CASE(4, pinc, 1<<INP_C_AileDR)
|
||||
@@ -309,8 +317,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();
|
||||
}
|
||||
|
||||
@@ -225,6 +225,7 @@ extern void rxPdcUsart( void (*pChProcess)(uint8_t x) );
|
||||
#define PINC ~pinc
|
||||
#define PIND ~pind
|
||||
#define PINE ~pine
|
||||
#define PINF ~pinf
|
||||
#define PING ~ping
|
||||
#define PINH ~pinh
|
||||
#define PINJ ~pinj
|
||||
@@ -334,7 +335,7 @@ extern uint32_t Master_frequency;
|
||||
#define __enable_irq()
|
||||
#endif
|
||||
|
||||
extern volatile unsigned char pina, pinb, pinc, pind, pine, ping, pinh, pinj, pinl;
|
||||
extern volatile unsigned char pina, pinb, pinc, pind, pine, pinf, ping, pinh, pinj, pinl;
|
||||
extern uint8_t portb, portc, porth, dummyport;
|
||||
extern uint16_t dummyport16;
|
||||
extern uint8_t main_thread_running;
|
||||
|
||||
@@ -107,6 +107,7 @@ bool dacQueue(AudioBuffer *buffer)
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GCC optimize ("O1")
|
||||
extern "C" void DAC_IRQHandler()
|
||||
{
|
||||
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer();
|
||||
@@ -118,6 +119,7 @@ extern "C" void DAC_IRQHandler()
|
||||
dacStop();
|
||||
}
|
||||
}
|
||||
#pragma GCC optimize ("O2")
|
||||
|
||||
// Sound routines
|
||||
void audioInit()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -142,8 +142,9 @@ extern int _write( int file, char *ptr, int len )
|
||||
|
||||
extern void _exit( int status )
|
||||
{
|
||||
#if defined(SIMU)
|
||||
printf( "Exiting with status %d.\n", status ) ;
|
||||
|
||||
#endif
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
@@ -156,3 +157,8 @@ extern int _getpid ( void )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
void _init (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
volatile uint16_t Analog_values[NUMBER_ANALOG];
|
||||
|
||||
#if defined(REVPLUS)
|
||||
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,-1,1,-1,1, 1};
|
||||
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1,-1,1, 1};
|
||||
#elif defined(REV4a)
|
||||
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,-1,0,-1,1, 1};
|
||||
#elif !defined(REV3)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 |
+32
-32
@@ -54,7 +54,7 @@
|
||||
#define LEN_SPECIAL_CHARS 6
|
||||
#elif defined(TRANSLATIONS_CZ)
|
||||
#include "translations/cz.h"
|
||||
#define LEN_SPECIAL_CHARS 0
|
||||
#define LEN_SPECIAL_CHARS 17
|
||||
#elif defined(TRANSLATIONS_ES)
|
||||
#include "translations/es.h"
|
||||
#define LEN_SPECIAL_CHARS 0
|
||||
@@ -372,7 +372,7 @@ extern const pm_char STR_BLADES[];
|
||||
extern const pm_char STR_SCREEN[];
|
||||
extern const pm_char STR_SOUND_LABEL[];
|
||||
extern const pm_char STR_LENGTH[];
|
||||
extern const pm_char STR_BEEP_LENGTH[];
|
||||
extern const pm_char STR_BEEP_LENGTH[];
|
||||
#if defined(CPUARM)
|
||||
extern const pm_char STR_BEEP_LENGTH[];
|
||||
#else
|
||||
@@ -407,11 +407,11 @@ extern const pm_char STR_SWITCHWARNING[];
|
||||
extern const pm_char STR_TIMEZONE[];
|
||||
extern const pm_char STR_GPSCOORD[];
|
||||
extern const pm_char STR_VARIO[];
|
||||
extern const pm_char STR_PITCH_AT_ZERO[];
|
||||
extern const pm_char STR_PITCH_AT_MAX[];
|
||||
extern const pm_char STR_REPEAT_AT_ZERO[];
|
||||
extern const pm_char STR_PITCH_AT_ZERO[];
|
||||
extern const pm_char STR_PITCH_AT_MAX[];
|
||||
extern const pm_char STR_REPEAT_AT_ZERO[];
|
||||
extern const pm_char STR_RXCHANNELORD[];
|
||||
extern const pm_char STR_SWITCHES_DELAY[];
|
||||
extern const pm_char STR_SWITCHES_DELAY[];
|
||||
extern const pm_char STR_SLAVE[];
|
||||
extern const pm_char STR_MODESRC[];
|
||||
extern const pm_char STR_MULTIPLIER[];
|
||||
@@ -471,8 +471,8 @@ extern const pm_char STR_MENUCURVE[];
|
||||
extern const pm_char STR_MENULOGICALSWITCH[];
|
||||
extern const pm_char STR_MENULOGICALSWITCHES[];
|
||||
extern const pm_char STR_MENUCUSTOMFUNC[];
|
||||
extern const pm_char STR_MENUCUSTOMSCRIPTS[];
|
||||
extern const pm_char STR_MENUCUSTOMSCRIPT[];
|
||||
extern const pm_char STR_MENUCUSTOMSCRIPTS[];
|
||||
extern const pm_char STR_MENUCUSTOMSCRIPT[];
|
||||
extern const pm_char STR_MENUTELEMETRY[];
|
||||
extern const pm_char STR_MENUTEMPLATES[];
|
||||
extern const pm_char STR_MENUSTAT[];
|
||||
@@ -574,7 +574,7 @@ extern const pm_char STR_RESET_BTN[];
|
||||
|
||||
extern const pm_char STR_WARNING[];
|
||||
extern const pm_char STR_EEPROMWARN[];
|
||||
extern const pm_char STR_EEPROM_CONVERTING[];
|
||||
extern const pm_char STR_EEPROM_CONVERTING[];
|
||||
extern const pm_char STR_THROTTLEWARN[];
|
||||
extern const pm_char STR_ALARMSWARN[];
|
||||
extern const pm_char STR_SWITCHWARN[];
|
||||
@@ -599,10 +599,10 @@ extern const pm_char STR_SDHC_CARD[];
|
||||
extern const pm_char STR_NO_SOUNDS_ON_SD[];
|
||||
extern const pm_char STR_NO_MODELS_ON_SD[];
|
||||
extern const pm_char STR_NO_BITMAPS_ON_SD[];
|
||||
extern const pm_char STR_NO_SCRIPTS_ON_SD[];
|
||||
extern const pm_char STR_NO_SCRIPTS_ON_SD[];
|
||||
extern const pm_char STR_PLAY_FILE[];
|
||||
extern const pm_char STR_ASSIGN_BITMAP[];
|
||||
extern const pm_char STR_EXECUTE_FILE[];
|
||||
extern const pm_char STR_EXECUTE_FILE[];
|
||||
extern const pm_char STR_DELETE_FILE[];
|
||||
extern const pm_char STR_COPY_FILE[];
|
||||
extern const pm_char STR_RENAME_FILE[];
|
||||
@@ -628,14 +628,14 @@ extern const pm_char STR_OWN[];
|
||||
extern const pm_char STR_ROTARY_ENCODER[];
|
||||
extern const pm_char STR_DATE[];
|
||||
extern const pm_char STR_CHANNELS_MONITOR[];
|
||||
extern const pm_char STR_PATH_TOO_LONG[];
|
||||
extern const pm_char STR_VIEW_TEXT[];
|
||||
extern const pm_char STR_FLASH_BOOTLOADER[];
|
||||
extern const pm_char STR_WRITING[];
|
||||
extern const pm_char STR_PATH_TOO_LONG[];
|
||||
extern const pm_char STR_VIEW_TEXT[];
|
||||
extern const pm_char STR_FLASH_BOOTLOADER[];
|
||||
extern const pm_char STR_WRITING[];
|
||||
extern const pm_char STR_CONFIRM_FORMAT[];
|
||||
extern const pm_char STR_EEBACKUP[];
|
||||
extern const pm_char STR_TOO_MANY_LUA_SCRIPTS[];
|
||||
extern const pm_char STR_BLCOLOR[];
|
||||
extern const pm_char STR_TOO_MANY_LUA_SCRIPTS[];
|
||||
extern const pm_char STR_BLCOLOR[];
|
||||
|
||||
#if defined(VOICE) && defined(CPUARM)
|
||||
struct LanguagePack {
|
||||
@@ -697,24 +697,24 @@ extern const pm_char STR_BLCOLOR[];
|
||||
#if defined(PCBTARANIS)
|
||||
extern const pm_char STR_BYTES[];
|
||||
extern const pm_char STR_ANTENNAPROBLEM[];
|
||||
extern const pm_char STR_MODULE[];
|
||||
extern const pm_char STR_ENABLE_POPUP[];
|
||||
extern const pm_char STR_DISABLE_POPUP[];
|
||||
extern const pm_char STR_CURVE_PRESET[];
|
||||
extern const pm_char STR_PRESET[];
|
||||
extern const pm_char STR_MIRROR[];
|
||||
extern const pm_char STR_CLEAR[];
|
||||
extern const pm_char STR_MODULE[];
|
||||
extern const pm_char STR_ENABLE_POPUP[];
|
||||
extern const pm_char STR_DISABLE_POPUP[];
|
||||
extern const pm_char STR_CURVE_PRESET[];
|
||||
extern const pm_char STR_PRESET[];
|
||||
extern const pm_char STR_MIRROR[];
|
||||
extern const pm_char STR_CLEAR[];
|
||||
extern const pm_char STR_RESET[];
|
||||
extern const pm_char STR_COUNT[];
|
||||
extern const pm_char STR_PT[];
|
||||
extern const pm_char STR_PTS[];
|
||||
extern const pm_char STR_SMOOTH[];
|
||||
extern const pm_char STR_COPY_STICKS_TO_OFS[];
|
||||
extern const pm_char STR_COPY_TRIMS_TO_OFS[];
|
||||
extern const pm_char STR_COUNT[];
|
||||
extern const pm_char STR_PT[];
|
||||
extern const pm_char STR_PTS[];
|
||||
extern const pm_char STR_SMOOTH[];
|
||||
extern const pm_char STR_COPY_STICKS_TO_OFS[];
|
||||
extern const pm_char STR_COPY_TRIMS_TO_OFS[];
|
||||
extern const pm_char STR_TOP_BAR[];
|
||||
extern const pm_char STR_ALTITUDE[];
|
||||
extern const pm_char STR_SCALE[];
|
||||
extern const pm_char STR_VIEW_CHANNELS[];
|
||||
extern const pm_char STR_SCALE[];
|
||||
extern const pm_char STR_VIEW_CHANNELS[];
|
||||
extern const pm_char STR_POTWARNING[];
|
||||
extern const pm_char STR_UART3MODE[];
|
||||
extern const pm_char STR_THROTTLE_LABEL[];
|
||||
|
||||
@@ -80,10 +80,10 @@
|
||||
#define TR_TRNCHN "CH1CH2CH3CH4"
|
||||
|
||||
#define LEN_UART3MODES "\017"
|
||||
#define TR_UART3MODES "VYP\0 ""S-Port Mirror\0 ""Telemetry\0 ""Debug\0 "
|
||||
#define TR_UART3MODES "VYP\0 ""S-Port Mirror\0 ""Telemetrie\0 ""Debug\0 "
|
||||
|
||||
#define LEN_POTTYPES "\017"
|
||||
#define TR_POTTYPES "Není\0 ""Pot with detent""Vícepol. přep.\0""Potenciometr\0"
|
||||
#define TR_POTTYPES "Není\0 ""Pot s aretací\0 ""Vícepol. přep.\0""Potenciometr\0"
|
||||
|
||||
#define LEN_DATETIME "\006"
|
||||
#define TR_DATETIME "DATUM:""ČAS: "
|
||||
@@ -92,7 +92,7 @@
|
||||
#define TR_VLCD "NormalOptrex"
|
||||
|
||||
#define LEN_VPERSISTENT "\014"
|
||||
#define TR_VPERSISTENT "OFF\0 ""Flight\0 ""Manual Reset"
|
||||
#define TR_VPERSISTENT "Ne\0 ""V rámci letu""Reset ručně\0"
|
||||
|
||||
#define LEN_COUNTRYCODES TR("\002", "\010")
|
||||
#define TR_COUNTRYCODES TR("US""JP""EU", "Amerika\0""Japonsko""Evropa\0 ")
|
||||
@@ -253,7 +253,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(LUA)
|
||||
#define TR_CFN_PLAY_SCRIPT "Lua Script\0"
|
||||
#define TR_CFN_PLAY_SCRIPT "Lua Skript\0"
|
||||
#else
|
||||
#define TR_CFN_PLAY_SCRIPT "[Lua]\0 "
|
||||
#endif
|
||||
@@ -570,7 +570,7 @@
|
||||
#define TR_SCREEN "Panel "
|
||||
#define TR_SOUND_LABEL "Zvuk"
|
||||
#define TR_LENGTH INDENT"Délka"
|
||||
#define TR_BEEP_LENGTH INDENT "Beep Length"
|
||||
#define TR_BEEP_LENGTH INDENT "Délka"
|
||||
#define TR_SPKRPITCH INDENT"Tón"
|
||||
#define TR_HAPTIC_LABEL "Vibrace"
|
||||
#define TR_HAPTICSTRENGTH INDENT"Síla"
|
||||
@@ -598,7 +598,7 @@
|
||||
#define TR_POTWARNING TR("* Potenc.", INDENT "Nastavení Pot.")
|
||||
#define TR_TIMEZONE "časové pásmo"
|
||||
#define TR_RXCHANNELORD TR("Pořadí kanálů", "Výchozí pořadí kanálů")
|
||||
#define TR_SWITCHES_DELAY "Switches Delay"
|
||||
#define TR_SWITCHES_DELAY "Přechod středu přepínače"
|
||||
#define TR_SLAVE "Podřízený"
|
||||
#define TR_MODESRC " Mód\006% Zdroj"
|
||||
#define TR_MULTIPLIER "Násobič"
|
||||
@@ -800,7 +800,7 @@
|
||||
#define TR_ANTENNAPROBLEM CENTER "Problém s TX anténou!"
|
||||
#define TR_MODELIDUSED TR("ID již použito","ID modelu je již použito")
|
||||
#define TR_MODULE INDENT "Modul"
|
||||
#define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type")
|
||||
#define TR_TELEMETRY_TYPE TR("Typ", "Typ telemetrie")
|
||||
#define TR_CHANNELRANGE INDENT "Rozsah kanálů"
|
||||
#define TR_LOWALARM INDENT "Nízký Alarm"
|
||||
#define TR_CRITICALALARM INDENT "Kritický Alarm"
|
||||
@@ -816,8 +816,8 @@
|
||||
#define TR_PT "č."
|
||||
#define TR_PTS " b."
|
||||
#define TR_SMOOTH "Hladká"
|
||||
#define TR_COPY_STICKS_TO_OFS "Kopírovat stick do subtrimu"
|
||||
#define TR_COPY_TRIMS_TO_OFS "Copy trims to subtrim"
|
||||
#define TR_COPY_STICKS_TO_OFS "Kopie pák do subtrimu"
|
||||
#define TR_COPY_TRIMS_TO_OFS "Kopíe trimů do subtrimu"
|
||||
#define TR_PERSISTENT_MAH TR(INDENT "Str mAh", INDENT "Ukládat mAh")
|
||||
#define TR_PREFLIGHT "Předletová kontrola"
|
||||
#define TR_CHECKLIST INDENT "Zobrazit poznámky"
|
||||
@@ -827,7 +827,7 @@
|
||||
#define TR_INPUTS "Vstupy"
|
||||
#define TR_OUTPUTS "Výstupy"
|
||||
#define TR_EEBACKUP "\010[dlouze ENTER] zálohuje EEPROM"
|
||||
#define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!"
|
||||
#define TR_TO_MANY_LUA_SCRIPTS "Příliš mnoho skriptů!"
|
||||
|
||||
#if defined(MAVLINK)
|
||||
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
|
||||
@@ -871,7 +871,7 @@
|
||||
|
||||
#define TR_ABOUT_BERTRAND_1 "Bertrand Songis"
|
||||
#define TR_ABOUT_BERTRAND_2 "Hlavní vývojář OpenTX"
|
||||
#define TR_ABOUT_BERTRAND_3 "Spoluautor Companion9x"
|
||||
#define TR_ABOUT_BERTRAND_3 "Spoluautor Companion"
|
||||
|
||||
#define TR_ABOUT_MIKE_1 "Mike Blandford"
|
||||
#define TR_ABOUT_MIKE_2 "Specialista na kód,"
|
||||
@@ -880,7 +880,7 @@
|
||||
|
||||
#define TR_ABOUT_ROMOLO_1 "Romolo Manfredini"
|
||||
#define TR_ABOUT_ROMOLO_2 "Hlavní vývojář"
|
||||
#define TR_ABOUT_ROMOLO_3 "Companion9x"
|
||||
#define TR_ABOUT_ROMOLO_3 "Companion"
|
||||
|
||||
#define TR_ABOUT_ANDRE_1 "Andre Bernet"
|
||||
#define TR_ABOUT_ANDRE_2 "Funkčnost, použitelnost,"
|
||||
@@ -891,8 +891,8 @@
|
||||
|
||||
#define TR_ABOUT_KJELL_1 "Kjell Kernen"
|
||||
#define TR_ABOUT_KJELL_2 "www.open-tx.org main author"
|
||||
#define TR_ABOUT_KJELL_3 "OpenTX Recorder author"
|
||||
#define TR_ABOUT_KJELL_4 "Companion contributor"
|
||||
#define TR_ABOUT_KJELL_3 "autor OpenTX Recorder"
|
||||
#define TR_ABOUT_KJELL_4 "Spoluautor Companion"
|
||||
|
||||
#define TR_ABOUT_MARTIN_1 "Martin Hotař"
|
||||
#define TR_ABOUT_MARTIN_2 "Grafický design, Čeština"
|
||||
|
||||
@@ -460,7 +460,7 @@
|
||||
#define TR_VSRCRAW "---\0""Rud\0""Ele\0""Thr\0""Ail\0" TR_POTS_VSRCRAW TR_ROTARY_ENCODERS "MAX\0" TR_CYC_VSRCRAW "TrmR" "TrmE" "TrmT" "TrmA" TR_SW_VSRCRAW
|
||||
|
||||
#define LEN_VTMRMODES "\003"
|
||||
#define TR_VTMRMODES "OFF""ABS""THs""TH%""THt"
|
||||
#define TR_VTMRMODES "OFF""ON\0""THs""TH%""THt"
|
||||
|
||||
#define LEN_VTRAINERMODES "\006"
|
||||
#define TR_VTRAINERMODES "Master""Slave\0"
|
||||
@@ -518,11 +518,15 @@
|
||||
#define TR_ELIMITS TR("E.Limits", "Extended Limits")
|
||||
#define TR_ETRIMS TR("E.Trims", "Extended Trims")
|
||||
#define TR_TRIMINC "Trim Step"
|
||||
#define TR_TTRACE TR("T-Source", INDENT "Timer Source")
|
||||
#define TR_TTRACE TR("T-Source", INDENT "Source")
|
||||
#define TR_TTRIM TR("T-Trim", INDENT "Trim Idle Only")
|
||||
#define TR_BEEPCTR TR("Ctr Beep", "Center Beep")
|
||||
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
|
||||
#define TR_PPMFRAME TR(INDENT "PPM frame", INDENT "PPM frame")
|
||||
#if defined(CPUARM)
|
||||
#define TR_PPMFRAME INDENT "PPM frame"
|
||||
#else
|
||||
#define TR_PPMFRAME "PPM frame"
|
||||
#endif
|
||||
#define TR_MS "ms"
|
||||
#define TR_SWITCH "Switch"
|
||||
#define TR_TRIMS "Trims"
|
||||
@@ -680,7 +684,11 @@
|
||||
#define TR_MENUTEMPLATES "TEMPLATES"
|
||||
#define TR_MENUSTAT "STATS"
|
||||
#define TR_MENUDEBUG "DEBUG"
|
||||
#define TR_RXNUM TR(INDENT "RxNum", INDENT "Receiver No.")
|
||||
#if defined(CPUARM)
|
||||
#define TR_RXNUM TR(INDENT "RxNum", INDENT "Receiver No.")
|
||||
#else
|
||||
#define TR_RXNUM "RxNum"
|
||||
#endif
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT "Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -458,7 +458,7 @@
|
||||
#define TR_VSRCRAW "---\0""Dir\0""Prf\0""Gaz\0""Ail\0" TR_POTS_VSRCRAW TR_ROTARY_ENCODERS "MAX\0" TR_CYC_VSRCRAW "TrmD" "TrmP" "TrmG" "TrmA" TR_SW_VSRCRAW
|
||||
|
||||
#define LEN_VTMRMODES "\003"
|
||||
#define TR_VTMRMODES "OFF""ABS""GZs""GZ%""GZt"
|
||||
#define TR_VTMRMODES "OFF""ON\0""GZs""GZ%""GZt"
|
||||
|
||||
#define LEN_VTRAINERMODES "\006"
|
||||
#define TR_VTRAINERMODES "Maître""Elève\0"
|
||||
@@ -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("Source Gaz", INDENT "Source")
|
||||
#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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user