1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-15 04:15:26 +03:00

Merge against latest 2.3

This commit is contained in:
Bertrand Songis 2019-09-17 13:28:42 +02:00
commit 9e83c5d10f
No known key found for this signature in database
GPG key ID: F189F79290FEC50F
247 changed files with 35085 additions and 42445 deletions

2
.gitignore vendored
View file

@ -9,3 +9,5 @@ build*/
cmake-build-*/
/debian/
/*.vscode
radio/src/tests/googletest*
radio/src/tests/gtest*.tar.gz

View file

@ -6,7 +6,7 @@ set(VERSION_REVISION "0")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
set(SDCARD_REVISION "0020")
set(SDCARD_REVISION "0021")
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8)
@ -80,6 +80,14 @@ endif()
option(DISABLE_COMPANION "Disable building companion and simulators" OFF)
if(NOT DISABLE_COMPANION) # FIXME cosmetics/style
if(APPLE AND EXISTS /usr/local/opt/qt5)
# Homebrew installs Qt5 (up to at least 5.9.1) in
# /usr/local/qt5, ensure it can be found by CMake since
# it is not in the default /usr/local prefix.
list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
endif()
find_package(Qt5Core)
find_package(Qt5Widgets)
find_package(Qt5Xml)
@ -190,6 +198,32 @@ if(WIN32)
endif()
endif()
set(GTEST_ROOT /usr CACHE STRING "Base path to Google Test headers and source.")
find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').")
find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.")
if(NOT GTEST_INCDIR OR NOT GTEST_SRCDIR)
message(STATUS "Googletest will be downloaded")
set(GTEST_VERSION 1.8.1)
set(GTEST_SRCDIR "${RADIO_SRC_DIRECTORY}/tests/googletest-release-${GTEST_VERSION}/googletest")
set(GTEST_INCDIR "${GTEST_SRCDIR}/include")
set(GTEST_URL "https://github.com/google/googletest/archive/release-${GTEST_VERSION}.tar.gz")
set(GTEST_ARCHIVE "${RADIO_SRC_DIRECTORY}/tests/gtest-${GTEST_VERSION}.tar.gz")
if (NOT EXISTS "${GTEST_SRCDIR}")
file(DOWNLOAD "${GTEST_URL}" ${GTEST_ARCHIVE} SHOW_PROGRESS)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar -xf ${GTEST_ARCHIVE}
WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}/tests)
execute_process(
COMMAND ${CMAKE_COMMAND} -E remove -f ${GTEST_ARCHIVE})
endif()
endif()
add_subdirectory(${RADIO_SRC_DIRECTORY})
if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)

View file

@ -166,7 +166,7 @@ Eric Burdis
Nigel Chippindale
Michael Deasy
Stephen Stough
Kenneth Lilja (monthly)
Kenneth Lilja
Robert Jero
Gary Bancroft
Robert Cotsford
@ -351,7 +351,6 @@ Roberto Orsello
David Finger
Jean-Marie Oddo
Mike Matheny
Glen Roe (Showmaster)
Arron Bates
Tim Spurr
Daniel Morgan
@ -832,7 +831,7 @@ Carsten Wache
Brock White
Steven Poretz
David Huelster
Gordon Stahl (monthly)
Gordon Stahl
John Mathison
Richard Duczmal
Gregory Barron
@ -910,7 +909,7 @@ George Carnie
Philippe Stofleth
Tim Dzugan
Illia Izotov
Richard Miles (monthly)
Richard Miles
Attila Kapolnai
Gilles Dando
Denis Roussille
@ -1009,7 +1008,7 @@ Julien Kieffer
Gregor Walter
Carlos Viegas
Roberto Orsello
Steve Murray (monthly)
Steve Murray
Marcel Schäfer
Sean Cull
Holger Bothmer
@ -1443,7 +1442,7 @@ Marko Domagoj Zic
Fabrice Debonnet
Ms Place
Jörg Hammer
Rapid Informatics LLC
Rapid Informatics LLC (monthly)
Renaud Perriguey
Edmond Dufresne
Jaroslav Gazik
@ -1535,3 +1534,8 @@ Alain Labonne
Darko Perković
Pierre Malriq
Donald Manson
Johannes Ferschl
Piotr Wysocki
Thomas Halenbeck (monthly)
Sjoerd Dost
Ralph Gustafson

View file

@ -588,7 +588,7 @@ elseif(APPLE)
set(CPACK_GENERATOR "DragNDrop")
# set(CPACK_GENERATOR "TGZ") # for quick testing
set(CPACK_BINARY_DRAGNDROP ON)
set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash22_3_dmg.png)
set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash_dmg.png)
set(CPACK_DMG_VOLUME_NAME "OpenTX Companion")
set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store)
set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}")

View file

@ -37,6 +37,7 @@ AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
{
ui->setupUi(this);
setWindowIcon(CompanionIcon("apppreferences.png"));
ui->tabWidget->setCurrentIndex(0);
initSettings();
connect(ui->boardCB, SIGNAL(currentIndexChanged(int)), this, SLOT(onBaseFirmwareChanged()));

View file

@ -56,7 +56,7 @@ void Boards::setBoardType(const Type & board)
uint32_t Boards::getFourCC(Type board)
{
switch (board) {
case BOARD_X12S:
case BOARD_HORUS_X12S:
return 0x3478746F;
case BOARD_X10:
case BOARD_X10_EXPRESS:
@ -82,8 +82,8 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
return 0x3178746F;
case BOARD_STOCK:
case BOARD_M128:
case BOARD_9X_M64:
case BOARD_9X_M128:
return 0;
case BOARD_JUMPER_T12:
return 0x3D78746F;
@ -94,12 +94,12 @@ uint32_t Boards::getFourCC(Type board)
return 0;
}
const int Boards::getEEpromSize(Board::Type board)
int Boards::getEEpromSize(Board::Type board)
{
switch (board) {
case BOARD_STOCK:
case BOARD_9X_M64:
return EESIZE_STOCK;
case BOARD_M128:
case BOARD_9X_M128:
return EESIZE_M128;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
@ -121,7 +121,7 @@ const int Boards::getEEpromSize(Board::Type board)
return EESIZE_TARANIS;
case BOARD_UNKNOWN:
return EESIZE_MAX;
case BOARD_X12S:
case BOARD_HORUS_X12S:
case BOARD_X10:
case BOARD_X10_EXPRESS:
return 0;
@ -130,12 +130,12 @@ const int Boards::getEEpromSize(Board::Type board)
return 0;
}
const int Boards::getFlashSize(Type board)
int Boards::getFlashSize(Type board)
{
switch (board) {
case BOARD_STOCK:
case BOARD_9X_M64:
return FSIZE_STOCK;
case BOARD_M128:
case BOARD_9X_M128:
return FSIZE_M128;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
@ -155,7 +155,7 @@ const int Boards::getFlashSize(Type board)
case BOARD_TARANIS_X9E:
case BOARD_JUMPER_T12:
return FSIZE_TARANIS;
case BOARD_X12S:
case BOARD_HORUS_X12S:
case BOARD_X10:
case BOARD_X10_EXPRESS:
return FSIZE_HORUS;
@ -166,7 +166,7 @@ const int Boards::getFlashSize(Type board)
}
}
const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
{
if (index < 0)
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
@ -260,7 +260,7 @@ const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
}
const int Boards::getCapability(Board::Type board, Board::Capability capability)
int Boards::getCapability(Board::Type board, Board::Capability capability)
{
switch (capability) {
case Sticks:
@ -280,12 +280,6 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else
return 3;
case PotsStorage:
if (IS_HORUS(board))
return 5;
else
return getCapability(board, Pots);
case FactoryInstalledPots:
if (IS_TARANIS_X9(board))
return 2;
@ -300,12 +294,6 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else
return 0;
case SlidersStorage:
if (IS_HORUS_X10(board))
return 4;
else
return getCapability(board, Sliders);
case MouseAnalogs:
if (IS_HORUS(board))
return 2;
@ -313,7 +301,7 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
return 0;
case GyroAnalogs:
if (IS_HORUS_X12S(board) || IS_TARANIS_XLITES(board))
if (IS_TARANIS_XLITES(board))
return 2;
else
return 0;
@ -350,6 +338,8 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
case FactoryInstalledSwitches:
if (IS_TARANIS_X9E(board))
return 8;
if (IS_HORUS_X12S(board))
return 8;
else
return getCapability(board, Switches);
@ -372,7 +362,7 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
return 0;
}
const QString Boards::getAxisName(int index)
QString Boards::getAxisName(int index)
{
const QString axes[] = {
tr("Left Horizontal"),
@ -388,7 +378,7 @@ const QString Boards::getAxisName(int index)
return tr("Unknown");
}
const QString Boards::getAnalogInputName(Board::Type board, int index)
QString Boards::getAnalogInputName(Board::Type board, int index)
{
if (index < 0)
return CPN_STR_UNKNOWN_ITEM;
@ -454,8 +444,8 @@ const QString Boards::getAnalogInputName(Board::Type board, int index)
"S1",
"6P",
"S2",
"L1",
"L2",
"S3",
"S4",
"LS",
"RS",
"JSx",
@ -481,17 +471,17 @@ const QString Boards::getAnalogInputName(Board::Type board, int index)
return CPN_STR_UNKNOWN_ITEM;
}
const bool Boards::isBoardCompatible(Type board1, Type board2)
bool Boards::isBoardCompatible(Type board1, Type board2)
{
return (getFourCC(board1) == getFourCC(board2));
}
const QString Boards::getBoardName(Board::Type board)
QString Boards::getBoardName(Board::Type board)
{
switch (board) {
case BOARD_STOCK:
case BOARD_9X_M64:
return "9X";
case BOARD_M128:
case BOARD_9X_M128:
return "9X128";
case BOARD_GRUVIN9X:
return "Gruvin9x";
@ -521,7 +511,7 @@ const QString Boards::getBoardName(Board::Type board)
return "9XR-PRO";
case BOARD_AR9X:
return "AR9X";
case BOARD_X12S:
case BOARD_HORUS_X12S:
return "Horus X12S";
case BOARD_X10:
return "Horus X10/X10S";

View file

@ -32,8 +32,8 @@ namespace Board {
enum Type
{
BOARD_UNKNOWN = -1,
BOARD_STOCK = 0,
BOARD_M128,
BOARD_9X_M64 = 0,
BOARD_9X_M128,
BOARD_MEGA2560,
BOARD_GRUVIN9X,
BOARD_SKY9X,
@ -44,7 +44,7 @@ namespace Board {
BOARD_TARANIS_X9DP,
BOARD_TARANIS_X9DP_2019,
BOARD_TARANIS_X9E,
BOARD_X12S,
BOARD_HORUS_X12S,
BOARD_X10,
BOARD_X10_EXPRESS,
BOARD_TARANIS_XLITE,
@ -115,10 +115,8 @@ namespace Board {
enum Capability {
Sticks,
Pots,
PotsStorage,
FactoryInstalledPots,
Sliders,
SlidersStorage,
MouseAnalogs,
GyroAnalogs,
MaxAnalogs,
@ -172,14 +170,14 @@ class Boards
const bool isBoardCompatible(Board::Type board2) const { return isBoardCompatible(m_boardType, board2); }
static uint32_t getFourCC(Board::Type board);
static const int getEEpromSize(Board::Type board);
static const int getFlashSize(Board::Type board);
static const Board::SwitchInfo getSwitchInfo(Board::Type board, int index);
static const int getCapability(Board::Type board, Board::Capability capability);
static const QString getAxisName(int index);
static const QString getAnalogInputName(Board::Type board, int index);
static const bool isBoardCompatible(Board::Type board1, Board::Type board2);
static const QString getBoardName(Board::Type board);
static int getEEpromSize(Board::Type board);
static int getFlashSize(Board::Type board);
static Board::SwitchInfo getSwitchInfo(Board::Type board, int index);
static int getCapability(Board::Type board, Board::Capability capability);
static QString getAxisName(int index);
static QString getAnalogInputName(Board::Type board, int index);
static bool isBoardCompatible(Board::Type board1, Board::Type board2);
static QString getBoardName(Board::Type board);
protected:
@ -189,29 +187,129 @@ class Boards
// temporary aliases for transition period, use Boards class instead.
#define getBoardCapability(b__, c__) Boards::getCapability(b__, c__)
#define IS_9X(board) (board==Board::BOARD_STOCK || board==Board::BOARD_M128)
#define IS_STOCK(board) (board==Board::BOARD_STOCK)
#define IS_M128(board) (board==Board::BOARD_M128)
#define IS_2560(board) (board==Board::BOARD_GRUVIN9X || board==Board::BOARD_MEGA2560)
#define IS_SKY9X(board) (board==Board::BOARD_SKY9X || board==Board::BOARD_9XRPRO || board==Board::BOARD_AR9X)
#define IS_9XRPRO(board) (board==Board::BOARD_9XRPRO)
#define IS_JUMPER_T12(board) (board==Board::BOARD_JUMPER_T12)
#define IS_TARANIS_XLITE(board) (board==Board::BOARD_TARANIS_XLITE || board==Board::BOARD_TARANIS_XLITES)
#define IS_TARANIS_XLITES(board) (board==Board::BOARD_TARANIS_XLITES)
#define IS_TARANIS_X7(board) (board==Board::BOARD_TARANIS_X7)
#define IS_TARANIS_X9LITE(board) (board==Board::BOARD_TARANIS_X9LITE)
#define IS_TARANIS_X9(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9DP_2019 || board==Board::BOARD_TARANIS_X9E)
#define IS_TARANIS_X9D(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9DP_2019)
#define IS_TARANIS_PLUS(board) (board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
#define IS_TARANIS_X9E(board) (board==Board::BOARD_TARANIS_X9E)
#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITE(board) || IS_JUMPER_T12(board))
#define IS_TARANIS_SMALL(board) (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_T12(board))
#define IS_HORUS_X12S(board) (board==Board::BOARD_X12S)
#define IS_HORUS_X10(board) (board==Board::BOARD_X10 || board==Board::BOARD_X10_EXPRESS)
#define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board))
#define IS_HORUS_OR_TARANIS(board) (IS_HORUS(board) || IS_TARANIS(board))
#define IS_STM32(board) (IS_TARANIS(board) || IS_HORUS(board))
#define IS_ARM(board) (IS_STM32(board) || IS_SKY9X(board))
#define HAS_LARGE_LCD(board) (IS_HORUS(board) || IS_TARANIS_X9(board))
inline bool IS_9X(Board::Type board)
{
return board == Board::BOARD_9X_M64 || board == Board::BOARD_9X_M128;
}
inline bool IS_STOCK(Board::Type board)
{
return board == Board::BOARD_9X_M64;
}
inline bool IS_M128(Board::Type board)
{
return board == Board::BOARD_9X_M128;
}
inline bool IS_2560(Board::Type board)
{
return board == Board::BOARD_GRUVIN9X || board == Board::BOARD_MEGA2560;
}
inline bool IS_SKY9X(Board::Type board)
{
return board == Board::BOARD_SKY9X || board == Board::BOARD_9XRPRO || board == Board::BOARD_AR9X;
}
inline bool IS_9XRPRO(Board::Type board)
{
return board == Board::BOARD_9XRPRO;
}
inline bool IS_JUMPER_T12(Board::Type board)
{
return board == Board::BOARD_JUMPER_T12;
}
inline bool IS_TARANIS_XLITE(Board::Type board)
{
return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES;
}
inline bool IS_TARANIS_XLITES(Board::Type board)
{
return board == Board::BOARD_TARANIS_XLITES;
}
inline bool IS_TARANIS_X7(Board::Type board)
{
return board == Board::BOARD_TARANIS_X7;
}
inline bool IS_TARANIS_X9LITE(Board::Type board)
{
return board == Board::BOARD_TARANIS_X9LITE;
}
inline bool IS_TARANIS_X9(Board::Type board)
{
return board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9DP_2019 || board==Board::BOARD_TARANIS_X9E;
}
inline bool IS_TARANIS_X9D(Board::Type board)
{
return board == Board::BOARD_TARANIS_X9D || board == Board::BOARD_TARANIS_X9DP || board == Board::BOARD_TARANIS_X9DP_2019;
}
inline bool IS_TARANIS_PLUS(Board::Type board)
{
return board == Board::BOARD_TARANIS_X9DP || board == Board::BOARD_TARANIS_X9E;
}
inline bool IS_TARANIS_X9E(Board::Type board)
{
return board == Board::BOARD_TARANIS_X9E;
}
inline bool IS_TARANIS(Board::Type board)
{
return IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITE(board) || IS_JUMPER_T12(board);
}
inline bool IS_TARANIS_SMALL(Board::Type board)
{
return IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_T12(board);
}
inline bool IS_HORUS_X10(Board::Type board)
{
return board == Board::BOARD_X10 || board == Board::BOARD_X10_EXPRESS;
}
inline bool IS_HORUS_X12S(Board::Type board)
{
return board == Board::BOARD_HORUS_X12S;
}
inline bool IS_HORUS(Board::Type board)
{
return IS_HORUS_X12S(board) || IS_HORUS_X10(board);
}
inline bool IS_HORUS_OR_TARANIS(Board::Type board)
{
return IS_HORUS(board) || IS_TARANIS(board);
}
inline bool IS_STM32(Board::Type board)
{
return IS_TARANIS(board) || IS_HORUS(board);
}
inline bool IS_ARM(Board::Type board)
{
return IS_STM32(board) || IS_SKY9X(board);
}
inline bool HAS_LARGE_LCD(Board::Type board)
{
return IS_HORUS(board) || IS_TARANIS_X9(board);
}
inline bool HAS_EXTERNAL_ANTENNA(Board::Type board)
{
return (IS_HORUS(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board));
}
#endif // _BOARDS_H_

View file

@ -22,23 +22,22 @@
#define _EEPROMIMPORTEXPORT_H_
#include "customdebug.h"
#include <QtCore>
#include <QBitArray>
#include <utility>
class DataField {
Q_DECLARE_TR_FUNCTIONS(DataField)
public:
DataField(DataField * parent, const char * name=""):
explicit DataField(DataField * parent, const char * name=""):
parent(parent),
name(name)
{
}
virtual ~DataField()
{
}
= default;
virtual const QString & getName()
{
@ -49,7 +48,7 @@ class DataField {
virtual void ExportBits(QBitArray & output) = 0;
virtual void ImportBits(const QBitArray & input) = 0;
QBitArray bytesToBits(QByteArray bytes)
static QBitArray bytesToBits(QByteArray bytes)
{
QBitArray bits(bytes.count()*8);
// Convert from QByteArray to QBitArray
@ -59,7 +58,7 @@ class DataField {
return bits;
}
QByteArray bitsToBytes(QBitArray bits, int offset=0)
static QByteArray bitsToBytes(QBitArray bits, int offset=0)
{
QByteArray bytes;
bytes.resize((offset+bits.count()+7)/8);
@ -126,16 +125,16 @@ class DataField {
QString name;
};
class ProxyField: public DataField {
public:
explicit ProxyField(DataField * parent):
DataField(parent, "Proxy")
{
}
virtual DataField * getField() = 0;
};
//class ProxyField: public DataField {
// public:
// explicit ProxyField(DataField * parent):
// DataField(parent, "Proxy")
// {
// }
//
// virtual DataField * getField() = 0;
//
//};
template<class container, int N>
class BaseUnsignedField: public DataField {
@ -164,7 +163,9 @@ class BaseUnsignedField: public DataField {
{
}
virtual void ExportBits(QBitArray & output)
BaseUnsignedField() = delete;
void ExportBits(QBitArray & output) override
{
container value = field;
if (value > max) value = max;
@ -178,7 +179,7 @@ class BaseUnsignedField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
field = 0;
for (int i=0; i<N; i++) {
@ -188,7 +189,7 @@ class BaseUnsignedField: public DataField {
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
unsigned int size() override
{
return N;
}
@ -197,9 +198,6 @@ class BaseUnsignedField: public DataField {
container & field;
container min;
container max;
private:
BaseUnsignedField();
};
template <int N>
@ -231,7 +229,9 @@ class BoolField: public DataField {
{
}
virtual void ExportBits(QBitArray & output)
BoolField() = delete;
void ExportBits(QBitArray & output) override
{
output.resize(N);
if (field) {
@ -239,22 +239,19 @@ class BoolField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
field = input[0] ? true : false;
field = input[0];
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
unsigned int size() override
{
return N;
}
protected:
bool & field;
private:
BoolField();
};
template<int N>
@ -262,17 +259,13 @@ class SignedField: public DataField {
public:
SignedField(DataField * parent, int & field):
DataField(parent, "Signed"),
field(field),
min(INT_MIN),
max(INT_MAX)
field(field)
{
}
SignedField(DataField * parent, int & field, const char *name):
DataField(parent, name),
field(field),
min(INT_MIN),
max(INT_MAX)
field(field)
{
}
@ -284,7 +277,7 @@ class SignedField: public DataField {
{
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
int value = field;
if (value > max) value = max;
@ -297,7 +290,7 @@ class SignedField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
unsigned int value = 0;
for (int i=0; i<N; i++) {
@ -315,25 +308,26 @@ class SignedField: public DataField {
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
unsigned int size() override
{
return N;
}
protected:
int & field;
int min;
int max;
int min = INT_MIN;
int max = INT_MAX;
};
template<int N>
class SpareBitsField: public UnsignedField<N> {
public:
SpareBitsField(DataField * parent):
explicit SpareBitsField(DataField * parent):
UnsignedField<N>(parent, spare, 0, 0, "Spare"),
spare(0)
{
}
protected:
unsigned int spare;
};
@ -348,7 +342,7 @@ class CharField: public DataField {
{
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
output.resize(N*8);
int b = 0;
@ -362,7 +356,7 @@ class CharField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
unsigned int b = 0;
for (int i=0; i<N; i++) {
@ -376,7 +370,7 @@ class CharField: public DataField {
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
}
virtual unsigned int size()
unsigned int size() override
{
return 8 * N;
}
@ -423,7 +417,7 @@ class ZCharField: public DataField {
{
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
output.resize(N*8);
int b = 0;
@ -437,7 +431,7 @@ class ZCharField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
unsigned int b = 0;
for (int i=0; i<N; i++) {
@ -459,7 +453,7 @@ class ZCharField: public DataField {
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
}
virtual unsigned int size()
unsigned int size() override
{
return 8*N;
}
@ -470,12 +464,12 @@ class ZCharField: public DataField {
class StructField: public DataField {
public:
StructField(DataField * parent, const char * name="Struct"):
explicit StructField(DataField * parent, const char * name = "Struct"):
DataField(parent, name)
{
}
~StructField() {
~StructField() override {
foreach(DataField * field, fields) {
delete field;
}
@ -486,7 +480,7 @@ class StructField: public DataField {
fields.append(field);
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
int offset = 0;
output.resize(size());
@ -498,7 +492,7 @@ class StructField: public DataField {
}
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
qCDebug(eepromImport) << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
int offset = 0;
@ -512,7 +506,7 @@ class StructField: public DataField {
}
}
virtual unsigned int size()
unsigned int size() override
{
unsigned int result = 0;
foreach(DataField *field, fields) {
@ -543,17 +537,16 @@ class TransformedField: public DataField {
{
}
virtual ~TransformedField()
{
}
~TransformedField() override
= default;
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
beforeExport();
field.ExportBits(output);
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
qCDebug(eepromImport) << QString("\timporting TransformedField %1:").arg(field.getName());
field.ImportBits(input);
@ -561,12 +554,12 @@ class TransformedField: public DataField {
}
virtual const QString & getName()
const QString & getName() override
{
return field.getName();
}
virtual unsigned int size()
unsigned int size() override
{
return field.size();
}
@ -575,7 +568,7 @@ class TransformedField: public DataField {
virtual void afterImport() = 0;
virtual int dump(int level=0, int offset=0)
int dump(int level, int offset) override
{
beforeExport();
return field.dump(level, offset);
@ -591,7 +584,7 @@ class UnionField: public DataField {
class UnionMember {
public:
virtual ~UnionMember() {}
virtual ~UnionMember() = default;
virtual bool select(const selectorT& attr) const = 0;
virtual DataField* getField() = 0;
};
@ -602,6 +595,7 @@ class UnionField: public DataField {
TransformedField(parent, field)
{
}
virtual DataField* getField()
{
return this;
@ -613,7 +607,7 @@ class UnionField: public DataField {
{
}
~UnionField() {
~UnionField() override {
foreach(UnionMember *member, members) {
delete member;
}
@ -625,7 +619,7 @@ class UnionField: public DataField {
maxSize = member->getField()->size();
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
foreach(UnionMember *member, members) {
if (member->select(selectField)) {
@ -636,7 +630,7 @@ class UnionField: public DataField {
output.resize(maxSize);
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
foreach(UnionMember *member, members) {
if (member->select(selectField)) {
@ -646,7 +640,7 @@ class UnionField: public DataField {
}
}
virtual unsigned int size()
unsigned int size() override
{
return maxSize;
}
@ -664,8 +658,7 @@ class ConversionTable {
{
after = 0;
for (std::list<ConversionTuple>::iterator it=exportTable.begin(); it!=exportTable.end(); it++) {
ConversionTuple & tuple = *it;
for (auto & tuple : exportTable) {
if (before == tuple.a) {
after = tuple.b;
return true;
@ -679,8 +672,7 @@ class ConversionTable {
{
after = 0;
for (std::list<ConversionTuple>::iterator it=importTable.begin(); it!=importTable.end(); it++) {
ConversionTuple & tuple = *it;
for (auto & tuple : importTable) {
if (before == tuple.b) {
after = tuple.a;
return true;
@ -711,15 +703,15 @@ class ConversionTable {
exportTable.push_back(conversion);
}
void addImportConversion(const int a, const int b)
{
importTable.push_back(ConversionTuple(a, b));
}
void addExportConversion(const int a, const int b)
{
exportTable.push_back(ConversionTuple(a, b));
}
// void addImportConversion(const int a, const int b)
// {
// importTable.push_back(ConversionTuple(a, b));
// }
//
// void addExportConversion(const int a, const int b)
// {
// exportTable.push_back(ConversionTuple(a, b));
// }
std::list<ConversionTuple> importTable;
std::list<ConversionTuple> exportTable;
@ -728,35 +720,21 @@ class ConversionTable {
template<class T>
class ConversionField: public TransformedField {
public:
ConversionField(DataField * parent, int & field, ConversionTable *table, const char *name, const QString & error = ""):
ConversionField(DataField * parent, int & field, ConversionTable *table, const char *name, QString error = ""):
TransformedField(parent, internalField),
internalField(this, _field, name),
field(field),
_field(0),
table(table),
shift(0),
scale(1),
min(INT_MIN),
max(INT_MAX),
exportFunc(NULL),
importFunc(NULL),
error(error)
error(std::move(error))
{
}
ConversionField(DataField * parent, unsigned int & field, ConversionTable *table, const char *name, const QString & error = ""):
ConversionField(DataField * parent, unsigned int & field, ConversionTable *table, const char *name, QString error = ""):
TransformedField(parent, internalField),
internalField(this, (unsigned int &)_field, name),
field((int &)field),
_field(0),
table(table),
shift(0),
scale(0),
min(INT_MIN),
max(INT_MAX),
exportFunc(NULL),
importFunc(NULL),
error(error)
error(std::move(error))
{
}
@ -764,15 +742,8 @@ class ConversionField: public TransformedField {
TransformedField(parent, internalField),
internalField(this, _field),
field(field),
_field(0),
table(NULL),
shift(0),
scale(0),
min(INT_MIN),
max(INT_MAX),
exportFunc(exportFunc),
importFunc(importFunc),
error("")
importFunc(importFunc)
{
}
@ -780,15 +751,10 @@ class ConversionField: public TransformedField {
TransformedField(parent, internalField),
internalField(this, _field, name),
field(field),
_field(0),
table(NULL),
shift(shift),
scale(scale),
min(min),
max(max),
exportFunc(NULL),
importFunc(NULL),
error("")
max(max)
{
}
@ -796,25 +762,14 @@ class ConversionField: public TransformedField {
TransformedField(parent, internalField),
internalField(this, (unsigned int &)_field),
field((int &)field),
_field(0),
table(NULL),
shift(shift),
scale(scale),
min(INT_MIN),
max(INT_MAX),
exportFunc(NULL),
importFunc(NULL),
error("")
scale(scale)
{
}
virtual void beforeExport()
void beforeExport() override
{
_field = field;
if (scale) {
_field /= scale;
}
_field = scale ? field / scale : field;
if (table) {
if (!table->exportValue(_field, _field)) {
@ -837,7 +792,7 @@ class ConversionField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
field = _field;
@ -857,21 +812,22 @@ class ConversionField: public TransformedField {
if (scale) {
field *= scale;
}
qCDebug(eepromImport) << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
}
protected:
T internalField;
int & field;
int _field;
ConversionTable * table;
int shift;
int scale;
int min;
int max;
int (*exportFunc)(int);
int (*importFunc)(int);
const QString error;
int _field = 0;
ConversionTable * table = nullptr;
int shift = 0;
int scale = 0;
int min = INT_MIN;
int max = INT_MAX;
int (*exportFunc)(int) = nullptr;
int (*importFunc)(int) = nullptr;
const QString error = "";
};
#endif // _EEPROMIMPORTEXPORT_H_

View file

@ -32,7 +32,7 @@
#define FILE_MODEL(n) (1+n)
Er9xInterface::Er9xInterface():
EEPROMInterface(Board::BOARD_STOCK),
EEPROMInterface(Board::BOARD_9X_M64),
efile(new RleFile())
{
}
@ -120,13 +120,13 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
std::bitset<NUM_ERRORS> errors;
if (size != Boards::getEEpromSize(Board::BOARD_STOCK)) {
if (size != Boards::getEEpromSize(Board::BOARD_9X_M64)) {
dbg << "wrong size";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_STOCK)) {
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_9X_M64)) {
dbg << "wrong file system";
errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong();

View file

@ -53,13 +53,15 @@ bool GeneralSettings::switchSourceAllowedTaranis(int index) const
bool GeneralSettings::isPotAvailable(int index) const
{
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Pots)) return false;
if (index < 0 || index > getBoardCapability(getCurrentBoard(), Board::Pots))
return false;
return potConfig[index] != Board::POT_NONE;
}
bool GeneralSettings::isSliderAvailable(int index) const
{
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Sliders)) return false;
if (index < 0 || index > getBoardCapability(getCurrentBoard(), Board::Sliders))
return false;
return sliderConfig[index] != Board::SLIDER_NONE;
}

View file

@ -151,7 +151,8 @@ class GeneralSettings {
int backgroundVolume;
unsigned int mavbaud;
unsigned int switchUnlockStates;
unsigned int hw_uartMode; // UartModes
unsigned int auxSerialMode;
int antennaMode;
unsigned int backlightColor;
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
char switchName[CPN_MAX_SWITCHES][3+1];

View file

@ -157,30 +157,14 @@ void ModelData::clear()
{
memset(reinterpret_cast<void *>(this), 0, sizeof(ModelData));
modelIndex = -1; // an invalid index, this is managed by the TreeView data model
moduleData[0].protocol = PULSES_OFF;
moduleData[1].protocol = PULSES_OFF;
moduleData[0].channelsCount = 8;
moduleData[1].channelsStart = 0;
moduleData[1].channelsCount = 8;
moduleData[0].ppm.delay = 300;
moduleData[1].ppm.delay = 300;
moduleData[2].ppm.delay = 300;
Firmware * firmware = Firmware::getCurrentVariant();
int board = firmware->getBoard();
if (firmware->isAvailable(PULSES_ACCESS_ISRM, 0)) {
moduleData[0].protocol = PULSES_ACCESS_ISRM;
moduleData[1].protocol = PULSES_OFF;
}
else if (IS_HORUS_OR_TARANIS(board)) {
moduleData[0].protocol = PULSES_PXX_XJT_X16;
moduleData[1].protocol = PULSES_OFF;
}
else if (IS_SKY9X(board)) {
moduleData[0].protocol = PULSES_PPM;
moduleData[1].protocol = PULSES_PPM;
}
else {
moduleData[0].protocol = PULSES_PPM;
moduleData[1].protocol = PULSES_OFF;
}
moduleData[2].ppm.delay = 300; //Trainer PPM
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
flightModeData[i].clear(i);
}

View file

@ -178,8 +178,8 @@ class ModelData {
uint64_t switchWarningStates;
unsigned int switchWarningEnable;
unsigned int potsWarningMode;
bool potsWarningEnabled[CPN_MAX_POTS];
int potPosition[CPN_MAX_POTS];
bool potsWarnEnabled[CPN_MAX_POTS];
int potsWarnPosition[CPN_MAX_POTS];
bool displayChecklist;
GVarData gvarData[CPN_MAX_GVARS];
MavlinkData mavlink;

View file

@ -96,10 +96,6 @@ QString ModuleData::subTypeToString(int type) const
QString ModuleData::powerValueToString(Firmware * fw) const
{
const QStringList & strRef = powerValueStrings(subType, fw);
// EU module with telemetry can only be < 100/200mW.
if (pxx.sport_out && subType == MODULE_SUBTYPE_R9M_EU && pxx.power > 1)
return CPN_STR_UNKNOWN_ITEM;
return strRef.value(pxx.power, CPN_STR_UNKNOWN_ITEM);
}

View file

@ -169,10 +169,9 @@ class ModuleData {
struct PXX {
unsigned int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
bool receiver_telem_off; // false = receiver telem enabled
bool receiver_channel_9_16; // false = pwm out 1-8, true 9-16
bool external_antenna; // false = internal antenna, true = external antenna
bool sport_out;
bool receiverTelemetryOff; // false = receiver telem enabled
bool receiverHigherChannels; // false = pwm out 1-8, true 9-16
int antennaMode; // false = internal antenna, true = external antenna
} pxx;
struct Access {

View file

@ -30,6 +30,7 @@
#define STR_MULTI_RFPOWER QT_TRANSLATE_NOOP("Multiprotocols", "Radio output power")
#define STR_MULTI_SERVOFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Servo output frequency")
#define STR_MULTI_OPTION QT_TRANSLATE_NOOP("Multiprotocols", "Option value")
#define STR_MULTI_FIXEDID QT_TRANSLATE_NOOP("Multiprotocols", "Fixed ID value")
#define STR_MULTI_DEFAULT QT_TRANSLATE_NOOP("Multiprotocols", "DEFAULT")
static const QStringList STR_SUBTYPE_CUSTOM ({
@ -42,6 +43,7 @@ static const QStringList STR_SUBTYPE_FRSKY {"D16", "D8", "D16 8ch", "V8", "D
static const QStringList STR_SUBTYPE_HISKY {"Standard", "HK310"};
static const QStringList STR_SUBTYPE_V2X2 {"Standard", "JXD506"};
static const QStringList STR_SUBTYPE_DSM {"DSM2 22ms", "DSM2 11ms", "DSMX 22ms", "DSMX 11ms"};
static const QStringList STR_SUBTYPE_DEVO {"8 Channel", "10 Channel", "12 Channel", "6 Channel", "7 Channel"};
static const QStringList STR_SUBTYPE_YD717 {"Standard", "Skywalker", "Syma X4", "XINXUN", "NIHUI"};
static const QStringList STR_SUBTYPE_KN {"WLtoys", "FeiLun"};
static const QStringList STR_SUBTYPE_SYMAX {"Standard", "Syma X5C"};
@ -61,11 +63,14 @@ static const QStringList STR_SUBTYPE_CABELL {"Cabell V3", "Cab V3 Telem", "-"
static const QStringList STR_SUBTYPE_H83D {"H8 Mini 3D", "H20H", "H20 Mini", "H30 Mini"};
static const QStringList STR_SUBTYPE_CORONA {"Corona V1", "Corona V2", "Flydream V3"};
static const QStringList STR_SUBTYPE_HITEC {"Optima", "Optima Hub Telem", "Minima"};
static const QStringList STR_SUBTYPE_TRAXXAS {"6519 RX"};
static const QStringList STR_SUBTYPE_BUGS_MINI {"Standard", "Bugs 3H"};
static const QStringList STR_SUBTYPE_E01X {"E012", "E015", "E016H"};
static const QStringList STR_SUBTYPE_GD00X {"GD V1", "GD V2"};
static const QStringList STR_SUBTYPE_REDPINE {"Fast", "Slow"};
static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly", " - "};
static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly"};
static const QStringList STR_SUBTYPE_ZSX {"JJRC ZSX-280"};
static const QStringList STR_SUBTYPE_FLYZONE {"FZ-410 TX"};
static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
@ -79,6 +84,7 @@ const Multiprotocols multiProtocols {
{MODULE_SUBTYPE_MULTI_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr},
{MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr},
{MODULE_SUBTYPE_MULTI_DSM2, 3, false, STR_SUBTYPE_DSM, nullptr},
{MODULE_SUBTYPE_MULTI_DEVO, 4, false, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID},
{MODULE_SUBTYPE_MULTI_YD717, 4, false, STR_SUBTYPE_YD717, nullptr},
{MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr},
{MODULE_SUBTYPE_MULTI_SYMAX, 1, false, STR_SUBTYPE_SYMAX, nullptr},
@ -101,14 +107,15 @@ const Multiprotocols multiProtocols {
{MODULE_SUBTYPE_MULTI_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr},
{MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr},
{MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, nullptr},
{MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, nullptr},
{MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_POTENSIC, 1, false, STR_SUBTYPE_POTENSIC, nullptr},
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, NO_SUBTYPE, nullptr},
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, NO_SUBTYPE, nullptr},
{MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr},
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr},
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr},
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION},
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
@ -151,7 +158,7 @@ QString Multiprotocols::protocolToString(int protocol, bool custom)
"Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","Open LRS",
"FlySky AFHDS2A", "Q2x2", "Walkera", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie",
"Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761",
"KFPlan KF606", "Redpine", "Potensic", "ZXS", "Flyzone"
"KFPlan KF606", "Redpine", "Potensic", "ZXS", "FlyZone"
});
if (protocol == MM_RF_CUSTOM_SELECTED || custom)

View file

@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <stdlib.h>
#include <cstdlib>
#include <algorithm>
#include "boards.h"
#include "helpers.h"
@ -33,19 +33,40 @@ using namespace Board;
inline int MAX_SWITCHES(Board::Type board, int version)
{
if (version <= 218 && IS_TARANIS_X7(board))
if (version <= 218) {
if (IS_TARANIS_X7(board))
return 6;
if (version <= 218 && (IS_TARANIS_X9D(board) || IS_HORUS(board)))
if (IS_TARANIS_X9D(board) || IS_HORUS(board))
return 8;
if (IS_TARANIS_XLITE(board))
return 4;
}
if (IS_TARANIS_X9D(board))
return 9;
if (IS_JUMPER_T12(board))
return 8;
return Boards::getCapability(board, Board::Switches);
}
inline int MAX_KNOBS(Board::Type board, int version)
inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
{
if (IS_HORUS_OR_TARANIS(board)) {
return MAX_SWITCHES(board, version) * 3;
}
else {
return Boards::getCapability(board, Board::SwitchPositions);
}
}
inline int POTS_CONFIG_SIZE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
return 8;
return 16;
return 4;
return 8;
}
inline int MAX_POTS(Board::Type board, int version)
@ -59,10 +80,33 @@ inline int MAX_POTS_STORAGE(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
return 3;
return Boards::getCapability(board, Board::PotsStorage);
if (version >= 219 && IS_HORUS(board))
return 5;
return Boards::getCapability(board, Board::Pots);
}
inline int MAX_SLIDERS_SLOTS(Board::Type board, int version)
inline int MAX_POTS_SOURCES(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
return 5;
return Boards::getCapability(board, Board::Pots);
}
inline int MAX_SLIDERS_STORAGE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
return 4;
return Boards::getCapability(board, Board::Sliders);
}
inline int MAX_SLIDERS_SOURCES(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
return 2;
return Boards::getCapability(board, Board::Sliders);
}
inline int SLIDERS_CONFIG_SIZE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
return 8;
@ -70,32 +114,20 @@ inline int MAX_SLIDERS_SLOTS(Board::Type board, int version)
return 4;
}
// bitsize of swconfig_t / 2 (see radio/src/datastructs.h)
inline int MAX_SWITCH_SLOTS(Board::Type board, int version)
inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
{
if (IS_TARANIS_X9E(board))
return 32;
return 64;
if (IS_HORUS(board))
return 16;
return 32;
if (version >= 219 && IS_TARANIS_X9D(board))
return 32;
return 16;
return 8;
}
inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
{
if (version < 219) {
if (IS_TARANIS_X7(board) || IS_HORUS(board))
return Boards::getCapability(board, Board::SwitchPositions) - 2*3;
}
return Boards::getCapability(board, Board::SwitchPositions);
}
//#define MAX_SWITCHES_POSITION(board, version) (Boards::getCapability(board, Board::SwitchPositions))
#define MAX_ROTARY_ENCODERS(board) (IS_SKY9X(board) ? 1 : 0)
#define MAX_FLIGHT_MODES(board, version) 9
#define MAX_TIMERS(board, version) 3
@ -216,8 +248,7 @@ class SwitchesConversionTable: public ConversionTable {
static SwitchesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned long flags=0)
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache & element = *it;
for (auto & element : internalCache) {
if (element.board == board && element.version == version && element.flags == flags)
return element.table;
}
@ -228,9 +259,7 @@ class SwitchesConversionTable: public ConversionTable {
}
static void Cleanup()
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache & element = *it;
if (element.table)
for (auto & element : internalCache) {
delete element.table;
}
internalCache.clear();
@ -244,7 +273,6 @@ std::list<SwitchesConversionTable::Cache> SwitchesConversionTable::internalCache
#define FLAG_NOTELEMETRY 0x04
class SourcesConversionTable: public ConversionTable {
public:
SourcesConversionTable(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0)
{
@ -268,10 +296,9 @@ class SourcesConversionTable: public ConversionTable {
}
}
for (int i=0; i<CPN_MAX_STICKS+MAX_POTS_STORAGE(board, version)+Boards::getCapability(board, Board::SlidersStorage)+Boards::getCapability(board, Board::MouseAnalogs)+MAX_GYRO_ANALOGS(board, version); i++) {
for (int i=0; i<CPN_MAX_STICKS + MAX_POTS_SOURCES(board, version) + MAX_SLIDERS_SOURCES(board, version) + Boards::getCapability(board, Board::MouseAnalogs) + MAX_GYRO_ANALOGS(board, version); i++) {
int offset = 0;
if (version <= 218 && IS_HORUS(board) && i>=CPN_MAX_STICKS+MAX_POTS_STORAGE(board, version))
if (version <= 218 && IS_HORUS_X10(board) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version))
offset += 2;
addConversion(RawSource(SOURCE_TYPE_STICK, i + offset), val++);
@ -401,7 +428,7 @@ class SwitchField: public ConversionField< SignedField<N> > {
ConversionField< SignedField<N> >::beforeExport();
}
virtual void afterImport()
void afterImport() override
{
ConversionField< SignedField<N> >::afterImport();
sw = RawSwitch(_switch);
@ -435,7 +462,7 @@ class SourceField: public ConversionField< UnsignedField<N> > {
ConversionField< UnsignedField<N> >::beforeExport();
}
virtual void afterImport()
void afterImport() override
{
ConversionField< UnsignedField<N> >::afterImport();
source = RawSource(_source);
@ -567,7 +594,7 @@ class CurveReferenceField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
curve.type = (CurveReference::CurveRefType)_curve_type;
curve.value = smallGvarExport(_curve_value);
@ -688,7 +715,7 @@ class FlightModeField: public TransformedField {
trim = 501 + phase.trimRef[i] - (phase.trimRef[i] > index ? 1 : 0);
else
trim = std::max(-500, std::min(500, phase.trim[i]));
if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) {
if (board == BOARD_9X_M64 || (board == BOARD_9X_M128 && version >= 215)) {
trimBase[i] = trim >> 2;
trimExt[i] = (trim & 0x03);
}
@ -699,7 +726,7 @@ class FlightModeField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
for (int i=0; i<CPN_MAX_STICKS+MAX_AUX_TRIMS(board); i++) {
if (IS_HORUS_OR_TARANIS(board) || version >= 218) {
@ -719,7 +746,7 @@ class FlightModeField: public TransformedField {
}
else {
int trim;
if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215))
if (board == BOARD_9X_M64 || (board == BOARD_9X_M128 && version >= 215))
trim = ((trimBase[i]) << 2) + (trimExt[i] & 0x03);
else
trim = trimBase[i];
@ -824,7 +851,7 @@ class MixField: public TransformedField {
}
}
virtual void beforeExport() override
void beforeExport() override
{
if (mix.destCh && mix.srcRaw.type != SOURCE_TYPE_NONE) {
_destCh = mix.destCh - 1;
@ -842,14 +869,14 @@ class MixField: public TransformedField {
_curveParam = mix.curve.value;
}
else if (mix.curve.type == CurveReference::CURVE_REF_DIFF) {
_curveMode = 0;
_curveMode = false;
_curveParam = smallGvarImport(mix.curve.value);
}
}
else {
mix.clear();
_destCh = 0;
_curveMode = 0;
_curveMode = false;
_curveParam = 0;
}
@ -888,13 +915,12 @@ class MixField: public TransformedField {
Board::Type board;
unsigned int version;
ModelData * model;
unsigned int _destCh;
bool _curveMode;
int _curveParam;
int _weight;
int _offset;
unsigned int _weightMode;
unsigned int _offsetMode;
unsigned int _destCh = 0;
bool _curveMode = false;
int _curveParam = 0;
int _weight = 0;
int _offset = 0;
unsigned int _offsetMode = 0;
};
class InputField: public TransformedField {
@ -950,7 +976,7 @@ class InputField: public TransformedField {
}
}
virtual void beforeExport()
void beforeExport() override
{
_weight = smallGvarImport(expo.weight);
@ -974,7 +1000,7 @@ class InputField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
if (!IS_STM32(board) && expo.mode) {
expo.srcRaw = RawSource(SOURCE_TYPE_STICK, expo.chn);
@ -1002,10 +1028,10 @@ class InputField: public TransformedField {
ExpoData & expo;
Board::Type board;
unsigned int version;
bool _curveMode;
int _weight;
int _offset;
int _curveParam;
bool _curveMode = false;
int _weight = 0;
int _offset = 0;
int _curveParam = 0;
};
class LimitField: public StructField {
@ -1205,8 +1231,8 @@ class CurvesField: public TransformedField {
unsigned int version;
int maxCurves;
int maxPoints;
int _curves[CPN_MAX_CURVES];
int _points[CPN_MAX_CURVES*CPN_MAX_POINTS*2];
int _curves[CPN_MAX_CURVES] = {};
int _points[CPN_MAX_CURVES*CPN_MAX_POINTS*2] = {};
};
class LogicalSwitchesFunctionsTable: public ConversionTable {
@ -1249,10 +1275,7 @@ class LogicalSwitchField: public TransformedField {
model(model),
functionsConversionTable(board, version),
sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, 0)),
switchesConversionTable(SwitchesConversionTable::getInstance(board, version)),
v1(0),
v2(0),
v3(0)
switchesConversionTable(SwitchesConversionTable::getInstance(board, version))
{
if (version >= 218) {
internalField.Append(new ConversionField< UnsignedField<8> >(this, csw.func, &functionsConversionTable, "Function"));
@ -1278,9 +1301,8 @@ class LogicalSwitchField: public TransformedField {
}
}
~LogicalSwitchField()
{
}
~LogicalSwitchField() override
= default;
void beforeExport() override
{
@ -1344,9 +1366,9 @@ class LogicalSwitchField: public TransformedField {
LogicalSwitchesFunctionsTable functionsConversionTable;
SourcesConversionTable * sourcesConversionTable;
SwitchesConversionTable * switchesConversionTable;
int v1;
int v2;
int v3;
int v1 = 0;
int v2 = 0;
int v3 = 0;
};
class CustomFunctionsConversionTable: public ConversionTable {
@ -1431,7 +1453,7 @@ class SwitchesWarningField: public TransformedField {
protected:
BaseUnsignedField<uint64_t, N> internalField;
uint64_t & sw;
uint64_t _sw;
uint64_t _sw = 0;
Board::Type board;
unsigned int version;
};
@ -1446,10 +1468,7 @@ class ArmCustomFunctionField: public TransformedField {
version(version),
variant(variant),
functionsConversionTable(board, version),
sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, 0)),
_func(0),
_active(0),
_mode(0)
sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, 0))
{
memset(_param, 0, sizeof(_param));
@ -1475,7 +1494,7 @@ class ArmCustomFunctionField: public TransformedField {
return (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic);
}
virtual void beforeExport()
void beforeExport() override
{
if (fn.swtch.type != SWITCH_TYPE_NONE) {
_func = fn.func;
@ -1534,7 +1553,7 @@ class ArmCustomFunctionField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
fn.func = (AssignFunc)_func;
@ -1596,10 +1615,9 @@ class ArmCustomFunctionField: public TransformedField {
unsigned int variant;
CustomFunctionsConversionTable functionsConversionTable;
SourcesConversionTable * sourcesConversionTable;
unsigned int _func;
char _param[10];
int _active;
unsigned int _mode;
unsigned int _func = 0;
char _param[10] = {};
int _active = 0;
};
class FrskyScreenField: public DataField {
@ -1647,7 +1665,7 @@ class FrskyScreenField: public DataField {
none.Append(new SpareBitsField<20*8>(this));
}
virtual void ExportBits(QBitArray & output)
void ExportBits(QBitArray & output) override
{
if (screen.type == TELEMETRY_SCREEN_SCRIPT)
script.ExportBits(output);
@ -1659,7 +1677,7 @@ class FrskyScreenField: public DataField {
none.ExportBits(output);
}
virtual void ImportBits(const QBitArray & input)
void ImportBits(const QBitArray & input) override
{
qCDebug(eepromImport) << QString("importing %1: type: %2").arg(name).arg(screen.type);
@ -1674,7 +1692,7 @@ class FrskyScreenField: public DataField {
none.ImportBits(input);
}
virtual unsigned int size()
unsigned int size() override
{
// NOTA: screen.type should have been imported first!
if (screen.type == TELEMETRY_SCREEN_SCRIPT)
@ -1700,7 +1718,7 @@ class FrskyScreenField: public DataField {
class RSSIConversionTable: public ConversionTable
{
public:
RSSIConversionTable(int index)
explicit RSSIConversionTable(int index)
{
addConversion(0, 2-index);
addConversion(1, 3-index);
@ -1709,8 +1727,7 @@ class RSSIConversionTable: public ConversionTable
}
RSSIConversionTable()
{
}
= default;
};
class TelemetryVarioSourceConversionTable: public ConversionTable
@ -1861,8 +1878,7 @@ class SensorField: public TransformedField {
internalField(this, "Sensor"),
sensor(sensor),
model(model),
version(version),
_param(0)
version(version)
{
internalField.Append(new UnsignedField<16>(this, _id, "id/persistentValue"));
internalField.Append(new UnsignedField<8>(this, _instance, "instance/formula"));
@ -1917,7 +1933,7 @@ class SensorField: public TransformedField {
}
}
virtual void afterImport()
void afterImport() override
{
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) {
sensor.id = _id;
@ -1960,11 +1976,11 @@ class SensorField: public TransformedField {
SensorData & sensor;
const ModelData& model;
unsigned int version;
unsigned int _id;
unsigned int _subid;
unsigned int _instance;
unsigned int _id = 0;
unsigned int _subid = 0;
unsigned int _instance = 0;
union {
unsigned int _param;
unsigned int _param = 0;
uint8_t _sources[4];
struct {
uint16_t _ratio;
@ -1989,12 +2005,12 @@ class ModuleUnionField: public UnionField<unsigned int> {
Append(new SignedField<8>(parent, ppm.frameLength));
}
virtual bool select(const unsigned int& attr) const
bool select(const unsigned int & attr) const override
{
return true; // take what's left
}
virtual DataField* getField()
DataField * getField() override
{
return this;
}
@ -2017,21 +2033,20 @@ class ModuleUnionField: public UnionField<unsigned int> {
internalField.Append(new SignedField<8>(this, multi.optionValue));
}
virtual bool select(const unsigned int& attr) const
bool select(const unsigned int & attr) const override
{
return attr == PULSES_MULTIMODULE;
}
virtual void beforeExport()
void beforeExport() override
{
module.rfProtocol = module.multi.rfProtocol & 0xf;
rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03;
}
virtual void afterImport()
void afterImport() override
{
module.multi.rfProtocol =
(rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf);
module.multi.rfProtocol = (rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf);
}
private:
@ -2042,37 +2057,41 @@ class ModuleUnionField: public UnionField<unsigned int> {
class PxxField: public UnionField::TransformedMember {
public:
PxxField(DataField * parent, ModuleData& module):
PxxField(DataField * parent, ModuleData& module, unsigned int version):
UnionField::TransformedMember(parent, internalField),
internalField(this, "Pxx"),
module(module)
module(module),
version(version)
{
ModuleData::PXX& pxx = module.pxx;
internalField.Append(new UnsignedField<2>(this, pxx.power));
internalField.Append(new SpareBitsField<2>(this));
internalField.Append(new BoolField<1>(this, pxx.receiver_telem_off));
internalField.Append(new BoolField<1>(this, pxx.receiver_channel_9_16));
internalField.Append(new BoolField<1>(this, pxx.external_antenna));
internalField.Append(new BoolField<1>(this, pxx.sport_out));
internalField.Append(new BoolField<1>(this, pxx.receiverTelemetryOff));
internalField.Append(new BoolField<1>(this, pxx.receiverHigherChannels));
internalField.Append(new SignedField<2>(this, pxx.antennaMode));
internalField.Append(new SpareBitsField<8>(this));
}
bool select(const unsigned int& attr) const {
return attr==PULSES_PXX_XJT_X16 ||
bool select(const unsigned int& attr) const override {
return (attr >= PULSES_PXX_XJT_X16 && attr <= PULSES_PXX_XJT_LR12) ||
attr==PULSES_PXX_DJT ||
attr==PULSES_PXX_R9M ||
attr==PULSES_PXX_R9M_LITE;
}
virtual void beforeExport()
void beforeExport() override
{
if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) {
module.subType = module.protocol - PULSES_PXX_XJT_X16;
}
}
virtual void afterImport()
void afterImport() override
{
if (module.protocol == PULSES_PXX_XJT_X16) {
if (version <= 218)
module.protocol += module.rfProtocol;
else
module.protocol += module.subType;
}
}
@ -2080,6 +2099,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
private:
StructField internalField;
ModuleData& module;
unsigned int version;
};
class AccessField: public UnionField::TransformedMember {
@ -2094,24 +2114,23 @@ class ModuleUnionField: public UnionField<unsigned int> {
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++)
internalField.Append(new CharField<8>(this, receiverName[i]));
memset(receiverName, 0, sizeof(receiverName));
}
bool select(const unsigned int& attr) const {
bool select(const unsigned int& attr) const override {
return attr >= PULSES_ACCESS_ISRM && attr <= PULSES_ACCESS_R9M_LITE_PRO;
}
virtual void beforeExport()
void beforeExport() override
{
if (module.protocol == PULSES_ACCST_ISRM_D16 ||
module.protocol == PULSES_ACCESS_ISRM) {
if (module.protocol == PULSES_ACCST_ISRM_D16 || module.protocol == PULSES_ACCESS_ISRM) {
module.subType = module.protocol - PULSES_ACCESS_ISRM;
}
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++) {
for (int pos=0; pos<PXX2_LEN_RX_NAME+1; pos++) {
if (pos == PXX2_LEN_RX_NAME
|| module.access.receiverName[i][pos] == '\0') {
if (pos == PXX2_LEN_RX_NAME || module.access.receiverName[i][pos] == '\0') {
memset(module.access.receiverName[i]+pos,'\0',PXX2_LEN_RX_NAME-pos);
break;
}
@ -2120,17 +2139,14 @@ class ModuleUnionField: public UnionField<unsigned int> {
}
}
virtual void afterImport()
void afterImport() override
{
if (module.protocol == PULSES_ACCESS_ISRM) {
module.protocol += module.subType;
}
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++) {
for (int pos=0; pos<PXX2_LEN_RX_NAME+1; pos++) {
if (pos == PXX2_LEN_RX_NAME || receiverName[i][pos] == ' '
|| receiverName[i][pos] == '\0') {
if (pos == PXX2_LEN_RX_NAME || receiverName[i][pos] == ' ' || receiverName[i][pos] == '\0') {
module.access.receiverName[i][pos] = '\0';
break;
}
@ -2142,7 +2158,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
private:
StructField internalField;
ModuleData & module;
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1];
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1] = {};
};
public:
@ -2151,7 +2167,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
{
if (version >= 219)
Append(new AccessField(parent, module));
Append(new PxxField(parent, module));
Append(new PxxField(parent, module, version));
Append(new MultiField(parent, module));
Append(new PPMField(parent, module.ppm));
}
@ -2182,14 +2198,14 @@ class ModuleField: public TransformedField {
internalField.Append(new ModuleUnionField(parent, module, board, version));
}
virtual void beforeExport()
void beforeExport() override
{
if (module.protocol >= PULSES_LP45 && module.protocol <= PULSES_DSMX) {
module.rfProtocol = module.protocol - PULSES_LP45;
}
}
virtual void afterImport()
void afterImport() override
{
if (module.protocol == PULSES_LP45) {
module.protocol += module.rfProtocol;
@ -2297,6 +2313,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version));
else if (IS_TARANIS_X9E(board))
internalField.Append(new SwitchesWarningField<64>(this, modelData.switchWarningStates, board, version));
else if (version >= 219 && IS_TARANIS_X9D(board))
internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version));
else if (IS_TARANIS(board))
internalField.Append(new SwitchesWarningField<16>(this, modelData.switchWarningStates, board, version));
else
@ -2304,6 +2322,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
if (IS_TARANIS_X9E(board))
internalField.Append(new UnsignedField<32>(this, modelData.switchWarningEnable));
else if (version >= 219 && IS_TARANIS_X9D(board))
internalField.Append(new UnsignedField<16>(this, modelData.switchWarningEnable));
else if (!IS_HORUS(board))
internalField.Append(new UnsignedField<8>(this, modelData.switchWarningEnable));
@ -2356,7 +2376,6 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
int modulesCount = (version <= 218 ? 3 : 2);
for (int module = 0; module < modulesCount; module++) {
internalField.Append(new ModuleField(this, modelData.moduleData[module], board, version));
}
@ -2416,13 +2435,17 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
for (int i=0; i<8; i++) {
if (i < Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders))
internalField.Append(new BoolField<1>(this, modelData.potsWarningEnabled[i]));
internalField.Append(new BoolField<1>(this, modelData.potsWarnEnabled[i]));
else
internalField.Append(new SpareBitsField<1>(this));
}
for (int i=0; i < Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders); i++) {
internalField.Append(new SignedField<8>(this, modelData.potPosition[i]));
for (int i=0; i < MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version); i++) {
internalField.Append(new SignedField<8>(this, modelData.potsWarnPosition[i]));
}
if (version <= 218 && IS_HORUS_X10(board)) {
internalField.Append(new SpareBitsField<16>(this));
}
if (IS_SKY9X(board)) {
@ -2464,9 +2487,6 @@ void OpenTxModelData::beforeExport()
{
// qDebug() << QString("before export model") << modelData.name;
for (int module=0; module<2; module++) {
}
if (IS_HORUS(board)) {
uint32_t newSwitchWarningStates = 0;
for (int i = 0; i < MAX_SWITCHES(board, version); i++) {
@ -2483,11 +2503,6 @@ void OpenTxModelData::afterImport()
{
qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name;
// ??? what's this ???
if (IS_HORUS(board)) {
modelData.moduleData[0].protocol = PULSES_PXX_XJT_X16;
}
if (IS_HORUS(board)) {
uint32_t newSwitchWarningStates = 0;
for (int i = 0; i < MAX_SWITCHES(board, version); i++) {
@ -2500,9 +2515,10 @@ void OpenTxModelData::afterImport()
modelData.switchWarningStates = newSwitchWarningStates;
}
if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3)
if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3) {
modelData.thrTraceSrc += 2;
}
}
OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant):
TransformedField(nullptr, internalField),
@ -2510,7 +2526,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
generalData(generalData),
board(board),
version(version),
inputsCount(CPN_MAX_STICKS + Boards::getCapability(board, Board::PotsStorage) + Boards::getCapability(board, Board::SlidersStorage) + Boards::getCapability(board, Board::MouseAnalogs))
inputsCount(CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version) + Boards::getCapability(board, Board::MouseAnalogs))
{
qCDebug(eepromImport) << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
@ -2520,29 +2536,40 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new UnsignedField<8>(this, generalData.version));
internalField.Append(new UnsignedField<16>(this, generalData.variant));
for (int i=0; i<inputsCount; i++) {
if (version <= 218 && IS_HORUS(board) && (i == CPN_MAX_STICKS + 3)) {
// skip not yet existing pots (EXT1 / EXT2 for X10)
i += 2;
for (int i=0, input=0; i<inputsCount; i++, input++) {
if (version <= 218 && IS_HORUS_X10(board) && (i == CPN_MAX_STICKS + 3)) {
input += 2;
}
internalField.Append(new SignedField<16>(this, generalData.calibMid[i]));
internalField.Append(new SignedField<16>(this, generalData.calibSpanNeg[i]));
internalField.Append(new SignedField<16>(this, generalData.calibSpanPos[i]));
internalField.Append(new SignedField<16>(this, generalData.calibMid[input]));
internalField.Append(new SignedField<16>(this, generalData.calibSpanNeg[input]));
internalField.Append(new SignedField<16>(this, generalData.calibSpanPos[input]));
}
if (version <= 218 && IS_HORUS_X10(board)) {
internalField.Append(new SpareBitsField<16*6>(this));
}
internalField.Append(new UnsignedField<16>(this, chkSum));
if (!IS_HORUS(board)) {
internalField.Append(new UnsignedField<8>(this, generalData.currModelIndex));
internalField.Append(new UnsignedField<8>(this, generalData.contrast));
}
internalField.Append(new UnsignedField<8>(this, generalData.vBatWarn));
internalField.Append(new SignedField<8>(this, generalData.txVoltageCalibration));
internalField.Append(new SignedField<8>(this, generalData.backlightMode));
for (int i=0; i<CPN_MAX_STICKS; i++) {
internalField.Append(new SignedField<3>(this, generalData.backlightMode));
if (version >= 219)
internalField.Append(new SignedField<2>(this, generalData.antennaMode));
else
internalField.Append(new SpareBitsField<2>(this));
internalField.Append(new SpareBitsField<3>(this));
for (int i=0; i<4; i++) {
internalField.Append(new SignedField<16>(this, generalData.trainer.calib[i]));
}
for (int i=0; i<CPN_MAX_STICKS; i++) {
for (int i=0; i<4; i++) {
internalField.Append(new UnsignedField<6>(this, generalData.trainer.mix[i].src));
internalField.Append(new UnsignedField<2>(this, generalData.trainer.mix[i].mode));
internalField.Append(new SignedField<8>(this, generalData.trainer.mix[i].weight));
@ -2665,18 +2692,18 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
if (IS_STM32(board)) {
if (version >= 218) {
internalField.Append(new UnsignedField<4>(this, generalData.hw_uartMode));
if (!IS_HORUS(board) || version < 219) {
for (uint8_t i=0; i<4; i++) {
internalField.Append(new UnsignedField<4>(this, generalData.auxSerialMode));
if (IS_HORUS(board) && version >= 219) {
internalField.Append(new SpareBitsField<4>(this));
}
else {
for (uint8_t i=0; i<SLIDERS_CONFIG_SIZE(board,version); i++) {
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
}
}
else {
internalField.Append(new SpareBitsField<4>(this));
}
}
else {
internalField.Append(new UnsignedField<6>(this, generalData.hw_uartMode));
internalField.Append(new UnsignedField<6>(this, generalData.auxSerialMode));
if (IS_TARANIS_X9E(board)) {
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[2]));
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[3]));
@ -2687,33 +2714,35 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
if (IS_HORUS(board)) {
for (int i=0; i<MAX_SWITCH_SLOTS(board, version); i++) { // bits swconfig_t / 2
for (int i=0; i<SWITCHES_CONFIG_SIZE(board, version) / 2; i++) {
if (i < MAX_SWITCHES(board, version))
internalField.Append(new UnsignedField<2>(this, generalData.switchConfig[i]));
else
internalField.Append(new SpareBitsField<2>(this));
}
}
for (int i=0; i<MAX_KNOBS(board, version); i++) {
for (int i=0; i<POTS_CONFIG_SIZE(board, version) / 2; i++) {
int offset = 0;
// 2 new pots for Horus from 219 on
if (version <= 218 && IS_HORUS(board) && (i >= 3))
offset += 2;
if (i < Boards::getCapability(board, Board::PotsStorage))
if (i < MAX_POTS_STORAGE(board, version))
internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i+offset]));
else
internalField.Append(new SpareBitsField<2>(this));
}
if (IS_HORUS(board) && version >= 219) {
for (int i=0; i<MAX_SLIDERS_SLOTS(board,version); i++) {
if (i < Boards::getCapability(board, Board::SlidersStorage))
for (int i=0; i<SLIDERS_CONFIG_SIZE(board,version); i++) {
if (i < MAX_SLIDERS_STORAGE(board, version))
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
else
internalField.Append(new SpareBitsField<1>(this));
}
}
if (!IS_HORUS(board)) {
internalField.Append(new UnsignedField<8>(this, generalData.backlightColor));
}
@ -2752,13 +2781,16 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
for (int i=0; i<MAX_POTS_STORAGE(board, version); ++i) {
internalField.Append(new ZCharField<3>(this, generalData.potName[i], "Pot name"));
}
for (int i=0; i<Boards::getCapability(board, Board::SlidersStorage); ++i) {
for (int i=0; i<MAX_SLIDERS_STORAGE(board, version); ++i) {
internalField.Append(new ZCharField<3>(this, generalData.sliderName[i], "Slider name"));
}
if (version <= 218 && IS_HORUS_X10(board)) {
internalField.Append(new SpareBitsField<48>(this)); // DUMMY_ANAS
}
internalField.Append(new CharField<17>(this, generalData.currModelFilename, true, "Current model filename"));
}
else if (IS_TARANIS(board)) {
for (int i=0; i<MAX_SWITCH_SLOTS(board, version); i++) {
for (int i=0; i<SWITCHES_CONFIG_SIZE(board, version) / 2; i++) {
if (i < MAX_SWITCHES(board, version))
internalField.Append(new UnsignedField<2>(this, generalData.switchConfig[i]));
else
@ -2799,7 +2831,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new ZCharField<8>(this, generalData.registrationId, "ACCESS Registration ID"));
}
if (version >= 219 && (IS_TARANIS_XLITES(board) || IS_HORUS(board))) {
if (version >= 219 && IS_TARANIS_XLITES(board)) {
internalField.Append(new SignedField<8>(this, generalData.gyroMax, "Gyro full scale"));
internalField.Append(new SignedField<8>(this, generalData.gyroOffset, "Gyro Offset"));
}

View file

@ -58,9 +58,9 @@ OpenTxEepromInterface::~OpenTxEepromInterface()
const char * OpenTxEepromInterface::getName()
{
switch (board) {
case BOARD_STOCK:
case BOARD_9X_M64:
return "OpenTX for 9X board";
case BOARD_M128:
case BOARD_9X_M128:
return "OpenTX for M128 / 9X board";
case BOARD_MEGA2560:
return "OpenTX for MEGA2560 board";
@ -90,7 +90,7 @@ const char * OpenTxEepromInterface::getName()
return "OpenTX for 9XR-PRO";
case BOARD_AR9X:
return "OpenTX for ar9x board / 9X";
case BOARD_X12S:
case BOARD_HORUS_X12S:
return "OpenTX for FrSky Horus";
case BOARD_X10:
return "OpenTX for FrSky X10";
@ -273,11 +273,11 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board)
{
switch (board) {
case BOARD_STOCK:
case BOARD_9X_M64:
return 216;
case BOARD_GRUVIN9X:
case BOARD_MEGA2560:
case BOARD_M128:
case BOARD_9X_M128:
return 217;
default:
return 219;
@ -317,7 +317,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
efile->EeFsCreate(eeprom, size, board, version);
if (board == BOARD_M128) {
if (board == BOARD_9X_M128) {
variant |= M128_VARIANT;
}
else if (IS_TARANIS_X9E(board)) {
@ -433,7 +433,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
return 0;
else if (IS_ARM(board))
return 60;
else if (board == BOARD_M128)
else if (board == BOARD_9X_M128)
return 30;
else if (IS_2560(board))
return 30;
@ -512,7 +512,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
case CustomFunctions:
if (IS_ARM(board))
return 64;
else if (IS_2560(board) || board == BOARD_M128)
else if (IS_2560(board) || board == BOARD_9X_M128)
return 24;
else
return 16;
@ -703,9 +703,9 @@ int OpenTxFirmware::getCapability(::Capability capability)
case HasMahPersistent:
return (IS_ARM(board) ? true : false);
case SimulatorVariant:
if (board == BOARD_STOCK)
if (board == BOARD_9X_M64)
return SIMU_STOCK_VARIANTS;
else if (board == BOARD_M128)
else if (board == BOARD_9X_M128)
return SIMU_M128_VARIANTS;
else if (IS_TARANIS_X9E(board))
return TARANIS_X9E_VARIANT;
@ -774,9 +774,8 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_PPM:
return id.contains("internalppm");
case PULSES_ACCESS_ISRM:
return IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess"));
case PULSES_ACCST_ISRM_D16:
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board));
return IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess"));
default:
return false;
}
@ -945,7 +944,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int variant)
{
bool variantError = false;
if (board == BOARD_M128 && !(variant & M128_VARIANT)) {
if (board == BOARD_9X_M128 && !(variant & M128_VARIANT)) {
if (version == 212) {
uint8_t tmp[1000];
for (int i = 1; i < 31; i++) {
@ -1268,7 +1267,7 @@ void registerOpenTxFirmwares()
registerOpenTxFirmware(firmware);
/* FrSky X12 (Horus) board */
firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_X12S);
firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_HORUS_X12S);
addOpenTxFrskyOptions(firmware);
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version"));
@ -1302,10 +1301,10 @@ void registerOpenTxFirmwares()
registerOpenTxFirmware(firmware);
// These are kept only for import purposes, marked as deprecated to hide from UI.
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr", Firmware::tr("Turnigy 9XR"), BOARD_STOCK), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr128", Firmware::tr("Turnigy 9XR with m128 chip"), BOARD_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x", Firmware::tr("9X with stock board"), BOARD_STOCK), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x128", Firmware::tr("9X with stock board and m128 chip"), BOARD_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr", Firmware::tr("Turnigy 9XR"), BOARD_9X_M64), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr128", Firmware::tr("Turnigy 9XR with m128 chip"), BOARD_9X_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x", Firmware::tr("9X with stock board"), BOARD_9X_M64), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x128", Firmware::tr("9X with stock board and m128 chip"), BOARD_9X_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-gruvin9x", Firmware::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-mega2560", Firmware::tr("DIY MEGA2560 radio"), BOARD_MEGA2560), true);

View file

@ -48,7 +48,7 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
RawSourceRange result;
Firmware * firmware = Firmware::getCurrentVariant();
int board = firmware->getBoard();
Board::Type board = firmware->getBoard();
switch (type) {
case SOURCE_TYPE_TELEMETRY:

View file

@ -256,14 +256,14 @@ ui(new Ui::GeneralSetup)
}
if (!firmware->getCapability(PwrButtonPress)) {
ui->pwrOnSpeedLabel->hide();
ui->pwrOnSpeed->hide();
ui->pwrOffSpeedLabel->hide();
ui->pwrOffSpeed->hide();
ui->pwrOnDelayLabel->hide();
ui->pwrOnDelay->hide();
ui->pwrOffDelayLabel->hide();
ui->pwrOffDelay->hide();
}
else if (!IS_TARANIS(firmware->getBoard())) {
ui->pwrOnSpeedLabel->hide();
ui->pwrOnSpeed->hide();
ui->pwrOnDelayLabel->hide();
ui->pwrOnDelay->hide();
}
setValues();
@ -453,8 +453,8 @@ void GeneralSetupPanel::setValues()
ui->vBatMaxDSB->setValue((double)(generalSettings.vBatMax + 120) / 10);
}
ui->pwrOnSpeed->setValue(generalSettings.pwrOnSpeed);
ui->pwrOffSpeed->setValue(generalSettings.pwrOffSpeed);
ui->pwrOnDelay->setValue(2 - generalSettings.pwrOnSpeed);
ui->pwrOffDelay->setValue(2 - generalSettings.pwrOffSpeed);
// TODO: only if ACCESS available??
ui->registrationId->setText(generalSettings.registrationId);
@ -510,15 +510,15 @@ void GeneralSetupPanel::on_splashScreenDuration_currentIndexChanged(int index)
emit modified();
}
void GeneralSetupPanel::on_pwrOnSpeed_valueChanged()
void GeneralSetupPanel::on_pwrOnDelay_valueChanged()
{
generalSettings.pwrOnSpeed = ui->pwrOnSpeed->value();
generalSettings.pwrOnSpeed = 2 - ui->pwrOnDelay->value();
emit modified();
}
void GeneralSetupPanel::on_pwrOffSpeed_valueChanged()
void GeneralSetupPanel::on_pwrOffDelay_valueChanged()
{
generalSettings.pwrOffSpeed = ui->pwrOffSpeed->value();
generalSettings.pwrOffSpeed = 2 - ui->pwrOffDelay->value();
emit modified();
}

View file

@ -89,8 +89,8 @@ class GeneralSetupPanel : public GeneralPanel
void on_contrastSB_editingFinished();
void on_ownerID_editingFinished();
void on_pwrOnSpeed_valueChanged();
void on_pwrOffSpeed_valueChanged();
void on_pwrOnDelay_valueChanged();
void on_pwrOffDelay_valueChanged();
private:
Ui::GeneralSetup *ui;

View file

@ -1567,9 +1567,9 @@ Acceptable values are 5v..10v</string>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="pwrOnSpeedLabel">
<widget class="QLabel" name="pwrOnDelayLabel">
<property name="text">
<string>Power On Speed</string>
<string>Power On Delay</string>
</property>
</widget>
</item>
@ -2432,35 +2432,29 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="pwrOffSpeedLabel">
<widget class="QLabel" name="pwrOffDelayLabel">
<property name="text">
<string>Power Off Speed</string>
<string>Power Off Delay</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSlider" name="pwrOnSpeed">
<property name="minimum">
<number>-1</number>
<widget class="QSpinBox" name="pwrOnDelay">
<property name="suffix">
<string> sec</string>
</property>
<property name="maximum">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<number>3</number>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QSlider" name="pwrOffSpeed">
<property name="minimum">
<number>-1</number>
<widget class="QSpinBox" name="pwrOffDelay">
<property name="suffix">
<string> sec</string>
</property>
<property name="maximum">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<number>3</number>
</property>
</widget>
</item>

View file

@ -153,7 +153,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
setupSwitchType(17, ui->srLabel, ui->srName, ui->srType);
if (IS_TARANIS(board) && !IS_TARANIS_SMALL(board)) {
ui->serialPortMode->setCurrentIndex(generalSettings.hw_uartMode);
ui->serialPortMode->setCurrentIndex(generalSettings.auxSerialMode);
}
else {
ui->serialPortMode->setCurrentIndex(0);
@ -183,6 +183,18 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
ui->bluetoothWidget->hide();
}
if ((IS_HORUS(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))) {
ui->antennaMode->addItem(tr("Internal"), -2);
ui->antennaMode->addItem(tr("Ask"), -1);
ui->antennaMode->addItem(tr("Per model"), 0);
ui->antennaMode->addItem(IS_HORUS_X12S(board) ? tr("Internal + External") : tr("External"), 1);
ui->antennaMode->setField(generalSettings.antennaMode, this);
}
else {
ui->antennaLabel->hide();
ui->antennaMode->hide();
}
if (IS_HORUS_OR_TARANIS(board)) {
ui->filterEnable->setChecked(!generalSettings.jitterFilter);
}
@ -277,6 +289,6 @@ void HardwarePanel::on_txVoltageCalibration_editingFinished()
void HardwarePanel::on_serialPortMode_currentIndexChanged(int index)
{
generalSettings.hw_uartMode = index;
generalSettings.auxSerialMode = index;
emit modified();
}

File diff suppressed because it is too large Load diff

View file

@ -67,6 +67,14 @@ class GVarGroup: public QObject {
void setWeight(int val);
void setMinimum(int min) {
mini = min;
}
void setMaximum(int max) {
maxi = max;
}
signals:
void valueChanged();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 585 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 866 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 960 KiB

View file

@ -1,948 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800"
height="500"
id="svg2"
inkscape:label="Pozadí"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="splash22_3_dmg.svg"
inkscape:export-filename="/home/martin/Dokumenty/MojeDokumenty/OpenTXwip/Grafika/splash/splash22_3_dmg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs3">
<inkscape:path-effect
effect="spiro"
id="path-effect4023"
is_visible="true" />
<linearGradient
inkscape:collect="always"
id="linearGradient3977">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3979" />
<stop
style="stop-color:#6b6e7a;stop-opacity:1"
offset="1"
id="stop3981" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3959">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3961" />
<stop
style="stop-color:#adb0b6;stop-opacity:1"
offset="1"
id="stop3963" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4110"
id="linearGradient8590"
gradientUnits="userSpaceOnUse"
x1="32.03112"
y1="919.08826"
x2="13.698381"
y2="917.573" />
<linearGradient
id="linearGradient4110"
inkscape:collect="always">
<stop
id="stop4112"
offset="0"
style="stop-color:#787878;stop-opacity:1;" />
<stop
id="stop4114"
offset="1"
style="stop-color:#787878;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4087"
id="radialGradient8592"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1208029,0.28390177,-0.22234482,0.87778509,-104.71658,-31.467902)"
cx="-112.21627"
cy="-531.93341"
fx="-112.21627"
fy="-531.93341"
r="23.035715" />
<linearGradient
id="linearGradient4087"
inkscape:collect="always">
<stop
id="stop4089"
offset="0"
style="stop-color:#ff8080;stop-opacity:1" />
<stop
id="stop4091"
offset="1"
style="stop-color:#c80000;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4100"
id="linearGradient8594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.89739834,0,0,0.87587127,4.0183202,712.56816)"
x1="34.241589"
y1="83.140976"
x2="49.625"
y2="83.140976" />
<linearGradient
id="linearGradient4100"
inkscape:collect="always">
<stop
id="stop4102"
offset="0"
style="stop-color:#ff8080;stop-opacity:1;" />
<stop
id="stop4104"
offset="1"
style="stop-color:#ff8080;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4123"
id="linearGradient8596"
gradientUnits="userSpaceOnUse"
x1="98.229652"
y1="132.15594"
x2="103.66933"
y2="160.80135" />
<linearGradient
id="linearGradient4123"
inkscape:collect="always">
<stop
id="stop4125"
offset="0"
style="stop-color:#928c8c;stop-opacity:1;" />
<stop
id="stop4127"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4135"
id="linearGradient8598"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.63134529,702.36218)"
x1="121.7157"
y1="133.16609"
x2="137.76198"
y2="147.41682" />
<linearGradient
inkscape:collect="always"
id="linearGradient4135">
<stop
style="stop-color:#928c8c;stop-opacity:0"
offset="0"
id="stop4137" />
<stop
style="stop-color:#ffffff;stop-opacity:0.40282686"
offset="1"
id="stop4139" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3977"
id="linearGradient3921"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(123.50835,-63.991344)"
x1="747.14288"
y1="873.79077"
x2="773.57141"
y2="994.505" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3959"
id="linearGradient3923"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-291.32112,-51.262515)"
x1="81.822357"
y1="878.61597"
x2="107.07617"
y2="837.19971" />
<linearGradient
inkscape:collect="always"
id="linearGradient3977-5">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3979-5" />
<stop
style="stop-color:#6b6e7a;stop-opacity:1"
offset="1"
id="stop3981-5" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3959-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3961-7" />
<stop
style="stop-color:#adb0b6;stop-opacity:1"
offset="1"
id="stop3963-1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3977"
id="linearGradient4188"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(123.50835,-63.991344)"
x1="747.14288"
y1="873.79077"
x2="773.57141"
y2="994.505" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3959"
id="linearGradient4190"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-291.32112,-51.262515)"
x1="81.822357"
y1="878.61597"
x2="107.07617"
y2="837.19971" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4312">
<rect
y="545.63458"
x="131.18359"
height="133.1575"
width="261.93893"
id="rect4314"
style="fill:none;stroke:#d62929;stroke-opacity:1" />
</clipPath>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3977-5"
id="linearGradient4444"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(123.50835,-63.991344)"
x1="747.14288"
y1="873.79077"
x2="773.57141"
y2="994.505" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3959-3"
id="linearGradient4446"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-291.32112,-51.262515)"
x1="81.822357"
y1="878.61597"
x2="107.07617"
y2="837.19971" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3977-5"
id="linearGradient4505"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(123.50835,-63.991344)"
x1="747.14288"
y1="873.79077"
x2="773.57141"
y2="994.505" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3959-3"
id="linearGradient4507"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-291.32112,-51.262515)"
x1="81.822357"
y1="878.61597"
x2="107.07617"
y2="837.19971" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3274">
<rect
style="fill:none;stroke:#d62929;stroke-opacity:1"
id="rect3276"
width="420.34811"
height="133.34306"
x="130.51035"
y="521.02094" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3274-3">
<rect
style="fill:none;stroke:#d62929;stroke-opacity:1"
id="rect3276-2"
width="420.34811"
height="133.34306"
x="130.51035"
y="521.02094" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4312-9">
<rect
y="545.63458"
x="131.18359"
height="133.1575"
width="261.93893"
id="rect4314-5"
style="fill:none;stroke:#d62929;stroke-opacity:1" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3883">
<rect
style="fill:#d89119;fill-opacity:1;stroke:none"
id="rect3885"
width="241.35912"
height="37.132172"
x="211.64659"
y="1009.2491" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4891-2">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4893-0"
width="640"
height="210"
x="0"
y="842.36218" />
</clipPath>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5591"
id="linearGradient12262"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-91.923881,-6.3134535)"
x1="146.07436"
y1="846.03851"
x2="218.59071"
y2="846.03851" />
<linearGradient
id="linearGradient5591"
inkscape:collect="always">
<stop
id="stop5593"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop5595"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3977-0"
id="linearGradient3965"
x1="532.14532"
y1="869.62433"
x2="494.59061"
y2="997.27747"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3977-0">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3979-1" />
<stop
style="stop-color:#c3b7a1;stop-opacity:1;"
offset="1"
id="stop3981-4" />
</linearGradient>
<filter
inkscape:collect="always"
id="filter4196"
x="-0.080580361"
width="1.1611607"
y="-0.18846314"
height="1.3769263"
style="color-interpolation-filters:sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="30.294119"
id="feGaussianBlur4198" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3977-0"
id="radialGradient4178"
cx="321.13412"
cy="1244.5212"
fx="321.13412"
fy="1244.5212"
r="469.35312"
gradientTransform="matrix(1.9217668,0.29348951,-0.18210814,1.1924423,-68.177703,-526.12911)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3333">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3335" />
<stop
style="stop-color:#c3b7a1;stop-opacity:1;"
offset="1"
id="stop3337" />
</linearGradient>
<filter
inkscape:collect="always"
id="filter4204"
x="-0.087714754"
width="1.1754295"
y="-0.15834162"
height="1.3166832"
style="color-interpolation-filters:sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="33.153964"
id="feGaussianBlur4206" />
</filter>
<linearGradient
id="linearGradient4347">
<stop
style="stop-color:#f0e47c;stop-opacity:1;"
offset="0"
id="stop4349" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4351" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4291"
id="radialGradient4297"
cx="232.55463"
cy="997.94202"
fx="232.55463"
fy="997.94202"
r="247.41025"
gradientTransform="matrix(1.7432285,-1.5632483,1.7076977,1.4428782,-1700.9789,-1057.0931)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4291">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4293" />
<stop
style="stop-color:#8296d6;stop-opacity:0;"
offset="1"
id="stop4295" />
</linearGradient>
<linearGradient
id="linearGradient5611">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5613" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5615" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5591-6"
id="linearGradient4003-4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-91.923881,-6.3134535)"
x1="146.07436"
y1="846.03851"
x2="218.59071"
y2="846.03851" />
<linearGradient
id="linearGradient5591-6"
inkscape:collect="always">
<stop
id="stop5593-1"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop5595-0"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5591-6"
id="linearGradient5018"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-91.923881,-6.3134535)"
x1="146.07436"
y1="846.03851"
x2="218.59071"
y2="846.03851" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5591-6"
id="linearGradient5046"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-91.923881,-6.3134535)"
x1="146.07436"
y1="846.03851"
x2="218.59071"
y2="846.03851" />
<filter
inkscape:collect="always"
id="filter8684">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.37919011"
id="feGaussianBlur8686" />
</filter>
<filter
inkscape:collect="always"
id="filter8696">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.37919011"
id="feGaussianBlur8698" />
</filter>
<filter
inkscape:collect="always"
id="filter8708">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.37919011"
id="feGaussianBlur8710" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5591"
id="linearGradient9450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.7604321,0,0,3.7554825,-1099.283,-1774.0469)"
x1="146.07436"
y1="846.03851"
x2="218.59071"
y2="846.03851" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.39482968"
inkscape:cx="240.13866"
inkscape:cy="72.917006"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
borderlayer="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1215"
inkscape:window-height="1000"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1">
<sodipodi:guide
orientation="0,1"
position="225.44567,-819.73138"
id="guide3904" />
<sodipodi:guide
orientation="0,1"
position="228.337,-793.0061"
id="guide3906" />
<sodipodi:guide
orientation="0,1"
position="143.37385,50.789259"
id="guide4005" />
</sodipodi:namedview>
<metadata
id="metadata6">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Vrstva#1"
style="display:inline"
transform="translate(0,290)">
<rect
style="display:inline;fill:#234ca2;fill-opacity:1;stroke:none"
id="rect3846-4"
width="804.09418"
height="503.88089"
x="-2.954421"
y="-291.07556" />
<path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:19;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 253.27378,-420.65169 416.16531,-138.51528 176.19537,277.12476"
id="path5011"
inkscape:connector-curvature="0" />
<path
style="fill:#ffeb0e;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 245.67556,-416.85258 159.66351,276.54531 -280.60799,486.02728 -218.442373,0 0,-768.90443 z"
id="path5014"
inkscape:connector-curvature="0" />
<rect
y="-292.86649"
x="-23.549952"
height="457.31708"
width="868.56714"
id="rect4289"
style="display:inline;fill:url(#radialGradient4297);fill-opacity:1;stroke:none" />
<path
style="display:inline;fill:#fff9f9;fill-opacity:1;stroke:none"
d="m 877.13158,56.928644 -30.07273,-72.66535 -10.647,4.40919 c -0.17223,-0.79215 -0.39809,-1.58039 -0.71897,-2.3558 -2.90654,-7.02343 -10.9547,-10.3598 -17.9757,-7.45219 -5.55461,2.30021 -8.78643,7.82963 -8.46164,13.51264 -2.92241,-3.09113 -7.55211,-4.22774 -11.71605,-2.50328 -5.39129,2.23251 -7.95886,8.43043 -5.72708,13.82349 0.0122,0.022 0.0159,0.0391 0.0244,0.0599 -1.57291,-0.23301 -3.23597,-0.0794 -4.81206,0.57295 -3.0569,1.26588 -5.03792,4.02051 -5.49659,7.07108 l -12.49426,5.17422 c -0.1136,-0.96652 -0.33908,-1.94342 -0.72935,-2.88684 -2.28382,-5.5183 -8.61127,-8.14158 -14.12788,-5.85701 -4.94387,2.0474 -7.54039,7.34869 -6.38693,12.39754 -1.54666,-0.14772 -3.15108,0.0709 -4.68662,0.70723 -3.09904,1.28336 -5.19109,3.95869 -5.84874,7.00742 -3.84696,-1.78322 -9.65796,-1.65651 -15.4063,0.7241 -0.23587,0.0965 -0.45647,0.20479 -0.68709,0.30779 -3.08255,-4.50596 -8.99982,-6.39782 -14.24392,-4.22615 -6.01804,2.49217 -8.87047,9.37666 -6.37899,15.3968 0.5978,1.44452 1.45638,2.71382 2.48854,3.76415 l -8.99823,3.7264 c -2.34795,-4.67312 -7.93713,-6.8146 -12.84532,-4.78211 -1.25691,0.52065 -2.35259,1.28311 -3.25955,2.1878 -3.04566,-4.9439 -9.31325,-7.08257 -14.84966,-4.78994 -3.65055,1.51173 -6.14483,4.59908 -7.04861,8.15612 -2.30129,-0.34518 -4.71386,-0.0965 -7.02052,0.85887 -5.02399,2.08063 -8.09763,6.89684 -8.20023,12.00789 -1.69946,-0.36914 -3.51985,-0.24035 -5.24838,0.47446 -2.59152,1.0733 -4.39505,3.24625 -5.11328,5.74856 -3.11297,-6.10621 -10.44729,-8.8942 -16.88711,-6.2273 -5.2253,2.16391 -8.31884,7.28974 -8.17678,12.62659 -2.04295,-0.2798 -4.19216,-0.056 -6.23474,0.78975 -5.91433,2.4493 -8.81782,9.0684 -6.7585,15.0418 l -18.55274,7.6831 c -1.99787,-3.7365 -6.54926,-5.4343 -10.54562,-3.7793 -0.36363,0.1511 -0.70968,0.3298 -1.03973,0.5237 -2.71342,-4.6598 -8.51012,-6.7171 -13.62964,-4.597 -5.58514,2.313 -8.23712,8.7139 -5.92484,14.300996 0.13058,0.3158 0.28999,0.6127 0.44621,0.9091 -2.1166,-0.8527 -4.552,-0.908 -6.82666,0.034 -3.926,1.626 -6.08584,5.713 -5.46471,9.7346 -0.12215,-0.4249 -0.25749,-0.8465 -0.43033,-1.2647 -2.49575,-6.0305 -9.41953,-8.9008 -15.44795,-6.4043 -3.6812,1.5245 -6.16132,4.704 -6.98289,8.3149 -4.00881,-4.9547 -10.94053,-6.8976 -17.12799,-4.3353 -6.64857,2.7534 -10.21044,9.7934 -8.81599,16.5922 -1.06086,0.089 -2.13248,0.3473 -3.16879,0.7769 -4.53466,1.878 -7.06376,6.54154 -6.44519,11.18824 l -22.86313,9.4682 c -0.0122,-1.2886 -0.26238,-2.6006 -0.78506,-3.8647 -2.16545,-5.2322 -8.16688,-7.7204 -13.39743,-5.5543 -3.66019,1.5158 -5.96222,4.9132 -6.28078,8.6061 -1.19181,0.034 -2.4133,0.2544 -3.58043,0.738 -4.88743,2.0238 -7.30965,7.4482 -5.71231,12.3975 l -6.21738,2.5746 c -2.45178,-4.4168 -7.86237,-6.38 -12.64097,-4.4011 -1.04681,0.4334 -1.98663,1.0314 -2.79391,1.7388 -3.19884,-4.0115 -8.7758,-5.6061 -13.75264,-3.5451 -5.26145,2.1789 -8.11204,7.7246 -7.09308,13.109 -0.73485,0.3458 -1.40972,0.7753 -2.00886,1.2741 -2.75397,-2.0639 -6.50627,-2.6591 -9.91631,-1.2468 -3.99561,1.6546 -6.33465,5.5806 -6.19222,9.6634 -1.14368,0.02 -2.30422,0.2555 -3.42482,0.7201 -3.72823,1.5439 -5.90407,5.209 -5.76091,9.0193 l -8.28318,3.4303 c -2.18683,-4.8632 -7.83415,-7.1601 -12.79316,-5.1063 -2.10377,0.8711 -3.73263,2.4051 -4.78421,4.239 -1.44563,0.1236 -2.97909,0.4891 -4.5139,1.1245 -0.49152,0.2032 -0.96485,0.4397 -1.41717,0.6798 -2.25292,-0.9814 -4.86141,-1.0822 -7.31099,-0.067 -1.50585,0.6234 -2.76154,1.5858 -3.71577,2.7722 -3.41346,-2.9002 -8.29344,-3.8273 -12.71609,-1.9959 -5.59748,2.318 -8.57034,8.2778 -7.3298,13.9985 -1.71265,-0.2724 -3.51923,-0.1027 -5.23897,0.6098 -4.37868,1.8135 -6.72577,6.4472 -5.80965,10.9252 l -4.74733,1.9659 30.07274,72.6653 597.06608,-77.3299 z"
id="rect3848-0-85"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccsccccccccscccccssccccccccsccccccccscccccccscccccccsccccscccccccccccccsccccccc" />
<path
inkscape:connector-curvature="0"
id="path3975-80"
d="m 1193.5465,858.03124 -29.4521,-110.4209 -16.1842,4.3168 c -0.097,-1.174 -0.2718,-2.3525 -0.586,-3.5308 -2.8466,-10.6726 -13.8062,-17.0168 -24.4788,-14.1701 -8.4433,2.2521 -14.1567,9.5997 -14.7743,17.848 -3.6206,-5.0114 -10.0747,-7.5331 -16.4041,-5.8449 -8.1951,2.1858 -13.0791,10.623 -10.8932,18.8181 0.01,0.032 0.016,0.06 0.024,0.09 -2.222,-0.6369 -4.6479,-0.7332 -7.0436,-0.094 -4.6467,1.2394 -8.0276,4.8289 -9.2713,9.1355 l -18.9922,5.0658 c 0.021,-1.4139 -0.1174,-2.8641 -0.4995,-4.2978 -2.2367,-8.3856 -10.8531,-13.3735 -19.2388,-11.1368 -7.5151,2.0044 -12.2694,9.1448 -11.5717,16.638 -2.2004,-0.5087 -4.5543,-0.4994 -6.8884,0.1232 -4.7108,1.2564 -8.23652,4.7104 -9.76662,8.9765 -5.2026,-3.304 -13.6002,-4.2318 -22.3382,-1.9011 -0.3585,0.096 -0.6969,0.2076 -1.0488,0.3121 -3.581,-7.08 -11.7462,-10.9359 -19.7177,-8.8097 -9.1479,2.4399 -14.5732,11.8119 -12.1332,20.9599 0.5855,2.195 1.5801,4.1876 2.8669,5.8978 l -13.6781,3.6483 c -2.4906,-7.1803 -10.1353,-11.3332 -17.5961,-9.3433 -1.9107,0.5097 -3.6352,1.3986 -5.1148,2.5286 -3.4444,-7.7036 -12.0671,-11.9823 -20.4828,-9.7376 -5.5491,1.48 -9.7331,5.4506 -11.715,10.4017 -3.2501,-0.9368 -6.7741,-1.0393 -10.2803,-0.1041 -7.6369,2.037 -12.9861,8.3873 -14.1102,15.7302 -2.3784,-0.8566 -5.0258,-1.0204 -7.6534,-0.3196 -3.9394,1.0508 -6.9532,3.8363 -8.4663,7.3036 -3.3191,-9.3907 -13.355,-14.8083 -23.144,-12.1975 -7.9429,2.1187 -13.3799,8.9113 -14.1947,16.6261 -2.8902,-0.7934 -6.02995,-0.882 -9.13489,-0.054 -8.99025,2.398 -14.43842,11.3779 -12.61231,20.3763 l -28.20158,7.5221 c -2.16498,-5.7643 -8.39914,-9.0797 -14.47374,-7.4594 -0.55283,0.1479 -1.0856,0.3396 -1.59838,0.5557 -3.01962,-7.2309 -10.9796,-11.3022 -18.76147,-9.2265 -8.48998,2.2645 -13.53415,10.9783 -11.26966,19.4682 0.12794,0.4798 0.3009,0.938 0.46937,1.3949 -2.88702,-1.6328 -6.38577,-2.1779 -9.84361,-1.2556 -5.96773,1.5918 -9.86057,7.0664 -9.73405,12.9783 -0.0947,-0.6354 -0.20909,-1.2688 -0.37854,-1.9042 -2.44421,-9.1638 -11.87275,-14.6217 -21.03641,-12.1774 -5.59564,1.4924 -9.7769,5.5986 -11.65065,10.6432 -4.82999,-7.9033 -14.44707,-12.0266 -23.85245,-9.5181 -10.10638,2.6957 -16.58369,12.1562 -15.87323,22.2162 -1.5458,-0.073 -3.13924,0.093 -4.7144,0.5137 -6.89322,1.8386 -11.42848,8.073 -11.42493,14.8847 l -34.7537,9.2697 c 0.2357,-1.8574 0.11937,-3.7962 -0.39288,-5.7168 -2.12072,-7.951 -10.29329,-12.682 -18.24422,-10.5613 -5.5638,1.484 -9.52984,5.9381 -10.69443,11.1969 -1.72402,-0.1789 -3.52593,-0.095 -5.30017,0.3788 -7.42927,1.9815 -11.95597,9.332 -10.59952,16.7667 l -9.45087,2.5208 c -2.68926,-6.8309 -10.11075,-10.693 -17.37455,-8.7555 -1.5911,0.4243 -3.05966,1.106 -4.35807,1.9709 -3.84299,-6.3899 -11.5747,-9.7527 -19.13992,-7.7348 -7.99785,2.1332 -13.16481,9.5769 -12.72512,17.52777 -1.12488,0.3576 -2.17944,0.8474 -3.13812,1.4515 -3.57408,-3.49947 -8.86743,-5.07357 -14.05092,-3.69107 -6.07344,1.61997 -10.19397,6.82827 -10.76873,12.73677 -1.65177,-0.1901 -3.369,-0.072 -5.07271,0.3827 -5.66704,1.5116 -9.50243,6.3754 -10.02407,11.8914 l -12.59113,3.3584 c -2.22216,-7.4232 -9.92099,-11.811 -17.4591,-9.8004 -3.19785,0.853 -5.83796,2.7513 -7.70353,5.192 -2.10667,-0.098 -4.38619,0.135 -6.71932,0.7572 -0.74697,0.1989 -1.47434,0.4492 -2.17189,0.7087 -3.0588,-1.8442 -6.79851,-2.4883 -10.52203,-1.495 -2.28891,0.6105 -4.28205,1.7566 -5.88374,3.2834 -4.36467,-4.8302 -11.21945,-7.0983 -17.94211,-5.3052 -8.50871,2.2695 -13.93086,10.2864 -13.23639,18.7638 -2.41578,-0.7193 -5.05157,-0.8196 -7.66547,-0.1224 -6.6561,1.7754 -10.92344,8.0017 -10.4587,14.627 l -7.21641,1.9248 29.45211,110.42089 875.12416,-11.811 z"
style="display:inline;fill:url(#radialGradient4178);fill-opacity:1;stroke:none;filter:url(#filter4204)"
transform="matrix(0.85505879,0.09386503,-0.09382668,0.85540827,-193.08489,-633.44617)"
sodipodi:nodetypes="ccccscsccccccccccccscccccccsccccccccccsccscccccccccssccccccccccccccccccccscsccccc" />
<path
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none"
d="m 624.36947,366.03444 35.80221,-91.5894 -13.41855,-5.2496 c 0.53058,-0.8637 1.00939,-1.7702 1.39152,-2.7474 3.4604,-8.8525 -0.90784,-18.8354 -9.7567,-22.297 -7.00054,-2.739 -14.70287,-0.5526 -19.33073,4.8536 0.0413,-5.3201 -3.14945,-10.3566 -8.39726,-12.4099 -6.7948,-2.6581 -14.47681,0.7063 -17.13386,7.5037 -0.0153,0.026 -0.0199,0.049 -0.029,0.075 -1.21635,-1.5734 -2.84919,-2.876 -4.83544,-3.6532 -3.85277,-1.5072 -8.02444,-0.739 -11.07934,1.6137 l -15.74692,-6.1604 c 0.73417,-0.97 1.37716,-2.046 1.84192,-3.2353 2.71889,-6.9554 -0.71539,-14.8038 -7.66811,-17.5239 -6.23094,-2.4378 -13.16274,0.093 -16.49424,5.6458 -1.26659,-1.4737 -2.90324,-2.6662 -4.83849,-3.4234 -3.90576,-1.5281 -8.10874,-0.9285 -11.34172,1.2512 -1.92486,-4.9414 -7.27469,-9.8626 -14.51959,-12.6969 -0.29721,-0.1161 -0.58877,-0.2116 -0.88599,-0.3177 1.12211,-6.7347 -2.57579,-13.5683 -9.18503,-16.1539 -7.58473,-2.9674 -16.11806,0.7696 -19.08407,8.3574 -0.71173,1.8207 -1.03673,3.7094 -1.01535,5.5509 l -11.34082,-4.4365 c 1.92929,-6.249 -1.25636,-13.0233 -7.44223,-15.4434 -1.58426,-0.6197 -3.23253,-0.8816 -4.8336,-0.8516 1.53433,-7.0978 -2.26545,-14.4574 -9.24306,-17.1873 -4.60085,-1.7999 -9.52333,-1.1771 -13.41841,1.2475 -1.77624,-2.3054 -4.16724,-4.1715 -7.07445,-5.3088 -6.33189,-2.4771 -13.27376,-0.7972 -17.79197,3.7232 -1.21283,-1.8057 -2.96481,-3.2677 -5.14349,-4.1201 -3.26613,-1.2778 -6.77405,-0.8803 -9.5884,0.7533 2.48019,-8.204 -1.71943,-17.07374 -9.83566,-20.24894 -6.58556,-2.5766 -13.81367,-0.6345 -18.30668,4.3015 -1.59985,-2.0227 -3.73165,-3.6833 -6.30607,-4.6904 -7.45398,-2.9162 -15.80344,0.5371 -19.11889,7.70854 l -23.38251,-9.14734 c 1.43398,-5.101 -1.20031,-10.5759 -6.23688,-12.5463 -0.45835,-0.1795 -0.92555,-0.3174 -1.39107,-0.4287 1.58808,-6.5535 -1.8578,-13.4318 -8.30989,-15.956 -7.03917,-2.7538 -14.97304,0.7206 -17.72584,7.7628 -0.15549,0.3978 -0.26896,0.8037 -0.38474,1.2063 -1.17037,-2.6028 -3.31851,-4.763 -6.18556,-5.8846 -4.94784,-1.9358 -10.43436,-0.1222 -13.3567,4.0434 0.25766,-0.4891 0.50111,-0.9866 0.70715,-1.5136 2.9712,-7.6011 -0.78688,-16.1893 -8.38458,-19.1615 -4.63948,-1.8152 -9.62902,-1.0977 -13.49676,1.4476 0.67538,-7.9419 -3.89278,-15.70065 -11.69102,-18.75147 -8.37938,-3.2781 -17.68705,-0.0159 -22.31675,7.32392 -1.03445,-0.83825 -2.22406,-1.53423 -3.53005,-2.04511 -5.71531,-2.23606 -12.03405,-0.22189 -15.49981,4.50446 L 159.20103,78.45548 c 1.10913,-1.16821 2.01557,-2.57223 2.63841,-4.16539 2.57793,-6.59482 -0.67934,-14.03907 -7.27163,-16.61821 -4.61306,-1.80464 -9.6307,-0.73554 -13.11554,2.31878 -1.10438,-1.00217 -2.39649,-1.86162 -3.86758,-2.43704 -6.15976,-2.40985 -13.0407,0.38275 -15.88575,6.23031 l -7.83598,-3.06552 c 1.6136,-6.10772 -1.56547,-12.56672 -7.58808,-14.92293 -1.31913,-0.51614 -2.68439,-0.79132 -4.02504,-0.85273 0.58907,-6.38964 -3.059189,-12.66023 -9.331659,-15.11424 -6.63122,-2.59426 -14.00351,-0.0627 -17.74692,5.67547 -0.96205,-0.32482 -1.94258,-0.52223 -2.91485,-0.5916 -0.69615,-4.24779 -3.56456,-8.03597 -7.86223,-9.7173 -5.03567,-1.96995 -10.54434,-0.45639 -13.95128,3.3489 -1.04835,-0.97313 -2.2992,-1.76566 -3.711808,-2.31831 -4.69873,-1.83825 -9.83428,-0.41835 -13.0045,3.14187 l -10.43955,-4.08429 c 2.23903,-6.28055 -0.8646,-13.24543 -7.11462,-15.69057 -2.6514,-1.03715 -5.44849,-1.06527 -7.9845699,-0.3227 -1.41077,-1.14089 -3.10973,-2.14062 -5.04406,-2.8974 -0.61932,-0.24233 -1.25102,-0.43943 -1.86667,-0.61484 -1.18183005,-2.83705 -3.44666,-5.18867001 -6.53394,-6.39650001 C -7.1544869,-1.38118 -9.1199769,-1.6015 -11.007877,-1.35826 c -0.56678,-5.57357 -4.16434,-10.63833 -9.73837,-12.81897 -7.054599,-2.7599 -14.895919,0.0382 -18.730659,6.27242 -1.30874,-1.72945 -3.08499,-3.14156 -5.25223,-3.98941 -5.51875,-2.1591 -11.6475,-0.0153 -14.69874,4.81786 l -5.9832,-2.34078 -53.009694,246.06918 742.7907,129.383 z"
id="rect3848-52"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccscccccscccscccccccscccccccccccsccsccccssccccccsccscsccscccscscsccccc" />
<path
inkscape:connector-curvature="0"
id="path3957-2"
d="m 784.03557,1142.9676 29.5781,-110.3871 -16.1792,-4.3352 c 0.5019,-1.0657 0.9384,-2.1743 1.2541,-3.3522 2.8588,-10.6693 -3.4729,-21.6361 -14.1422,-24.4949 -8.4408,-2.26169 -17.0585,1.2547 -21.7097,8.0944 -0.6369,-6.1495 -4.9716,-11.55547 -11.2991,-13.25092 -8.1926,-2.1952 -16.6353,2.67926 -18.8305,10.87182 -0.01,0.031 -0.016,0.06 -0.024,0.09 -1.6077,-1.6607 -3.6619,-2.9547 -6.0569,-3.5965 -4.6453,-1.2447 -9.3663,0.1788 -12.5932,3.2903 l -18.9864,-5.0874 c 0.7234,-1.215 1.3277,-2.54036 1.7118,-3.97363 2.2462,-8.38304 -2.7318,-17.00523 -11.1149,-19.25147 -7.5128,-2.01304 -15.196,1.80223 -18.3305,8.644 -1.6531,-1.53882 -3.6976,-2.70544 -6.031,-3.33067 -4.7093,-1.26185 -9.4882,-0.0282 -12.943,2.90536 -2.8599,-5.45936 -9.6742,-10.45382 -18.4096,-12.79448 -0.3584,-0.096 -0.7075,-0.16773 -1.0646,-0.25284 0.4297,-7.9224 -4.7221,-15.33856 -12.6911,-17.47387 -9.1451,-2.45042 -18.5234,2.96407 -20.9738,12.1092 -0.588,2.1944 -0.7204,4.41748 -0.4587,6.54167 l -13.6739,-3.66389 c 1.4247,-7.4653 -3.1278,-14.87902 -10.5863,-16.87752 -1.9101,-0.51182 -3.8481,-0.602 -5.6942,-0.36109 0.8593,-8.39474 -4.478,-16.40548 -12.8911,-18.65977 -5.5474,-1.48642 -11.1546,-0.13339 -15.3428,3.1682 -2.349,-2.43368 -5.3517,-4.281 -8.8569,-5.22021 -7.6346,-2.04568 -15.439,0.78829 -20.0774,6.59066 -1.6336,-1.92926 -3.8461,-3.3923 -6.4729,-4.09613 -3.9382,-1.05523 -7.94,-0.14518 -10.9814,2.10452 1.8097,-9.79428 -4.1839,-19.49723 -13.9698,-22.11938 -7.9405,-2.12764 -16.0418,1.04575 -20.5977,7.32478 -2.1087,-2.12989 -4.7854,-3.77339 -7.8894,-4.6051 -8.9875,-2.40819 -18.1899,2.65497 -21.0977,11.36424 l -28.193,-7.55428 c 1.0003,-6.07563 -2.7478,-12.05962 -8.8206,-13.68681 -0.5527,-0.1481 -1.1102,-0.24747 -1.6624,-0.31602 0.9915,-7.77313 -3.875,-15.27335 -11.6545,-17.35788 -8.4874,-2.27419 -17.2069,2.76003 -19.4811,11.24743 -0.1285,0.47963 -0.2073,0.96298 -0.2893,1.44303 -1.6871,-2.85561 -4.4471,-5.07388 -7.9039,-6.00012 -5.9659,-1.59857 -12.0713,1.20312 -14.9118,6.3895 0.2348,-0.598 0.452,-1.20392 0.6222,-1.83913 2.4547,-9.16099 -2.9925,-18.59564 -12.1534,-21.0503 -5.5939,-1.49887 -11.2664,-0.0273 -15.4075,3.40968 -0.2418,-9.25926 -6.5183,-17.6316 -15.9208,-20.15099 -10.1033,-2.70717 -20.4374,2.25898 -24.8418,11.33158 -1.303,-0.83492 -2.7671,-1.48554 -4.3418,-1.90747 -6.8911,-1.84647 -13.9324,1.29314 -17.3284,7.19784 l -34.7431,-9.30938 c 1.1311,-1.49197 1.9978,-3.23022 2.5123,-5.15026 2.1298,-7.94851 -2.5917,-16.12655 -10.5402,-18.25634 -5.5621,-1.49036 -11.2217,0.39044 -14.8551,4.36649 -1.4048,-1.01526 -3.0084,-1.84135 -4.7821,-2.31662 -7.427,-1.99006 -15.0178,2.12099 -17.5523,9.24076 l -9.448,-2.53159 c 1.0782,-7.26161 -3.426,-14.31189 -10.6876,-16.25761 -1.5906,-0.4262 -3.2034,-0.56831 -4.7602,-0.46669 -0.1417,-7.45513 -5.1639,-14.22755 -12.7268,-16.25403 -7.9954,-2.14237 -16.1876,1.73002 -19.7741,8.83953 -1.1533,-0.25135 -2.3116,-0.3531 -3.4438,-0.30807 -1.351,-4.81613 -5.152699,-8.8217 -10.334599,-10.21018 -6.0716,-1.62689 -12.2414,0.83038 -15.6879,5.66389 -1.3366,-0.98895 -2.8838,-1.74327 -4.587,-2.19965 -5.6653,-1.518 -11.4161,0.78299 -14.6207,5.30283 l -12.5873,-3.37274 c 1.7785,-7.54171 -2.7037,-15.18597 -10.2395,-17.2052 -3.1969,-0.85659 -6.4321,-0.52891 -9.2667,0.65519 -1.7769,-1.13587 -3.8684,-2.07181 -6.2008,-2.69678 -0.7467,-0.20009 -1.5018,-0.3465 -2.2358,-0.46967 -1.7305,-3.12447 -4.6499,-5.54881 -8.3722996,-6.54622 -2.2882,-0.61312 -4.5874,-0.61445 -6.7373,-0.0906 -1.3721,-6.36384 -6.1806,-11.75002 -12.9012004,-13.55081 -8.5061,-2.27921 -17.2055,1.96262 -20.83394,9.65554 -1.73458,-1.8288 -3.96869,-3.23102 -6.5818,-3.9312 -6.65407,-1.78296 -13.4591,1.48324 -16.36247,7.45666 l -7.21421,-1.93304 -36.017883,370.02255 881.296802,-25.2181 z"
style="display:inline;opacity:0.76678443;fill:url(#linearGradient3965);fill-opacity:1;stroke:none;filter:url(#filter4196)"
transform="matrix(0.85837445,-0.05590027,0.05587743,0.85872528,-281.62956,-689.27743)"
sodipodi:nodetypes="ccccscsccccccscscccssccscscscscscsccscsccscsscscscccscsccscsccscsccscccscscsccccc" />
<rect
style="opacity:0.459;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:7.8415556;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5016"
width="490.40955"
height="183.9483"
x="154.96779"
y="-232.75832"
ry="38.450249" />
</g>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-552.36218)"
style="display:inline">
<g
id="g9429"
transform="translate(715.89458,-484.76097)">
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path5521"
d="m -541.16139,1401.9765 -133.15983,-126.4507 c -2.67796,-3.1869 4.36168,-10.2653 7.69711,-8.84 l 42.71889,22.6766 53.49485,37.6661 46.95231,34.207 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.98724842;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path5500"
d="m -550.63035,1394.3425 c 2.30616,13.423 7.07661,27.1453 16.86881,36.8888 14.06473,13.8692 32.5591,22.4132 51.78176,26.3534 10.03569,2.0175 20.53541,-0.2419 30.76131,0.022 26.27854,-1.1777 52.65257,-1.2221 78.8705,-3.1197 14.63631,-1.2671 28.79784,-5.3814 43.02494,-8.6398 13.37018,-5.5166 26.49631,-14.0331 32.57971,-27.6668 4.77003,-9.4263 10.66489,-18.5689 14.7418,-28.17 2.16574,-7.0809 -7.89007,-2.4276 -10.07958,0.7336 -8.05751,8.63 -16.11503,17.26 -24.17255,25.89 -16.06434,-8.8296 -31.45372,-19.0573 -48.95319,-24.9143 -13.03118,-5.448 -27.50414,-5.9791 -41.18036,-9.2276 -13.7795,-2.7366 -27.92117,-4.205 -40.70957,-10.4122 -17.83415,-6.5723 -35.33415,-14.2911 -53.37768,-20.1453 -8.53908,-2.1286 -18.7772,-3.1026 -26.3501,1.651 -7.93527,13.5854 -15.87053,27.1708 -23.8058,40.7562 z"
style="fill:#9ab3d9;fill-opacity:1;stroke:#000000;stroke-width:1.06395769;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="matrix(0.94985292,0.31269703,-0.31269703,0.94985292,397.05926,247.01432)"
inkscape:connector-curvature="0"
inkscape:tile-y0="495.09051"
inkscape:tile-x0="-540.98978"
inkscape:tile-h="46.001777"
inkscape:tile-w="169.04809"
inkscape:tile-cy="535.18738"
inkscape:tile-cx="-541.1986"
id="path7694"
d="m -407.89167,1272.2747 c 5.14001,6.3357 -20.61438,35.9473 -57.52404,66.1395 -36.90965,30.1922 -70.99764,49.5317 -76.13765,43.1961 -5.14002,-6.3357 20.61437,-35.9474 57.52403,-66.1395 36.90966,-30.1922 70.99764,-49.5318 76.13766,-43.1961 z"
inkscape:transform-center-y="-30.293294"
inkscape:transform-center-x="-80.958308"
style="opacity:0.61100003;fill:#cecece;fill-opacity:1;stroke:none;filter:url(#filter8696)" />
<g
style="fill:#ffffff;fill-opacity:1"
transform="matrix(1.0775939,0,0,1.0761756,-480.68834,1077.7838)"
id="g5514">
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 31.892648,275.48747 6.25,-3.57143 5.26786,-2.05357 4.64286,-0.71429 7.85714,0.89286 5.17857,1.25 4.46429,2.14286 4.10714,3.57143 3.30357,2.85714 5.98214,3.21428 6.60715,2.67858 -0.0893,6.51785 c 0,0 -1.16071,3.66072 -1.16071,4.01786 0,0.35714 -1.69643,4.55357 -1.69643,4.55357 l -7.05357,-4.01786 -2.05357,-0.44642 -5,3.92857 -5.44643,1.78571 -5.44643,1.96429 -1.60714,0.17857 -4.375,-7.05357 -3.92858,-5.625 -3.21428,-4.28572 -2.94643,-3.66071 -4.01786,-3.39286 -4.01785,-3.125 z"
id="path5503"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 41.267648,283.79104 14.01786,-13.83929 0,0"
id="path5505"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 43.410508,286.02318 15.17857,-15.26785"
id="path5507"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 56.446218,303.88033 c 0,0 1.875,-22.14286 1.875,-22.58929 0,-0.44643 -0.0893,-7.41071 -0.0893,-7.41071 l 0.17857,-2.67858"
id="path5509"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 74.035508,296.46961 0,-16.25"
id="path5511"
inkscape:connector-curvature="0" />
</g>
<path
transform="matrix(0.79625178,0.45406311,-0.45381717,0.79676123,512.52081,521.26661)"
style="opacity:0.61100003;fill:#cecece;fill-opacity:1;stroke:none;filter:url(#filter8684)"
inkscape:transform-center-x="17.57733"
inkscape:transform-center-y="55.045522"
d="m -512.87163,1507.2802 c -5.80542,1.2629 -16.61393,-25.2242 -24.14142,-59.1607 -7.52755,-33.9364 -8.92364,-62.4711 -3.11834,-63.7341 5.80542,-1.2628 16.61393,25.2243 24.14141,59.1608 7.52756,33.9364 8.92371,62.4711 3.11835,63.734 z"
id="path8280"
inkscape:tile-cx="-541.1986"
inkscape:tile-cy="535.18738"
inkscape:tile-w="169.04809"
inkscape:tile-h="46.001777"
inkscape:tile-x0="-540.98978"
inkscape:tile-y0="495.09051"
inkscape:connector-curvature="0" />
<circle
transform="matrix(1.0775939,0,0,1.0761756,-580.01711,1931.488)"
id="path5523"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.38783747;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="47.098362"
cy="-512.54401"
r="23.359777" />
<path
transform="matrix(1.0155585,0.26208382,-0.26208513,1.0155506,375.59085,113.89354)"
style="opacity:0.61100003;fill:#cecece;fill-opacity:1;stroke:none;filter:url(#filter8708)"
inkscape:transform-center-x="36.497207"
inkscape:transform-center-y="-42.010802"
d="m -627.24914,1324.3778 c 2.81378,-4.1267 24.76631,5.7977 49.03238,22.1666 24.26609,16.3688 41.65657,32.9837 38.84289,37.1104 -2.81386,4.1266 -24.76633,-5.7976 -49.03231,-22.1665 -24.26608,-16.3689 -41.65674,-32.9838 -38.84296,-37.1105 z"
id="path8282"
inkscape:tile-cx="-541.1986"
inkscape:tile-cy="535.18738"
inkscape:tile-w="169.04809"
inkscape:tile-h="46.001777"
inkscape:tile-x0="-540.98978"
inkscape:tile-y0="495.09051"
inkscape:connector-curvature="0" />
<circle
transform="matrix(1.0775939,0,0,1.0761756,-573.75806,1934.4775)"
id="path5525"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.38783747;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="33.966381"
cy="-518.09985"
r="16.28871" />
<ellipse
inkscape:transform-center-y="-17.09598"
inkscape:transform-center-x="-84.732874"
transform="matrix(2.834602,-0.60010423,0.5942,2.8637499,-358.0305,2555.1763)"
id="path5529"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.14347301;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="50.507626"
cy="-406.60425"
rx="29.7995"
ry="5.0507627" />
<ellipse
transform="matrix(-1.1277765,-1.744406,1.752265,-1.1244094,202.6751,961.09238)"
id="path5529-7"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.20083466;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="50.507626"
cy="-406.60425"
rx="29.7995"
ry="5.0507627" />
<ellipse
inkscape:transform-center-y="-0.70656384"
inkscape:transform-center-x="-0.68115835"
transform="matrix(1.1338996,-2.0198832,2.0232381,1.1299859,199.61444,1989.4171)"
id="path5529-4"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.18026559;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="50.507626"
cy="-406.60425"
rx="29.7995"
ry="5.0507627" />
<path
inkscape:connector-curvature="0"
id="path5563"
d="m -312.42545,1421.5179 6.35009,-2.1139 46.9523,26.1357 12.12296,10.5696 -0.96214,1.5374 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.83382982;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path5500-4"
d="m -548.10009,1393.2764 c 2.30616,13.423 7.0766,27.1453 16.86881,36.8889 14.06473,13.8691 32.5591,22.4131 51.78175,26.3533 10.03569,2.0175 20.53542,-0.2418 30.76131,0.022 26.27854,-1.1776 52.65256,-1.2221 78.87053,-3.1197 14.63631,-1.267 28.79784,-5.3814 43.02494,-8.6397 13.37018,-5.5166 26.49631,-14.0332 32.57971,-27.6669 4.77003,-9.4263 10.66489,-18.5689 14.7418,-28.1699 2.16574,-7.081 -7.89007,-2.4277 -10.07958,0.7335 -8.05751,8.63 -16.11503,17.26 -24.17254,25.89 -16.06434,-8.8296 -31.45372,-19.0573 -48.9532,-24.9143 -13.03121,-5.448 -27.50419,-5.9791 -41.18039,-9.2275 -13.7795,-2.7367 -27.92117,-4.205 -40.70957,-10.4122 -17.83415,-6.5724 -35.33415,-14.2912 -53.37768,-20.1453 -8.53908,-2.1287 -18.77719,-3.1027 -26.3501,1.6509 -7.93527,13.5854 -15.87053,27.1708 -23.80579,40.7562 z"
style="opacity:0.49823321;fill:url(#linearGradient9450);fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccsccccccccccc"
inkscape:connector-curvature="0"
id="path5496"
d="m -485.62932,1455.857 4.61826,-6.5339 3.84854,-2.6905 8.08196,-2.3061 8.85168,-3.0748 16.54876,-1.5373 c 0,0 8.08196,1.153 9.62136,1.153 1.53941,0 18.47305,2.6904 18.47305,2.6904 l 21.93676,3.4592 6.92736,3.0748 5.77282,4.6122 -12.70018,3.0747 -5.38798,3.0748 -3.46371,4.2279 -1.92429,2.6904 239.76468,161.042 c 5.82092,4.1638 1.20266,16.4949 -4.61826,14.2209 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.98724842;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g7664"
transform="translate(318.31762,-3.8891046)"
style="opacity:0.858">
<g
transform="matrix(0.95511441,0,0,0.95385727,205.18996,51.838406)"
id="text7238"
style="font-style:normal;font-weight:normal;font-size:110.7744751px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none">
<g
transform="matrix(0.68786515,0,0,0.68786515,161.92514,215.41774)"
id="g7273"
style="">
<path
d="m -154.78125,940.90625 c -16.83367,0.0841 -32.94231,5.79147 -48.3125,12.1875 0,11.85417 0,23.70833 0,35.5625 17.7207,-10.62322 38.58707,-22.68911 59.8125,-16.25 13.04398,5.00743 16.63873,22.94986 8.66918,33.81085 -11.30773,19.951 -29.75582,34.2821 -44.49033,51.4383 -8.37949,9.1645 -18.35443,17.5352 -24.99135,27.8758 0,8.1146 0,16.2292 0,24.3438 35.57292,0 71.14583,0 106.71875,0 0,-9.8542 0,-19.7083 0,-29.5625 -20.85373,-0.1908 -41.71203,0.331 -62.5625,-0.1875 18.72263,-20.4224 40.27979,-39.0816 55.0625,-62.75 11.305666,-20.54355 8.686275,-50.04312 -10.9375,-64.4375 -10.92302,-8.6146 -25.15049,-12.36911 -38.96875,-12.03125 z"
id="path7243"
inkscape:connector-curvature="0"
style="" />
<path
style="font-style:normal;font-weight:normal;font-size:110.7744751px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:none;stroke:#000000;stroke-width:1.16349924;stroke-opacity:1"
d="m -155.61282,936.62569 c -18.35737,0.048 -35.64676,6.5447 -52.28125,13.5 0,15.0834 0,30.1667 0,45.25 18.18309,-10.4957 37.97826,-24.6759 60.0625,-20.0624 13.23334,2.403 16.32048,21.2393 7.9375,30.37501 -14.06333,22.1049 -34.68279,38.4853 -51.72671,58.1017 -6.37015,6.5604 -13.70611,12.9672 -17.27329,21.4607 0,9.448 0,18.8959 0,28.3438 38.23958,0 76.47917,0 114.718752,0 0,-12.5 0,-25 0,-37.5 -19.144232,-0.341 -38.293232,0.1821 -57.437502,-0.125 18.7872,-20.259 41.09596,-38.8741 52.906252,-64.4375 8.900061,-22.73901 2.040917,-52.61991 -19.875002,-65.18751 -10.99187,-6.9728 -24.10026,-10.0645 -37.03125,-9.7188 z"
id="path7243-3"
inkscape:connector-curvature="0" />
</g>
</g>
<g
style="font-style:normal;font-weight:normal;font-size:110.7744751px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none"
id="g12221"
transform="matrix(0.95511441,0,0,0.95385727,308.812,51.838406)">
<g
id="g12223"
transform="matrix(0.68786515,0,0,0.68786515,161.92514,215.41774)"
style="">
<path
inkscape:connector-curvature="0"
id="path12225"
d="m -154.78125,940.90625 c -16.83367,0.0841 -32.94231,5.79147 -48.3125,12.1875 0,11.85417 0,23.70833 0,35.5625 17.7207,-10.62322 38.58707,-22.68911 59.8125,-16.25 13.04398,5.00743 16.63873,22.94986 8.66918,33.81085 -11.30773,19.951 -29.75582,34.2821 -44.49033,51.4383 -8.37949,9.1645 -18.35443,17.5352 -24.99135,27.8758 0,8.1146 0,16.2292 0,24.3438 35.57292,0 71.14583,0 106.71875,0 0,-9.8542 0,-19.7083 0,-29.5625 -20.85373,-0.1908 -41.71203,0.331 -62.5625,-0.1875 18.72263,-20.4224 40.27979,-39.0816 55.0625,-62.75 11.305666,-20.54355 8.686275,-50.04312 -10.9375,-64.4375 -10.92302,-8.6146 -25.15049,-12.36911 -38.96875,-12.03125 z"
style="" />
<path
inkscape:connector-curvature="0"
id="path12227"
d="m -155.61282,936.62569 c -18.35737,0.048 -35.64676,6.5447 -52.28125,13.5 0,15.0834 0,30.1667 0,45.25 18.18309,-10.4957 37.97826,-24.6759 60.0625,-20.0624 13.23334,2.403 16.32048,21.2393 7.9375,30.37501 -14.06333,22.1049 -34.68279,38.4853 -51.72671,58.1017 -6.37015,6.5604 -13.70611,12.9672 -17.27329,21.4607 0,9.448 0,18.8959 0,28.3438 38.23958,0 76.47917,0 114.718752,0 0,-12.5 0,-25 0,-37.5 -19.144232,-0.341 -38.293232,0.1821 -57.437502,-0.125 18.7872,-20.259 41.09596,-38.8741 52.906252,-64.4375 8.900061,-22.73901 2.040917,-52.61991 -19.875002,-65.18751 -10.99187,-6.9728 -24.10026,-10.0645 -37.03125,-9.7188 z"
style="font-style:normal;font-weight:normal;font-size:110.7744751px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:none;stroke:#000000;stroke-width:1.16349924;stroke-opacity:1" />
</g>
</g>
<rect
y="965.94965"
x="302.44888"
height="19.519009"
width="19.544735"
id="rect12229"
style="display:inline;fill:#000000;fill-opacity:1;stroke:none" />
<rect
style="display:inline;fill:none;stroke:#000000;stroke-width:1.11054337;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect12231"
width="24.647095"
height="24.614655"
x="299.89771"
y="963.40186" />
</g>
<rect
y="992.5824"
x="346.09998"
height="54.969776"
width="373.92401"
id="rect9140"
style="fill:#009100;fill-opacity:1;stroke:none" />
<text
sodipodi:linespacing="125%"
id="text8636-8-3-41-8-8-3-1-7-0-2"
y="1221.6985"
x="49.664951"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24.44179535px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none"
xml:space="preserve"
transform="scale(0.99979574,1.0002043)"><tspan
y="1221.6985"
x="49.664951"
id="tspan8638-9-0-6-09-8-3-2-1-3-6"
sodipodi:role="line">Copyright (C) OpenTX www.open-tx.org</tspan></text>
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Vrstva"
style="display:inline"
transform="translate(0,290)">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="rect9140-2-4-2"
d="m 78.807562,150.66824 43.329348,0 10.20977,25.6073 -10.20977,25.6075 -43.329348,0 z"
style="fill:#e5201e;fill-opacity:1;stroke:none" />
<g
transform="matrix(1.1462245,0,0,1.146693,-282.4675,-1143.4763)"
id="g4285">
<path
d="m 322.76938,1149.8874 13.1654,0 0,2.6087 -4.7361,0 0,10.7752 -3.68363,0 0,-10.7752 -4.74567,0 0,-2.6087"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:40px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none"
id="path7326-3-8"
inkscape:connector-curvature="0" />
<path
d="m 345.78969,1156.4405 4.95618,6.8308 -3.83672,0 -3.3392,-4.5719 -3.31049,4.5719 -3.85585,0 4.95617,-6.8308 -4.76482,-6.5531 3.84629,0 3.1287,4.3119 3.11913,-4.3119 3.86542,0 -4.76481,6.5531"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:40px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none"
id="path7328-5-2"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.44830608px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none"
x="320.66251"
y="1147.8616"
id="text7317-6-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7319-0-7"
x="320.66251"
y="1147.8616">OPEN</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.37788773px;line-height:89.99999762%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
x="140.42691"
y="174.21489"
id="text3859-0-1"
sodipodi:linespacing="89.999998%"><tspan
sodipodi:role="line"
id="tspan3861-7-1"
x="140.42691"
y="174.21489">THE ULTIMATE</tspan><tspan
sodipodi:role="line"
x="140.42691"
y="198.85498"
id="tspan4223-9-4">TRANSMITTER</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.75551224px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none"
x="356.35379"
y="194.75381"
id="text3869-7-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3871-2-3"
x="356.35379"
y="194.75381">COMPANION</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View file

@ -82,12 +82,14 @@ void LimitsGroup::updateMinMax(int max)
{
if (spinbox->maximum() == 0) {
spinbox->setMinimum(-max * displayStep);
gvarGroup->setMinimum(-max);
if (value < -max) {
value = -max;
}
}
if (spinbox->minimum() == 0) {
spinbox->setMaximum(max * displayStep);
gvarGroup->setMaximum(max);
if (value > max) {
value = max;
}

View file

@ -199,7 +199,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
}
if (generalSettings.hw_uartMode != UART_MODE_SBUS_TRAINER) {
if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER) {
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
}
ui->trainerMode->setCurrentIndex(model.trainerMode);
@ -400,7 +400,7 @@ void ModulePanel::update()
else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M ||
protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO)
mask |= MASK_RX_NUMBER | MASK_ACCESS;
if ((IS_HORUS(board) || board == Board::BOARD_TARANIS_XLITE) && moduleIdx == 0)
if (moduleIdx == 0 && HAS_EXTERNAL_ANTENNA(board) && generalSettings.antennaMode == 0 /* per model */)
mask |= MASK_ANTENNA;
break;
case PULSES_LP45:
@ -486,16 +486,18 @@ void ModulePanel::update()
ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength));
ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5);
// Antenna selection on Horus and xlite
ui->label_antenna->setVisible(mask & MASK_ANTENNA);
ui->antennaMode->setVisible(mask & MASK_ANTENNA);
if IS_HORUS_X12S(board) {
ui->antennaMode->setItemText(1,tr("Ext. + Int"));
// Antenna mode on Horus and XLite
if (mask & MASK_ANTENNA) {
ui->antennaMode->clear();
ui->antennaMode->addItem(tr("Ask"), -1);
ui->antennaMode->addItem(tr("Internal"), 0);
ui->antennaMode->addItem(IS_HORUS_X12S(board) ? tr("Internal + External") : tr("External"), 1);
ui->antennaMode->setField(module.pxx.antennaMode, this);
}
else {
ui->antennaMode->setItemText(1,tr("External"));
ui->antennaLabel->hide();
ui->antennaMode->hide();
}
ui->antennaMode->setCurrentIndex(module.pxx.external_antenna);
// R9M options
ui->r9mPower->setVisible(mask & MASK_R9M);
@ -642,14 +644,6 @@ void ModulePanel::on_ppmPolarity_currentIndexChanged(int index)
}
}
void ModulePanel::on_antennaMode_currentIndexChanged(int index)
{
if (!lock && module.pxx.external_antenna != (bool)index) {
module.pxx.external_antenna = index;
emit modified();
}
}
void ModulePanel::on_r9mPower_currentIndexChanged(int index)
{
if (!lock && module.pxx.power != (unsigned int)index) {
@ -1387,7 +1381,7 @@ void SetupPanel::updatePotWarnings()
for (int i=0; i<potWarningCheckboxes.size(); i++) {
QCheckBox *checkbox = potWarningCheckboxes[i];
int index = checkbox->property("index").toInt();
checkbox->setChecked(!model->potsWarningEnabled[index]);
checkbox->setChecked(!model->potsWarnEnabled[index]);
checkbox->setDisabled(model->potsWarningMode == 0);
}
lock = false;
@ -1397,7 +1391,7 @@ void SetupPanel::potWarningToggled(bool checked)
{
if (!lock) {
int index = sender()->property("index").toInt();
model->potsWarningEnabled[index] = !checked;
model->potsWarnEnabled[index] = !checked;
updatePotWarnings();
emit modified();
}

View file

@ -80,7 +80,6 @@ class ModulePanel : public ModelPanel
void on_ppmPolarity_currentIndexChanged(int index);
void on_ppmOutputType_currentIndexChanged(int index);
void on_ppmFrameLength_editingFinished();
void on_antennaMode_currentIndexChanged(int index);
void on_rxNumber_editingFinished();
void on_failsafeMode_currentIndexChanged(int value);
void onMultiProtocolChanged(int index);

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1042</width>
<height>375</height>
<width>1075</width>
<height>434</height>
</rect>
</property>
<property name="windowTitle">
@ -252,7 +252,7 @@
<item row="4" column="1">
<layout class="QHBoxLayout" name="rx1Layout">
<property name="spacing">
<number>-1</number>
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
@ -595,7 +595,7 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_antenna">
<widget class="QLabel" name="antennaLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
@ -611,7 +611,7 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="antennaMode">
<widget class="AutoComboBox" name="antennaMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -621,16 +621,6 @@
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Internal</string>
</property>
</item>
<item>
<property name="text">
<string>Ext. + Int.</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
@ -732,6 +722,26 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="registrationIdLabel">
<property name="text">
<string>Registration ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_multiProtocol">
<property name="text">
@ -775,6 +785,50 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="warning_r9mFlex">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>198</red>
<green>17</green>
<blue>36</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>198</red>
<green>17</green>
<blue>36</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>106</red>
<green>104</green>
<blue>100</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>WARNING: Requires non-certified firmware!</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_failsafeMode">
<property name="maximumSize">
@ -883,70 +937,6 @@
</item>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="warning_r9mFlex">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>198</red>
<green>17</green>
<blue>36</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>198</red>
<green>17</green>
<blue>36</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>106</red>
<green>104</green>
<blue>100</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>WARNING: Requires non-certified firmware!</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="registrationIdLabel">
<property name="text">
<string>Registration ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
@ -1069,6 +1059,13 @@ QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; pad
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>AutoComboBox</class>
<extends>QComboBox</extends>
<header>autocombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>protocol</tabstop>
<tabstop>channelsStart</tabstop>

View file

@ -939,7 +939,7 @@ void TelemetryPanel::setup()
ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0);
ui->telemetryProtocol->addItem(tr("FrSky D"), 1);
if (IS_9XRPRO(firmware->getBoard()) ||
(IS_TARANIS(firmware->getBoard()) && generalSettings.hw_uartMode == 2)) {
(IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) {
ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2);
}
ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol);

View file

@ -223,7 +223,6 @@ QString ModelPrinter::printModule(int idx)
if (module.protocol == PULSES_PXX_R9M) {
str << printLabelValue(tr("Sub Type"), module.subTypeToString());
str << printLabelValue(tr("RF Output Power"), module.powerValueToString(firmware));
str << printLabelValue(tr("Telemetry"), printBoolean(module.pxx.sport_out, BOOLEAN_ENABLEDISABLE));
}
}
}
@ -869,7 +868,7 @@ QString ModelPrinter::printPotWarnings()
for (int i=0; i<board.getCapability(Board::Pots)+board.getCapability(Board::Sliders); i++) {
RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
if ((src.isPot(&genAryIdx) && generalSettings.isPotAvailable(genAryIdx)) || (src.isSlider(&genAryIdx) && generalSettings.isSliderAvailable(genAryIdx))) {
if (!model.potsWarningEnabled[i])
if (!model.potsWarnEnabled[i])
str += src.toString(&model, &generalSettings);
}
}

View file

@ -722,20 +722,22 @@ void TreeModel::refresh()
}
int protocol;
QString rxs;
for (unsigned j=0; j<CPN_MAX_MODULES; j++) {
protocol = model.moduleData[j].protocol;
unsigned moduleIdx = 0;
for (auto const& moduleData: model.moduleData) {
protocol = moduleData.protocol;
// These are the only RXs that allow nominating RX # but changing RX or copying models can leave residual configuration which can cause issues
// if (protocol == PULSES_PXX_XJT_X16 || protocol == PULSES_PXX_XJT_LR12 || protocol == PULSES_PXX_R9M || protocol == PULSES_DSMX || protocol == PULSES_MULTIMODULE) {
if (protocol != PULSES_OFF && model.moduleData[j].modelId > 0) {
if (protocol != PULSES_OFF && moduleData.modelId > 0) {
if (!rxs.isEmpty()) {
rxs.append(", ");
}
unsigned mdlidx = model.moduleData[j].modelId;
unsigned mdlidx = moduleData.modelId;
rxs.append(QString("%1").arg(uint(mdlidx), 2, 10, QChar('0')));
if (!isModelIdUnique(mdlidx)) {
if (!isModelIdUnique(mdlidx, moduleIdx, protocol)) {
current->setHighlightRX(true);
}
}
moduleIdx++;
}
current->setData(currentColumn++, rxs);
}
@ -746,20 +748,18 @@ void TreeModel::refresh()
}
}
bool TreeModel::isModelIdUnique(unsigned modelIdx)
bool TreeModel::isModelIdUnique(unsigned modelIdx, unsigned module, unsigned protocol)
{
int cnt = 0;
for (unsigned i=0; i<radioData->models.size(); i++) {
ModelData & model = radioData->models[i];
for (auto const& model: radioData->models) {
if (!model.isEmpty()) {
for (unsigned j=0; j<CPN_MAX_MODULES; j++) {
if (model.moduleData[j].protocol != PULSES_OFF && model.moduleData[j].modelId == modelIdx) {
const ModuleData& moduleData = model.moduleData[module];
if (moduleData.protocol == protocol && moduleData.modelId == modelIdx) {
if (++cnt > 1) {
return false;
}
}
}
}
}
return true;
}

View file

@ -149,7 +149,7 @@ class TreeModel : public QAbstractItemModel
private:
TreeItem * getItem(const QModelIndex & index) const;
bool isModelIdUnique(unsigned modelId);
bool isModelIdUnique(unsigned modelId, unsigned module, unsigned protocol);
TreeItem * rootItem;
RadioData * radioData;

View file

@ -55,7 +55,7 @@ QStringList getAvrdudeArgs(const QString & cmd, const QString & filename)
args << "-c" << programmer << "-p";
if (IS_2560(board))
args << "m2560";
else if (board == Board::BOARD_M128)
else if (board == Board::BOARD_9X_M128)
args << "m128";
else
args << mcu;

View file

@ -29,12 +29,8 @@ class AutoComboBox: public QComboBox
Q_OBJECT
public:
explicit AutoComboBox(QWidget *parent = 0):
QComboBox(parent),
field(NULL),
panel(NULL),
next(0),
lock(false)
explicit AutoComboBox(QWidget *parent = nullptr):
QComboBox(parent)
{
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
}
@ -67,14 +63,14 @@ class AutoComboBox: public QComboBox
updateValue();
}
void setField(unsigned int & field, GenericPanel * panel=NULL)
void setField(unsigned int & field, GenericPanel * panel=nullptr)
{
this->field = (int *)&field;
this->panel = panel;
updateValue();
}
void setField(int & field, GenericPanel * panel=NULL)
void setField(int & field, GenericPanel * panel=nullptr)
{
this->field = &field;
this->panel = panel;
@ -113,10 +109,10 @@ class AutoComboBox: public QComboBox
}
protected:
int * field;
GenericPanel * panel;
int next;
bool lock;
int * field = nullptr;
GenericPanel * panel = nullptr;
int next = 0;
bool lock = false;
};
#endif // _AUTOCOMBOBOX_H_

View file

@ -223,7 +223,7 @@ void RadioOutputsWidget::setupGVarsDisplay()
QPalette::ColorRole bgrole = QPalette::AlternateBase;
for (int fm=0; fm < fmodes; fm++) {
QLabel * label = new QLabel(gvarsWidget);
label->setText(QString("FM%1").arg(fm));
label->setText(QString(tr("FM%1")).arg(fm));
label->setAlignment(Qt::AlignCenter);
label->setBackgroundRole(bgrole);
gvarsLayout->addWidget(label, 0, fm+1);
@ -232,7 +232,7 @@ void RadioOutputsWidget::setupGVarsDisplay()
for (int gv=0; gv < gvars; gv++) {
bgrole = ((gv % 2) ? QPalette::Background : QPalette::AlternateBase);
QLabel * label = new QLabel(gvarsWidget);
label->setText(QString("GV%1").arg(gv+1));
label->setText(QString(tr("GV%1")).arg(gv+1));
label->setAutoFillBackground(true);
label->setBackgroundRole(bgrole);
gvarsLayout->addWidget(label, gv+1, 0);

View file

@ -97,7 +97,6 @@ class SimulatedUIWidget : public QWidget
unsigned int m_backLight;
int m_beepShow;
int m_beepVal;
};

View file

@ -153,19 +153,12 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwa
SimulatorMainWindow::~SimulatorMainWindow()
{
if (m_telemetryDockWidget)
delete m_telemetryDockWidget;
if (m_trainerDockWidget)
delete m_trainerDockWidget;
if (m_outputsDockWidget)
delete m_outputsDockWidget;
if (m_simulatorDockWidget)
delete m_simulatorDockWidget;
else if (m_simulatorWidget)
delete m_simulatorWidget;
if (m_consoleDockWidget)
delete m_consoleDockWidget;
delete ui;
if (m_simulator) {
@ -293,7 +286,7 @@ void SimulatorMainWindow::createDockWidgets()
if (!m_telemetryDockWidget) {
SimulatorIcon icon("telemetry");
m_telemetryDockWidget = new QDockWidget(tr("Telemetry Simulator"), this);
TelemetrySimulator * telem = new TelemetrySimulator(this, m_simulator);
auto * telem = new TelemetrySimulator(this, m_simulator);
m_telemetryDockWidget->setWidget(telem);
m_telemetryDockWidget->setObjectName("TELEMETRY_SIMULATOR");
addTool(m_telemetryDockWidget, Qt::LeftDockWidgetArea, icon, QKeySequence(tr("F4")));
@ -302,7 +295,7 @@ void SimulatorMainWindow::createDockWidgets()
if (!m_trainerDockWidget) {
SimulatorIcon icon("trainer");
m_trainerDockWidget = new QDockWidget(tr("Trainer Simulator"), this);
TrainerSimulator * trainer = new TrainerSimulator(this, m_simulator);
auto * trainer = new TrainerSimulator(this, m_simulator);
m_trainerDockWidget->setWidget(trainer);
m_trainerDockWidget->setObjectName("TRAINER_SIMULATOR");
addTool(m_trainerDockWidget, Qt::TopDockWidgetArea, icon, QKeySequence(tr("F5")));

View file

@ -50,17 +50,8 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
simulator(simulator),
firmware(getCurrentFirmware()),
radioSettings(GeneralSettings()),
radioUiWidget(NULL),
vJoyLeft(NULL),
vJoyRight(NULL),
m_board(getCurrentBoard()),
flags(flags),
startupFromFile(false),
deleteTempRadioData(false),
saveTempRadioData(false)
#ifdef JOYSTICKS
, joystick(NULL)
#endif
flags(flags)
{
ui->setupUi(this);
@ -86,7 +77,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
case Board::BOARD_TARANIS_X9E:
radioUiWidget = new SimulatedUIWidgetX9E(simulator, this);
break;
case Board::BOARD_X12S:
case Board::BOARD_HORUS_X12S:
radioUiWidget = new SimulatedUIWidgetX12(simulator, this);
break;
case Board::BOARD_X10:
@ -154,21 +145,16 @@ SimulatorWidget::~SimulatorWidget()
{
shutdown();
if (radioUiWidget)
delete radioUiWidget;
if (vJoyLeft)
delete vJoyLeft;
if (vJoyRight)
delete vJoyRight;
#ifdef JOYSTICKS
if (joystick)
delete joystick;
#endif
firmware = NULL;
firmware = nullptr;
delete ui;
}
/*
* Public slots/setters
*/
@ -570,7 +556,7 @@ void SimulatorWidget::setupRadioWidgets()
continue;
swcfg = Board::SwitchType(radioSettings.switchConfig[i]);
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(NULL, &radioSettings);
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(nullptr, &radioSettings);
RadioSwitchWidget * sw = new RadioSwitchWidget(swcfg, wname, -1, ui->radioWidgetsHT);
sw->setIndex(i);
ui->radioWidgetsHTLayout->addWidget(sw);
@ -585,7 +571,7 @@ void SimulatorWidget::setupRadioWidgets()
if (!radioSettings.isPotAvailable(i))
continue;
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + i).toString(NULL, &radioSettings);
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + i).toString(nullptr, &radioSettings);
RadioKnobWidget * pot = new RadioKnobWidget(Board::PotType(radioSettings.potConfig[i]), wname, 0, ui->radioWidgetsHT);
pot->setIndex(i);
ui->radioWidgetsHTLayout->insertWidget(midpos++, pot);
@ -599,7 +585,7 @@ void SimulatorWidget::setupRadioWidgets()
if (!radioSettings.isSliderAvailable(i))
continue;
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + ttlKnobs + i).toString(NULL, &radioSettings);
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + ttlKnobs + i).toString(nullptr, &radioSettings);
RadioFaderWidget * sl = new RadioFaderWidget(wname, 0, ui->radioWidgetsVC);
sl->setIndex(i);
ui->VCGridLayout->addWidget(sl, 0, c++, 1, 1);
@ -613,7 +599,7 @@ void SimulatorWidget::setupRadioWidgets()
for (i = extraTrims; i > 0; --i) {
trswidx -= 2;
--tridx;
wname = RawSource(RawSourceType::SOURCE_TYPE_TRIM, tridx).toString(NULL, &radioSettings);
wname = RawSource(RawSourceType::SOURCE_TYPE_TRIM, tridx).toString(nullptr, &radioSettings);
wname = wname.left(1) % wname.right(1);
RadioTrimWidget * tw = new RadioTrimWidget(Qt::Vertical, ui->radioWidgetsVC);
tw->setIndices(tridx, trswidx, trswidx + 1);
@ -672,7 +658,7 @@ void SimulatorWidget::setupJoysticks()
if (vJoyRight)
disconnect(this, 0, vJoyRight, 0);
joystick->deleteLater();
joystick = NULL;
joystick = nullptr;
}
if (vJoyRight)
vJoyRight->setStickConstraint((VirtualJoystickWidget::HOLD_X | VirtualJoystickWidget::HOLD_Y), joysticksEnabled);

View file

@ -33,8 +33,6 @@
#include <QWidget>
#include <QVector>
void traceCb(const char * text);
class Firmware;
class SimulatorInterface;
class SimulatedUIWidget;
@ -130,9 +128,9 @@ class SimulatorWidget : public QWidget
QVector<Simulator::keymapHelp_t> keymapHelp;
QElapsedTimer m_heartbeatTimer;
SimulatedUIWidget * radioUiWidget;
VirtualJoystickWidget * vJoyLeft;
VirtualJoystickWidget * vJoyRight;
SimulatedUIWidget * radioUiWidget = nullptr;
VirtualJoystickWidget * vJoyLeft = nullptr;
VirtualJoystickWidget * vJoyRight = nullptr;
QVector<RadioWidget *> m_radioWidgets;
QString sdCardPath;
@ -141,14 +139,13 @@ class SimulatorWidget : public QWidget
Board::Type m_board;
quint8 flags;
int radioProfileId;
bool startupFromFile;
bool deleteTempRadioData;
bool saveTempRadioData;
bool startupFromFile = false;
bool deleteTempRadioData = false;
bool saveTempRadioData = false;
#ifdef JOYSTICKS
Joystick *joystick;
Joystick * joystick = nullptr;
#endif
};
#endif // _SIMULATORWIDGET_H_

View file

@ -86,7 +86,7 @@ void RleFile::EeFsCreate(uint8_t *eeprom, int size, Board::Type board, unsigned
}
else {
eeFs = (EeFs *)eeprom;
eeFsVersion = (IS_2560(board) || board==Board::BOARD_M128) ? 5 : 4;
eeFsVersion = (IS_2560(board) || board==Board::BOARD_9X_M128) ? 5 : 4;
eeFsBlockSize = 16;
eeFsLinkSize = 1;

View file

@ -1,7 +1,4 @@
set(GTEST_ROOT /usr CACHE STRING "Base path to Google Test headers and source.")
find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').")
find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.")
if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND)
add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc )

View file

@ -12,8 +12,6 @@ TEST(Conversions, ConversionX9DPFrom22)
ASSERT_EQ(true, store.load(radioData));
ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
@ -28,6 +26,12 @@ TEST(Conversions, ConversionX9DPFrom22)
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(CurveReference::CURVE_REF_CUSTOM, model.expoData[0].curve.type);
EXPECT_EQ(1, model.expoData[0].curve.value);
EXPECT_EQ(CurveReference::CURVE_REF_EXPO, model.expoData[1].curve.type);
EXPECT_EQ(20, model.expoData[1].curve.value);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name);
@ -42,6 +46,60 @@ TEST(Conversions, ConversionX9DPFrom22)
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model.logicalSw[0].val1);
}
TEST(Conversions, ConversionX9DPFrom23)
{
RadioData radioData;
Storage store = Storage(RADIO_TESTS_PATH "/eeprom_23_x9d+.bin");
ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(20, settings.speakerVolume);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
const ModelData & model1 = radioData.models[0];
EXPECT_STREQ("Test", model1.name);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH, SWITCH_SA0), model1.timers[0].mode);
EXPECT_EQ(80, model1.mixData[0].weight);
EXPECT_EQ(900, model1.limitData[0].max); // -100
EXPECT_EQ(80, model1.expoData[0].weight);
// EXPECT_EQ(HELI_SWASH_TYPE_120X, model1.swashRingData.type);
EXPECT_EQ(10, model1.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model1.gvarData[0].name);
EXPECT_EQ(PULSES_ACCST_ISRM_D16, model1.moduleData[0].protocol);
EXPECT_EQ(PULSES_PXX_R9M, model1.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_FCC, model1.moduleData[1].subType);
EXPECT_STREQ("Rud", model1.inputNames[0]);
EXPECT_STREQ("Tes", model1.sensorData[0].label);
EXPECT_EQ(10, model1.sensorData[0].id);
EXPECT_EQ(10, model1.sensorData[0].instance);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model1.logicalSw[0].val1);
const ModelData & model2 = radioData.models[1];
EXPECT_STREQ("Test", model2.name);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH, SWITCH_SA0), model2.timers[0].mode);
EXPECT_EQ(80, model2.mixData[0].weight);
EXPECT_EQ(900, model2.limitData[0].max); // -100
EXPECT_EQ(80, model2.expoData[0].weight);
// EXPECT_EQ(HELI_SWASH_TYPE_120X, model2.swashRingData.type);
EXPECT_EQ(10, model2.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model2.gvarData[0].name);
EXPECT_EQ(PULSES_ACCESS_ISRM, model2.moduleData[0].protocol);
EXPECT_EQ(0, model2.moduleData[0].subType);
EXPECT_EQ(PULSES_PXX_R9M, model2.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_FCC, model2.moduleData[1].subType);
EXPECT_STREQ("Rud", model2.inputNames[0]);
EXPECT_STREQ("Tes", model2.sensorData[0].label);
EXPECT_EQ(10, model2.sensorData[0].id);
EXPECT_EQ(10, model2.sensorData[0].instance);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model2.logicalSw[0].val1);
}
TEST(Conversions, ConversionX7From22)
{
RadioData radioData;
@ -90,6 +148,48 @@ TEST(Conversions, ConversionX7From22)
EXPECT_EQ(RawSource(SOURCE_TYPE_SPECIAL,4), screen.body.lines[0].source[1]);
}
TEST(Conversions, ConversionXLiteFrom22)
{
RadioData radioData;
Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_xlite.bin");
ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
const ModelData& model = radioData.models[0];
EXPECT_STREQ("Test", model.name);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[4].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[4].swtch);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Thr", model.inputNames[0]);
EXPECT_STREQ("Tes", model.sensorData[0].label);
EXPECT_EQ(10, model.sensorData[0].id);
EXPECT_EQ(8, model.sensorData[0].instance);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1);
EXPECT_EQ(0, model.logicalSw[0].val2);
const FrSkyScreenData& screen = model.frsky.screens[0];
EXPECT_EQ(TELEMETRY_SCREEN_NUMBERS, screen.type);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), screen.body.lines[0].source[0]);
EXPECT_EQ(RawSource(SOURCE_TYPE_SPECIAL,4), screen.body.lines[0].source[1]);
}
bool loadFile(QByteArray & filedata, const QString & filename)
{
@ -178,6 +278,83 @@ TEST(Conversions, ConversionX10From22)
EXPECT_STREQ("Tes", model.flightModeData[0].name);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name);
EXPECT_EQ(PULSES_PXX_XJT_D8, model.moduleData[0].protocol);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_STREQ("Rud", model.inputNames[0]);
EXPECT_STREQ("Tes", model.sensorData[0].label);
EXPECT_EQ(10, model.sensorData[0].id);
EXPECT_EQ(9, model.sensorData[0].instance);
EXPECT_EQ(5 + 2 + 3, model.thrTraceSrc); // CH3
}
TEST(Conversions, ConversionX12SFrom22)
{
QByteArray byteBuffer;
#define USE_OTX
#if defined(USE_OTX)
OtxFormat otx(RADIO_TESTS_PATH "/model_22_x12s.otx");
RadioData radio;
EXPECT_EQ(true, otx.load(radio));
const GeneralSettings& settings = radio.generalSettings;
const ModelData& model = radio.models[0];
#else
ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x12s/RADIO/radio.bin"));
GeneralSettings settings;
EXPECT_NE(nullptr, loadRadioSettingsFromByteArray(settings, byteBuffer));
#endif
EXPECT_EQ(-30, settings.vBatMin);
EXPECT_EQ(20, settings.speakerVolume);
EXPECT_STREQ("en", settings.ttsLanguage);
EXPECT_STREQ("model1.bin", settings.currModelFilename);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch);
EXPECT_EQ(FuncVolume, settings.customFn[1].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
EXPECT_STREQ("BT", settings.bluetoothName);
EXPECT_STREQ("Default", settings.themeName);
#if !defined(USE_OTX)
byteBuffer.clear();
ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x10/MODELS/model1.bin"));
ModelData model;
ASSERT_NE(nullptr, loadModelFromByteArray(model, byteBuffer));
#endif
EXPECT_STREQ("Test", model.name);
EXPECT_EQ(0, model.noGlobalFunctions);
EXPECT_EQ(0, model.beepANACenter);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM, 0), model.mixData[5].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[5].swtch);
EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); // TR1
EXPECT_EQ(0, model.logicalSw[0].val2);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY, 19*3).toValue(), model.logicalSw[1].val1); // TELE:20
EXPECT_EQ(20, model.logicalSw[1].val2);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1).toValue(), model.logicalSw[1].andsw);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Test", model.flightModeData[0].name);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name);
EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_STREQ("Rud", model.inputNames[0]);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -48,6 +48,7 @@
class AppMessages
{
Q_DECLARE_TR_FUNCTIONS("AppMessages")
public:
// These are used for saving "[don't] show this message again" user preferences.
enum MessageCodes {

Binary file not shown.

View file

@ -320,7 +320,7 @@ local function fieldCommandLoad(field, data, offset)
field.status = data[offset]
field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then
if field.status == 0 then
fieldPopup = nil
end
end
@ -406,8 +406,7 @@ local function refreshNext()
local time = getTime()
if fieldPopup then
if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id }
crossfireTelemetryPush(0x2D, frame)
crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
fieldTimeout = time + fieldPopup.timeout
end
elseif time > fieldTimeout and not edit then
@ -435,7 +434,7 @@ local function runDevicePage(event)
else
return "crossfire.lua"
end
elseif event == EVT_VIRTUAL_EXIT then -- toggle editing/selecting current field
elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field
local field = getField(lineIndex)
if field.name then
if field.type == 10 then

View file

@ -0,0 +1,515 @@
---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
local version = "v1.1"
local VALUE = 0
local COMBO = 1
local FLPOI = 2
local edit = false
local page = 1
local current = 1 --row
local refreshState = 0
local refreshIndex = 0
local refreshIndex3 = 0
local pageOffset = 0
local pages = {}
local fields = {}
local modifications = {}
local thistime = getTime()
local lastTime = thistime
local margin = 1
local spacing = 8
local configFields = {}
local counter = 0
local appId = 0
local function drawScreenTitle(title,page, pages)
if math.fmod(math.floor(getTime()/100),10) == 0 then
title = version
end
if LCD_W == 480 then
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
lcd.drawText(LCD_W-40, 5, page.."/"..pages, MENU_TITLE_COLOR)
else
lcd.drawScreenTitle(title, page, pages)
end
end
local interfaceconfig = {
{"Sensor group select", VALUE, appId, nil, 0, 15},
}
local settingsFields = {
{"Software version", FLPOT, 0x0c, nil, 1, 100 },
{"Physical ID", VALUE, 0x01, nil, 0, 26 },
{"Application IDgroup", VALUE, 0x0D, nil, 0, 15 },
{"Data rate(*100ms)", VALUE, 0x22, nil, 1, 255 },
}
local telemetryFields = {
{"TEMP1(C/F)", VALUE, 0x90, nil, -30, 600},
{"TEMP2(C/F)", VALUE, 0x91, nil, -30, 600},
{"SPEED(r/min)", VALUE, 0x92, nil, 0, 100000},
{"Residual Volume(mL)", VALUE, 0x93, nil, 0, 60000},
{"Residual Percent(%)", VALUE, 0x94, nil, 0, 100},
{"FLOW(mL/min)", VALUE, 0x95, nil, 0, 2000},
{"Max Flow(mL/min)", VALUE, 0x96, nil, 0, 2000},
{"Avg Flow(mL/min)", VALUE, 0x97, nil, 0, 2000},
}
-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if field[2] ~= FLPOT then --only read ?
if field[2] == VALUE and field[6] > 256 then
if field[4] > 1000 then
step = step * 50
field[4] = math.floor(field[4]/50)
field[4] = field[4] *50
elseif field[4] > 500 then
step = step * 20
field[4] = math.floor(field[4]/20)
field[4] = field[4] *20
elseif field[4] > 200 then
step = step * 10
field[4] = math.floor(field[4]/10)
field[4] = field[4] *10
else
step = step * 1
field[4] = math.floor(field[4]/1)
field[4] = field[4] *1
end
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
else
field[4] = field[4]
end
end
-- Select the next or previous page
local function selectPage(step)
page = 1 + ((page + step - 1 + #pages) % #pages)
refreshIndex = 0
pageOffset = 0
end
-- Select the next or previous editable field
local function selectField(step)
current = current + step
if current > #fields then
current = #fields
elseif current < 1 then
current = 1
end
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end
local function drawProgressBar()
if LCD_W == 480 then
local width = (300 * refreshIndex) / #fields
lcd.drawRectangle(100, 10, 300, 6)
lcd.drawFilledRectangle(102, 13, width, 2);
else
local width = (60 * refreshIndex) / #fields
lcd.drawRectangle(45, 1, 60, 6)
lcd.drawFilledRectangle(47, 3, width, 2);
end
end
-- Redraw the current page
local function redrawFieldsPage()
lcd.clear()
drawScreenTitle("GasSuit", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 7, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end
local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(1, margin+ spacing * index, field[1])
if field[4] == nil then
lcd.drawText(LCD_W, margin+ spacing * index, "---", attr + RIGHT)
else
if field[2] == VALUE then
if (field[3] == 0x90 or field[3] == 0x91) and field[4] == 500 then
lcd.drawText(LCD_W, margin+ spacing * index, "---", attr + RIGHT)
else
lcd.drawNumber(LCD_W, margin+ spacing * index, field[4] , attr + RIGHT)
end
elseif field[2] == COMBO then
if field[4] >= 0 and field[4] < #(field[5]) then
lcd.drawText(LCD_W, margin+ spacing * index, field[5][1+field[4]], attr + RIGHT)
end
elseif field[2] == FLPOT then
lcd.drawText(LCD_W, margin+ spacing * index, field[4], attr + RIGHT)
end
end
end
end
local function telemetryRead(fieldx)
return sportTelemetryPush(0x1b, 0x30, appId, fieldx)
end
local function telemetryListen(fieldx)
return sportTelemetryPush(0x1b, 0, 0, 0)
end
local function telemetryWrite(fieldx, valuex)
return sportTelemetryPush(0x1b, 0x31, appId, fieldx + valuex*256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 and page ~= 3 then --
if #modifications > 0 then --
if modifications[1][1] ~= 0x0c then
if modifications[1][1] == 0x22 then
modifications[1][2] = modifications[1][2] + 0xf00
end
local modificationstmp = modifications[1][2]
if modifications[1][1] == 0x8a or modifications[1][1] == 0x8b then
if configFields[11][4]== 1 then
modificationstmp = (modifications[1][2] - 32)*10
modificationstmp = math.floor(modificationstmp/18)
end
end
telemetryWrite(modifications[1][1], modificationstmp)
refreshIndex = 0
end
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80
end
end
elseif refreshState == 0 and page == 3 then
if #modifications > 0 then
if modifications[1][1] == 0x96 or modifications[1][1] == 0x97 or modifications[1][1] == 0x93 then
telemetryWrite(modifications[1][1], 0)
end
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 20
end
elseif refreshIndex >= #fields then
refreshIndex = 0
refreshState = 0
end
elseif refreshState == 1 and page ~= 3 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if primId == 0x32 and dataId >= 0x0d00 and dataId <= 0x0d7f then
local fieldId = value % 256
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[2] == COMBO then
for index = 1, #(field[6]), 1 do
if value == field[6][index] then
value = index - 1
break
end
end
elseif field[2] == VALUE then
value = value -- - field[8] + field[5]
end
if field[1] == "Software version" then
local flo_string = string.char(value/16%16 + 48).."."..string.char(value%16 + 48)
fields[refreshIndex + 1][4] = flo_string
else
fields[refreshIndex + 1][4] = value
end
refreshIndex = refreshIndex + 1
refreshState = 0
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
end
elseif refreshState == 1 and page == 3 then
local pageID3 = 0
local physicalId3, primId3, dataId3, value3 = sportTelemetryPop()
if value3 ~= nil then
pageID3 = value3 % 256
value3 = math.floor(value3 / 0x100)
end
if primId3 == 0x32 and value3 ~= nil then
if pageID3 == fields[refreshIndex + 1][3] then
local field = fields[refreshIndex + 1]
if field[2] == COMBO and #field == 6 then
for index = 1, #(field[6]), 1 do
if value3 == field[6][index] then
value3 = index - 1
break
end
end
elseif field[2] == VALUE then
if field[3] == 0x90 or field[3] == 0x91 then
value3 = math.floor(value3 % 0x10000)
if value3 > 0xf000 then
value3 = value3 - 0x10000
end
if configFields[11][4]== 1 and (field[3] == 0x90 or field[3] == 0x91) then
value3 =(value3*18)
value3 = math.floor(value3/10)+32
end
else
value3 = value3
end
end
fields[refreshIndex + 1][4] = value3
refreshIndex = refreshIndex + 1
refreshState = 0
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == COMBO and #field == 6 then
value = field[6][1+value]
elseif field[2] == VALUE and #field == 6 then
value = value -- + field[8] - field[5]
elseif field[2] == FLPOT then
value = 0
end
modifications[#modifications+1] = {field[3], value}
end
-- Main1
local function runFieldsPage(event)
if event == EVT_VIRTUAL_EXIT then
return 2
elseif event == EVT_VIRTUAL_ENTER then
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then
addField(1)
elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then
addField(-1)
end
else
if event == EVT_VIRTUAL_NEXT then
selectField(1)
elseif event == EVT_VIRTUAL_PREVIOUS then
selectField(-1)
end
end
redrawFieldsPage()
return 0
end
local function runConfigPage(event)
fields = configFields
local result = runFieldsPage(event)
return result
end
local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end
local function runTelemetryPage(event)
fields = telemetryFields
return runFieldsPage(event)
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
if LCD_W == 480 then
margin = 10
spacing = 20
end
if LCD_W == 128 then
configFields = {
{"CDI off speed limit", VALUE, 0x81, nil, 10,10000}, -- 1
{"Milliliter per pulse", VALUE, 0x80, nil, 1, 2000}, -- 2
{"Volume", VALUE, 0x83, nil, 10,60000}, -- 3
-- {"Flow trigger", VALUE, 0x84, nil, 5, 50 },
-- {"Flow Reset", COMBO, 0x85, nil, { "ON", "OFF" }, {1 , 0}},
{"Auto Reset", COMBO, 0x8d, nil, { "ON", "OFF" }, {0 , 1}}, -- 4
{"Reset settings", COMBO, 0x86, nil,{ "YES", "NO" }, {1 , 0} }, -- 5
{"Volume alarm(%)", VALUE, 0x87, nil, 0, 90 }, -- 6
{"Max.Flow alarm", VALUE, 0x88, nil, 0, 2000 }, -- 7
{"Over speed alarm", VALUE, 0x89, nil, 0, 10000 }, -- 8
{"Over temp1 alarm", VALUE, 0x8a, nil, 0, 600 }, -- 9
{"Over temp2 alarm", VALUE, 0x8b, nil, 0, 600 }, -- 10
{"Temperature C/F", COMBO, 0x8c, nil,{ "C", "F" }, {0 , 1} }, -- 11
}
else
configFields = {
{"CDI off speed limit(*100RPM)", VALUE, 0x81, nil, 10,10000},
{"Milliliter per pulse(*0.001mL/pul)", VALUE, 0x80, nil, 1, 2000},
{"Volume(mL)", VALUE, 0x83, nil, 10,60000},
-- {"Flow trigger(mL/min)", VALUE, 0x84, nil, 5, 50 },
-- {"Flow Reset", COMBO, 0x85, nil, { "ON", "OFF" }, {1 , 0}},
{"Auto Reset", COMBO, 0x8d, nil, { "ON", "OFF" }, {0 , 1}},
{"Reset to factory settings", COMBO, 0x86, nil,{ "YES", "NO" }, {1 , 0} },
{"Volume alarm(%)", VALUE, 0x87, nil, 0, 90 },
{"Max.Flow alarm(mL/min)", VALUE, 0x88, nil, 0, 2000 },
{"Over speed alarm(*100RPM)", VALUE, 0x89, nil, 0, 10000 },
{"Over temperature1 alarm(C/F)", VALUE, 0x8a, nil, 0, 600 },
{"Over temperature2 alarm(C/F)", VALUE, 0x8b, nil, 0, 600 },
{"Temperature Celsius/Fahrenheit", COMBO, 0x8c, nil,{ "C", "F" }, {0 , 1} },
}
end
pages = {
runConfigPage,
runSettingsPage,
runTelemetryPage,
}
-- Warning : GaSuite tool requires Temp2 to be connected and discovered for script to work
for index = 1, 40, 1 do
local sensor = model.getSensor(index)
if sensor ~= nil and sensor.id >= 0x0d10 and sensor.id <= 0x0d1f then
appId = sensor.id
break
end
end
if appId == 0 then
error("No GasSuit sensor in this model!")
end
end
local function background()
local tonefrq,tonelength,tonepause
thistime = getTime()
lastTime = thistime
refreshNext()
if page == 3 then --alarm
local alarmnum = 0
if fields[3][4] ~= nil and configFields[9][4] ~= nil then
local speedtest = fields[3][4]
local speedover = configFields[9][4]*100
if speedtest >= speedover then
tonefrq = 800 + math.max(0,math.floor((speedtest - speedover)/10))
tonelength = 50 + math.max(0,(150 - math.floor((speedtest - speedover)/10)))
tonepause = tonelength
playTone(tonefrq, tonelength, tonepause, PLAY_BACKGROUND,10)
alarmnum = alarmnum + 1
end
end
if fields[5][4] ~= nil and configFields[7][4] ~= nil then
local Residualtest = fields[5][4]
local Residualline = configFields[6][4]
if Residualtest < Residualline then
tonefrq = 400
tonelength = 100
tonepause = 1000 + math.floor( Residualline - Residualtest )*30
playTone(tonefrq, tonelength, tonepause, PLAY_BACKGROUND,10)
alarmnum = alarmnum + 1
end
end
if fields[6][4] ~= nil and configFields[8][4] ~= nil then
local Flowtest = fields[6][4]
local Flowover = configFields[7][4]
if Flowtest > Flowover then
tonefrq = 400
tonelength = 100
tonepause = 200
playTone(tonefrq, tonelength, tonepause, PLAY_BACKGROUND,10)
alarmnum = alarmnum + 1
end
end
if fields[1][4] ~= nil and configFields[10][4] ~= nil then
local temp1test = fields[1][4] --
local temp1over = configFields[9][4]
if temp1test > temp1over and (temp1test ~= 500 and temp1test ~= 932) then
tonefrq = 2000
tonelength = 100
tonepause = 900
playTone(tonefrq, tonelength, tonepause, PLAY_BACKGROUND,10)
alarmnum = alarmnum + 1
end
end
if fields[2][4] ~= nil and configFields[11][4] ~= nil then
local temp2test = fields[2][4]
local temp2over = configFields[10][4]
if temp2test > temp2over and (temp2test ~= 500 and temp2test ~= 932) then
tonefrq = 2000
tonelength = 300
tonepause = 700
playTone(tonefrq, tonelength, tonepause, PLAY_BACKGROUND,10)
alarmnum = alarmnum + 1
end
end
if alarmnum > 1 then
playTone(2000, 100, 100, PLAY_BACKGROUND,10)
end
alarmnum = 0
end
end
local function run(event)
if event == nil then
error("Cannot be run as a sensor script!")
return 2
elseif event == EVT_VIRTUAL_NEXT_PAGE then
selectPage(1)
elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then
killEvents(event);
selectPage(-1)
end
local result = pages[page](event)
if page ~= 3 then
refreshNext()
end
background()
return result
end
return { init=init, background=background, run=run }

View file

@ -0,0 +1,289 @@
---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
local version = "v1.2"
local VALUE = 0
local COMBO = 1
local edit = false
local page = 1
local current = 1 --row
local refreshState = 0
local refreshIndex = 0
local pageOffset = 0
local pages = {}
local fields = {}
local modifications = {}
local margin = 1
local spacing = 8
local appId = 0
local function drawScreenTitle(title,page, pages)
if math.fmod(math.floor(getTime()/100),10) == 0 then
title = version
end
if LCD_W == 480 then
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
lcd.drawText(LCD_W-40, 5, page.."/"..pages, MENU_TITLE_COLOR)
else
lcd.drawScreenTitle(title, page, pages)
end
end
local settingsFields = {
{"SBEC OUTPUT (V)", VALUE, 0x80, nil, 50, 84 },
{"Physical ID", VALUE, 0x01, nil, 0, 26 },
{"Application IDgroup", VALUE, 0x0D, nil, 0, 15 },
{"Data rate(*100ms)", VALUE, 0x22, nil, 1, 255 },
}
-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if field[2] ~= FLPOT then --only read ?
if field[2] == VALUE and field[6] > 256 then
if field[4] > 1000 then
step = step * 50
field[4] = math.floor(field[4]/50)
field[4] = field[4] *50
elseif field[4] > 500 then
step = step * 20
field[4] = math.floor(field[4]/20)
field[4] = field[4] *20
elseif field[4] > 200 then
step = step * 10
field[4] = math.floor(field[4]/10)
field[4] = field[4] *10
else
step = step * 1
field[4] = math.floor(field[4]/1)
field[4] = field[4] *1
end
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
else
field[4] = field[4]
end
end
-- Select the next or previous editable field
local function selectField(step)
current = current + step
if current > #fields then
current = #fields
elseif current < 1 then
current = 1
end
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end
local function drawProgressBar()
if LCD_W == 480 then
local width = (300 * refreshIndex) / #fields
lcd.drawRectangle(100, 10, 300, 6)
lcd.drawFilledRectangle(102, 13, width, 2);
else
local width = (60 * refreshIndex) / #fields
lcd.drawRectangle(45, 1, 60, 6)
lcd.drawFilledRectangle(47, 3, width, 2);
end
end
-- Redraw the current page
local function redrawFieldsPage()
lcd.clear()
drawScreenTitle("SBEC", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 7, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end
local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(1, margin+ spacing * index, field[1])
if field[4] == nil then
lcd.drawText(LCD_W, margin+ spacing * index, "---", attr + RIGHT)
else
if field[2] == VALUE then
if field[3] == 0x80 then
lcd.drawNumber(LCD_W, margin+ spacing * index, field[4] , attr + RIGHT + PREC1)
else
lcd.drawNumber(LCD_W, margin+ spacing * index, field[4] , attr + RIGHT)
end
end
end
end
end
local function telemetryRead(fieldx)
return sportTelemetryPush(0x17, 0x30, appId, fieldx)
end
local function telemetryIdle(field)
return sportTelemetryPush(0x17, 0x21, appId, field)
end
local function telemetryUnIdle(field)
return sportTelemetryPush(0x17, 0x20, appId, field)
end
local function telemetryWrite(fieldx, valuex)
return sportTelemetryPush(0x17, 0x31, appId, fieldx + valuex*256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 then
if #modifications > 0 then
local modificationstmp = modifications[1][2]
telemetryWrite(modifications[1][1], modificationstmp)
refreshIndex = 0
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if primId == 0x32 and dataId == appId then
local fieldId = value % 256
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[2] == VALUE then
value = value
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == VALUE and #field == 6 then
value = value
end
modifications[#modifications+1] = {field[3], value}
end
-- Main1
local function runFieldsPage(event)
if event == EVT_VIRTUAL_EXIT then
telemetryUnIdle(0x80)
return 2
elseif event == EVT_VIRTUAL_ENTER then
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then
addField(1)
elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then
addField(-1)
end
else
if event == EVT_VIRTUAL_NEXT then
selectField(1)
elseif event == EVT_VIRTUAL_PREVIOUS then
selectField(-1)
end
end
redrawFieldsPage()
return 0
end
local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
if LCD_W == 480 then
margin = 10
spacing = 20
end
pages = {
runSettingsPage,
}
for index = 1, 40, 1 do
local sensor = model.getSensor(index)
if sensor ~= nil and sensor.id >= 0x0e50 and sensor.id <= 0x0e5f then
appId = sensor.id
break
end
end
if appId == 0 then
error("No SBEC sensor in this model!")
end
telemetryIdle(0x80)
end
local function run(event)
if event == nil then
error("Cannot run as a model script!")
return 2
elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST or event == EVT_SHIFT_BREAK then
--selectPage(1)
elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST or event == EVT_SHIFT_LONG then
--killEvents(event);
--selectPage(-1)
end
local result = pages[page](event)
refreshNext()
return result
end
return { init=init, background=background, run=run }

View file

@ -0,0 +1,363 @@
--- - #########################################################################
---- # #
---- # Copyright (C) OpenTX #
----- # #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
local version = "v2.00"
local VALUE = 0
local COMBO = 1
local COLUMN_2 = 300
local edit = false
local page = 1
local current = 1
local refreshState = 0
local refreshIndex = 0
local calibrationState = 0
local pageOffset = 0
local calibrationStep = 0
local pages = {}
local fields = {}
local modifications = {}
local wingBitmaps = {}
local mountBitmaps = {}
local margin = 1
local spacing = 8
local counter = 0
local configFields = {
{ "Wing type", COMBO, 0x80, nil, { "Normal", "Delta", "VTail" } },
{ "Mounting type", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } },
}
local wingBitmapsFile = { "bmp/plane.bmp", "bmp/delta.bmp", "bmp/vtail.bmp" }
local mountBitmapsFile = { "bmp/horz.bmp", "bmp/horz-r.bmp", "bmp/vert.bmp", "bmp/vert-r.bmp" }
local settingsFields = {
{"SxR functions", COMBO, 0x9C, nil, { "Disable", "Enable" } },
{"Quick Mode:", COMBO, 0xAA, nil, { "Disable", "Enable" } },
{"CH5 mode", COMBO, 0xA8, nil, { "AIL2", "AUX1" } },
{"CH6 mode", COMBO, 0xA9, nil, { "ELE2", "AUX2" } },
{"AIL direction", COMBO, 0x82, nil, { "Normal", "Invers" }, { 255, 0 } },
{"ELE direction", COMBO, 0x83, nil, { "Normal", "Invers" }, { 255, 0 } },
{"RUD direction", COMBO, 0x84, nil, { "Normal", "Invers" }, { 255, 0 } },
{"AIL2 direction", COMBO, 0x9A, nil, { "Normal", "Invers" }, { 255, 0 } },
{"ELE2 direction", COMBO, 0x9B, nil, { "Normal", "Invers" }, { 255, 0 } },
{"AIL stab gain", VALUE, 0x85, nil, 0, 200, "%"},
{"ELE stab gain", VALUE, 0x86, nil, 0, 200, "%"},
{"RUD stab gain", VALUE, 0x87, nil, 0, 200, "%"},
{"AIL autolvl gain", VALUE, 0x88, nil, 0, 200, "%"},
{"ELE autolvl gain", VALUE, 0x89, nil, 0, 200, "%"},
{"ELE hover gain", VALUE, 0x8C, nil, 0, 200, "%"},
{"RUD hover gain", VALUE, 0x8D, nil, 0, 200, "%"},
{"AIL knife gain", VALUE, 0x8E, nil, 0, 200, "%"},
{"RUD knife gain", VALUE, 0x90, nil, 0, 200, "%"},
{"AIL autolvl offset", VALUE, 0x91, nil, -20, 20, "%", 0x6C},
{"ELE autolvl offset", VALUE, 0x92, nil, -20, 20, "%", 0x6C},
{"ELE hover offset", VALUE, 0x95, nil, -20, 20, "%", 0x6C},
{"RUD hover offset", VALUE, 0x96, nil, -20, 20, "%", 0x6C},
{"AIL knife offset", VALUE, 0x97, nil, -20, 20, "%", 0x6C},
{"RUD knife offset", VALUE, 0x99, nil, -20, 20, "%", 0x6C},
}
local calibrationFields = {
{ "X:", VALUE, 0x9E, 0, -100, 100, "%" },
{ "Y:", VALUE, 0x9F, 0, -100, 100, "%" },
{ "Z:", VALUE, 0xA0, 0, -100, 100, "%" }
}
local function drawScreenTitle(title, page, pages)
if math.fmod(math.floor(getTime() / 100), 10) == 0 then
title = version
end
if LCD_W == 480 then
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
lcd.drawText(LCD_W - 40, 5, page .. "/" .. pages, MENU_TITLE_COLOR)
else
lcd.drawScreenTitle(title, page, pages)
end
end
-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
end
-- Select the next or previous page
local function selectPage(step)
page = 1 + ((page + step - 1 + #pages) % #pages)
refreshIndex = 0
calibrationStep = 0
pageOffset = 0
end
-- Select the next or previous editable field
local function selectField(step)
current = 1 + ((current + step - 1 + #fields) % #fields)
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end
local function drawProgressBar()
if LCD_W == 480 then
local width = (300 * refreshIndex) / #fields
lcd.drawRectangle(100, 10, 300, 6)
lcd.drawFilledRectangle(102, 13, width, 2);
else
local width = (60 * refreshIndex) / #fields
lcd.drawRectangle(45, 1, 60, 6)
lcd.drawFilledRectangle(47, 3, width, 2);
end
end
-- Redraw the current page
local function redrawFieldsPage(event)
lcd.clear()
drawScreenTitle("SxR", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 10, 1 do
local field = fields[pageOffset + index]
if field == nil then
break
end
local attr = current == (pageOffset + index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(1, margin + spacing * index, field[1], attr)
if field[4] == nil then
lcd.drawText(LCD_W, margin + spacing * index, "---", RIGHT + attr)
else
if field[2] == VALUE then
lcd.drawNumber(LCD_W, margin + spacing * index, field[4], RIGHT + attr)
elseif field[2] == COMBO then
if field[4] >= 0 and field[4] < #(field[5]) then
lcd.drawText(LCD_W, margin + spacing * index, field[5][1 + field[4]], RIGHT + attr)
end
end
end
end
end
local function telemetryRead(field)
return sportTelemetryPush(0x17, 0x30, 0x0C30, field)
end
local function telemetryWrite(field, value)
return sportTelemetryPush(0x17, 0x31, 0x0C30, field + value * 256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 then
if calibrationState == 1 then
if telemetryWrite(0x9D, calibrationStep) == true then
refreshState = 1
calibrationState = 2
telemetryPopTimeout = getTime() + 120 -- normal delay is 500ms
end
elseif #modifications > 0 then
telemetryWrite(modifications[1][1], modifications[1][2])
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if physicalId == 0x1A and primId == 0x32 and dataId == 0x0C30 then
local fieldId = value % 256
if calibrationState == 2 then
if fieldId == 0x9D then
refreshState = 0
calibrationState = 0
calibrationStep = (calibrationStep + 1) % 7
end
else
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[3] == 0xAA then
value = bit32.band(value, 0x0001)
end
if field[3] >= 0x9E and field[3] <= 0xA0 then
local b1 = value % 256
local b2 = math.floor(value / 256)
value = b1 * 256 + b2
value = value - bit32.band(value, 0x8000) * 2
end
if field[2] == COMBO and #field == 6 then
for index = 1, #(field[6]), 1 do
if value == field[6][index] then
value = index - 1
break
end
end
elseif field[2] == VALUE and #field == 8 then
value = value - field[8] + field[5]
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
end
elseif getTime() > telemetryPopTimeout then
fields[refreshIndex + 1][4] = nil
refreshIndex = refreshIndex + 1
refreshState = 0
calibrationState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == COMBO and #field == 6 then
value = field[6][1 + value]
elseif field[2] == VALUE and #field == 8 then
value = value + field[8] - field[5]
end
modifications[#modifications + 1] = { field[3], value }
end
-- Main
local function runFieldsPage(event)
if event == EVT_VIRTUAL_EXIT then -- exit script
return 2
elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then
addField(1)
elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then
addField(-1)
end
else
if event == EVT_VIRTUAL_NEXT then
selectField(1)
elseif event == EVT_VIRTUAL_PREVIOUS then
selectField(-1)
end
end
redrawFieldsPage(event)
return 0
end
local function runConfigPage(event)
fields = configFields
local result = runFieldsPage(event)
if LCD_W == 128 then
local mountText = { "Label is facing the sky", "Label is facing ground", "Label is left when", "Label is right when" }
if fields[2][4] ~= nil then
lcd.drawText(1, 30, "Pins toward tail")
lcd.drawText(1, 40, mountText[1 + fields[2][4]])
if fields[2][4] > 1 then
lcd.drawText(1, 50, "looking from the tail")
end
end
else
if fields[1][4] ~= nil then
if LCD_W == 480 then
if wingBitmaps[1 + fields[1][4]] == nil then
wingBitmaps[1 + fields[1][4]] = Bitmap.open(wingBitmapsFile[1 + fields[1][4]])
end
lcd.drawBitmap(wingBitmaps[1 + fields[1][4]], 10, 90)
else
lcd.drawPixmap(20, 28, wingBitmapsFile[1 + fields[1][4]])
end
end
if fields[2][4] ~= nil then
if LCD_W == 480 then
if mountBitmaps[1 + fields[2][4]] == nil then
mountBitmaps[1 + fields[2][4]] = Bitmap.open(mountBitmapsFile[1 + fields[2][4]])
end
lcd.drawBitmap(mountBitmaps[1 + fields[2][4]], 190, 110)
else
lcd.drawPixmap(128, 28, mountBitmapsFile[1 + fields[2][4]])
end
end
end
return result
end
local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
if LCD_W == 480 then
margin = 10
spacing = 20
wingBitmapsFile = { "img/plane_b.png", "img/delta_b.png", "img/planev_b.png" }
mountBitmapsFile = { "img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png" }
end
pages = {
runConfigPage,
runSettingsPage,
}
end
-- Main
local function run(event)
if event == nil then
error("Cannot be run as a model script!")
return 2
elseif event == EVT_VIRTUAL_NEXT_PAGE then
selectPage(1)
elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then
killEvents(event);
selectPage(-1)
end
local result = pages[page](event)
refreshNext()
return result
end
return { init = init, run = run }

View file

@ -0,0 +1,37 @@
local toolName = "TNS|Crossfire configure|TNE"
---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
-- Init
local function init()
end
-- Run
local function run(event)
if event == nil then
error("Cannot run as a model script!")
return 2
end
chdir("CROSSFIRE")
return "crossfire.lua"
end
return { init=init, run=run }

View file

@ -0,0 +1 @@
Scripts that need to be available in TOOLS menu should be in this directory

View file

@ -258,7 +258,7 @@ local function runFlapsConfig(event)
end
local TailFields = {
{50, 50, COMBO, 1, 1, { "1 channel for Elevator, no Rudder", "One chan for Elevator, one for Rudder", "Two chans for Elevator, one for Rudder", "V Tail"} },
{50, 50, COMBO, 1, 1, { "1 channel for Elevator, no Rudder", "One channel for Elevator, one for Rudder", "Two channels for Elevator, one for Rudder", "V Tail"} },
{50, 127, COMBO, 1, 1, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --ele
{50, 167, COMBO, 1, 3, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --rud
{50, 207, COMBO, 0, 5, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --ele2
@ -302,8 +302,8 @@ local function runTailConfig(event)
if fields[1][5] == 2 then
lcd.drawBitmap(ImgTail, 252, 100)
lcd.drawBitmap(ImgTailRud, 340, 100)
drawMark(415, 150, "A")
drawMark(380, 120, "C")
drawMark(415, 150, "C")
drawMark(380, 120, "A")
drawMark(390, 185, "B")
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
drawMark(152, 124, "A")
@ -332,7 +332,7 @@ end
local lineIndex
local function drawNextLine(text, text2)
lcd.drawText(40, lineIndex, text, TEXT_COLOR)
lcd.drawText(250, lineIndex, text2 + 1, TEXT_COLOR)
lcd.drawText(242, lineIndex, ": CH" .. text2 + 1, TEXT_COLOR)
lineIndex = lineIndex + 20
end
@ -354,38 +354,35 @@ local function runConfigSummary(event)
lineIndex = 40
-- motors
if(MotorFields[1][5] == 1) then
drawNextLine("Motor chan :", MotorFields[2][5])
elseif (MotorFields[1][5] == 2) then
drawNextLine("Motor 1 chan :", MotorFields[2][5])
drawNextLine("Motor 2 chan :", MotorFields[3][5])
drawNextLine("Motor channel", MotorFields[2][5])
end
-- ail
if(AilFields[1][5] == 1) then
drawNextLine("Aileron chan :",AilFields[2][5])
drawNextLine("Aileron channel",AilFields[2][5])
elseif (AilFields[1][5] == 2) then
drawNextLine("Aileron 1 chan :",AilFields[2][5])
drawNextLine("Aileron 2 chan :",AilFields[3][5])
drawNextLine("Aileron Right channel",AilFields[2][5])
drawNextLine("Aileron Left channel",AilFields[3][5])
end
-- flaps
if(FlapsFields[1][5] == 1) then
drawNextLine("Flaps chan :",FlapsFields[2][5])
drawNextLine("Flaps channel",FlapsFields[2][5])
elseif (FlapsFields[1][5] == 2) then
drawNextLine("Flaps 1 chan :",FlapsFields[2][5])
drawNextLine("Flaps 2 chan :",FlapsFields[3][5])
drawNextLine("Flaps Right channel",FlapsFields[2][5])
drawNextLine("Flaps Left channel",FlapsFields[3][5])
end
-- tail
if(TailFields[1][5] == 0) then
drawNextLine("Elevator chan :",TailFields[2][5])
drawNextLine("Elevator channel",TailFields[2][5])
elseif (TailFields[1][5] == 1) then
drawNextLine("Elevator chan :",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5])
drawNextLine("Elevator channel",TailFields[2][5])
drawNextLine("Rudder channel",TailFields[3][5])
elseif (TailFields[1][5] == 2) then
drawNextLine("Elevator 1 chan :",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5])
drawNextLine("Elevator 2 chan :",TailFields[4][5])
drawNextLine("Elevator Right channel",TailFields[2][5])
drawNextLine("Rudder channel",TailFields[3][5])
drawNextLine("Elevator Left channel",TailFields[4][5])
elseif (TailFields[1][5] == 3) then
drawNextLine("V-Tail elevator :", TailFields[2][5])
drawNextLine("V-Tail rudder :", TailFields[3][5])
drawNextLine("V-Tail Right", TailFields[2][5])
drawNextLine("V-Tail Left", TailFields[3][5])
end
local result = runFieldsPage(event)
if(fields[1][5] == 1 and edit == false) then
@ -414,23 +411,20 @@ local function createModel(event)
-- motor
if(MotorFields[1][5] == 1) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor")
elseif (MotorFields[1][5] == 2) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor1")
addMix(MotorFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor2")
end
-- Ailerons
if(AilFields[1][5] == 1) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif (AilFields[1][5] == 2) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100)
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
end
-- Flaps
if(FlapsFields[1][5] == 1) then
addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps")
elseif (FlapsFields[1][5] == 2) then
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsL")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsL")
end
-- Tail
if(TailFields[1][5] == 0) then
@ -439,14 +433,14 @@ local function createModel(event)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "Elev")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
elseif (TailFields[1][5] == 2) then
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevL")
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevR")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
addMix(TailFields[4][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevR")
addMix(TailFields[4][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevL")
elseif (TailFields[1][5] == 3) then
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
end
lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR)
lcd.drawText(100, 130, "Press RTN to exit", TEXT_COLOR)

View file

@ -258,7 +258,7 @@ local function runFlapsConfig(event)
end
local TailFields = {
{50, 50, COMBO, 1, 1, { "1 channel for Elevator, no Rudder", "One chan for Elevator, one for Rudder", "Two chans for Elevator, one for Rudder", "V Tail"} },
{50, 50, COMBO, 1, 1, { "1 channel for Elevator, no Rudder", "One channel for Elevator, one for Rudder", "Two channels for Elevator, one for Rudder", "V Tail"} },
{50, 127, COMBO, 1, 1, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --ele
{50, 167, COMBO, 1, 3, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --rud
{50, 207, COMBO, 0, 5, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --ele2
@ -332,7 +332,7 @@ end
local lineIndex
local function drawNextLine(text, text2)
lcd.drawText(40, lineIndex, text, TEXT_COLOR)
lcd.drawText(250, lineIndex, text2 + 1, TEXT_COLOR)
lcd.drawText(242, lineIndex, ": CH" .. text2 + 1, TEXT_COLOR)
lineIndex = lineIndex + 20
end
@ -354,38 +354,35 @@ local function runConfigSummary(event)
lineIndex = 40
-- motors
if(MotorFields[1][5] == 1) then
drawNextLine("Motor chan :", MotorFields[2][5])
elseif (MotorFields[1][5] == 2) then
drawNextLine("Motor 1 chan :", MotorFields[2][5])
drawNextLine("Motor 2 chan :", MotorFields[3][5])
drawNextLine("Motor channel", MotorFields[2][5])
end
-- ail
if(AilFields[1][5] == 1) then
drawNextLine("Aileron chan :",AilFields[2][5])
drawNextLine("Aileron channel",AilFields[2][5])
elseif (AilFields[1][5] == 2) then
drawNextLine("Aileron 1 chan :",AilFields[2][5])
drawNextLine("Aileron 2 chan :",AilFields[3][5])
drawNextLine("Aileron Right channel",AilFields[2][5])
drawNextLine("Aileron Left channel",AilFields[3][5])
end
-- flaps
if(FlapsFields[1][5] == 1) then
drawNextLine("Flaps chan :",FlapsFields[2][5])
drawNextLine("Flaps channel",FlapsFields[2][5])
elseif (FlapsFields[1][5] == 2) then
drawNextLine("Flaps 1 chan :",FlapsFields[2][5])
drawNextLine("Flaps 2 chan :",FlapsFields[3][5])
drawNextLine("Flaps Right channel",FlapsFields[2][5])
drawNextLine("Flaps Left channel",FlapsFields[3][5])
end
-- tail
if(TailFields[1][5] == 0) then
drawNextLine("Elevator chan :",TailFields[2][5])
drawNextLine("Elevator channel",TailFields[2][5])
elseif (TailFields[1][5] == 1) then
drawNextLine("Elevator chan :",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5])
drawNextLine("Elevator channel",TailFields[2][5])
drawNextLine("Rudder channel",TailFields[3][5])
elseif (TailFields[1][5] == 2) then
drawNextLine("Elevator 1 chan :",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5])
drawNextLine("Elevator 2 chan :",TailFields[4][5])
drawNextLine("Elevator Right channel",TailFields[2][5])
drawNextLine("Rudder channel",TailFields[3][5])
drawNextLine("Elevator Left channel",TailFields[4][5])
elseif (TailFields[1][5] == 3) then
drawNextLine("V-Tail elevator :", TailFields[2][5])
drawNextLine("V-Tail rudder :", TailFields[3][5])
drawNextLine("V-Tail Right", TailFields[2][5])
drawNextLine("V-Tail Left", TailFields[3][5])
end
local result = runFieldsPage(event)
if(fields[1][5] == 1 and edit == false) then
@ -414,23 +411,20 @@ local function createModel(event)
-- motor
if(MotorFields[1][5] == 1) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor")
elseif (MotorFields[1][5] == 2) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor1")
addMix(MotorFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor2")
end
-- Ailerons
if(AilFields[1][5] == 1) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif (AilFields[1][5] == 2) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100)
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
end
-- Flaps
if(FlapsFields[1][5] == 1) then
addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps")
elseif (FlapsFields[1][5] == 2) then
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsL")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsL")
end
-- Tail
if(TailFields[1][5] == 0) then
@ -439,14 +433,14 @@ local function createModel(event)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "Elev")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
elseif (TailFields[1][5] == 2) then
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevL")
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevR")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
addMix(TailFields[4][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevR")
addMix(TailFields[4][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "ElevL")
elseif (TailFields[1][5] == 3) then
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
end
lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR)
lcd.drawText(100, 130, "Press RTN to exit", TEXT_COLOR)

View file

@ -315,7 +315,7 @@ local function fieldCommandLoad(field, data, offset)
field.status = data[offset]
field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then
if field.status == 0 then
fieldPopup = nil
end
end
@ -401,8 +401,7 @@ local function refreshNext()
local time = getTime()
if fieldPopup then
if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id }
crossfireTelemetryPush(0x2D, frame)
crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
fieldTimeout = time + fieldPopup.timeout
end
elseif time > fieldTimeout and not edit then

View file

@ -0,0 +1,37 @@
local toolName = "TNS|Crossfire config|TNE"
---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
-- Init
local function init()
end
-- Run
local function run(event)
if event == nil then
error("Cannot run as a model script!")
return 2
end
chdir("CROSSFIRE")
return "crossfire.lua"
end
return { init=init, run=run }

View file

@ -311,6 +311,7 @@ end
local function drawNextLine(x, y, label, channel)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+48, y, ":", 0);
lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0)
y = y + 8
if y > 50 then
@ -327,12 +328,12 @@ local function drawConfirmationMenu()
lcd.drawText(48, 1, "Ready to go?", 0);
lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
if engineMode == 1 then
x, y = drawNextLine(x, y, "Thr:", thrCH1)
x, y = drawNextLine(x, y, "Throttle", thrCH1)
end
x, y = drawNextLine(x, y, "Ele L:", elevCH1)
x, y = drawNextLine(x, y, "Ele R:", elevCH2)
x, y = drawNextLine(x, y, "Elevon L", elevCH1)
x, y = drawNextLine(x, y, "Elevon R", elevCH2)
if rudderMode == 1 then
drawNextLine(x, y, "Rudder:", rudCH1)
drawNextLine(x, y, "Rudder", rudCH1)
end
lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)

View file

@ -165,8 +165,8 @@ end
-- Init function
local function init()
thrCH1 = defaultChannel(2)
rollCH1 = defaultChannel(3)
yawCH1 = defaultChannel(0)
rollCH1 = defaultChannel(0)
yawCH1 = defaultChannel(3)
pitchCH1 = defaultChannel(1)
local ver, radio, maj, minor, rev = getVersion()
if string.match(radio, "x7") then
@ -326,6 +326,7 @@ end
-- Confirmation Menu
local function drawNextLine(x, y, label, channel)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+46, y, ":", 0);
lcd.drawSource(x+50, y, MIXSRC_CH1+channel, 0)
y = y + 8
if y > 50 then
@ -337,6 +338,7 @@ end
local function drawNextSWLine(x, y, label, switch)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+38, y, ":", 0);
lcd.drawText(x+42, y, switches[switch], 0)
y = y + 8
if y > 50 then
@ -352,15 +354,15 @@ local function drawConfirmationMenu()
lcd.clear()
lcd.drawText(0, 1, "Ready to go?", 0);
lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
x, y = drawNextLine(x, y, "Throttle:", thrCH1)
x, y = drawNextLine(x, y, "Roll:", rollCH1)
x, y = drawNextLine(x, y, "Pitch:", pitchCH1)
x, y = drawNextLine(x, y, "Yaw:", yawCH1)
x, y = drawNextLine(x, y, "Throttle", thrCH1)
x, y = drawNextLine(x, y, "Roll", rollCH1)
x, y = drawNextLine(x, y, "Pitch", pitchCH1)
x, y = drawNextLine(x, y, "Yaw", yawCH1)
local x = 72
local y = 12
x, y = drawNextSWLine(x, y, "Arm:", armSW1)
x, y = drawNextSWLine(x, y, "Mode:", modeSW1)
x, y = drawNextSWLine(x, y, "Beeper:", beeperSW1)
x, y = drawNextSWLine(x, y, "Arm", armSW1)
x, y = drawNextSWLine(x, y, "Mode", modeSW1)
x, y = drawNextSWLine(x, y, "Beeper", beeperSW1)
lcd.drawText(0, LCD_H-8, "[Enter Long] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)
fieldsMax = 0

View file

@ -429,6 +429,7 @@ end
-- Confirmation Menu
local function drawNextLine(x, y, label, channel)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+26, y, ":", 0);
lcd.drawSource(x+30, y, MIXSRC_CH1+channel, 0)
y = y + 8
if y > 50 then
@ -502,8 +503,8 @@ local function applySettings()
if aileronsMode == 1 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif aileronsMode == 2 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL")
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100)
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
end
if flapsMode == 1 then
addMix(flapsCH1, MIXSRC_SA, "Flap")
@ -519,9 +520,9 @@ local function applySettings()
end
if tailMode == 3 then
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1)
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
else
if tailMode > 0 then
addMix(rudCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")

View file

@ -315,7 +315,7 @@ local function fieldCommandLoad(field, data, offset)
field.status = data[offset]
field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then
if field.status == 0 then
fieldPopup = nil
end
end
@ -401,8 +401,7 @@ local function refreshNext()
local time = getTime()
if fieldPopup then
if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id }
crossfireTelemetryPush(0x2D, frame)
crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
fieldTimeout = time + fieldPopup.timeout
end
elseif time > fieldTimeout and not edit then

View file

@ -0,0 +1,37 @@
local toolName = "TNS|Crossfire configure|TNE"
---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
-- Init
local function init()
end
-- Run
local function run(event)
if event == nil then
error("Cannot run as a model script!")
return 2
end
chdir("CROSSFIRE")
return "crossfire.lua"
end
return { init=init, run=run }

View file

@ -338,10 +338,10 @@ local function drawConfirmationMenu()
if engineMode == 1 then
x, y = drawNextLine(x, y, "Throttle", thrCH1)
end
x, y = drawNextLine(x, y, "Elev L", elevCH1)
x, y = drawNextLine(x, y, "Elev R", elevCH2)
x, y = drawNextLine(x, y, "Elevon L", elevCH1)
x, y = drawNextLine(x, y, "Elevon R", elevCH2)
if rudderMode == 1 then
drawNextLine(x, y, "Rudder:", rudCH1)
drawNextLine(x, y, "Rudder", rudCH1)
end
lcd.drawText(48, LCD_H-8, "Long [ENT] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)

View file

@ -20,8 +20,8 @@ local ROLL_PAGE = 1
local PITCH_PAGE = 2
local YAW_PAGE = 3
local ARM_PAGE = 4
local MODE_PAGE = 5
local BEEPER_PAGE = 6
local BEEPER_PAGE = 5
local MODE_PAGE = 6
local CONFIRMATION_PAGE = 7
-- Navigation variables
@ -340,6 +340,7 @@ end
-- Confirmation Menu
local function drawNextCHLine(x, y, label, channel)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+48, y, ":", 0);
lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0)
y = y + 8
if y > 50 then
@ -351,6 +352,7 @@ end
local function drawNextSWLine(x, y, label, switch)
lcd.drawText(x, y, label, 0);
lcd.drawText(x+76, y, ":", 0);
lcd.drawText(x+80, y, switches[switch], 0)
y = y + 8
if y > 50 then
@ -366,15 +368,15 @@ local function drawConfirmationMenu()
lcd.clear()
lcd.drawText(48, 1, "Ready to go?", 0);
lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
x, y = drawNextCHLine(x, y, "Throttle:", thrCH1)
x, y = drawNextCHLine(x, y, "Roll:", rollCH1)
x, y = drawNextCHLine(x, y, "Pitch:", pitchCH1)
x, y = drawNextCHLine(x, y, "Yaw:", yawCH1)
x, y = drawNextCHLine(x, y, "Throttle", thrCH1)
x, y = drawNextCHLine(x, y, "Roll", rollCH1)
x, y = drawNextCHLine(x, y, "Pitch", pitchCH1)
x, y = drawNextCHLine(x, y, "Yaw", yawCH1)
x = 95
y = 12
x, y = drawNextSWLine(x, y, "Arm switch:", armSW1)
x, y = drawNextSWLine(x, y, "Mode switch:", modeSW1)
x, y = drawNextSWLine(x, y, "Beeper switch:", beeperSW1)
x, y = drawNextSWLine(x, y, "Arm switch", armSW1)
x, y = drawNextSWLine(x, y, "Beeper switch", beeperSW1)
x, y = drawNextSWLine(x, y, "Mode switch", modeSW1)
lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)
lcd.drawPixmap(LCD_W-18, 0, "confirm-tick.bmp")
@ -396,7 +398,7 @@ end
local function applySettings()
model.defaultInputs()
model.deleteMixes()
addMix(thrCH1, MIXSRC_FIRST_INPUT+defaultChannel(2), "Throttle")
addMix(thrCH1, MIXSRC_FIRST_INPUT+defaultChannel(2), "Engine")
addMix(rollCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Roll")
addMix(yawCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Yaw")
addMix(pitchCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "Pitch")

View file

@ -509,8 +509,8 @@ local function applySettings()
if aileronsMode == 1 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif aileronsMode == 2 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL")
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100)
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
end
if flapsMode == 1 then
addMix(flapsCH1, MIXSRC_SA, "Flaps")
@ -526,9 +526,9 @@ local function applySettings()
end
if tailMode == 3 then
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1)
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1)
addMix(eleCH2, MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
else
if tailMode > 0 then
addMix(rudCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")

View file

@ -32,7 +32,7 @@ option(AUTOSOURCE "Automatic source detection in menus" ON)
option(AUTOSWITCH "Automatic switch detection in menus" ON)
option(SEMIHOSTING "Enable debugger semihosting" OFF)
option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
option(WATCHDOG_DISABLED "Disable hardware Watchdog" OFF)
option(WATCHDOG "Enable hardware Watchdog" ON)
if(SDL_FOUND)
option(SIMU_AUDIO "Enable simulator audio." ON)
endif()
@ -232,8 +232,8 @@ if(JITTER_MEASURE)
add_definitions(-DJITTER_MEASURE)
endif()
if(WATCHDOG_DISABLED)
add_definitions(-DWATCHDOG_DISABLED)
if(WATCHDOG)
add_definitions(-DWATCHDOG)
endif()
if(SIMU_AUDIO)

View file

@ -529,7 +529,7 @@ void audioTask(void * pdata)
RTOS_WAIT_MS(1000); // 1s
#endif
if (!unexpectedShutdown) {
if (!globalData.unexpectedShutdown) {
AUDIO_HELLO();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

View file

@ -54,6 +54,7 @@ class Bluetooth
public:
void writeString(const char * str);
char * readline(bool error_reset = true);
void write(const uint8_t * data, uint8_t length);
void forwardTelemetry(const uint8_t * packet);
void wakeup();
@ -66,7 +67,6 @@ class Bluetooth
protected:
void pushByte(uint8_t byte);
uint8_t read(uint8_t * data, uint8_t size, uint32_t timeout=1000/*ms*/);
void write(const uint8_t * data, uint8_t length);
void appendTrainerByte(uint8_t data);
void processTrainerFrame(const uint8_t * buffer);
void processTrainerByte(uint8_t data);

View file

@ -191,8 +191,8 @@ enum TrainerMode {
#if defined(PCBTARANIS)
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
#endif
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
#endif
#if defined(BLUETOOTH)
TRAINER_MODE_MASTER_BLUETOOTH,
TRAINER_MODE_SLAVE_BLUETOOTH,
@ -482,7 +482,6 @@ enum SwitchSources {
SWSRC_SR2,
#endif
#if defined(PCBSKY9X)
SWSRC_ID0 = SWSRC_FIRST_SWITCH,
SWSRC_ID1,
@ -501,7 +500,7 @@ enum SwitchSources {
#if NUM_XPOTS > 0
SWSRC_FIRST_MULTIPOS_SWITCH,
SWSRC_LAST_MULTIPOS_SWITCH = SWSRC_FIRST_MULTIPOS_SWITCH + (NUM_POTS * XPOTS_MULTIPOS_COUNT) - 1,
SWSRC_LAST_MULTIPOS_SWITCH = SWSRC_FIRST_MULTIPOS_SWITCH + (NUM_XPOTS * XPOTS_MULTIPOS_COUNT) - 1,
#endif
SWSRC_FIRST_TRIM,

View file

@ -323,6 +323,9 @@ PACK(struct VarioData {
* Telemetry Sensor structure
*/
#define TELEMETRY_ENDPOINT_NONE 0xFF
#define TELEMETRY_ENDPOINT_SPORT 0x07
PACK(struct TelemetrySensor {
union {
uint16_t id; // data identifier, for FrSky we can reuse existing ones. Source unit is derived from type.
@ -383,19 +386,18 @@ PACK(struct TelemetrySensor {
int32_t getPrecDivisor() const;
bool isSameInstance(TelemetryProtocol protocol, uint8_t instance)
{
if (this->instance == instance)
return true;
if (protocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) {
if (((this->instance ^ instance) & 0x9F) == 0) {
if (((this->instance ^ instance) & 0x9F) == 0 && (this->instance >> 5) != TELEMETRY_ENDPOINT_SPORT && (instance >> 5) != TELEMETRY_ENDPOINT_SPORT) {
this->instance = instance; // update the instance in case we had telemetry switching
return true;
}
else {
}
return false;
}
}
else {
return this->instance == instance;
}
}
);
});
@ -422,16 +424,13 @@ PACK(struct TrainerModuleData {
#define MM_RF_CUSTOM_SELECTED 0xff
PACK(struct ModuleData {
uint8_t type:4;
// TODO some refactoring is needed, rfProtocol is only used by DSM2 and MULTI, it could be merged with subType
int8_t rfProtocol:4;
uint8_t channelsStart;
int8_t channelsCount; // 0=8 channels
union {
struct {
uint8_t failsafeMode:4; // only 3 bits used
uint8_t subType:3;
uint8_t invertedSerial:1; // telemetry serial inverted from standard
};
};
union {
uint8_t raw[PXX2_MAX_RECEIVERS_PER_MODULE * PXX2_LEN_RX_NAME + 1];
@ -452,10 +451,9 @@ PACK(struct ModuleData {
NOBACKUP(struct {
uint8_t power:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
uint8_t spare1:2;
uint8_t receiver_telem_off:1; // false = receiver telem enabled
uint8_t receiver_channel_9_16:1; // false = pwm out 1-8, true 9-16
uint8_t external_antenna:1; // false = internal antenna, true = external antenna
uint8_t fast:1; // TODO: to be used later by external module (fast means serial @ high speed)
uint8_t receiverTelemetryOff:1; // false = receiver telem enabled
uint8_t receiverHigherChannels:1; // false = pwm out 1-8, true 9-16
int8_t antennaMode:2;
uint8_t spare2;
} pxx);
NOBACKUP(struct {
@ -668,7 +666,7 @@ PACK(struct TrainerData {
#define SPLASH_MODE uint8_t splashMode:1; uint8_t splashSpare:2
#endif
#if defined(PCBXLITES) || defined(PCBHORUS)
#if defined(PCBXLITES)
#define GYRO_FIELDS \
int8_t gyroMax; \
int8_t gyroOffset;
@ -685,13 +683,13 @@ PACK(struct TrainerData {
NOBACKUP(char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME]); \
NOBACKUP(char anaNames[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS][LEN_ANA_NAME]); \
NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
NOBACKUP(uint8_t spare4:1); \
NOBACKUP(uint8_t spare5:1); \
NOBACKUP(uint8_t blOffBright:7); \
NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]);
#elif defined(PCBTARANIS) || defined(PCBNV14)
#if defined(STORAGE_BLUETOOTH)
#define BLUETOOTH_FIELDS \
uint8_t spare4; \
uint8_t spare5; \
char bluetoothName[LEN_BLUETOOTH_NAME];
#else
#define BLUETOOTH_FIELDS
@ -709,7 +707,7 @@ PACK(struct TrainerData {
#elif defined(PCBSKY9X)
#define EXTRA_GENERAL_FIELDS \
int8_t txCurrentCalibration; \
int8_t spare4; \
int8_t spare5; \
uint8_t mAhWarn; \
uint16_t mAhUsed; \
int8_t temperatureCalib; \
@ -735,7 +733,7 @@ PACK(struct TrainerData {
#if defined(BUZZER)
#define BUZZER_FIELD int8_t buzzerMode:2 // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware)
#else
#define BUZZER_FIELD int8_t spare3:2
#define BUZZER_FIELD int8_t spare4:2
#endif
PACK(struct RadioData {
@ -747,7 +745,9 @@ PACK(struct RadioData {
N_HORUS_FIELD(uint8_t contrast);
NOBACKUP(uint8_t vBatWarn);
NOBACKUP(int8_t txVoltageCalibration);
NOBACKUP(int8_t backlightMode);
uint8_t backlightMode:3;
int8_t antennaMode:2;
int8_t spare1:3;
NOBACKUP(TrainerData trainer);
NOBACKUP(uint8_t view); // index of view in main screen
NOBACKUP(BUZZER_FIELD); /* 2bits */
@ -768,7 +768,7 @@ PACK(struct RadioData {
NOBACKUP(uint8_t templateSetup); // RETA order for receiver channels
NOBACKUP(int8_t PPM_Multiplier);
NOBACKUP(int8_t hapticLength);
N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t spare1));
N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t spare2));
N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t stickReverse));
NOBACKUP(int8_t beepLength:3);
NOBACKUP(int8_t hapticStrength:3);
@ -791,7 +791,7 @@ PACK(struct RadioData {
NOBACKUP(uint8_t disableRssiPoweroffAlarm:1);
NOBACKUP(uint8_t USBMode:2);
NOBACKUP(uint8_t jackMode:2);
NOBACKUP(uint8_t spare2:1);
NOBACKUP(uint8_t spare3:1);
NOBACKUP(char ttsLanguage[2]);
NOBACKUP(int8_t beepVolume:4);
NOBACKUP(int8_t wavVolume:4);
@ -945,7 +945,7 @@ static inline void check_struct()
CHKSIZE(RadioData, 735);
CHKSIZE(ModelData, 5301);
#elif defined(PCBHORUS)
CHKSIZE(RadioData, 883);
CHKSIZE(RadioData, 881);
CHKSIZE(ModelData, 9736);
#endif

View file

@ -129,10 +129,11 @@ uint8_t * lcdLoadBitmap(uint8_t * bmp, const char * filename, uint8_t width, uin
memset(dest, 0, BITMAP_BUFFER_SIZE(w, h) - 2);
uint8_t rowSize = (w + 7) / 8;
uint8_t rowSize;
switch (depth) {
case 1:
rowSize = ((w + 31) / 32) * 4;
for (int8_t i=h-1; i>=0; i--) {
result = f_read(&bmpFile, buf, rowSize, &read);
if (result != FR_OK || read != rowSize) {

View file

@ -183,8 +183,7 @@ void title(const char * s);
title(name)
typedef int choice_t;
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event);
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, IsValueAvailable isValueAvailable = nullptr);
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char * label, LcdFlags attr, event_t event);
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event);
@ -231,15 +230,11 @@ void drawStatusLine();
#define drawStatusLine()
#endif
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(event_t event);
void pushMenuTextView(const char *filename);
void pushModelNotes();
void readModelNotes();
#define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)

View file

@ -922,15 +922,34 @@ void lcdDraw1bitBitmap(coord_t x, coord_t y, const uint8_t * img, uint8_t idx, L
const uint8_t * q = img;
uint8_t w = *q++;
uint8_t hb = ((*q++) + 7) / 8;
uint8_t yShift = y % 8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb;
for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[(y / 8 + yb) * LCD_W + x];
for (coord_t i=0; i<w; i++){
uint8_t b = *q++;
uint8_t b = inv ? ~(*q++) : *q++;
if (p < DISPLAY_END) {
*p++ = inv ? ~b : b;
if (!yShift) {
*p = b;
}
else {
*p = (*p & ((1 << yShift) - 1)) | (b << yShift);
if (p + LCD_W < DISPLAY_END) {
p[LCD_W] = (p[LCD_W] & (0xFF >> yShift)) | (b >> (8 - yShift));
}
}
}
p++;
}
}
}

View file

@ -23,7 +23,7 @@
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay)
{
lcdDrawTextAlignedLeft(y, str);
lcdDrawNumber(MIXES_2ND_COLUMN, y, (10/DELAY_STEP)*delay, attr|PREC1|LEFT);
lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|PREC1|LEFT);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX);
return delay;
}

View file

@ -22,7 +22,7 @@
void menuRadioSpecialFunctions(event_t event)
{
#if defined(PCBTARANIS)
#if defined(NAVIGATION_X7)
const CustomFunctionData * cfn = &g_eeGeneral.customFn[menuVerticalPosition];
if (!CFN_SWITCH(cfn) && menuHorizontalPosition < 0 && event==EVT_KEY_BREAK(KEY_ENTER)) {
menuHorizontalPosition = 0;
@ -33,7 +33,7 @@ void menuRadioSpecialFunctions(event_t event)
menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext);
#if defined(PCBX7)
#if defined(NAVIGATION_X7)
if (!CFN_SWITCH(cfn) && menuHorizontalPosition == 0 && s_editMode <= 0) {
menuHorizontalPosition = -1;
}

View file

@ -22,6 +22,15 @@
#define MODELSEL_W LCD_W
void onDeleteModelConfirm(const char * result)
{
if (result == STR_OK) {
storageCheck(true);
eeDeleteModel(menuVerticalPosition); // delete file
s_copyMode = 0;
}
}
void onModelSelectMenu(const char * result)
{
int8_t sub = menuVerticalPosition;
@ -45,13 +54,14 @@ void onModelSelectMenu(const char * result)
POPUP_WARNING(eeBackupModel(sub));
}
else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) {
if (!sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) {
if (sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, nullptr))
POPUP_MENU_START(onModelSelectMenu);
else
POPUP_WARNING(STR_NO_MODELS_ON_SD);
}
}
#endif
else if (result == STR_DELETE_MODEL) {
POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr);
POPUP_CONFIRMATION(STR_DELETEMODEL, onDeleteModelConfirm);
SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR);
}
#if defined(SDCARD)
@ -68,14 +78,6 @@ void onModelSelectMenu(const char * result)
void menuModelSelect(event_t event)
{
if (warningResult) {
warningResult = 0;
storageCheck(true);
eeDeleteModel(menuVerticalPosition); // delete file
s_copyMode = 0;
event = EVT_ENTRY_UP;
}
event_t _event_ = event;
if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event)) {
_event_ = 0;

View file

@ -90,7 +90,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS,
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM,
#if defined(EXTERNAL_ANTENNA)
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA,
#endif
ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE,
@ -224,8 +224,25 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
#define TRAINER_BLUETOOTH_S_ROW (bluetooth.distantAddr[0] == '\0' ? HIDDEN_ROW : LABEL())
#define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW)
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
#define EXTERNAL_ANTENNA_ROW ((isModuleXJT(INTERNAL_MODULE) && g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL) ? (uint8_t)0 : HIDDEN_ROW),
void onModelAntennaSwitchConfirm(const char * result)
{
if (result == STR_OK) {
// Switch to external antenna confirmation
g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode = ANTENNA_MODE_EXTERNAL;
globalData.externalAntennaEnabled = true;
storageDirty(EE_MODEL);
}
else {
reusableBuffer.moduleSetup.antennaMode = g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode;
}
}
#else
#define EXTERNAL_ANTENNA_ROW
#endif
#if defined(PCBX7) || defined(PCBX9LITE)
#define ANTENNA_ROW
#if defined(BLUETOOTH)
#define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)),
#else
@ -234,12 +251,10 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
#define TRAINER_PPM_PARAMS_ROW (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW)
#define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PPM_PARAMS_ROW
#elif defined(PCBXLITES)
#define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)),
#define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW))
#define TRAINER_PPM_PARAMS_ROW (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW)
#define TRAINER_ROWS LABEL(Trainer), 0, IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), TRAINER_CHANNELS_ROW, TRAINER_PPM_PARAMS_ROW
#elif defined(PCBXLITE)
#define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)),
#define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW))
#define TRAINER_ROWS IF_BT_TRAINER_ON(LABEL(Trainer)), IF_BT_TRAINER_ON(0), IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), IF_BT_TRAINER_ON(TRAINER_CHANNELS_ROW), HIDDEN_ROW /* xlite has only BT trainer, so never PPM */
#else
@ -274,7 +289,7 @@ void onBluetoothConnectMenu(const char * result)
INTERNAL_MODULE_CHANNELS_ROWS, \
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1)), \
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* RxNum */ \
ANTENNA_ROW \
EXTERNAL_ANTENNA_ROW \
IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* Failsafe */ \
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* Range check and Register buttons */ \
IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* Module options */ \
@ -285,16 +300,6 @@ void onBluetoothConnectMenu(const char * result)
#define INTERNAL_MODULE_ROWS
#endif
#if defined(EXTERNAL_ANTENNA)
void onAntennaSwitchConfirm(const char * result)
{
if (result == STR_OK) {
// Switch to external antenna confirmation
g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna = XJT_EXTERNAL_ANTENNA;
}
}
#endif
void menuModelSetup(event_t event)
{
int8_t old_editMode = s_editMode;
@ -372,6 +377,9 @@ void menuModelSetup(event_t event)
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) {
memclear(&reusableBuffer.moduleSetup, sizeof(reusableBuffer.moduleSetup));
reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power;
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
reusableBuffer.moduleSetup.antennaMode = g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode;
#endif
}
#if (defined(DSM2) || defined(PXX))
@ -910,16 +918,16 @@ void menuModelSetup(event_t event)
if (isModuleR9MNonAccess(EXTERNAL_MODULE)) {
if (g_model.moduleData[EXTERNAL_MODULE].subType > MODULE_SUBTYPE_R9M_EU) {
POPUP_WARNING(STR_MODULE_PROTOCOL_FLEX_WARN_LINE1);
SET_WARNING_INFO(STR_R9M_PROTO_WARN_LINE2, sizeof(TR_R9M_PROTO_WARN_LINE2) - 1, 0);
SET_WARNING_INFO(STR_MODULE_PROTOCOL_WARN_LINE2, sizeof(TR_MODULE_PROTOCOL_WARN_LINE2) - 1, 0);
}
#if POPUP_LEVEL >= 3
else if (g_model.moduleData[EXTERNAL_MODULE].subType == MODULE_SUBTYPE_R9M_EU) {
POPUP_WARNING(STR_R9M_PROTO_EU_WARN_LINE1);
SET_WARNING_INFO(STR_R9M_PROTO_WARN_LINE2, sizeof(TR_R9M_PROTO_WARN_LINE2) - 1, 0);
POPUP_WARNING(STR_MODULE_PROTOCOL_EU_WARN_LINE1);
SET_WARNING_INFO(STR_MODULE_PROTOCOL_WARN_LINE2, sizeof(TR_MODULE_PROTOCOL_WARN_LINE2) - 1, 0);
}
else {
POPUP_WARNING(STR_R9M_PROTO_FCC_WARN_LINE1);
SET_WARNING_INFO(STR_R9M_PROTO_WARN_LINE2, sizeof(TR_R9M_PROTO_WARN_LINE2) - 1, 0);
POPUP_WARNING(STR_MODULE_PROTOCOL_FCC_WARN_LINE1);
SET_WARNING_INFO(STR_MODULE_PROTOCOL_WARN_LINE2, sizeof(TR_MODULE_PROTOCOL_WARN_LINE2) - 1, 0);
}
#endif
}
@ -1379,20 +1387,23 @@ void menuModelSetup(event_t event)
}
break;
#if defined(EXTERNAL_ANTENNA)
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA:
{
uint8_t newAntennaSel = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_ANTENNASELECTION, STR_VANTENNATYPES, g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna, 0, 1, attr, event);
if (newAntennaSel != g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna && newAntennaSel == XJT_EXTERNAL_ANTENNA) {
POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onAntennaSwitchConfirm);
const char * w = STR_ANTENNACONFIRM2;
SET_WARNING_INFO(w, strlen(w), 0);
reusableBuffer.moduleSetup.antennaMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_ANTENNA, STR_ANTENNA_MODES,
reusableBuffer.moduleSetup.antennaMode == ANTENNA_MODE_PER_MODEL ? ANTENNA_MODE_INTERNAL : reusableBuffer.moduleSetup.antennaMode,
ANTENNA_MODE_INTERNAL, ANTENNA_MODE_EXTERNAL, attr, event,
[](int value) { return value != ANTENNA_MODE_PER_MODEL; });
if (event && !s_editMode && reusableBuffer.moduleSetup.antennaMode != g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode) {
if (reusableBuffer.moduleSetup.antennaMode == ANTENNA_MODE_EXTERNAL && !isExternalAntennaEnabled()) {
POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onModelAntennaSwitchConfirm);
SET_WARNING_INFO(STR_ANTENNACONFIRM2, sizeof(TR_ANTENNACONFIRM2), 0);
}
else {
g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna = newAntennaSel;
g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode = reusableBuffer.moduleSetup.antennaMode;
checkExternalAntenna();
}
}
break;
}
#endif
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS:

View file

@ -70,7 +70,6 @@ void onCustomFunctionsFileSelectionMenu(const char * result)
#endif // SDCARD
#if defined(PCBTARANIS)
void onAdjustGvarSourceLongEnterPress(const char * result)
{
CustomFunctionData * cfn = &g_model.customFn[menuVerticalPosition];
@ -148,9 +147,8 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#if defined(PCBTARANIS)
#if defined(PCBXLITE)
if (menuHorizontalPosition==0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
killEvents(KEY_ENTER);
if (IS_SHIFT_PRESSED()) { // ENT LONG on xlite brings up switch type menu, so this menu is activated with SHIT + ENT LONG
// ENT LONG on xlite brings up switch type menu, so this menu is activated with SHIT + ENT LONG
if (menuHorizontalPosition==0 && event==EVT_KEY_LONG(KEY_ENTER) && IS_SHIFT_PRESSED() && !READ_ONLY()) {
#else
if (menuHorizontalPosition<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
#endif
@ -172,9 +170,6 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
}
POPUP_MENU_START(onCustomFunctionsMenu);
}
#if defined(PCBXLITE)
}
#endif
#endif // PCBTARANIS
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
@ -389,7 +384,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
else if (attr) {
REPEAT_LAST_CURSOR_MOVE();
}
#if defined(PCBX7) || defined(PCBX9LITE)
#if defined(NAVIGATION_X7)
if (active || event==EVT_KEY_LONG(KEY_ENTER)) {
CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max);
if (func == FUNC_ADJUST_GVAR && attr && event==EVT_KEY_LONG(KEY_ENTER)) {
@ -436,7 +431,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
break;
}
}
#if defined(PCBX7) || defined(PCBX9LITE)
#if defined(NAVIGATION_X7)
if (sub==k && menuHorizontalPosition<0 && CFN_SWITCH(cfn)) {
lcdInvertLine(i+1);
}

Some files were not shown because too many files have changed in this diff Show more