diff --git a/DONATIONS.txt b/DONATIONS.txt
index 2f8a9e743..ad2efa2db 100644
--- a/DONATIONS.txt
+++ b/DONATIONS.txt
@@ -317,3 +317,4 @@ Arold Reinders
Robert Miller
Aviomotive - www.aviomotive.com
Mark Gaskievicz
+Roland Müller
diff --git a/companion/src/customizesplashdialog.cpp b/companion/src/customizesplashdialog.cpp
index 070fe3dc0..3b8240f6c 100644
--- a/companion/src/customizesplashdialog.cpp
+++ b/companion/src/customizesplashdialog.cpp
@@ -7,19 +7,128 @@
#include "splashlibrary.h"
#include "flashinterface.h"
+//*** Side Class ***
+
Side::Side(){
imageLabel = 0;
fileNameEdit = 0;
saveButton = 0;
- source=new Source;
- *source = UNDEFINED;
+ saveToFileName = new QString("");
+ source = new Source(UNDEFINED);
}
-void Side::copyImage( Side side ){
- if ((*source!=UNDEFINED) && (*side.source!=UNDEFINED))
+void Side::copyImage( Side side )
+{
+ if ((*source!=UNDEFINED) && (*side.source!=UNDEFINED))
imageLabel->setPixmap(*side.imageLabel->pixmap());
}
+bool Side::displayImage( QString fileName, Source pictSource )
+{
+ QImage image;
+
+ if (fileName.isEmpty()) {
+ return false;
+ }
+ if (pictSource == FW ){
+ FlashInterface flash(fileName);
+ if (!flash.hasSplash())
+ return false;
+ else
+ image = flash.getSplash();
+ }
+ else {
+ image.load(fileName);
+ }
+ if (image.isNull()) {
+ return false;
+ }
+ if (imageLabel->width()==424) {
+ image=image.convertToFormat(QImage::Format_RGB32);
+ QRgb col;
+ int gray;
+ int width = image.width();
+ int height = image.height();
+ for (int i = 0; i < width; ++i) {
+ for (int j = 0; j < height; ++j) {
+ col = image.pixel(i, j);
+ gray = qGray(col);
+ image.setPixel(i, j, qRgb(gray, gray, gray));
+ }
+ }
+ imageLabel->setPixmap(QPixmap::fromImage(image.scaled(imageLabel->width()/2, imageLabel->height()/2)));
+ }
+ else {
+ imageLabel->setPixmap(QPixmap::fromImage(image.scaled(imageLabel->width()/2, imageLabel->height()/2).convertToFormat(QImage::Format_Mono)));
+ }
+ switch (pictSource){
+ case FW:
+ fileNameEdit->setText(QObject::tr("FW: %1").arg(fileName));
+ *saveToFileName = fileName;
+ *source=FW;
+ break;
+ case PICT:
+ fileNameEdit->setText(QObject::tr("Pict: %1").arg(fileName));
+ *saveToFileName = fileName;
+ *source=PICT;
+ break;
+ case PROFILE:
+ fileNameEdit->setText(QObject::tr("Profile image"));
+ *saveToFileName = fileName;
+ *source=PROFILE;
+ break;
+ default:
+ break;
+ }
+ saveButton->setEnabled(true);
+ libraryButton->setEnabled(true);
+ invertButton->setEnabled(true);
+ return true;
+}
+
+bool Side::refreshImage()
+{
+ return displayImage( *saveToFileName, *source );
+}
+
+bool Side::saveImage()
+{
+ QSettings settings;
+
+ if (*source == FW )
+ {
+ FlashInterface flash(*saveToFileName);
+ if (!flash.hasSplash()) {
+ return false;
+ }
+ QImage image = imageLabel->pixmap()->toImage().scaled(flash.getSplashWidth(), flash.getSplashHeight());
+ if (flash.setSplash(image) && (flash.saveFlash(*saveToFileName) > 0)) {
+ settings.setValue("lastFlashDir", QFileInfo(*saveToFileName).dir().absolutePath());
+ }
+ else {
+ return false;
+ }
+ }
+ else if (*source == PICT) {
+ QImage image = imageLabel->pixmap()->toImage().scaled(imageLabel->width()/2, imageLabel->height()/2).convertToFormat(QImage::Format_Indexed8);
+ if (image.save(*saveToFileName)) {
+ settings.setValue("lastImagesDir", QFileInfo(*saveToFileName).dir().absolutePath());
+ }
+ else {
+ return false;
+ }
+ }
+ else if (*source == PROFILE) {
+ QImage image = imageLabel->pixmap()->toImage().scaled(imageLabel->width()/2, imageLabel->height()/2).convertToFormat(QImage::Format_Indexed8);
+ if (!image.save(*saveToFileName)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+//*** customizeSplashDialog Class ***
+
customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::customizeSplashDialog)
@@ -39,6 +148,7 @@ customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
left.invertButton = ui->leftInvertButton;
right.invertButton = ui->rightInvertButton;
+ loadProfile(left);
resize(0,0);
}
@@ -62,25 +172,10 @@ void customizeSplashDialog::loadFirmware(Side side)
QSettings settings;
QString fileName = QFileDialog::getOpenFileName(this, tr("Open"), settings.value("lastFlashDir").toString(), FLASH_FILES_FILTER);
if (!fileName.isEmpty()) {
- QFile file(fileName);
- if (fileName.isEmpty() || !file.exists())
- return;
-
- FlashInterface flash(fileName);
- if (!flash.hasSplash()) {
- QMessageBox::information(this, tr("Error"), tr("Could not find bitmap to replace in file"));
- return;
- }
-
- side.saveButton->setEnabled(true);
- side.imageLabel->setPixmap(QPixmap::fromImage(flash.getSplash()));
- side.imageLabel->setFixedSize(flash.getSplashWidth()*2,flash.getSplashHeight()*2);
- side.fileNameEdit->setText(fileName);
+ if (!side.displayImage( fileName, FW ))
+ QMessageBox::critical(this, tr("Error"), tr("Cannot load embedded FW image from %1.").arg(fileName));
+ else
settings.setValue("lastFlashDir", QFileInfo(fileName).dir().absolutePath());
- *side.source=FW;
- side.saveButton->setEnabled(true);
- side.libraryButton->setEnabled(true);
- side.invertButton->setEnabled(true);
}
}
@@ -96,46 +191,25 @@ void customizeSplashDialog::loadPicture(Side side)
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image to load"), settings.value("lastImagesDir").toString(), tr("Images (%1)").arg(supportedImageFormats));
- if (fileName.isEmpty()){
- return;
+ if (!fileName.isEmpty()) {
+ if (!side.displayImage( fileName, PICT ))
+ QMessageBox::critical(this, tr("Error"), tr("Cannot load the image file %1.").arg(fileName));
+ else
+ settings.setValue("lastImagesDir", QFileInfo(fileName).dir().absolutePath());
}
- QImage image(fileName);
- if (image.isNull()) {
- QMessageBox::critical(this, tr("Error"), tr("Cannot load %1.").arg(fileName));
- return;
- }
- if (side.imageLabel->width()==424) {
- image=image.convertToFormat(QImage::Format_RGB32);
- QRgb col;
- int gray;
- int width = image.width();
- int height = image.height();
- for (int i = 0; i < width; ++i)
- {
- for (int j = 0; j < height; ++j)
- {
- col = image.pixel(i, j);
- gray = qGray(col);
- image.setPixel(i, j, qRgb(gray, gray, gray));
- }
- }
- side.imageLabel->setPixmap(QPixmap::fromImage(image.scaled(side.imageLabel->width()/2, side.imageLabel->height()/2)));
- } else {
- side.imageLabel->setPixmap(QPixmap::fromImage(image.scaled(side.imageLabel->width()/2, side.imageLabel->height()/2).convertToFormat(QImage::Format_Mono)));
- }
-
- settings.setValue("lastImagesDir", QFileInfo(fileName).dir().absolutePath());
- side.fileNameEdit->setText(fileName);
- *side.source=PICT;
- side.saveButton->setEnabled(true);
- side.libraryButton->setEnabled(true);
- side.invertButton->setEnabled(true);
}
void customizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
void customizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
void customizeSplashDialog::loadProfile(Side side)
{
+ QSettings settings;
+ QString fileName=settings.value("SplashFileName","").toString();
+
+ if (!fileName.isEmpty()) {
+ if (!side.displayImage( fileName, PROFILE ))
+ QMessageBox::critical(this, tr("Error"), tr("Cannot load the profile image %1.").arg(fileName));
+ }
}
void customizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
@@ -143,67 +217,26 @@ void customizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicke
void customizeSplashDialog::libraryButton_clicked( Side side )
{
QString fileName;
-
splashLibrary *ld = new splashLibrary(this,&fileName);
ld->exec();
if (!fileName.isEmpty()) {
- QImage image(fileName);
- if (image.isNull()) {
- QMessageBox::critical(this, tr("Error"), tr("Cannot load %1.").arg(fileName));
- return;
- }
- if (side.imageLabel->width()==424) {
- image=image.convertToFormat(QImage::Format_RGB32);
- QRgb col;
- int gray;
- int width = image.width();
- int height = image.height();
- for (int i = 0; i < width; ++i)
- {
- for (int j = 0; j < height; ++j)
- {
- col = image.pixel(i, j);
- gray = qGray(col);
- image.setPixel(i, j, qRgb(gray, gray, gray));
- }
- }
- side.imageLabel->setPixmap(QPixmap::fromImage(image.scaled(side.imageLabel->width()/2, side.imageLabel->height()/2)));
- } else {
- side.imageLabel->setPixmap(QPixmap::fromImage(image.scaled(side.imageLabel->width()/2, side.imageLabel->height()/2).convertToFormat(QImage::Format_Mono)));
- }
+ if (!side.displayImage( fileName, UNDEFINED ))
+ QMessageBox::critical(this, tr("Error"), tr("Cannot load the library image %1.").arg(fileName));
}
}
void customizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
void customizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
-void customizeSplashDialog::saveButton_clicked(Side side)
+void customizeSplashDialog::saveButton_clicked( Side side )
{
- QSettings settings;
- QString fileName = side.fileNameEdit->text();
-
- if (*side.source == FW)
- {
- FlashInterface flash(fileName);
- if (!flash.hasSplash()) {
- QMessageBox::critical(this, tr("Error"), tr("Could not store image in firmware file %1").arg(fileName));
- return;
- }
- QImage image = side.imageLabel->pixmap()->toImage().scaled(flash.getSplashWidth(), flash.getSplashHeight());
- if (flash.setSplash(image) && (flash.saveFlash(fileName) > 0))
- settings.setValue("lastFlashDir", QFileInfo(fileName).dir().absolutePath());
- else
- QMessageBox::critical(this, tr("Error"), tr("Could not store image in firmware file %1").arg(fileName));
- }
- else if (*side.source == PICT)
- {
- if (!fileName.isEmpty()) {
- QImage image = side.imageLabel->pixmap()->toImage().scaled(side.imageLabel->width()/2, side.imageLabel->height()/2).convertToFormat(QImage::Format_Indexed8);
- if (image.save(fileName))
- settings.setValue("lastImagesDir", QFileInfo(fileName).dir().absolutePath());
- else
- QMessageBox::critical(this, tr("Error"), tr("The image file %1 could not be stored").arg(fileName));
+ if (side.saveImage()){
+ QMessageBox::information(this, tr("File Saved"), tr("The image was saved to the file %1").arg(*side.saveToFileName));
+ if ( !side.refreshImage()){
+ QMessageBox::critical(this, tr("Image Refresh Error"), tr("Failed to refresh image from file %1").arg(*side.saveToFileName));
}
}
+ else
+ QMessageBox::critical(this, tr("File Save Error"), tr("Failed to write image to %1").arg(*side.saveToFileName));
}
void customizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
diff --git a/companion/src/customizesplashdialog.h b/companion/src/customizesplashdialog.h
index 8ae954d1c..b4db9a60e 100644
--- a/companion/src/customizesplashdialog.h
+++ b/companion/src/customizesplashdialog.h
@@ -17,6 +17,9 @@ class Side
public:
Side();
void copyImage( Side );
+ bool displayImage( QString fileName, Source source );
+ bool saveImage();
+ bool refreshImage();
QLabel *imageLabel;
QLineEdit *fileNameEdit;
@@ -24,6 +27,9 @@ public:
QPushButton *invertButton;
QToolButton *libraryButton;
+ QString *saveToFileName;
+
+private:
Source *source;
};
diff --git a/companion/src/customizesplashdialog.ui b/companion/src/customizesplashdialog.ui
index b98d87907..fa6c57d9f 100644
--- a/companion/src/customizesplashdialog.ui
+++ b/companion/src/customizesplashdialog.ui
@@ -254,6 +254,16 @@
-
+
-
+
+
+ true
+
+
+ Load Profile
+
+
+
-
@@ -268,16 +278,6 @@
- -
-
-
- false
-
-
- Load Profile
-
-
-
-
@@ -550,6 +550,16 @@
-
+
-
+
+
+ true
+
+
+ Load Profile
+
+
+
-
@@ -567,16 +577,6 @@
- -
-
-
- false
-
-
- Load Profile
-
-
-
-
@@ -625,12 +625,17 @@
leftFileNameEdit
leftInvertButton
+ leftLibraryButton
+ leftLoadProfileButton
+ leftLoadFwButton
leftLoadPictButton
leftSaveButton
copyLeftToRightButton
copyRightToLeftButton
rightFileNameEdit
rightInvertButton
+ rightLibraryButton
+ rightLoadProfileButton
rightLoadFwButton
rightLoadPictButton
rightSaveButton
diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h
index 06c9ec13f..4c5780b82 100644
--- a/companion/src/eeprominterface.h
+++ b/companion/src/eeprominterface.h
@@ -883,8 +883,12 @@ class ModelData {
SwashRingData swashRingData;
unsigned int thrTraceSrc;
int8_t traineron; // 0 disable trainer, 1 allow trainer
- unsigned int modelId;
+ unsigned int modelId;
unsigned int switchWarningStates;
+ unsigned int nSwToWarn;
+ unsigned int nPotsToWarn;
+ int potPosition[C9X_NUM_POTS];
+ bool displayText;
// TODO structure
char gvars_names[C9X_MAX_GVARS][6+1];
bool gvars_popups[C9X_MAX_GVARS];
@@ -1030,6 +1034,7 @@ enum Capability {
CSFunc,
LCDWidth,
GetThrSwitch,
+ HasDisplayText,
VirtualInputs,
LuaInputs,
LimitsPer1000,
diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp
index b36ed2c50..e4056d696 100644
--- a/companion/src/firmwares/opentx/opentxeeprom.cpp
+++ b/companion/src/firmwares/opentx/opentxeeprom.cpp
@@ -24,13 +24,13 @@
#define MAX_CURVES(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 216) ? 32 : 16) : O9X_MAX_CURVES)
#define MAX_GVARS(board, version) ((IS_ARM(board) && version >= 216) ? 9 : 5)
-#define IS_RELEASE_21_MARCH_2013(board, version) (version >= 214 || (!IS_ARM(board) && version >= 213))
-#define IS_RELEASE_23_MARCH_2013(board, version) (version >= 214 || (board==BOARD_STOCK && version >= 213))
+#define IS_AFTER_RELEASE_21_MARCH_2013(board, version) (version >= 214 || (!IS_ARM(board) && version >= 213))
+#define IS_AFTER_RELEASE_23_MARCH_2013(board, version) (version >= 214 || (board==BOARD_STOCK && version >= 213))
inline int switchIndex(int i, BoardEnum board, unsigned int version)
{
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
- if (!IS_TARANIS(board) && release21March2013)
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
+ if (!IS_TARANIS(board) && afterrelease21March2013)
return (i<=3 ? i+3 : (i<=6 ? i-3 : i));
else
return i;
@@ -153,7 +153,7 @@ class SourcesConversionTable: public ConversionTable {
public:
SourcesConversionTable(BoardEnum board, unsigned int version, unsigned int variant, unsigned long flags=0)
{
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
int val=0;
@@ -177,19 +177,19 @@ class SourcesConversionTable: public ConversionTable {
for (int i=0; i(mix.name));
}
}
- else if (IS_DBLRAM(board, version) && IS_RELEASE_23_MARCH_2013(board, version)) {
+ else if (IS_DBLRAM(board, version) && IS_AFTER_RELEASE_23_MARCH_2013(board, version)) {
internalField.Append(new UnsignedField<4>(_destCh));
internalField.Append(new BoolField<1>(_curveMode));
internalField.Append(new BoolField<1>(mix.noExpo));
@@ -849,7 +849,7 @@ class ExpoField: public TransformedField {
}
internalField.Append(new SignedField<8>(_curveParam));
}
- else if (IS_DBLRAM(board, version) && IS_RELEASE_23_MARCH_2013(board, version)) {
+ else if (IS_DBLRAM(board, version) && IS_AFTER_RELEASE_23_MARCH_2013(board, version)) {
internalField.Append(new UnsignedField<2>(expo.mode));
internalField.Append(new UnsignedField<2>(expo.chn));
internalField.Append(new BoolField<1>(_curveMode));
@@ -1051,9 +1051,9 @@ class LogicalSwitchesFunctionsTable: public ConversionTable {
LogicalSwitchesFunctionsTable(BoardEnum board, unsigned int version)
{
int val=0;
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
addConversion(LS_FN_OFF, val++);
- if (release21March2013)
+ if (afterrelease21March2013)
addConversion(LS_FN_VEQUAL, val++);
addConversion(LS_FN_VPOS, val++);
addConversion(LS_FN_VNEG, val++);
@@ -1065,11 +1065,11 @@ class LogicalSwitchesFunctionsTable: public ConversionTable {
addConversion(LS_FN_XOR, val++);
if (IS_ARM(board) && version >= 216) addConversion(LS_FN_STAY, val++);
addConversion(LS_FN_EQUAL, val++);
- if (!release21March2013)
+ if (!afterrelease21March2013)
addConversion(LS_FN_NEQUAL, val++);
addConversion(LS_FN_GREATER, val++);
addConversion(LS_FN_LESS, val++);
- if (!release21March2013) {
+ if (!afterrelease21March2013) {
addConversion(LS_FN_EGREATER, val++);
addConversion(LS_FN_ELESS, val++);
}
@@ -1371,20 +1371,17 @@ class SwitchesWarningField: public TransformedField {
virtual void beforeExport()
{
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
- if (release21March2013) {
- _sw = (sw & 0xC1) + ((sw & 0x30) >> 3) + ((sw & 0x0E) << 2);
- }
- else {
_sw = sw;
- }
}
virtual void afterImport()
{
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
- if (release21March2013) {
- sw = (_sw & 0xC1) + ((_sw & 0x38) >> 2) + ((_sw & 0x06) << 3);
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
+ if (afterrelease21March2013 && version < 216) {
+ sw = _sw >> 1;
+ }
+ else if (!afterrelease21March2013) {
+ sw = ((_sw & 0x30) >> 4) + ((_sw & 0x0E) << 1) + ((_sw & 0xC0) >> 1);
}
else {
sw = _sw;
@@ -1784,8 +1781,8 @@ class FrskyScreenField: public DataField {
{
_screen = screen;
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
- if (!release21March2013) {
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
+ if (!afterrelease21March2013) {
for (int i=0; i<4; i++) {
if (_screen.body.bars[i].source > 0)
_screen.body.bars[i].source--;
@@ -1809,12 +1806,12 @@ class FrskyScreenField: public DataField {
{
_screen = screen;
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
// NOTA: screen.type should have been imported first!
if (screen.type == 0) {
numbers.ImportBits(input);
- if (!release21March2013) {
+ if (!afterrelease21March2013) {
int columns=(IS_TARANIS(board) ? 3:2);
for (int i=0; i<4; i++) {
for (int j=0; j 0)
_screen.body.bars[i].source++;
@@ -2016,9 +2013,9 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u
else
internalField.Append(new ZCharField<10>(modelData.name));
- bool release21March2013 = IS_RELEASE_21_MARCH_2013(board, version);
+ bool afterrelease21March2013 = IS_AFTER_RELEASE_21_MARCH_2013(board, version);
- if (release21March2013)
+ if (afterrelease21March2013)
internalField.Append(new UnsignedField<8>(modelData.modelId));
if (IS_TARANIS(board) && version >= 215) {
@@ -2035,7 +2032,7 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u
internalField.Append(new SpareBitsField<4>());
internalField.Append(new SignedField<16>(modelData.timers[i].pvalue));
}
- else if (release21March2013) {
+ else if (afterrelease21March2013) {
internalField.Append(new UnsignedField<12>(modelData.timers[i].val));
internalField.Append(new BoolField<1>((bool &)modelData.timers[i].countdownBeep));
internalField.Append(new BoolField<1>(modelData.timers[i].minuteBeep));
@@ -2077,7 +2074,7 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u
internalField.Append(new BoolField<1>(modelData.disableThrottleWarning));
if (IS_TARANIS(board) || (IS_ARM(board) && version >= 216))
- internalField.Append(new SpareBitsField<1>());
+ internalField.Append(new BoolField<1>(modelData.displayText));
else
internalField.Append(new BoolField<1>(modelData.moduleData[0].ppmPulsePol));
@@ -2119,15 +2116,19 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u
internalField.Append(new UnsignedField<8>(modelData.thrTraceSrc));
- if (!release21March2013) {
+ if (!afterrelease21March2013) {
internalField.Append(new UnsignedField<8>(modelData.modelId));
}
if (IS_TARANIS(board))
- internalField.Append(new UnsignedField<16>(modelData.switchWarningStates));
+ internalField.Append(new SwitchesWarningField<16>(modelData.switchWarningStates, board, version));
else
internalField.Append(new SwitchesWarningField<8>(modelData.switchWarningStates, board, version));
+ if (version >= 216) {
+ internalField.Append(new UnsignedField<8>(modelData.nSwToWarn));
+ }
+
if ((board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) && (variant & GVARS_VARIANT)) {
for (int i=0; i= 216) {
+ internalField.Append(new UnsignedField<8>(modelData.nPotsToWarn));
+ for (int i=0; i < GetEepromInterface()->getCapability(Pots); i++) {
+ internalField.Append(new SignedField<8>(modelData.potPosition[i]));
+ }
+ }
+
if (IS_TARANIS(board)) {
for (int i=0; i(modelData.curves[i].name));
@@ -2189,6 +2197,10 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u
internalField.Append(new SpareBitsField<720>());
for (int i=0; i<32; i++)
internalField.Append(new ZCharField<4>(modelData.inputNames[i]));
+ internalField.Append(new UnsignedField<8>(modelData.nPotsToWarn));
+ for (int i=0; i < GetEepromInterface()->getCapability(Pots); i++) {
+ internalField.Append(new SignedField<8>(modelData.potPosition[i]));
+ }
}
}
diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp
index fd79fbaa1..16dbfeca9 100644
--- a/companion/src/firmwares/opentx/opentxinterface.cpp
+++ b/companion/src/firmwares/opentx/opentxinterface.cpp
@@ -671,6 +671,7 @@ int Open9xInterface::getCapability(const Capability capability)
return (IS_TARANIS(board) ? 212 : 128) ;
case GetThrSwitch:
return (IS_TARANIS(board) ? DSW_SF1 : DSW_THR) ;
+ case HasDisplayText:
case VirtualInputs:
return IS_TARANIS(board) ? 32 : 0;
case LuaInputs:
diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp
index d9f00b7f2..4a134983f 100644
--- a/companion/src/mainwindow.cpp
+++ b/companion/src/mainwindow.cpp
@@ -1829,6 +1829,9 @@ void MainWindow::createActions()
connect(profileActs[i], SIGNAL(triggered()), this, SLOT(loadProfile()));
}
updateProfilesActions();
+ createProfileAct = new QAction(tr("New Profile"), this);
+ createProfileAct->setStatusTip(tr("Create a new Radio Setting Profile"));
+ connect(createProfileAct, SIGNAL(triggered()), this, SLOT(createProfile()));
classicThemeAct = new QAction(tr("Classic"), this);
classicThemeAct->setStatusTip(tr("The multicolor classical Companion icon theme"));
@@ -1913,7 +1916,6 @@ void MainWindow::createMenus()
{
QMenu *recentFileMenu=new QMenu(tr("Recent Files"));
- QMenu *profilesMenu=new QMenu(tr("Firmware Profiles"));
QMenu *languageMenu=new QMenu(tr("Set Menu Language"));
QMenu *themeMenu=new QMenu(tr("Set Icon Theme"));
QMenu *iconThemeSizeMenu=new QMenu(tr("Set Icon Size"));
@@ -1935,11 +1937,7 @@ void MainWindow::createMenus()
fileMenu->addAction(compareAct);
fileMenu->addSeparator();
fileMenu->addAction(fwPreferencesAct);
- fileMenu->addMenu(profilesMenu);
-
- profilesMenu->setIcon(CompanionIcon("profiles.png"));
- for (int i=0; iaddAction(profileActs[i]);
+ fileMenu->addMenu(createProfilesMenu());
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
@@ -2016,9 +2014,11 @@ QMenu *MainWindow::createRecentFileMenu()
QMenu *MainWindow::createProfilesMenu()
{
- QMenu *profilesMenu = new QMenu(this);
+ QMenu *profilesMenu=new QMenu(tr("Radio Settings Profiles"));
for ( int i = 0; i < MAX_PROFILES; ++i)
profilesMenu->addAction(profileActs[i]);
+ profilesMenu->addAction(createProfileAct);
+ profilesMenu->setIcon(CompanionIcon("profiles.png"));
return profilesMenu;
}
@@ -2199,9 +2199,11 @@ void MainWindow::updateProfilesActions()
}
settings.endGroup();
}
- // separatorAct->setVisible(numRecentFiles > 0);
}
+void MainWindow::createProfile()
+{
+}
QString MainWindow::strippedName(const QString &fullFileName)
{
diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h
index c39e8175a..e3e082b90 100644
--- a/companion/src/mainwindow.h
+++ b/companion/src/mainwindow.h
@@ -150,6 +150,7 @@ private slots:
void appPreferences();
void fwPreferences();
void updateMenus();
+ void createProfile();
MdiChild *createMdiChild();
void setActiveSubWindow(QWidget *window);
QMenu * createRecentFileMenu();
@@ -252,6 +253,7 @@ private:
QAction *logsAct;
QAction *recentFileActs[MAX_RECENT];
QAction *profileActs[MAX_PROFILES];
+ QAction *createProfileAct;
QAction *classicThemeAct;
QAction *monoThemeAct;
QAction *monoBlueThemeAct;
diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp
index aa86c1275..8042ccfe3 100644
--- a/companion/src/modeledit/setup.cpp
+++ b/companion/src/modeledit/setup.cpp
@@ -392,6 +392,10 @@ Setup::Setup(QWidget *parent, ModelData & model):
ui->modelImage_label->hide();
ui->imagePreview->hide();
}
+
+ if (!GetEepromInterface()->getCapability(HasDisplayText)) {
+ ui->displayText->hide();
+ }
// Beep Center checkboxes
int analogs = 4 + GetEepromInterface()->getCapability(Pots);
@@ -403,14 +407,12 @@ Setup::Setup(QWidget *parent, ModelData & model):
connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
centerBeepCheckboxes << checkbox;
}
- ui->switchesStartupLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, analogs+GetEepromInterface()->getCapability(RotaryEncoders));
// Startup switches warnings
- ui->switchesStartupWarning->setProperty("index", 0);
- connect(ui->switchesStartupWarning, SIGNAL(currentIndexChanged(int)), this, SLOT(startupSwitchEdited(int)));
for (int i=0; igetCapability(Switches)-1; i++) {
- QLabel * label = new QLabel();
- QSlider * slider = new QSlider();
+ QLabel * label = new QLabel(this);
+ QSlider * slider = new QSlider(this);
+ QCheckBox * cb = new QCheckBox(this);
slider->setProperty("index", i+1);
slider->setOrientation(Qt::Vertical);
slider->setMinimum(0);
@@ -429,13 +431,35 @@ Setup::Setup(QWidget *parent, ModelData & model):
label->setText(switches9X[i]);
slider->setMaximum(i==0 ? 2 : 1);
}
+ cb->setProperty("index", i+1);
ui->switchesStartupLayout->addWidget(label, 0, i+1);
+ ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter);
ui->switchesStartupLayout->addWidget(slider, 1, i+1);
+ ui->switchesStartupLayout->setAlignment(slider, Qt::AlignCenter);
+ ui->switchesStartupLayout->addWidget(cb, 2, i+1);
+ ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int)));
+ connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool)));
startupSwitchesSliders << slider;
+ startupSwitchesCheckboxes << cb;
}
ui->switchesStartupLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, GetEepromInterface()->getCapability(Switches));
+ // Pot warnings
+ if(IS_TARANIS(GetEepromInterface()->getBoard())) {
+ for (int i=0; igetCapability(Pots); i++) {
+ QCheckBox * cb = new QCheckBox(this);
+ cb->setProperty("index", i+1);
+ cb->setText(AnalogString(i+4));
+ ui->potWarningLayout->addWidget(cb, 0, i+1);
+ connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool)));
+ potWarningCheckboxes << cb;
+ }
+ }
+ else {
+ ui->label_potWarning->hide();
+ ui->potWarningMode->hide();
+ }
lock = false;
}
@@ -533,9 +557,14 @@ void Setup::update()
ui->throttleTrim->setChecked(model.thrTrim);
ui->extendedLimits->setChecked(model.extendedLimits);
ui->extendedTrims->setChecked(model.extendedTrims);
+ ui->displayText->setChecked(model.displayText);
updateBeepCenter();
updateStartupSwitches();
+
+ if(IS_TARANIS(GetEepromInterface()->getBoard())) {
+ updatePotWarnings();
+ }
for (int i=0; iupdate();
@@ -557,13 +586,13 @@ void Setup::updateStartupSwitches()
lock = true;
unsigned int switchStates = model.switchWarningStates;
- bool enabled = !(switchStates & 0x01);
- ui->switchesStartupWarning->setCurrentIndex(switchStates & 0x01);
- switchStates >>= 1;
for (int i=0; igetCapability(Switches)-1; i++) {
QSlider * slider = startupSwitchesSliders[i];
+ QCheckBox * cb = startupSwitchesCheckboxes[i];
+ bool enabled = !(model.nSwToWarn & (1 << i));
slider->setEnabled(enabled);
+ cb->setChecked(enabled);
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
slider->setValue(i==5 ? (switchStates & 0x3)/2 : switchStates & 0x3);
switchStates >>= 2;
@@ -584,36 +613,31 @@ void Setup::startupSwitchEdited(int value)
unsigned int mask;
int index = sender()->property("index").toInt();
- if (index == 0) {
- mask = 0x01;
- }
- else if (IS_TARANIS(GetEepromInterface()->getBoard())) {
- if (index == 6)
- mask = 0x02 << (index*2 - 1);
+ if (IS_TARANIS(GetEepromInterface()->getBoard())) {
+ if (index == 6) {
+ shift = (index - 1) * 2;
+ mask = 0x02 << shift;
+ shift++;
+ }
else {
- shift = index*2 - 1;
+ shift = (index - 1) * 2;
mask = 0x03 << shift;
}
}
else {
if (index == 1) {
- shift = 1;
- mask = 0x03 << shift;
+ mask = 0x03;
}
else {
- mask = 0x01 << (index+1);
+ shift = index;
+ mask = 0x01 << shift;
}
}
model.switchWarningStates &= ~mask;
if (value) {
- if (shift == 0) {
- model.switchWarningStates |= mask;
- }
- else {
- model.switchWarningStates |= (value << shift);
- }
+ model.switchWarningStates |= (value << shift);
}
updateStartupSwitches();
@@ -621,6 +645,72 @@ void Setup::startupSwitchEdited(int value)
}
}
+void Setup::startupSwitchToggled(bool checked)
+{
+ if (!lock) {
+ int index = sender()->property("index").toInt()-1;
+
+ if (checked)
+ model.nSwToWarn &= ~(1 << index);
+ else
+ model.nSwToWarn |= (1 << index);
+
+ updateStartupSwitches();
+ emit modified();
+ }
+}
+
+void Setup::updatePotWarnings()
+{
+ lock = true;
+ int mode = model.nPotsToWarn >> 6;
+ ui->potWarningMode->setCurrentIndex(mode);
+
+ if (mode == 0)
+ model.nPotsToWarn = 0x3F;
+
+ for (int i=0; isetChecked(enabled);
+ potWarningCheckboxes[i]->setDisabled(mode == 0);
+ }
+ lock = false;
+}
+
+void Setup::potWarningToggled(bool checked)
+{
+ if (!lock) {
+ int index = sender()->property("index").toInt()-1;
+
+ if(checked)
+ model.nPotsToWarn &= ~(1 << index);
+ else
+ model.nPotsToWarn |= (1 << index);
+
+ updatePotWarnings();
+ emit modified();
+ }
+}
+
+void Setup::on_potWarningMode_currentIndexChanged(int index)
+{
+ if (!lock) {
+ int mask = 0xC0;
+ model.nPotsToWarn = model.nPotsToWarn & ~mask;
+ model.nPotsToWarn = model.nPotsToWarn | ((index << 6) & mask);
+
+ updatePotWarnings();
+ emit modified();
+ }
+}
+
+void Setup::on_displayText_toggled(bool checked)
+{
+ model.displayText = checked;
+ emit modified();
+}
+
void Setup::on_throttleTrim_toggled(bool checked)
{
model.thrTrim = checked;
diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h
index 9608d85a3..b785e2750 100644
--- a/companion/src/modeledit/setup.h
+++ b/companion/src/modeledit/setup.h
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
namespace Ui {
class Setup;
@@ -82,19 +83,26 @@ class Setup : public ModelPanel
void on_extendedTrims_toggled(bool checked);
void on_throttleWarning_toggled(bool checked);
void on_throttleReverse_toggled(bool checked);
+ void on_displayText_toggled(bool checked);
void on_image_currentIndexChanged(int index);
void on_trimIncrement_currentIndexChanged(int index);
void onBeepCenterToggled(bool checked);
void startupSwitchEdited(int value);
+ void startupSwitchToggled(bool checked);
+ void potWarningToggled(bool checked);
+ void on_potWarningMode_currentIndexChanged(int index);
void onChildModified();
private:
Ui::Setup *ui;
QVector startupSwitchesSliders;
+ QVector startupSwitchesCheckboxes;
+ QVector potWarningCheckboxes;
QVector centerBeepCheckboxes;
ModulePanel * modules[C9X_NUM_MODULES+1];
TimerPanel * timers[C9X_MAX_TIMERS];
void updateStartupSwitches();
+ void updatePotWarnings();
void updateBeepCenter();
};
diff --git a/companion/src/modeledit/setup.ui b/companion/src/modeledit/setup.ui
index c4a632c00..29753cdb3 100644
--- a/companion/src/modeledit/setup.ui
+++ b/companion/src/modeledit/setup.ui
@@ -6,8 +6,8 @@
0
0
- 782
- 334
+ 787
+ 727
@@ -16,134 +16,6 @@
-
-
-
-
-
- Model Name
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- Timer2
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- Timer1
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- Throttle Source
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Switch startup Warning
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- Center beep
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- -
-
-
- Trim Increment
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- QLayout::SetMinimumSize
-
-
- 0
-
-
- 0
-
-
-
-
-
-
- 0
- 0
-
-
-
-
-
- ON
-
-
- -
-
- OFF
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Check
-
-
- Qt::AlignCenter
-
-
-
-
-
-
-
@@ -231,6 +103,85 @@
+ -
+
+
+ Model Name
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Timer2
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Timer1
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Throttle Source
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Switch Warnings
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Center beep
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ -
+
+
+ Trim Increment
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
-
-
@@ -288,6 +239,29 @@
+ -
+
+
+ Qt::RightToLeft
+
+
+ Display Checklist
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
-
@@ -353,6 +327,58 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi
+ -
+
+
+ QLayout::SetMinimumSize
+
+
+ 0
+
+
+ 6
+
+
+ 6
+
+
+
+ -
+
+
+ true
+
+
+ Pot Warnings
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
-
+
+
-
+
+ OFF
+
+
+ -
+
+ Manual
+
+
+ -
+
+ Auto
+
+
+
+
+
+
-
diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp
index defef59ea..99bd2c841 100644
--- a/radio/src/eeprom_conversions.cpp
+++ b/radio/src/eeprom_conversions.cpp
@@ -111,6 +111,8 @@ PACK(typedef struct {
}) MixData_v215;
#endif
+
+
PACK(typedef struct {
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
uint16_t start:12;
@@ -474,7 +476,8 @@ void ConvertModel_215_to_216(ModelData &model)
#endif
}
g_model.thrTraceSrc = oldModel.thrTraceSrc;
- g_model.switchWarningStates = oldModel.switchWarningStates;
+ g_model.switchWarningStates = oldModel.switchWarningStates >> 1;
+ g_model.nSwToWarn = (oldModel.switchWarningStates & 0x01) ? 0xFF : 0;
for (uint8_t i=0; i<5; i++) {
memcpy(g_model.gvars[i].name, oldModel.gvar_names[i], LEN_GVAR_NAME);
}
diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp
index a7499aa0b..db47af0c2 100644
--- a/radio/src/gui/menu_model.cpp
+++ b/radio/src/gui/menu_model.cpp
@@ -669,7 +669,8 @@ void menuModelFailsafe(uint8_t event)
bool newLongNames = false;
uint8_t ch;
- if (event == EVT_KEY_BREAK(KEY_ENTER) && s_editMode) {
+ if (event == EVT_KEY_LONG(KEY_ENTER) && s_editMode) {
+ s_noHi = NO_HI_LEN;
g_model.moduleData[g_moduleIdx].failsafeChannels[m_posVert] = channelOutputs[m_posVert];
eeDirty(EE_MODEL);
AUDIO_WARNING1();
@@ -721,7 +722,7 @@ void menuModelFailsafe(uint8_t event)
// Value
LcdFlags flags = TINSIZE;
- if (m_posVert == ch) {
+ if (m_posVert == ch && !s_noHi) {
flags |= INVERS;
if (s_editMode)
flags |= BLINK;
@@ -873,7 +874,11 @@ enum menuModelSetupItems {
ITEM_MODEL_THROTTLE_TRACE,
ITEM_MODEL_THROTTLE_TRIM,
ITEM_MODEL_THROTTLE_WARNING,
+#if defined(PCBTARANIS)
+ ITEM_MODEL_CHECKLIST_DISPLAY,
+#endif
ITEM_MODEL_SWITCHES_WARNING,
+ CASE_PCBTARANIS(ITEM_MODEL_POT_WARNING)
ITEM_MODEL_BEEP_CENTER,
#if defined(PCBTARANIS)
ITEM_MODEL_INTERNAL_MODULE_LABEL,
@@ -956,21 +961,22 @@ void menuModelSetup(uint8_t event)
#define PORT_CHANNELS_ROWS(x) (x==0 ? PORT1_CHANNELS_ROWS() : (x==1 ? PORT2_CHANNELS_ROWS() : TRAINER_CHANNELS_ROWS()))
#define FAILSAFE_ROWS(x) ((g_model.moduleData[x].rfProtocol==RF_PROTO_X16 || g_model.moduleData[x].rfProtocol==RF_PROTO_LR12) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
#define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX)
+ #define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
bool CURSOR_ON_CELL = (m_posHorz >= 0);
- MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_PORT1_ON(1), IF_PORT1_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_PORT1_ON(FAILSAFE_ROWS(0)), LABEL(ExternalModule), (g_model.externalModule==MODULE_TYPE_XJT || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, PORT2_CHANNELS_ROWS(), (IS_MODULE_XJT(1) && IS_D8_RX(1)) ? (uint8_t)1 : (IS_MODULE_PPM(1) || IS_MODULE_XJT(1) || IS_MODULE_DSM2(1)) ? (uint8_t)2 : HIDDEN_ROW, IF_PORT2_XJT(FAILSAFE_ROWS(1)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
+ MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, CASE_PCBTARANIS(0) 7, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_PORT1_ON(1), IF_PORT1_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_PORT1_ON(FAILSAFE_ROWS(0)), LABEL(ExternalModule), (g_model.externalModule==MODULE_TYPE_XJT || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, PORT2_CHANNELS_ROWS(), (IS_MODULE_XJT(1) && IS_D8_RX(1)) ? (uint8_t)1 : (IS_MODULE_PPM(1) || IS_MODULE_XJT(1) || IS_MODULE_DSM2(1)) ? (uint8_t)2 : HIDDEN_ROW, IF_PORT2_XJT(FAILSAFE_ROWS(1)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
#elif defined(CPUM64)
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX)
uint8_t protocol = g_model.protocol;
- MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 });
+ MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 });
#else
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX)
uint8_t protocol = g_model.protocol;
- MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, IF_PCBSKY9X(1) IF_PCBSKY9X(2) });
+ MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, IF_PCBSKY9X(1) IF_PCBSKY9X(2) });
#endif
if (!MENU_CHECK(menuTabModel, e_ModelSetup, MODEL_SETUP_MAX_LINES)) {
@@ -1096,10 +1102,11 @@ void menuModelSetup(uint8_t event)
g_model.extendedTrims = onoffMenuItem(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, attr, event);
#else
g_model.extendedTrims = onoffMenuItem(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, m_posHorz<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0);
- lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_RESET_BTN, m_posHorz>0 ? attr : 0);
+ lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_RESET_BTN, m_posHorz>0 && !s_noHi ? attr : 0);
if (attr && m_posHorz>0) {
s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)) {
+ s_noHi = NO_HI_LEN;
for (uint8_t i=0; i>= 1;
- for (uint8_t i=1; i>= 2;
+ c = "\300-\301"[states & 0x03];
+ lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+i*(2*FW), y, 'A'+i, line && (m_posHorz == i) ? INVERS : 0);
+ if (swactive) lcd_putc(MODEL_SETUP_2ND_COLUMN+i*(2*FW)+FWNUM, y, c);
+ lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+((NUM_SWITCHES-1)*2*FW+2), y, PSTR("<]"), (m_posHorz == NUM_SWITCHES-1 && !s_noHi) ? line : 0);
+ states >>= 2;
#else
- attr = 0;
- if (IS_3POS(i-1)) {
- c = '0'+(states & 0x03);
- states >>= 2;
- }
- else {
- if (states & 0x01)
- attr = INVERS;
- c = pgm_read_byte(STR_VSWITCHES - 2 + 6 + (3*i));
- states >>= 1;
- }
- lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+2*FW+i*FW, y, c, attr);
-#endif
+ attr = 0;
+
+ if (IS_3POS(i)) {
+ c = '0'+(states & 0x03);
+ states >>= 2;
}
+ else {
+ if ((states & 0x01) && swactive)
+ attr = INVERS;
+ c = pgm_read_byte(STR_VSWITCHES - 2 + 9 + (3*i));
+ states >>= 1;
+ }
+ if (line && (m_posHorz == i)) {
+ attr = BLINK;
+ if (swactive)
+ attr |= INVERS;
+ }
+ lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+i*FW, y, (swactive || (attr & BLINK)) ? c : '-', attr);
+#if !defined(CPUM64)
+ lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+(NUM_SWITCHES*FW), y, PSTR("<]"), (m_posHorz == NUM_SWITCHES-1 && !s_noHi) ? line : 0);
+#endif
+#endif
}
break;
}
+#if defined(PCBTARANIS)
+ case ITEM_MODEL_POT_WARNING:
+ {
+ lcd_putsLeft(y, STR_POTWARNING);
+ uint8_t potMode = g_model.nPotsToWarn >> 6;
+ if(attr) {
+ if (m_posHorz) s_editMode = 0;
+ if (!READ_ONLY() && m_posHorz) {
+ switch(event) {
+ case EVT_KEY_LONG(KEY_ENTER):
+ killEvents(event);
+ if(potMode == 1) {
+ g_model.potPosition[m_posHorz-1] = getValue(MIXSRC_FIRST_POT+m_posHorz-1) >> 3;
+ AUDIO_WARNING1();
+ eeDirty(EE_MODEL);
+ }
+ break;
+ case EVT_KEY_BREAK(KEY_ENTER):
+ g_model.nPotsToWarn ^= (1 << (m_posHorz-1));
+ eeDirty(EE_MODEL);
+ break;
+ }
+ }
+ }
+
+ lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""Off\0""Man\0""Auto"), potMode, attr & ((m_posHorz == 0) ? attr : !INVERS));
+ if (potMode)
+ for (uint8_t i=0; i> 6;
+ if(potMode) {
+ perOut(e_perout_mode_normal, 0);
+ bad_pots = 0;
+ for (uint8_t i=0; i> 3)) > 2)) {
+ warn = true;
+ bad_pots |= (1<> (i*2)];
+ lcd_putcAtt(60+i*(2*FW+FW/2), 4*FH+3, 'A'+i, attr);
+ lcd_putcAtt(60+i*(2*FW+FW/2)+FW, 4*FH+3, c, attr);
+ }
+ }
+ if(potMode) {
+ for (uint8_t i=0; i> 3)) > 2) {
+ switch (i) {
+ case 0:
+ case 1:
+ lcd_putc(60+i*(5*FW)+2*FW+2, 6*FH-2, g_model.potPosition[i] > (getValue(MIXSRC_FIRST_POT+i) >> 3) ? 126 : 127);
+ break;
+ case 2:
+ case 3:
+ lcd_putc(60+i*(5*FW)+2*FW+2, 6*FH-2, g_model.potPosition[i] > (getValue(MIXSRC_FIRST_POT+i) >> 3) ? '\300' : '\301');
+ break;
+ }
+ flags = INVERS;
+ }
+ lcd_putsiAtt(60+i*(5*FW), 6*FH-2, STR_VSRCRAW, NUM_STICKS+1+i, flags);
+ }
+ }
+ }
+ last_bad_pots = bad_pots;
+#else
if (last_bad_switches != switches_states) {
MESSAGE(STR_SWITCHWARN, NULL, STR_PRESSANYKEYTOSKIP, last_bad_switches == 0xff ? AU_SWITCH_ALERT : AU_NONE);
-#if defined(PCBTARANIS)
- for (uint8_t i=0; i> (1+i*2)];
- lcd_putcAtt(60+i*(2*FW+FW/2), 5*FH, 'A'+i, attr);
- lcd_putcAtt(60+i*(2*FW+FW/2)+FW, 5*FH, c, attr);
- }
-#else
uint8_t x = 2;
- for (uint8_t i=1; i2?(i+1):1+((states>>1)&0x3)), attr);
- if (i == 1 && attr) i++;
- if (i != 1) x += 3*FW+FW/2;
+ for (uint8_t i=0; i0?(i+3):(states&0x3)+1), attr);
+ x += 3*FW+FW/2;
}
#endif
lcdRefresh();
@@ -4294,8 +4365,10 @@ void opentxClose()
hapticOff();
#endif
+ saveTimers();
+
#if defined(CPUARM) && defined(FRSKY)
- if((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) {
+ if ((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) {
g_model.frsky.storedMah = frskyData.hub.currentConsumption;
eeDirty(EE_MODEL);
}
@@ -4305,20 +4378,24 @@ void opentxClose()
}
#endif
- saveTimers();
-
#if defined(PCBSKY9X)
uint32_t mAhUsed = g_eeGeneral.mAhUsed + Current_used * (488 + g_eeGeneral.currentCalib) / 8192 / 36;
- if (g_eeGeneral.mAhUsed != mAhUsed)
+ if (g_eeGeneral.mAhUsed != mAhUsed) {
g_eeGeneral.mAhUsed = mAhUsed;
+ }
#endif
-#if defined(CPUARM) && !defined(REVA)
- if (sessionTimer > 0)
- g_eeGeneral.globalTimer += sessionTimer;
+#if defined(PCBTARANIS)
+ if ((g_model.nPotsToWarn >> 6) == 2) {
+ for (uint8_t i=0; i> 3;
+ eeDirty(EE_MODEL);
+ }
#endif
g_eeGeneral.unexpectedShutdown = 0;
+
eeDirty(EE_GENERAL);
eeCheck(true);
}
@@ -4909,6 +4986,12 @@ void saveTimers()
}
}
}
+
+#if defined(CPUARM) && !defined(REVA)
+ if (sessionTimer > 0) {
+ g_eeGeneral.globalTimer += sessionTimer;
+ }
+#endif
}
#endif
diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp
index a5d0ba320..786c0c059 100644
--- a/radio/src/translations.cpp
+++ b/radio/src/translations.cpp
@@ -494,6 +494,8 @@ const pm_char STR_VIEW_TEXT[] PROGMEM = "View text";
const pm_char STR_SCALE[] PROGMEM = "Scale";
const pm_char STR_VIEW_CHANNELS[] PROGMEM = "View Channels";
const pm_char STR_VIEW_NOTES[] PROGMEM = "View Notes";
+ const pm_char STR_POTWARNING[] PROGMEM = TR_POTWARNING;
+ const pm_char STR_CHECKLIST[] PROGMEM = TR_CHECKLIST;
const pm_char STR_UART3MODE[] PROGMEM = TR_UART3MODE;
const pm_char STR_POT1TYPE[] PROGMEM = TR_POT1TYPE;
const pm_char STR_POT2TYPE[] PROGMEM = TR_POT2TYPE;
diff --git a/radio/src/translations.h b/radio/src/translations.h
index 7b60be0e1..ceeda44b7 100644
--- a/radio/src/translations.h
+++ b/radio/src/translations.h
@@ -682,6 +682,8 @@ extern const pm_char STR_VIEW_TEXT[];
extern const pm_char STR_SCALE[];
extern const pm_char STR_VIEW_CHANNELS[];
extern const pm_char STR_VIEW_NOTES[];
+ extern const pm_char STR_POTWARNING[];
+ extern const pm_char STR_CHECKLIST[];
extern const pm_char STR_UART3MODE[];
extern const pm_char STR_POT1TYPE[];
extern const pm_char STR_POT2TYPE[];
diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt
index 2dab10773..3d718ec79 100644
--- a/radio/src/translations/cz.h.txt
+++ b/radio/src/translations/cz.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "úvodníLogo"
#define TR_THROTTLEWARNING "(\043)Plyn"
#define TR_SWITCHWARNING "(\043)Spínače"
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE "časové pásmo"
#define TR_RXCHANNELORD TR("Pořadí kanálů", "Výchozí pořadí kanálů")
#define TR_SLAVE "Podřízený"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Nízký Alarm"
#define TR_CRITICALALARM INDENT "Kritický Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt
index e6097fcaa..8b0b2d5ec 100644
--- a/radio/src/translations/de.h.txt
+++ b/radio/src/translations/de.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Startbild"
#define TR_THROTTLEWARNING "Gas Alarm"
#define TR_SWITCHWARNING TR("Sch. Alarm","Schalter Alarm")
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE TR("Zeitzone","GPS Zeit Zone")
#define TR_RXCHANNELORD TR("Kanalanordnung","Kanalvoreinstellung")
#define TR_SLAVE "Sch\205ler PPM1-8 als Ausgang"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Kritisch Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h
index 292eb2e52..ed29c91a3 100644
--- a/radio/src/translations/en.h
+++ b/radio/src/translations/en.h
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Splash screen"
#define TR_THROTTLEWARNING TR("T-Warning","Throttle Warning")
#define TR_SWITCHWARNING TR("S-Warning","Switch Warning")
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE TR("Time Zone","GPS Time zone")
#define TR_RXCHANNELORD TR("Rx Channel Ord","Default channel order")
#define TR_SLAVE "Slave"
@@ -611,7 +612,7 @@
#define TR_EEPROMWARN "EEPROM"
#define TR_THROTTLEWARN "THROTTLE"
#define TR_ALARMSWARN "ALARMS"
-#define TR_SWITCHWARN "SWITCH"
+#define TR_SWITCHWARN TR("SWITCH","CONTROL")
#define TR_INVERT_THR TR("Invert Thr?","Invert Throttle?")
#define TR_SPEAKER_VOLUME INDENT "Volume"
#define TR_LCD "LCD"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Critical Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt
index b8d954dfb..6454a1c10 100644
--- a/radio/src/translations/es.h.txt
+++ b/radio/src/translations/es.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Ptalla.inicio"
#define TR_THROTTLEWARNING TR("Aviso-A", "Aviso Acelerador")
#define TR_SWITCHWARNING TR("Aviso-I", "Aviso Intrptor")
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE TR("Zona Hora", "GPS Zona Hora")
#define TR_RXCHANNELORD TR("Rx Orden canal", "Orden habitual canales")
#define TR_SLAVE "Esclavo"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Alarma baja"
#define TR_CRITICALALARM INDENT "Alarma Critica"
#define TR_PERSISTENT_MAH INDENT "Valor mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt
index 57a7a9c22..d568e0ccb 100644
--- a/radio/src/translations/fr.h.txt
+++ b/radio/src/translations/fr.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Logo d'accueil"
#define TR_THROTTLEWARNING "Alerte gaz"
#define TR_SWITCHWARNING TR("Alerte int","Alerte interrupt.")
+#define TR_POTWARNING TR("Alerte pot","Alerte potentiom.")
#define TR_TIMEZONE "Fuseau horaire"
#define TR_RXCHANNELORD TR("Ordre voies RX","Ordre des voies préféré")
#define TR_SLAVE "Elève"
@@ -611,7 +612,7 @@
#define TR_EEPROMWARN "EEPROM"
#define TR_THROTTLEWARN "GAZ"
#define TR_ALARMSWARN "SON"
-#define TR_SWITCHWARN "INTERS"
+#define TR_SWITCHWARN TR("INTERS","CONTROLES")
#define TR_INVERT_THR "Inverser Gaz?"
#define TR_SPEAKER_VOLUME INDENT "Volume"
#define TR_LCD "Afficheur"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Alarme basse"
#define TR_CRITICALALARM INDENT "Alarme critique"
#define TR_PERSISTENT_MAH TR(INDENT "Enr. mAh",INDENT "Enregistrer mAh")
+#define TR_CHECKLIST "Afficher notes"
#define TR_FAS_OFFSET TR(INDENT "Corr FAS", INDENT "Correction FAS")
#define TR_UART3MODE "Port série"
#define TR_POT1TYPE "Type S1"
diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt
index ec58310d9..9a5571c86 100644
--- a/radio/src/translations/it.h.txt
+++ b/radio/src/translations/it.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN TR("Schermo avvio", "Schermata di avvio")
#define TR_THROTTLEWARNING TR("All. Thr", "Allarme Throttle")
#define TR_SWITCHWARNING TR("Avv. Int.", "Avviso Interr.")
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE "Ora locale"
#define TR_RXCHANNELORD "Ordine ch RX"
#define TR_SLAVE "Allievo"
@@ -698,10 +699,11 @@
#define TR_LOWALARM INDENT "Allarme Basso"
#define TR_CRITICALALARM INDENT "Allarme Critico"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
-#define TR_POT2TYPE "S2 Type"
+#define TR_POT2TYPE "S2 Type"
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt
index 0a40f2733..87a6a3627 100644
--- a/radio/src/translations/pl.h.txt
+++ b/radio/src/translations/pl.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Logo ekranu"
#define TR_THROTTLEWARNING "(\043)Gaz"
#define TR_SWITCHWARNING "(\043)Przełącznik"
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE "Strefa czasowa"
#define TR_RXCHANNELORD TR("Kolejność kanałów", "Bazowa kolejność kanałów")
#define TR_SLAVE "Uczeń"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Alarm niski"
#define TR_CRITICALALARM INDENT "Alarm krytyczny"
#define TR_PERSISTENT_MAH INDENT "Zapisz mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Port szreg."
#define TR_POT1TYPE "Typ S1"
diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt
index f38725a5b..41ac94296 100644
--- a/radio/src/translations/pt.h.txt
+++ b/radio/src/translations/pt.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Splash screen"
#define TR_THROTTLEWARNING "Avisa Acel"
#define TR_SWITCHWARNING "Avisa Chav"
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE "Time Zone"
#define TR_RXCHANNELORD "Ordem Canal RX"
#define TR_SLAVE "Escravo"
@@ -697,11 +698,12 @@
#define TR_CHANNELRANGE INDENT "Channel Range"
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Critical Alarm"
-#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serial port"
#define TR_POT1TYPE "S1 Type"
-#define TR_POT2TYPE "S2 Type"
+#define TR_POT2TYPE "S2 Type"
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt
index 3fc70ed7d..5e117d67c 100644
--- a/radio/src/translations/se.h.txt
+++ b/radio/src/translations/se.h.txt
@@ -505,6 +505,7 @@
#define TR_SPLASHSCREEN "Startbild"
#define TR_THROTTLEWARNING "Gasvarning"
#define TR_SWITCHWARNING TR("Bryt.varn.","Brytarvarning")
+#define TR_POTWARNING TR("Pot Warn.","Pot Warning")
#define TR_TIMEZONE TR("Tidszon","GPS Tidszon")
#define TR_RXCHANNELORD "Kanaler i RX"
#define TR_SLAVE "Elev"
@@ -698,6 +699,7 @@
#define TR_LOWALARM INDENT "Låg-alarm"
#define TR_CRITICALALARM INDENT "Kritiskt alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_CHECKLIST "Display Checklist"
#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#define TR_UART3MODE "Serieporten"
#define TR_POT1TYPE "S1-ratten"