Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf0e7c4a44 | |||
| fd2e0e4994 | |||
| be457b40fc | |||
| 41b91d8f5b | |||
| 4f9576b09d | |||
| 04f635404a | |||
| 64dd923e86 | |||
| 051503e75c | |||
| 0520127fe6 | |||
| 9d48dca7a8 | |||
| 426077ed16 | |||
| 81f2b91b91 | |||
| 7ac876af54 | |||
| 147d041b20 | |||
| 45ea2bf559 | |||
| c9fd91e755 | |||
| f2d316b89b | |||
| 0283161f3d | |||
| 87b2a4c0f1 | |||
| 013152cf1f | |||
| 57881edb93 | |||
| 82450c6419 | |||
| 7ad5c1e287 | |||
| 02e9eb3555 | |||
| 7284db8514 | |||
| f7c1888509 | |||
| 3159dd5066 | |||
| 221e3dbdda | |||
| e5b27d3de4 | |||
| f9946dff03 | |||
| 2c2b6e7483 | |||
| 1c16a99d9e | |||
| 0771486e4e | |||
| 4040828e7a | |||
| 66caf7dc79 | |||
| 3decae21b0 | |||
| ff8183fdbb | |||
| f0a5b28ef5 | |||
| b814373391 | |||
| c059e9affb | |||
| 0dee1c207f | |||
| cbcf06964e | |||
| 9285985ff8 | |||
| 415ae55a93 | |||
| 526c88dbe8 | |||
| 5ccdbeb8f8 | |||
| f91bfb1310 | |||
| 641a382ef3 | |||
| 2b6cf2aa9d | |||
| d476696126 | |||
| 909350dc66 | |||
| e62c552217 | |||
| fc935126b2 | |||
| 3018328ae7 | |||
| eb657d5686 | |||
| fa2bf0afaa | |||
| f481d2f236 | |||
| bdb22c37c6 | |||
| 6aa4bd1c68 | |||
| 9f1a6c85c7 | |||
| 23389081a5 | |||
| 920e856dfd | |||
| 30336ff481 | |||
| eb03c6a054 | |||
| 46218c148e | |||
| 1f557bcda7 | |||
| 19567b099d | |||
| 18e85c4cbb | |||
| ad34c2042e | |||
| 8d96cfa420 | |||
| 0783f728a9 | |||
| 9e1f19a8ed | |||
| 6914b4347a | |||
| 95ea3514e7 | |||
| 7e385b8754 | |||
| b9a518192b | |||
| 70fe6327c9 | |||
| f432a2d4ec | |||
| 7522f97695 | |||
| 674e3a8872 | |||
| f32ff084ad | |||
| 31a651ad1a | |||
| b5cf6a13b0 | |||
| 31924c1a23 | |||
| 73cddc76cf | |||
| 64f66133cb | |||
| 9c135095af | |||
| 18f7586890 | |||
| 8818aba486 | |||
| 042b2498b3 | |||
| 03f6d9ca77 | |||
| 82e2ecb362 | |||
| dadac58103 | |||
| 297f7fa374 | |||
| b7bdefabb3 | |||
| 0cb1221312 | |||
| 00fb68084a | |||
| ac0d710efa | |||
| a29279e995 | |||
| 92bc7e9946 | |||
| 3b2878f88a | |||
| d862a13290 | |||
| 9d9e0b83c4 | |||
| 3fc2a27346 | |||
| e0035aea53 | |||
| 74cd5e3041 | |||
| 3b9391df96 | |||
| 22f0ff4660 | |||
| 02a84d04cd | |||
| edece6f083 | |||
| d65b04d393 | |||
| 57c4b8a4c6 | |||
| 8b74de27d3 | |||
| e726848d83 | |||
| 3d409ba7c0 | |||
| 25fdffc417 | |||
| f83239945c | |||
| ce832b2736 | |||
| 6aa2bd2f83 | |||
| 47f8e6d0b6 | |||
| 0f9ddc736b | |||
| a4a6d27f83 | |||
| 25e60aeb66 | |||
| 5447490fed | |||
| 5a4a8ce43e | |||
| b645c9b03a | |||
| 62b21985a8 | |||
| fbc31db730 | |||
| c86d326869 | |||
| da68fd68c5 | |||
| 89a62f115e | |||
| 47fa885cfa | |||
| 6c3591507f | |||
| b4ceda1a98 | |||
| 27bba73d3c | |||
| f4ccc9023b | |||
| ced0546dd9 | |||
| 367bb54119 | |||
| 88be3ac7a6 | |||
| cb13ad1e8c | |||
| 1bada4d7d6 | |||
| 87675d3baf | |||
| 52226f362a | |||
| 713a99b1a9 | |||
| 2ef2a0cc58 |
+14
@@ -0,0 +1,14 @@
|
||||
language: cpp
|
||||
|
||||
before_install:
|
||||
- sudo apt-get remove cmake cmake-data --yes
|
||||
- sudo add-apt-repository ppa:george-edison55/precise-backports --yes
|
||||
- sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded --yes
|
||||
- sudo apt-get update
|
||||
|
||||
install:
|
||||
- sudo apt-get install -y lcov cmake cmake-data bc curl gcc-arm-none-eabi gcc-avr avr-libc avrdude libqtcore4 libqt4-dev qt4-qmake g++ libxerces-c-dev xsdcxx libsdl1.2-dev libusb-1.0-0 libphonon-dev phonon libqtwebkit-dev python-qt4 python-qt4-dev libfox-1.6-dev libgtest-dev
|
||||
|
||||
script:
|
||||
- radio/util/commit-tests.sh
|
||||
- mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug ../companion/src && cmake --build .
|
||||
+40
-6
@@ -173,12 +173,12 @@ Keith Hertzog
|
||||
Johan Moelich
|
||||
Timo Esser
|
||||
Dean Church (monthly)
|
||||
Brian Paddock (monthly)
|
||||
Brian Paddock
|
||||
Jean Pierre Parisy
|
||||
Norbert Martsch
|
||||
Jean-Marie Guitard
|
||||
Mike Perkins
|
||||
Tilman Baumann (monthly)
|
||||
Tilman Baumann
|
||||
Fred Larssen
|
||||
Ari Aalto
|
||||
Robert Sams
|
||||
@@ -189,7 +189,7 @@ Paul Robinson
|
||||
Dave Matison
|
||||
Mike Matheny
|
||||
Pino Agostino
|
||||
Graham Boucher (monthly)
|
||||
Graham Boucher
|
||||
Nelson Noura
|
||||
Joel Allamy
|
||||
Philip David Martin
|
||||
@@ -200,7 +200,7 @@ Timothy Pelletier
|
||||
Glen Roe (ShowMaster)
|
||||
Jan Van Ooteghem
|
||||
David Ankers - Special thanks here to the OpenPilot project!
|
||||
Lawrence Christensen (monthly)
|
||||
Lawrence Christensen
|
||||
Leo Duflou
|
||||
Bruce Wood
|
||||
Arnd Feige
|
||||
@@ -259,7 +259,7 @@ Peter Mitrik
|
||||
Thomas Majewski
|
||||
ANF King
|
||||
Henrik Hammarström
|
||||
Kenneth Lilja (monthly)
|
||||
Kenneth Lilja
|
||||
R Wells
|
||||
Uwe Jordt
|
||||
Harald Wilczak
|
||||
@@ -600,7 +600,7 @@ Michel Baily
|
||||
Donald Burke
|
||||
Ronald Donker
|
||||
Fredie Singh
|
||||
Patrizio Simoncini (monthly)
|
||||
Patrizio Simoncini
|
||||
Harald Gabler
|
||||
Michael Brown
|
||||
Julien Gérard
|
||||
@@ -748,3 +748,37 @@ John Lipscomb
|
||||
Peter Glassey
|
||||
Joseph Kramer
|
||||
F.Javier Martinez Velasco
|
||||
Claudio Piccinini
|
||||
John Jackson
|
||||
John Beech
|
||||
Rene Traa
|
||||
Sebastien Charpentier (monthly)
|
||||
Nigel Hendriks
|
||||
Frédéric Devillard
|
||||
Albert Herzog
|
||||
Anindya Mukerjee
|
||||
Kenny Stanberry
|
||||
Tauno Rautakorpi
|
||||
Mathias Krapp
|
||||
Fernando Rimoldi
|
||||
Wolfgang Rauser
|
||||
Richard Shagam
|
||||
Stephen Bailey
|
||||
DK-System
|
||||
Casa Kuxtal
|
||||
Alain Labonne
|
||||
Christopher Potts
|
||||
Douglas George
|
||||
Michael Banks
|
||||
Jon Wiltshire
|
||||
David Green
|
||||
Guy Willems
|
||||
Xavier Mestelan Pinon
|
||||
Maik Gottschalk
|
||||
Scott Sparks
|
||||
John Dunning
|
||||
RAD51
|
||||
Ron Powell
|
||||
Alain Labonne
|
||||
Carol Sills
|
||||
Franck Aßmann
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
##OpenTX Master Branch
|
||||
##OpenTX 2.0 Branch
|
||||
|
||||
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 ongoing development is not done in this branch. It is performed in the branch called next.
|
||||
The ongoing development is not done in this branch. It is performed in the branches `master` and/or `next`. This branch is used for bug fixes of OpenTX 2.0.x series.
|
||||
|
||||
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,38 @@
|
||||
<h2>Version 2.0.19 / 2016-01-15</h2>
|
||||
<ul>
|
||||
<li>Throttle Source combobox was populated multiple times (<a href=https://github.com/opentx/opentx/issues/3222>#3222</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.18 / 2016-01-03</h2>
|
||||
<ul>
|
||||
<li>Enabled <i>Mixers monitor</i> in Taranis simulator</li>
|
||||
<li>Better support for multi-axes in Log Viewer (<a href=https://github.com/opentx/opentx/issues/2267>#2267</a>)</li>
|
||||
<li>File path issue in Taranis simulator function <i>findTrueFileName()</i> on Windows (<a href=https://github.com/opentx/opentx/issues/2301>#2301</a>)</li>
|
||||
<li>Added simulator volume gain setting (<a href=https://github.com/opentx/opentx/issues/2260>#2260</a>)</li>
|
||||
<li>Added GPS glitch filtering and Latitude/Longitude position synchronization to Google Earth export (<a href=https://github.com/opentx/opentx/issues/2326>#2326</a>)</li>
|
||||
<li>Fixed a rare program crash when editing Input for 9X radio (<a href=https://github.com/opentx/opentx/issues/2420>#2420</a>)</li>
|
||||
<li>Fixed missing RSSI audio warnings if simulator was started multiple times (<a href=https://github.com/opentx/opentx/issues/2446>#2446</a>)</li>
|
||||
<li>EU-only firmware option added</li>
|
||||
<li>Joystick channel mapping bug fixed (<a href=https://github.com/opentx/opentx/issues/1732>#1732</a>)</li>
|
||||
<li>Physical switches were missing from Adjust Volume special function sources (<a href=https://github.com/opentx/opentx/issues/2414>#2414</a>)</li>
|
||||
<li>Fixed a rare program crash: input name buffer overflow (<a href=https://github.com/opentx/opentx/issues/2420>#2420</a>)</li>
|
||||
<li>Alarms did not work if user started radio simulation several times (<a href=https://github.com/opentx/opentx/issues/2446>#2446</a>)</li>
|
||||
<li>Fixed endless loop in model compare (<a href=https://github.com/opentx/opentx/issues/2734>#2734</a>)</li>
|
||||
<li>Prevent user from opening 2.1 or higher EEPE (<a href=https://github.com/opentx/opentx/issues/2620>#2620</a>)</li>
|
||||
<li>Center beep checkbook for P3 was missing for some radios (<a href=https://github.com/opentx/opentx/issues/2707>#2707</a>)</li>
|
||||
<li>Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
|
||||
Users with such setups are advised to re-check their failsafe settings (<a href=https://github.com/opentx/opentx/issues/2975>#2975</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Version 2.0.17 / 2015-05-04</h2>
|
||||
<ul>
|
||||
<li>Simulator crash (<a href=https://github.com/opentx/opentx/issues/2253>#2253</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.16 / 2015-05-03</h2>
|
||||
<ul>
|
||||
<li><i>nooverridech</i> firmware option was not working</li>
|
||||
|
||||
@@ -2,7 +2,7 @@ PROJECT( companion )
|
||||
|
||||
SET( C9X_VERSION_MAJOR "2" )
|
||||
SET( C9X_VERSION_MINOR "0" )
|
||||
SET( C9X_VERSION_REVISION "16" )
|
||||
SET( C9X_VERSION_REVISION "19" )
|
||||
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
@@ -38,7 +38,7 @@ ELSE()
|
||||
MESSAGE( "SDL not found! Joysticks support will be disabled. Simulator audio will not work." )
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(Qt4 4.8.4 REQUIRED)
|
||||
FIND_PACKAGE(Qt4 4.8.1 REQUIRED)
|
||||
SET( QT_USE_QTNETWORK True )
|
||||
SET( QT_USE_QTXML True )
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
@@ -283,11 +283,7 @@ ELSE( )
|
||||
ADD_EXECUTABLE(companion WIN32 ${companion_SRCS} ${companion_QM})
|
||||
ENDIF( )
|
||||
|
||||
if(SDL_FOUND)
|
||||
target_link_libraries(companion modeledit simulation common qcustomplot ${QT_LIBRARIES} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
else()
|
||||
target_link_libraries(companion modeledit simulation common qcustomplot ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
endif()
|
||||
target_link_libraries(companion modeledit simulation common qcustomplot ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
|
||||
############# Standalone simu ###############
|
||||
|
||||
@@ -348,11 +344,7 @@ 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})
|
||||
else()
|
||||
target_link_libraries(simulator simulation common ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS})
|
||||
endif()
|
||||
target_link_libraries(simulator simulation common ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS})
|
||||
|
||||
############# Packaging ####################
|
||||
|
||||
|
||||
@@ -295,6 +295,7 @@ QString Profile::fwName() const { return _fwName; }
|
||||
QString Profile::fwType() const { return _fwType; }
|
||||
QString Profile::name() const { return _name; }
|
||||
QString Profile::sdPath() const { return _sdPath; }
|
||||
int Profile::volumeGain() const { return _volumeGain; }
|
||||
QString Profile::pBackupDir() const { return _pBackupDir; }
|
||||
QString Profile::splashFile() const { return _splashFile; }
|
||||
bool Profile::burnFirmware() const { return _burnFirmware; }
|
||||
@@ -324,6 +325,7 @@ void Profile::name (const QString x) { store(x, _name, "Name"
|
||||
void Profile::fwName (const QString x) { store(x, _fwName, "fwName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::fwType (const QString x) { store(x, _fwType, "fwType" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::sdPath (const QString x) { store(x, _sdPath, "sdPath" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::volumeGain (const int x) { store(x, _volumeGain, "volumeGain" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::pBackupDir (const QString x) { store(x, _pBackupDir, "pBackupDir" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::splashFile (const QString x) { store(x, _splashFile, "SplashFileName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::burnFirmware (const bool x) { store(x, _burnFirmware, "burnFirmware" ,"Profiles", QString("profile%1").arg(index));}
|
||||
@@ -361,6 +363,7 @@ Profile& Profile::operator=(const Profile& rhs)
|
||||
fwName ( rhs.fwName() );
|
||||
fwType ( rhs.fwType() );
|
||||
sdPath ( rhs.sdPath() );
|
||||
volumeGain ( rhs.volumeGain() );
|
||||
pBackupDir ( rhs.pBackupDir() );
|
||||
splashFile ( rhs.splashFile() );
|
||||
burnFirmware ( rhs.burnFirmware() );
|
||||
@@ -438,6 +441,7 @@ void Profile::init(int newIndex)
|
||||
_fwType = "";
|
||||
_name = "";
|
||||
_sdPath = "";
|
||||
_volumeGain = 10;
|
||||
_pBackupDir = "";
|
||||
_splashFile = "";
|
||||
_burnFirmware = false;
|
||||
@@ -462,6 +466,7 @@ void Profile::flush()
|
||||
getset( _fwType, "fwType" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _name, "Name" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _sdPath, "sdPath" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _volumeGain, "volumeGain" ,10 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _pBackupDir, "pBackupDir" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _splashFile, "SplashFileName" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _burnFirmware, "burnFirmware" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
|
||||
@@ -107,6 +107,7 @@ class Profile: protected CompStoreObj
|
||||
QString _fwType;
|
||||
QString _name;
|
||||
QString _sdPath;
|
||||
int _volumeGain;
|
||||
QString _pBackupDir;
|
||||
QString _splashFile;
|
||||
bool _burnFirmware;
|
||||
@@ -138,6 +139,7 @@ class Profile: protected CompStoreObj
|
||||
QString fwType() const;
|
||||
QString name() const;
|
||||
QString sdPath() const;
|
||||
int volumeGain() const;
|
||||
QString pBackupDir() const;
|
||||
QString splashFile() const;
|
||||
bool burnFirmware() const;
|
||||
@@ -166,6 +168,7 @@ class Profile: protected CompStoreObj
|
||||
void name (const QString);
|
||||
void fwName (const QString);
|
||||
void fwType (const QString);
|
||||
void volumeGain (const int);
|
||||
void sdPath (const QString);
|
||||
void pBackupDir (const QString);
|
||||
void splashFile (const QString);
|
||||
|
||||
@@ -48,6 +48,7 @@ void AppPreferencesDialog::writeValues()
|
||||
g.useWizard(ui->modelWizard_CB->isChecked());
|
||||
g.historySize(ui->historySize->value());
|
||||
g.backLight(ui->backLightColor->currentIndex());
|
||||
g.profile[g.id()].volumeGain(round(ui->volumeGain->value() * 10.0));
|
||||
g.libDir(ui->libraryPath->text());
|
||||
g.gePath(ui->ge_lineedit->text());
|
||||
g.embedSplashes(ui->splashincludeCB->currentIndex());
|
||||
@@ -111,6 +112,7 @@ void AppPreferencesDialog::initSettings()
|
||||
ui->showSplash->setChecked(g.showSplash());
|
||||
ui->historySize->setValue(g.historySize());
|
||||
ui->backLightColor->setCurrentIndex(g.backLight());
|
||||
ui->volumeGain->setValue(g.profile[g.id()].volumeGain() / 10.0);
|
||||
|
||||
if (IS_TARANIS(GetCurrentFirmware()->getBoard())) {
|
||||
ui->backLightColor->setEnabled(false);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>686</width>
|
||||
<height>550</height>
|
||||
<height>619</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -889,49 +889,10 @@ Mode 4:
|
||||
<string>Simulator Settings</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item row="5" column="4">
|
||||
<widget class="QPushButton" name="joystickcalButton">
|
||||
<property name="text">
|
||||
<string>Simulator BackLight</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QCheckBox" name="joystickChkB">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="snapshotPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
<string>Calibrate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -970,6 +931,73 @@ Mode 4:
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Simulator capture folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="snapshotClipboardCKB">
|
||||
<property name="text">
|
||||
<string>Only capture to clipboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QCheckBox" name="joystickChkB">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="joystickCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="snapshotPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
@@ -983,43 +1011,22 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="joystickCB">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4">
|
||||
<widget class="QPushButton" name="joystickcalButton">
|
||||
<property name="text">
|
||||
<string>Calibrate</string>
|
||||
<string>Simulator BackLight</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Simulator capture folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="snapshotPath">
|
||||
<property name="enabled">
|
||||
@@ -1036,13 +1043,6 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="snapshotClipboardCKB">
|
||||
<property name="text">
|
||||
<string>Only capture to clipboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="simuSW">
|
||||
<property name="text">
|
||||
@@ -1050,6 +1050,38 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_volumeGain">
|
||||
<property name="text">
|
||||
<string>Simulator Volume Gain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="volumeGain">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@@ -1058,6 +1090,7 @@ Mode 4:
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>profileNameLE</tabstop>
|
||||
<tabstop>removeProfileButton</tabstop>
|
||||
<tabstop>downloadVerCB</tabstop>
|
||||
<tabstop>langCombo</tabstop>
|
||||
@@ -1067,6 +1100,9 @@ Mode 4:
|
||||
<tabstop>clearImageButton</tabstop>
|
||||
<tabstop>sdPath</tabstop>
|
||||
<tabstop>sdPathButton</tabstop>
|
||||
<tabstop>profilebackupPath</tabstop>
|
||||
<tabstop>ProfilebackupPathButton</tabstop>
|
||||
<tabstop>pbackupEnable</tabstop>
|
||||
<tabstop>stickmodeCB</tabstop>
|
||||
<tabstop>channelorderCB</tabstop>
|
||||
<tabstop>renameFirmware</tabstop>
|
||||
@@ -1092,6 +1128,7 @@ Mode 4:
|
||||
<tabstop>joystickCB</tabstop>
|
||||
<tabstop>joystickChkB</tabstop>
|
||||
<tabstop>joystickcalButton</tabstop>
|
||||
<tabstop>volumeGain</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
||||
@@ -108,7 +108,7 @@ burnDialog::burnDialog(QWidget *parent, int Type, QString * fileName, bool * bac
|
||||
}
|
||||
}
|
||||
ui->FWFileName->hide();
|
||||
ui->FlashLoadButton->hide();
|
||||
ui->FlashLoadButton->hide();
|
||||
hexfileName->clear();
|
||||
}
|
||||
else if (Type==FLASH_FILE_TYPE) {
|
||||
@@ -168,7 +168,7 @@ void burnDialog::on_FlashLoadButton_clicked()
|
||||
ui->patchcalib_CB->setChecked(false);
|
||||
ui->patchhw_CB->setChecked(false);
|
||||
ui->patchhw_CB->hide();
|
||||
ui->patchcalib_CB->hide();
|
||||
ui->patchcalib_CB->hide();
|
||||
}
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
}
|
||||
@@ -205,7 +205,7 @@ void burnDialog::checkFw(QString fileName)
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Warning"), tr("%1 may not be a valid firmware file").arg(fileName));
|
||||
}
|
||||
}
|
||||
ui->BurnFlashButton->setEnabled(true);
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
g.flashDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
@@ -238,16 +238,17 @@ bool burnDialog::checkeEprom(QString fileName)
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
|
||||
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
|
||||
bool xmlOK = doc.setContent(&file);
|
||||
if(xmlOK) {
|
||||
if (!LoadEepromXml(radioData, doc)){
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEepromXml(radioData, doc));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
file.reset();
|
||||
|
||||
|
||||
QTextStream inputStream(&file);
|
||||
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
|
||||
QString hline = inputStream.readLine();
|
||||
@@ -268,7 +269,9 @@ bool burnDialog::checkeEprom(QString fileName)
|
||||
return true;
|
||||
}
|
||||
file.close();
|
||||
if (!LoadEeprom(radioData, eeprom, eeprom_size)) {
|
||||
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(radioData, eeprom, eeprom_size));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
int res = QMessageBox::question(this, "Companion",tr("Invalid binary Models and Settings File %1, Proceed anyway ?").arg(fileName),QMessageBox::Yes | QMessageBox::No);
|
||||
if (res == QMessageBox::No) {
|
||||
return false;
|
||||
@@ -292,7 +295,9 @@ bool burnDialog::checkeEprom(QString fileName)
|
||||
QMessageBox::critical(this, tr("Error"),tr("Error reading file %1:\n%2.").arg(fileName).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
if (!LoadEeprom(radioData, eeprom, eeprom_size)) {
|
||||
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(radioData, eeprom, eeprom_size));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
int res = QMessageBox::question(this, "Companion",tr("Invalid binary Models and Settings File %1, Proceed anyway ?").arg(fileName),QMessageBox::Yes | QMessageBox::No);
|
||||
if (res == QMessageBox::No) {
|
||||
return false;
|
||||
@@ -329,7 +334,7 @@ void burnDialog::updateUI()
|
||||
ui->useFwImageCB->setChecked( imageSource == FIRMWARE );
|
||||
ui->useLibraryImageCB->setChecked( imageSource == LIBRARY );
|
||||
ui->useAnotherImageCB->setChecked( imageSource == ANOTHER );
|
||||
|
||||
|
||||
displaySplash();
|
||||
}
|
||||
|
||||
@@ -384,7 +389,7 @@ void burnDialog::on_useAnotherImageCB_clicked()
|
||||
else{
|
||||
imageSource = ANOTHER;
|
||||
imageFile = fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateUI();
|
||||
}
|
||||
@@ -450,7 +455,7 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
}
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Warning"), tr("No firmware selected"));
|
||||
hexfileName->clear();
|
||||
hexfileName->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +468,7 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
int8_t PPM_Multiplier=(int8_t) g.profile[g.id()].ppmMultiplier();
|
||||
uint8_t GSStickMode=(uint8_t) g.profile[g.id()].gsStickMode();
|
||||
uint8_t vBatWarn=(uint8_t) g.profile[g.id()].vBatWarn();
|
||||
|
||||
|
||||
QString DisplaySet= g.profile[g.id()].display();
|
||||
QString BeeperSet= g.profile[g.id()].beeper();
|
||||
QString HapticSet= g.profile[g.id()].haptic();
|
||||
@@ -557,7 +562,7 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Warning"), tr("Wrong radio setting data in profile, Settings not patched"));
|
||||
}
|
||||
|
||||
|
||||
if (patch) {
|
||||
QString fileName = generateProcessUniqueTempFileName("temp.bin");
|
||||
QFile file(fileName);
|
||||
@@ -586,12 +591,12 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
}
|
||||
else {
|
||||
hexfileName->clear();
|
||||
hexfileName->append(ui->FWFileName->text());
|
||||
hexfileName->append(ui->FWFileName->text());
|
||||
}
|
||||
}
|
||||
else {
|
||||
hexfileName->clear();
|
||||
hexfileName->append(ui->FWFileName->text());
|
||||
hexfileName->append(ui->FWFileName->text());
|
||||
}
|
||||
}
|
||||
this->close();
|
||||
@@ -599,8 +604,8 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
|
||||
void burnDialog::on_cancelButton_clicked()
|
||||
{
|
||||
hexfileName->clear();
|
||||
this->close();
|
||||
hexfileName->clear();
|
||||
this->close();
|
||||
}
|
||||
|
||||
void burnDialog::on_EEpromCB_toggled(bool checked)
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <iostream>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
#endif
|
||||
#include "mainwindow.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
@@ -1088,11 +1088,11 @@ void CompareDialog::printCurves()
|
||||
painter2.drawLine(0,ISIZE/2,ISIZE,ISIZE/2);
|
||||
painter1.drawLine(ISIZE/2,0,ISIZE/2,ISIZE);
|
||||
painter2.drawLine(ISIZE/2,0,ISIZE/2,ISIZE);
|
||||
for(i=0; i<21; i++) {
|
||||
painter1.drawLine(ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5,(ISIZE*i)/(20));
|
||||
painter2.drawLine(ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5,(ISIZE*i)/(20));
|
||||
painter1.drawLine((ISIZE*i)/(20),ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5);
|
||||
painter2.drawLine((ISIZE*i)/(20),ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5);
|
||||
for(int k=0; k<21; k++) {
|
||||
painter1.drawLine(ISIZE/2-5,(ISIZE*k)/(20),ISIZE/2+5,(ISIZE*k)/(20));
|
||||
painter2.drawLine(ISIZE/2-5,(ISIZE*k)/(20),ISIZE/2+5,(ISIZE*k)/(20));
|
||||
painter1.drawLine((ISIZE*k)/(20),ISIZE/2-5,(ISIZE*k)/(20),ISIZE/2+5);
|
||||
painter2.drawLine((ISIZE*k)/(20),ISIZE/2-5,(ISIZE*k)/(20),ISIZE/2+5);
|
||||
}
|
||||
|
||||
cm1y.append("]");
|
||||
|
||||
@@ -366,7 +366,7 @@ QString RawSource::toString(const ModelData & model)
|
||||
QObject::tr("L21"), QObject::tr("L22"), QObject::tr("L23"), QObject::tr("L24"), QObject::tr("L25"), QObject::tr("L26"), QObject::tr("L27"), QObject::tr("L28"), QObject::tr("L29"), QObject::tr("L30"),
|
||||
QObject::tr("L31"), QObject::tr("L32")
|
||||
};
|
||||
|
||||
|
||||
if (index<0) {
|
||||
return QObject::tr("----");
|
||||
}
|
||||
@@ -402,7 +402,7 @@ QString RawSource::toString(const ModelData & model)
|
||||
case SOURCE_TYPE_TELEMETRY:
|
||||
return CHECK_IN_ARRAY(telemetry, index);
|
||||
case SOURCE_TYPE_GVAR:
|
||||
return QObject::tr("GV%1").arg(index+1);
|
||||
return QObject::tr("GV%1").arg(index+1);
|
||||
default:
|
||||
return QObject::tr("----");
|
||||
}
|
||||
@@ -1155,7 +1155,7 @@ void ModelData::clear()
|
||||
}
|
||||
else {
|
||||
moduleData[0].protocol=PPM;
|
||||
moduleData[1].protocol=OFF;
|
||||
moduleData[1].protocol=OFF;
|
||||
}
|
||||
for (int i=0; i<C9X_MAX_FLIGHT_MODES; i++) {
|
||||
flightModeData[i].clear();
|
||||
@@ -1336,7 +1336,7 @@ void RegisterEepromInterfaces()
|
||||
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_SKY9X));
|
||||
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_9XRPRO));
|
||||
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS));
|
||||
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_PLUS));
|
||||
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_PLUS));
|
||||
eepromInterfaces.push_back(new Gruvin9xInterface(BOARD_STOCK));
|
||||
eepromInterfaces.push_back(new Gruvin9xInterface(BOARD_GRUVIN9X));
|
||||
eepromInterfaces.push_back(new Ersky9xInterface());
|
||||
@@ -1349,7 +1349,7 @@ void UnregisterEepromInterfaces()
|
||||
foreach(EEPROMInterface * intf, eepromInterfaces) {
|
||||
// qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast<uint64_t>(intf), 16 );
|
||||
delete intf;
|
||||
}
|
||||
}
|
||||
OpenTxEepromCleanup();
|
||||
}
|
||||
|
||||
@@ -1357,42 +1357,119 @@ QList<FirmwareInterface *> firmwares;
|
||||
FirmwareInterface * default_firmware_variant;
|
||||
FirmwareInterface * current_firmware_variant;
|
||||
|
||||
void UnregisterFirmwares()
|
||||
void UnregisterFirmwares()
|
||||
{
|
||||
foreach (FirmwareInterface * f, firmwares) {
|
||||
delete f;
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadEeprom(RadioData &radioData, const uint8_t *eeprom, const int size)
|
||||
void ShowEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound)
|
||||
{
|
||||
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
|
||||
if (eepromInterface->load(radioData, eeprom, size))
|
||||
return true;
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList errorsList;
|
||||
|
||||
errorsList << QT_TRANSLATE_NOOP("EepromInterface", "Possible causes for this:");
|
||||
|
||||
if (errors.test(UNSUPPORTED_NEWER_VERSION)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is from a newer version of OpenTX"); }
|
||||
if (errors.test(NOT_OPENTX)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is not from OpenTX"); }
|
||||
if (errors.test(NOT_TH9X)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is not from Th9X"); }
|
||||
if (errors.test(NOT_GRUVIN9X)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is not from Gruvin9X"); }
|
||||
if (errors.test(NOT_ERSKY9X)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is not from ErSky9X"); }
|
||||
if (errors.test(NOT_ER9X)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is not from Er9X"); }
|
||||
if (errors.test(WRONG_SIZE)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom size is invalid"); }
|
||||
if (errors.test(WRONG_FILE_SYSTEM)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom file system is invalid"); }
|
||||
if (errors.test(UNKNOWN_BOARD)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is from a unknown board"); }
|
||||
if (errors.test(WRONG_BOARD)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom is from the wrong board"); }
|
||||
if (errors.test(BACKUP_NOT_SUPPORTED)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Eeprom backup not supported"); }
|
||||
|
||||
if (errors.test(UNKNOWN_ERROR)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Something that couldn't be guessed, sorry"); }
|
||||
|
||||
if (errors.test(HAS_WARNINGS)) {
|
||||
errorsList << QT_TRANSLATE_NOOP("EepromInterface", "Warning:");
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { errorsList << QT_TRANSLATE_NOOP("EepromInterface", "- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
}
|
||||
|
||||
return false;
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(mainMessage);
|
||||
msgBox.setInformativeText(errorsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
bool LoadBackup(RadioData &radioData, uint8_t *eeprom, int size, int index)
|
||||
void ShowEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList warningsList;
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << QT_TRANSLATE_NOOP("EepromInterface", "- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setText(QT_TRANSLATE_NOOP("EepromInterface", "Warnings!"));
|
||||
msgBox.setInformativeText(warningsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
unsigned long LoadEeprom(RadioData &radioData, const uint8_t *eeprom, const int size)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
|
||||
if (eepromInterface->loadBackup(radioData, eeprom, size, index))
|
||||
return true;
|
||||
std::bitset<NUM_ERRORS> result((unsigned long long)eepromInterface->load(radioData, eeprom, size));
|
||||
if (result.test(NO_ERROR)) {
|
||||
return result.to_ulong();
|
||||
} else {
|
||||
errors |= result;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if (errors.none()) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
}
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long LoadBackup(RadioData &radioData, uint8_t *eeprom, int size, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
|
||||
std::bitset<NUM_ERRORS> result((unsigned long long)eepromInterface->loadBackup(radioData, eeprom, size, index));
|
||||
if (result.test(NO_ERROR)) {
|
||||
return result.to_ulong();
|
||||
} else {
|
||||
errors |= result;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.none()) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
}
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
bool LoadEepromXml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long LoadEepromXml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
|
||||
if (eepromInterface->loadxml(radioData, doc))
|
||||
return true;
|
||||
std::bitset<NUM_ERRORS> result((unsigned long long)eepromInterface->loadxml(radioData, doc));
|
||||
if (result.test(NO_ERROR)) {
|
||||
return result.to_ulong();
|
||||
} else {
|
||||
errors |= result;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if (errors.none()) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
}
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
QString getBoardName(BoardEnum board)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <QtXml>
|
||||
#include <iostream>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#if __GNUC__
|
||||
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
|
||||
#else
|
||||
@@ -1179,11 +1181,11 @@ class EEPROMInterface
|
||||
|
||||
inline BoardEnum getBoard() { return board; }
|
||||
|
||||
virtual bool load(RadioData &radioData, const uint8_t *eeprom, int size) = 0;
|
||||
virtual unsigned long load(RadioData &radioData, const uint8_t *eeprom, int size) = 0;
|
||||
|
||||
virtual bool loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index) = 0;
|
||||
virtual unsigned long loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index) = 0;
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc) = 0;
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc) = 0;
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0) = 0;
|
||||
|
||||
@@ -1305,9 +1307,34 @@ void RegisterEepromInterfaces();
|
||||
void UnregisterFirmwares();
|
||||
void registerOpenTxFirmwares();
|
||||
|
||||
bool LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index);
|
||||
bool LoadEeprom(RadioData &radioData, const uint8_t *eeprom, int size);
|
||||
bool LoadEepromXml(RadioData &radioData, QDomDocument &doc);
|
||||
enum EepromLoadErrors {
|
||||
NO_ERROR,
|
||||
|
||||
UNKNOWN_ERROR,
|
||||
UNSUPPORTED_NEWER_VERSION,
|
||||
WRONG_SIZE,
|
||||
WRONG_FILE_SYSTEM,
|
||||
NOT_OPENTX,
|
||||
NOT_TH9X,
|
||||
NOT_GRUVIN9X,
|
||||
NOT_ERSKY9X,
|
||||
NOT_ER9X,
|
||||
UNKNOWN_BOARD,
|
||||
WRONG_BOARD,
|
||||
BACKUP_NOT_SUPPORTED,
|
||||
|
||||
HAS_WARNINGS,
|
||||
WARNING_WRONG_FIRMWARE,
|
||||
|
||||
NUM_ERRORS
|
||||
};
|
||||
|
||||
void ShowEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound);
|
||||
void ShowEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound);
|
||||
|
||||
unsigned long LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index);
|
||||
unsigned long LoadEeprom(RadioData &radioData, const uint8_t *eeprom, int size);
|
||||
unsigned long LoadEepromXml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
struct Option {
|
||||
const char * name;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -89,14 +89,17 @@ inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying er9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Er9xGeneral er9xGeneral;
|
||||
memset(&er9xGeneral,0,sizeof(er9xGeneral));
|
||||
if(!loadGeneralDataXML(&doc, &er9xGeneral)) {
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
} else {
|
||||
radioData.generalSettings=er9xGeneral;
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
@@ -111,29 +114,35 @@ bool Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying er9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != getEEpromSize()) {
|
||||
std::cout << "wrong size\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
return false;
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Er9xGeneral er9xGeneral;
|
||||
|
||||
if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
@@ -151,16 +160,19 @@ bool Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
break;
|
||||
default:
|
||||
std::cout << "not er9x\n";
|
||||
return false;
|
||||
errors.set(NOT_ER9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
|
||||
}
|
||||
radioData.generalSettings = er9xGeneral;
|
||||
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
@@ -170,16 +182,19 @@ bool Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
else {
|
||||
applyStickModeToModel(er9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Er9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Er9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -29,21 +29,21 @@ class Er9xInterface : public EEPROMInterface
|
||||
virtual ~Er9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual bool load(RadioData &, const uint8_t * eeprom, int size);
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual bool loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t * eeprom, RadioData & radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
virtual int getSize(ModelData &);
|
||||
|
||||
|
||||
virtual int getSize(GeneralSettings &settings);
|
||||
|
||||
virtual int isAvailable(Protocol proto, int port=0);
|
||||
@@ -54,17 +54,17 @@ class Er9xInterface : public EEPROMInterface
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
|
||||
|
||||
void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false);
|
||||
|
||||
|
||||
void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size);
|
||||
|
||||
|
||||
QDomElement getGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); //parse out data to XML format
|
||||
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
|
||||
bool loadGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); // get data from XML
|
||||
|
||||
|
||||
bool loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum = -1); // get data from XML
|
||||
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <QMessageBox>
|
||||
#include "ersky9xinterface.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
#include "ersky9xsimulator.h"
|
||||
@@ -120,14 +119,17 @@ inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mod
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
bool Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying ersky9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
memset(&ersky9xGeneral,0,sizeof(ersky9xGeneral));
|
||||
if(!loadGeneralDataXML(&doc, &ersky9xGeneral)) {
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=ersky9xGeneral;
|
||||
@@ -137,40 +139,48 @@ bool Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
if (ersky9xGeneral.myVers == 10) {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v10>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v11>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying ersky9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != EESIZE_SKY9X) {
|
||||
std::cout << "wrong size\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_SKY9X)) {
|
||||
std::cout << "wrong file system\n";
|
||||
return false;
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
|
||||
if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
@@ -182,21 +192,23 @@ bool Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int siz
|
||||
break;
|
||||
default:
|
||||
std::cout << "not ersky9x\n";
|
||||
return false;
|
||||
errors.set(NOT_ERSKY9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
radioData.generalSettings = ersky9xGeneral;
|
||||
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
uint8_t buffer[4096];
|
||||
uint size;
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
|
||||
|
||||
// if (!efile->readRlc2((uint8_t*)&ersky9xModel, sizeof(Ersky9xModelData))) {
|
||||
size=efile->readRlc2(buffer, 4096);
|
||||
if (!size) {
|
||||
@@ -214,16 +226,19 @@ bool Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int siz
|
||||
applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = ersky9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Ersky9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Ersky9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Ersky9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -29,21 +29,21 @@ class Ersky9xInterface : public EEPROMInterface
|
||||
virtual ~Ersky9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual bool load(RadioData &, const uint8_t * eeprom, int size);
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual bool loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t * eeprom, RadioData & radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
virtual int getSize(ModelData &);
|
||||
|
||||
|
||||
virtual int getSize(GeneralSettings &settings);
|
||||
|
||||
virtual int isAvailable(Protocol proto, int port=0);
|
||||
@@ -54,17 +54,17 @@ class Ersky9xInterface : public EEPROMInterface
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
|
||||
|
||||
void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false);
|
||||
|
||||
|
||||
void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size);
|
||||
|
||||
|
||||
QDomElement getGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); //parse out data to XML format
|
||||
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
|
||||
bool loadGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); // get data from XML
|
||||
|
||||
|
||||
template <class T>
|
||||
bool loadModelDataXML(QDomDocument * qdoc, ModelData * model, int modelNum, int stickMode); // get data from XML
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -93,24 +93,30 @@ bool Gruvin9xInterface::loadGeneral(GeneralSettings &settings, int version)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Gruvin9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long Gruvin9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
bool Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
unsigned long Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying " << getName() << " import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != this->getEEpromSize()) {
|
||||
std::cout << "wrong size\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
return false;
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
@@ -118,14 +124,16 @@ bool Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int si
|
||||
uint8_t version;
|
||||
if (efile->readRlc2(&version, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (efile->readRlc1(&version, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,27 +153,35 @@ bool Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int si
|
||||
break;
|
||||
default:
|
||||
std::cout << "not gruvin9x\n";
|
||||
return false;
|
||||
errors.set(NOT_GRUVIN9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (version == 5) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings, 1))
|
||||
return false;
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings, 1)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else if (version < 104) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings))
|
||||
return false;
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else if (version <= 106) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v104>(radioData.generalSettings))
|
||||
return false;
|
||||
if (!loadGeneral<Gruvin9xGeneral_v104>(radioData.generalSettings)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
if (version == 5) {
|
||||
@@ -185,17 +201,21 @@ bool Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int si
|
||||
}
|
||||
else {
|
||||
std::cout << "ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Gruvin9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Gruvin9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Gruvin9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -30,21 +30,21 @@ class Gruvin9xInterface : public EEPROMInterface
|
||||
virtual ~Gruvin9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual bool load(RadioData &, const uint8_t *eeprom, int size);
|
||||
virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size);
|
||||
|
||||
virtual bool loadBackup(RadioData &, uint8_t *eeprom,int esize, int index);
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom,int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
virtual int getSize(ModelData &);
|
||||
|
||||
|
||||
virtual int getSize(GeneralSettings &settings);
|
||||
|
||||
virtual int isAvailable(Protocol proto, int port=0);
|
||||
|
||||
@@ -183,7 +183,7 @@ void Open9xSky9xSimulator::start(QByteArray & eeprom, bool tests)
|
||||
g_rotenc[0] = 0;
|
||||
memcpy(Open9xSky9x::eeprom, eeprom.data(), std::min<int>(sizeof(Open9xSky9x::eeprom), eeprom.size()));
|
||||
StartEepromThread(NULL);
|
||||
StartAudioThread();
|
||||
StartAudioThread(g.profile[g.id()].volumeGain());
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ void Open9xSky9xSimulator::start(const char * filename, bool tests)
|
||||
{
|
||||
g_rotenc[0] = 0;
|
||||
StartEepromThread(filename);
|
||||
StartAudioThread();
|
||||
StartAudioThread(g.profile[g.id()].volumeGain());
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define OVERRIDE_CHANNEL_FUNCTION
|
||||
#define NUM_POTS 5
|
||||
#define FLAVOUR "taranis-plus"
|
||||
#define MIXERS_MONITOR
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
@@ -223,14 +224,14 @@ void OpentxTaranisSimulator::start(QByteArray & eeprom, bool tests)
|
||||
{
|
||||
memcpy(Open9xX9D::eeprom, eeprom.data(), std::min<int>(sizeof(Open9xX9D::eeprom), eeprom.size()));
|
||||
StartEepromThread(NULL);
|
||||
StartAudioThread();
|
||||
StartAudioThread(g.profile[g.id()].volumeGain());
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::start(const char * filename, bool tests)
|
||||
{
|
||||
StartEepromThread(filename);
|
||||
StartAudioThread();
|
||||
StartAudioThread(g.profile[g.id()].volumeGain());
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,15 +300,19 @@ bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData &model, unsi
|
||||
return (sz == eeprom.size());
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying " << getName() << " import...";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != getEEpromSize()) {
|
||||
if (size==4096) {
|
||||
int notnull=false;
|
||||
@@ -319,21 +323,25 @@ bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, in
|
||||
}
|
||||
if (notnull) {
|
||||
std::cout << " wrong size (" << size << ")\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(NULL, "companion", QObject::tr("Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"));
|
||||
errors.set(HAS_WARNINGS);
|
||||
errors.set(WARNING_WRONG_FIRMWARE);
|
||||
size=2048;
|
||||
}
|
||||
} else {
|
||||
std::cout << " wrong size (" << size << ")\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, board)) {
|
||||
std::cout << " wrong file system\n";
|
||||
return false;
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
@@ -341,30 +349,36 @@ bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, in
|
||||
uint8_t version;
|
||||
if (efile->readRlc2(&version, 1) != 1) {
|
||||
std::cout << " no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " version " << (unsigned int)version;
|
||||
|
||||
if (!checkVersion(version)) {
|
||||
EepromLoadErrors version_error = checkVersion(version);
|
||||
if (version_error != NO_ERROR) {
|
||||
std::cout << " not open9x\n";
|
||||
return false;
|
||||
errors.set(version_error);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!loadGeneral<OpenTxGeneralData>(radioData.generalSettings, version)) {
|
||||
std::cout << " ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " variant " << radioData.generalSettings.variant;
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
if (!loadModel(version, radioData.models[i], NULL, i, radioData.generalSettings.variant, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << " ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
std::cout << " ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int OpenTxEepromInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
@@ -847,7 +861,7 @@ size_t getSizeA(T (&)[SIZE]) {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::checkVersion(unsigned int version)
|
||||
EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
|
||||
{
|
||||
switch(version) {
|
||||
case 201:
|
||||
@@ -908,12 +922,13 @@ bool OpenTxEepromInterface::checkVersion(unsigned int version)
|
||||
break;
|
||||
case 217:
|
||||
// 3 logical switches removed on M128 / gruvin9x boards
|
||||
return UNSUPPORTED_NEWER_VERSION;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
return NOT_OPENTX;
|
||||
}
|
||||
|
||||
return true;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int variant)
|
||||
@@ -938,13 +953,16 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
std::cout << "trying " << getName() << " backup import...";
|
||||
|
||||
if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) {
|
||||
std::cout << " no\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
BoardEnum backupBoard = (BoardEnum)-1;
|
||||
@@ -960,12 +978,14 @@ bool OpenTxEepromInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, in
|
||||
break;
|
||||
default:
|
||||
std::cout << " unknown board\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_BOARD);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (backupBoard != board) {
|
||||
std::cout << " not right board\n";
|
||||
return false;
|
||||
errors.set(WRONG_BOARD);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
uint8_t version = eeprom[4];
|
||||
@@ -975,29 +995,35 @@ bool OpenTxEepromInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, in
|
||||
|
||||
std::cout << " version " << (unsigned int)version << " ";
|
||||
|
||||
if (!checkVersion(version)) {
|
||||
EepromLoadErrors version_error = checkVersion(version);
|
||||
if (version_error != NO_ERROR) {
|
||||
std::cout << " not open9x\n";
|
||||
return false;
|
||||
errors.set(version_error);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (size > esize-8) {
|
||||
std::cout << " wrong size\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (bcktype=='M') {
|
||||
if (!loadModel(version, radioData.models[index], &eeprom[8], size, variant)) {
|
||||
std::cout << " ko\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << " backup type not supported\n";
|
||||
return false;
|
||||
errors.set(BACKUP_NOT_SUPPORTED);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
QString OpenTxFirmware::getFirmwareUrl()
|
||||
@@ -1273,6 +1299,7 @@ void registerOpenTxFirmwares()
|
||||
openTx->addOption("lua", QObject::tr("Support for Lua model scripts"));
|
||||
openTx->addOption("nojoystick", QObject::tr("No Joystick emulation inside the FW (only Mass Storage as in the Bootloader)"));
|
||||
openTx->addOption("mixersmon", QObject::tr("Adds mixers output view to the CHANNELS MONITOR screen, pressing [ENT] switches between the views"));
|
||||
openTx->addOption("eu", QObject::tr("Removes D8 and LR12 FrSky protocols that are not legal for use anymore on radios sold after Jan 1st, 2015"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
@@ -1283,6 +1310,7 @@ void registerOpenTxFirmwares()
|
||||
openTx->addOption("lua", QObject::tr("Support for Lua model scripts"));
|
||||
openTx->addOption("nojoystick", QObject::tr("No Joystick emulation inside the FW (only Mass Storage as in the Bootloader)"));
|
||||
openTx->addOption("mixersmon", QObject::tr("Adds mixers output view to the CHANNELS MONITOR screen, pressing [ENT] switches between the views"));
|
||||
openTx->addOption("eu", QObject::tr("Removes D8 and LR12 FrSky protocols that are not legal for use anymore on radios sold after Jan 1st, 2015"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,25 +34,25 @@ class OpenTxEepromInterface : public EEPROMInterface
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual bool load(RadioData &, const uint8_t *eeprom, int size);
|
||||
virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size);
|
||||
|
||||
virtual bool loadBackup(RadioData &, uint8_t *eeprom, int esize, int index);
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom, int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
virtual int getSize(ModelData &);
|
||||
|
||||
virtual int getSize(GeneralSettings &);
|
||||
|
||||
|
||||
virtual int isAvailable(Protocol proto, int port=0);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const char * getName();
|
||||
|
||||
bool checkVersion(unsigned int version);
|
||||
EepromLoadErrors checkVersion(unsigned int version);
|
||||
|
||||
bool checkVariant(unsigned int version, unsigned int variant);
|
||||
|
||||
@@ -111,7 +111,7 @@ class OpenTxFirmware: public FirmwareInterface {
|
||||
}
|
||||
|
||||
virtual FirmwareInterface * getFirmwareVariant(const QString & id);
|
||||
|
||||
|
||||
virtual QString getStampUrl();
|
||||
|
||||
virtual QString getReleaseNotesUrl();
|
||||
@@ -123,7 +123,7 @@ class OpenTxFirmware: public FirmwareInterface {
|
||||
virtual bool isTelemetrySourceAvailable(int source);
|
||||
|
||||
virtual SimulatorInterface * getSimulator();
|
||||
|
||||
|
||||
};
|
||||
|
||||
void registerOpenTxFirmwares();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -57,31 +57,38 @@ const int Th9xInterface::getMaxModels()
|
||||
return 16;
|
||||
}
|
||||
|
||||
bool Th9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
unsigned long Th9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Th9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
unsigned long Th9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying th9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != getEEpromSize()) {
|
||||
std::cout << "wrong size\n";
|
||||
return false;
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
return false;
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Th9xGeneral th9xGeneral;
|
||||
|
||||
if (efile->readRlc2((uint8_t*)&th9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
return false;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)th9xGeneral.myVers << " ";
|
||||
@@ -91,17 +98,19 @@ bool Th9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
break;
|
||||
default:
|
||||
std::cout << "not th9x\n";
|
||||
return false;
|
||||
errors.set(NOT_TH9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
int len = efile->readRlc2((uint8_t*)&th9xGeneral, sizeof(Th9xGeneral));
|
||||
if (len != sizeof(Th9xGeneral)) {
|
||||
std::cout << "not th9x\n";
|
||||
return false;
|
||||
errors.set(NOT_TH9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
radioData.generalSettings = th9xGeneral;
|
||||
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
Th9xModelData th9xModel;
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
@@ -110,16 +119,19 @@ bool Th9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
}
|
||||
else {
|
||||
radioData.models[i] = th9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
return true;
|
||||
errors.set(NO_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
bool Th9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Th9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Th9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,11 +34,11 @@ class Th9xInterface : public EEPROMInterface
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual bool load(RadioData &, const uint8_t *eeprom, int size);
|
||||
virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size);
|
||||
|
||||
virtual bool loadBackup(RadioData &, uint8_t *eeprom, int esize, int index);
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom, int esize, int index);
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
|
||||
@@ -1097,3 +1097,55 @@ bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
|
||||
{
|
||||
return s1.toLower() < s2.toLower();
|
||||
}
|
||||
|
||||
bool GpsGlitchFilter::isGlitch(double latitude, double longitude)
|
||||
{
|
||||
if ((fabs(latitude) < 0.1) && (fabs(longitude) < 0.1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastValid) {
|
||||
if (fabs(latitude - lastLat) > 0.01) {
|
||||
// qDebug() << "GpsGlitchFilter(): latitude glitch " << latitude << lastLat;
|
||||
if ( ++glitchCount < 10) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (fabs(longitude - lastLon) > 0.01) {
|
||||
// qDebug() << "GpsGlitchFilter(): longitude glitch " << longitude << lastLon;
|
||||
if ( ++glitchCount < 10) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
lastLat = latitude;
|
||||
lastLon = longitude;
|
||||
lastValid = true;
|
||||
glitchCount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpsLatLonFilter::isValid(const QString & latitude, const QString & longitude)
|
||||
{
|
||||
if (lastLat == latitude) {
|
||||
return false;
|
||||
}
|
||||
if (lastLon == longitude) {
|
||||
return false;
|
||||
}
|
||||
lastLat = latitude;
|
||||
lastLon = longitude;
|
||||
return true;
|
||||
}
|
||||
|
||||
double toDecimalCoordinate(const QString & value)
|
||||
{
|
||||
if (value.isEmpty()) return 0.0;
|
||||
double temp = int(value.left(value.length()-1).toDouble() / 100);
|
||||
double result = temp + (value.left(value.length() - 1).toDouble() - temp * 100) / 60.0;
|
||||
QChar direction = value.at(value.size()-1);
|
||||
if ((direction == 'S') || (direction == 'W')) {
|
||||
result = -result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -162,4 +162,31 @@ QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int ma
|
||||
|
||||
bool caseInsensitiveLessThan(const QString &s1, const QString &s2);
|
||||
|
||||
|
||||
class GpsGlitchFilter
|
||||
{
|
||||
public:
|
||||
GpsGlitchFilter() : lastValid(false), glitchCount(0) {};
|
||||
bool isGlitch(double latitude, double longitude);
|
||||
|
||||
private:
|
||||
bool lastValid;
|
||||
int glitchCount;
|
||||
double lastLat;
|
||||
double lastLon;
|
||||
};
|
||||
|
||||
class GpsLatLonFilter
|
||||
{
|
||||
public:
|
||||
GpsLatLonFilter() {};
|
||||
bool isValid(const QString & latitude, const QString & longitude);
|
||||
|
||||
private:
|
||||
QString lastLat;
|
||||
QString lastLon;
|
||||
};
|
||||
|
||||
double toDecimalCoordinate(const QString & value);
|
||||
|
||||
#endif // HELPERS_H
|
||||
|
||||
+358
-197
@@ -46,19 +46,35 @@ logsDialog::logsDialog(QWidget *parent) :
|
||||
ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
|
||||
QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
|
||||
|
||||
ui->customPlot->xAxis->setLabel(tr("Time (hh:mm:ss)"));
|
||||
ui->customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
|
||||
ui->customPlot->xAxis->setDateTimeFormat("hh:mm:ss");
|
||||
axisRect = ui->customPlot->axisRect();
|
||||
axisRect->axis(QCPAxis::atBottom)->setLabel(tr("Time (hh:mm:ss)"));
|
||||
axisRect->axis(QCPAxis::atBottom)->setTickLabelType(QCPAxis::ltDateTime);
|
||||
axisRect->axis(QCPAxis::atBottom)->setDateTimeFormat("hh:mm:ss");
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
ui->customPlot->xAxis->setRange(now.addSecs(-60*60*2).toTime_t(),
|
||||
axisRect->axis(QCPAxis::atBottom)->setRange(now.addSecs(-60*60*2).toTime_t(),
|
||||
now.toTime_t());
|
||||
|
||||
ui->customPlot->yAxis->setTickLabels(false);
|
||||
axisRect->axis(QCPAxis::atLeft)->setTickLabels(false);
|
||||
|
||||
axisRect->addAxis(QCPAxis::atLeft);
|
||||
axisRect->addAxis(QCPAxis::atRight);
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setVisible(false);
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setVisible(false);
|
||||
|
||||
QFont legendFont = font();
|
||||
legendFont.setPointSize(10);
|
||||
ui->customPlot->legend->setFont(legendFont);
|
||||
ui->customPlot->legend->setSelectedFont(legendFont);
|
||||
axisRect->insetLayout()->setInsetAlignment(0, Qt::AlignTop | Qt::AlignLeft);
|
||||
|
||||
rightLegend = new QCPLegend;
|
||||
axisRect->insetLayout()->addElement(rightLegend, Qt::AlignTop | Qt::AlignRight);
|
||||
rightLegend->setLayer("legend");
|
||||
rightLegend->setFont(legendFont);
|
||||
rightLegend->setSelectedFont(legendFont);
|
||||
rightLegend->setVisible(false);
|
||||
|
||||
ui->customPlot->setAutoAddPlottableToLegend(false);
|
||||
|
||||
QString Path=g.gePath();
|
||||
if (Path.isEmpty() || !QFile(Path).exists()) {
|
||||
@@ -72,7 +88,7 @@ logsDialog::logsDialog(QWidget *parent) :
|
||||
connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
|
||||
|
||||
// make left axes transfer its range to right axes:
|
||||
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(setRangeyAxis2(QCPRange)));
|
||||
connect(axisRect->axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChangeRanges(QCPRange)));
|
||||
|
||||
// connect some interaction slots:
|
||||
connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*, QCPPlotTitle*)), this, SLOT(titleDoubleClick(QMouseEvent*, QCPPlotTitle*)));
|
||||
@@ -151,24 +167,43 @@ void logsDialog::selectionChanged()
|
||||
if (plotLock) return;
|
||||
|
||||
// handle bottom axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
if (axisRect->axis(QCPAxis::atBottom)->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
axisRect->axis(QCPAxis::atBottom)->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
{
|
||||
ui->customPlot->xAxis->setSelectedParts(QCPAxis::spAxis |
|
||||
axisRect->axis(QCPAxis::atBottom)->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
}
|
||||
// make left and right axes be selected synchronously,
|
||||
// and handle axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
|
||||
ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
{
|
||||
ui->customPlot->yAxis->setSelectedParts(QCPAxis::spAxis |
|
||||
if (axisRect->axis(QCPAxis::atLeft)->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
axisRect->axis(QCPAxis::atLeft)->selectedParts().testFlag(QCPAxis::spTickLabels) ||
|
||||
(
|
||||
axisRect->axis(QCPAxis::atRight)->visible() &&
|
||||
(axisRect->axis(QCPAxis::atRight)->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
axisRect->axis(QCPAxis::atRight)->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
) || (
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->visible() &&
|
||||
(axisRect->axis(QCPAxis::atLeft, 1)->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
) || (
|
||||
axisRect->axis(QCPAxis::atRight)->visible() &&
|
||||
(axisRect->axis(QCPAxis::atRight, 1)->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
axisRect->axis(QCPAxis::atRight, 1)->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
)
|
||||
) {
|
||||
axisRect->axis(QCPAxis::atLeft)->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
if (hasyAxis2) {
|
||||
ui->customPlot->yAxis2->setSelectedParts(QCPAxis::spAxis |
|
||||
if (axisRect->axis(QCPAxis::atRight)->visible()) {
|
||||
axisRect->axis(QCPAxis::atRight)->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
if (axisRect->axis(QCPAxis::atLeft, 1)->visible()) {
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
if (axisRect->axis(QCPAxis::atRight, 1)->visible()) {
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +212,7 @@ void logsDialog::selectionChanged()
|
||||
{
|
||||
QCPGraph *graph = ui->customPlot->graph(i);
|
||||
QCPPlottableLegendItem *item = ui->customPlot->legend->itemWithPlottable(graph);
|
||||
if (item == NULL) item = rightLegend->itemWithPlottable(graph);
|
||||
if (item->selected() || graph->selected())
|
||||
{
|
||||
item->setSelected(true);
|
||||
@@ -185,38 +221,88 @@ void logsDialog::selectionChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void logsDialog::on_mapsButton_clicked()
|
||||
QList<QStringList> logsDialog::filterGePoints(const QList<QStringList> & input)
|
||||
{
|
||||
int n = csvlog.count(); // number of points in graph
|
||||
if (n==0) return;
|
||||
int latcol=0, longcol=0, altcol=0, speedcol=0;
|
||||
int itemSelected=0.;
|
||||
bool rangeSelected=false;
|
||||
ui->FieldsTW->setDisabled(true);
|
||||
ui->logTable->setDisabled(true);
|
||||
QList<QStringList> result;
|
||||
|
||||
QString gePath=g.gePath();
|
||||
if (gePath.isEmpty() || !QFile(gePath).exists()) {
|
||||
ui->FieldsTW->setDisabled(false);
|
||||
ui->logTable->setDisabled(false);
|
||||
return;
|
||||
int n = input.count();
|
||||
if (n == 0) {
|
||||
return result;
|
||||
}
|
||||
QSet<int> nondataCols;
|
||||
for (int i=1; i<csvlog.at(0).count(); i++) {
|
||||
|
||||
int latcol=0, longcol=0;
|
||||
for (int i=1; i<input.at(0).count(); i++) {
|
||||
//Long,Lat,Course,GPS Speed,GPS Alt
|
||||
if (csvlog.at(0).at(i).contains("Long")) {
|
||||
if (input.at(0).at(i).contains("Long")) {
|
||||
longcol=i;
|
||||
}
|
||||
if (input.at(0).at(i).contains("Lat")) {
|
||||
latcol=i;
|
||||
}
|
||||
}
|
||||
if (longcol==0 || latcol==0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.append(input.at(0));
|
||||
bool rangeSelected = ui->logTable->selectionModel()->selectedRows().length() > 0;
|
||||
|
||||
GpsGlitchFilter glitchFilter;
|
||||
GpsLatLonFilter latLonFilter;
|
||||
|
||||
for (int i = 1; i < n; i++) {
|
||||
if ((ui->logTable->item(i-1, 1)->isSelected() && rangeSelected) || !rangeSelected) {
|
||||
|
||||
QString latitude = input.at(i).at(latcol).trimmed();
|
||||
QString longitude = input.at(i).at(longcol).trimmed();
|
||||
double flatitude = toDecimalCoordinate(latitude);
|
||||
double flongitude = toDecimalCoordinate(longitude);
|
||||
|
||||
// glitch filter
|
||||
if ( glitchFilter.isGlitch(flatitude, flongitude) ) {
|
||||
qDebug() << "filterGePoints(): GPS glitch detected at" << i << flatitude << flongitude;
|
||||
continue;
|
||||
}
|
||||
|
||||
// lat long pair filter
|
||||
if ( !latLonFilter.isValid(latitude, longitude) ) {
|
||||
// qDebug() << "filterGePoints(): Lat-Lon pair wrong, skipping at" << i << latitude << longitude;
|
||||
continue;
|
||||
}
|
||||
|
||||
// qDebug() << "point " << latitude << longitude;
|
||||
result.append(input.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "filterGePoints(): filtered from" << input.count() << "to " << result.count() << "points";
|
||||
return result;
|
||||
}
|
||||
|
||||
void logsDialog::exportToGoogleEarth()
|
||||
{
|
||||
// filter data points
|
||||
QList<QStringList> dataPoints = filterGePoints(csvlog);
|
||||
int n = dataPoints.count(); // number of points to export
|
||||
if (n==0) return;
|
||||
|
||||
int latcol=0, longcol=0, altcol=0, speedcol=0;
|
||||
QSet<int> nondataCols;
|
||||
for (int i=1; i<dataPoints.at(0).count(); i++) {
|
||||
//Long,Lat,Course,GPS Speed,GPS Alt
|
||||
if (dataPoints.at(0).at(i).contains("Long")) {
|
||||
longcol=i;
|
||||
nondataCols << i;
|
||||
}
|
||||
if (csvlog.at(0).at(i).contains("Lat")) {
|
||||
if (dataPoints.at(0).at(i).contains("Lat")) {
|
||||
latcol=i;
|
||||
nondataCols << i;
|
||||
}
|
||||
if (csvlog.at(0).at(i).contains("GPS Alt")) {
|
||||
if (dataPoints.at(0).at(i).contains("GPS Alt")) {
|
||||
altcol=i;
|
||||
nondataCols << i;
|
||||
}
|
||||
if (csvlog.at(0).at(i).contains("GPS Speed")) {
|
||||
if (dataPoints.at(0).at(i).contains("GPS Speed")) {
|
||||
speedcol=i;
|
||||
nondataCols << i;
|
||||
}
|
||||
@@ -224,15 +310,6 @@ void logsDialog::on_mapsButton_clicked()
|
||||
if (longcol==0 || latcol==0 || altcol==0) {
|
||||
return;
|
||||
}
|
||||
for (int i=1; i<n; i++) {
|
||||
if (ui->logTable->item(i-1,1)->isSelected()) {
|
||||
rangeSelected=true;
|
||||
itemSelected++;
|
||||
}
|
||||
}
|
||||
if (itemSelected==0) {
|
||||
itemSelected=n-1;
|
||||
}
|
||||
|
||||
QString geIconFilename = generateProcessUniqueTempFileName("track0.png");
|
||||
if (QFile::exists(geIconFilename)) {
|
||||
@@ -250,25 +327,25 @@ void logsDialog::on_mapsButton_clicked()
|
||||
tr("Cannot write file %1:\n%2.")
|
||||
.arg(geFilename)
|
||||
.arg(geFile.errorString()));
|
||||
ui->FieldsTW->setDisabled(false);
|
||||
ui->logTable->setDisabled(false);
|
||||
return;
|
||||
}
|
||||
QString latitude,longitude;
|
||||
double flatitude, flongitude,temp;
|
||||
|
||||
QTextStream outputStream(&geFile);
|
||||
|
||||
// file header
|
||||
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://" << 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<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://" << 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>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";
|
||||
outputStream << "\t\t<Schema id=\"schema\">\n";
|
||||
outputStream << "\t\t\t<gx:SimpleArrayField name=\"GPSSpeed\" type=\"float\">\n\t\t\t\t<displayName>GPS Speed</displayName>\n\t\t\t</gx:SimpleArrayField>\n";
|
||||
|
||||
// declare additional fields
|
||||
for (int i=0; i<csvlog.at(0).count()-2; i++) {
|
||||
for (int i=0; i<dataPoints.at(0).count()-2; i++) {
|
||||
if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) {
|
||||
QString origName = csvlog.at(0).at(i+2);
|
||||
QString origName = dataPoints.at(0).at(i+2);
|
||||
QString safeName = origName;
|
||||
safeName.replace(" ","_");
|
||||
outputStream << "\t\t\t<gx:SimpleArrayField name=\""<< safeName <<"\" ";
|
||||
@@ -276,7 +353,6 @@ void logsDialog::on_mapsButton_clicked()
|
||||
outputStream << ">\n\t\t\t\t<displayName>" << origName << "</displayName>\n\t\t\t</gx:SimpleArrayField>\n";
|
||||
}
|
||||
}
|
||||
outputStream << "\t\t</Schema>\n";
|
||||
|
||||
QString planeName;
|
||||
if (logFilename.indexOf("-")>0) {
|
||||
@@ -284,60 +360,55 @@ void logsDialog::on_mapsButton_clicked()
|
||||
} else {
|
||||
planeName=logFilename;
|
||||
}
|
||||
|
||||
outputStream << "\t\t</Schema>\n";
|
||||
outputStream << "\t\t<Folder>\n\t\t\t<name>Log Data</name>\n\t\t\t<Placemark>\n\t\t\t\t<name>" << planeName << "</name>";
|
||||
outputStream << "\n\t\t\t\t<styleUrl>#multiTrack</styleUrl>";
|
||||
outputStream << "\n\t\t\t\t<gx:Track>\n";
|
||||
outputStream << "\n\t\t\t\t\t<altitudeMode>absolute</altitudeMode>\n";
|
||||
|
||||
// time data points
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
QString tstamp=csvlog.at(i).at(0)+QString("T")+csvlog.at(i).at(1)+QString("Z");
|
||||
outputStream << "\t\t\t\t\t<when>"<< tstamp <<"</when>\n";
|
||||
}
|
||||
QString tstamp=dataPoints.at(i).at(0)+QString("T")+dataPoints.at(i).at(1)+QString("Z");
|
||||
outputStream << "\t\t\t\t\t<when>"<< tstamp <<"</when>\n";
|
||||
}
|
||||
|
||||
// coordinate data points
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
latitude=csvlog.at(i).at(latcol).trimmed();
|
||||
longitude=csvlog.at(i).at(longcol).trimmed();
|
||||
temp=int(latitude.left(latitude.length()-1).toDouble()/100);
|
||||
flatitude=temp+(latitude.left(latitude.length()-1).toDouble()-temp*100)/60.0;
|
||||
temp=int(longitude.left(longitude.length()-1).toDouble()/100);
|
||||
flongitude=temp+(longitude.left(longitude.length()-1).toDouble()-temp*100)/60.0;
|
||||
if (latitude.right(1)!="N") {
|
||||
flatitude*=-1;
|
||||
}
|
||||
if (longitude.right(1)!="E") {
|
||||
flongitude*=-1;
|
||||
}
|
||||
latitude.sprintf("%3.8f", flatitude);
|
||||
longitude.sprintf("%3.8f", flongitude);
|
||||
outputStream << "\t\t\t\t\t<gx:coord>" << longitude << " " << latitude << " " << csvlog.at(i).at(altcol).toFloat() << " </gx:coord>\n" ;
|
||||
}
|
||||
QString latitude=dataPoints.at(i).at(latcol).trimmed();
|
||||
QString longitude=dataPoints.at(i).at(longcol).trimmed();
|
||||
latitude.sprintf("%3.8f", toDecimalCoordinate(latitude));
|
||||
longitude.sprintf("%3.8f", toDecimalCoordinate(longitude));
|
||||
outputStream << "\t\t\t\t\t<gx:coord>" << longitude << " " << latitude << " " << dataPoints.at(i).at(altcol).toFloat() << " </gx:coord>\n" ;
|
||||
}
|
||||
|
||||
// additional data for data points
|
||||
outputStream << "\t\t\t\t\t<ExtendedData>\n\t\t\t\t\t\t<SchemaData schemaUrl=\"#schema\">\n";
|
||||
|
||||
// gps speed data points
|
||||
outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\"GPSSpeed\">\n";
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< csvlog.at(i).at(speedcol) <<"</gx:value>\n";
|
||||
}
|
||||
outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< dataPoints.at(i).at(speedcol) <<"</gx:value>\n";
|
||||
}
|
||||
outputStream << "\t\t\t\t\t\t\t</gx:SimpleArrayData>\n";
|
||||
|
||||
// add values for additional fields
|
||||
for (int i=0; i<csvlog.at(0).count()-2; i++) {
|
||||
for (int i=0; i<dataPoints.at(0).count()-2; i++) {
|
||||
if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) {
|
||||
QString safeName = csvlog.at(0).at(i+2);;
|
||||
QString safeName = dataPoints.at(0).at(i+2);;
|
||||
safeName.replace(" ","_");
|
||||
outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\""<< safeName <<"\">\n";
|
||||
for (int j=1; j<n; j++) {
|
||||
if ((ui->logTable->item(j-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< csvlog.at(j).at(i+2) <<"</gx:value>\n";
|
||||
}
|
||||
outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< dataPoints.at(j).at(i+2) <<"</gx:value>\n";
|
||||
}
|
||||
outputStream << "\t\t\t\t\t\t\t</gx:SimpleArrayData>\n";
|
||||
}
|
||||
}
|
||||
|
||||
outputStream << "\t\t\t\t\t\t</SchemaData>\n\t\t\t\t\t</ExtendedData>\n\t\t\t\t</gx:Track>\n\t\t\t</Placemark>\n\t\t</Folder>\n\t</Document>\n</kml>";
|
||||
geFile.close();
|
||||
|
||||
QString gePath = g.gePath();
|
||||
QStringList parameters;
|
||||
#ifdef __APPLE__
|
||||
parameters << "-a";
|
||||
@@ -347,22 +418,30 @@ void logsDialog::on_mapsButton_clicked()
|
||||
parameters << geFilename;
|
||||
QProcess *process = new QProcess(this);
|
||||
process->start(gePath, parameters);
|
||||
}
|
||||
|
||||
void logsDialog::on_mapsButton_clicked()
|
||||
{
|
||||
ui->FieldsTW->setDisabled(true);
|
||||
ui->logTable->setDisabled(true);
|
||||
|
||||
exportToGoogleEarth();
|
||||
|
||||
ui->FieldsTW->setDisabled(false);
|
||||
ui->logTable->setDisabled(false);
|
||||
}
|
||||
|
||||
|
||||
void logsDialog::mousePress()
|
||||
{
|
||||
// if an axis is selected, only allow the direction of that axis to be dragged
|
||||
// if no axis is selected, both directions may be dragged
|
||||
|
||||
if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->xAxis->orientation());
|
||||
else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->yAxis->orientation());
|
||||
if (axisRect->axis(QCPAxis::atBottom)->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
axisRect->setRangeDrag(axisRect->axis(QCPAxis::atBottom)->orientation());
|
||||
else if (axisRect->axis(QCPAxis::atLeft)->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
axisRect->setRangeDrag(axisRect->axis(QCPAxis::atLeft)->orientation());
|
||||
else
|
||||
ui->customPlot->axisRect()->setRangeDrag(Qt::Horizontal | Qt::Vertical);
|
||||
axisRect->setRangeDrag(Qt::Horizontal | Qt::Vertical);
|
||||
}
|
||||
|
||||
void logsDialog::mouseWheel()
|
||||
@@ -377,18 +456,9 @@ void logsDialog::mouseWheel()
|
||||
orientation|=Qt::Vertical;
|
||||
}
|
||||
if (orientation) {
|
||||
ui->customPlot->axisRect()->setRangeZoom((Qt::Orientation)orientation);
|
||||
axisRect->setRangeZoom((Qt::Orientation)orientation);
|
||||
} else {
|
||||
ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
void logsDialog::removeSelectedGraph()
|
||||
{
|
||||
if (ui->customPlot->selectedGraphs().size() > 0)
|
||||
{
|
||||
ui->customPlot->removeGraph(ui->customPlot->selectedGraphs().first());
|
||||
ui->customPlot->replot();
|
||||
axisRect->setRangeZoom(Qt::Horizontal|Qt::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,8 +466,17 @@ void logsDialog::removeAllGraphs()
|
||||
{
|
||||
ui->customPlot->clearGraphs();
|
||||
ui->customPlot->legend->setVisible(false);
|
||||
ui->customPlot->yAxis2->setVisible(false);
|
||||
ui->customPlot->yAxis->setTickLabels(false);
|
||||
rightLegend->clearItems();
|
||||
rightLegend->setVisible(false);
|
||||
axisRect->axis(QCPAxis::atRight)->setSelectedParts(QCPAxis::spNone);
|
||||
axisRect->axis(QCPAxis::atRight)->setVisible(false);
|
||||
axisRect->axis(QCPAxis::atLeft)->setSelectedParts(QCPAxis::spNone);
|
||||
axisRect->axis(QCPAxis::atLeft)->setTickLabels(false);
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setVisible(false);
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setSelectedParts(QCPAxis::spNone);
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setVisible(false);
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setSelectedParts(QCPAxis::spNone);
|
||||
axisRect->axis(QCPAxis::atBottom)->setSelectedParts(QCPAxis::spNone);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
|
||||
@@ -525,7 +604,6 @@ bool logsDialog::cvsFileParse()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void logsDialog::on_sessions_CB_currentIndexChanged(int index)
|
||||
{
|
||||
if (plotLock) return;
|
||||
@@ -588,9 +666,9 @@ void logsDialog::plotLogs()
|
||||
coords plotCoords;
|
||||
int plotColumn = plot->row() + 2; // Date and Time first
|
||||
|
||||
plotCoords.min_y = 999999;
|
||||
plotCoords.max_y = -999999;
|
||||
plotCoords.secondRange = false;
|
||||
plotCoords.min_y = INVALID_MIN;
|
||||
plotCoords.max_y = INVALID_MAX;
|
||||
plotCoords.yaxis = firstLeft;
|
||||
plotCoords.name = plot->text();
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
@@ -612,11 +690,8 @@ void logsDialog::plotLogs()
|
||||
y = logValue->text().toDouble();
|
||||
plotCoords.y.push_back(y);
|
||||
|
||||
if (plotCoords.min_y > y) {
|
||||
plotCoords.min_y = y;
|
||||
} else if (plotCoords.max_y < y) {
|
||||
plotCoords.max_y = y;
|
||||
}
|
||||
if (plotCoords.min_y > y) plotCoords.min_y = y;
|
||||
if (plotCoords.max_y < y) plotCoords.max_y = y;
|
||||
|
||||
if (time_str.contains('.')) {
|
||||
time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss.zzz")
|
||||
@@ -628,133 +703,219 @@ void logsDialog::plotLogs()
|
||||
}
|
||||
plotCoords.x.push_back(time);
|
||||
|
||||
if (plots.min_x > time) {
|
||||
plots.min_x = time;
|
||||
} else if (plots.max_x < time) {
|
||||
plots.max_x = time;
|
||||
}
|
||||
if (plots.min_x > time) plots.min_x = time;
|
||||
if (plots.max_x < time) plots.max_x = time;
|
||||
}
|
||||
|
||||
double range_inc = (plotCoords.max_y - plotCoords.min_y) / 100;
|
||||
if (range_inc == 0) range_inc = 1;
|
||||
plotCoords.max_y += range_inc;
|
||||
plotCoords.min_y -= range_inc;
|
||||
|
||||
plots.coords.append(plotCoords);
|
||||
}
|
||||
|
||||
plots.rangeOneMin = plots.coords.at(0).min_y;
|
||||
plots.rangeOneMax = plots.coords.at(0).max_y;
|
||||
plots.twoRanges = false;
|
||||
yAxesRanges[firstLeft].min = plots.coords.at(0).min_y;
|
||||
yAxesRanges[firstLeft].max = plots.coords.at(0).max_y;
|
||||
for (int i = firstRight; i < AXES_LIMIT; i++) {
|
||||
yAxesRanges[i].min = INVALID_MIN;
|
||||
yAxesRanges[i].max = INVALID_MAX;
|
||||
}
|
||||
plots.tooManyRanges = false;
|
||||
|
||||
for (int i = 1; i < plots.coords.size(); i++) {
|
||||
if (plots.tooManyRanges) {
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
double actualRange = plots.rangeOneMax - plots.rangeOneMin;
|
||||
double actualRange = yAxesRanges[firstLeft].max - yAxesRanges[firstLeft].min;
|
||||
double thisRange = plots.coords.at(i).max_y - plots.coords.at(i).min_y;
|
||||
|
||||
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
|
||||
plots.coords.at(i).min_y > plots.rangeOneMax ||
|
||||
plots.coords.at(i).max_y < plots.rangeOneMin) {
|
||||
plots.coords[i].secondRange = true;
|
||||
if (plots.twoRanges) {
|
||||
actualRange = plots.rangeTwoMax - plots.rangeTwoMin;
|
||||
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
|
||||
plots.coords.at(i).min_y > plots.rangeTwoMax ||
|
||||
plots.coords.at(i).max_y < plots.rangeTwoMin) {
|
||||
while (yAxesRanges[plots.coords.at(i).yaxis].max != INVALID_MAX &&
|
||||
(thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
|
||||
plots.coords.at(i).min_y > yAxesRanges[plots.coords.at(i).yaxis].max ||
|
||||
plots.coords.at(i).max_y < yAxesRanges[plots.coords.at(i).yaxis].min)
|
||||
) {
|
||||
|
||||
switch (plots.coords[i].yaxis) {
|
||||
case firstLeft:
|
||||
plots.coords[i].yaxis = firstRight;
|
||||
break;
|
||||
case firstRight:
|
||||
plots.coords[i].yaxis = secondLeft;
|
||||
break;
|
||||
case secondLeft:
|
||||
plots.coords[i].yaxis = secondRight;
|
||||
break;
|
||||
case secondRight:
|
||||
plots.tooManyRanges = true;
|
||||
plots.twoRanges = false;
|
||||
if (plots.rangeTwoMin < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.rangeTwoMin;
|
||||
}
|
||||
if (plots.rangeTwoMax > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.rangeTwoMax;
|
||||
}
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
} else {
|
||||
if (plots.coords.at(i).min_y < plots.rangeTwoMin) {
|
||||
plots.rangeTwoMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeTwoMax) {
|
||||
plots.rangeTwoMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plots.twoRanges = true;
|
||||
plots.rangeTwoMax = plots.coords.at(i).max_y;
|
||||
plots.rangeTwoMin = plots.coords.at(i).min_y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (plots.tooManyRanges) break;
|
||||
|
||||
actualRange = yAxesRanges[plots.coords.at(i).yaxis].max
|
||||
- yAxesRanges[plots.coords.at(i).yaxis].min;
|
||||
}
|
||||
|
||||
if (plots.tooManyRanges) {
|
||||
break;
|
||||
} else {
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
if (plots.coords.at(i).min_y < yAxesRanges[plots.coords.at(i).yaxis].min) {
|
||||
yAxesRanges[plots.coords.at(i).yaxis].min = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
if (plots.coords.at(i).max_y > yAxesRanges[plots.coords.at(i).yaxis].max) {
|
||||
yAxesRanges[plots.coords.at(i).yaxis].max = plots.coords.at(i).max_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plots.twoRanges) {
|
||||
rangeRatio = (plots.rangeTwoMax - plots.rangeTwoMin) /
|
||||
(plots.rangeOneMax - plots.rangeOneMin);
|
||||
rangeyAxisMin = plots.rangeOneMin;
|
||||
rangeyAxisMax = plots.rangeOneMax;
|
||||
rangeyAxis2Min = plots.rangeTwoMin;
|
||||
rangeyAxis2Max = plots.rangeTwoMax;
|
||||
if (plots.tooManyRanges) {
|
||||
yAxesRanges[firstLeft].max = 101;
|
||||
yAxesRanges[firstLeft].min = -1;
|
||||
yAxesRanges[firstRight].max = INVALID_MAX;
|
||||
yAxesRanges[firstRight].min = INVALID_MIN;
|
||||
yAxesRanges[secondLeft].max = INVALID_MAX;
|
||||
yAxesRanges[secondLeft].min = INVALID_MIN;
|
||||
yAxesRanges[secondRight].max = INVALID_MAX;
|
||||
yAxesRanges[secondRight].min = INVALID_MIN;
|
||||
|
||||
hasyAxis2 = true;
|
||||
for (int i = 0; i < plots.coords.size(); i++) {
|
||||
plots.coords[i].yaxis = firstLeft;
|
||||
|
||||
double factor = 100 / (plots.coords.at(i).max_y - plots.coords.at(i).min_y);
|
||||
for (int j = 0; j < plots.coords.at(i).y.count(); j++) {
|
||||
plots.coords[i].y[j] = factor * (plots.coords.at(i).y.at(j) - plots.coords.at(i).min_y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasyAxis2 = false;
|
||||
for (int i = firstRight; i < AXES_LIMIT; i++) {
|
||||
if (yAxesRanges[i].max == INVALID_MAX) break;
|
||||
|
||||
yAxesRatios[i] = (yAxesRanges[i].max - yAxesRanges[i].min) /
|
||||
(yAxesRanges[firstLeft].max - yAxesRanges[firstLeft].min);
|
||||
}
|
||||
}
|
||||
|
||||
removeAllGraphs();
|
||||
|
||||
ui->customPlot->xAxis->setRange(plots.min_x, plots.max_x);
|
||||
axisRect->axis(QCPAxis::atBottom)->setRange(plots.min_x, plots.max_x);
|
||||
|
||||
ui->customPlot->yAxis->setRange(plots.rangeOneMin, plots.rangeOneMax);
|
||||
ui->customPlot->yAxis->setTickLabels(true);
|
||||
axisRect->axis(QCPAxis::atLeft)->setRange(yAxesRanges[firstLeft].min,
|
||||
yAxesRanges[firstLeft].max);
|
||||
|
||||
if (plots.twoRanges) {
|
||||
ui->customPlot->yAxis2->setRange(plots.rangeTwoMin, plots.rangeTwoMax);
|
||||
ui->customPlot->yAxis2->setVisible(true);
|
||||
if (plots.tooManyRanges) {
|
||||
axisRect->axis(QCPAxis::atLeft)->setTickLabels(false);
|
||||
} else {
|
||||
axisRect->axis(QCPAxis::atLeft)->setTickLabels(true);
|
||||
}
|
||||
|
||||
if (yAxesRanges[firstRight].max != INVALID_MAX) {
|
||||
axisRect->axis(QCPAxis::atRight)->setRange(yAxesRanges[firstRight].min,
|
||||
yAxesRanges[firstRight].max);
|
||||
axisRect->axis(QCPAxis::atRight)->setVisible(true);
|
||||
|
||||
rightLegend->setVisible(true);
|
||||
|
||||
if (yAxesRanges[secondLeft].max != INVALID_MAX) {
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setVisible(true);
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setRange(yAxesRanges[secondLeft].min,
|
||||
yAxesRanges[secondLeft].max);
|
||||
|
||||
if (yAxesRanges[secondRight].max != INVALID_MAX) {
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setVisible(true);
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setRange(yAxesRanges[secondRight].min,
|
||||
yAxesRanges[secondRight].max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < plots.coords.size(); i++) {
|
||||
if (plots.coords.at(i).secondRange && plots.twoRanges) {
|
||||
ui->customPlot->addGraph(ui->customPlot->xAxis, ui->customPlot->yAxis2);
|
||||
} else {
|
||||
ui->customPlot->addGraph();
|
||||
switch (plots.coords[i].yaxis) {
|
||||
case firstLeft:
|
||||
ui->customPlot->addGraph();
|
||||
if (yAxesRanges[secondLeft].max != INVALID_MAX) {
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name + tr(" (L1)"));
|
||||
} else {
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name);
|
||||
}
|
||||
ui->customPlot->legend->addItem(
|
||||
new QCPPlottableLegendItem(ui->customPlot->legend, ui->customPlot->graph(i)));
|
||||
break;
|
||||
case firstRight:
|
||||
ui->customPlot->addGraph(axisRect->axis(QCPAxis::atBottom),
|
||||
axisRect->axis(QCPAxis::atRight));
|
||||
if (yAxesRanges[secondRight].max != INVALID_MAX) {
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name + tr(" (R1)"));
|
||||
} else {
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name);
|
||||
}
|
||||
rightLegend->addItem(
|
||||
new QCPPlottableLegendItem(rightLegend, ui->customPlot->graph(i)));
|
||||
break;
|
||||
case secondLeft:
|
||||
ui->customPlot->addGraph(axisRect->axis(QCPAxis::atBottom),
|
||||
axisRect->axis(QCPAxis::atLeft, 1));
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name + tr(" (L2)"));
|
||||
ui->customPlot->legend->addItem(
|
||||
new QCPPlottableLegendItem(ui->customPlot->legend, ui->customPlot->graph(i)));
|
||||
break;
|
||||
case secondRight:
|
||||
ui->customPlot->addGraph(axisRect->axis(QCPAxis::atBottom),
|
||||
axisRect->axis(QCPAxis::atRight, 1));
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name + tr(" (R2)"));
|
||||
rightLegend->addItem(
|
||||
new QCPPlottableLegendItem(rightLegend, ui->customPlot->graph(i)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ui->customPlot->graph(i)->setData(plots.coords.at(i).x,
|
||||
plots.coords.at(i).y);
|
||||
pen.setColor(colors.at(i % colors.size()));
|
||||
ui->customPlot->graph(i)->setPen(pen);
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name);
|
||||
}
|
||||
|
||||
ui->customPlot->legend->setVisible(true);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
|
||||
void logsDialog::setRangeyAxis2(QCPRange range)
|
||||
void logsDialog::yAxisChangeRanges(QCPRange range)
|
||||
{
|
||||
if (hasyAxis2) {
|
||||
double lowerChange = (range.lower - rangeyAxisMin) * rangeRatio;
|
||||
double upperChange = (range.upper - rangeyAxisMax) * rangeRatio;
|
||||
rangeyAxisMin = range.lower;
|
||||
rangeyAxisMax = range.upper;
|
||||
rangeyAxis2Min += lowerChange;
|
||||
rangeyAxis2Max += upperChange;
|
||||
if (axisRect->axis(QCPAxis::atRight)->visible()) {
|
||||
double lowerChange = (range.lower - yAxesRanges[firstLeft].min) *
|
||||
yAxesRatios[firstRight];
|
||||
double upperChange = (range.upper - yAxesRanges[firstLeft].max) *
|
||||
yAxesRatios[firstRight];
|
||||
|
||||
ui->customPlot->yAxis2->setRange(rangeyAxis2Min, rangeyAxis2Max);
|
||||
yAxesRanges[firstRight].min += lowerChange;
|
||||
yAxesRanges[firstRight].max += upperChange;
|
||||
axisRect->axis(QCPAxis::atRight)->setRange(yAxesRanges[firstRight].min,
|
||||
yAxesRanges[firstRight].max);
|
||||
|
||||
if (axisRect->axisCount(QCPAxis::atLeft) == 2) {
|
||||
lowerChange = (range.lower - yAxesRanges[firstLeft].min) *
|
||||
yAxesRatios[secondLeft];
|
||||
upperChange = (range.upper - yAxesRanges[firstLeft].max) *
|
||||
yAxesRatios[secondLeft];
|
||||
|
||||
yAxesRanges[secondLeft].min += lowerChange;
|
||||
yAxesRanges[secondLeft].max += upperChange;
|
||||
axisRect->axis(QCPAxis::atLeft, 1)->setRange(yAxesRanges[secondLeft].min,
|
||||
yAxesRanges[secondLeft].max);
|
||||
|
||||
if (axisRect->axisCount(QCPAxis::atRight) == 2) {
|
||||
lowerChange = (range.lower - yAxesRanges[firstLeft].min) *
|
||||
yAxesRatios[secondRight];
|
||||
upperChange = (range.upper - yAxesRanges[firstLeft].max) *
|
||||
yAxesRatios[secondRight];
|
||||
|
||||
yAxesRanges[secondRight].min += lowerChange;
|
||||
yAxesRanges[secondRight].max += upperChange;
|
||||
axisRect->axis(QCPAxis::atRight, 1)->setRange(yAxesRanges[secondRight].min,
|
||||
yAxesRanges[secondRight].max);
|
||||
}
|
||||
}
|
||||
|
||||
yAxesRanges[firstLeft].min = range.lower;
|
||||
yAxesRanges[firstLeft].max = range.upper;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-15
@@ -5,24 +5,35 @@
|
||||
#include <QtGui>
|
||||
#include "qcustomplot/qcustomplot.h"
|
||||
|
||||
#define INVALID_MIN 999999
|
||||
#define INVALID_MAX -999999
|
||||
|
||||
enum yaxes_t {
|
||||
firstLeft = 0,
|
||||
firstRight,
|
||||
secondLeft,
|
||||
secondRight,
|
||||
AXES_LIMIT // = 4
|
||||
};
|
||||
|
||||
struct coords {
|
||||
QVector<double> x, y;
|
||||
double min_y;
|
||||
double max_y;
|
||||
bool secondRange;
|
||||
yaxes_t yaxis;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct minMax {
|
||||
double min;
|
||||
double max;
|
||||
};
|
||||
|
||||
struct plotsCollection {
|
||||
QVarLengthArray<struct coords> coords;
|
||||
double min_x;
|
||||
double max_x;
|
||||
bool twoRanges;
|
||||
bool tooManyRanges;
|
||||
double rangeOneMin;
|
||||
double rangeOneMax;
|
||||
double rangeTwoMin;
|
||||
double rangeTwoMax;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
@@ -44,30 +55,31 @@ private slots:
|
||||
void selectionChanged();
|
||||
void mousePress();
|
||||
void mouseWheel();
|
||||
void removeSelectedGraph();
|
||||
void removeAllGraphs();
|
||||
void plotLogs();
|
||||
void on_fileOpen_BT_clicked();
|
||||
void on_sessions_CB_currentIndexChanged(int index);
|
||||
void on_mapsButton_clicked();
|
||||
void setRangeyAxis2(QCPRange range);
|
||||
void yAxisChangeRanges(QCPRange range);
|
||||
|
||||
private:
|
||||
QList<QStringList> csvlog;
|
||||
Ui::logsDialog *ui;
|
||||
bool cvsFileParse();
|
||||
QCPAxisRect *axisRect;
|
||||
QCPLegend *rightLegend;
|
||||
bool plotLock;
|
||||
QString logFilename;
|
||||
|
||||
QVarLengthArray<Qt::GlobalColor> colors;
|
||||
QPen pen;
|
||||
|
||||
bool hasyAxis2;
|
||||
double rangeRatio;
|
||||
double rangeyAxisMin;
|
||||
double rangeyAxisMax;
|
||||
double rangeyAxis2Min;
|
||||
double rangeyAxis2Max;
|
||||
double yAxesRatios[AXES_LIMIT];
|
||||
minMax yAxesRanges[AXES_LIMIT];
|
||||
|
||||
bool cvsFileParse();
|
||||
QList<QStringList> filterGePoints(const QList<QStringList> & input);
|
||||
void exportToGoogleEarth();
|
||||
|
||||
};
|
||||
|
||||
#endif // LOGSDIALOG_H
|
||||
|
||||
@@ -110,12 +110,12 @@ MainWindow::MainWindow():
|
||||
this->setIconSize(QSize(32, 32));
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
setAcceptDrops(true);
|
||||
|
||||
|
||||
// give time to the splash to disappear and main window to open before starting updates
|
||||
int updateDelay = 1000;
|
||||
bool showSplash = g.showSplash();
|
||||
if (showSplash) {
|
||||
updateDelay += (SPLASH_TIME*1000);
|
||||
updateDelay += (SPLASH_TIME*1000);
|
||||
}
|
||||
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
|
||||
QTimer::singleShot(updateDelay, this, SLOT(displayWarnings()));
|
||||
@@ -153,13 +153,13 @@ MainWindow::MainWindow():
|
||||
child->show();
|
||||
}
|
||||
else {
|
||||
child->show();
|
||||
child->show();
|
||||
child->print(model,printfilename);
|
||||
child->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printing) {
|
||||
QTimer::singleShot(0, this, SLOT(autoClose()));
|
||||
}
|
||||
@@ -180,7 +180,7 @@ void MainWindow::displayWarnings()
|
||||
}
|
||||
}
|
||||
else if (warnId==0) {
|
||||
g.warningId(WARNING_ID);
|
||||
g.warningId(WARNING_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,10 +193,10 @@ QString MainWindow::getBackupPath() {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!backupEnable) {
|
||||
backupEnable=g.enableBackup();
|
||||
@@ -213,8 +213,8 @@ QString MainWindow::getBackupPath() {
|
||||
if ((g.enableBackup() || g.profile[g.id()].penableBackup()) && !(backupEnable) && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable=false;
|
||||
}
|
||||
@@ -316,15 +316,15 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
int c9xver = version2index(c9xversion);
|
||||
|
||||
if (c9xver < vnum) {
|
||||
#if defined WIN32 || !defined __GNUC__ // || defined __APPLE__ // OSX should only notify of updates since no update packages are available.
|
||||
#if defined WIN32 || !defined __GNUC__ // || defined __APPLE__ // OSX should only notify of updates since no update packages are available.
|
||||
int ret = QMessageBox::question(this, "Companion", tr("A new version of Companion is available (version %1)<br>"
|
||||
"Would you like to download it?").arg(version) ,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
#if defined __APPLE__
|
||||
#if defined __APPLE__
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.updatesDir() + QString(C9X_INSTALLER).arg(version));
|
||||
#else
|
||||
#else
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.updatesDir() + QString(C9X_INSTALLER).arg(version), tr("Executable (*.exe)"));
|
||||
#endif
|
||||
if (!fileName.isEmpty()) {
|
||||
@@ -337,7 +337,7 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
}
|
||||
#else
|
||||
QMessageBox::warning(this, tr("New release available"), tr("A new release of Companion is available, please check the OpenTX website!"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (downloadDialog_forWait && checkForUpdatesState==0) {
|
||||
@@ -564,9 +564,9 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
}
|
||||
|
||||
void MainWindow::setLanguage(QString langString)
|
||||
{
|
||||
{
|
||||
g.locale( langString );
|
||||
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(tr("The selected language will be used the next time you start Companion."));
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
@@ -575,9 +575,9 @@ void MainWindow::setLanguage(QString langString)
|
||||
}
|
||||
|
||||
void MainWindow::setTheme(int index)
|
||||
{
|
||||
{
|
||||
g.theme( index );
|
||||
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(tr("The new theme will be loaded the next time you start Companion."));
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
@@ -586,7 +586,7 @@ void MainWindow::setTheme(int index)
|
||||
}
|
||||
|
||||
void MainWindow::setIconThemeSize(int index)
|
||||
{
|
||||
{
|
||||
g.iconSize( index );
|
||||
|
||||
QMessageBox msgBox;
|
||||
@@ -725,7 +725,7 @@ void MainWindow::fwchangelog()
|
||||
}
|
||||
|
||||
void MainWindow::customizeSplash()
|
||||
{
|
||||
{
|
||||
customizeSplashDialog *cd = new customizeSplashDialog(this);
|
||||
cd->exec();
|
||||
}
|
||||
@@ -901,7 +901,7 @@ QStringList MainWindow::GetSendFlashCommand(const QString &filename)
|
||||
QStringList ret;
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
if (IS_TARANIS(eepromInterface->getBoard())) {
|
||||
ret=GetDFUUtilArguments("-D", filename);
|
||||
ret=GetDFUUtilArguments("-D", filename);
|
||||
}
|
||||
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
|
||||
ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n");
|
||||
@@ -919,7 +919,7 @@ QStringList MainWindow::GetReceiveFlashCommand(const QString &filename)
|
||||
{
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
if (IS_TARANIS(eepromInterface->getBoard())) {
|
||||
return GetDFUUtilArguments("-U", filename);
|
||||
return GetDFUUtilArguments("-U", filename);
|
||||
}
|
||||
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
|
||||
return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n");
|
||||
@@ -988,7 +988,7 @@ void MainWindow::readEeprom()
|
||||
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
|
||||
if (IS_ARM(eepromInterface->getBoard()))
|
||||
if (IS_ARM(eepromInterface->getBoard()))
|
||||
tempFile = generateProcessUniqueTempFileName("temp.bin");
|
||||
else
|
||||
tempFile += generateProcessUniqueTempFileName("temp.hex");
|
||||
@@ -1247,7 +1247,7 @@ int MainWindow::getFileType(const QString &fullFileName)
|
||||
}
|
||||
|
||||
bool MainWindow::isValidEEPROM(QString eepromfile)
|
||||
{
|
||||
{
|
||||
int eeprom_size;
|
||||
QFile file(eepromfile);
|
||||
int fileType = getFileType(eepromfile);
|
||||
@@ -1262,10 +1262,12 @@ bool MainWindow::isValidEEPROM(QString eepromfile)
|
||||
return false;
|
||||
}
|
||||
file.close();
|
||||
|
||||
RadioData * radioData = new RadioData();
|
||||
bool result = LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size);
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size));
|
||||
delete radioData;
|
||||
return result;
|
||||
|
||||
return errors.test(NO_ERROR);
|
||||
}
|
||||
else if (fileType==FILE_TYPE_BIN) { //read binary
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
@@ -1277,10 +1279,12 @@ bool MainWindow::isValidEEPROM(QString eepromfile)
|
||||
if (read != eeprom_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RadioData * radioData = new RadioData();
|
||||
bool result = LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size);
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size));
|
||||
delete radioData;
|
||||
return result;
|
||||
|
||||
return errors.test(NO_ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1308,7 +1312,8 @@ bool MainWindow::convertEEPROM(QString backupFile, QString restoreFile, QString
|
||||
file.close();
|
||||
|
||||
QSharedPointer<RadioData> radioData = QSharedPointer<RadioData>(new RadioData());
|
||||
if (!LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size) || !firmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version))
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size));
|
||||
if (!errors.test(NO_ERROR) || !firmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version))
|
||||
return false;
|
||||
|
||||
QFile file2(restoreFile);
|
||||
@@ -1335,7 +1340,7 @@ void MainWindow::writeFlash(QString fileToFlash)
|
||||
burnDialog *cd = new burnDialog(this, 2, &fileName, &backup);
|
||||
cd->exec();
|
||||
qDebug() << "MainWindow::writeFlash(): flashing " << fileName;
|
||||
|
||||
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
backup=false;
|
||||
}
|
||||
@@ -1362,11 +1367,9 @@ void MainWindow::writeFlash(QString fileToFlash)
|
||||
}
|
||||
g.backupOnFlash(backup);
|
||||
if (backup) {
|
||||
bool backupEnable=true;
|
||||
QString backupFile;
|
||||
QString backupPath=getBackupPath();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupEnable=false;
|
||||
backupFile = generateProcessUniqueTempFileName("backup.bin");
|
||||
}
|
||||
else {
|
||||
@@ -1481,7 +1484,7 @@ void MainWindow::about()
|
||||
aboutStr.append("<br/><br/>");
|
||||
aboutStr.append(QString("Version %1, %2").arg(C9X_VERSION).arg(__DATE__));
|
||||
aboutStr.append("<br/><br/>");
|
||||
aboutStr.append(tr("Copyright OpenTX Team") + "<br/>© 2011-2014<br/>");
|
||||
aboutStr.append(tr("Copyright OpenTX Team") + "<br/>© 2011-2015<br/>");
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowIcon(CompanionIcon("information.png"));
|
||||
msgBox.setWindowTitle(tr("About Companion"));
|
||||
@@ -1497,7 +1500,7 @@ void MainWindow::updateMenus()
|
||||
pasteAct->setEnabled(hasMdiChild ? activeMdiChild()->hasPasteData() : false);
|
||||
writeEepromAct->setEnabled(hasMdiChild);
|
||||
separatorAct->setVisible(hasMdiChild);
|
||||
|
||||
|
||||
bool hasSelection = (activeMdiChild() && activeMdiChild()->hasSelection());
|
||||
cutAct->setEnabled(hasSelection);
|
||||
copyAct->setEnabled(hasSelection);
|
||||
@@ -1540,7 +1543,7 @@ QAction * MainWindow::addAct(const QString & icon, const QString & sName, const
|
||||
QAction * newAction = new QAction( this );
|
||||
if (!icon.isEmpty())
|
||||
newAction->setIcon(CompanionIcon(icon));
|
||||
if (!sName.isEmpty())
|
||||
if (!sName.isEmpty())
|
||||
newAction->setText(sName);
|
||||
if (!lName.isEmpty())
|
||||
newAction->setStatusTip(lName);
|
||||
@@ -1561,7 +1564,7 @@ QAction * MainWindow::addAct(QActionGroup *aGroup, const QString & sName, const
|
||||
{
|
||||
QAction *action = addAct("", sName, lName, QKeySequence::UnknownKey, slot);
|
||||
action->setCheckable(true);
|
||||
aGroup->addAction(action);
|
||||
aGroup->addAction(action);
|
||||
return action;
|
||||
}
|
||||
|
||||
@@ -1595,7 +1598,7 @@ void MainWindow::createActions()
|
||||
cutAct = addAct("cut.png", tr("Cut Model"), tr("Cut current model to the clipboard"), QKeySequence::Cut, SLOT(cut()));
|
||||
copyAct = addAct("copy.png", tr("Copy Model"), tr("Copy current model to the clipboard"), QKeySequence::Copy, SLOT(copy()));
|
||||
pasteAct = addAct("paste.png", tr("Paste Model"), tr("Paste model from clipboard"), QKeySequence::Paste, SLOT(paste()));
|
||||
|
||||
|
||||
QActionGroup *themeAlignGroup = new QActionGroup(this);
|
||||
classicThemeAct = addAct( themeAlignGroup, tr("Classical"), tr("The classic companion9x icon theme"), SLOT(setClassicTheme()));
|
||||
yericoThemeAct = addAct( themeAlignGroup, tr("Yerico"), tr("Yellow round honey sweet icon theme"), SLOT(setYericoTheme()));
|
||||
@@ -1648,7 +1651,7 @@ void MainWindow::createActions()
|
||||
writeBackupToRadioAct = addAct("write_eeprom_file.png", tr("Write Backup to Radio"), tr("Write Backup from file to Radio"), SLOT(writeBackup()));
|
||||
readBackupToFileAct = addAct("read_eeprom_file.png", tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio"), SLOT(readBackup()));
|
||||
contributorsAct = addAct("contributors.png", tr("Contributors..."), tr("A tribute to those who have contributed to OpenTX and Companion"), SLOT(contributors()));
|
||||
|
||||
|
||||
compareAct->setEnabled(false);
|
||||
simulateAct->setEnabled(false);
|
||||
printAct->setEnabled(false);
|
||||
@@ -1730,7 +1733,7 @@ void MainWindow::createMenus()
|
||||
burnMenu->addSeparator();
|
||||
burnMenu->addSeparator();
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
if (!IS_ARM(eepromInterface->getBoard())) {
|
||||
if (!IS_ARM(eepromInterface->getBoard())) {
|
||||
burnMenu->addAction(burnFusesAct);
|
||||
burnMenu->addAction(burnListAct);
|
||||
}
|
||||
@@ -1747,7 +1750,7 @@ void MainWindow::createMenus()
|
||||
helpMenu->addSeparator();
|
||||
helpMenu->addAction(contributorsAct);
|
||||
}
|
||||
|
||||
|
||||
QMenu *MainWindow::createRecentFileMenu()
|
||||
{
|
||||
QMenu *recentFileMenu = new QMenu(this);
|
||||
@@ -1788,7 +1791,7 @@ void MainWindow::createToolBars()
|
||||
break;
|
||||
default:
|
||||
size=QSize(24,24);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
fileToolBar = addToolBar(tr("File"));
|
||||
fileToolBar->setIconSize(size);
|
||||
@@ -1833,7 +1836,7 @@ void MainWindow::createToolBars()
|
||||
editToolBar->addAction(cutAct);
|
||||
editToolBar->addAction(copyAct);
|
||||
editToolBar->addAction(pasteAct);
|
||||
|
||||
|
||||
burnToolBar = new QToolBar(tr("Write"));
|
||||
addToolBar( Qt::LeftToolBarArea, burnToolBar );
|
||||
burnToolBar->setIconSize(size);
|
||||
@@ -1890,7 +1893,7 @@ void MainWindow::setActiveSubWindow(QWidget *window)
|
||||
void MainWindow::updateRecentFileActions()
|
||||
{
|
||||
int i, numRecentFiles;
|
||||
|
||||
|
||||
// Hide all document slots
|
||||
for ( i=0 ; i < g.historySize(); i++)
|
||||
recentFileActs[i]->setVisible(false);
|
||||
@@ -1898,7 +1901,7 @@ void MainWindow::updateRecentFileActions()
|
||||
// Fill slots with content and unhide them
|
||||
QStringList files = g.recentFiles();
|
||||
numRecentFiles = qMin(files.size(), g.historySize());
|
||||
|
||||
|
||||
for ( i = 0; i < numRecentFiles; i++) {
|
||||
QString text = strippedName(files[i]);
|
||||
if (!text.trimmed().isEmpty())
|
||||
@@ -1925,31 +1928,31 @@ void MainWindow::updateLanguageActions()
|
||||
{
|
||||
QString langId = g.locale();
|
||||
|
||||
if (langId=="")
|
||||
if (langId=="")
|
||||
sysLangAct->setChecked(true);
|
||||
else if (langId=="cs_CZ")
|
||||
else if (langId=="cs_CZ")
|
||||
czechLangAct->setChecked(true);
|
||||
else if (langId=="de_DE")
|
||||
else if (langId=="de_DE")
|
||||
germanLangAct->setChecked(true);
|
||||
else if (langId=="en")
|
||||
else if (langId=="en")
|
||||
englishLangAct->setChecked(true);
|
||||
else if (langId=="fi_FI")
|
||||
else if (langId=="fi_FI")
|
||||
finnishLangAct->setChecked(true);
|
||||
else if (langId=="fr_FR")
|
||||
else if (langId=="fr_FR")
|
||||
frenchLangAct->setChecked(true);
|
||||
else if (langId=="it_IT")
|
||||
else if (langId=="it_IT")
|
||||
italianLangAct->setChecked(true);
|
||||
else if (langId=="he_IL")
|
||||
else if (langId=="he_IL")
|
||||
hebrewLangAct->setChecked(true);
|
||||
else if (langId=="pl_PL")
|
||||
else if (langId=="pl_PL")
|
||||
polishLangAct->setChecked(true);
|
||||
else if (langId=="pt_PT")
|
||||
else if (langId=="pt_PT")
|
||||
portugueseLangAct->setChecked(true);
|
||||
else if (langId=="ru_RU")
|
||||
else if (langId=="ru_RU")
|
||||
russianLangAct->setChecked(true);
|
||||
else if (langId=="sv_SE")
|
||||
else if (langId=="sv_SE")
|
||||
swedishLangAct->setChecked(true);
|
||||
else if (langId=="nl_NL")
|
||||
else if (langId=="nl_NL")
|
||||
dutchLangAct->setChecked(true);
|
||||
}
|
||||
|
||||
@@ -1967,9 +1970,9 @@ void MainWindow::updateIconThemeActions()
|
||||
|
||||
void MainWindow::updateProfilesActions()
|
||||
{
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
{
|
||||
if (g.profile[i].existsOnDisk())
|
||||
if (g.profile[i].existsOnDisk())
|
||||
{
|
||||
QString text = tr("%2").arg(g.profile[i].name());
|
||||
profileActs[i]->setText(text);
|
||||
@@ -1977,8 +1980,8 @@ void MainWindow::updateProfilesActions()
|
||||
profileActs[i]->setVisible(true);
|
||||
if (i == g.id())
|
||||
profileActs[i]->setChecked(true);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
profileActs[i]->setVisible(false);
|
||||
}
|
||||
@@ -1992,7 +1995,7 @@ void MainWindow::createProfile()
|
||||
;
|
||||
if (i==MAX_PROFILES) //Failed to find free slot
|
||||
return;
|
||||
|
||||
|
||||
// Copy current profile to new and give it a new name
|
||||
g.profile[i] = g.profile[g.id()];
|
||||
g.profile[i].name(tr("New Radio"));
|
||||
@@ -2033,16 +2036,17 @@ int MainWindow::getEpromVersion(QString fileName)
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
|
||||
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
|
||||
bool xmlOK = doc.setContent(&file);
|
||||
if(xmlOK) {
|
||||
if (!LoadEepromXml(testData, doc)){
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEepromXml(testData, doc));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
file.reset();
|
||||
|
||||
|
||||
QTextStream inputStream(&file);
|
||||
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
|
||||
QString hline = inputStream.readLine();
|
||||
@@ -2059,7 +2063,9 @@ int MainWindow::getEpromVersion(QString fileName)
|
||||
return -1;
|
||||
}
|
||||
file.close();
|
||||
if (!LoadEeprom(testData, eeprom, eeprom_size)) {
|
||||
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(testData, eeprom, eeprom_size));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
QMessageBox::critical(this, tr("Error"),tr("Invalid Models and Settings File %1").arg(fileName));
|
||||
return -1;
|
||||
}
|
||||
@@ -2077,7 +2083,9 @@ int MainWindow::getEpromVersion(QString fileName)
|
||||
QMessageBox::critical(this, tr("Error"),tr("Error reading file %1:\n%2.").arg(fileName).arg(file.errorString()));
|
||||
return -1;
|
||||
}
|
||||
if (!LoadEeprom(testData, (uint8_t *)eeprom.data(), eeprom_size)) {
|
||||
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(testData, (uint8_t *)eeprom.data(), eeprom_size));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
QMessageBox::critical(this, tr("Error"),tr("Invalid binary Models and Settings File %1").arg(fileName));
|
||||
return -1;
|
||||
}
|
||||
|
||||
+36
-24
@@ -81,7 +81,7 @@ MdiChild::MdiChild():
|
||||
}
|
||||
}
|
||||
|
||||
MdiChild::~MdiChild()
|
||||
MdiChild::~MdiChild()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ void MdiChild::modelEdit()
|
||||
|
||||
if (row == 0){
|
||||
generalEdit();
|
||||
}
|
||||
}
|
||||
else {
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
checkAndInitModel( row );
|
||||
@@ -251,7 +251,7 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
|
||||
XmlInterface(inputStream).load(radioData);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
@@ -260,18 +260,19 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
|
||||
.arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
|
||||
bool xmlOK = doc.setContent(&file);
|
||||
if(xmlOK) {
|
||||
if (LoadEepromXml(radioData, doc)){
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEepromXml(radioData, doc));
|
||||
if (errors.test(NO_ERROR)) {
|
||||
ui->modelsList->refreshList();
|
||||
if(resetCurrentFile) setCurrentFile(fileName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
file.reset();
|
||||
|
||||
|
||||
QTextStream inputStream(&file);
|
||||
|
||||
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
|
||||
@@ -294,12 +295,14 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
|
||||
|
||||
file.close();
|
||||
|
||||
if (!LoadEeprom(radioData, eeprom, eeprom_size)) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Invalid EEPROM File %1")
|
||||
.arg(fileName));
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(radioData, eeprom, eeprom_size));
|
||||
if (!errors.test(NO_ERROR)) {
|
||||
ShowEepromErrors(this, tr("Error"), tr("Invalid EEPROM File %1").arg(fileName), errors.to_ulong());
|
||||
return false;
|
||||
}
|
||||
if (errors.test(HAS_WARNINGS)) {
|
||||
ShowEepromWarnings(this, tr("Warning"), errors.to_ulong());
|
||||
}
|
||||
|
||||
ui->modelsList->refreshList();
|
||||
if(resetCurrentFile) setCurrentFile(fileName);
|
||||
@@ -330,11 +333,18 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Invalid binary EEPROM File %1")
|
||||
.arg(fileName));
|
||||
return false;
|
||||
std::bitset<NUM_ERRORS> errorsEeprom((unsigned long long)LoadEeprom(radioData, eeprom, eeprom_size));
|
||||
if (!errorsEeprom.test(NO_ERROR)) {
|
||||
std::bitset<NUM_ERRORS> errorsBackup((unsigned long long)LoadBackup(radioData, eeprom, eeprom_size, 0));
|
||||
if (!errorsBackup.test(NO_ERROR)) {
|
||||
ShowEepromErrors(this, tr("Error"), tr("Invalid binary EEPROM File %1").arg(fileName), (errorsEeprom | errorsBackup).to_ulong());
|
||||
return false;
|
||||
}
|
||||
if (errorsBackup.test(HAS_WARNINGS)) {
|
||||
ShowEepromWarnings(this, tr("Warning"), errorsBackup.to_ulong());
|
||||
}
|
||||
} else if (errorsEeprom.test(HAS_WARNINGS)) {
|
||||
ShowEepromWarnings(this, tr("Warning"), errorsEeprom.to_ulong());
|
||||
}
|
||||
|
||||
ui->modelsList->refreshList();
|
||||
@@ -367,7 +377,7 @@ bool MdiChild::saveAs(bool isNew)
|
||||
fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName());
|
||||
#else
|
||||
fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(BIN_FILES_FILTER));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
QFileInfo fi(curFile);
|
||||
@@ -375,14 +385,14 @@ bool MdiChild::saveAs(bool isNew)
|
||||
fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName());
|
||||
#else
|
||||
fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(EEPROM_FILES_FILTER));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
g.eepromDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
if (isNew)
|
||||
return saveFile(fileName);
|
||||
else
|
||||
else
|
||||
return saveFile(fileName,true);
|
||||
}
|
||||
|
||||
@@ -505,7 +515,7 @@ void MdiChild::setCurrentFile(const QString &fileName)
|
||||
files.prepend(fileName);
|
||||
while (files.size() > MaxRecentFiles)
|
||||
files.removeLast();
|
||||
|
||||
|
||||
g.recentFiles( files );
|
||||
}
|
||||
|
||||
@@ -594,7 +604,7 @@ void MdiChild::print(int model, QString filename)
|
||||
else if (ui->modelsList->currentRow() > 0) {
|
||||
pd = new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData.generalSettings, &radioData.models[ui->modelsList->currentRow()-1]);
|
||||
}
|
||||
|
||||
|
||||
if (pd) {
|
||||
pd->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
pd->show();
|
||||
@@ -646,12 +656,14 @@ bool MdiChild::loadBackup()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Invalid binary backup File %1")
|
||||
.arg(fileName));
|
||||
std::bitset<NUM_ERRORS> errorsEeprom((unsigned long long)LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index));
|
||||
if (!errorsEeprom.test(NO_ERROR)) {
|
||||
ShowEepromErrors(this, tr("Error"), tr("Invalid binary backup File %1").arg(fileName), (errorsEeprom).to_ulong());
|
||||
return false;
|
||||
}
|
||||
if (errorsEeprom.test(HAS_WARNINGS)) {
|
||||
ShowEepromWarnings(this, tr("Warning"), errorsEeprom.to_ulong());
|
||||
}
|
||||
|
||||
ui->modelsList->refreshList();
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class MdiChild : public QWidget
|
||||
void modelEdit();
|
||||
void wizardEdit();
|
||||
void openEditWindow();
|
||||
|
||||
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
|
||||
@@ -691,7 +691,7 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, const ModelData & m
|
||||
b->setCurrentIndex(value);
|
||||
}
|
||||
else if (function==FuncVolume) {
|
||||
populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_TRIMS);
|
||||
populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_TRIMS|POPULATE_SWITCHES);
|
||||
}
|
||||
else if (function==FuncPlayValue) {
|
||||
populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_SWITCHES|POPULATE_GVARS|POPULATE_TRIMS|POPULATE_TELEMETRYEXT);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#include "ui_expodialog.h"
|
||||
#include "helpers.h"
|
||||
|
||||
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, FirmwareInterface * firmware, char * inputName) :
|
||||
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
|
||||
FirmwareInterface * firmware, QString & inputName) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ExpoDialog),
|
||||
model(model),
|
||||
@@ -62,6 +63,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
ui->inputName->setMaxLength(4);
|
||||
populateSourceCB(ui->sourceCB, ed->srcRaw, model, POPULATE_SOURCES | POPULATE_SWITCHES | POPULATE_TRIMS | POPULATE_TELEMETRY);
|
||||
ui->sourceCB->removeItem(0);
|
||||
ui->inputName->setValidator(new QRegExpValidator(rx, this));
|
||||
ui->inputName->setText(inputName);
|
||||
}
|
||||
else {
|
||||
ui->inputNameLabel->hide();
|
||||
@@ -87,9 +90,6 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
ui->lineName->setMaxLength(expolength);
|
||||
}
|
||||
|
||||
ui->inputName->setValidator(new QRegExpValidator(rx, this));
|
||||
ui->inputName->setText(inputName);
|
||||
|
||||
ui->lineName->setValidator(new QRegExpValidator(rx, this));
|
||||
ui->lineName->setText(ed->name);
|
||||
|
||||
@@ -153,7 +153,8 @@ void ExpoDialog::valuesChanged()
|
||||
ed->mode = ui->sideCB->currentIndex() + 1;
|
||||
|
||||
strcpy(ed->name, ui->lineName->text().toAscii().data());
|
||||
strcpy(inputName, ui->inputName->text().toAscii().data());
|
||||
if (firmware->getCapability(VirtualInputs))
|
||||
inputName = ui->inputName->text();
|
||||
|
||||
ed->phases=0;
|
||||
for (int i=8; i>=0 ; i--) {
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace Ui {
|
||||
class ExpoDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings, FirmwareInterface * firmware, char * inputName);
|
||||
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings,
|
||||
FirmwareInterface * firmware, QString & inputName);
|
||||
~ExpoDialog();
|
||||
|
||||
protected:
|
||||
@@ -30,7 +31,7 @@ class ExpoDialog : public QDialog {
|
||||
GeneralSettings & generalSettings;
|
||||
FirmwareInterface * firmware;
|
||||
ExpoData * ed;
|
||||
char * inputName;
|
||||
QString & inputName;
|
||||
GVarGroup * gvWeightGroup;
|
||||
GVarGroup * gvOffsetGroup;
|
||||
CurveGroup * curveGroup;
|
||||
|
||||
@@ -216,18 +216,18 @@ void InputsPanel::gm_openExpo(int index)
|
||||
if(index<0 || index>=C9X_MAX_EXPOS) return;
|
||||
|
||||
ExpoData mixd(model.expoData[index]);
|
||||
char inputName[4+1];
|
||||
emit modified();
|
||||
update();
|
||||
|
||||
QString inputName;
|
||||
if (firmware->getCapability(VirtualInputs))
|
||||
strcpy(inputName, model.inputNames[mixd.chn]);
|
||||
inputName = model.inputNames[mixd.chn];
|
||||
|
||||
ExpoDialog *g = new ExpoDialog(this, model, &mixd, generalSettings, firmware, inputName);
|
||||
if (g->exec()) {
|
||||
model.expoData[index] = mixd;
|
||||
if (firmware->getCapability(VirtualInputs))
|
||||
strcpy(model.inputNames[mixd.chn], inputName);
|
||||
strncpy(model.inputNames[mixd.chn], inputName.toAscii().data(), 4);
|
||||
emit modified();
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -260,6 +260,11 @@ void ModulePanel::update()
|
||||
|
||||
ui->failsafesLayoutLabel->setVisible(mask & MASK_FAILSAFES);
|
||||
ui->failsafesFrame->setVisible(mask & MASK_FAILSAFES);
|
||||
|
||||
if (mask & MASK_CHANNELS_RANGE) {
|
||||
ui->channelsStart->setMaximum(32 - ui->channelsCount->value());
|
||||
ui->channelsCount->setMaximum(qMin(16, 32-ui->channelsStart->value()));
|
||||
}
|
||||
}
|
||||
|
||||
void ModulePanel::on_trainerMode_currentIndexChanged(int index)
|
||||
@@ -428,8 +433,8 @@ SetupPanel::SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & gen
|
||||
ui->centerBeepLayout->addWidget(checkbox, 0, i+1);
|
||||
connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
|
||||
centerBeepCheckboxes << checkbox;
|
||||
if (!IS_TARANIS_PLUS(firmware->getBoard()) && i==6) {
|
||||
checkbox->hide();
|
||||
if (firmware->getBoard()==BOARD_TARANIS && i==6) {
|
||||
checkbox->hide();
|
||||
}
|
||||
QWidget::setTabOrder(prevFocus, checkbox);
|
||||
prevFocus = checkbox;
|
||||
@@ -605,6 +610,7 @@ void SetupPanel::populateThrottleSourceCB()
|
||||
|
||||
lock = true;
|
||||
|
||||
ui->throttleSource->clear();
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
for (i=0; i<6; i++) {
|
||||
ui->throttleSource->addItem(sourcesTaranis[i], i);
|
||||
|
||||
@@ -344,7 +344,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16</number>
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#### Version 1.3.1 released on 25.04.15 ####
|
||||
|
||||
Bugfixes:
|
||||
- Fixed bug that prevented automatic axis rescaling when some graphs/curves had only NaN data points
|
||||
- Improved QCPItemBracket selection boundaries, especially bsCurly and bsCalligraphic
|
||||
- Fixed bug of axis rect and colorscale background shifted downward by one logical pixel (visible in scaled png and pdf export)
|
||||
- Replot upon mouse release is now only performed if a selection change has actually happened (improves responsivity on particularly complex plots)
|
||||
- Fixed bug that allowed scatter-only graphs to be selected by clicking the non-existent line between scatters
|
||||
- Fixed crash when trying to select a scatter-only QCPGraph whose only points in the visible key range are at identical key coordinates and vertically off-screen, with adaptive sampling enabled
|
||||
- Fixed pdf export of QCPColorMap with enabled interpolation (didn't appear interpolated in pdf)
|
||||
- Reduced QCPColorMap jitter of internal cell boundaries for small sized maps when viewed with high zoom, by applying oversampling factors dependant on map size
|
||||
- Fixed bug of QCPColorMap::fill() not causing the buffered internal image map to be updated, and thus the change didn't become visible immediately
|
||||
- Axis labels with size set in pixels (setPixelSize) instead of points now correctly calculate the exponent's font size if beautifully typeset powers are enabled
|
||||
- Fixed QCPColorMap appearing at the wrong position for logarithmic axes and color map spanning larger ranges
|
||||
|
||||
Other:
|
||||
- Pdf export used to embed entire QCPColorMaps, potentially leading to large files. Now only the visible portion of the map is embedded in the pdf
|
||||
- Many documentation fixes and extensions, style modernization
|
||||
- Reduced documentation file size (and thus full package size) by automatically reducing image palettes during package build
|
||||
- Fixed MSVC warning message (at warning level 4) due to temporary QLists in some foreach statements
|
||||
|
||||
#### Version 1.3.0 released on 27.12.14 ####
|
||||
|
||||
Added features:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
** **
|
||||
** QCustomPlot, an easy to use, modern plotting widget for Qt **
|
||||
** Copyright (C) 2011, 2012, 2013, 2014 Emanuel Eichhammer **
|
||||
** Copyright (C) 2011-2015 Emanuel Eichhammer **
|
||||
** **
|
||||
** This program is free software: you can redistribute it and/or modify **
|
||||
** it under the terms of the GNU General Public License as published by **
|
||||
@@ -19,8 +19,8 @@
|
||||
****************************************************************************
|
||||
** Author: Emanuel Eichhammer **
|
||||
** Website/Contact: http://www.qcustomplot.com/ **
|
||||
** Date: 27.12.14 **
|
||||
** Version: 1.3.0 **
|
||||
** Date: 25.04.15 **
|
||||
** Version: 1.3.1 **
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCUSTOMPLOT_H
|
||||
@@ -3099,7 +3099,7 @@ protected:
|
||||
bool mTightBoundary;
|
||||
QPointer<QCPColorScale> mColorScale;
|
||||
// non-property members:
|
||||
QImage mMapImage;
|
||||
QImage mMapImage, mUndersampledMapImage;
|
||||
QPixmap mLegendIcon;
|
||||
bool mMapImageInvalidated;
|
||||
|
||||
|
||||
@@ -112,22 +112,24 @@ void JoystickDialog::on_cancelButton_clicked()
|
||||
|
||||
void JoystickDialog::on_okButton_clicked()
|
||||
{
|
||||
int sticks[8] = {0,0,0,0,0,0,0,0};
|
||||
int stickAssignments[MAX_JOYSTICKS] = {0};
|
||||
foreach(QComboBox *cb, findChildren<QComboBox *>(QRegExp("jsmapCB_[0-9]+"))) {
|
||||
sticks[cb->currentIndex()]++;
|
||||
}
|
||||
bool duplicated=false;
|
||||
for (int i=1; i<8;i++) {
|
||||
if (sticks[i]>1) {
|
||||
duplicated = true;
|
||||
int mappedValue = cb->currentIndex() - 1;
|
||||
// qDebug() << "cb->currentIndex()" << mappedValue;
|
||||
if (mappedValue >= 0 && mappedValue < MAX_JOYSTICKS) {
|
||||
stickAssignments[mappedValue]++;
|
||||
}
|
||||
}
|
||||
if (duplicated) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Duplicated stick assignement"));
|
||||
return;
|
||||
|
||||
for (int i=0; i<MAX_JOYSTICKS; i++) {
|
||||
if (stickAssignments[i] > 1) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Duplicated stick assignment"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
joystick->close();
|
||||
for (int i=0; i<8; i++) {
|
||||
for (int i=0; i<MAX_JOYSTICKS; i++) {
|
||||
g.joystick[i].remove();
|
||||
}
|
||||
QCheckBox * ib[]={ui->ChInv_1, ui->ChInv_2, ui->ChInv_3, ui->ChInv_4, ui->ChInv_5, ui->ChInv_6, ui->ChInv_7, ui->ChInv_8};
|
||||
@@ -135,7 +137,7 @@ void JoystickDialog::on_okButton_clicked()
|
||||
int axe=cb->objectName().mid(cb->objectName().lastIndexOf("_")+1).toInt()-1;
|
||||
int stick=cb->currentIndex() - 1;
|
||||
qDebug() << "joystick mapping " << cb->objectName() <<"axe:" << axe << "stick:" << stick;
|
||||
if (stick >= 0) {
|
||||
if (stick >= 0 && stick < MAX_JOYSTICKS) {
|
||||
g.joystick[stick].stick_axe( axe );
|
||||
g.joystick[stick].stick_max( jscal[axe][2] );
|
||||
g.joystick[stick].stick_med( jscal[axe][1] );
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <iostream>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
#endif
|
||||
#include "simulatordialog.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7695,12 +7695,12 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location filename="../eeprominterface.cpp" line="461"/>
|
||||
<source>EleTrim Down</source>
|
||||
<translation>TrmE Bas</translation>
|
||||
<translation>TrmP Bas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../eeprominterface.cpp" line="461"/>
|
||||
<source>EleTrim Up</source>
|
||||
<translation>TrmE Haut</translation>
|
||||
<translation>TrmP Haut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../eeprominterface.cpp" line="462"/>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -121,7 +121,7 @@ void saveModel(ModelData & m, model & xm)
|
||||
if (t.mode) {
|
||||
timer xt(TimerSwitch::value(t.mode+TMR_NUM_OPTION), direction::value(t.dir), timer::value_type(t.val/3600, (t.val%3600)/60, t.val%60));
|
||||
timer_sequence.push_back(xt);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (m.moduleData[0].protocol != PPM || m.moduleData[0].channelsCount != 8 || m.moduleData[0].ppmDelay != 300 || m.moduleData[0].ppmPulsePol != 0) {
|
||||
@@ -185,7 +185,7 @@ bool XmlInterface::save(RadioData &radioData)
|
||||
radio r;
|
||||
|
||||
// the general settings
|
||||
global_settings gs;
|
||||
global_settings gs;
|
||||
saveGeneralSettings(settings, gs);
|
||||
r.global_settings(gs);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright © 2011-2014 OpenTX team
|
||||
Copyright © 2011-2015 OpenTX team
|
||||
|
||||
OpenTX Companion is based on code named eePe by author - Erez Raviv <erezraviv@gmail.com>
|
||||
|
||||
@@ -9,4 +9,4 @@ Permission is granted to anyone to use this software for any purpose, including
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
|
||||
If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any distribution.
|
||||
3. This notice may not be removed or altered from any distribution.
|
||||
|
||||
@@ -1,3 +1,49 @@
|
||||
<h2>Version 2.0.19 / 2016-01-15</h2>
|
||||
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Fixed : Logical switch internal state was being reset by the AND switch, that affected its function
|
||||
(it looked like AND was applied before the EDGE processing, not after like it is done for other logical switch types)
|
||||
(<a href=https://github.com/opentx/opentx/issues/2939>#2939</a>)</li>
|
||||
<li>SD manager bug when scrolling up fixed (<a href=https://github.com/opentx/opentx/issues/3230>#3230</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Version 2.0.18 / 2016-01-03</h2>
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Lua <i>model.insertInput()</i> could not add more than 32 inputs (<a href=https://github.com/opentx/opentx/issues/2084>#2084</a>)</li>
|
||||
<li>Fixed auto-source problem on radios with non-existing S3 pot (<a href=https://github.com/opentx/opentx/issues/2364>#2364</a>)</li>
|
||||
<li>Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
|
||||
Users with such setups are advised to re-check their failsafe settings (<a href=https://github.com/opentx/opentx/issues/2975>#2975</a>)</li>
|
||||
</ul>
|
||||
|
||||
[ARM Boards]
|
||||
<ul>
|
||||
<li>Fixed Edge Logical switch erroneous delay (<a href=https://github.com/opentx/opentx/issues/2368>#2368</a>)</li>
|
||||
<li>Fixed a problem with FMxx switches (<a href=https://github.com/opentx/opentx/issues/2442>#2442</a>)</li>
|
||||
<li>Fixed: playing two background sounds at once causes sound to stop (<a href=https://github.com/opentx/opentx/issues/2704>#2704</a>)</li>
|
||||
<li>SD Card manager improvements: Disable menu for [..], refresh file list after delete, removed delete menu option for directories (<a href=https://github.com/opentx/opentx/issues/2623>#2623</a>)</li>
|
||||
<li>Added a warning about used receiver ID on model copy (<a href=https://github.com/opentx/opentx/issues/2187>#2187</a>)</li>
|
||||
<li>PPM center did not work with the DSM hack module (<a href=https://github.com/opentx/opentx/issues/2880>#2880</a>)</li>
|
||||
<li>Fixed: Edge Logical Switch could trigger right after the model was loaded or the radio turned on (<a href=https://github.com/opentx/opentx/issues/2728>#2728</a>)</li>
|
||||
<li>Prevent issue when timer reaches maximum</li>
|
||||
</ul>
|
||||
|
||||
[All]
|
||||
<ul>
|
||||
<li>Fixed a compilation problem on MAC (<a href=https://github.com/opentx/opentx/issues/2271>#2271</a>)</li>
|
||||
<li>Fixed FrSky-D Telemetry protocol bug (0x5D followed by 0x3D)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.17 / 2015-05-04</h2>
|
||||
|
||||
Nothing new (only Companion fixes)
|
||||
|
||||
|
||||
<h2>Version 2.0.16 / 2015-05-03</h2>
|
||||
|
||||
[Taranis]
|
||||
|
||||
+17
-20
@@ -313,6 +313,10 @@ TRACE_AUDIO = NO
|
||||
# Values = NO, YES
|
||||
TARANIS_INTERNAL_PPM = NO
|
||||
|
||||
# Support for D16-EU only (no D8, no LR12 which are not EU compatible)
|
||||
# Value = NO, YES
|
||||
SUPPORT_D16_EU_ONLY = NO
|
||||
|
||||
# Enable disk IO simulation in simulator
|
||||
# Simulator will use FatFs module and simulated IO layer that
|
||||
# uses "./sdcard.image" file as image of SD card.
|
||||
@@ -331,7 +335,7 @@ SHELL = sh
|
||||
IMG2LBM = -python ../util/img2lbm.py
|
||||
BIN2LBM = -python ../util/bin2lbm.py
|
||||
TRANSLATE = -python ../util/translate.py
|
||||
VERSION = 2.0.16
|
||||
VERSION = 2.0.19
|
||||
|
||||
SRC =
|
||||
CPPSRC =
|
||||
@@ -734,6 +738,9 @@ ifeq ($(PCB), TARANIS)
|
||||
ifeq ($(TARANIS_INTERNAL_PPM), YES)
|
||||
CPPDEFS += -DTARANIS_INTERNAL_PPM
|
||||
endif
|
||||
ifeq ($(SUPPORT_D16_EU_ONLY), YES)
|
||||
CPPDEFS += -DMODULE_D16_EU_ONLY_SUPPORT
|
||||
endif
|
||||
LDSCRIPT = targets/taranis/stm32_flash_bl.ld
|
||||
TRGT = arm-none-eabi-
|
||||
MCU = cortex-m3
|
||||
@@ -1551,15 +1558,16 @@ endif
|
||||
|
||||
#### GOOGLE TESTS
|
||||
|
||||
GTEST_DIR = ../gtest-1.6.0
|
||||
GTEST_INCDIR = /usr/include/gtest
|
||||
GTEST_SRCDIR = /usr/src/gtest/
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ./
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
GTEST_HEADERS = $(GTEST_INCDIR)/*.h \
|
||||
$(GTEST_INCDIR)/internal/*.h
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
@@ -1567,25 +1575,14 @@ GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
GTEST_SRCS = $(GTEST_SRCDIR)/src/*.cc $(GTEST_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on Google Test's
|
||||
# implementation details, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Test
|
||||
# compiles fast and for ordinary users its source rarely changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GTEST_DIR)/include -c \
|
||||
$(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gtest_main.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GTEST_DIR)/include -c \
|
||||
$(GTEST_DIR)/src/gtest_main.cc
|
||||
|
||||
gtest.a : gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gtest_main.a : gtest-all.o gtest_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
gtest-all.o : $(GTEST_SRCS)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_SRCDIR) -I$(GTEST_INCDIR) -c $(GTEST_SRCDIR)/src/gtest-all.cc
|
||||
|
||||
# Builds a sample test. A test should link with either gtest.a or
|
||||
# gtest_main.a, depending on whether it defines its own main()
|
||||
@@ -1594,6 +1591,6 @@ gtest_main.a : gtest-all.o gtest_main.o
|
||||
#use all .cpp files from tests/ dir
|
||||
GTEST_TESTS_SRCS = $(shell find tests/ -type f -name '*.cpp')
|
||||
|
||||
gtests: $(BOARDSRC) $(CPPSRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp *.h gtest_main.a
|
||||
g++ -std=gnu++0x $(CPPFLAGS) $(BOARDSRC) $(CPPSRC) $(LUASRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp -I$(GTEST_DIR) ${INCFLAGS} -I$(GTEST_DIR)/include -o gtests -lpthread -MD -DSIMU -lQtCore -lQtGui gtest_main.a -fexceptions
|
||||
gtests: $(BOARDSRC) $(CPPSRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp *.h gtest-all.o
|
||||
g++ -std=gnu++0x $(CPPFLAGS) $(BOARDSRC) $(CPPSRC) $(LUASRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp ${INCFLAGS} -I$(GTEST_INCDIR) -I/usr/include/qt4 -o gtests -lpthread -MD -DSIMU -lQtCore -lQtGui gtest-all.o -fexceptions
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ class AudioQueue {
|
||||
|
||||
friend void audioTask(void* pdata);
|
||||
#if defined(SIMU)
|
||||
friend void *audio_thread(void *);
|
||||
friend void *audioThread(void *);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
|
||||
#include "../opentx.h"
|
||||
|
||||
#define REFRESH_FILES() do { reusableBuffer.sdmanager.offset = 65535; m_posVert = 1; } while(0)
|
||||
#define NODE_TYPE(fname) fname[SD_SCREEN_FILE_LENGTH+1]
|
||||
#define IS_DIRECTORY(fname) ((bool)(!NODE_TYPE(fname)))
|
||||
#define IS_FILE(fname) ((bool)(NODE_TYPE(fname)))
|
||||
|
||||
const pm_uchar sticks[] PROGMEM = {
|
||||
#include "../bitmaps/sticks.lbm"
|
||||
};
|
||||
@@ -713,12 +718,12 @@ void menuGeneralSdManagerInfo(uint8_t event)
|
||||
|
||||
inline bool isFilenameGreater(bool isfile, const char * fn, const char * line)
|
||||
{
|
||||
return (isfile && !line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) > 0);
|
||||
return (isfile && IS_DIRECTORY(line)) || (isfile==IS_FILE(line) && strcasecmp(fn, line) > 0);
|
||||
}
|
||||
|
||||
inline bool isFilenameLower(bool isfile, const char * fn, const char * line)
|
||||
{
|
||||
return (!isfile && line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) < 0);
|
||||
return (!isfile && IS_FILE(line)) || (isfile==IS_FILE(line) && strcasecmp(fn, line) < 0);
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
@@ -845,8 +850,7 @@ void onSdManagerMenu(const char *result)
|
||||
strncpy(statusLineMsg, reusableBuffer.sdmanager.lines[index], 13);
|
||||
strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED);
|
||||
showStatusLine();
|
||||
if ((uint16_t)m_posVert == reusableBuffer.sdmanager.count) m_posVert--;
|
||||
reusableBuffer.sdmanager.offset = s_pgOfs-1;
|
||||
REFRESH_FILES();
|
||||
}
|
||||
#if defined(CPUARM)
|
||||
/* TODO else if (result == STR_LOAD_FILE) {
|
||||
@@ -956,7 +960,7 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
{
|
||||
if (m_posVert > 0) {
|
||||
vertpos_t index = m_posVert-1-s_pgOfs;
|
||||
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
|
||||
if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[index])) {
|
||||
f_chdir(reusableBuffer.sdmanager.lines[index]);
|
||||
s_pgOfs = 0;
|
||||
m_posVert = 1;
|
||||
@@ -980,10 +984,14 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if defined(CPUARM)
|
||||
uint8_t index = m_posVert-1-s_pgOfs;
|
||||
char *line = reusableBuffer.sdmanager.lines[index];
|
||||
if (!strcmp(line, "..")) {
|
||||
break; // no menu for parent dir
|
||||
}
|
||||
#if defined(CPUARM)
|
||||
// TODO duplicated code for finding extension
|
||||
char * ext = reusableBuffer.sdmanager.lines[index];
|
||||
char * ext = line;
|
||||
int len = strlen(ext) - 4;
|
||||
ext += len;
|
||||
/* TODO if (!strcasecmp(ext, MODELS_EXT)) {
|
||||
@@ -1010,7 +1018,7 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
}
|
||||
#endif
|
||||
if (!READ_ONLY()) {
|
||||
MENU_ADD_ITEM(STR_DELETE_FILE);
|
||||
if (IS_FILE(line)) MENU_ADD_ITEM(STR_DELETE_FILE);
|
||||
// MENU_ADD_ITEM(STR_RENAME_FILE); TODO: Implement
|
||||
// MENU_ADD_ITEM(STR_COPY_FILE); TODO: Implement
|
||||
}
|
||||
@@ -1031,7 +1039,7 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
else if (s_pgOfs > reusableBuffer.sdmanager.offset) {
|
||||
memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
memset(reusableBuffer.sdmanager.lines[6], 0xff, SD_SCREEN_FILE_LENGTH);
|
||||
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = 1;
|
||||
NODE_TYPE(reusableBuffer.sdmanager.lines[6]) = 1;
|
||||
}
|
||||
else {
|
||||
memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
@@ -1051,7 +1059,8 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
#else
|
||||
fn = fno.fname;
|
||||
#endif
|
||||
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
|
||||
TRACE("strlen(%s) = %d", fn, strlen(fn));
|
||||
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) { TRACE("too long"); continue; }
|
||||
|
||||
reusableBuffer.sdmanager.count++;
|
||||
|
||||
@@ -1062,9 +1071,9 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
char *line = reusableBuffer.sdmanager.lines[i];
|
||||
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) {
|
||||
if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i));
|
||||
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
|
||||
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
strcpy(line, fn);
|
||||
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
|
||||
NODE_TYPE(line) = isfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1074,9 +1083,9 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
char *line = reusableBuffer.sdmanager.lines[i];
|
||||
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) {
|
||||
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
|
||||
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
|
||||
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
strcpy(line, fn);
|
||||
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
|
||||
NODE_TYPE(line) = isfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1085,14 +1094,14 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) {
|
||||
memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
strcpy(reusableBuffer.sdmanager.lines[6], fn);
|
||||
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile;
|
||||
NODE_TYPE(reusableBuffer.sdmanager.lines[6]) = isfile;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) {
|
||||
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
|
||||
strcpy(reusableBuffer.sdmanager.lines[0], fn);
|
||||
reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile;
|
||||
NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1106,9 +1115,9 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
lcdNextPos = 0;
|
||||
uint8_t attr = (m_posVert-1-s_pgOfs == i ? BSS|INVERS : BSS);
|
||||
if (reusableBuffer.sdmanager.lines[i][0]) {
|
||||
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', attr); }
|
||||
if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[i])) { lcd_putcAtt(0, y, '[', attr); }
|
||||
lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);
|
||||
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', attr); }
|
||||
if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[i])) { lcd_putcAtt(lcdNextPos, y, ']', attr); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -439,7 +439,7 @@ void menuModelSelect(uint8_t event)
|
||||
s_editMode = 0;
|
||||
break;
|
||||
}
|
||||
// no break;
|
||||
// no break;
|
||||
#endif
|
||||
case EVT_KEY_LONG(KEY_ENTER):
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
@@ -479,6 +479,10 @@ void menuModelSelect(uint8_t event)
|
||||
eeDirty(EE_GENERAL);
|
||||
}
|
||||
|
||||
#if defined(CPUARM)
|
||||
checkModelIdUnique(g_eeGeneral.currModel);
|
||||
#endif
|
||||
|
||||
s_copyMode = 0;
|
||||
event = EVT_ENTRY_UP;
|
||||
}
|
||||
@@ -666,16 +670,17 @@ void menuModelFailsafe(uint8_t event)
|
||||
static bool longNames = false;
|
||||
bool newLongNames = false;
|
||||
uint8_t ch = 0;
|
||||
uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart;
|
||||
|
||||
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];
|
||||
g_model.moduleData[g_moduleIdx].failsafeChannels[m_posVert] = channelOutputs[m_posVert+channelStart];
|
||||
eeDirty(EE_MODEL);
|
||||
AUDIO_WARNING1();
|
||||
SEND_FAILSAFE_NOW(g_moduleIdx);
|
||||
}
|
||||
|
||||
SIMPLE_SUBMENU_NOTITLE(NUM_CHNOUT);
|
||||
SIMPLE_SUBMENU_NOTITLE(NUM_CHANNELS(g_moduleIdx));
|
||||
|
||||
SET_SCROLLBAR_X(0);
|
||||
|
||||
@@ -684,10 +689,6 @@ void menuModelFailsafe(uint8_t event)
|
||||
const uint8_t SLIDER_W = 64;
|
||||
// Column separator
|
||||
lcd_vline(LCD_W/2, FH, LCD_H-FH);
|
||||
|
||||
if (m_posVert >= 16) {
|
||||
ch = 16;
|
||||
}
|
||||
#else
|
||||
#define COL_W (LCD_W)
|
||||
const uint8_t SLIDER_W = 90;
|
||||
@@ -708,59 +709,64 @@ void menuModelFailsafe(uint8_t event)
|
||||
// Channels
|
||||
for (uint8_t line=0; line<8; line++) {
|
||||
uint8_t y = 9+line*7;
|
||||
int32_t val;
|
||||
int32_t failsafeValue = 0;
|
||||
bool failsafeEditable = false;
|
||||
uint8_t ofs = (col ? 0 : 1);
|
||||
|
||||
if (ch < g_model.moduleData[g_moduleIdx].channelsStart || ch >= NUM_CHANNELS(g_moduleIdx) + g_model.moduleData[g_moduleIdx].channelsStart)
|
||||
val = 0;
|
||||
else if (s_editMode && m_posVert == ch)
|
||||
val = channelOutputs[ch];
|
||||
else
|
||||
val = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line];
|
||||
if (ch < NUM_CHANNELS(g_moduleIdx)) {
|
||||
if (s_editMode && m_posVert == ch) {
|
||||
failsafeValue = channelOutputs[ch+channelStart];
|
||||
}
|
||||
else {
|
||||
failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line];
|
||||
}
|
||||
failsafeEditable = true;
|
||||
}
|
||||
|
||||
if (failsafeEditable) {
|
||||
#if defined(PCBTARANIS)
|
||||
// Channel name if present, number if not
|
||||
uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
|
||||
if (lenLabel > 4) {
|
||||
newLongNames = longNames = true;
|
||||
}
|
||||
|
||||
if (lenLabel > 0)
|
||||
lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE);
|
||||
else
|
||||
// Channel name if present, number if not
|
||||
uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name);
|
||||
if (lenLabel > 4) {
|
||||
newLongNames = longNames = true;
|
||||
}
|
||||
|
||||
if (lenLabel > 0)
|
||||
lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE);
|
||||
else
|
||||
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
|
||||
#else
|
||||
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
|
||||
#else
|
||||
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
|
||||
#endif
|
||||
|
||||
// Value
|
||||
LcdFlags flags = TINSIZE;
|
||||
if (m_posVert == ch && !s_noHi) {
|
||||
flags |= INVERS;
|
||||
if (s_editMode)
|
||||
flags |= BLINK;
|
||||
}
|
||||
|
||||
// failsafeValueue
|
||||
LcdFlags flags = TINSIZE;
|
||||
if (m_posVert == ch && !s_noHi) {
|
||||
flags |= INVERS;
|
||||
if (s_editMode)
|
||||
flags |= BLINK;
|
||||
}
|
||||
#if defined(PPM_UNIT_US)
|
||||
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+val/2, flags);
|
||||
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags);
|
||||
#elif defined(PPM_UNIT_PERCENT_PREC1)
|
||||
uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val), PREC1|flags);
|
||||
uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue), PREC1|flags);
|
||||
#else
|
||||
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val)/10, flags);
|
||||
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
|
||||
lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue)/10, flags);
|
||||
#endif
|
||||
|
||||
// Gauge
|
||||
lcd_rect(x+COL_W-3-wbar-ofs, y, wbar+1, 6);
|
||||
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
|
||||
uint8_t len = limit((uint8_t)1, uint8_t((abs(val) * wbar/2 + lim/2) / lim), uint8_t(wbar/2));
|
||||
uint8_t x0 = (val>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-len;
|
||||
lcd_hline(x0, y+1, len);
|
||||
lcd_hline(x0, y+2, len);
|
||||
lcd_hline(x0, y+3, len);
|
||||
lcd_hline(x0, y+4, len);
|
||||
|
||||
|
||||
// Gauge
|
||||
lcd_rect(x+COL_W-3-wbar-ofs, y, wbar+1, 6);
|
||||
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
|
||||
uint8_t len = limit((uint8_t)1, uint8_t((abs(failsafeValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2));
|
||||
uint8_t x0 = (failsafeValue>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-len;
|
||||
lcd_hline(x0, y+1, len);
|
||||
lcd_hline(x0, y+2, len);
|
||||
lcd_hline(x0, y+3, len);
|
||||
lcd_hline(x0, y+4, len);
|
||||
}
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
@@ -988,24 +994,28 @@ void menuModelSetup(uint8_t event)
|
||||
#define IF_EXTERNAL_MODULE_ON(x) (g_model.externalModule == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
|
||||
#define IF_TRAINER_ON(x) (g_model.trainerMode ? (uint8_t)(x) : HIDDEN_ROW)
|
||||
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
|
||||
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
|
||||
#define INTERNAL_MODULE_CHANNELS_ROWS() IF_INTERNAL_MODULE_ON(1)
|
||||
#define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
|
||||
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
|
||||
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS() : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_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 INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
|
||||
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
|
||||
#define TRAINER_CHANNELS_ROWS IF_TRAINER_ON(1)
|
||||
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS))
|
||||
#define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
|
||||
#if defined(MODULE_D16_EU_ONLY_SUPPORT)
|
||||
#define EXTERNAL_MODULE_MODE_ROWS IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)1 : (uint8_t)0
|
||||
#else
|
||||
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
|
||||
#endif
|
||||
#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|NAVIGATION_LINE_BY_LINE, CASE_PERSISTENT_TIMERS(0) 0, 0, 2|NAVIGATION_LINE_BY_LINE, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 7, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_INTERNAL_MODULE_ON(1), IF_INTERNAL_MODULE_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
|
||||
MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2|NAVIGATION_LINE_BY_LINE, CASE_PERSISTENT_TIMERS(0) 0, 0, 2|NAVIGATION_LINE_BY_LINE, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 7, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_INTERNAL_MODULE_ON(1), IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[0].rfProtocol) ? (uint8_t)2 : (uint8_t)1), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS, IF_TRAINER_ON(2)});
|
||||
#elif defined(CPUARM)
|
||||
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
|
||||
#define IF_EXTERNAL_MODULE_ON(x) (g_model.externalModule == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
|
||||
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
|
||||
#define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
|
||||
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
|
||||
#define TRAINER_CHANNELS_ROWS() (HIDDEN_ROW)
|
||||
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS() : 0)
|
||||
#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 PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0)
|
||||
#define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
|
||||
#define CURSOR_ON_CELL (true)
|
||||
#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)
|
||||
@@ -1019,7 +1029,7 @@ void menuModelSetup(uint8_t event)
|
||||
#else
|
||||
#define TRAINER_MODULE_ROWS
|
||||
#endif
|
||||
MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), EXTRA_MODULE_ROWS TRAINER_MODULE_ROWS });
|
||||
MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), EXTRA_MODULE_ROWS TRAINER_MODULE_ROWS });
|
||||
#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)
|
||||
@@ -1107,7 +1117,7 @@ void menuModelSetup(uint8_t event)
|
||||
#if defined(CPUARM)
|
||||
timer->countdownBeep = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, STR_VBEEPCOUNTDOWN, timer->countdownBeep, 0, 2, attr, event);
|
||||
#else
|
||||
timer->countdownBeep = onoffMenuItem(timer->countdownBeep, MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event);
|
||||
timer->countdownBeep = onoffMenuItem(timer->countdownBeep, MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@@ -1235,7 +1245,7 @@ void menuModelSetup(uint8_t event)
|
||||
case ITEM_MODEL_THROTTLE_WARNING:
|
||||
g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event);
|
||||
break;
|
||||
|
||||
|
||||
case ITEM_MODEL_SWITCHES_WARNING:
|
||||
{
|
||||
lcd_putsLeft(y, STR_SWITCHWARNING);
|
||||
@@ -1257,7 +1267,7 @@ void menuModelSetup(uint8_t event)
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
case EVT_KEY_LONG(KEY_ENTER):
|
||||
#if defined(CPUM64)
|
||||
getMovedSwitch();
|
||||
@@ -1274,24 +1284,24 @@ void menuModelSetup(uint8_t event)
|
||||
}
|
||||
#endif
|
||||
killEvents(event);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LcdFlags line = attr;
|
||||
|
||||
|
||||
for (uint8_t i=0; i<NUM_SWITCHES-1; i++) {
|
||||
uint8_t swactive = !(g_model.nSwToWarn & 1 << i);
|
||||
#if defined(PCBTARANIS)
|
||||
c = "\300-\301"[states & 0x03];
|
||||
lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+i*(2*FW+1), y, 'A'+i, line && (m_posHorz == i) ? INVERS : 0);
|
||||
if (swactive) lcd_putc(MODEL_SETUP_2ND_COLUMN+i*(2*FW+1)+FWNUM+1, y, c);
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+((NUM_SWITCHES-1)*2*FW+8), y, PSTR("<]"), (m_posHorz == NUM_SWITCHES-1 && !s_noHi) ? line : 0);
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+((NUM_SWITCHES-1)*2*FW+8), y, PSTR("<]"), (m_posHorz == NUM_SWITCHES-1 && !s_noHi) ? line : 0);
|
||||
states >>= 2;
|
||||
#else
|
||||
attr = 0;
|
||||
|
||||
|
||||
if (IS_3POS(i)) {
|
||||
c = '0'+(states & 0x03);
|
||||
states >>= 2;
|
||||
@@ -1310,7 +1320,7 @@ void menuModelSetup(uint8_t event)
|
||||
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
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -1356,7 +1366,7 @@ void menuModelSetup(uint8_t event)
|
||||
x += (2*FW+3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (attr && (m_posHorz == 0)) {
|
||||
CHECK_INCDEC_MODELVAR(event, potMode, 0, 2);
|
||||
g_model.nPotsToWarn = (g_model.nPotsToWarn & 0x3F) | ((potMode << 6) & 0xC0);
|
||||
@@ -1542,7 +1552,7 @@ void menuModelSetup(uint8_t event)
|
||||
else {
|
||||
horzpos_t l_posHorz = m_posHorz;
|
||||
uint8_t xOffsetBind = MODEL_SETUP_BIND_OFS;
|
||||
if (IS_MODULE_XJT(moduleIdx) && IS_D8_RX(moduleIdx)) {
|
||||
if (IS_MODULE_XJT(moduleIdx) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[moduleIdx].rfProtocol)) {
|
||||
xOffsetBind = 0;
|
||||
lcd_putsLeft(y, INDENT "Receiver");
|
||||
if (attr) l_posHorz += 1;
|
||||
@@ -2216,7 +2226,7 @@ void menuModelFlightModesAll(uint8_t event)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (p->fadeIn || p->fadeOut)
|
||||
if (p->fadeIn || p->fadeOut)
|
||||
lcd_putc(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, (p->fadeIn && p->fadeOut) ? '*' : (p->fadeIn ? 'I' : 'O'));
|
||||
|
||||
}
|
||||
@@ -3189,7 +3199,7 @@ void menuModelMixOne(uint8_t event)
|
||||
if ((m_posVert == MIX_FIELD_TRIM && md2->srcRaw > NUM_STICKS) || (m_posVert == MIX_FIELD_CURVE && md2->curveMode == MODE_CURVE))
|
||||
#else
|
||||
if (m_posVert == MIX_FIELD_TRIM && md2->srcRaw > NUM_STICKS)
|
||||
#endif
|
||||
#endif
|
||||
SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, CASE_9X(0) CASE_CURVES(0) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/})
|
||||
else
|
||||
SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, CASE_9X(1) CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/});
|
||||
@@ -3508,7 +3518,7 @@ void displayExpoInfos(uint8_t y, ExpoData *ed)
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
void displayExpoLine(uint8_t y, ExpoData *ed)
|
||||
{
|
||||
{
|
||||
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0);
|
||||
|
||||
if (ed->carryTrim != TRIM_ON) {
|
||||
@@ -3519,7 +3529,7 @@ void displayExpoLine(uint8_t y, ExpoData *ed)
|
||||
displayExpoInfos(y, ed);
|
||||
else
|
||||
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes);
|
||||
|
||||
|
||||
if (ed->name[0]) {
|
||||
lcd_putsnAtt(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR);
|
||||
}
|
||||
@@ -3528,7 +3538,7 @@ void displayExpoLine(uint8_t y, ExpoData *ed)
|
||||
void displayExpoLine(uint8_t y, ExpoData *ed)
|
||||
{
|
||||
displayExpoInfos(y, ed);
|
||||
|
||||
|
||||
if (ed->name[0]) {
|
||||
lcd_putsnAtt(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR);
|
||||
}
|
||||
@@ -3536,7 +3546,7 @@ void displayExpoLine(uint8_t y, ExpoData *ed)
|
||||
#else
|
||||
#define displayExpoLine(y, ed) \
|
||||
displayExpoInfos(y, ed); \
|
||||
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes)
|
||||
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes)
|
||||
#endif
|
||||
|
||||
void menuModelExpoMix(uint8_t expo, uint8_t event)
|
||||
@@ -3735,13 +3745,13 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
|
||||
s_currIdx = i;
|
||||
}
|
||||
if (s_pgOfs < cur && cur-s_pgOfs < 8) {
|
||||
uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
|
||||
uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
|
||||
if (expo) {
|
||||
ed->weight = GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, event);
|
||||
displayExpoLine(y, ed);
|
||||
if (ed->mode!=3) {
|
||||
lcd_putc(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if LCD_W >= 212
|
||||
@@ -3757,7 +3767,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
|
||||
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event);
|
||||
|
||||
displayMixLine(y, md);
|
||||
|
||||
|
||||
char cs = ' ';
|
||||
if (md->speedDown || md->speedUp)
|
||||
cs = 'S';
|
||||
@@ -5645,7 +5655,7 @@ enum menuModelTelemetryItems {
|
||||
#if defined(FAS_OFFSET) || !defined(CPUM64)
|
||||
#define IF_FAS_OFFSET(x) x,
|
||||
#else
|
||||
#define IF_FAS_OFFSET(x)
|
||||
#define IF_FAS_OFFSET(x)
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
@@ -5884,7 +5894,7 @@ void menuModelTelemetry(uint8_t event)
|
||||
lcd_putsiAtt(TELEM_COL2, y, STR_AMPSRC, g_model.frsky.currentSource, attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.frsky.currentSource, FRSKY_CURRENT_SOURCE_LAST);
|
||||
break;
|
||||
|
||||
|
||||
#if defined(FAS_OFFSET) || !defined(CPUM64)
|
||||
case ITEM_TELEMETRY_FAS_OFFSET:
|
||||
lcd_putsLeft(y, STR_FAS_OFFSET);
|
||||
@@ -5898,7 +5908,7 @@ void menuModelTelemetry(uint8_t event)
|
||||
#if defined(CPUARM)
|
||||
case ITEM_TELEMTETRY_PERSISTENT_MAH:
|
||||
g_model.frsky.mAhPersistent = onoffMenuItem(g_model.frsky.mAhPersistent, TELEM_COL2, y, STR_PERSISTENT_MAH, attr, event);
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(VARIO)
|
||||
|
||||
@@ -398,7 +398,7 @@ void displayBattVoltage()
|
||||
LcdFlags att = (g_vbat100mV <= g_eeGeneral.vBatWarn ? BLINK|INVERS : 0) | BIGSIZE;
|
||||
putsVBat(VBATT_X-1, VBATT_Y, att|NO_UNIT);
|
||||
#if LCD_W >= 212
|
||||
lcd_putcAtt(VBATTUNIT_X, VBATTUNIT_Y, 'v', MIDSIZE);
|
||||
lcd_putcAtt(VBATTUNIT_X, VBATTUNIT_Y, 'V', MIDSIZE);
|
||||
#else
|
||||
lcd_putc(VBATT_X, VBATTUNIT_Y, 'V');
|
||||
#endif
|
||||
|
||||
@@ -666,7 +666,7 @@ void putsTimer(xcoord_t x, uint8_t y, putstime_t tme, LcdFlags att, LcdFlags att
|
||||
void putsVolts(xcoord_t x, uint8_t y, uint16_t volts, LcdFlags att)
|
||||
{
|
||||
lcd_outdezAtt(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1)));
|
||||
if (~att & NO_UNIT) lcd_putcAtt(lcdLastPos, y, 'v', att);
|
||||
if (~att & NO_UNIT) lcd_putcAtt(lcdLastPos, y, 'V', att);
|
||||
}
|
||||
|
||||
void putsVBat(xcoord_t x, uint8_t y, LcdFlags att)
|
||||
@@ -1079,7 +1079,7 @@ void putsTelemetryChannel(xcoord_t x, uint8_t y, uint8_t channel, lcdint_t val,
|
||||
case TELEM_TX_VOLTAGE-1:
|
||||
lcd_outdezAtt(x, y, val, (att|PREC1) & (~NO_UNIT));
|
||||
if (!(att & NO_UNIT))
|
||||
lcd_putc(lcdLastPos/*+1*/, y, 'v');
|
||||
lcd_putc(lcdLastPos/*+1*/, y, 'V');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -689,7 +689,7 @@ static int luaModelInsertInput(lua_State *L)
|
||||
unsigned int first = getFirstInput(chn);
|
||||
unsigned int count = getInputsCountFromFirst(chn, first);
|
||||
|
||||
if (chn<MAX_INPUTS && getExpoMixCount(1)<MAX_INPUTS && idx<=count) {
|
||||
if (chn<MAX_INPUTS && getExpoMixCount(1)<MAX_EXPOS && idx<=count) {
|
||||
idx = first + idx;
|
||||
s_currCh = chn + 1;
|
||||
insertExpoMix(1, idx);
|
||||
|
||||
@@ -1676,11 +1676,21 @@ enum Protocols {
|
||||
enum RFProtocols {
|
||||
RF_PROTO_OFF = -1,
|
||||
RF_PROTO_X16,
|
||||
#if defined(MODULE_D16_EU_ONLY_SUPPORT)
|
||||
RF_PROTO_LAST = RF_PROTO_X16
|
||||
#else
|
||||
RF_PROTO_D8,
|
||||
RF_PROTO_LR12,
|
||||
RF_PROTO_LAST = RF_PROTO_LR12
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(MODULE_D16_EU_ONLY_SUPPORT)
|
||||
#define HAS_RF_PROTOCOL_FAILSAFE(protocol) ((protocol) == RF_PROTO_X16)
|
||||
#else
|
||||
#define HAS_RF_PROTOCOL_FAILSAFE(protocol) ((protocol) == RF_PROTO_X16 || (protocol) == RF_PROTO_LR12)
|
||||
#endif
|
||||
|
||||
enum DSM2Protocols {
|
||||
DSM2_PROTO_LP45,
|
||||
DSM2_PROTO_DSM2,
|
||||
|
||||
@@ -247,7 +247,7 @@ void per10ms()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FRSKY) || defined(JETI) || defined(SIMU)
|
||||
#if defined(FRSKY) || defined(JETI)
|
||||
if (!IS_DSM2_SERIAL_PROTOCOL(s_current_protocol[0]))
|
||||
telemetryInterrupt10ms();
|
||||
#endif
|
||||
@@ -2076,9 +2076,11 @@ void evalFunctions()
|
||||
}
|
||||
|
||||
case FUNC_BACKGND_MUSIC:
|
||||
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC);
|
||||
if (!IS_PLAYING(i+1)) {
|
||||
playCustomFunctionFile(sd, i+1);
|
||||
if (!(newActiveFunctions & (1 << FUNCTION_BACKGND_MUSIC))) {
|
||||
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC);
|
||||
if (!IS_PLAYING(i+1)) {
|
||||
playCustomFunctionFile(sd, i+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -171,7 +171,9 @@ void setupPulsesDSM2(unsigned int port)
|
||||
dsmDat[1] = g_model.header.modelId; // DSM2 Header second byte for model match
|
||||
|
||||
for (int i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, ((channelOutputs[g_model.moduleData[port].channelsStart+i]*13)>>5)+512, 1023);
|
||||
int channel = g_model.moduleData[port].channelsStart+i;
|
||||
int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER;
|
||||
uint16_t pulse = limit(0, ((value*13)>>5)+512, 1023);
|
||||
dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03);
|
||||
dsmDat[3+2*i] = pulse & 0xff;
|
||||
}
|
||||
|
||||
@@ -243,9 +243,9 @@ void setupPulsesPXX(unsigned int port)
|
||||
}
|
||||
else {
|
||||
if (i < sendUpperChannels)
|
||||
chan = limit(2049, PPM_CH_CENTER(8+g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[8+g_model.moduleData[port].channelsStart+i] * 512 / 682) + 3072, 4094);
|
||||
chan = limit(2049, PPM_CH_CENTER(8+g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[8+i] * 512 / 682) + 3072, 4094);
|
||||
else
|
||||
chan = limit(1, PPM_CH_CENTER(g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[g_model.moduleData[port].channelsStart+i] * 512 / 682) + 1024, 2046);
|
||||
chan = limit(1, PPM_CH_CENTER(g_model.moduleData[port].channelsStart+i) - PPM_CENTER + (g_model.moduleData[port].failsafeChannels[i] * 512 / 682) + 1024, 2046);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -421,6 +421,8 @@ int main(int argc,char **argv)
|
||||
|
||||
printf("Model size = %d\n", (int)sizeof(g_model));
|
||||
|
||||
simuInit();
|
||||
|
||||
StartEepromThread(argc >= 2 ? argv[1] : "eeprom.bin");
|
||||
StartAudioThread();
|
||||
StartMainThread();
|
||||
|
||||
+14
-1
@@ -219,7 +219,12 @@ bool getLogicalSwitch(uint8_t idx)
|
||||
#endif
|
||||
|
||||
if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) {
|
||||
#if defined(CPUARM)
|
||||
if (ls->func != LS_FUNC_STICKY && ls->func != LS_FUNC_STAY ) {
|
||||
#else
|
||||
if (ls->func != LS_FUNC_STICKY) {
|
||||
#endif
|
||||
// AND switch must not affect STICKY and EDGE (STAY) processing
|
||||
LS_LAST_VALUE(mixerCurrentFlightMode, idx) = CS_LAST_VALUE_INIT;
|
||||
}
|
||||
result = false;
|
||||
@@ -378,7 +383,7 @@ DurationAndDelayProcessing:
|
||||
if (context.timerState == SWITCH_START) {
|
||||
// set delay timer
|
||||
context.timerState = SWITCH_DELAY;
|
||||
context.timer = ls->delay;
|
||||
context.timer = (ls->func == LS_FUNC_STAY ? 0 : ls->delay);
|
||||
}
|
||||
|
||||
if (context.timerState == SWITCH_DELAY) {
|
||||
@@ -776,6 +781,13 @@ void logicalSwitchesTimerTick()
|
||||
#if defined(CPUARM)
|
||||
else if (ls->func == LS_FUNC_STAY) {
|
||||
ls_stay_struct & lastValue = (ls_stay_struct &)LS_LAST_VALUE(fm, i);
|
||||
// if this ls was reset by the logicalSwitchesReset() the lastValue will be set to CS_LAST_VALUE_INIT(0x8000)
|
||||
// when it is unpacked into ls_stay_struct the lastValue.duration will have a value of 0x4000
|
||||
// this will produce an instant true for edge logical switch if the second parameter is big enough.
|
||||
// So we reset it here.
|
||||
if (LS_LAST_VALUE(fm, i) == CS_LAST_VALUE_INIT) {
|
||||
lastValue.duration = 0;
|
||||
}
|
||||
lastValue.state = false;
|
||||
bool state = getSwitch(ls->v1);
|
||||
if (state) {
|
||||
@@ -834,6 +846,7 @@ int16_t lswTimerValue(delayval_t val)
|
||||
void logicalSwitchesReset()
|
||||
{
|
||||
#if defined(CPUARM)
|
||||
flightModeTransitionLast = 255;
|
||||
memset(lswFm, 0, sizeof(lswFm));
|
||||
#else
|
||||
s_last_switch_value = 0;
|
||||
|
||||
@@ -109,6 +109,14 @@ char simuSdDirectory[1024] = "";
|
||||
uint8_t eeprom[EESIZE_SIMU];
|
||||
sem_t *eeprom_write_sem;
|
||||
|
||||
void simuInit()
|
||||
{
|
||||
for (int i = 0; i <= 17; i++) {
|
||||
simuSetSwitch(i, 0);
|
||||
simuSetKey(i, false); // a little dirty, but setting keys that don't exist is perfectly OK here
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CPUARM)
|
||||
#if defined(PCBTARANIS)
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
@@ -380,7 +388,21 @@ void StartMainThread(bool tests)
|
||||
pthread_mutex_init(&audioMutex, NULL);
|
||||
#endif
|
||||
|
||||
g_tmr10ms = 1; // must be non-zero otherwise some SF functions (that use this timer as a marker when it was last executed) will be executed twice on startup
|
||||
/*
|
||||
g_tmr10ms must be non-zero otherwise some SF functions (that use this timer as a marker when it was last executed)
|
||||
will be executed twice on startup. Normal radio does not see this issue because g_tmr10ms is already a big number
|
||||
before the first call to the Special Functions. Not so in the simulator.
|
||||
|
||||
There is another issue, some other function static variables depend on this value. If simulator is started
|
||||
multiple times in one Companion session, they are set to their initial values only first time the simulator
|
||||
is started. Therefore g_tmr10ms must also be set to non-zero value only the first time, then it must be left
|
||||
alone to continue from the previous simulator session value. See the issue #2446
|
||||
|
||||
*/
|
||||
if (g_tmr10ms == 0) {
|
||||
g_tmr10ms = 1;
|
||||
}
|
||||
|
||||
#if defined(RTCLOCK)
|
||||
g_rtcTime = time(0);
|
||||
#endif
|
||||
@@ -396,7 +418,16 @@ void StopMainThread()
|
||||
}
|
||||
|
||||
#if defined(CPUARM)
|
||||
int Volume = volumeScale[VOLUME_LEVEL_DEF];
|
||||
|
||||
struct SimulatorAudio {
|
||||
int volumeGain;
|
||||
int currentVolume;
|
||||
uint16_t leftoverData[AUDIO_BUFFER_SIZE];
|
||||
int leftoverLen;
|
||||
bool threadRunning;
|
||||
pthread_t threadPid;
|
||||
} simuAudio;
|
||||
|
||||
bool dacQueue(AudioBuffer *buffer)
|
||||
{
|
||||
return false;
|
||||
@@ -404,33 +435,31 @@ bool dacQueue(AudioBuffer *buffer)
|
||||
|
||||
void setVolume(uint8_t volume)
|
||||
{
|
||||
Volume = volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)];
|
||||
simuAudio.currentVolume = min<int>((volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)] * simuAudio.volumeGain) / 10, 127);
|
||||
// TRACE("setVolume(): in: %u, out: %u", volume, simuAudio.currentVolume);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SIMU_AUDIO) && defined(CPUARM)
|
||||
|
||||
int leftover_len = 0;
|
||||
uint16_t leftover_data[AUDIO_BUFFER_SIZE];
|
||||
|
||||
void copyBuffer(uint8_t * dest, uint16_t * buff, unsigned int samples)
|
||||
{
|
||||
for(unsigned int i=0; i<samples; i++) {
|
||||
int sample = ((int32_t)(uint32_t)(buff[i]) - 0x8000); // conversion from uint16_t
|
||||
*((uint16_t*)dest) = (int16_t)((sample * Volume)/127);
|
||||
*((uint16_t*)dest) = (int16_t)((sample * simuAudio.currentVolume)/127);
|
||||
dest += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_audio(void *udata, Uint8 *stream, int len)
|
||||
void fillAudioBuffer(void *udata, Uint8 *stream, int len)
|
||||
{
|
||||
SDL_memset(stream, 0, len);
|
||||
|
||||
if (leftover_len) {
|
||||
copyBuffer(stream, leftover_data, leftover_len);
|
||||
len -= leftover_len*2;
|
||||
stream += leftover_len*2;
|
||||
leftover_len = 0;
|
||||
if (simuAudio.leftoverLen) {
|
||||
copyBuffer(stream, simuAudio.leftoverData, simuAudio.leftoverLen);
|
||||
len -= simuAudio.leftoverLen*2;
|
||||
stream += simuAudio.leftoverLen*2;
|
||||
simuAudio.leftoverLen = 0;
|
||||
// putchar('l');
|
||||
}
|
||||
|
||||
@@ -447,8 +476,8 @@ void fill_audio(void *udata, Uint8 *stream, int len)
|
||||
else {
|
||||
//partial
|
||||
copyBuffer(stream, nextBuffer->data, len/2);
|
||||
leftover_len = (nextBuffer->size-len/2);
|
||||
memcpy(leftover_data, &nextBuffer->data[len/2], leftover_len*2);
|
||||
simuAudio.leftoverLen = (nextBuffer->size-len/2);
|
||||
memcpy(simuAudio.leftoverData, &nextBuffer->data[len/2], simuAudio.leftoverLen*2);
|
||||
len = 0;
|
||||
// putchar('p');
|
||||
break;
|
||||
@@ -467,9 +496,7 @@ void fill_audio(void *udata, Uint8 *stream, int len)
|
||||
}
|
||||
}
|
||||
|
||||
bool audio_thread_running = false;
|
||||
|
||||
void *audio_thread(void *)
|
||||
void * audioThread(void *)
|
||||
{
|
||||
/*
|
||||
Checking here if SDL audio was initialized is wrong, because
|
||||
@@ -488,7 +515,7 @@ void *audio_thread(void *)
|
||||
wanted.format = AUDIO_S16SYS;
|
||||
wanted.channels = 1; /* 1 = mono, 2 = stereo */
|
||||
wanted.samples = AUDIO_BUFFER_SIZE*2; /* Good low-latency value for callback */
|
||||
wanted.callback = fill_audio;
|
||||
wanted.callback = fillAudioBuffer;
|
||||
wanted.userdata = NULL;
|
||||
|
||||
/*
|
||||
@@ -501,7 +528,7 @@ void *audio_thread(void *)
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
while (audio_thread_running) {
|
||||
while (simuAudio.threadRunning) {
|
||||
audioQueue.wakeup();
|
||||
sleep(1);
|
||||
}
|
||||
@@ -509,26 +536,28 @@ void *audio_thread(void *)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t audio_thread_pid;
|
||||
|
||||
void StartAudioThread()
|
||||
void StartAudioThread(int volumeGain)
|
||||
{
|
||||
simuAudio.leftoverLen = 0;
|
||||
simuAudio.threadRunning = true;
|
||||
simuAudio.volumeGain = volumeGain;
|
||||
setVolume(VOLUME_LEVEL_DEF);
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
struct sched_param sp;
|
||||
sp.sched_priority = SCHED_RR;
|
||||
pthread_attr_setschedparam(&attr, &sp);
|
||||
pthread_create(&audio_thread_pid, &attr, &audio_thread, NULL);
|
||||
audio_thread_running = true;
|
||||
pthread_create(&simuAudio.threadPid, &attr, &audioThread, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
void StopAudioThread()
|
||||
{
|
||||
audio_thread_running = false;
|
||||
pthread_join(audio_thread_pid, NULL);
|
||||
simuAudio.threadRunning = false;
|
||||
pthread_join(simuAudio.threadPid, NULL);
|
||||
}
|
||||
#endif // #if defined(CPUARM)
|
||||
#endif // #if defined(SIMU_AUDIO) && defined(CPUARM)
|
||||
|
||||
pthread_t eeprom_thread_pid;
|
||||
|
||||
@@ -673,28 +702,26 @@ char *findTrueFileName(const char *path)
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
_splitpath(path, drive, dir, fname, ext);
|
||||
std::string fileName = std::string(fname) + "." + std::string(ext);
|
||||
std::string fileName = std::string(fname) + std::string(ext);
|
||||
std::string dirName = std::string(drive) + std::string(dir);
|
||||
if (dir) {
|
||||
// TRACE("\tsearching for: %s", fileName.c_str());
|
||||
WIN32_FIND_DATA ffd;
|
||||
HANDLE hFind = FindFirstFile(dirName.c_str(), &ffd);
|
||||
if (INVALID_HANDLE_VALUE != hFind) {
|
||||
do {
|
||||
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) {
|
||||
// TRACE("comparing with: %s", ffd.cFileName);
|
||||
if (!strcasecmp(fileName.c_str(), ffd.cFileName)) {
|
||||
strcpy(result, dirName.c_str());
|
||||
strcat(result, "/");
|
||||
strcat(result, ffd.cFileName);
|
||||
TRACE("\tfound: %s", ffd.cFileName);
|
||||
fileMap.insert(filemap_t:: value_type(path, result));
|
||||
return result;
|
||||
}
|
||||
std::string searchName = dirName + "*";
|
||||
// TRACE("\tsearching for: %s", fileName.c_str());
|
||||
WIN32_FIND_DATA ffd;
|
||||
HANDLE hFind = FindFirstFile(searchName.c_str(), &ffd);
|
||||
if (INVALID_HANDLE_VALUE != hFind) {
|
||||
do {
|
||||
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
//TRACE("comparing with: %s", ffd.cFileName);
|
||||
if (!strcasecmp(fileName.c_str(), ffd.cFileName)) {
|
||||
strcpy(result, dirName.c_str());
|
||||
strcat(result, ffd.cFileName);
|
||||
TRACE("\tfound: %s", ffd.cFileName);
|
||||
fileMap.insert(filemap_t:: value_type(path, result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
while (FindNextFile(hFind, &ffd) != 0);
|
||||
}
|
||||
while (FindNextFile(hFind, &ffd) != 0);
|
||||
}
|
||||
#else
|
||||
strcpy(result, path);
|
||||
@@ -707,7 +734,11 @@ char *findTrueFileName(const char *path)
|
||||
for (;;) {
|
||||
struct simu::dirent * res = simu::readdir(dir);
|
||||
if (res == 0) break;
|
||||
#if defined(__APPLE__)
|
||||
if ((res->d_type == DT_REG) || (res->d_type == DT_LNK)) {
|
||||
#else
|
||||
if ((res->d_type == simu::DT_REG) || (res->d_type == simu::DT_LNK)) {
|
||||
#endif
|
||||
// TRACE("comparing with: %s", res->d_name);
|
||||
if (!strcasecmp(fileName.c_str(), res->d_name)) {
|
||||
strcpy(result, dirName.c_str());
|
||||
@@ -861,8 +892,14 @@ FRESULT f_mkdir (const TCHAR*)
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
FRESULT f_unlink (const TCHAR*)
|
||||
FRESULT f_unlink (const TCHAR* name)
|
||||
{
|
||||
char *path = convertSimuPath(name);
|
||||
if (unlink(path)) {
|
||||
TRACE("f_unlink(%s) = error %d (%s)", path, errno, strerror(errno));
|
||||
return FR_INVALID_NAME;
|
||||
}
|
||||
TRACE("f_unlink(%s) = OK", path);
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
@@ -892,7 +929,22 @@ int f_printf (FIL *fil, const TCHAR * format, ...)
|
||||
|
||||
FRESULT f_getcwd (TCHAR *path, UINT sz_path)
|
||||
{
|
||||
strcpy(path, ".");
|
||||
char cwd[1024];
|
||||
if (!getcwd(cwd, 1024)) {
|
||||
TRACE("f_getcwd() = getcwd() error %d (%s)", errno, strerror(errno));
|
||||
strcpy(path, ".");
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
|
||||
if (strlen(cwd) < strlen(simuSdDirectory)) {
|
||||
TRACE("f_getcwd() = logic error strlen(cwd) < strlen(simuSdDirectory): cwd: \"%s\", simuSdDirectory: \"%s\"", cwd, simuSdDirectory);
|
||||
strcpy(path, ".");
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
|
||||
// remove simuSdDirectory from the cwd
|
||||
strcpy(path, cwd + strlen(simuSdDirectory));
|
||||
TRACE("f_getcwd() = %s", path);
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -345,6 +345,7 @@ extern uint8_t main_thread_running;
|
||||
|
||||
#define SIMU_SLEEP(x) do { if (!main_thread_running) return; sleep(x/*ms*/); } while (0)
|
||||
|
||||
void simuInit();
|
||||
void simuSetKey(uint8_t key, bool state);
|
||||
void simuSetTrim(uint8_t trim, bool state);
|
||||
void simuSetSwitch(uint8_t swtch, int8_t state);
|
||||
@@ -354,7 +355,7 @@ void StopMainThread();
|
||||
void StartEepromThread(const char *filename="eeprom.bin");
|
||||
void StopEepromThread();
|
||||
#if defined(SIMU_AUDIO) && defined(CPUARM)
|
||||
void StartAudioThread(void);
|
||||
void StartAudioThread(int volumeGain = 10);
|
||||
void StopAudioThread(void);
|
||||
#else
|
||||
#define StartAudioThread()
|
||||
|
||||
@@ -136,6 +136,12 @@ void adcRead()
|
||||
Analog_values[i] = 0;
|
||||
}
|
||||
#endif
|
||||
if (IS_POT(i) && !IS_POT_AVAILABLE(i)) {
|
||||
// Use fixed analog value for non-existing and/or non-connected pots.
|
||||
// Non-connected analog inputs will slightly follow the adjacent connected analog inputs,
|
||||
// which produces ghost readings on these inputs.
|
||||
Analog_values[i] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ void parseTelemHubByte(uint8_t byte)
|
||||
byte = byte ^ 0x60;
|
||||
state = (TS_STATE)(state - TS_XOR);
|
||||
}
|
||||
if (byte == 0x5d) {
|
||||
else if (byte == 0x5d) {
|
||||
state = (TS_STATE)(state | TS_XOR);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,13 @@ inline void MIXER_RESET()
|
||||
logicalSwitchesReset();
|
||||
}
|
||||
|
||||
#if defined(FRSKY)
|
||||
inline void TELEMETRY_RESET()
|
||||
{
|
||||
memclear(&frskyData, sizeof(frskyData));
|
||||
frskyData.rssi[0].value = 100;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool checkScreenshot(QString test);
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 904 B After Width: | Height: | Size: 909 B |
@@ -361,3 +361,196 @@ TEST(getSwitch, inputWithTrim)
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
|
||||
/*
|
||||
PACK(typedef struct t_LogicalSwitchData { // Logical Switches data
|
||||
int8_t v1;
|
||||
int16_t v2;
|
||||
int16_t v3;
|
||||
uint8_t func;
|
||||
uint8_t delay;
|
||||
uint8_t duration;
|
||||
int8_t andsw;
|
||||
}) LogicalSwitchData;
|
||||
*/
|
||||
TEST(getSwitch, edgeInstant)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
// LS1 setup: EDGE SFup (0:instant)
|
||||
// LS2 setup: (EDGE SFup (0:instant)) AND SAup
|
||||
g_model.logicalSw[0] = { SWSRC_SF2, -129, -1, LS_FUNC_STAY };
|
||||
g_model.logicalSw[1] = { SWSRC_SF2, -129, -1, LS_FUNC_STAY, 0, 0, SWSRC_SA2 };
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), false);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now trigger SFup, LS1 should become true
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), true);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now release SA0 and SW2 should stay true
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now reset logical switches
|
||||
logicalSwitchesReset();
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
|
||||
// second part with SAup
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), false);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now trigger SFup, LS1 should become true
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), true);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), true);
|
||||
|
||||
// now release SA0 and SW2 should stay true
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now reset logical switches
|
||||
logicalSwitchesReset();
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now bug #2939
|
||||
// SF is kept up and SA is toggled
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
//test what happens when EDGE condition is true and
|
||||
//logical switches are reset - the switch should fire again
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false); //switch will not trigger, because SF was already up
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
logicalSwitchesReset();
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), true);
|
||||
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
}
|
||||
|
||||
TEST(getSwitch, edgeRelease)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
// test for issue #2728
|
||||
// LS1 setup: EDGE SFup (0:release)
|
||||
// LS2 setup: (EDGE SFup (0:release)) AND SAup
|
||||
g_model.logicalSw[0] = { SWSRC_SF2, -129, 0, LS_FUNC_STAY };
|
||||
g_model.logicalSw[1] = { SWSRC_SF2, -129, 0, LS_FUNC_STAY, 0, 0, SWSRC_SA2 };
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
|
||||
// second part with SAup
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), true);
|
||||
|
||||
// with switches reset both should remain false
|
||||
logicalSwitchesReset();
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
}
|
||||
|
||||
#endif // #if defined(CPUARM)
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 986 B |
+2
-2
@@ -42,8 +42,8 @@
|
||||
#define TMR_NEGATIVE 2
|
||||
#define TMR_STOPPED 3
|
||||
|
||||
#define TIMER_MAX (32767)
|
||||
#define TIMER_MIN (-32767-1)
|
||||
#define TIMER_MIN (-0xffff/2)
|
||||
#define TIMER_MAX (-TIMER_MIN-1)
|
||||
|
||||
struct TimerState {
|
||||
uint16_t cnt;
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metr.\0""Imper.", "Metrické""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
@@ -706,7 +706,7 @@
|
||||
#define TR_RESTORE_MODEL "Obnov model z SD"
|
||||
#define TR_SDCARD_ERROR "Chyba SD karty"
|
||||
#define TR_NO_SDCARD "Není SD karta"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_SDCARD_FULL "SD je již plná"
|
||||
#define TR_INCOMPATIBLE "Nekompatibilní"
|
||||
#define TR_WARNING "KONTROLA"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
@@ -765,7 +765,7 @@
|
||||
#define TR_DATE "Datum"
|
||||
#define TR_ROTARY_ENCODER "R.Encs"
|
||||
#define TR_CHANNELS_MONITOR "MONITOR KANÁLU"
|
||||
#define TR_MIXERS_MONITOR "MIXERS MONITOR"
|
||||
#define TR_MIXERS_MONITOR "MONITOR MIXU"
|
||||
#define TR_PATH_TOO_LONG "Cesta je moc dlouhá"
|
||||
#define TR_VIEW_TEXT "Zobrazit text"
|
||||
#define TR_FLASH_BOOTLOADER "Flash BootLoader"
|
||||
|
||||
@@ -100,8 +100,13 @@
|
||||
#define LEN_TARANIS_PROTOCOLS "\004"
|
||||
#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM2"
|
||||
|
||||
#define LEN_XJT_PROTOCOLS "\004"
|
||||
#define TR_XJT_PROTOCOLS "AUS\0""D16\0""D8\0 ""LR12"
|
||||
#if defined(MODULE_D16_EU_ONLY_SUPPORT)
|
||||
#define LEN_XJT_PROTOCOLS "\006"
|
||||
#define TR_XJT_PROTOCOLS "AUS\0 ""D16-EU"
|
||||
#else
|
||||
#define LEN_XJT_PROTOCOLS "\004"
|
||||
#define TR_XJT_PROTOCOLS "AUS\0""D16\0""D8\0 ""LR12"
|
||||
#endif
|
||||
|
||||
#define LEN_DSM_PROTOCOLS "\004"
|
||||
#define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX"
|
||||
@@ -561,12 +566,12 @@
|
||||
#define TR_MIXER "MISCHER"
|
||||
#define TR_CV "KV"
|
||||
#define TR_GV "GV"
|
||||
#define TR_ACHANNEL TR("A\004gemessen","A\004Kanal gemessen =>") //9XR-Pro
|
||||
#define TR_RANGE TR(INDENT"Bereich",INDENT"Messbereich") //9XR-Pro
|
||||
#define TR_ACHANNEL TR("A\004gemessen", "A\004Kanal gemessen =>") // 9XR-Pro
|
||||
#define TR_RANGE TR(INDENT"Bereich", INDENT "Reichweite") // 9XR-Pro
|
||||
#define TR_BAR "Streifen"
|
||||
#define TR_ALARM INDENT"Alarm"
|
||||
#define TR_USRDATA "Daten berechnen aus"
|
||||
#define TR_BLADES TR(INDENT"Prop",INDENT"Prop-Blätter") //9XR-Pro
|
||||
#define TR_BLADES TR(INDENT"Prop", INDENT "Prop-Blätter") // 9XR-Pro
|
||||
#define TR_SCREEN "Telm-Bild "
|
||||
#define TR_SOUND_LABEL "----Töne---------"
|
||||
#define TR_LENGTH INDENT"Dauer"
|
||||
|
||||
@@ -344,9 +344,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -356,7 +356,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\012")
|
||||
#define TR_VUNITSSYSTEM TR("Métr.\0""Impér.", "Métriques\0""Impériales")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\011")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metriche\0""Imperiali")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
@@ -381,7 +381,7 @@
|
||||
|
||||
#define LEN_VARIOSRC "\005"
|
||||
#if defined(FRSKY_SPORT)
|
||||
#define TR_VARIOSRC "Vario""A1\0 ""A2\0 "
|
||||
#define TR_VARIOSRC "Vario""A1\0 ""A2\0 ""dTE\0 "
|
||||
#else
|
||||
#define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0 "
|
||||
#endif
|
||||
@@ -562,9 +562,9 @@
|
||||
#define TR_CV "CV"
|
||||
#define TR_GV "GV"
|
||||
#define TR_ACHANNEL "A\002ingresso"
|
||||
#define TR_RANGE tr(INDENT"Campo",INDENT"Campo")
|
||||
#define TR_RANGE INDENT "Campo"
|
||||
#define TR_BAR "Barra"
|
||||
#define TR_ALARM tr(INDENT"Allar.",INDENT"Allarme")
|
||||
#define TR_ALARM TR(INDENT"Allar.", INDENT"Allarme")
|
||||
#define TR_USRDATA "Dati"
|
||||
#define TR_BLADES INDENT"Pale"
|
||||
#define TR_SCREEN "Schermo "
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metr. ""Imper.", "Metryczn""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_METR LENGTH_UNIT_METR "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT_IMP LENGTH_UNIT_IMP "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
@@ -342,9 +342,9 @@
|
||||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metri.""Imper.", "Metriska""Imperial")
|
||||
#define LEN_VTELEMUNIT_METR "\003"
|
||||
#define TR_VTELEMUNIT_METR "v\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_METR "V\0 ""A\0 ""m/s""-\0 ""kmh""m\0 ""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define LEN_VTELEMUNIT_IMP "\003"
|
||||
#define TR_VTELEMUNIT_IMP "v\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT_IMP "V\0 ""A\0 ""m/s""-\0 ""kts""ft\0""@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#else
|
||||
#if defined(IMPERIAL_UNITS)
|
||||
#define LENGTH_UNIT LENGTH_UNIT_IMP
|
||||
@@ -354,7 +354,7 @@
|
||||
#define SPEED_UNIT SPEED_UNIT_METR
|
||||
#endif
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#define TR_VTELEMUNIT "V\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh""W\0 "
|
||||
#endif
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
import time
|
||||
import re
|
||||
import re
|
||||
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
inputFile = sys.argv[1]
|
||||
inp = open(inputFile, "r")
|
||||
else:
|
||||
inp = sys.stdin
|
||||
|
||||
pattern = re.compile("#\d+")
|
||||
while True:
|
||||
skip = False
|
||||
line = inp.readline()
|
||||
if len(line) == 0:
|
||||
break
|
||||
line = line.strip('\r\n')
|
||||
|
||||
if len(line) == 0:
|
||||
skip = True
|
||||
if line.startswith("<"):
|
||||
skip = True
|
||||
if line.startswith("["):
|
||||
skip = True
|
||||
|
||||
if not skip:
|
||||
#line = line.strip()
|
||||
#print "line: %s" % line
|
||||
found = re.findall(pattern, line)
|
||||
if len(found) > 0:
|
||||
for issue in found:
|
||||
line = line.replace(issue, '')
|
||||
#add issues
|
||||
issue_links = ["<a href=https://github.com/opentx/opentx/issues/%d>#%d</a>" % (int(issue[1:]), int(issue[1:])) for issue in found]
|
||||
links = "(" + ", ".join(issue_links) + ")"
|
||||
line = "<li>" + line + " " + links + "</li>"
|
||||
|
||||
print line
|
||||
|
||||
|
||||
inp.close()
|
||||
sys.exit(0)
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Stops on first error, echo on
|
||||
set -e
|
||||
set -x
|
||||
|
||||
cd radio/src/
|
||||
|
||||
# OpenTX on 9X stock
|
||||
make clean
|
||||
make PCB=9X EXT=FRSKY HELI=YES
|
||||
make simu PCB=9X EXT=FRSKY HELI=YES
|
||||
make gtests EXT=FRSKY HELI=YES
|
||||
./gtests
|
||||
|
||||
# OpenTX on Taranis X9E
|
||||
make clean
|
||||
make PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES
|
||||
make simu PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES
|
||||
make gtests PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES
|
||||
./gtests
|
||||
|
||||
# OpenTX on Taranis Plus
|
||||
make clean
|
||||
make PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES
|
||||
make simu PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES
|
||||
make gtests PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES
|
||||
./gtests
|
||||
|
||||
# OpenTX on Taranis
|
||||
make clean
|
||||
make PCB=TARANIS HELI=YES LUA=YES
|
||||
make simu PCB=TARANIS HELI=YES LUA=YES
|
||||
make gtests PCB=TARANIS HELI=YES LUA=YES
|
||||
./gtests
|
||||
|
||||
# OpenTX on Sky9x
|
||||
make clean
|
||||
make PCB=SKY9X HELI=YES
|
||||
make simu PCB=SKY9X HELI=YES
|
||||
make gtests PCB=SKY9X HELI=YES
|
||||
./gtests
|
||||
|
||||
# OpenTX on Gruvin9x
|
||||
make clean
|
||||
make PCB=GRUVIN9X EXT=FRSKY SDCARD=YES
|
||||
make simu PCB=GRUVIN9X EXT=FRSKY SDCARD=YES
|
||||
|
||||
# OpenTX on MEGA2560
|
||||
make clean
|
||||
make PCB=MEGA2560
|
||||
+3
-1
@@ -255,7 +255,9 @@ def ttsFr():
|
||||
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE+146+i)))
|
||||
for i, s in enumerate(["virgule 0", "virgule 1", "virgule 2", "virgule 3", "virgule 4", "virgule 5", "virgule 6", "virgule 7", "virgule 8", "virgule 9"]):
|
||||
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE+180+i)))
|
||||
for s, f, a in [(u"Batterie radio faible !", "lowbatt", 485),
|
||||
for s, f, a in [(u"Trim centré", "midtrim", 495),
|
||||
(u"Trim maximum atteint", "endtrim", NO_ALTERNATE),
|
||||
(u"Batterie radio faible !", "lowbatt", 485),
|
||||
(u"Radio inactive !", "inactiv", 486),
|
||||
(u"Alerte manche des gaz", "thralert", 481),
|
||||
(u"Alerte inters", "swalert", 482),
|
||||
|
||||
Reference in New Issue
Block a user