Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 36481471a3 | |||
| dd08886f2c | |||
| 76ef4b5948 | |||
| eaa247f46d | |||
| 3ada9f7cf5 | |||
| 10a5e4dc89 | |||
| 50e4850745 | |||
| a92de216ac | |||
| 3f3708f0f1 | |||
| 72c433ce9d | |||
| f123b69521 | |||
| 80369f0e8f | |||
| 8cd67bf31e | |||
| 34ef060e16 | |||
| 1f07f88dce | |||
| 4db5bdd486 | |||
| 05ac0682f0 | |||
| f12c3072b5 | |||
| 35aea83c89 | |||
| cf9b5d05a8 | |||
| d5393be5cb | |||
| 10c9936fa0 | |||
| 7a74d3ac85 | |||
| 39edaff669 | |||
| c5aed5f79b | |||
| 9b07a77e14 | |||
| 380fe5e44d | |||
| 8bd2c120d6 | |||
| 741ef45f3e | |||
| 4103adf75d | |||
| c0e612531d | |||
| 55cb5dce87 | |||
| 12ba27247e | |||
| 1e33e99655 | |||
| 50acd1fd92 | |||
| c3626225aa | |||
| b71a96ed55 | |||
| d2fcd544d8 | |||
| 50997721e2 | |||
| 828372ab29 | |||
| 21ae270c0e | |||
| 1b2efd1121 | |||
| 8d6a7c9495 | |||
| 189becfbb2 | |||
| 5a19e147fd | |||
| 062f93ae38 | |||
| 9861a08150 | |||
| de15d0a5a4 | |||
| 1e77bb3c02 | |||
| adadbe06ad | |||
| 92f2c48de9 | |||
| 1d4fa2a8b0 | |||
| 5493776b9c | |||
| b166b77c3e | |||
| 0ecb978364 | |||
| c8d792d3d8 | |||
| e9663e40e2 | |||
| a7e906dea9 | |||
| 685ab3d101 | |||
| 77564d74a4 | |||
| a0142d65be | |||
| 662bf15562 | |||
| 79b928af56 | |||
| 8c28f4bc48 | |||
| 7a4d6c89a1 | |||
| 38347becca | |||
| 49036dbb40 | |||
| abf36de157 | |||
| 32afbf5a5a | |||
| cba4a02cc1 |
@@ -536,3 +536,56 @@ Cyberauto Systems
|
||||
John Alsbrooks
|
||||
John Kearney
|
||||
Christopher Borden
|
||||
Marc Virgilio Ricci
|
||||
Frederick Davie
|
||||
Jürgen Enders
|
||||
Terrence Pitts
|
||||
Thomas Sandner
|
||||
Marco Coltorti
|
||||
Harald Wilczak
|
||||
Rodney Lorimor
|
||||
Richard Davis
|
||||
Stephen Palmer
|
||||
Michael Napolitan
|
||||
Joshua Bardwell
|
||||
Fred Dawson
|
||||
Jim Wagner
|
||||
Peter Johnson
|
||||
Fredrik Lewerth
|
||||
Arvin Stenersen
|
||||
Daniel Morgan
|
||||
Roy Nixon
|
||||
Joachim Blunck
|
||||
Karl-Heinz Gansel
|
||||
Monrovia Mountain Enterprises
|
||||
Alessandro Villa
|
||||
Jan-Åke Nilsson
|
||||
Matthias Rei
|
||||
DVR Solutions BV
|
||||
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
|
||||
|
||||
@@ -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,3 +1,10 @@
|
||||
<h2>Version 2.0.10</h2>
|
||||
<ul>
|
||||
<li>Taranis is now the default board in General Settings</li>
|
||||
<li>GVARS allowed in Limits min/max/offset</li>
|
||||
<li>Limits displayed in us when ppmus option selected
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.8</h2>
|
||||
<ul>
|
||||
<li>Compare dialog bugfixes</li>
|
||||
|
||||
@@ -2,7 +2,7 @@ PROJECT( companion )
|
||||
|
||||
SET( C9X_VERSION_MAJOR "2" )
|
||||
SET( C9X_VERSION_MINOR "0" )
|
||||
SET( C9X_VERSION_REVISION "8" )
|
||||
SET( C9X_VERSION_REVISION "10" )
|
||||
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
@@ -338,7 +338,11 @@ if(WIN32)
|
||||
set(simu_SRCS ${simu_SRCS} icon.rc)
|
||||
endif()
|
||||
|
||||
add_executable(simulator WIN32 ${simu_SRCS})
|
||||
if(APPLE)
|
||||
add_executable(simulator MACOSX_BUNDLE ${simu_SRCS})
|
||||
else()
|
||||
add_executable(simulator WIN32 ${simu_SRCS})
|
||||
endif()
|
||||
|
||||
if(SDL_FOUND)
|
||||
target_link_libraries(simulator simulation common ${QT_LIBRARIES} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS})
|
||||
|
||||
@@ -156,11 +156,11 @@ void avrOutputDialog::doCopy()
|
||||
dest.close();
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Error"),tr("Cannot write destination") + ": " + dest.errorString());
|
||||
QMessageBox::warning(this, tr("Error"),tr("Cannot write destination") + ": " + dest.fileName() + ", " + tr("reason") + ": " + dest.errorString());
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Error"),tr("Cannot open source file") + ": " + source.errorString());
|
||||
QMessageBox::warning(this, tr("Error"),tr("Cannot open source file") + ": " + source.fileName() + ", " + tr("reason") + ": " + source.errorString());
|
||||
}
|
||||
|
||||
source.close();
|
||||
|
||||
@@ -354,10 +354,8 @@ void burnConfigDialog::restFuses(bool eeProtect)
|
||||
//use hfuse = 0x81 to prevent eeprom being erased with every flashing
|
||||
}
|
||||
else {
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString tempFile;
|
||||
QString lfuses;
|
||||
tempFile = tempDir + "/ftemp.bin";
|
||||
QString tempFile = generateProcessUniqueTempFileName("ftemp.bin");
|
||||
QStringList argread;
|
||||
argread << "-c" << avrProgrammer << "-p" << avrMCU << args <<"-U" << "lfuse:r:"+tempFile+":r" ;
|
||||
avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, argread, "Reset Fuses",AVR_DIALOG_CLOSE_IF_SUCCESSFUL,FALSE);
|
||||
@@ -376,7 +374,7 @@ void burnConfigDialog::restFuses(bool eeProtect)
|
||||
lfuses="lfuse:w:0x3F:m";
|
||||
}
|
||||
file.close();
|
||||
unlink(tempFile.toAscii());
|
||||
qunlink(tempFile);
|
||||
}
|
||||
else {
|
||||
lfuses="lfuse:w:0x3F:m";
|
||||
|
||||
@@ -418,12 +418,11 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
image = pixmap->toImage().scaled(ui->imageLabel->width(), ui->imageLabel->height());
|
||||
}
|
||||
if (!image.isNull()) {
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString tempFile;
|
||||
if (getFileType(fileName) == FILE_TYPE_HEX)
|
||||
tempFile = tempDir + "/flash.hex";
|
||||
tempFile = generateProcessUniqueTempFileName("flash.hex");
|
||||
else
|
||||
tempFile = tempDir + "/flash.bin";
|
||||
tempFile = generateProcessUniqueTempFileName("flash.bin");
|
||||
FlashInterface flash(fileName);
|
||||
flash.setSplash(image);
|
||||
if (flash.saveFlash(tempFile) > 0) {
|
||||
@@ -556,8 +555,7 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
}
|
||||
|
||||
if (patch) {
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString fileName = tempDir + "/temp.bin";
|
||||
QString fileName = generateProcessUniqueTempFileName("temp.bin");
|
||||
QFile file(fileName);
|
||||
|
||||
uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize());
|
||||
|
||||
@@ -156,16 +156,12 @@ void CompareDialog::dropEvent(QDropEvent *event)
|
||||
|
||||
void CompareDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
QByteArray ba = curvefile5.toLatin1();
|
||||
char *name = ba.data();
|
||||
unlink(name);
|
||||
ba = curvefile9.toLatin1();
|
||||
name = ba.data();
|
||||
unlink(name);
|
||||
}
|
||||
|
||||
CompareDialog::~CompareDialog()
|
||||
{
|
||||
qunlink(curvefile5);
|
||||
qunlink(curvefile9);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@@ -260,13 +256,10 @@ void CompareDialog::printSetup()
|
||||
str.append(fv(tr("Pulse Polarity"), g_model1->moduleData[0].polarityToString(), color));
|
||||
color=getColor1(g_model1->thrTrim,g_model2->thrTrim);
|
||||
str.append(fv(tr("Throttle Trim"), g_model1->thrTrim ? tr("Enabled") : tr("Disabled"), color));
|
||||
color=getColor1(g_model1->thrExpo,g_model2->thrExpo);
|
||||
str.append(fv(tr("Throttle Expo"), g_model1->thrExpo ? tr("Enabled") : tr("Disabled"),color));
|
||||
// TODO str.append(fv(tr("Trim Switch"), getSWName(g_model->trimSw)));
|
||||
color=getColor1(getTrimInc(g_model1),getTrimInc(g_model2));
|
||||
str.append(fv(tr("Trim Increment"), getTrimInc(g_model1),color));
|
||||
color=getColor1(getCenterBeep(g_model1),getCenterBeep(g_model2));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeep(g_model1),color)); // specify which channels beep
|
||||
color = getColor1(getCenterBeepStr(g_model1), getCenterBeepStr(g_model2));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeepStr(g_model1), color)); // specify which channels beep
|
||||
str.append("</table></td>");
|
||||
str.append("<td><table border=0 cellspacing=0 cellpadding=3 width=\"50%\">");
|
||||
color=getColor2(g_model1->name,g_model2->name);
|
||||
@@ -283,13 +276,10 @@ void CompareDialog::printSetup()
|
||||
str.append(fv(tr("Pulse Polarity"), g_model2->moduleData[0].polarityToString(), color));
|
||||
color=getColor2(g_model1->thrTrim,g_model2->thrTrim);
|
||||
str.append(fv(tr("Throttle Trim"), g_model2->thrTrim ? tr("Enabled") : tr("Disabled"), color));
|
||||
color=getColor2(g_model1->thrExpo,g_model2->thrExpo);
|
||||
str.append(fv(tr("Throttle Expo"), g_model2->thrExpo ? tr("Enabled") : tr("Disabled"),color));
|
||||
// TODO str.append(fv(tr("Trim Switch"), getSWName(g_model->trimSw)));
|
||||
color=getColor2(getTrimInc(g_model1),getTrimInc(g_model2));
|
||||
str.append(fv(tr("Trim Increment"), getTrimInc(g_model2),color));
|
||||
color=getColor2(getCenterBeep(g_model1),getCenterBeep(g_model2));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeep(g_model2),color)); // specify which channels beep
|
||||
color = getColor2(getCenterBeepStr(g_model1),getCenterBeepStr(g_model2));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeepStr(g_model2), color)); // specify which channels beep
|
||||
str.append("</td></tr></table></td></tr></table>");
|
||||
te->append(str);
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ class ConversionTable {
|
||||
{
|
||||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=internalTable.begin(); it!=internalTable.end(); it++) {
|
||||
for (std::list<ConversionTuple>::iterator it=exportTable.begin(); it!=exportTable.end(); it++) {
|
||||
ConversionTuple tuple = *it;
|
||||
if (before == tuple.a) {
|
||||
after = tuple.b;
|
||||
@@ -520,7 +520,7 @@ class ConversionTable {
|
||||
{
|
||||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=internalTable.begin(); it!=internalTable.end(); it++) {
|
||||
for (std::list<ConversionTuple>::iterator it=importTable.begin(); it!=importTable.end(); it++) {
|
||||
ConversionTuple tuple = *it;
|
||||
if (before == tuple.b) {
|
||||
after = tuple.a;
|
||||
@@ -547,10 +547,23 @@ class ConversionTable {
|
||||
|
||||
void addConversion(const int a, const int b)
|
||||
{
|
||||
internalTable.push_back(ConversionTuple(a, b));
|
||||
ConversionTuple conversion(a, b);
|
||||
importTable.push_back(conversion);
|
||||
exportTable.push_back(conversion);
|
||||
}
|
||||
|
||||
std::list<ConversionTuple> internalTable;
|
||||
void addImportConversion(const int a, const int b)
|
||||
{
|
||||
importTable.push_back(ConversionTuple(a, b));
|
||||
}
|
||||
|
||||
void addExportConversion(const int a, const int b)
|
||||
{
|
||||
exportTable.push_back(ConversionTuple(a, b));
|
||||
}
|
||||
|
||||
std::list<ConversionTuple> importTable;
|
||||
std::list<ConversionTuple> exportTable;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -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;
|
||||
@@ -919,7 +921,6 @@ class TimerData {
|
||||
RawSwitch mode;
|
||||
bool minuteBeep;
|
||||
unsigned int countdownBeep;
|
||||
bool dir; // 0=>Count Down, 1=>Count Up
|
||||
unsigned int val;
|
||||
unsigned int persistent;
|
||||
int pvalue;
|
||||
@@ -986,7 +987,6 @@ class ModelData {
|
||||
char name[12+1];
|
||||
TimerData timers[2];
|
||||
bool thrTrim; // Enable Throttle Trim
|
||||
bool thrExpo; // Enable Throttle Expo
|
||||
int trimInc; // Trim Increments
|
||||
bool disableThrottleWarning;
|
||||
|
||||
@@ -1131,6 +1131,7 @@ enum Capability {
|
||||
HasSoundMixer,
|
||||
NumModules,
|
||||
PPMCenter,
|
||||
PPMUnitMicroseconds,
|
||||
SYMLimits,
|
||||
HasCurrentCalibration,
|
||||
HasVolume,
|
||||
|
||||
@@ -138,8 +138,8 @@ t_Er9xLimitData::t_Er9xLimitData()
|
||||
t_Er9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
@@ -358,7 +358,6 @@ t_Er9xModelData::operator ModelData ()
|
||||
c9x.used = true;
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0].mode = getEr9xTimerMode(tmrMode);
|
||||
c9x.timers[0].dir = tmrDir;
|
||||
c9x.timers[0].val = tmrVal;
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
@@ -377,7 +376,6 @@ t_Er9xModelData::operator ModelData ()
|
||||
c9x.moduleData[0].ppmFrameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.funcSw[0].func = FuncInstantTrim;
|
||||
|
||||
@@ -147,8 +147,8 @@ t_Ersky9xLimitData::t_Ersky9xLimitData()
|
||||
t_Ersky9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
@@ -489,7 +489,6 @@ t_Ersky9xModelData_v10::operator ModelData ()
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++) {
|
||||
c9x.timers[i].mode = getErSky9xTimerMode(timer[i].tmrModeA);
|
||||
c9x.timers[i].dir = timer[i].tmrDir;
|
||||
c9x.timers[i].val = timer[i].tmrVal;
|
||||
}
|
||||
switch(protocol) {
|
||||
@@ -509,7 +508,6 @@ t_Ersky9xModelData_v10::operator ModelData ()
|
||||
c9x.moduleData[0].ppmFrameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.funcSw[0].func = FuncInstantTrim;
|
||||
@@ -607,7 +605,6 @@ t_Ersky9xModelData_v11::operator ModelData ()
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++) {
|
||||
c9x.timers[i].mode = getErSky9xTimerMode(timer[i].tmrModeA);
|
||||
c9x.timers[i].dir = timer[i].tmrDir;
|
||||
c9x.timers[i].val = timer[i].tmrVal;
|
||||
}
|
||||
switch(protocol) {
|
||||
@@ -627,7 +624,6 @@ t_Ersky9xModelData_v11::operator ModelData ()
|
||||
c9x.moduleData[0].ppmFrameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.funcSw[0].func = FuncInstantTrim;
|
||||
|
||||
@@ -201,8 +201,8 @@ t_Gruvin9xLimitData::t_Gruvin9xLimitData()
|
||||
t_Gruvin9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
@@ -378,7 +378,6 @@ t_Gruvin9xTimerData::operator TimerData ()
|
||||
TimerData c9x;
|
||||
c9x.mode = getEr9xTimerMode(mode);
|
||||
c9x.val = val;
|
||||
c9x.dir = dir;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -447,7 +446,6 @@ t_Gruvin9xModelData_v102::operator ModelData ()
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
@@ -518,7 +516,6 @@ t_Gruvin9xModelData_v103::operator ModelData ()
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
@@ -589,7 +586,6 @@ t_Gruvin9xModelData_v105::operator ModelData ()
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
@@ -680,7 +676,6 @@ t_Gruvin9xModelData_v106::operator ModelData ()
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
|
||||
@@ -138,7 +138,6 @@ t_Open9xArmTimerData_v202::operator TimerData ()
|
||||
*/
|
||||
c9x.val = val;
|
||||
c9x.persistent = false;
|
||||
c9x.dir = (val == 0);
|
||||
return c9x;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +129,8 @@ t_Open9xExpoData_v211::operator ExpoData ()
|
||||
t_Open9xLimitData_v201::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
@@ -139,8 +139,8 @@ t_Open9xLimitData_v201::operator LimitData ()
|
||||
t_Open9xLimitData_v211::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
c9x.symetrical=symetrical;
|
||||
@@ -704,7 +704,6 @@ t_Open9xTimerData_v201::operator TimerData ()
|
||||
// c9x.mode = TMRMODE_OFF;
|
||||
c9x.val = val;
|
||||
c9x.persistent = persistent;
|
||||
c9x.dir = dir;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -725,7 +724,6 @@ t_Open9xTimerData_v202::operator TimerData ()
|
||||
*/
|
||||
c9x.val = val;
|
||||
c9x.persistent = false;
|
||||
c9x.dir = (val == 0);
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -939,7 +937,6 @@ t_Open9xModelData_v201::operator ModelData ()
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
|
||||
@@ -40,11 +40,11 @@ inline int switchIndex(int i, BoardEnum board, unsigned int version)
|
||||
class SwitchesConversionTable: public ConversionTable {
|
||||
|
||||
public:
|
||||
SwitchesConversionTable(BoardEnum board, unsigned int version, unsigned long flags=0)
|
||||
SwitchesConversionTable(BoardEnum board, unsigned int version, bool timer=false)
|
||||
{
|
||||
int val=0;
|
||||
int offset=0;
|
||||
if (flags & POPULATE_TIMER_MODES) {
|
||||
if (timer) {
|
||||
offset = 4;
|
||||
for (int i=0; i<5; i++) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_TIMER_MODE, i), val++);
|
||||
@@ -56,8 +56,15 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
|
||||
for (int i=1; i<=MAX_SWITCHES_POSITION(board); i++) {
|
||||
int s = switchIndex(i, board, version);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val++);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val);
|
||||
if (IS_TARANIS(board) && s>=21/*SHup/SHdown*/) {
|
||||
addImportConversion(RawSwitch(SWITCH_TYPE_SWITCH, 21+22-s), -val+offset);
|
||||
addExportConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val+offset);
|
||||
}
|
||||
else {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val+offset);
|
||||
}
|
||||
val++;
|
||||
}
|
||||
|
||||
if (IS_TARANIS(board) && version >= 216) {
|
||||
@@ -86,17 +93,15 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++);
|
||||
}
|
||||
|
||||
if (!(flags & POPULATE_TIMER_MODES)) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_OFF), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ON), val++);
|
||||
if (version >= 216) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, -1), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, 1), val++);
|
||||
if (IS_ARM(board)) {
|
||||
for (int i=1; i<=MAX_FLIGHT_MODES(board, version); i++) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, -i), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i), val++);
|
||||
}
|
||||
addConversion(RawSwitch(SWITCH_TYPE_OFF), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ON), val++);
|
||||
if (version >= 216) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, -1), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, 1), val++);
|
||||
if (IS_ARM(board)) {
|
||||
for (int i=1; i<=MAX_FLIGHT_MODES(board, version); i++) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, -i), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i), val++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,6 +129,16 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
ConversionTable::addConversion(sw.toValue(), b);
|
||||
}
|
||||
|
||||
void addImportConversion(const RawSwitch & sw, const int b)
|
||||
{
|
||||
ConversionTable::addImportConversion(sw.toValue(), b);
|
||||
}
|
||||
|
||||
void addExportConversion(const RawSwitch & sw, const int b)
|
||||
{
|
||||
ConversionTable::addExportConversion(sw.toValue(), b);
|
||||
}
|
||||
|
||||
class Cache {
|
||||
public:
|
||||
Cache(BoardEnum board, unsigned int version, unsigned long flags, SwitchesConversionTable * table):
|
||||
@@ -1136,7 +1151,7 @@ class InputField: public TransformedField {
|
||||
|
||||
virtual void beforeExport()
|
||||
{
|
||||
_weight = smallGvarToEEPROM(expo.weight);
|
||||
_weight = smallGvarToEEPROM(expo.weight);
|
||||
|
||||
if (!IS_TARANIS(board) || version < 216) {
|
||||
if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) {
|
||||
@@ -1191,19 +1206,43 @@ class InputField: public TransformedField {
|
||||
|
||||
class LimitField: public StructField {
|
||||
public:
|
||||
template <int shift>
|
||||
static int exportLimitValue(int value)
|
||||
{
|
||||
if (value > 10000)
|
||||
return 4095 + value - 10000;
|
||||
else if (value < -10000)
|
||||
return -4096 + value + 10000;
|
||||
else
|
||||
return value + shift;
|
||||
}
|
||||
|
||||
template <int shift>
|
||||
static int importLimitValue(int value)
|
||||
{
|
||||
if (value > 4095)
|
||||
return 10000 + value - 4095;
|
||||
else if (value < -4096)
|
||||
return -10000 + value + 4096;
|
||||
else
|
||||
return value - shift;
|
||||
}
|
||||
|
||||
LimitField(LimitData & limit, BoardEnum board, unsigned int version):
|
||||
StructField("Limit")
|
||||
{
|
||||
if (IS_TARANIS(board) && version >= 216) {
|
||||
Append(new ConversionField< SignedField<16> >(limit.min, +1000));
|
||||
Append(new ConversionField< SignedField<16> >(limit.max, -1000));
|
||||
Append(new ConversionField< SignedField<16> >(limit.min, exportLimitValue<1000>, importLimitValue<1000>));
|
||||
Append(new ConversionField< SignedField<16> >(limit.max, exportLimitValue<-1000>, importLimitValue<-1000>));
|
||||
Append(new SignedField<8>(limit.ppmCenter));
|
||||
Append(new ConversionField< SignedField<14> >(limit.offset, exportLimitValue<0>, importLimitValue<0>));
|
||||
}
|
||||
else {
|
||||
Append(new ConversionField< SignedField<8> >(limit.min, +100, 10));
|
||||
Append(new ConversionField< SignedField<8> >(limit.max, -100, 10));
|
||||
Append(new SignedField<8>(limit.ppmCenter));
|
||||
Append(new SignedField<14>(limit.offset));
|
||||
}
|
||||
Append(new SignedField<8>(limit.ppmCenter));
|
||||
Append(new SignedField<14>(limit.offset));
|
||||
Append(new BoolField<1>(limit.symetrical));
|
||||
Append(new BoolField<1>(limit.revert));
|
||||
if (HAS_LARGE_LCD(board)) {
|
||||
@@ -1547,9 +1586,25 @@ class LogicalSwitchField: public TransformedField {
|
||||
else if (csw.func >= LS_FN_EQUAL && csw.func <= LS_FN_ELESS) {
|
||||
sourcesConversionTable->importValue((uint8_t)v1, csw.val1);
|
||||
sourcesConversionTable->importValue((uint8_t)v2, csw.val2);
|
||||
if (IS_TARANIS(board) && version < 216) {
|
||||
RawSource val1(csw.val1);
|
||||
if (val1.type == SOURCE_TYPE_STICK && val1.index < NUM_STICKS) {
|
||||
csw.val1 = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, val1.index).toValue();
|
||||
}
|
||||
RawSource val2(csw.val2);
|
||||
if (val2.type == SOURCE_TYPE_STICK && val2.index < NUM_STICKS) {
|
||||
csw.val2 = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, val2.index).toValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (csw.func != LS_FN_OFF) {
|
||||
sourcesConversionTable->importValue((uint8_t)v1, csw.val1);
|
||||
if (IS_TARANIS(board) && version < 216) {
|
||||
RawSource val1(csw.val1);
|
||||
if (val1.type == SOURCE_TYPE_STICK && val1.index < NUM_STICKS) {
|
||||
csw.val1 = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, val1.index).toValue();
|
||||
}
|
||||
}
|
||||
csw.val2 = v2;
|
||||
RawSource val1(csw.val1);
|
||||
if (IS_ARM(board) && version < 216 && val1.type == SOURCE_TYPE_TELEMETRY) {
|
||||
@@ -2396,7 +2451,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne
|
||||
}
|
||||
|
||||
for (int i=0; i<O9X_MAX_TIMERS; i++) {
|
||||
internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, POPULATE_TIMER_MODES));
|
||||
internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, true));
|
||||
if ((IS_ARM(board) || IS_2560(board)) && version >= 216) {
|
||||
internalField.Append(new UnsignedField<16>(modelData.timers[i].val));
|
||||
internalField.Append(new UnsignedField<2>(modelData.timers[i].countdownBeep));
|
||||
@@ -2759,8 +2814,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
|
||||
if (version >= 213) {
|
||||
internalField.Append(new SignedField<8>(generalData.temperatureWarn)); // TODO
|
||||
internalField.Append(new UnsignedField<8>(generalData.mAhWarn));
|
||||
internalField.Append(new SpareBitsField<16>()); // mAhUsed
|
||||
internalField.Append(new SpareBitsField<32>()); // globalTimer
|
||||
internalField.Append(new UnsignedField<16>(generalData.mAhUsed));
|
||||
internalField.Append(new UnsignedField<32>(generalData.globalTimer));
|
||||
internalField.Append(new SignedField<8>(generalData.temperatureCalib)); // TODO
|
||||
internalField.Append(new UnsignedField<8>(generalData.btBaudrate)); // TODO
|
||||
internalField.Append(new BoolField<8>(generalData.optrexDisplay)); //TODO
|
||||
|
||||
@@ -663,7 +663,9 @@ int OpenTxFirmware::getCapability(const Capability capability)
|
||||
case TelemetryMaxMultiplier:
|
||||
return (IS_ARM(board) ? 32 : 8);
|
||||
case PPMCenter:
|
||||
return 1;
|
||||
return (IS_TARANIS(board) || id.contains("ppmca")) ? 1 : 0;
|
||||
case PPMUnitMicroseconds:
|
||||
return id.contains("ppmus") ? 1 : 0;
|
||||
case SYMLimits:
|
||||
return 1;
|
||||
case OptrexDisplay:
|
||||
|
||||
@@ -124,8 +124,8 @@ t_Th9xLimitData::t_Th9xLimitData()
|
||||
t_Th9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = min-100;
|
||||
c9x.max = max+100;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
@@ -272,7 +272,6 @@ t_Th9xModelData::operator ModelData ()
|
||||
/*c9x.protocol = (Protocol)protocol;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.thrExpo = thrExpo;
|
||||
c9x.trimInc = trimInc;
|
||||
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
|
||||
c9x.funcSw[0].func = FuncTrims2Offsets;
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
These will be relevant for all models in the same EEPROM.</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabSetup">
|
||||
<attribute name="title">
|
||||
@@ -275,7 +275,10 @@ These will be relevant for all models in the same EEPROM.</string>
|
||||
<item>
|
||||
<widget class="QSlider" name="backlightColor_SL">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#include <QtGui>
|
||||
#if defined WIN32
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#if !defined WIN32 && defined __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "simulatordialog.h"
|
||||
@@ -140,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()));
|
||||
@@ -163,21 +170,32 @@ GVarGroup::GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightC
|
||||
}
|
||||
}
|
||||
|
||||
weightSB->setMinimum(mini);
|
||||
weightSB->setMaximum(maxi);
|
||||
int val;
|
||||
|
||||
if (weight>maxi || weight<mini) {
|
||||
val = deflt;
|
||||
weightGV->setChecked(true);
|
||||
weightSB->hide();
|
||||
weightCB->show();
|
||||
}
|
||||
else {
|
||||
val = weight;
|
||||
weightGV->setChecked(false);
|
||||
weightSB->setValue(weight);
|
||||
weightSB->show();
|
||||
weightCB->hide();
|
||||
}
|
||||
|
||||
if (sb) {
|
||||
sb->setMinimum(step*mini);
|
||||
sb->setMaximum(step*maxi);
|
||||
sb->setValue(step*val);
|
||||
}
|
||||
else {
|
||||
dsb->setMinimum(step*mini);
|
||||
dsb->setMaximum(step*maxi);
|
||||
dsb->setValue(step*val);
|
||||
}
|
||||
|
||||
connect(weightSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged()));
|
||||
|
||||
lock = false;
|
||||
@@ -186,16 +204,23 @@ GVarGroup::GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightC
|
||||
void GVarGroup::gvarCBChanged(int state)
|
||||
{
|
||||
weightCB->setVisible(state);
|
||||
weightSB->setVisible(!state);
|
||||
if (weightSB)
|
||||
weightSB->setVisible(!state);
|
||||
else
|
||||
weightSB->setVisible(!state);
|
||||
valuesChanged();
|
||||
}
|
||||
|
||||
void GVarGroup::valuesChanged()
|
||||
{
|
||||
if (weightGV->isChecked())
|
||||
weight = weightCB->itemData(weightCB->currentIndex()).toInt();
|
||||
else
|
||||
weight = weightSB->value();
|
||||
if (!lock) {
|
||||
if (weightGV->isChecked())
|
||||
weight = weightCB->itemData(weightCB->currentIndex()).toInt();
|
||||
else if (sb)
|
||||
weight = sb->value()/step;
|
||||
else
|
||||
weight = dsb->value()/step;
|
||||
}
|
||||
}
|
||||
|
||||
CurveGroup::CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags):
|
||||
@@ -371,13 +396,13 @@ void populateBacklightCB(QComboBox *b, const uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettings & generalSettings, unsigned long attr)
|
||||
void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettings & generalSettings, SwitchContext context)
|
||||
{
|
||||
RawSwitch item;
|
||||
|
||||
b->clear();
|
||||
|
||||
if (attr & POPULATE_ONOFF) {
|
||||
if (context != MixesContext) {
|
||||
// !FMx
|
||||
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
|
||||
for (int i=-GetCurrentFirmware()->getCapability(FlightModes); i<0; i++) {
|
||||
@@ -386,14 +411,6 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettin
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
}
|
||||
// !One
|
||||
item = RawSwitch(SWITCH_TYPE_ONE, 1);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
// OFF
|
||||
item = RawSwitch(SWITCH_TYPE_OFF);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
|
||||
for (int i=-GetCurrentFirmware()->getCapability(LogicalSwitches); i<0; i++) {
|
||||
@@ -428,13 +445,13 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettin
|
||||
item = RawSwitch(SWITCH_TYPE_SWITCH, i);
|
||||
if (IS_TARANIS(GetCurrentFirmware()->getBoard())) {
|
||||
//hide up and down for !SH and !SF, because they are redundant (!SFup == SFdown)
|
||||
if (item.toString().contains("H") || item.toString().contains("F")) continue;
|
||||
if (item.toString().contains("H") || item.toString().contains("F")) continue;
|
||||
}
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
|
||||
if (attr & POPULATE_TIMER_MODES) {
|
||||
if (context == TimersContext) {
|
||||
for (int i=0; i<5; i++) {
|
||||
item = RawSwitch(SWITCH_TYPE_TIMER_MODE, i);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
@@ -481,7 +498,7 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettin
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
|
||||
if (attr & POPULATE_ONOFF) {
|
||||
if (context == CustomFunctionsContext) {
|
||||
// ON
|
||||
item = RawSwitch(SWITCH_TYPE_ON);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
@@ -490,7 +507,10 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettin
|
||||
item = RawSwitch(SWITCH_TYPE_ONE, 1);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
// FMx
|
||||
}
|
||||
|
||||
// FMx
|
||||
if (context != MixesContext) {
|
||||
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
|
||||
for (int i=1; i<=GetCurrentFirmware()->getCapability(FlightModes); i++) {
|
||||
item = RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i);
|
||||
@@ -782,19 +802,35 @@ QString getFrSkySrc(int index)
|
||||
|
||||
QString getTrimInc(ModelData * g_model)
|
||||
{
|
||||
switch (g_model->trimInc) {
|
||||
case (1): return QObject::tr("Extra Fine");
|
||||
case (2): return QObject::tr("Fine");
|
||||
case (3): return QObject::tr("Medium");
|
||||
case (4): return QObject::tr("Coarse");
|
||||
default: return QObject::tr("Exponential");
|
||||
}
|
||||
switch (g_model->trimInc) {
|
||||
case -2:
|
||||
return QObject::tr("Exponential");
|
||||
case -1:
|
||||
return QObject::tr("Extra Fine");
|
||||
case 0:
|
||||
return QObject::tr("Fine");
|
||||
case 1:
|
||||
return QObject::tr("Medium");
|
||||
case 2:
|
||||
return QObject::tr("Coarse");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
QString getTimerStr(TimerData & timer)
|
||||
{
|
||||
QString str = ", " + (timer.dir ? QObject::tr("Count Up") : QObject::tr("Count Down"));
|
||||
return QObject::tr("%1:%2, ").arg(timer.val/60, 2, 10, QChar('0')).arg(timer.val%60, 2, 10, QChar('0')) + timer.mode.toString() + str;
|
||||
QString result = QObject::tr("%1:%2").arg(timer.val/60, 2, 10, QChar('0')).arg(timer.val%60, 2, 10, QChar('0'));
|
||||
result += QString(", ") + timer.mode.toString();
|
||||
if (timer.persistent)
|
||||
result += QObject::tr(", Persistent");
|
||||
if (timer.minuteBeep)
|
||||
result += QObject::tr(", MinuteBeep");
|
||||
if (timer.countdownBeep == 1)
|
||||
result += QObject::tr(", CountDown(Beeps)");
|
||||
else if (timer.countdownBeep == 2)
|
||||
result += QObject::tr(", CountDown(Voice)");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getProtocol(ModelData * g_model)
|
||||
@@ -835,18 +871,37 @@ QString getPhasesStr(unsigned int phases, ModelData & model)
|
||||
}
|
||||
}
|
||||
|
||||
QString getCenterBeep(ModelData * g_model)
|
||||
QString getCenterBeepStr(ModelData * g_model)
|
||||
{
|
||||
//RETA123
|
||||
QStringList strl;
|
||||
if(g_model->beepANACenter & 0x01) strl << QObject::tr("Rudder");
|
||||
if(g_model->beepANACenter & 0x02) strl << QObject::tr("Elevator");
|
||||
if(g_model->beepANACenter & 0x04) strl << QObject::tr("Throttle");
|
||||
if(g_model->beepANACenter & 0x08) strl << QObject::tr("Aileron");
|
||||
if(g_model->beepANACenter & 0x10) strl << "P1";
|
||||
if(g_model->beepANACenter & 0x20) strl << "P2";
|
||||
if(g_model->beepANACenter & 0x40) strl << "P3";
|
||||
if(g_model->beepANACenter & 0x80) strl << "LS";
|
||||
if (g_model->beepANACenter & 0x01)
|
||||
strl << QObject::tr("Rudder");
|
||||
if (g_model->beepANACenter & 0x02)
|
||||
strl << QObject::tr("Elevator");
|
||||
if (g_model->beepANACenter & 0x04)
|
||||
strl << QObject::tr("Throttle");
|
||||
if (g_model->beepANACenter & 0x08)
|
||||
strl << QObject::tr("Aileron");
|
||||
if (IS_TARANIS(GetCurrentFirmware()->getBoard())) {
|
||||
if (g_model->beepANACenter & 0x10)
|
||||
strl << "S1";
|
||||
if (g_model->beepANACenter & 0x20)
|
||||
strl << "S2";
|
||||
if (g_model->beepANACenter & 0x40)
|
||||
strl << "S3";
|
||||
if (g_model->beepANACenter & 0x80)
|
||||
strl << "LS";
|
||||
if (g_model->beepANACenter & 0x100)
|
||||
strl << "RS";
|
||||
}
|
||||
else {
|
||||
if (g_model->beepANACenter & 0x10)
|
||||
strl << "P1";
|
||||
if (g_model->beepANACenter & 0x20)
|
||||
strl << "P2";
|
||||
if (g_model->beepANACenter & 0x40)
|
||||
strl << "P3";
|
||||
}
|
||||
return strl.join(", ");
|
||||
}
|
||||
|
||||
@@ -964,3 +1019,17 @@ QString index2version(int index)
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
int qunlink(const QString & fileName)
|
||||
{
|
||||
qDebug() << "unlinking "<< fileName;
|
||||
QByteArray ba = fileName.toLatin1();
|
||||
return unlink(ba.constData());
|
||||
}
|
||||
|
||||
QString generateProcessUniqueTempFileName(const QString & fileName)
|
||||
{
|
||||
QString sanitizedFileName = fileName;
|
||||
sanitizedFileName.remove('/');
|
||||
return QDir::tempPath() + QString("/%1-").arg(QCoreApplication::applicationPid()) + sanitizedFileName;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
extern const QColor colors[C9X_MAX_CURVES];
|
||||
|
||||
#define TMR_NUM_OPTION (TMR_VAROFS+2*9+2*GetCurrentFirmware()->getCapability(LogicalSwitches)-1)
|
||||
#define TMR_NUM_OPTION (TMRMODE_COUNT+2*9+2*GetCurrentFirmware()->getCapability(LogicalSwitches)-1)
|
||||
|
||||
//convert from mode 1 to mode generalSettings.stickMode
|
||||
//NOTICE! => 1..4 -> 1..4
|
||||
@@ -37,12 +37,12 @@ class CompanionIcon: public QIcon {
|
||||
CompanionIcon(QString baseimage);
|
||||
};
|
||||
|
||||
class GVarGroup : public QObject {
|
||||
class GVarGroup: public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GVarGroup(QCheckBox *weightGV, QSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const unsigned int flags=0);
|
||||
GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step=1, bool allowGVars=true);
|
||||
|
||||
protected slots:
|
||||
void gvarCBChanged(int);
|
||||
@@ -50,10 +50,12 @@ class GVarGroup : public QObject {
|
||||
|
||||
protected:
|
||||
QCheckBox *weightGV;
|
||||
QSpinBox *weightSB;
|
||||
QAbstractSpinBox *weightSB;
|
||||
QSpinBox *sb;
|
||||
QDoubleSpinBox *dsb;
|
||||
QComboBox *weightCB;
|
||||
int & weight;
|
||||
const unsigned int flags;
|
||||
double step;
|
||||
bool lock;
|
||||
};
|
||||
|
||||
@@ -81,9 +83,15 @@ class CurveGroup : public QObject {
|
||||
int lastType;
|
||||
};
|
||||
|
||||
#define POPULATE_ONOFF 0x01
|
||||
#define POPULATE_TIMER_MODES 0x02
|
||||
void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettings & generalSettings, unsigned long attr=0);
|
||||
enum SwitchContext
|
||||
{
|
||||
LogicalSwitchesContext,
|
||||
CustomFunctionsContext,
|
||||
TimersContext,
|
||||
MixesContext
|
||||
};
|
||||
|
||||
void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettings & generalSettings, SwitchContext context);
|
||||
|
||||
void populatePhasesCB(QComboBox *b, int value);
|
||||
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
||||
@@ -114,7 +122,7 @@ int findmult(float value, float base);
|
||||
QString getTrimInc(ModelData * g_model);
|
||||
QString getTimerStr(TimerData & timer);
|
||||
QString getProtocol(ModelData * g_model);
|
||||
QString getCenterBeep(ModelData * g_model);
|
||||
QString getCenterBeepStr(ModelData * g_model);
|
||||
|
||||
/* FrSky helpers */
|
||||
QString getFrSkyAlarmType(int alarm);
|
||||
@@ -139,4 +147,8 @@ class QTimeS : public QTime
|
||||
int seconds() const { return hour()*3600 + minute()*60 + second(); };
|
||||
};
|
||||
|
||||
int qunlink(const QString & fileName);
|
||||
|
||||
QString generateProcessUniqueTempFileName(const QString & fileName);
|
||||
|
||||
#endif // HELPERS_H
|
||||
|
||||
@@ -239,13 +239,13 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
itemSelected=n-1;
|
||||
}
|
||||
|
||||
QString geFilename = QDir::tempPath() + "/track0.png";
|
||||
if (QFile::exists(geFilename)) {
|
||||
QFile::remove(geFilename);
|
||||
QString geIconFilename = generateProcessUniqueTempFileName("track0.png");
|
||||
if (QFile::exists(geIconFilename)) {
|
||||
QFile::remove(geIconFilename);
|
||||
}
|
||||
QFile::copy(":/images/track0.png", geFilename);
|
||||
QFile::copy(":/images/track0.png", geIconFilename);
|
||||
|
||||
geFilename = QDir::tempPath() + "/flight.kml";
|
||||
QString geFilename = generateProcessUniqueTempFileName("flight.kml");
|
||||
if (QFile::exists(geFilename)) {
|
||||
QFile::remove(geFilename);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
QTextStream outputStream(&geFile);
|
||||
outputStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n";
|
||||
outputStream << "\t<Document>\n\t\t<name>" << logFilename << "</name>\n";
|
||||
outputStream << "\t\t<Style id=\"multiTrack_n\">\n\t\t\t<IconStyle>\n\t\t\t\t<Icon>\n\t\t\t\t\t<href>file://" << QDir::tempPath() << "/track0.png</href>\n\t\t\t\t</Icon>\n\t\t\t</IconStyle>\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>6</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n";
|
||||
outputStream << "\t\t<Style id=\"multiTrack_n\">\n\t\t\t<IconStyle>\n\t\t\t\t<Icon>\n\t\t\t\t\t<href>file://" << geIconFilename << "</href>\n\t\t\t\t</Icon>\n\t\t\t</IconStyle>\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>6</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n";
|
||||
outputStream << "\t\t<Style id=\"multiTrack_h\">\n\t\t\t<IconStyle>\n\t\t\t\t<scale>0</scale>\n\t\t\t\t<Icon>\n\t\t\t\t\t<href>file://" << QDir::tempPath() << "/track0.png</href>\n\t\t\t\t</Icon>\n\t\t\t</IconStyle>\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>8</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n";
|
||||
outputStream << "\t\t<StyleMap id=\"multiTrack\">\n\t\t\t<Pair>\n\t\t\t\t<key>normal</key>\n\t\t\t\t<styleUrl>#multiTrack_n</styleUrl>\n\t\t\t</Pair>\n\t\t\t<Pair>\n\t\t\t\t<key>highlight</key>\n\t\t\t\t<styleUrl>#multiTrack_h</styleUrl>\n\t\t\t</Pair>\n\t\t</StyleMap>\n";
|
||||
outputStream << "\t\t<Style id=\"lineStyle\">\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>6</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n";
|
||||
|
||||
@@ -804,9 +804,9 @@ QStringList MainWindow::GetSambaArguments(const QString &tcl)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
QString tclFilename = QDir::tempPath() + "/temp.tcl";
|
||||
QString tclFilename = generateProcessUniqueTempFileName("temp.tcl");
|
||||
if (QFile::exists(tclFilename)) {
|
||||
unlink(tclFilename.toAscii());
|
||||
qunlink(tclFilename);
|
||||
}
|
||||
QFile tclFile(tclFilename);
|
||||
if (!tclFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
@@ -946,21 +946,23 @@ QString MainWindow::FindMassstoragePath(QString filename)
|
||||
|
||||
void MainWindow::readEeprom()
|
||||
{
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString tempFile;
|
||||
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
|
||||
if (IS_ARM(eepromInterface->getBoard()))
|
||||
tempFile = tempDir + "/temp.bin";
|
||||
tempFile = generateProcessUniqueTempFileName("temp.bin");
|
||||
else
|
||||
tempFile = tempDir + "/temp.hex";
|
||||
tempFile += generateProcessUniqueTempFileName("temp.hex");
|
||||
|
||||
qDebug() << "MainWindow::readEeprom(): using temp file: " << tempFile;
|
||||
|
||||
if (readEepromFromRadio(tempFile, tr("Read Models and Settings From Radio"))) {
|
||||
MdiChild *child = createMdiChild();
|
||||
child->newFile();
|
||||
child->loadFile(tempFile, false);
|
||||
child->show();
|
||||
qunlink(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,7 +1044,10 @@ bool MainWindow::readEepromFromRadio(const QString filename, const QString messa
|
||||
|
||||
QFile file(filename);
|
||||
if (file.exists()) {
|
||||
file.remove();
|
||||
if (!file.remove()) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("Could not delete temporary file: %1").arg(filename));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
|
||||
@@ -1165,13 +1170,12 @@ void MainWindow::writeBackup()
|
||||
return;
|
||||
}
|
||||
int oldrev = getEpromVersion(fileName);
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString tempFlash = tempDir + "/flash.bin";
|
||||
QString tempFlash = generateProcessUniqueTempFileName("flash.bin");
|
||||
|
||||
if (!readFirmwareFromRadio(tempFlash))
|
||||
return;
|
||||
|
||||
QString restoreFile = tempDir + "/compat.bin";
|
||||
QString restoreFile = generateProcessUniqueTempFileName("compat.bin");
|
||||
if (!convertEEPROM(fileName, restoreFile, tempFlash)) {
|
||||
int ret = QMessageBox::question(this, "Error", tr("Cannot check Models and Settings compatibility! Continue anyway?") ,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
@@ -1188,9 +1192,7 @@ void MainWindow::writeBackup()
|
||||
}
|
||||
fileName = restoreFile;
|
||||
}
|
||||
QByteArray ba = tempFlash.toLatin1();
|
||||
char *name = ba.data();
|
||||
unlink(name);
|
||||
qunlink(tempFlash);
|
||||
}
|
||||
else {
|
||||
if (backupEnable) {
|
||||
@@ -1304,8 +1306,7 @@ void MainWindow::writeFlash(QString fileToFlash)
|
||||
if (!fileName.isEmpty()) {
|
||||
g.backupOnFlash(backup);
|
||||
if (backup) {
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString backupFile = tempDir + "/backup.bin";
|
||||
QString backupFile = generateProcessUniqueTempFileName("backup.bin");
|
||||
bool backupEnable=g.enableBackup();
|
||||
QString backupPath=g.backupDir();
|
||||
if (!backupPath.isEmpty() && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
@@ -1330,7 +1331,7 @@ void MainWindow::writeFlash(QString fileToFlash)
|
||||
sleep(2);
|
||||
int res = writeFirmwareToRadio(fileName);
|
||||
if (res) {
|
||||
QString restoreFile = tempDir + "/restore.bin";
|
||||
QString restoreFile = generateProcessUniqueTempFileName("restore.bin");
|
||||
if (!convertEEPROM(backupFile, restoreFile, fileName)) {
|
||||
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
|
||||
restoreFile = backupFile;
|
||||
|
||||
@@ -531,8 +531,7 @@ void MdiChild::writeEeprom() // write to Tx
|
||||
}
|
||||
QString stickCal=g.profile[g.id()].stickPotCalib();
|
||||
burnConfigDialog bcd;
|
||||
QString tempDir = QDir::tempPath();
|
||||
QString tempFile = tempDir + "/temp.bin";
|
||||
QString tempFile = generateProcessUniqueTempFileName("temp.bin");
|
||||
saveFile(tempFile, false);
|
||||
if(!QFileInfo(tempFile).exists()) {
|
||||
QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!"));
|
||||
@@ -550,12 +549,12 @@ void MdiChild::writeEeprom() // write to Tx
|
||||
return;
|
||||
}
|
||||
int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile);
|
||||
QString tempFlash=tempDir + "/flash.bin";
|
||||
QString tempFlash = generateProcessUniqueTempFileName("flash.bin");
|
||||
|
||||
if (!((MainWindow *)this->parent())->readFirmwareFromRadio(tempFlash))
|
||||
return;
|
||||
|
||||
QString restoreFile = tempDir + "/compat.bin";
|
||||
QString restoreFile = generateProcessUniqueTempFileName("compat.bin");
|
||||
if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) {
|
||||
int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret == QMessageBox::No)
|
||||
@@ -571,9 +570,7 @@ void MdiChild::writeEeprom() // write to Tx
|
||||
}
|
||||
tempFile=restoreFile;
|
||||
}
|
||||
QByteArray ba = tempFlash.toLatin1();
|
||||
char *name = ba.data();
|
||||
unlink(name);
|
||||
qunlink(tempFlash);
|
||||
}
|
||||
else {
|
||||
if (backupEnable) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "channels.h"
|
||||
#include "helpers.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
@@ -6,6 +7,74 @@
|
||||
#include <QCheckBox>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt):
|
||||
firmware(firmware),
|
||||
spinbox(new QDoubleSpinBox()),
|
||||
value(value),
|
||||
step(1.0)
|
||||
{
|
||||
|
||||
bool allowGVars = false;
|
||||
|
||||
spinbox->setProperty("index", row);
|
||||
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
spinbox->setAccelerated(true);
|
||||
|
||||
if (firmware->getCapability(PPMUnitMicroseconds)) {
|
||||
step = 5.12;
|
||||
spinbox->setDecimals(1);
|
||||
spinbox->setSuffix("us");
|
||||
}
|
||||
else {
|
||||
spinbox->setDecimals(0);
|
||||
spinbox->setSuffix("%");
|
||||
}
|
||||
|
||||
if (IS_TARANIS(firmware->getBoard()) || deflt == 0 /*it's the offset*/) {
|
||||
min *= 10;
|
||||
max *= 10;
|
||||
deflt *= 10;
|
||||
step /= 10;
|
||||
spinbox->setDecimals(1);
|
||||
allowGVars = true;
|
||||
}
|
||||
|
||||
spinbox->setSingleStep(step);
|
||||
|
||||
QHBoxLayout * horizontalLayout = new QHBoxLayout();
|
||||
QCheckBox * gv = new QCheckBox(QObject::tr("GV"));
|
||||
horizontalLayout->addWidget(gv);
|
||||
QComboBox * cb = new QComboBox();
|
||||
horizontalLayout->addWidget(cb);
|
||||
horizontalLayout->addWidget(spinbox);
|
||||
gridLayout->addLayout(horizontalLayout, row, col, 1, 1);
|
||||
gvarGroup = new GVarGroup(gv, spinbox, cb, value, deflt, min, max, step, allowGVars);
|
||||
}
|
||||
|
||||
LimitsGroup::~LimitsGroup()
|
||||
{
|
||||
delete gvarGroup;
|
||||
}
|
||||
|
||||
void LimitsGroup::updateMinMax(int max)
|
||||
{
|
||||
if (IS_TARANIS(firmware->getBoard())) {
|
||||
max *= 10;
|
||||
}
|
||||
if (spinbox->maximum() == 0) {
|
||||
spinbox->setMinimum(-step*max);
|
||||
if (value < -max) {
|
||||
value = -max;
|
||||
}
|
||||
}
|
||||
if (spinbox->minimum() == 0) {
|
||||
spinbox->setMaximum(step*max);
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware):
|
||||
ModelPanel(parent, model, generalSettings, firmware)
|
||||
{
|
||||
@@ -13,8 +82,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
bool minimize = false;
|
||||
|
||||
int col = 1;
|
||||
if (firmware->getCapability(ChannelsName))
|
||||
{
|
||||
if (firmware->getCapability(ChannelsName)) {
|
||||
minimize=true;
|
||||
addLabel(gridLayout, tr("Name"), col++);
|
||||
}
|
||||
@@ -52,44 +120,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
}
|
||||
|
||||
// Channel offset
|
||||
QDoubleSpinBox * offset = new QDoubleSpinBox(this);
|
||||
offset->setProperty("index", i);
|
||||
offset->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
offset->setAccelerated(true);
|
||||
offset->setDecimals(1);
|
||||
offset->setMinimum(-100);
|
||||
offset->setSingleStep(0.1);
|
||||
offset->setValue(float(model.limitData[i].offset) / 10);
|
||||
connect(offset, SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
|
||||
gridLayout->addWidget(offset, i+1, col++, 1, 1);
|
||||
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].offset, -100, 100, 0);
|
||||
|
||||
// Channel min
|
||||
QDoubleSpinBox * minSB = new QDoubleSpinBox(this);
|
||||
minSB->setProperty("index", i);
|
||||
minSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
minSB->setAccelerated(true);
|
||||
minSB->setDecimals(1);
|
||||
minSB->setMinimum(-model.getChannelsMax());
|
||||
minSB->setSingleStep(0.1);
|
||||
minSB->setMaximum(0);
|
||||
minSB->setValue(float(model.limitData[i].min) / 10);
|
||||
connect(minSB, SIGNAL(editingFinished()), this, SLOT(minEdited()));
|
||||
gridLayout->addWidget(minSB, i+1, col++, 1, 1);
|
||||
minSpins << minSB;
|
||||
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].min, -model.getChannelsMax(), 0, -100);
|
||||
|
||||
// Channel max
|
||||
QDoubleSpinBox * maxSB = new QDoubleSpinBox(this);
|
||||
maxSB->setProperty("index", i);
|
||||
maxSB->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
maxSB->setAccelerated(true);
|
||||
maxSB->setDecimals(1);
|
||||
maxSB->setMinimum(0);
|
||||
maxSB->setSingleStep(0.1);
|
||||
maxSB->setMaximum(model.getChannelsMax());
|
||||
maxSB->setValue(float(model.limitData[i].max) / 10);
|
||||
connect(maxSB, SIGNAL(editingFinished()), this, SLOT(maxEdited()));
|
||||
gridLayout->addWidget(maxSB, i+1, col++, 1, 1);
|
||||
maxSpins << maxSB;
|
||||
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].max, 0, model.getChannelsMax(), 100);
|
||||
|
||||
// Channel inversion
|
||||
QComboBox * invCB = new QComboBox(this);
|
||||
@@ -117,6 +154,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
QSpinBox * center = new QSpinBox(this);
|
||||
center->setProperty("index", i);
|
||||
center->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
center->setSuffix("us");
|
||||
center->setMinimum(1375);
|
||||
center->setMaximum(1625);
|
||||
center->setValue(1500);
|
||||
@@ -134,6 +172,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
gridLayout->addWidget(symlimits, i+1, col++, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Push the rows up
|
||||
addVSpring(gridLayout, 0,firmware->getCapability(Outputs)+1);
|
||||
|
||||
@@ -142,6 +181,9 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
|
||||
Channels::~Channels()
|
||||
{
|
||||
foreach(LimitsGroup *group, limitsGroups) {
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
|
||||
void Channels::symlimitsEdited()
|
||||
@@ -164,46 +206,14 @@ void Channels::nameEdited()
|
||||
}
|
||||
}
|
||||
|
||||
void Channels::offsetEdited()
|
||||
{
|
||||
QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int index = dsb->property("index").toInt();
|
||||
model.limitData[index].offset = round(dsb->value() * 10);
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void Channels::minEdited()
|
||||
{
|
||||
QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int index = sb->property("index").toInt();
|
||||
model.limitData[index].min = round(sb->value() * 10);
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void Channels::maxEdited()
|
||||
{
|
||||
QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int index = sb->property("index").toInt();
|
||||
model.limitData[index].max = round(sb->value() * 10);
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void Channels::refreshExtendedLimits()
|
||||
{
|
||||
int channelMax = model.getChannelsMax();
|
||||
int channelMaxValue = channelMax * 10;
|
||||
|
||||
for (int i=0; i<firmware->getCapability(Outputs); i++) {
|
||||
QDoubleSpinBox * minDSB = minSpins[i];
|
||||
QDoubleSpinBox * maxDSB = maxSpins[i];
|
||||
|
||||
minDSB->setMinimum(-channelMax);
|
||||
maxDSB->setMaximum(+channelMax);
|
||||
|
||||
//reset any limit that is bigger than current maximum (dependent on extended limits setting)
|
||||
if ( model.limitData[i].min < -channelMaxValue ) model.limitData[i].min = -channelMaxValue;
|
||||
if ( model.limitData[i].max > +channelMaxValue ) model.limitData[i].max = +channelMaxValue;
|
||||
foreach(LimitsGroup *group, limitsGroups) {
|
||||
group->updateMinMax(channelMax);
|
||||
}
|
||||
|
||||
emit modified();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,24 @@
|
||||
#include "modelpanel.h"
|
||||
#include <QSpinBox>
|
||||
|
||||
class GVarGroup;
|
||||
|
||||
class LimitsGroup
|
||||
{
|
||||
public:
|
||||
LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt);
|
||||
~LimitsGroup();
|
||||
|
||||
void updateMinMax(int max);
|
||||
|
||||
protected:
|
||||
FirmwareInterface * firmware;
|
||||
QDoubleSpinBox * spinbox;
|
||||
GVarGroup * gvarGroup;
|
||||
int & value;
|
||||
double step;
|
||||
};
|
||||
|
||||
class Channels : public ModelPanel
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -13,8 +31,7 @@ class Channels : public ModelPanel
|
||||
~Channels();
|
||||
|
||||
private:
|
||||
QVector<QDoubleSpinBox *> minSpins;
|
||||
QVector<QDoubleSpinBox *> maxSpins;
|
||||
QVector<LimitsGroup *> limitsGroups;
|
||||
|
||||
public slots:
|
||||
void refreshExtendedLimits();
|
||||
@@ -22,9 +39,6 @@ class Channels : public ModelPanel
|
||||
private slots:
|
||||
void symlimitsEdited();
|
||||
void nameEdited();
|
||||
void offsetEdited();
|
||||
void minEdited();
|
||||
void maxEdited();
|
||||
void invEdited();
|
||||
void curveEdited();
|
||||
void ppmcenterEdited();
|
||||
|
||||
@@ -506,7 +506,7 @@ void CustomFunctionsPanel::update()
|
||||
lock = true;
|
||||
for (int i=0; i<firmware->getCapability(CustomFunctions); i++) {
|
||||
if (!initialized) {
|
||||
populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, generalSettings, POPULATE_ONOFF);
|
||||
populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, generalSettings, CustomFunctionsContext);
|
||||
populateFuncCB(fswtchFunc[i], model.funcSw[i].func);
|
||||
populateGVmodeCB(fswtchGVmode[i], model.funcSw[i].adjustMode);
|
||||
populateFuncParamCB(fswtchParamT[i], model, model.funcSw[i].func, model.funcSw[i].param, model.funcSw[i].adjustMode);
|
||||
@@ -527,7 +527,7 @@ void CustomFunctionsPanel::fswPaste()
|
||||
FuncSwData *fsw = &model.funcSw[selectedFunction];
|
||||
memcpy(fsw, fswData.mid(0, sizeof(FuncSwData)).constData(), sizeof(FuncSwData));
|
||||
lock = true;
|
||||
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, POPULATE_ONOFF);
|
||||
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
|
||||
populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
|
||||
populateGVmodeCB(fswtchGVmode[selectedFunction], model.funcSw[selectedFunction].adjustMode);
|
||||
populateFuncParamCB(fswtchParamT[selectedFunction], model, model.funcSw[selectedFunction].func, model.funcSw[selectedFunction].param, model.funcSw[selectedFunction].adjustMode);
|
||||
@@ -543,7 +543,7 @@ void CustomFunctionsPanel::fswDelete()
|
||||
model.funcSw[selectedFunction].clear();
|
||||
// TODO update switch and func
|
||||
lock = true;
|
||||
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, POPULATE_ONOFF);
|
||||
populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
|
||||
populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
|
||||
refreshCustomFunction(selectedFunction);
|
||||
lock = false;
|
||||
|
||||
@@ -33,7 +33,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
|
||||
curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve);
|
||||
|
||||
populateSwitchCB(ui->switchesCB, ed->swtch, generalSettings);
|
||||
populateSwitchCB(ui->switchesCB, ed->swtch, generalSettings, MixesContext);
|
||||
|
||||
ui->sideCB->setCurrentIndex(ed->mode-1);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
|
||||
// Phase switch
|
||||
if (phaseIdx > 0) {
|
||||
populateSwitchCB(ui->swtch, phase.swtch, generalSettings);
|
||||
populateSwitchCB(ui->swtch, phase.swtch, generalSettings, MixesContext);
|
||||
connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
|
||||
}
|
||||
else {
|
||||
@@ -315,10 +315,10 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index)
|
||||
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||
int gvar = comboBox->property("index").toInt();
|
||||
if (index == 0) {
|
||||
phase.gvars[gvar]=0;
|
||||
phase.gvars[gvar] = 0;
|
||||
}
|
||||
else {
|
||||
phase.gvars[gvar] = 1024+index+(index>phaseIdx?1:0);
|
||||
phase.gvars[gvar] = 1024 + index;
|
||||
}
|
||||
update();
|
||||
emit modified();
|
||||
|
||||
@@ -239,6 +239,7 @@ void LogicalSwitchesPanel::edited()
|
||||
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
|
||||
break;
|
||||
case LS_FAMILY_STAY:
|
||||
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
|
||||
if (sender() == cswitchOffset[i]) {
|
||||
model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value());
|
||||
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
|
||||
@@ -246,10 +247,12 @@ void LogicalSwitchesPanel::edited()
|
||||
else {
|
||||
model.customSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.customSw[i].val2;
|
||||
}
|
||||
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value());
|
||||
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
|
||||
if (model.customSw[i].val3 == 0) {
|
||||
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
|
||||
cswitchOffset2[i]->clear();
|
||||
cswitchOffset2[i]->setSuffix("(infinite)");
|
||||
}
|
||||
else {
|
||||
cswitchOffset2[i]->setSuffix("");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -274,7 +277,6 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl
|
||||
else
|
||||
sb->setSingleStep(0.1);
|
||||
sb->setValue(value);
|
||||
sb->setSuffix("");
|
||||
}
|
||||
|
||||
#define SOURCE1_VISIBLE 0x1
|
||||
@@ -320,21 +322,24 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
|
||||
}
|
||||
break;
|
||||
case LS_FAMILY_STICKY:
|
||||
mask &= ~DELAY_ENABLED;
|
||||
// no break
|
||||
case LS_FAMILY_VBOOL:
|
||||
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
|
||||
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings);
|
||||
populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2), generalSettings);
|
||||
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
|
||||
populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2), generalSettings, LogicalSwitchesContext);
|
||||
break;
|
||||
case LS_FAMILY_STAY:
|
||||
mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE;
|
||||
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings);
|
||||
mask &= ~DELAY_ENABLED;
|
||||
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
|
||||
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
|
||||
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value());
|
||||
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
|
||||
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
|
||||
if (model.customSw[i].val3 == 0) {
|
||||
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
|
||||
cswitchOffset2[i]->clear();
|
||||
}
|
||||
else {
|
||||
cswitchOffset2[i]->setSuffix("");
|
||||
}
|
||||
break;
|
||||
case LS_FAMILY_VCOMP:
|
||||
@@ -410,7 +415,7 @@ void LogicalSwitchesPanel::populateCSWCB(QComboBox *b, int value)
|
||||
void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b, const RawSwitch & value)
|
||||
{
|
||||
if (IS_ARM(firmware->getBoard())) {
|
||||
populateSwitchCB(b, value, generalSettings, POPULATE_ONOFF);
|
||||
populateSwitchCB(b, value, generalSettings, LogicalSwitchesContext);
|
||||
}
|
||||
else {
|
||||
RawSwitch item;
|
||||
|
||||
@@ -76,7 +76,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, G
|
||||
}
|
||||
}
|
||||
|
||||
populateSwitchCB(ui->switchesCB, md->swtch, generalSettings);
|
||||
populateSwitchCB(ui->switchesCB, md->swtch, generalSettings, MixesContext);
|
||||
ui->warningCB->setCurrentIndex(md->mixWarn);
|
||||
ui->mltpxCB->setCurrentIndex(md->mltpx);
|
||||
int scale=firmware->getCapability(SlowScale);
|
||||
|
||||
@@ -15,7 +15,7 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
|
||||
lock = true;
|
||||
|
||||
// Mode
|
||||
populateSwitchCB(ui->mode, timer.mode, generalSettings, POPULATE_TIMER_MODES);
|
||||
populateSwitchCB(ui->mode, timer.mode, generalSettings, TimersContext);
|
||||
|
||||
if (!firmware->getCapability(PermTimers)) {
|
||||
ui->persistent->hide();
|
||||
@@ -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);
|
||||
|
||||
@@ -31,12 +31,12 @@ PrintDialog::PrintDialog(QWidget *parent, FirmwareInterface * firmware, GeneralS
|
||||
te->clear();
|
||||
QString modelname=g_model->name;
|
||||
if (modelname.isEmpty()) {
|
||||
curvefile5=QString("%1/curve5.png").arg(qd->tempPath());
|
||||
curvefile9=QString("%1/curve9.png").arg(qd->tempPath());
|
||||
curvefile5=generateProcessUniqueTempFileName("curve5.png");
|
||||
curvefile9=generateProcessUniqueTempFileName("curve9.png");
|
||||
}
|
||||
else {
|
||||
curvefile5=QString("%1/%2-curve5.png").arg(qd->tempPath()).arg(modelname);
|
||||
curvefile9=QString("%1/%2-curve9.png").arg(qd->tempPath()).arg(modelname);
|
||||
curvefile5=generateProcessUniqueTempFileName(QString("%1-curve5.png").arg(modelname));
|
||||
curvefile9=generateProcessUniqueTempFileName(QString("%1-curve9.png").arg(modelname));
|
||||
}
|
||||
printSetup();
|
||||
if (gvars) {
|
||||
@@ -60,19 +60,14 @@ PrintDialog::PrintDialog(QWidget *parent, FirmwareInterface * firmware, GeneralS
|
||||
|
||||
void PrintDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (printfilename.isEmpty()) {
|
||||
QByteArray ba = curvefile5.toLatin1();
|
||||
char *name = ba.data();
|
||||
unlink(name);
|
||||
ba = curvefile9.toLatin1();
|
||||
name = ba.data();
|
||||
unlink(name);
|
||||
}
|
||||
}
|
||||
|
||||
PrintDialog::~PrintDialog()
|
||||
{
|
||||
delete ui;
|
||||
// notice PrintDialog::closeEvent() is not called if user clicks on Close button
|
||||
qunlink(curvefile5);
|
||||
qunlink(curvefile9);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString doTC(const QString s, const QString color="", bool bold=false)
|
||||
@@ -121,10 +116,8 @@ void PrintDialog::printSetup()
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model))); //proto, numch, delay,
|
||||
str.append(fv(tr("Pulse Polarity"), g_model->moduleData[0].polarityToString()));
|
||||
str.append(fv(tr("Throttle Trim"), g_model->thrTrim ? tr("Enabled") : tr("Disabled")));
|
||||
str.append(fv(tr("Throttle Expo"), g_model->thrExpo ? tr("Enabled") : tr("Disabled")));
|
||||
// TODO str.append(fv(tr("Trim Switch"), getSWName(g_model->trimSw)));
|
||||
str.append(fv(tr("Trim Increment"), getTrimInc(g_model)));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeep(g_model))); // specify which channels beep
|
||||
str.append(fv(tr("Center Beep"), getCenterBeepStr(g_model))); // specify which channels beep
|
||||
str.append("</td></tr></table></td>");
|
||||
if (!gvars) {
|
||||
str.append("<td width=\"380\">");
|
||||
|
||||
@@ -1458,82 +1458,82 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<message>
|
||||
<location filename="../modeledit/templates.cpp" line="+39"/>
|
||||
<source>Simple 4-CH</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Enkel 4-Kanal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>T-Cut</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Gas-klipp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Sticky T-Cut</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Sticky Gas-Klipp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>V-Tail</source>
|
||||
<translation type="unfinished">V-stjärt</translation>
|
||||
<translation>V-stjärt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Elevon\Delta</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Flygande vinge/Deltavinge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Heli Setup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Helikopter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Heli Setup with gyro gain control</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Helikopter med gyro-gain</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Gyro gain control</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Gyrogain-kontroll</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Heli Setup (Futaba's channel assignment style)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Helikopter (Futabas kanalordning)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Heli Setup with gyro gain control (Futaba's channel assignment style)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Helikopter med gyro gain (Futabas kanalordning)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Gyro gain control (Futaba's channel assignment style)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Gyrogain-kontroll (Futabas kanalordning)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Servo Test</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Servotest</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>MultiCopter</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Multikopter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Use Model Config Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Använd Modellguiden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+29"/>
|
||||
<source>Apply Template?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Använd Mall?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Apply template "%1"?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Använd Mall "%1"?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+88"/>
|
||||
@@ -1544,7 +1544,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+2"/>
|
||||
<location line="+129"/>
|
||||
<source>RUD</source>
|
||||
<translation type="unfinished">ROD</translation>
|
||||
<translation>ROD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-316"/>
|
||||
@@ -1558,14 +1558,14 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+113"/>
|
||||
<location line="+1"/>
|
||||
<source>ELE</source>
|
||||
<translation type="unfinished">HÖJ</translation>
|
||||
<translation>HJD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-298"/>
|
||||
<location line="+171"/>
|
||||
<location line="+122"/>
|
||||
<source>THR</source>
|
||||
<translation type="unfinished">GAS</translation>
|
||||
<translation>GAS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-277"/>
|
||||
@@ -1577,7 +1577,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+94"/>
|
||||
<location line="+1"/>
|
||||
<source>AIL</source>
|
||||
<translation type="unfinished">SKE</translation>
|
||||
<translation>SKE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-279"/>
|
||||
@@ -1585,7 +1585,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+185"/>
|
||||
<location line="+6"/>
|
||||
<source>AIL2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>SKE2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-184"/>
|
||||
@@ -1593,7 +1593,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+185"/>
|
||||
<location line="+6"/>
|
||||
<source>ELE2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>HJD2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-187"/>
|
||||
@@ -1603,7 +1603,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+94"/>
|
||||
<location line="+1"/>
|
||||
<source>FLAPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>FLAPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-272"/>
|
||||
@@ -1613,7 +1613,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+89"/>
|
||||
<location line="+6"/>
|
||||
<source>FLAP%1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>FLAP%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-252"/>
|
||||
@@ -1621,7 +1621,7 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+21"/>
|
||||
<location line="+4"/>
|
||||
<source>PITCH</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>PITCH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-16"/>
|
||||
@@ -1633,41 +1633,41 @@ Behöver inte vara samma som menyspråket</translation>
|
||||
<location line="+3"/>
|
||||
<location line="+1"/>
|
||||
<source>GYRO</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>GYRO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+118"/>
|
||||
<location line="+1"/>
|
||||
<source>SPOIL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>SPOIL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+14"/>
|
||||
<location line="+6"/>
|
||||
<source>SPOIL%1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>SPOIL%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+39"/>
|
||||
<location line="+6"/>
|
||||
<source>RUD2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>ROD2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+203"/>
|
||||
<location line="+112"/>
|
||||
<source>Clear Mixes?</source>
|
||||
<translation type="unfinished">Ta bort mixarna?</translation>
|
||||
<translation>Nollställ mixarna?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-112"/>
|
||||
<source>Really clear existing mixes on CH6?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Vill du verkligen ta bort mixarna på kanal 6?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+112"/>
|
||||
<source>Really clear existing mixes on CH5?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Vill du verkligen ta bort mixarna på kanal 5?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -6480,7 +6480,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+383"/>
|
||||
<source>Override %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>I stället för %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+2"/>
|
||||
@@ -6655,7 +6655,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Cell</source>
|
||||
<translation>Batt</translation>
|
||||
<translation>Cell</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+43"/>
|
||||
@@ -6713,7 +6713,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+13"/>
|
||||
<source>Speed+</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Hastighet+</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
@@ -7044,7 +7044,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="-627"/>
|
||||
<source>(displaying only first 10 warnings)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>(enbart de 10 första varningarna visas)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+660"/>
|
||||
@@ -8336,13 +8336,13 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+452"/>
|
||||
<source>OpenTX doesn't accept this telemetry protocol</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>OpenTX accepterar inte detta telemetri-protokoll</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+104"/>
|
||||
<location line="+5"/>
|
||||
<source>OpenTX doesn't accept this radio protocol</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>OpenTX accepterar inte detta radio-protokoll</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OpenTX doesn't accept this protocol</source>
|
||||
@@ -8389,7 +8389,7 @@ eeprom-storleken är 4096, men enbart den första hälften används</translation
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>No OverrideCH functions available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Inga funktioner finns för att ersätta kanaldata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+37"/>
|
||||
@@ -8532,12 +8532,12 @@ OpenTX-gruppen.</translation>
|
||||
<message>
|
||||
<location filename="../eeprominterface.h" line="+957"/>
|
||||
<source>Positive</source>
|
||||
<translation type="unfinished">Positiv</translation>
|
||||
<translation>Positiv</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Negative</source>
|
||||
<translation type="unfinished">Negativ</translation>
|
||||
<translation>Negativ</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -8761,7 +8761,7 @@ Gasen reverseras om alternativet väljs. Tomgång ligger då uppåt. Trim och ga
|
||||
<location line="+23"/>
|
||||
<location line="+1"/>
|
||||
<source>Outputs</source>
|
||||
<translation type="unfinished">Utgångar</translation>
|
||||
<translation>Utgångar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+153"/>
|
||||
@@ -8827,7 +8827,7 @@ Gasen reverseras om alternativet väljs. Tomgång ligger då uppåt. Trim och ga
|
||||
<message>
|
||||
<location line="+638"/>
|
||||
<source>Outputs2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Outputs2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+13"/>
|
||||
@@ -8900,7 +8900,7 @@ Gasen reverseras om alternativet väljs. Tomgång ligger då uppåt. Trim och ga
|
||||
<message>
|
||||
<location line="+219"/>
|
||||
<source>Outputs2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Outputs2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+13"/>
|
||||
@@ -9499,17 +9499,17 @@ Gasen reverseras om alternativet väljs. Tomgång ligger då uppåt. Trim och ga
|
||||
<message>
|
||||
<location line="-189"/>
|
||||
<source>FrSky S.PORT</source>
|
||||
<translation type="unfinished">FrSky S.PORT</translation>
|
||||
<translation>FrSky S.PORT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>FrSky D</source>
|
||||
<translation type="unfinished">FrSky D</translation>
|
||||
<translation>FrSky D</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+2"/>
|
||||
<source>FrSky D (cable)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>FrSky D (kabel)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+187"/>
|
||||
@@ -9629,17 +9629,17 @@ Gasen reverseras om alternativet väljs. Tomgång ligger då uppåt. Trim och ga
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<source>Not persistent</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ej bestående</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Persistent (flight)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Bestående (under flygning)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Persistent (manual reset)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Bestående (återställs manuellt)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
||||
@@ -136,7 +136,6 @@ void saveModel(ModelData & m, model & xm)
|
||||
trims xtrims;
|
||||
xtrims.extended(m.extendedTrims);
|
||||
xtrims.throttleTrim(m.thrTrim);
|
||||
xtrims.throttleTrimExpo(m.thrExpo);
|
||||
xm.trims(xtrims);
|
||||
}
|
||||
if (m.beepANACenter) {
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
<h2>Version 2.0.10 / 2014-09-08</h2>
|
||||
[All]
|
||||
<ul>
|
||||
<li>Duration and AND fixed on Sticky and Edge logical switches
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>CCPM issue on Helis when cross trims used
|
||||
<li>Taranis+ LCD color range and brightness adjusted
|
||||
<li>Taranis+ SWR removed
|
||||
<li>Lua small enhancements (TIMEHOUR constant, GVARS over 500)
|
||||
<li>Lua hardening, use of newlib-nano (optimizes RAM usage)
|
||||
<li>Incoming telemetry rejected if RSSI=0
|
||||
<li>Assign Bitmap impossible if filename length too big
|
||||
<li>
|
||||
|
||||
[9XR-PRO]
|
||||
<ul>
|
||||
<li>Telemetry enabled
|
||||
|
||||
<h2>Version 2.0.8 / 2014-07-23</h2>
|
||||
[Taranis]
|
||||
<ul>
|
||||
|
||||
@@ -26,3 +26,4 @@
|
||||
/gtests.d
|
||||
/lua_exports.cpp
|
||||
/lua_exports.txt
|
||||
/lua_fields.txt
|
||||
|
||||
@@ -289,6 +289,10 @@ USB = JOYSTICK
|
||||
# NO - normal behaviour, show real channel values
|
||||
CHANNELS_MONITOR_INV_HIDE = NO
|
||||
|
||||
# Use newlib-nano
|
||||
# Values = NO, YES
|
||||
NANO = YES
|
||||
|
||||
#------- END BUILD OPTIONS ---------------------------
|
||||
|
||||
# Define programs and commands.
|
||||
@@ -296,7 +300,7 @@ SHELL = sh
|
||||
IMG2LBM = -python ../util/img2lbm.py
|
||||
BIN2LBM = -python ../util/bin2lbm.py
|
||||
TRANSLATE = -python ../util/translate.py
|
||||
VERSION = 2.0.8
|
||||
VERSION = 2.0.10
|
||||
|
||||
SRC =
|
||||
CPPSRC =
|
||||
@@ -718,6 +722,12 @@ ifeq ($(PCB), TARANIS)
|
||||
EXTRABOARDSRC += targets/taranis/usbd_storage_msd.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(NANO), YES)
|
||||
# use newlib-nano for linking
|
||||
NEWLIB_NANO_FLAGS = --specs=nano.specs -u _printf_float
|
||||
CPPDEFS += -DNANO
|
||||
endif
|
||||
|
||||
ifneq ($(LUA), NO)
|
||||
ifeq ($(LUA), YES)
|
||||
CPPDEFS += -DLUA_MODEL_SCRIPTS
|
||||
@@ -1278,9 +1288,10 @@ bitmaps/sticks.lbm: bitmaps/sticks_4x1.xbm bitmaps/splash_9x.xbm bitmaps/splash_
|
||||
|
||||
lua_exports.cpp: myeeprom.h ../util/luaexport.py
|
||||
@echo "Generating a list of Lua exported constants in lua_exports.txt"
|
||||
@$(CPP) -DPCBTARANIS -DCPUARM -DLUA -DEXPORT myeeprom.h | grep LEXP > lua_exports.txt
|
||||
@$(CPP) -DPCBTARANIS -DCPUARM -DLUA -DEXPORT myeeprom.h | grep LEXP > lua_exports.txt
|
||||
@echo "Parsing and generating C Lua exports in lua_exports.cpp"
|
||||
@python ../util/luaexport.py lua_exports.txt lua_exports.cpp
|
||||
@python ../util/luaexport.py $(VERSION) lua_exports.txt lua_exports.cpp lua_fields.txt
|
||||
@rm lua_exports.txt
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
@@ -1323,7 +1334,7 @@ FOXLIB=-L/usr/local/lib \
|
||||
-Wl,-rpath,$(FOXPATH)/src/.libs
|
||||
|
||||
simu: $(LUADEP) stamp_header $(BOARDSRC) $(CPPSRC) Makefile simu.cpp targets/simu/simpgmspace.cpp *.h tra lbm eeprom.bin
|
||||
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions
|
||||
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -DLUA_USE_APICHECK -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions
|
||||
|
||||
eeprom.bin:
|
||||
dd if=/dev/zero of=$@ bs=1 count=2048
|
||||
@@ -1389,7 +1400,7 @@ OBJS = $(TMP:.s=.o)
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $@
|
||||
$(CC) $(ARMCPPFLAGS) $< -o allsrc.o
|
||||
$(CC) $(OBJS) allsrc.o -mcpu=cortex-m3 -mthumb -nostartfiles -lm -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch,--gc-sections -o $@
|
||||
$(CC) $(OBJS) allsrc.o -mcpu=cortex-m3 -mthumb -nostartfiles -lm -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch,--gc-sections $(NEWLIB_NANO_FLAGS) -o $@
|
||||
endif
|
||||
|
||||
# Target: clean project.
|
||||
@@ -1419,7 +1430,7 @@ clean_list :
|
||||
$(REMOVE) stamp-opentx.h
|
||||
$(REMOVE) bitmaps/*.lbm
|
||||
$(REMOVE) fonts/*/*.lbm
|
||||
$(REMOVE) lua_exports.txt lua_exports.cpp
|
||||
$(REMOVE) lua_exports.txt lua_exports.cpp lua_fields.txt
|
||||
$(MAKE) -C bootloader clean
|
||||
|
||||
#### Install
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -183,7 +183,7 @@ const pm_char * bmpLoad(uint8_t *bmp, const char *filename, const xcoord_t width
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
for (uint32_t j=0; j<w/2; j++) {
|
||||
for (uint32_t j=0; j<(w+1)/2; j++) {
|
||||
uint8_t * dst = dest + (i/2)*w + j*2;
|
||||
if (i & 1) {
|
||||
uint8_t val = palette[(buf[j] >> 4) & 0x0F] << 4;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -472,8 +472,8 @@ void ConvertModel_215_to_216(ModelData &model)
|
||||
memcpy(&g_model.header, &oldModel.header, sizeof(g_model.header));
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
TimerData & timer = g_model.timers[i];
|
||||
if (oldModel.timers[i].mode >= TMRMODE_FIRST_SWITCH)
|
||||
timer.mode = TMRMODE_FIRST_SWITCH + ConvertSwitch_215_to_216(oldModel.timers[i].mode - TMRMODE_FIRST_SWITCH + 1) - 1;
|
||||
if (oldModel.timers[i].mode >= TMRMODE_COUNT)
|
||||
timer.mode = TMRMODE_COUNT + ConvertSwitch_215_to_216(oldModel.timers[i].mode - TMRMODE_COUNT + 1) - 1;
|
||||
else
|
||||
timer.mode = oldModel.timers[i].mode;
|
||||
timer.start = oldModel.timers[i].start;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -229,16 +229,16 @@ void menuGeneralSetup(uint8_t event)
|
||||
#if defined(RTCLOCK)
|
||||
case ITEM_SETUP_DATE:
|
||||
lcd_putsLeft(y, STR_DATE);
|
||||
lcd_putc(RADIO_SETUP_DATE_COLUMN+2, y, '-'); lcd_putc(RADIO_SETUP_DATE_COLUMN+3*FW, y, '-');
|
||||
lcd_putc(RADIO_SETUP_DATE_COLUMN, y, '-'); lcd_putc(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-');
|
||||
for (uint8_t j=0; j<3; j++) {
|
||||
uint8_t rowattr = (m_posHorz==j ? attr : 0);
|
||||
switch (j) {
|
||||
case 0:
|
||||
lcd_outdezAtt(RADIO_SETUP_DATE_COLUMN+2, y, t.tm_year+1900, rowattr);
|
||||
lcd_outdezAtt(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr);
|
||||
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0);
|
||||
break;
|
||||
case 1:
|
||||
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+3*FW, y, t.tm_mon+1, rowattr|LEADING0, 2);
|
||||
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0, 2);
|
||||
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0);
|
||||
break;
|
||||
case 2:
|
||||
@@ -247,7 +247,7 @@ void menuGeneralSetup(uint8_t event)
|
||||
int8_t dlim = (((((year%4==0) && (year%100!=0)) || (year%400==0)) && (t.tm_mon==1)) ? 1 : 0);
|
||||
static const pm_uint8_t dmon[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
dlim += pgm_read_byte(&dmon[t.tm_mon]);
|
||||
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+6*FW-2, y, t.tm_mday, rowattr|LEADING0, 2);
|
||||
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0, 2);
|
||||
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0);
|
||||
break;
|
||||
}
|
||||
@@ -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, 100, attr);
|
||||
if (attr) g_eeGeneral.backlightColor = checkIncDec(event, g_eeGeneral.backlightColor, 0, 100, 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;
|
||||
}
|
||||
|
||||
@@ -1120,7 +1120,7 @@ void menuModelSetup(uint8_t event)
|
||||
div_t qr = div(timer->start, 60);
|
||||
switch (m_posHorz) {
|
||||
case 0:
|
||||
CHECK_INCDEC_MODELVAR(event, timer->mode, SWSRC_FIRST, TMR_VAROFS+SWSRC_LAST-1);
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, timer->mode, SWSRC_FIRST, TMRMODE_COUNT+SWSRC_LAST-1/*SWSRC_None removed*/, isSwitchAvailableInTimers);
|
||||
break;
|
||||
case 1:
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59);
|
||||
@@ -1224,7 +1224,7 @@ void menuModelSetup(uint8_t event)
|
||||
if (attr) {
|
||||
s_editMode = 0;
|
||||
if (!READ_ONLY()) {
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
CASE_EVT_ROTARY_BREAK
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
#if defined(CPUM64)
|
||||
@@ -1320,12 +1320,12 @@ void menuModelSetup(uint8_t event)
|
||||
}
|
||||
}
|
||||
|
||||
lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""Off\0""Man\0""Auto"), potMode, attr & ((m_posHorz == 0) ? attr : !INVERS));
|
||||
lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), potMode, attr & ((m_posHorz == 0) ? attr : !INVERS));
|
||||
if (potMode) {
|
||||
uint8_t x = MODEL_SETUP_2ND_COLUMN+5*FW;
|
||||
for (uint8_t i=0; i<NUM_POTS ; i++) {
|
||||
#if !defined(REVPLUS)
|
||||
if (i == POT3-POT1) {
|
||||
if (attr && i == POT3-POT1) {
|
||||
if (m_posHorz==i+1) REPEAT_LAST_CURSOR_MOVE();
|
||||
continue;
|
||||
}
|
||||
@@ -1940,7 +1940,7 @@ void menuModelFlightModesAll(uint8_t event)
|
||||
|
||||
case ITEM_FLIGHT_MODES_SWITCH:
|
||||
putsSwitches((5+LEN_FP_NAME)*FW+FW/2, y, p->swtch, attr);
|
||||
if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_SHORT_LIST, SWSRC_LAST_SHORT_LIST);
|
||||
if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
|
||||
break;
|
||||
|
||||
case ITEM_FLIGHT_MODES_TRIM_RUD:
|
||||
@@ -3097,12 +3097,13 @@ void menuModelExpoOne(uint8_t event)
|
||||
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
|
||||
putsTelemetryChannel(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x512, 0);
|
||||
if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
|
||||
x512 = limit(-1024, x512, 1024);
|
||||
}
|
||||
else {
|
||||
lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1);
|
||||
}
|
||||
x512 = limit(-1024, x512, 1024);
|
||||
int y512 = expoFn(x512);
|
||||
y512 = limit(-1024, y512, 1024);
|
||||
lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1);
|
||||
#else
|
||||
int16_t x512 = calibratedStick[ed->chn];
|
||||
@@ -3111,10 +3112,11 @@ void menuModelExpoOne(uint8_t event)
|
||||
lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0);
|
||||
#endif
|
||||
|
||||
x512 = X0+x512/(RESXu/WCHART);
|
||||
#if defined(CPUARM)
|
||||
x512 = X0+x512/(RESX/WCHART);
|
||||
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
|
||||
#else
|
||||
x512 = X0+x512/(RESXu/WCHART);
|
||||
y512 = (LCD_H-1) - (uint16_t)((y512+RESX)/2) * (LCD_H-1) / RESX;
|
||||
#endif
|
||||
|
||||
@@ -4359,6 +4361,22 @@ enum LogicalSwitchFields {
|
||||
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
void putsEdgeDelayParam(xcoord_t x, uint8_t y, LogicalSwitchData *cs, uint8_t lattr, uint8_t rattr)
|
||||
{
|
||||
lcd_putc(x-4, y, '[');
|
||||
lcd_outdezAtt(x, y, lswTimerValue(cs->v2), LEFT|PREC1|lattr);
|
||||
lcd_putc(lcdLastPos, y, ':');
|
||||
if (cs->v3 < 0)
|
||||
lcd_putsAtt(lcdLastPos+3, y, "<<", rattr);
|
||||
else if (cs->v3 == 0)
|
||||
lcd_putsAtt(lcdLastPos+3, y, "--", rattr);
|
||||
else
|
||||
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|rattr);
|
||||
lcd_putc(lcdLastPos, y, ']');
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM) && LCD_W < 212
|
||||
|
||||
#define CSWONE_2ND_COLUMN (11*FW)
|
||||
@@ -4440,17 +4458,10 @@ void menuModelLogicalSwitchOne(uint8_t event)
|
||||
v2_max = 99;
|
||||
}
|
||||
else if (cstate == LS_FAMILY_STAY) {
|
||||
lcd_putc(CSWONE_2ND_COLUMN-4, y, '[');
|
||||
lcd_outdezAtt(CSWONE_2ND_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|(m_posHorz==0 ? attr : 0));
|
||||
lcd_putc(lcdLastPos, y, ':');
|
||||
if (cs->v3 == 0)
|
||||
lcd_putsAtt(lcdLastPos+3, y, "--", (m_posHorz==1 ? attr : 0));
|
||||
else
|
||||
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(m_posHorz==1 ? attr : 0));
|
||||
lcd_putc(lcdLastPos, y, ']');
|
||||
putsEdgeDelayParam(CSWONE_2ND_COLUMN, y, cs, m_posHorz==0 ? attr : 0, m_posHorz==1 ? attr : 0);
|
||||
if (s_editMode <= 0) continue;
|
||||
if (attr && m_posHorz==1) {
|
||||
CHECK_INCDEC_MODELVAR(event, cs->v3, 0, 222 - cs->v2);
|
||||
CHECK_INCDEC_MODELVAR(event, cs->v3, -1, 222 - cs->v2);
|
||||
break;
|
||||
}
|
||||
v2_min = -129; v2_max = 122;
|
||||
@@ -4563,14 +4574,7 @@ void menuModelLogicalSwitches(uint8_t event)
|
||||
}
|
||||
else if (cstate == LS_FAMILY_STAY) {
|
||||
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0);
|
||||
lcd_putc(CSW_3RD_COLUMN-4, y, '[');
|
||||
lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1);
|
||||
lcd_putc(lcdLastPos, y, ':');
|
||||
if (cs->v3 == 0)
|
||||
lcd_puts(lcdLastPos+3, y, "--");
|
||||
else
|
||||
lcd_outdezAtt(lcdLastPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1);
|
||||
lcd_putc(lcdLastPos-1, y, ']');
|
||||
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, 0, 0);
|
||||
}
|
||||
else if (cstate == LS_FAMILY_TIMER) {
|
||||
lcd_outdezAtt(CSW_2ND_COLUMN, y, cs->v1+1, LEFT);
|
||||
@@ -4682,7 +4686,7 @@ void menuModelLogicalSwitches(uint8_t event)
|
||||
uint8_t cstate = lswFamily(cs->func);
|
||||
#if defined(CPUARM)
|
||||
int16_t v1_val=cs->v1, v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM;
|
||||
int16_t v3_min=0, v3_max=100;
|
||||
int16_t v3_min=-1, v3_max=100;
|
||||
#else
|
||||
int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM;
|
||||
#define v1_val cs->v1
|
||||
@@ -4691,28 +4695,21 @@ void menuModelLogicalSwitches(uint8_t event)
|
||||
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
|
||||
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1);
|
||||
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
|
||||
v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1;
|
||||
v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1;
|
||||
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
|
||||
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
|
||||
INCDEC_SET_FLAG(INCDEC_SWITCH);
|
||||
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
|
||||
}
|
||||
#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, ']');
|
||||
v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1;
|
||||
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;
|
||||
if (horz == 1) {
|
||||
INCDEC_SET_FLAG(INCDEC_SWITCH);
|
||||
INCDEC_ENABLE_CHECK(isSwitchAvailable);
|
||||
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
|
||||
}
|
||||
else {
|
||||
INCDEC_SET_FLAG(0);
|
||||
@@ -5042,7 +5039,7 @@ void menuModelCustomFunctions(uint8_t event)
|
||||
switch (j) {
|
||||
case 0:
|
||||
putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(sd), attr | ((activeFnSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
|
||||
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, CFN_SWITCH(sd), SWSRC_FIRST, SWSRC_LAST);
|
||||
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, CFN_SWITCH(sd), SWSRC_FIRST, SWSRC_LAST, isSwitchAvailableInCustomFunctions);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
@@ -1117,7 +1117,7 @@ int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t
|
||||
{
|
||||
lcd_putsColumnLeft(x, y, STR_SWITCH);
|
||||
putsSwitches(x, y, value, attr);
|
||||
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_SHORT_LIST, SWSRC_LAST_SHORT_LIST);
|
||||
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1462,6 +1468,14 @@ bool isTelemetrySourceAvailable(int source)
|
||||
|
||||
bool isInputSourceAvailable(int source)
|
||||
{
|
||||
#if defined(PCBTARANIS) && !defined(REVPLUS)
|
||||
if (source == MIXSRC_POT3)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
|
||||
return true;
|
||||
|
||||
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
|
||||
return true;
|
||||
|
||||
@@ -1480,17 +1494,25 @@ bool isInputSourceAvailable(int source)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSwitchAvailableInLogicalSwitches(int swtch)
|
||||
enum SwitchContext
|
||||
{
|
||||
LogicalSwitchesContext,
|
||||
CustomFunctionsContext,
|
||||
TimersContext,
|
||||
MixesContext
|
||||
};
|
||||
|
||||
bool isSwitchAvailable(int swtch, SwitchContext context)
|
||||
{
|
||||
if (swtch < 0) {
|
||||
if (swtch <= -SWSRC_ON)
|
||||
return false;
|
||||
#if defined(PCBTARANIS)
|
||||
else if (swtch == -SWSRC_SF0 || swtch == -SWSRC_SF2 || swtch == -SWSRC_SH0 || swtch == -SWSRC_SH2)
|
||||
if (swtch == -SWSRC_SF0 || swtch == -SWSRC_SF2 || swtch == -SWSRC_SH0 || swtch == -SWSRC_SH2)
|
||||
return false;
|
||||
#endif
|
||||
else
|
||||
swtch = -swtch;
|
||||
if (swtch == -SWSRC_ON || swtch == -SWSRC_One) {
|
||||
return false;
|
||||
}
|
||||
swtch = -swtch;
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
@@ -1506,27 +1528,59 @@ bool isSwitchAvailableInLogicalSwitches(int swtch)
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isSwitchAvailable(int swtch)
|
||||
{
|
||||
if (!isSwitchAvailableInLogicalSwitches(swtch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swtch < 0) {
|
||||
swtch = -swtch;
|
||||
}
|
||||
|
||||
if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
|
||||
if (context != LogicalSwitchesContext && swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
|
||||
LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
|
||||
return (cs->func != LS_FUNC_NONE);
|
||||
}
|
||||
|
||||
if (context != CustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) {
|
||||
if (context == MixesContext) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
swtch -= SWSRC_FIRST_FLIGHT_MODE;
|
||||
if (swtch == 0) {
|
||||
return true;
|
||||
}
|
||||
FlightModeData * fm = flightModeAddress(swtch);
|
||||
return (fm->swtch != SWSRC_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isSwitchAvailableInLogicalSwitches(int swtch)
|
||||
{
|
||||
return isSwitchAvailable(swtch, LogicalSwitchesContext);
|
||||
}
|
||||
|
||||
bool isSwitchAvailableInCustomFunctions(int swtch)
|
||||
{
|
||||
return isSwitchAvailable(swtch, CustomFunctionsContext);
|
||||
}
|
||||
|
||||
bool isSwitchAvailableInMixes(int swtch)
|
||||
{
|
||||
return isSwitchAvailable(swtch, MixesContext);
|
||||
}
|
||||
|
||||
bool isSwitchAvailableInTimers(int swtch)
|
||||
{
|
||||
if (swtch >= 0) {
|
||||
if (swtch < TMRMODE_COUNT) {
|
||||
return true;
|
||||
}
|
||||
swtch -= TMRMODE_COUNT-1;
|
||||
}
|
||||
|
||||
return isSwitchAvailable(swtch, TimersContext);
|
||||
}
|
||||
|
||||
bool isThrottleSourceAvailable(int source)
|
||||
{
|
||||
#if defined(PCBTARANIS)
|
||||
|
||||
@@ -209,9 +209,13 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
|
||||
var = checkIncDecModelZero(event,var,max)
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
|
||||
var = checkIncDec(event, var, min, max, EE_MODEL, check)
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
|
||||
var = checkIncDec(event, var, 0, max, EE_MODEL, check)
|
||||
#else
|
||||
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
|
||||
var = checkIncDec(event, var, min, max, EE_MODEL)
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, var, max)
|
||||
#endif
|
||||
@@ -220,19 +224,22 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
|
||||
bool isThrottleSourceAvailable(int source);
|
||||
bool isLogicalSwitchFunctionAvailable(int function);
|
||||
bool isAssignableFunctionAvailable(int function);
|
||||
bool isSwitchAvailable(int swtch);
|
||||
bool isSwitchAvailableInLogicalSwitches(int swtch);
|
||||
bool isSwitchAvailableInCustomFunctions(int swtch);
|
||||
bool isSwitchAvailableInMixes(int swtch);
|
||||
bool isSwitchAvailableInTimers(int swtch);
|
||||
bool isModuleAvailable(int module);
|
||||
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \
|
||||
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, isSwitchAvailable)
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
|
||||
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, available)
|
||||
#elif defined(AUTOSWITCH)
|
||||
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
|
||||
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH)
|
||||
#else
|
||||
#define AUTOSWITCH_ENTER_LONG() (0)
|
||||
#define CHECK_INCDEC_MODELSWITCH CHECK_INCDEC_MODELVAR
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
|
||||
CHECK_INCDEC_MODELVAR(event, var, min, max)
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
|
||||
@@ -306,7 +306,7 @@ void displayTopBar()
|
||||
}
|
||||
|
||||
/* Audio volume */
|
||||
if (requiredSpeakerVolume == 0)
|
||||
if (requiredSpeakerVolume == 0 || g_eeGeneral.beepMode == e_mode_quiet)
|
||||
LCD_ICON(BAR_VOLUME_X, BAR_Y, ICON_SPEAKER0);
|
||||
else if (requiredSpeakerVolume < 10)
|
||||
LCD_ICON(BAR_VOLUME_X, BAR_Y, ICON_SPEAKER1);
|
||||
|
||||
@@ -92,9 +92,20 @@ void menuStatisticsView(uint8_t event)
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define MENU_DEBUG_COL1_OFS (11*FW-2)
|
||||
#define MENU_DEBUG_Y_MIXMAX (2*FH-3)
|
||||
#define MENU_DEBUG_Y_LUA (3*FH-2)
|
||||
#define MENU_DEBUG_Y_FREE_RAM (4*FH-1)
|
||||
#define MENU_DEBUG_Y_STACK (5*FH)
|
||||
#define MENU_DEBUG_Y_RTOS (6*FH)
|
||||
#elif defined(PCBSKY9X)
|
||||
#define MENU_DEBUG_COL1_OFS (11*FW-3)
|
||||
#define MENU_DEBUG_COL2_OFS (17*FW)
|
||||
#define MENU_DEBUG_Y_CURRENT (1*FH)
|
||||
#define MENU_DEBUG_Y_MAH (2*FH)
|
||||
#define MENU_DEBUG_Y_CPU_TEMP (3*FH)
|
||||
#define MENU_DEBUG_Y_COPROC (4*FH)
|
||||
#define MENU_DEBUG_Y_MIXMAX (5*FH)
|
||||
#define MENU_DEBUG_Y_RTOS (6*FH)
|
||||
#else
|
||||
#define MENU_DEBUG_COL1_OFS (14*FW)
|
||||
#endif
|
||||
@@ -149,76 +160,86 @@ void menuStatisticsDebug(uint8_t event)
|
||||
|
||||
#if defined(PCBSKY9X) && !defined(REVA)
|
||||
// current
|
||||
lcd_putsLeft(1*FH, STR_CPU_CURRENT);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 1*FH, getCurrent(), UNIT_MILLIAMPS, LEFT);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT);
|
||||
uint32_t current_scale = 488 + g_eeGeneral.currentCalib;
|
||||
lcd_putc(MENU_DEBUG_COL2_OFS, 1*FH, '>');
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, 1*FH, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
|
||||
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>');
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
|
||||
// consumption
|
||||
lcd_putsLeft(2*FH, STR_CPU_MAH);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 2*FH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
|
||||
#endif
|
||||
|
||||
#if defined(PCBSKY9X)
|
||||
lcd_putsLeft(3*FH, STR_CPU_TEMP);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 3*FH, getTemperature(), UNIT_TEMPERATURE, LEFT);
|
||||
lcd_putc(MENU_DEBUG_COL2_OFS, 3*FH, '>');
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, 3*FH, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT);
|
||||
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>');
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
|
||||
#endif
|
||||
|
||||
#if defined(COPROCESSOR)
|
||||
lcd_putsLeft(4*FH, STR_COPROC_TEMP);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP);
|
||||
|
||||
if (Coproc_read==0) {
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Co Proc NACK"),INVERS);
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Co Proc NACK"),INVERS);
|
||||
}
|
||||
else if (Coproc_read==0x81) {
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Inst.TinyApp"),INVERS);
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Inst.TinyApp"),INVERS);
|
||||
}
|
||||
else if (Coproc_read<3) {
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH, PSTR("Upgr.TinyApp"),INVERS);
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Upgr.TinyApp"),INVERS);
|
||||
}
|
||||
else {
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, 4*FH, Coproc_temp, UNIT_TEMPERATURE, LEFT);
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS, 4*FH, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
|
||||
putsTelemetryValue(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT);
|
||||
putsTelemetryValue(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS) && !defined(SIMU)
|
||||
lcd_putsLeft(3*FH, "Free Mem");
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 3*FH, getAvailableMemory(), LEFT);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_FREE_RAM, "Free Mem");
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_FREE_RAM, getAvailableMemory(), LEFT);
|
||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_FREE_RAM, "b");
|
||||
#endif
|
||||
|
||||
#if defined(LUA)
|
||||
lcd_putsLeft(4*FH, "Lua scripts");
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 4*FH+1, "[Duration]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, 4*FH, 10*maxLuaDuration, LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, 4*FH+1, "[Interval]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, 4*FH, 10*maxLuaInterval, LEFT);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_LUA, "Lua scripts");
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_LUA+1, "[Duration]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaDuration, LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_LUA+1, "[Interval]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaInterval, LEFT);
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
lcd_putsLeft(5*FH, STR_TMIXMAXMS);
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 5*FH, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
|
||||
lcd_puts(lcdLastPos, 5*FH, "ms");
|
||||
lcd_putsLeft(6*FH, STR_FREESTACKMINB);
|
||||
|
||||
#if LCD_W >= 212
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, 6*FH+1, "[Main]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(0), UNSIGN|LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, 6*FH+1, "[Mix]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(1), UNSIGN|LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, 6*FH+1, "[Audio]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(2), UNSIGN|LEFT);
|
||||
#else
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 6*FH, stack_free(0), UNSIGN|LEFT);
|
||||
lcd_puts(lcdLastPos, 6*FH, "/");
|
||||
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(1), UNSIGN|LEFT);
|
||||
lcd_puts(lcdLastPos, 6*FH, "/");
|
||||
lcd_outdezAtt(lcdLastPos, 6*FH, stack_free(2), UNSIGN|LEFT);
|
||||
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
|
||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if defined(PCBTARANIS)
|
||||
lcd_putsLeft(MENU_DEBUG_Y_STACK, STR_FREESTACKMINB);
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_STACK, stack_free(255), UNSIGN|LEFT);
|
||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_STACK, "b");
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS+1, "[Main]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Mix]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
|
||||
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Audio]", SMLSIZE);
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
|
||||
#endif
|
||||
|
||||
#if defined(PCBSKY9X)
|
||||
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
|
||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
|
||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
|
||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
|
||||
#endif
|
||||
|
||||
#if !defined(CPUARM)
|
||||
lcd_putsLeft(1*FH, STR_TMR1LATMAXUS);
|
||||
lcd_outdez8(MENU_DEBUG_COL1_OFS , 1*FH, g_tmr1Latency_max/2 );
|
||||
lcd_putsLeft(2*FH, STR_TMR1LATMINUS);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -134,11 +134,7 @@ void lcdPutPattern(xcoord_t x, uint8_t y, const uint8_t * pattern, uint8_t width
|
||||
|
||||
void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
const pm_uchar *q = (c < 0xC0) ? &font_5x7[(c-0x20)*5] : &font_5x7_extra[(c-0xC0)*5];
|
||||
#else
|
||||
const pm_uchar *q = &font_5x7[(c-0x20)*5];
|
||||
#endif
|
||||
const pm_uchar * q;
|
||||
|
||||
lcdNextPos = x-1;
|
||||
|
||||
@@ -158,14 +154,17 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
|
||||
c_remapped = 4;
|
||||
else if (c!=' ')
|
||||
flags &= ~BOLD;
|
||||
if ((c>= 128) && (flags & DBLSIZE))
|
||||
c_remapped = c - 60;
|
||||
}
|
||||
|
||||
if (flags & DBLSIZE) {
|
||||
/* each letter consists of ten top bytes followed by
|
||||
* by ten bottom bytes (20 bytes per * char) */
|
||||
q = &font_10x14[((uint16_t)c_remapped)*20];
|
||||
if (c >= 0xC0) {
|
||||
q = &font_10x14_extra[((uint16_t)(c-0xC0))*20];
|
||||
}
|
||||
else {
|
||||
if (c >= 128)
|
||||
c_remapped = c - 60;
|
||||
q = &font_10x14[((uint16_t)c_remapped)*20];
|
||||
}
|
||||
lcdPutPattern(x, y, q, 10, 16, flags);
|
||||
}
|
||||
else if (flags & XXLSIZE) {
|
||||
@@ -193,6 +192,11 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
q = (c < 0xC0) ? &font_5x7[(c-0x20)*5] : &font_5x7_extra[(c-0xC0)*5];
|
||||
#else
|
||||
q = &font_5x7[(c-0x20)*5];
|
||||
#endif
|
||||
lcdPutPattern(x, y, q, 5, 7, flags);
|
||||
}
|
||||
}
|
||||
@@ -839,10 +843,10 @@ void putsCurve(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att)
|
||||
void putsTimerMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att)
|
||||
{
|
||||
if (mode >= 0) {
|
||||
if (mode < TMR_VAROFS)
|
||||
if (mode < TMRMODE_COUNT)
|
||||
return lcd_putsiAtt(x, y, STR_VTMRMODES, mode, att);
|
||||
else
|
||||
mode -= (TMR_VAROFS-1);
|
||||
mode -= (TMRMODE_COUNT-1);
|
||||
}
|
||||
putsSwitches(x, y, mode, att);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,12 @@ void lcd_bmp(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t offset, uint8_
|
||||
{
|
||||
const pm_uchar *q = img;
|
||||
uint8_t w = pgm_read_byte(q++);
|
||||
if (!width) width = w;
|
||||
if (!width || width > w) {
|
||||
width = w;
|
||||
}
|
||||
if (x+width > LCD_W) {
|
||||
width = LCD_W-x;
|
||||
}
|
||||
uint8_t rows = (pgm_read_byte(q++) + 1) / 2;
|
||||
|
||||
for (uint8_t row=0; row<rows; row++) {
|
||||
|
||||
@@ -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);
|
||||
@@ -155,7 +157,10 @@ tmr10ms_t lastLogTime = 0;
|
||||
|
||||
void closeLogs()
|
||||
{
|
||||
f_close(&g_oLogFile);
|
||||
if (f_close(&g_oLogFile) != FR_OK) {
|
||||
// close failed, forget file
|
||||
g_oLogFile.fs = 0;
|
||||
}
|
||||
lastLogTime = 0;
|
||||
}
|
||||
|
||||
@@ -195,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]));
|
||||
@@ -279,13 +286,15 @@ void writeLogs()
|
||||
if (result<0 && !error_displayed) {
|
||||
error_displayed = STR_SDCARD_ERROR;
|
||||
POPUP_WARNING(STR_SDCARD_ERROR);
|
||||
closeLogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
error_displayed = NULL;
|
||||
if (g_oLogFile.fs)
|
||||
if (g_oLogFile.fs) {
|
||||
closeLogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,19 @@ uint16_t maxLuaDuration = 0;
|
||||
#define SCRIPTS_MAX_HEAP 50
|
||||
#define SET_LUA_INSTRUCTIONS_COUNT(x) (instructionsPercent=0, lua_sethook(L, hook, LUA_MASKCOUNT, x))
|
||||
|
||||
struct our_longjmp * global_lj = 0;
|
||||
|
||||
/* custom panic handler */
|
||||
static int custom_lua_atpanic(lua_State *lua)
|
||||
{
|
||||
TRACE("PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1));
|
||||
if (global_lj) {
|
||||
longjmp(global_lj->b, 1);
|
||||
/* will never return */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int instructionsPercent = 0;
|
||||
void hook(lua_State* L, lua_Debug *ar)
|
||||
{
|
||||
@@ -1044,7 +1057,7 @@ static int luaModelSetGlobalVariable(lua_State *L)
|
||||
int idx = luaL_checkunsigned(L, 1);
|
||||
int phase = luaL_checkunsigned(L, 2);
|
||||
int value = luaL_checkinteger(L, 3);
|
||||
if (phase < MAX_FLIGHT_MODES && idx < MAX_GVARS && value >= -GVAR_LIMIT && value <= GVAR_LIMIT) {
|
||||
if (phase < MAX_FLIGHT_MODES && idx < MAX_GVARS && value >= -GVAR_MAX && value <= GVAR_MAX) {
|
||||
g_model.flightModeData[phase].gvars[idx] = value;
|
||||
eeDirty(EE_MODEL);
|
||||
}
|
||||
@@ -1330,14 +1343,29 @@ static const luaL_Reg lcdLib[] = {
|
||||
{ NULL, NULL } /* sentinel */
|
||||
};
|
||||
|
||||
void luaInit()
|
||||
void luaDisable()
|
||||
{
|
||||
POPUP_WARNING("Lua disabled!");
|
||||
luaState = INTERPRETER_PANIC;
|
||||
}
|
||||
|
||||
void luaClose()
|
||||
{
|
||||
if (L) {
|
||||
lua_close(L);
|
||||
PROTECT_LUA() {
|
||||
lua_close(L); // this should not panic, but we make sure anyway
|
||||
}
|
||||
else {
|
||||
// we can only disable Lua for the rest of the session
|
||||
luaDisable();
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
L = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
L = luaL_newstate();
|
||||
|
||||
void luaRegisterAll()
|
||||
{
|
||||
// Init lua
|
||||
luaL_openlibs(L);
|
||||
|
||||
@@ -1406,15 +1434,53 @@ void luaInit()
|
||||
lua_registerint(L, "DOTTED", DOTTED);
|
||||
lua_registerint(L, "LCD_W", LCD_W);
|
||||
lua_registerint(L, "LCD_H", LCD_H);
|
||||
lua_registerint(L, "TIMEHOUR", TIMEHOUR);
|
||||
}
|
||||
|
||||
void luaInit()
|
||||
{
|
||||
luaClose();
|
||||
if (luaState != INTERPRETER_PANIC) {
|
||||
L = luaL_newstate();
|
||||
if (L) {
|
||||
// install our panic handler
|
||||
lua_atpanic(L, &custom_lua_atpanic);
|
||||
|
||||
// protect libs and constants registration
|
||||
PROTECT_LUA() {
|
||||
luaRegisterAll();
|
||||
}
|
||||
else {
|
||||
// if we got panic during registration
|
||||
// we disable Lua for this session
|
||||
luaDisable();
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
else {
|
||||
/* log error and return */
|
||||
luaDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void luaFree(ScriptInternalData & sid)
|
||||
{
|
||||
if (sid.run) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
|
||||
sid.run = 0;
|
||||
PROTECT_LUA() {
|
||||
if (sid.run) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
|
||||
sid.run = 0;
|
||||
}
|
||||
if (sid.background) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.background);
|
||||
sid.background = 0;
|
||||
}
|
||||
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
}
|
||||
else {
|
||||
luaDisable();
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
|
||||
int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs * sio=NULL)
|
||||
@@ -1428,47 +1494,55 @@ int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs
|
||||
|
||||
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
|
||||
|
||||
if (luaL_loadfile(L, filename) == 0 &&
|
||||
lua_pcall(L, 0, 1, 0) == 0 &&
|
||||
lua_istable(L, -1)) {
|
||||
PROTECT_LUA() {
|
||||
if (luaL_loadfile(L, filename) == 0 &&
|
||||
lua_pcall(L, 0, 1, 0) == 0 &&
|
||||
lua_istable(L, -1)) {
|
||||
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
const char *key = lua_tostring(L, -2);
|
||||
if (!strcmp(key, "init")) {
|
||||
init = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
const char *key = lua_tostring(L, -2);
|
||||
if (!strcmp(key, "init")) {
|
||||
init = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (!strcmp(key, "run")) {
|
||||
sid.run = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (!strcmp(key, "background")) {
|
||||
sid.background = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (sio && !strcmp(key, "input")) {
|
||||
luaGetInputs(*sio);
|
||||
}
|
||||
else if (sio && !strcmp(key, "output")) {
|
||||
luaGetOutputs(*sio);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(key, "run")) {
|
||||
sid.run = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (!strcmp(key, "background")) {
|
||||
sid.background = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (sio && !strcmp(key, "input")) {
|
||||
luaGetInputs(*sio);
|
||||
}
|
||||
else if (sio && !strcmp(key, "output")) {
|
||||
luaGetOutputs(*sio);
|
||||
|
||||
if (init) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, init);
|
||||
if (lua_pcall(L, 0, 0, 0) != 0) {
|
||||
TRACE("Error in script %s init: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
}
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, init);
|
||||
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (init) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, init);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, init);
|
||||
if (lua_pcall(L, 0, 0, 0) != 0) {
|
||||
TRACE("Error in script %s init: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
}
|
||||
else {
|
||||
TRACE("Error in script %s: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Error in script %s: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
TRACE("Panic in script %s: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_PANIC;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
|
||||
if (sid.state != SCRIPT_OK) {
|
||||
luaFree(sid);
|
||||
@@ -1630,6 +1704,9 @@ void luaError(uint8_t error)
|
||||
case SCRIPT_KILLED:
|
||||
msg = "Script killed";
|
||||
break;
|
||||
case SCRIPT_PANIC:
|
||||
msg = "Script panic";
|
||||
break;
|
||||
}
|
||||
POPUP_WARNING(msg);
|
||||
}
|
||||
@@ -1637,22 +1714,198 @@ void luaError(uint8_t error)
|
||||
|
||||
void luaExec(const char *filename)
|
||||
{
|
||||
LUA_RESET();
|
||||
luaInit();
|
||||
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
int result = luaLoad(filename, standaloneScript);
|
||||
// TODO the same with run ...
|
||||
if (result == SCRIPT_OK) {
|
||||
luaState = LUASTATE_STANDALONE_SCRIPT_RUNNING;
|
||||
luaState = INTERPRETER_RUNNING_STANDALONE_SCRIPT;
|
||||
}
|
||||
else {
|
||||
luaError(result);
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
}
|
||||
|
||||
void luaDoOneRunStandalone(uint8_t evt)
|
||||
{
|
||||
static uint8_t luaDisplayStatistics = false;
|
||||
|
||||
if (standaloneScript.state == SCRIPT_OK && standaloneScript.run) {
|
||||
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, standaloneScript.run);
|
||||
lua_pushinteger(L, evt);
|
||||
if (lua_pcall(L, 1, 1, 0) == 0) {
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
if (instructionsPercent > 100) {
|
||||
TRACE("Script killed");
|
||||
standaloneScript.state = SCRIPT_KILLED;
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
else if (lua_isstring(L, -1)) {
|
||||
char nextScript[_MAX_LFN+1];
|
||||
strncpy(nextScript, lua_tostring(L, -1), _MAX_LFN);
|
||||
nextScript[_MAX_LFN] = '\0';
|
||||
luaExec(nextScript);
|
||||
}
|
||||
else {
|
||||
TRACE("Script error");
|
||||
standaloneScript.state = SCRIPT_SYNTAX_ERROR;
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int scriptResult = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1); /* pop returned value */
|
||||
if (scriptResult != 0) {
|
||||
TRACE("Script finished with status %d", scriptResult);
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
else if (luaDisplayStatistics) {
|
||||
lcd_hline(0, 7*FH-1, lcdLastPos+FW, ERASE);
|
||||
lcd_puts(0, 7*FH, "GV Use: ");
|
||||
lcd_outdezAtt(lcdLastPos, 7*FH, luaGetMemUsed(), LEFT);
|
||||
lcd_putc(lcdLastPos, 7*FH, 'b');
|
||||
lcd_hline(0, 7*FH-2, lcdLastPos+FW, FORCE);
|
||||
lcd_vlineStip(lcdLastPos+FW, 7*FH-2, FH+2, SOLID, FORCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Script error: %s", lua_tostring(L, -1));
|
||||
standaloneScript.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
|
||||
if (standaloneScript.state != SCRIPT_OK) {
|
||||
luaError(standaloneScript.state);
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
|
||||
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
|
||||
TRACE("Script force exit");
|
||||
killEvents(evt);
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
else if (evt == EVT_KEY_LONG(KEY_MENU)) {
|
||||
killEvents(evt);
|
||||
luaDisplayStatistics = !luaDisplayStatistics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void luaDoOneRunPermanentScript(uint8_t evt, int i)
|
||||
{
|
||||
ScriptInternalData & sid = scriptInternalData[i];
|
||||
if (sid.state == SCRIPT_OK) {
|
||||
SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
|
||||
int inputsCount = 0;
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
const char *filename;
|
||||
#endif
|
||||
ScriptInputsOutputs * sio = NULL;
|
||||
if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) {
|
||||
ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST];
|
||||
sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST];
|
||||
inputsCount = sio->inputsCount;
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = sd.file;
|
||||
#endif
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
for (int j=0; j<sio->inputsCount; j++) {
|
||||
if (sio->inputs[j].type == 1)
|
||||
luaGetValueAndPush((uint8_t)sd.inputs[j]);
|
||||
else
|
||||
lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def);
|
||||
}
|
||||
}
|
||||
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
|
||||
CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
|
||||
if (!getSwitch(fn.swtch)) {
|
||||
return;
|
||||
}
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = fn.play.name;
|
||||
#endif
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
}
|
||||
else {
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = "[telem]";
|
||||
#endif
|
||||
if (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
lua_pushinteger(L, evt);
|
||||
inputsCount = 1;
|
||||
}
|
||||
else if (sid.background) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) {
|
||||
if (sio) {
|
||||
for (int j=sio->outputsCount-1; j>=0; j--) {
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
|
||||
TRACE("Script %8s disabled", filename);
|
||||
break;
|
||||
}
|
||||
sio->outputs[j].value = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (instructionsPercent > 100) {
|
||||
TRACE("Script %8s killed", filename);
|
||||
sid.state = SCRIPT_KILLED;
|
||||
}
|
||||
else {
|
||||
TRACE("Script %8s error: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sid.state != SCRIPT_OK) {
|
||||
luaFree(sid);
|
||||
}
|
||||
else {
|
||||
if (instructionsPercent > sid.instructions) {
|
||||
sid.instructions = instructionsPercent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void luaDoGc()
|
||||
{
|
||||
PROTECT_LUA() {
|
||||
lua_gc(L, LUA_GCSTEP /*LUA_GCCOLLECT*/, 0); // LUA_GCSTEP is enough
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
static int lastgc = 0;
|
||||
int gc = luaGetMemUsed();
|
||||
if (gc != lastgc) {
|
||||
lastgc = gc;
|
||||
TRACE("GC Use: %dbytes", gc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// we disable Lua for the rest of the session
|
||||
luaDisable();
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
|
||||
void luaTask(uint8_t evt)
|
||||
{
|
||||
lcd_locked = false;
|
||||
static uint8_t luaDisplayStatistics = false;
|
||||
|
||||
uint32_t t0 = get_tmr10ms();
|
||||
static uint32_t lastLuaTime = 0;
|
||||
@@ -1662,176 +1915,40 @@ void luaTask(uint8_t evt)
|
||||
maxLuaInterval = interval;
|
||||
}
|
||||
|
||||
if (luaState & LUASTATE_STANDALONE_SCRIPT_RUNNING) {
|
||||
// standalone script
|
||||
if (standaloneScript.state == SCRIPT_OK && standaloneScript.run) {
|
||||
SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, standaloneScript.run);
|
||||
lua_pushinteger(L, evt);
|
||||
if (lua_pcall(L, 1, 1, 0) == 0) {
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
if (instructionsPercent > 100) {
|
||||
TRACE("Script killed");
|
||||
standaloneScript.state = SCRIPT_KILLED;
|
||||
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
|
||||
}
|
||||
else if (lua_isstring(L, -1)) {
|
||||
char nextScript[_MAX_LFN+1];
|
||||
strncpy(nextScript, lua_tostring(L, -1), _MAX_LFN);
|
||||
nextScript[_MAX_LFN] = '\0';
|
||||
luaExec(nextScript);
|
||||
}
|
||||
else {
|
||||
TRACE("Script error");
|
||||
standaloneScript.state = SCRIPT_SYNTAX_ERROR;
|
||||
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int scriptResult = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1); /* pop returned value */
|
||||
if (scriptResult != 0) {
|
||||
TRACE("Script finished with status %d", scriptResult);
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
|
||||
}
|
||||
else if (luaDisplayStatistics) {
|
||||
int gc = 1000*lua_gc(L, LUA_GCCOUNT, 0) + lua_gc(L, LUA_GCCOUNTB, 0);
|
||||
lcd_hline(0, 7*FH-1, lcdLastPos+FW, ERASE);
|
||||
lcd_puts(0, 7*FH, "GV Use: ");
|
||||
lcd_outdezAtt(lcdLastPos, 7*FH, gc, LEFT);
|
||||
lcd_putc(lcdLastPos, 7*FH, 'b');
|
||||
lcd_hline(0, 7*FH-2, lcdLastPos+FW, FORCE);
|
||||
lcd_vlineStip(lcdLastPos+FW, 7*FH-2, FH+2, SOLID, FORCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Script error: %s", lua_tostring(L, -1));
|
||||
standaloneScript.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
|
||||
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
|
||||
}
|
||||
|
||||
if (standaloneScript.state != SCRIPT_OK) {
|
||||
luaError(standaloneScript.state);
|
||||
}
|
||||
|
||||
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
|
||||
TRACE("Script force exit");
|
||||
killEvents(evt);
|
||||
standaloneScript.state = SCRIPT_NOFILE;
|
||||
luaState = LUASTATE_RELOAD_MODEL_SCRIPTS;
|
||||
}
|
||||
else if (evt == EVT_KEY_LONG(KEY_MENU)) {
|
||||
killEvents(evt);
|
||||
luaDisplayStatistics = !luaDisplayStatistics;
|
||||
}
|
||||
if (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) {
|
||||
PROTECT_LUA() {
|
||||
luaDoOneRunStandalone(evt);
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING("Script Panic!");
|
||||
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
else {
|
||||
// model scripts
|
||||
if (luaState & LUASTATE_RELOAD_MODEL_SCRIPTS) {
|
||||
if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) {
|
||||
luaState = 0;
|
||||
LUA_RESET();
|
||||
luaInit();
|
||||
if (!L) return;
|
||||
luaLoadPermanentScripts();
|
||||
}
|
||||
|
||||
for (int i=0; i<luaScriptsCount; i++) {
|
||||
ScriptInternalData & sid = scriptInternalData[i];
|
||||
if (sid.state == SCRIPT_OK) {
|
||||
SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
|
||||
int inputsCount = 0;
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
const char *filename;
|
||||
#endif
|
||||
ScriptInputsOutputs * sio = NULL;
|
||||
if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) {
|
||||
ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST];
|
||||
sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST];
|
||||
inputsCount = sio->inputsCount;
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = sd.file;
|
||||
#endif
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
for (int j=0; j<sio->inputsCount; j++) {
|
||||
if (sio->inputs[j].type == 1)
|
||||
luaGetValueAndPush((uint8_t)sd.inputs[j]);
|
||||
else
|
||||
lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def);
|
||||
}
|
||||
}
|
||||
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
|
||||
CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
|
||||
if (!getSwitch(fn.swtch)) {
|
||||
continue;
|
||||
}
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = fn.play.name;
|
||||
#endif
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
}
|
||||
else {
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
filename = "[telem]";
|
||||
#endif
|
||||
if (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
|
||||
lua_pushinteger(L, evt);
|
||||
inputsCount = 1;
|
||||
}
|
||||
else if (sid.background) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) {
|
||||
if (sio) {
|
||||
for (int j=sio->outputsCount-1; j>=0; j--) {
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
|
||||
TRACE("Script %8s disabled", filename);
|
||||
break;
|
||||
}
|
||||
sio->outputs[j].value = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (instructionsPercent > 100) {
|
||||
TRACE("Script %8s killed", filename);
|
||||
sid.state = SCRIPT_KILLED;
|
||||
}
|
||||
else {
|
||||
TRACE("Script %8s error: %s", filename, lua_tostring(L, -1));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sid.state != SCRIPT_OK) {
|
||||
luaFree(sid);
|
||||
}
|
||||
else {
|
||||
if (instructionsPercent > sid.instructions) {
|
||||
sid.instructions = instructionsPercent;
|
||||
}
|
||||
}
|
||||
PROTECT_LUA() {
|
||||
luaDoOneRunPermanentScript(evt, i);
|
||||
}
|
||||
else {
|
||||
// we disable this script for the rest of the session
|
||||
ScriptInternalData & sid = scriptInternalData[i];
|
||||
sid.state = SCRIPT_PANIC;
|
||||
luaFree(sid);
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
}
|
||||
|
||||
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
|
||||
#if defined(SIMU) || defined(DEBUG)
|
||||
static int lastgc = 0;
|
||||
int gc = luaGetMemUsed();
|
||||
if (gc != lastgc) {
|
||||
lastgc = gc;
|
||||
TRACE("GC Use: %dbytes", gc);
|
||||
}
|
||||
#endif
|
||||
luaDoGc();
|
||||
|
||||
t0 = get_tmr10ms() - t0;
|
||||
if (t0 > maxLuaDuration) {
|
||||
@@ -1841,5 +1958,5 @@ void luaTask(uint8_t evt)
|
||||
|
||||
int luaGetMemUsed()
|
||||
{
|
||||
return 1000*lua_gc(L, LUA_GCCOUNT, 0) + lua_gc(L, LUA_GCCOUNTB, 0);
|
||||
return (lua_gc(L, LUA_GCCOUNT, 0) << 10) + lua_gc(L, LUA_GCCOUNTB, 0);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ int16_t ex_chans[NUM_CHNOUT] = {0}; // Outputs (before LIMITS) of the last perMa
|
||||
int16_t cyc_anas[3] = {0};
|
||||
#if defined(PCBTARANIS)
|
||||
int16_t heliAnas[4] = {0};
|
||||
uint8_t heliTrims[4] = {0};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -105,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];
|
||||
@@ -151,10 +153,14 @@ void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS)
|
||||
virtualInputsTrims[cur_chn] = -1;
|
||||
|
||||
#if defined(HELI)
|
||||
if (ed->srcRaw == MIXSRC_Ele)
|
||||
if (ed->srcRaw == MIXSRC_Ele) {
|
||||
heliAnas[ELE_STICK] = v;
|
||||
else if (ed->srcRaw == MIXSRC_Ail)
|
||||
heliTrims[ELE_STICK] = virtualInputsTrims[cur_chn];
|
||||
}
|
||||
else if (ed->srcRaw == MIXSRC_Ail) {
|
||||
heliAnas[AIL_STICK] = v;
|
||||
heliTrims[AIL_STICK] = virtualInputsTrims[cur_chn];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -504,17 +510,17 @@ void evalInputs(uint8_t mode)
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
rawAnas[ch] = v;
|
||||
anas[ch] = v; //set values for mixer
|
||||
anas[ch] = v; // set values for mixer
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* TRIMs */
|
||||
evalTrims();
|
||||
|
||||
/* EXPOs */
|
||||
applyExpos(anas, mode);
|
||||
|
||||
/* TRIMs */
|
||||
evalTrims(); // when no virtual inputs, the trims need the anas array calculated above (when throttle trim enabled)
|
||||
|
||||
if (mode == e_perout_mode_normal) {
|
||||
#if !defined(CPUARM)
|
||||
anaCenter &= g_model.beepANACenter;
|
||||
@@ -525,9 +531,11 @@ void evalInputs(uint8_t mode)
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define HELI_ANAS_ARRAY heliAnas
|
||||
#define HELI_ANAS_ARRAY(x) heliAnas[x]
|
||||
#define HELI_TRIMS_ARRAY(x) trims[heliTrims[x]]
|
||||
#else
|
||||
#define HELI_ANAS_ARRAY anas
|
||||
#define HELI_ANAS_ARRAY(x) anas[x]
|
||||
#define HELI_TRIMS_ARRAY(x) trims[x]
|
||||
#endif
|
||||
|
||||
uint8_t mixerCurrentFlightMode;
|
||||
@@ -543,14 +551,14 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
|
||||
|
||||
#if defined(HELI)
|
||||
if (g_model.swashR.value) {
|
||||
uint32_t v = ((int32_t)HELI_ANAS_ARRAY[ELE_STICK]*HELI_ANAS_ARRAY[ELE_STICK] + (int32_t)HELI_ANAS_ARRAY[AIL_STICK]*HELI_ANAS_ARRAY[AIL_STICK]);
|
||||
uint32_t v = ((int32_t)HELI_ANAS_ARRAY(ELE_STICK)*HELI_ANAS_ARRAY(ELE_STICK) + (int32_t)HELI_ANAS_ARRAY(AIL_STICK)*HELI_ANAS_ARRAY(AIL_STICK));
|
||||
uint32_t q = calc100toRESX(g_model.swashR.value);
|
||||
q *= q;
|
||||
if (v>q) {
|
||||
uint16_t d = isqrt32(v);
|
||||
int16_t tmp = calc100toRESX(g_model.swashR.value);
|
||||
HELI_ANAS_ARRAY[ELE_STICK] = (int32_t) HELI_ANAS_ARRAY[ELE_STICK]*tmp/d;
|
||||
HELI_ANAS_ARRAY[AIL_STICK] = (int32_t) HELI_ANAS_ARRAY[AIL_STICK]*tmp/d;
|
||||
HELI_ANAS_ARRAY(ELE_STICK) = (int32_t) HELI_ANAS_ARRAY(ELE_STICK)*tmp/d;
|
||||
HELI_ANAS_ARRAY(AIL_STICK) = (int32_t) HELI_ANAS_ARRAY(AIL_STICK)*tmp/d;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,8 +566,8 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
|
||||
#define REZ_SWASH_Y(x) ((x)) // 1024 => 1024
|
||||
|
||||
if (g_model.swashR.type) {
|
||||
getvalue_t vp = HELI_ANAS_ARRAY[ELE_STICK]+trims[ELE_STICK];
|
||||
getvalue_t vr = HELI_ANAS_ARRAY[AIL_STICK]+trims[AIL_STICK];
|
||||
getvalue_t vp = HELI_ANAS_ARRAY(ELE_STICK) + HELI_TRIMS_ARRAY(ELE_STICK);
|
||||
getvalue_t vr = HELI_ANAS_ARRAY(AIL_STICK) + HELI_TRIMS_ARRAY(AIL_STICK);
|
||||
getvalue_t vc = 0;
|
||||
if (g_model.swashR.collectiveSource)
|
||||
vc = getValue(g_model.swashR.collectiveSource);
|
||||
@@ -637,7 +645,7 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
|
||||
|
||||
//========== PHASE && SWITCH =====
|
||||
bool mixCondition = (md->flightModes != 0 || md->swtch);
|
||||
delayval_t mixEnabled = !(md->flightModes & (1 << mixerCurrentFlightMode)) && getSwitch(md->swtch);
|
||||
delayval_t mixEnabled = (!(md->flightModes & (1 << mixerCurrentFlightMode)) && getSwitch(md->swtch)) ? DELAY_POS_MARGIN+1 : 0;
|
||||
|
||||
if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_TRAINER && md->srcRaw <= MIXSRC_LAST_TRAINER && !ppmInValid) {
|
||||
mixEnabled = 0;
|
||||
@@ -742,11 +750,17 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
|
||||
else
|
||||
mix_trim = -1;
|
||||
if (mix_trim >= 0) {
|
||||
int16_t trim = trims[mix_trim];
|
||||
if (mix_trim == THR_STICK && g_model.throttleReversed)
|
||||
v -= trim;
|
||||
else
|
||||
v += trim;
|
||||
int32_t trim = trims[mix_trim];
|
||||
if (mix_trim == THR_STICK) {
|
||||
if (g_model.thrTrim) {
|
||||
int16_t trimMin = g_model.extendedTrims ? 2*TRIM_EXTENDED_MIN : 2*TRIM_MIN;
|
||||
trim = (((g_model.throttleReversed)?(trim+trimMin):(trim-trimMin)) * (RESX-v)) >> (RESX_SHIFT+1);
|
||||
}
|
||||
if (g_model.throttleReversed) {
|
||||
trim = -trim;
|
||||
}
|
||||
}
|
||||
v += trim;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1451,8 +1451,15 @@ enum SwitchSources {
|
||||
SWSRC_LAST = SWSRC_COUNT-1,
|
||||
SWSRC_FIRST = -SWSRC_LAST,
|
||||
|
||||
SWSRC_LAST_SHORT_LIST = SWSRC_LAST_LOGICAL_SWITCH,
|
||||
SWSRC_FIRST_SHORT_LIST = -SWSRC_LAST_SHORT_LIST,
|
||||
#if defined(CPUARM)
|
||||
SWSRC_LAST_IN_LOGICAL_SWITCHES = SWSRC_LAST_FLIGHT_MODE,
|
||||
SWSRC_LAST_IN_MIXES = SWSRC_LAST_FLIGHT_MODE,
|
||||
#else
|
||||
SWSRC_LAST_IN_LOGICAL_SWITCHES = SWSRC_LAST_LOGICAL_SWITCH,
|
||||
SWSRC_LAST_IN_MIXES = SWSRC_LAST_LOGICAL_SWITCH,
|
||||
#endif
|
||||
SWSRC_FIRST_IN_LOGICAL_SWITCHES = -SWSRC_LAST_IN_LOGICAL_SWITCHES,
|
||||
SWSRC_FIRST_IN_MIXES = -SWSRC_LAST_IN_MIXES,
|
||||
};
|
||||
|
||||
enum MixSources {
|
||||
@@ -1610,12 +1617,14 @@ enum TimerModes {
|
||||
TMRMODE_THR,
|
||||
TMRMODE_THR_REL,
|
||||
TMRMODE_THR_TRG,
|
||||
TMRMODE_FIRST_SWITCH
|
||||
TMRMODE_COUNT
|
||||
};
|
||||
|
||||
#define COUNTDOWN_SILENT 0
|
||||
#define COUNTDOWN_BEEPS 1
|
||||
#define COUNTDOWN_VOICE 2
|
||||
enum CountDownModes {
|
||||
COUNTDOWN_SILENT,
|
||||
COUNTDOWN_BEEPS,
|
||||
COUNTDOWN_VOICE
|
||||
};
|
||||
|
||||
#if defined(CPUARM) || defined(CPUM2560)
|
||||
PACK(typedef struct t_TimerData {
|
||||
|
||||
@@ -441,11 +441,23 @@ 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);
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM) && defined(FLIGHT_MODES) && defined(GVARS)
|
||||
for (int p=1; p<MAX_FLIGHT_MODES; p++) {
|
||||
for (int i=0; i<MAX_GVARS; i++) {
|
||||
g_model.flightModeData[p].gvars[i] = GVAR_MAX+1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
g_model.frsky.channels[0].ratio = 132;
|
||||
#endif
|
||||
@@ -455,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)
|
||||
{
|
||||
@@ -466,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,10 +1078,16 @@ void doSplash()
|
||||
getADC();
|
||||
|
||||
#if defined(FSPLASH)
|
||||
if (!(g_eeGeneral.splashMode & 0x04))
|
||||
// Splash is forced, we can't skip it
|
||||
if (!(g_eeGeneral.splashMode & 0x04)) {
|
||||
#endif
|
||||
|
||||
if (keyDown() || inputsMoved()) return;
|
||||
|
||||
#if defined(FSPLASH)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pwrCheck()==e_power_off) return;
|
||||
|
||||
#if !defined(PCBTARANIS) && !defined(PCBSTD)
|
||||
@@ -1611,11 +1648,8 @@ void timerReset(uint8_t idx)
|
||||
|
||||
void flightReset()
|
||||
{
|
||||
static bool firstReset = true;
|
||||
if (firstReset)
|
||||
firstReset = false;
|
||||
else
|
||||
AUDIO_RESET();
|
||||
// we don't reset the whole audio here (the tada.wav would be cut, if a prompt is queued before FlightReset, it should be played)
|
||||
// TODO check if the vario / background music are stopped correctly if switching to a model which doesn't have these functions enabled
|
||||
|
||||
if (!IS_MANUAL_RESET_TIMER(0)) {
|
||||
timerReset(0);
|
||||
@@ -1653,10 +1687,13 @@ FORCEINLINE void evalTrims()
|
||||
for (uint8_t i=0; i<NUM_STICKS; i++) {
|
||||
// do trim -> throttle trim if applicable
|
||||
int16_t trim = getTrimValue(phase, i);
|
||||
#if !defined(PCBTARANIS)
|
||||
if (i==THR_STICK && g_model.thrTrim) {
|
||||
trim = (((g_model.throttleReversed)?(int32_t)(trim+TRIM_MIN):(int32_t)(trim-TRIM_MIN)) * (RESX-getValue(MIXSRC_Thr))) >> (RESX_SHIFT+1);
|
||||
int16_t trimMin = g_model.extendedTrims ? TRIM_EXTENDED_MIN : TRIM_MIN;
|
||||
trim = (((g_model.throttleReversed)?(int32_t)(trim+trimMin):(int32_t)(trim-trimMin)) * (RESX-anas[i])) >> (RESX_SHIFT+1);
|
||||
}
|
||||
else if (trimsCheckTimer > 0) {
|
||||
#endif
|
||||
if (trimsCheckTimer > 0) {
|
||||
trim = 0;
|
||||
}
|
||||
|
||||
@@ -2308,7 +2345,7 @@ void doMixerCalculations()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tm > 0) tm -= (TMR_VAROFS-1);
|
||||
if (tm > 0) tm -= (TMRMODE_COUNT-1);
|
||||
if (getSwitch(tm))
|
||||
newTimerVal++;
|
||||
}
|
||||
@@ -2497,6 +2534,10 @@ void opentxClose()
|
||||
// TODO needed? telemetryEnd();
|
||||
#endif
|
||||
|
||||
#if defined(LUA)
|
||||
luaClose();
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
closeLogs();
|
||||
sdDone();
|
||||
@@ -3286,6 +3327,13 @@ uint16_t stack_free(uint8_t tid)
|
||||
stack = audioStack;
|
||||
size = AUDIO_STACK_SIZE;
|
||||
break;
|
||||
#if defined(PCBTARANIS)
|
||||
case 255:
|
||||
// main stack
|
||||
stack = (OS_STK *)&_main_stack_start;
|
||||
size = ((unsigned char *)&_estack - (unsigned char *)&_main_stack_start) / 4;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -3378,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()) {
|
||||
@@ -3406,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)
|
||||
|
||||
@@ -354,10 +354,14 @@ enum PotType {
|
||||
POT_TYPE_MAX=POT_TYPE_NO_DETENT
|
||||
};
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#if defined(PCBTARANIS) && defined(REVPLUS)
|
||||
#define IS_POT_AVAILABLE(x) ((x)!=POT3 || (g_eeGeneral.potsType & (0x03 << (2*((x)-POT1))))!=POT_TYPE_NONE)
|
||||
#define IS_POT_MULTIPOS(x) ((x)>=POT1 && (x)<=POT_LAST && ((g_eeGeneral.potsType>>(2*((x)-POT1)))&0x03)==POT_TYPE_MULTIPOS)
|
||||
#define IS_POT_WITHOUT_DETENT(x) ((x)>=POT1 && (x)<=POT_LAST && ((g_eeGeneral.potsType>>(2*((x)-POT1)))&0x03)==POT_TYPE_NO_DETENT)
|
||||
#elif defined(PCBTARANIS)
|
||||
#define IS_POT_AVAILABLE(x) ((x)!=POT3)
|
||||
#define IS_POT_MULTIPOS(x) ((x)>=POT1 && (x)<=POT_LAST && ((g_eeGeneral.potsType>>(2*((x)-POT1)))&0x03)==POT_TYPE_MULTIPOS)
|
||||
#define IS_POT_WITHOUT_DETENT(x) ((x)>=POT1 && (x)<=POT_LAST && ((g_eeGeneral.potsType>>(2*((x)-POT1)))&0x03)==POT_TYPE_NO_DETENT)
|
||||
#else
|
||||
#define IS_POT_AVAILABLE(x) (true)
|
||||
#define IS_POT_MULTIPOS(x) (false)
|
||||
@@ -689,7 +693,8 @@ extern uint8_t flightModeTransitionLast;
|
||||
#if defined(CPUARM) && !defined(SIMU)
|
||||
extern unsigned char *heap;
|
||||
extern int _end;
|
||||
extern unsigned char *_estack;
|
||||
extern int _estack;
|
||||
extern int _main_stack_start;
|
||||
#define getAvailableMemory() ((unsigned int)((unsigned char *)&_estack - heap))
|
||||
#endif
|
||||
|
||||
@@ -1081,8 +1086,6 @@ extern int16_t calcRESXto1000(int16_t x);
|
||||
extern int8_t calcRESXto100(int16_t x);
|
||||
#endif
|
||||
|
||||
#define TMR_VAROFS 5
|
||||
|
||||
extern const char vers_stamp[];
|
||||
|
||||
extern uint8_t g_vbat100mV;
|
||||
@@ -1463,13 +1466,14 @@ enum AUDIO_SOUNDS {
|
||||
SCRIPT_OK,
|
||||
SCRIPT_NOFILE,
|
||||
SCRIPT_SYNTAX_ERROR,
|
||||
SCRIPT_KILLED
|
||||
SCRIPT_PANIC,
|
||||
SCRIPT_KILLED,
|
||||
};
|
||||
enum ScriptReference {
|
||||
SCRIPT_MIX_FIRST,
|
||||
SCRIPT_MIX_LAST=SCRIPT_MIX_FIRST+MAX_SCRIPTS-1,
|
||||
SCRIPT_FUNC_FIRST,
|
||||
SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+MAX_SCRIPTS-1,
|
||||
SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+NUM_CFN-1,
|
||||
SCRIPT_TELEMETRY_FIRST,
|
||||
SCRIPT_TELEMETRY_LAST=SCRIPT_TELEMETRY_FIRST+MAX_SCRIPTS, // telem0 and telem1 .. telem7
|
||||
};
|
||||
@@ -1486,13 +1490,18 @@ enum AUDIO_SOUNDS {
|
||||
uint8_t outputsCount;
|
||||
ScriptOutput outputs[MAX_SCRIPT_OUTPUTS];
|
||||
};
|
||||
#define LUASTATE_STANDALONE_SCRIPT_RUNNING 1
|
||||
#define LUASTATE_RELOAD_MODEL_SCRIPTS 2
|
||||
enum InterpreterState {
|
||||
INTERPRETER_RUNNING_PERMANENT_SCRIPTS,
|
||||
INTERPRETER_RUNNING_STANDALONE_SCRIPT,
|
||||
INTERPRETER_RELOAD_PERMANENT_SCRIPTS,
|
||||
INTERPRETER_PANIC,
|
||||
};
|
||||
extern uint8_t luaState;
|
||||
extern uint8_t luaScriptsCount;
|
||||
extern ScriptInternalData standaloneScript;
|
||||
extern ScriptInternalData scriptInternalData[MAX_SCRIPTS];
|
||||
extern ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS];
|
||||
void luaClose();
|
||||
void luaInit();
|
||||
void luaTask(uint8_t evt);
|
||||
void luaExec(const char *filename);
|
||||
@@ -1501,13 +1510,23 @@ enum AUDIO_SOUNDS {
|
||||
int luaGetMemUsed();
|
||||
#define luaGetCpuUsed(idx) scriptInternalData[idx].instructions
|
||||
bool isTelemetryScriptAvailable(uint8_t index);
|
||||
#define LUA_INIT()
|
||||
#define LUA_RESET() luaInit()
|
||||
#define LUA_LOAD_MODEL_SCRIPTS() luaState |= LUASTATE_RELOAD_MODEL_SCRIPTS
|
||||
#define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= LUASTATE_RELOAD_MODEL_SCRIPTS
|
||||
#define LUA_LOAD_MODEL_SCRIPTS() luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS
|
||||
#define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS
|
||||
|
||||
// Lua PROTECT/UNPROTECT
|
||||
#include <setjmp.h>
|
||||
struct our_longjmp {
|
||||
struct our_longjmp *previous;
|
||||
jmp_buf b;
|
||||
volatile int status; /* error code */
|
||||
};
|
||||
extern struct our_longjmp * global_lj;
|
||||
#define PROTECT_LUA() { struct our_longjmp lj; \
|
||||
lj.previous = global_lj; /* chain new error handler */ \
|
||||
global_lj = &lj; \
|
||||
if (setjmp(lj.b) == 0)
|
||||
#define UNPROTECT_LUA() global_lj = lj.previous; } /* restore old error handler */
|
||||
#else
|
||||
#define LUA_INIT()
|
||||
#define LUA_RESET()
|
||||
#define LUA_LOAD_MODEL_SCRIPTS()
|
||||
#define LUA_LOAD_MODEL_SCRIPT(idx)
|
||||
#endif
|
||||
|
||||
@@ -357,7 +357,7 @@ int main(int argc,char **argv)
|
||||
// We pass the "name" of the application, and its "vendor", the name
|
||||
// and vendor are used to search the registry database (which stores
|
||||
// persistent information e.g. fonts and colors).
|
||||
FXApp application("Open9xSim", "thus");
|
||||
FXApp application("OpenTX Simu", "OpenTX");
|
||||
|
||||
// Here we initialize the application. We pass the command line arguments
|
||||
// because FOX may sometimes need to filter out some of the arguments.
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -309,8 +309,6 @@ void *main_thread(void *)
|
||||
|
||||
if (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on
|
||||
|
||||
LUA_INIT();
|
||||
|
||||
if (main_thread_running == 1) {
|
||||
opentxStart();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include "debug.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported variables
|
||||
@@ -53,10 +54,8 @@
|
||||
|
||||
#undef errno
|
||||
extern int errno;
|
||||
extern int _end;
|
||||
extern int _estack;
|
||||
|
||||
#define RAM_END (unsigned char *)&_estack
|
||||
extern int _end;
|
||||
extern int _main_stack_start;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
@@ -68,7 +67,7 @@ extern int _getpid ( void ) ;
|
||||
unsigned char *heap = (unsigned char *)&_end;
|
||||
extern caddr_t _sbrk(int nbytes)
|
||||
{
|
||||
if (heap + nbytes < RAM_END-4096) {
|
||||
if (heap + nbytes < (unsigned char *)&_main_stack_start) {
|
||||
unsigned char *prev_heap = heap;
|
||||
heap += nbytes;
|
||||
return (caddr_t) prev_heap;
|
||||
@@ -142,7 +141,7 @@ extern int _write( int file, char *ptr, int len )
|
||||
|
||||
extern void _exit( int status )
|
||||
{
|
||||
printf( "Exiting with status %d.\n", status ) ;
|
||||
TRACE( "Exiting with status %d.\n", status ) ;
|
||||
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
@@ -156,3 +155,8 @@ extern int _getpid ( void )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
void _init (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include "../../opentx.h"
|
||||
|
||||
#define RX_UART_BUFFER_SIZE 32
|
||||
#define RX_UART_BUFFER_SIZE 128
|
||||
|
||||
struct t_rxUartBuffer
|
||||
{
|
||||
@@ -44,8 +44,7 @@ struct t_rxUartBuffer
|
||||
uint8_t *outPtr ;
|
||||
};
|
||||
|
||||
struct t_rxUartBuffer TelemetryInBuffer[2] ;
|
||||
uint32_t TelemetryActiveBuffer;
|
||||
struct t_rxUartBuffer TelemetryInBuffer ;
|
||||
uint16_t DsmRxTimeout;
|
||||
|
||||
// USART0 configuration
|
||||
@@ -106,18 +105,14 @@ extern "C" void USART0_IRQHandler()
|
||||
void startPdcUsartReceive()
|
||||
{
|
||||
register Usart *pUsart = SECOND_USART;
|
||||
|
||||
TelemetryInBuffer[0].outPtr = TelemetryInBuffer[0].fifo ;
|
||||
TelemetryInBuffer[1].outPtr = TelemetryInBuffer[1].fifo ;
|
||||
TelemetryInBuffer.outPtr = TelemetryInBuffer.fifo ;
|
||||
#ifndef SIMU
|
||||
// TODO because of the 64bits cast ...
|
||||
pUsart->US_RPR = (uint32_t)TelemetryInBuffer[0].fifo ;
|
||||
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer[1].fifo ;
|
||||
pUsart->US_RPR = (uint32_t)TelemetryInBuffer.fifo ;
|
||||
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ;
|
||||
#endif
|
||||
pUsart->US_RCR = RX_UART_BUFFER_SIZE ;
|
||||
pUsart->US_RNCR = RX_UART_BUFFER_SIZE ;
|
||||
pUsart->US_PTCR = US_PTCR_RXTEN ;
|
||||
TelemetryActiveBuffer = 0;
|
||||
}
|
||||
|
||||
void rxPdcUsart( void (*pChProcess)(uint8_t x) )
|
||||
@@ -126,34 +121,29 @@ void rxPdcUsart( void (*pChProcess)(uint8_t x) )
|
||||
register Usart *pUsart = SECOND_USART;
|
||||
uint8_t *ptr ;
|
||||
uint8_t *endPtr ;
|
||||
uint32_t j ;
|
||||
|
||||
// Find out where the DMA has got to
|
||||
__disable_irq() ;
|
||||
pUsart->US_PTCR = US_PTCR_RXTDIS ; // Freeze DMA
|
||||
ptr = (uint8_t *)pUsart->US_RPR ;
|
||||
j = pUsart->US_RNCR ;
|
||||
pUsart->US_PTCR = US_PTCR_RXTEN ; // DMA active again
|
||||
__enable_irq() ;
|
||||
|
||||
endPtr = ptr - 1 ;
|
||||
ptr = TelemetryInBuffer[TelemetryActiveBuffer].outPtr ;
|
||||
if ( j == 0 ) // First buf is full
|
||||
endPtr = (uint8_t *)pUsart->US_RPR ;
|
||||
// Check for DMA passed end of buffer
|
||||
if ( endPtr > &TelemetryInBuffer.fifo[RX_UART_BUFFER_SIZE-1] )
|
||||
{
|
||||
endPtr = &TelemetryInBuffer[TelemetryActiveBuffer].fifo[RX_UART_BUFFER_SIZE-1] ; // last byte
|
||||
endPtr = TelemetryInBuffer.fifo ;
|
||||
}
|
||||
while ( ptr <= endPtr )
|
||||
ptr = TelemetryInBuffer.outPtr ;
|
||||
while ( ptr != endPtr )
|
||||
{
|
||||
(*pChProcess)(*ptr++) ;
|
||||
if ( ptr > &TelemetryInBuffer.fifo[RX_UART_BUFFER_SIZE-1] ) // last byte
|
||||
{
|
||||
ptr = TelemetryInBuffer.fifo ;
|
||||
}
|
||||
}
|
||||
TelemetryInBuffer[TelemetryActiveBuffer].outPtr = ptr ;
|
||||
if ( j == 0 ) // First buf is full
|
||||
TelemetryInBuffer.outPtr = ptr ;
|
||||
|
||||
if ( pUsart->US_RNCR == 0 )
|
||||
{
|
||||
TelemetryInBuffer[TelemetryActiveBuffer].outPtr = TelemetryInBuffer[TelemetryActiveBuffer].fifo ;
|
||||
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer[TelemetryActiveBuffer].fifo ;
|
||||
pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ;
|
||||
pUsart->US_RNCR = RX_UART_BUFFER_SIZE ;
|
||||
TelemetryActiveBuffer ^= 1 ; // Other buffer is active
|
||||
rxPdcUsart( pChProcess ) ; // Get any chars from second buffer
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -98,8 +98,23 @@ LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/*Paint Main Stack */
|
||||
ldr r2, = _main_stack_start
|
||||
PaintMainStack:
|
||||
movs r3, #0x55555555
|
||||
str r3, [r2], #4
|
||||
LoopPaintMainStack:
|
||||
ldr r3, = _estack
|
||||
cmp r2, r3
|
||||
bcc PaintMainStack
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Call C++ constructors for static objects */
|
||||
bl __libc_init_array
|
||||
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
bx lr
|
||||
|
||||
@@ -61,10 +61,12 @@
|
||||
|
||||
volatile uint16_t Analog_values[NUMBER_ANALOG];
|
||||
|
||||
#if defined(REV4a)
|
||||
#if defined(REVPLUS)
|
||||
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)
|
||||
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,0,-1,1, 1};
|
||||
#endif
|
||||
|
||||
void adcInit()
|
||||
@@ -129,6 +131,11 @@ void adcRead()
|
||||
if (ana_direction[i] < 0) {
|
||||
Analog_values[i] = 4096-Analog_values[i];
|
||||
}
|
||||
#if !defined(REVPLUS)
|
||||
else if (ana_direction[i] == 0) {
|
||||
Analog_values[i] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -338,8 +338,8 @@ void lcdSetRefVolt(uint8_t val)
|
||||
#if defined(REVPLUS)
|
||||
void turnBacklightOn(uint8_t level, uint8_t color)
|
||||
{
|
||||
TIM4->CCR4 = (100-level)*color;
|
||||
TIM4->CCR2 = (100-level)*(100-color);
|
||||
TIM4->CCR4 = ((100-level)*(20-color))/20;
|
||||
TIM4->CCR2 = ((100-level)*color)/20;
|
||||
}
|
||||
|
||||
void turnBacklightOff(void)
|
||||
|
||||
@@ -34,6 +34,8 @@ ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20020000; /* end of 128K SRAM */
|
||||
_main_stack_size = 0x1000; /*size of main stack*/
|
||||
_main_stack_start = _estack - _main_stack_size;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0; /* required amount of heap */
|
||||
|
||||
@@ -21,6 +21,8 @@ ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20020000; /* end of 128K SRAM */
|
||||
_main_stack_size = 0x1000; /*size of main stack*/
|
||||
_main_stack_start = _estack - _main_stack_size;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0; /* required amount of heap */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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), UNIT_VOLTS);
|
||||
}
|
||||
else if (appId >= A4_FIRST_ID && appId <= A4_LAST_ID) {
|
||||
frskyData.analog[TELEM_ANA_A4].set(SPORT_DATA_U32(packet), 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;
|
||||
|
||||
|
After Width: | Height: | Size: 404 B |
|
After Width: | Height: | Size: 544 B |
@@ -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();
|
||||
}
|
||||
|
||||
@@ -242,5 +242,28 @@ TEST(Lcd, Dblsize)
|
||||
lcd_putsAtt(82, 10, "TST", DBLSIZE);
|
||||
EXPECT_TRUE(checkScreenshot("dblsize"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
TEST(Lcd, DrawSwitch)
|
||||
{
|
||||
lcd_clear();
|
||||
putsSwitches(0, 10, SWSRC_SA0, 0);
|
||||
putsSwitches(30, 10, SWSRC_SA0, SMLSIZE);
|
||||
// putsSwitches(60, 10, SWSRC_SA0, MIDSIZE); missing arrows in this font
|
||||
putsSwitches(90, 10, SWSRC_SA0, DBLSIZE);
|
||||
EXPECT_TRUE(checkScreenshot("drawswitch"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
TEST(Lcd, BMPWrapping)
|
||||
{
|
||||
lcd_clear();
|
||||
uint8_t bitmap[2+40*40/2];
|
||||
bmpLoad(bitmap, "./tests/plane.bmp", 40, 40);
|
||||
lcd_bmp(200, 0, bitmap);
|
||||
lcd_bmp(200, 60, bitmap);
|
||||
EXPECT_TRUE(checkScreenshot("bmpwrapping"));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -76,32 +76,311 @@ uint16_t anaIn(uint8_t chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST(Trims, throttleTrim)
|
||||
{
|
||||
MODEL_RESET();
|
||||
modelDefault(0);
|
||||
g_model.thrTrim = 1;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1024);
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1024);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+500);
|
||||
// stick min + trim mid
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+250);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024);
|
||||
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1024);
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1024);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+2000);
|
||||
// stick min + trim mid
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+1000);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024);
|
||||
|
||||
}
|
||||
|
||||
TEST(Trims, invertedThrottlePlusThrottleTrim)
|
||||
{
|
||||
MODEL_RESET();
|
||||
modelDefault(0);
|
||||
g_model.throttleReversed = 1;
|
||||
g_model.thrTrim = 1;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024);
|
||||
// stick max + trim mid
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+250);
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+500);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], +1024);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], +1024);
|
||||
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024);
|
||||
// stick max + trim mid
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+1000);
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], -1024+2000);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], +1024);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], +1024);
|
||||
}
|
||||
|
||||
TEST(Trims, throttleTrimWithZeroWeightOnThrottle)
|
||||
{
|
||||
MODEL_RESET();
|
||||
modelDefault(0);
|
||||
g_model.thrTrim = 1;
|
||||
#if defined(PCBTARANIS)
|
||||
// the input already exists
|
||||
ExpoData *expo = expoAddress(THR_STICK);
|
||||
#else
|
||||
ExpoData *expo = expoAddress(0);
|
||||
expo->mode = 3;
|
||||
expo->chn = THR_STICK;
|
||||
#endif
|
||||
expo->weight = 0;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 250);
|
||||
// stick max + trim mid
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[2] - 125), 1); //can't use precise comparison here because of lower precision math on 9X
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 250);
|
||||
// stick min + trim mid
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[2] - 125), 1);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
|
||||
// now some tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// trim min + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = -300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = +300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
|
||||
// trim max + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = -300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = +300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
}
|
||||
|
||||
TEST(Trims, invertedThrottlePlusthrottleTrimWithZeroWeightOnThrottle)
|
||||
{
|
||||
MODEL_RESET();
|
||||
modelDefault(0);
|
||||
g_model.throttleReversed = 1;
|
||||
g_model.thrTrim = 1;
|
||||
#if defined(PCBTARANIS)
|
||||
// the input already exists
|
||||
ExpoData *expo = expoAddress(THR_STICK);
|
||||
#else
|
||||
ExpoData *expo = expoAddress(0);
|
||||
expo->mode = 3;
|
||||
expo->chn = THR_STICK;
|
||||
#endif
|
||||
expo->weight = 0;
|
||||
// stick max + trim max
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
// stick max + trim mid
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[2] - 125), 1);
|
||||
// stick max + trim min
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 250);
|
||||
// stick min + trim max
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
// stick min + trim mid
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[2] - 125), 1);
|
||||
// stick min + trim min
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 250);
|
||||
|
||||
// now some tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// trim min + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = -300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = +300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 1000);
|
||||
|
||||
// trim max + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
anaInValues[THR_STICK] = -1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = -300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = +300;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
anaInValues[THR_STICK] = +1024;
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[2], 0);
|
||||
}
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
TEST(Trims, greaterTrimLink)
|
||||
{
|
||||
MODEL_RESET();
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(3, 0, 32);
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(1, 0), 0), 32);
|
||||
setTrimValue(1, RUD_STICK, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(3, RUD_STICK, 32);
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(1, RUD_STICK), RUD_STICK), 32);
|
||||
}
|
||||
|
||||
TEST(Trims, chainedTrims)
|
||||
{
|
||||
MODEL_RESET();
|
||||
setTrimValue(0, 0, 32);
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+1); // link to FP0 trim
|
||||
setTrimValue(2, 0, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 2), 0), 32);
|
||||
setTrimValue(0, RUD_STICK, 32);
|
||||
setTrimValue(1, RUD_STICK, TRIM_EXTENDED_MAX+1); // link to FP0 trim
|
||||
setTrimValue(2, RUD_STICK, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, RUD_STICK), RUD_STICK), 32);
|
||||
}
|
||||
|
||||
TEST(Trims, infiniteChainedTrims)
|
||||
{
|
||||
MODEL_RESET();
|
||||
setTrimValue(0, 0, 32);
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(2, 0, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
setTrimValue(3, 0, TRIM_EXTENDED_MAX+3); // link to FP2 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 2), 0), 32);
|
||||
setTrimValue(0, RUD_STICK, 32);
|
||||
setTrimValue(1, RUD_STICK, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(2, RUD_STICK, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
setTrimValue(3, RUD_STICK, TRIM_EXTENDED_MAX+3); // link to FP2 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, RUD_STICK), RUD_STICK), 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -109,10 +388,10 @@ TEST(Trims, CopyTrimsToOffset)
|
||||
{
|
||||
MODEL_RESET();
|
||||
modelDefault(0);
|
||||
setTrimValue(0, 1, -100); // -100 on elevator
|
||||
setTrimValue(0, ELE_STICK, -100); // -100 on elevator
|
||||
evalFunctions(); // it disables all safety channels
|
||||
copyTrimsToOffset(1);
|
||||
EXPECT_EQ(getTrimValue(0, 1), -100); // unchanged
|
||||
EXPECT_EQ(getTrimValue(0, ELE_STICK), -100); // unchanged
|
||||
#if defined(CPUARM)
|
||||
EXPECT_EQ(g_model.limitData[1].offset, -195);
|
||||
#else
|
||||
@@ -533,6 +812,34 @@ TEST(Mixer, SlowDisabledOnStartup)
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX);
|
||||
}
|
||||
|
||||
TEST(Mixer, DelayOnSwitch)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].swtch = TR(SWSRC_THR, SWSRC_SA2);
|
||||
g_model.mixData[0].delayUp = DELAY_STEP*5;
|
||||
g_model.mixData[0].delayDown = DELAY_STEP*5;
|
||||
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_DELAY(0, 500);
|
||||
|
||||
evalFlightModeMixes(e_perout_mode_normal, 1);
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX);
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
CHECK_DELAY(0, 500);
|
||||
|
||||
evalFlightModeMixes(e_perout_mode_normal, 1);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
}
|
||||
|
||||
#if !defined(CPUARM)
|
||||
TEST(Mixer, SlowAndDelayOnReplace3POSSource)
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 640 B After Width: | Height: | Size: 904 B |
|
After Width: | Height: | Size: 1002 B |
|
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 980 B |
@@ -172,7 +172,7 @@
|
||||
#define TR_VMLTPX2 "+=""*="":="
|
||||
|
||||
#define LEN_VMIXTRIMS "\003"
|
||||
#define TR_VMIXTRIMS "OFF""ON\0""Dir""Prf""Gaz""AL"
|
||||
#define TR_VMIXTRIMS "OFF""ON\0""Dir""Prf""Gaz""Ail"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define TR_CSWTIMER "Tempo"
|
||||
@@ -516,7 +516,7 @@
|
||||
#define TR_ELIMITS TR("Limites ét", "Limites étendues")
|
||||
#define TR_ETRIMS TR("Trims ét.", "Trims étendus")
|
||||
#define TR_TRIMINC TR("Pas Trim", "Pas des trims")
|
||||
#define TR_TTRACE TR("Source gaz", INDENT "Source gaz")
|
||||
#define TR_TTRACE TR("Src\001chrnos", INDENT "Source chronos")
|
||||
#define TR_TTRIM TR("Trim gaz", INDENT "Trim ralenti uniq.")
|
||||
#define TR_BEEPCTR TR("Bips centr", "Bips centrage")
|
||||
#define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole")
|
||||
@@ -613,7 +613,7 @@
|
||||
#define OFS_RX 4
|
||||
#define TR_ACCEL "Acc:"
|
||||
#define TR_NODATA "NO DATA"
|
||||
#define TR_TOTTM1TM2THRTHP "\037\146TOT\036TM1\037\146TM2\036THR\037\146TH%"
|
||||
#define TR_TOTTM1TM2THRTHP "\037\146TOT\036TM1\037\146TM2\036000GAZ\037\146GZ%"
|
||||
#define TR_TMR1LATMAXUS "Tmr1Lat max\037\124us"
|
||||
#define STR_US (STR_TMR1LATMAXUS+13)
|
||||
#define TR_TMR1LATMINUS "Tmr1Lat min\037\124us"
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#define TR_UART3MODES "OFF\0 ""Replica Porta-S""Telemetria\0 ""Debug\0 "
|
||||
|
||||
#define LEN_POTTYPES "\017"
|
||||
#define TR_POTTYPES "None\0 ""Pot with detent""Inter. Multipos""Potenziometro\0"
|
||||
#define TR_POTTYPES "None\0 ""Pot. con centro""Inter. Multipos""Potenziometro\0 "
|
||||
|
||||
#define LEN_DATETIME "\005"
|
||||
#define TR_DATETIME "DATA:""ORA :"
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#define TR_UART3MODES "Wyłącz\0 ""S-Port Mirror\0 ""Telemetry\0 ""Debug\0 "
|
||||
|
||||
#define LEN_POTTYPES "\017"
|
||||
#define TR_POTTYPES "Brak\0 ""Pot with detent""Przeł.Wielopoz.""Potencjometr\0"
|
||||
#define TR_POTTYPES "Brak\0 ""Poten z zapadką""Przeł.Wielopoz.""Potencjometr\0"
|
||||
|
||||
#define LEN_DATETIME "\005"
|
||||
#define TR_DATETIME "DATA:""CZAS:"
|
||||
@@ -92,7 +92,7 @@
|
||||
#define TR_VLCD "NormalOptrex"
|
||||
|
||||
#define LEN_VPERSISTENT "\014"
|
||||
#define TR_VPERSISTENT "OFF\0 ""Flight\0 ""Manual Reset"
|
||||
#define TR_VPERSISTENT "Wyłącz\0 ""Lot\0 ""Ręczny Reset"
|
||||
|
||||
#define LEN_COUNTRYCODES TR("\002", "\007")
|
||||
#define TR_COUNTRYCODES TR("US""JP""EU", "Ameryka""Japonia""Europa\0")
|
||||
|
||||
@@ -80,10 +80,10 @@
|
||||
#define TR_TRNCHN "KN1KN2KN3KN4"
|
||||
|
||||
#define LEN_UART3MODES "\022"
|
||||
#define TR_UART3MODES "Av\0 ""Spegling av S-Port""Telemetry\0 ""Debug\0 "
|
||||
#define TR_UART3MODES "Av\0 ""Spegling av S-Port""Telemetri\0 ""Debug\0 "
|
||||
|
||||
#define LEN_POTTYPES "\020"
|
||||
#define TR_POTTYPES "Ingen\0 ""Pot with detent""Flerlägesväljare""Potentiometer\0"
|
||||
#define TR_POTTYPES "Ingen\0 ""Mittläges-pot\0 ""Flerlägesväljare""Potentiometer\0"
|
||||
|
||||
#define LEN_DATETIME "\005"
|
||||
#define TR_DATETIME "DAG: ""TID: "
|
||||
@@ -92,7 +92,7 @@
|
||||
#define TR_VLCD "NormalOptrex"
|
||||
|
||||
#define LEN_VPERSISTENT "\014"
|
||||
#define TR_VPERSISTENT "OFF\0 ""Flight\0 ""Manual Reset"
|
||||
#define TR_VPERSISTENT "AV\0 ""Flygning\0 ""Nolla Själv\0"
|
||||
|
||||
#define LEN_COUNTRYCODES TR("\002", "\007")
|
||||
#define TR_COUNTRYCODES TR("US""JP""EU", "Amerika""Japan\0 ""Europa\0")
|
||||
@@ -816,8 +816,8 @@
|
||||
#define TR_PT "pt"
|
||||
#define TR_PTS "pkt"
|
||||
#define TR_SMOOTH "Mjuk"
|
||||
#define TR_COPY_STICKS_TO_OFS "Spara sticks som offset"
|
||||
#define TR_COPY_TRIMS_TO_OFS "Copy trims to subtrim"
|
||||
#define TR_COPY_STICKS_TO_OFS "Spara spakar som offset"
|
||||
#define TR_COPY_TRIMS_TO_OFS "Spara trimmar som offset"
|
||||
#define TR_PERSISTENT_MAH INDENT "Lagra mAh"
|
||||
#define TR_PREFLIGHT "Startkontroller"
|
||||
#define TR_CHECKLIST TR(INDENT "Checklista", INDENT "Visa Checklista")
|
||||
@@ -827,7 +827,7 @@
|
||||
#define TR_INPUTS "Input"
|
||||
#define TR_OUTPUTS "Outputs"
|
||||
#define TR_EEBACKUP "\004[ENTER Lång] säkerhetskopiera EEPROM"
|
||||
#define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!"
|
||||
#define TR_TO_MANY_LUA_SCRIPTS "För många Lua-scripts!"
|
||||
|
||||
#if defined(MAVLINK)
|
||||
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -246,7 +246,7 @@ def ttsFr():
|
||||
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE+110+i)))
|
||||
for i, s in enumerate(["virgule", "et", "moins", "minuit", "midi"]):
|
||||
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE+119+i)))
|
||||
for i, s in enumerate(["volts", u"ampères", u"mètres seconde", "", u"kilomètre heure", u"mètres", u"degrés", "pourcents", u"milli ampères", u"milli ampères / heure", "watt", "db", "pieds", "miles par heure", "heure", "minute", "seconde", "tours par minute", "g"]):
|
||||
for i, s in enumerate(["volts", u"ampères", u"mètres seconde", "", u"kilomètre heure", u"mètres", u"degrés", "pourcents", u"milli ampères", u"milli ampères / heure", "watt", "db", "pieds", "miles par heure", "heure", "minute", "seconde", "tours minute", "g"]):
|
||||
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE+125+i)))
|
||||
for i, s in enumerate(["timer", "", "tension", "tension", u"émission", u"réception", "altitude", "moteur",
|
||||
"essence", u"température", u"température", "vitesse", "distance", "altitude", u"élément lipo",
|
||||
@@ -279,6 +279,9 @@ def ttsFr():
|
||||
]:
|
||||
systemSounds.append((s, filename(f, a)))
|
||||
for i, (s, f) in enumerate([
|
||||
(u"altitude", "altitude"),
|
||||
(u"température moteur", "moteur"),
|
||||
(u"température contrôleur", "cntrleur"),
|
||||
(u"train rentré", "gearup"),
|
||||
(u"train sorti", "geardn"),
|
||||
(u"volets rentrés", "flapup"),
|
||||
|
||||