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-*/ cmake-build-*/
/debian/ /debian/
/*.vscode /*.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_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) 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}) set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
@ -80,6 +80,14 @@ endif()
option(DISABLE_COMPANION "Disable building companion and simulators" OFF) option(DISABLE_COMPANION "Disable building companion and simulators" OFF)
if(NOT DISABLE_COMPANION) # FIXME cosmetics/style 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(Qt5Core)
find_package(Qt5Widgets) find_package(Qt5Widgets)
find_package(Qt5Xml) find_package(Qt5Xml)
@ -190,6 +198,32 @@ if(WIN32)
endif() endif()
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}) add_subdirectory(${RADIO_SRC_DIRECTORY})
if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)

View file

@ -166,7 +166,7 @@ Eric Burdis
Nigel Chippindale Nigel Chippindale
Michael Deasy Michael Deasy
Stephen Stough Stephen Stough
Kenneth Lilja (monthly) Kenneth Lilja
Robert Jero Robert Jero
Gary Bancroft Gary Bancroft
Robert Cotsford Robert Cotsford
@ -351,7 +351,6 @@ Roberto Orsello
David Finger David Finger
Jean-Marie Oddo Jean-Marie Oddo
Mike Matheny Mike Matheny
Glen Roe (Showmaster)
Arron Bates Arron Bates
Tim Spurr Tim Spurr
Daniel Morgan Daniel Morgan
@ -832,7 +831,7 @@ Carsten Wache
Brock White Brock White
Steven Poretz Steven Poretz
David Huelster David Huelster
Gordon Stahl (monthly) Gordon Stahl
John Mathison John Mathison
Richard Duczmal Richard Duczmal
Gregory Barron Gregory Barron
@ -910,7 +909,7 @@ George Carnie
Philippe Stofleth Philippe Stofleth
Tim Dzugan Tim Dzugan
Illia Izotov Illia Izotov
Richard Miles (monthly) Richard Miles
Attila Kapolnai Attila Kapolnai
Gilles Dando Gilles Dando
Denis Roussille Denis Roussille
@ -1009,7 +1008,7 @@ Julien Kieffer
Gregor Walter Gregor Walter
Carlos Viegas Carlos Viegas
Roberto Orsello Roberto Orsello
Steve Murray (monthly) Steve Murray
Marcel Schäfer Marcel Schäfer
Sean Cull Sean Cull
Holger Bothmer Holger Bothmer
@ -1443,7 +1442,7 @@ Marko Domagoj Zic
Fabrice Debonnet Fabrice Debonnet
Ms Place Ms Place
Jörg Hammer Jörg Hammer
Rapid Informatics LLC Rapid Informatics LLC (monthly)
Renaud Perriguey Renaud Perriguey
Edmond Dufresne Edmond Dufresne
Jaroslav Gazik Jaroslav Gazik
@ -1535,3 +1534,8 @@ Alain Labonne
Darko Perković Darko Perković
Pierre Malriq Pierre Malriq
Donald Manson 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 "DragNDrop")
# set(CPACK_GENERATOR "TGZ") # for quick testing # set(CPACK_GENERATOR "TGZ") # for quick testing
set(CPACK_BINARY_DRAGNDROP ON) 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_VOLUME_NAME "OpenTX Companion")
set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store) set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store)
set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}") set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}")

View file

@ -37,6 +37,7 @@ AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowIcon(CompanionIcon("apppreferences.png")); setWindowIcon(CompanionIcon("apppreferences.png"));
ui->tabWidget->setCurrentIndex(0);
initSettings(); initSettings();
connect(ui->boardCB, SIGNAL(currentIndexChanged(int)), this, SLOT(onBaseFirmwareChanged())); 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) uint32_t Boards::getFourCC(Type board)
{ {
switch (board) { switch (board) {
case BOARD_X12S: case BOARD_HORUS_X12S:
return 0x3478746F; return 0x3478746F;
case BOARD_X10: case BOARD_X10:
case BOARD_X10_EXPRESS: case BOARD_X10_EXPRESS:
@ -82,8 +82,8 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_MEGA2560: case BOARD_MEGA2560:
case BOARD_GRUVIN9X: case BOARD_GRUVIN9X:
return 0x3178746F; return 0x3178746F;
case BOARD_STOCK: case BOARD_9X_M64:
case BOARD_M128: case BOARD_9X_M128:
return 0; return 0;
case BOARD_JUMPER_T12: case BOARD_JUMPER_T12:
return 0x3D78746F; return 0x3D78746F;
@ -94,12 +94,12 @@ uint32_t Boards::getFourCC(Type board)
return 0; return 0;
} }
const int Boards::getEEpromSize(Board::Type board) int Boards::getEEpromSize(Board::Type board)
{ {
switch (board) { switch (board) {
case BOARD_STOCK: case BOARD_9X_M64:
return EESIZE_STOCK; return EESIZE_STOCK;
case BOARD_M128: case BOARD_9X_M128:
return EESIZE_M128; return EESIZE_M128;
case BOARD_MEGA2560: case BOARD_MEGA2560:
case BOARD_GRUVIN9X: case BOARD_GRUVIN9X:
@ -121,7 +121,7 @@ const int Boards::getEEpromSize(Board::Type board)
return EESIZE_TARANIS; return EESIZE_TARANIS;
case BOARD_UNKNOWN: case BOARD_UNKNOWN:
return EESIZE_MAX; return EESIZE_MAX;
case BOARD_X12S: case BOARD_HORUS_X12S:
case BOARD_X10: case BOARD_X10:
case BOARD_X10_EXPRESS: case BOARD_X10_EXPRESS:
return 0; return 0;
@ -130,12 +130,12 @@ const int Boards::getEEpromSize(Board::Type board)
return 0; return 0;
} }
const int Boards::getFlashSize(Type board) int Boards::getFlashSize(Type board)
{ {
switch (board) { switch (board) {
case BOARD_STOCK: case BOARD_9X_M64:
return FSIZE_STOCK; return FSIZE_STOCK;
case BOARD_M128: case BOARD_9X_M128:
return FSIZE_M128; return FSIZE_M128;
case BOARD_MEGA2560: case BOARD_MEGA2560:
case BOARD_GRUVIN9X: case BOARD_GRUVIN9X:
@ -155,7 +155,7 @@ const int Boards::getFlashSize(Type board)
case BOARD_TARANIS_X9E: case BOARD_TARANIS_X9E:
case BOARD_JUMPER_T12: case BOARD_JUMPER_T12:
return FSIZE_TARANIS; return FSIZE_TARANIS;
case BOARD_X12S: case BOARD_HORUS_X12S:
case BOARD_X10: case BOARD_X10:
case BOARD_X10_EXPRESS: case BOARD_X10_EXPRESS:
return FSIZE_HORUS; 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) if (index < 0)
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM}; 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}; 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) { switch (capability) {
case Sticks: case Sticks:
@ -280,12 +280,6 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else else
return 3; return 3;
case PotsStorage:
if (IS_HORUS(board))
return 5;
else
return getCapability(board, Pots);
case FactoryInstalledPots: case FactoryInstalledPots:
if (IS_TARANIS_X9(board)) if (IS_TARANIS_X9(board))
return 2; return 2;
@ -300,12 +294,6 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else else
return 0; return 0;
case SlidersStorage:
if (IS_HORUS_X10(board))
return 4;
else
return getCapability(board, Sliders);
case MouseAnalogs: case MouseAnalogs:
if (IS_HORUS(board)) if (IS_HORUS(board))
return 2; return 2;
@ -313,7 +301,7 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
return 0; return 0;
case GyroAnalogs: case GyroAnalogs:
if (IS_HORUS_X12S(board) || IS_TARANIS_XLITES(board)) if (IS_TARANIS_XLITES(board))
return 2; return 2;
else else
return 0; return 0;
@ -350,6 +338,8 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
case FactoryInstalledSwitches: case FactoryInstalledSwitches:
if (IS_TARANIS_X9E(board)) if (IS_TARANIS_X9E(board))
return 8; return 8;
if (IS_HORUS_X12S(board))
return 8;
else else
return getCapability(board, Switches); return getCapability(board, Switches);
@ -372,7 +362,7 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
return 0; return 0;
} }
const QString Boards::getAxisName(int index) QString Boards::getAxisName(int index)
{ {
const QString axes[] = { const QString axes[] = {
tr("Left Horizontal"), tr("Left Horizontal"),
@ -388,7 +378,7 @@ const QString Boards::getAxisName(int index)
return tr("Unknown"); return tr("Unknown");
} }
const QString Boards::getAnalogInputName(Board::Type board, int index) QString Boards::getAnalogInputName(Board::Type board, int index)
{ {
if (index < 0) if (index < 0)
return CPN_STR_UNKNOWN_ITEM; return CPN_STR_UNKNOWN_ITEM;
@ -454,8 +444,8 @@ const QString Boards::getAnalogInputName(Board::Type board, int index)
"S1", "S1",
"6P", "6P",
"S2", "S2",
"L1", "S3",
"L2", "S4",
"LS", "LS",
"RS", "RS",
"JSx", "JSx",
@ -481,17 +471,17 @@ const QString Boards::getAnalogInputName(Board::Type board, int index)
return CPN_STR_UNKNOWN_ITEM; 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)); return (getFourCC(board1) == getFourCC(board2));
} }
const QString Boards::getBoardName(Board::Type board) QString Boards::getBoardName(Board::Type board)
{ {
switch (board) { switch (board) {
case BOARD_STOCK: case BOARD_9X_M64:
return "9X"; return "9X";
case BOARD_M128: case BOARD_9X_M128:
return "9X128"; return "9X128";
case BOARD_GRUVIN9X: case BOARD_GRUVIN9X:
return "Gruvin9x"; return "Gruvin9x";
@ -521,7 +511,7 @@ const QString Boards::getBoardName(Board::Type board)
return "9XR-PRO"; return "9XR-PRO";
case BOARD_AR9X: case BOARD_AR9X:
return "AR9X"; return "AR9X";
case BOARD_X12S: case BOARD_HORUS_X12S:
return "Horus X12S"; return "Horus X12S";
case BOARD_X10: case BOARD_X10:
return "Horus X10/X10S"; return "Horus X10/X10S";

View file

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

View file

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

View file

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

View file

@ -53,13 +53,15 @@ bool GeneralSettings::switchSourceAllowedTaranis(int index) const
bool GeneralSettings::isPotAvailable(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; return potConfig[index] != Board::POT_NONE;
} }
bool GeneralSettings::isSliderAvailable(int index) const 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; return sliderConfig[index] != Board::SLIDER_NONE;
} }

View file

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

View file

@ -157,30 +157,14 @@ void ModelData::clear()
{ {
memset(reinterpret_cast<void *>(this), 0, sizeof(ModelData)); memset(reinterpret_cast<void *>(this), 0, sizeof(ModelData));
modelIndex = -1; // an invalid index, this is managed by the TreeView data model 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[0].channelsCount = 8;
moduleData[1].channelsStart = 0; moduleData[1].channelsStart = 0;
moduleData[1].channelsCount = 8; moduleData[1].channelsCount = 8;
moduleData[0].ppm.delay = 300; moduleData[0].ppm.delay = 300;
moduleData[1].ppm.delay = 300; moduleData[1].ppm.delay = 300;
moduleData[2].ppm.delay = 300; moduleData[2].ppm.delay = 300; //Trainer PPM
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;
}
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) { for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
flightModeData[i].clear(i); flightModeData[i].clear(i);
} }

View file

@ -171,16 +171,16 @@ class ModelData {
ExpoData expoData[CPN_MAX_EXPOS]; ExpoData expoData[CPN_MAX_EXPOS];
CurveData curves[CPN_MAX_CURVES]; CurveData curves[CPN_MAX_CURVES];
LogicalSwitchData logicalSw[CPN_MAX_LOGICAL_SWITCHES]; LogicalSwitchData logicalSw[CPN_MAX_LOGICAL_SWITCHES];
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS]; CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
SwashRingData swashRingData; SwashRingData swashRingData;
unsigned int thrTraceSrc; unsigned int thrTraceSrc;
uint64_t switchWarningStates; uint64_t switchWarningStates;
unsigned int switchWarningEnable; unsigned int switchWarningEnable;
unsigned int potsWarningMode; unsigned int potsWarningMode;
bool potsWarningEnabled[CPN_MAX_POTS]; bool potsWarnEnabled[CPN_MAX_POTS];
int potPosition[CPN_MAX_POTS]; int potsWarnPosition[CPN_MAX_POTS];
bool displayChecklist; bool displayChecklist;
GVarData gvarData[CPN_MAX_GVARS]; GVarData gvarData[CPN_MAX_GVARS];
MavlinkData mavlink; MavlinkData mavlink;
unsigned int telemetryProtocol; unsigned int telemetryProtocol;

View file

@ -96,10 +96,6 @@ QString ModuleData::subTypeToString(int type) const
QString ModuleData::powerValueToString(Firmware * fw) const QString ModuleData::powerValueToString(Firmware * fw) const
{ {
const QStringList & strRef = powerValueStrings(subType, fw); 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); return strRef.value(pxx.power, CPN_STR_UNKNOWN_ITEM);
} }

View file

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

View file

@ -30,6 +30,7 @@
#define STR_MULTI_RFPOWER QT_TRANSLATE_NOOP("Multiprotocols", "Radio output power") #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_SERVOFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Servo output frequency")
#define STR_MULTI_OPTION QT_TRANSLATE_NOOP("Multiprotocols", "Option value") #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") #define STR_MULTI_DEFAULT QT_TRANSLATE_NOOP("Multiprotocols", "DEFAULT")
static const QStringList STR_SUBTYPE_CUSTOM ({ 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_HISKY {"Standard", "HK310"};
static const QStringList STR_SUBTYPE_V2X2 {"Standard", "JXD506"}; 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_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_YD717 {"Standard", "Skywalker", "Syma X4", "XINXUN", "NIHUI"};
static const QStringList STR_SUBTYPE_KN {"WLtoys", "FeiLun"}; static const QStringList STR_SUBTYPE_KN {"WLtoys", "FeiLun"};
static const QStringList STR_SUBTYPE_SYMAX {"Standard", "Syma X5C"}; 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_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_CORONA {"Corona V1", "Corona V2", "Flydream V3"};
static const QStringList STR_SUBTYPE_HITEC {"Optima", "Optima Hub Telem", "Minima"}; 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_BUGS_MINI {"Standard", "Bugs 3H"};
static const QStringList STR_SUBTYPE_E01X {"E012", "E015", "E016H"}; static const QStringList STR_SUBTYPE_E01X {"E012", "E015", "E016H"};
static const QStringList STR_SUBTYPE_GD00X {"GD V1", "GD V2"}; static const QStringList STR_SUBTYPE_GD00X {"GD V1", "GD V2"};
static const QStringList STR_SUBTYPE_REDPINE {"Fast", "Slow"}; 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}; 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_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr},
{MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr}, {MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr},
{MODULE_SUBTYPE_MULTI_DSM2, 3, false, STR_SUBTYPE_DSM, 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_YD717, 4, false, STR_SUBTYPE_YD717, nullptr},
{MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr}, {MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr},
{MODULE_SUBTYPE_MULTI_SYMAX, 1, false, STR_SUBTYPE_SYMAX, 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_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, 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_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_E01X, 2, false, STR_SUBTYPE_E01X, nullptr},
{MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, nullptr}, {MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, nullptr},
{MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {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_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_POTENSIC, 1, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr},
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, NO_SUBTYPE, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr},
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, NO_SUBTYPE, nullptr}, {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr},
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION}, {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) // 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", "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", "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", "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) if (protocol == MM_RF_CUSTOM_SELECTED || custom)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -153,7 +153,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
setupSwitchType(17, ui->srLabel, ui->srName, ui->srType); setupSwitchType(17, ui->srLabel, ui->srName, ui->srType);
if (IS_TARANIS(board) && !IS_TARANIS_SMALL(board)) { if (IS_TARANIS(board) && !IS_TARANIS_SMALL(board)) {
ui->serialPortMode->setCurrentIndex(generalSettings.hw_uartMode); ui->serialPortMode->setCurrentIndex(generalSettings.auxSerialMode);
} }
else { else {
ui->serialPortMode->setCurrentIndex(0); ui->serialPortMode->setCurrentIndex(0);
@ -183,6 +183,18 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
ui->bluetoothWidget->hide(); 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)) { if (IS_HORUS_OR_TARANIS(board)) {
ui->filterEnable->setChecked(!generalSettings.jitterFilter); ui->filterEnable->setChecked(!generalSettings.jitterFilter);
} }
@ -277,6 +289,6 @@ void HardwarePanel::on_txVoltageCalibration_editingFinished()
void HardwarePanel::on_serialPortMode_currentIndexChanged(int index) void HardwarePanel::on_serialPortMode_currentIndexChanged(int index)
{ {
generalSettings.hw_uartMode = index; generalSettings.auxSerialMode = index;
emit modified(); 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 setWeight(int val);
void setMinimum(int min) {
mini = min;
}
void setMaximum(int max) {
maxi = max;
}
signals: signals:
void valueChanged(); 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) { if (spinbox->maximum() == 0) {
spinbox->setMinimum(-max * displayStep); spinbox->setMinimum(-max * displayStep);
gvarGroup->setMinimum(-max);
if (value < -max) { if (value < -max) {
value = -max; value = -max;
} }
} }
if (spinbox->minimum() == 0) { if (spinbox->minimum() == 0) {
spinbox->setMaximum(max * displayStep); spinbox->setMaximum(max * displayStep);
gvarGroup->setMaximum(max);
if (value > max) { if (value > max) {
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_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_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->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
} }
ui->trainerMode->setCurrentIndex(model.trainerMode); ui->trainerMode->setCurrentIndex(model.trainerMode);
@ -400,7 +400,7 @@ void ModulePanel::update()
else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M || else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M ||
protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO) protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO)
mask |= MASK_RX_NUMBER | MASK_ACCESS; 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; mask |= MASK_ANTENNA;
break; break;
case PULSES_LP45: case PULSES_LP45:
@ -486,16 +486,18 @@ void ModulePanel::update()
ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength)); ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength));
ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5); ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5);
// Antenna selection on Horus and xlite // Antenna mode on Horus and XLite
ui->label_antenna->setVisible(mask & MASK_ANTENNA); if (mask & MASK_ANTENNA) {
ui->antennaMode->setVisible(mask & MASK_ANTENNA); ui->antennaMode->clear();
if IS_HORUS_X12S(board) { ui->antennaMode->addItem(tr("Ask"), -1);
ui->antennaMode->setItemText(1,tr("Ext. + Int")); 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 { else {
ui->antennaMode->setItemText(1,tr("External")); ui->antennaLabel->hide();
ui->antennaMode->hide();
} }
ui->antennaMode->setCurrentIndex(module.pxx.external_antenna);
// R9M options // R9M options
ui->r9mPower->setVisible(mask & MASK_R9M); 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) void ModulePanel::on_r9mPower_currentIndexChanged(int index)
{ {
if (!lock && module.pxx.power != (unsigned 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++) { for (int i=0; i<potWarningCheckboxes.size(); i++) {
QCheckBox *checkbox = potWarningCheckboxes[i]; QCheckBox *checkbox = potWarningCheckboxes[i];
int index = checkbox->property("index").toInt(); int index = checkbox->property("index").toInt();
checkbox->setChecked(!model->potsWarningEnabled[index]); checkbox->setChecked(!model->potsWarnEnabled[index]);
checkbox->setDisabled(model->potsWarningMode == 0); checkbox->setDisabled(model->potsWarningMode == 0);
} }
lock = false; lock = false;
@ -1397,7 +1391,7 @@ void SetupPanel::potWarningToggled(bool checked)
{ {
if (!lock) { if (!lock) {
int index = sender()->property("index").toInt(); int index = sender()->property("index").toInt();
model->potsWarningEnabled[index] = !checked; model->potsWarnEnabled[index] = !checked;
updatePotWarnings(); updatePotWarnings();
emit modified(); emit modified();
} }

View file

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

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1042</width> <width>1075</width>
<height>375</height> <height>434</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -252,7 +252,7 @@
<item row="4" column="1"> <item row="4" column="1">
<layout class="QHBoxLayout" name="rx1Layout"> <layout class="QHBoxLayout" name="rx1Layout">
<property name="spacing"> <property name="spacing">
<number>-1</number> <number>6</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
@ -595,7 +595,7 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_antenna"> <widget class="QLabel" name="antennaLabel">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
@ -611,7 +611,7 @@
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="antennaMode"> <widget class="AutoComboBox" name="antennaMode">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -621,16 +621,6 @@
<property name="sizeAdjustPolicy"> <property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum> <enum>QComboBox::AdjustToContents</enum>
</property> </property>
<item>
<property name="text">
<string>Internal</string>
</property>
</item>
<item>
<property name="text">
<string>Ext. + Int.</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
@ -732,6 +722,26 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="2" column="0">
<widget class="QLabel" name="label_multiProtocol"> <widget class="QLabel" name="label_multiProtocol">
<property name="text"> <property name="text">
@ -775,6 +785,50 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="5" column="0">
<widget class="QLabel" name="label_failsafeMode"> <widget class="QLabel" name="label_failsafeMode">
<property name="maximumSize"> <property name="maximumSize">
@ -883,70 +937,6 @@
</item> </item>
</widget> </widget>
</item> </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"> <item row="7" column="0" colspan="2">
<spacer name="horizontalSpacer_3"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">
@ -1069,6 +1059,13 @@ QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; pad
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>AutoComboBox</class>
<extends>QComboBox</extends>
<header>autocombobox.h</header>
</customwidget>
</customwidgets>
<tabstops> <tabstops>
<tabstop>protocol</tabstop> <tabstop>protocol</tabstop>
<tabstop>channelsStart</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 S.PORT"), 0);
ui->telemetryProtocol->addItem(tr("FrSky D"), 1); ui->telemetryProtocol->addItem(tr("FrSky D"), 1);
if (IS_9XRPRO(firmware->getBoard()) || 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->addItem(tr("FrSky D (cable)"), 2);
} }
ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol); ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol);

View file

@ -223,7 +223,6 @@ QString ModelPrinter::printModule(int idx)
if (module.protocol == PULSES_PXX_R9M) { if (module.protocol == PULSES_PXX_R9M) {
str << printLabelValue(tr("Sub Type"), module.subTypeToString()); str << printLabelValue(tr("Sub Type"), module.subTypeToString());
str << printLabelValue(tr("RF Output Power"), module.powerValueToString(firmware)); 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++) { for (int i=0; i<board.getCapability(Board::Pots)+board.getCapability(Board::Sliders); i++) {
RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i); RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
if ((src.isPot(&genAryIdx) && generalSettings.isPotAvailable(genAryIdx)) || (src.isSlider(&genAryIdx) && generalSettings.isSliderAvailable(genAryIdx))) { 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); str += src.toString(&model, &generalSettings);
} }
} }

View file

@ -722,20 +722,22 @@ void TreeModel::refresh()
} }
int protocol; int protocol;
QString rxs; QString rxs;
for (unsigned j=0; j<CPN_MAX_MODULES; j++) { unsigned moduleIdx = 0;
protocol = model.moduleData[j].protocol; 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 // 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_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()) { if (!rxs.isEmpty()) {
rxs.append(", "); rxs.append(", ");
} }
unsigned mdlidx = model.moduleData[j].modelId; unsigned mdlidx = moduleData.modelId;
rxs.append(QString("%1").arg(uint(mdlidx), 2, 10, QChar('0'))); rxs.append(QString("%1").arg(uint(mdlidx), 2, 10, QChar('0')));
if (!isModelIdUnique(mdlidx)) { if (!isModelIdUnique(mdlidx, moduleIdx, protocol)) {
current->setHighlightRX(true); current->setHighlightRX(true);
} }
} }
moduleIdx++;
} }
current->setData(currentColumn++, rxs); current->setData(currentColumn++, rxs);
} }
@ -746,17 +748,15 @@ void TreeModel::refresh()
} }
} }
bool TreeModel::isModelIdUnique(unsigned modelIdx) bool TreeModel::isModelIdUnique(unsigned modelIdx, unsigned module, unsigned protocol)
{ {
int cnt = 0; int cnt = 0;
for (unsigned i=0; i<radioData->models.size(); i++) { for (auto const& model: radioData->models) {
ModelData & model = radioData->models[i];
if (!model.isEmpty()) { if (!model.isEmpty()) {
for (unsigned j=0; j<CPN_MAX_MODULES; j++) { const ModuleData& moduleData = model.moduleData[module];
if (model.moduleData[j].protocol != PULSES_OFF && model.moduleData[j].modelId == modelIdx) { if (moduleData.protocol == protocol && moduleData.modelId == modelIdx) {
if (++cnt > 1) { if (++cnt > 1) {
return false; return false;
}
} }
} }
} }

View file

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

View file

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

View file

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

View file

@ -223,7 +223,7 @@ void RadioOutputsWidget::setupGVarsDisplay()
QPalette::ColorRole bgrole = QPalette::AlternateBase; QPalette::ColorRole bgrole = QPalette::AlternateBase;
for (int fm=0; fm < fmodes; fm++) { for (int fm=0; fm < fmodes; fm++) {
QLabel * label = new QLabel(gvarsWidget); 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->setAlignment(Qt::AlignCenter);
label->setBackgroundRole(bgrole); label->setBackgroundRole(bgrole);
gvarsLayout->addWidget(label, 0, fm+1); gvarsLayout->addWidget(label, 0, fm+1);
@ -232,7 +232,7 @@ void RadioOutputsWidget::setupGVarsDisplay()
for (int gv=0; gv < gvars; gv++) { for (int gv=0; gv < gvars; gv++) {
bgrole = ((gv % 2) ? QPalette::Background : QPalette::AlternateBase); bgrole = ((gv % 2) ? QPalette::Background : QPalette::AlternateBase);
QLabel * label = new QLabel(gvarsWidget); 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->setAutoFillBackground(true);
label->setBackgroundRole(bgrole); label->setBackgroundRole(bgrole);
gvarsLayout->addWidget(label, gv+1, 0); gvarsLayout->addWidget(label, gv+1, 0);

View file

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

View file

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

View file

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

View file

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

View file

@ -86,7 +86,7 @@ void RleFile::EeFsCreate(uint8_t *eeprom, int size, Board::Type board, unsigned
} }
else { else {
eeFs = (EeFs *)eeprom; 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; eeFsBlockSize = 16;
eeFsLinkSize = 1; 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) if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND)
add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc )

View file

@ -10,12 +10,10 @@ TEST(Conversions, ConversionX9DPFrom22)
RadioData radioData; RadioData radioData;
Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x9d+.bin"); Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x9d+.bin");
ASSERT_EQ(true, store.load(radioData));
ASSERT_EQ(true, store.load(radioData)); ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings; const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func); EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param); EXPECT_EQ(20, settings.customFn[0].param);
@ -24,10 +22,16 @@ TEST(Conversions, ConversionX9DPFrom22)
const ModelData& model = radioData.models[0]; const ModelData& model = radioData.models[0];
EXPECT_STREQ("Test", model.name); EXPECT_STREQ("Test", model.name);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH,SWITCH_SA0), model.timers[0].mode); EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH, SWITCH_SA0), model.timers[0].mode);
EXPECT_EQ(80, model.mixData[0].weight); EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(900, model.limitData[0].max); // -100 EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight); 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(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]); EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name); 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); 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) TEST(Conversions, ConversionX7From22)
{ {
RadioData radioData; RadioData radioData;
@ -50,7 +108,7 @@ TEST(Conversions, ConversionX7From22)
ASSERT_EQ(true, store.load(radioData)); ASSERT_EQ(true, store.load(radioData));
const GeneralSettings& settings = radioData.generalSettings; const GeneralSettings& settings = radioData.generalSettings;
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func); EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param); EXPECT_EQ(20, settings.customFn[0].param);
@ -66,7 +124,7 @@ TEST(Conversions, ConversionX7From22)
EXPECT_EQ(80, model.expoData[0].weight); EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[4].srcRaw); EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[4].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[4].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[4].swtch);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type); EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Thr", model.inputNames[0]); EXPECT_STREQ("Thr", model.inputNames[0]);
@ -90,6 +148,48 @@ TEST(Conversions, ConversionX7From22)
EXPECT_EQ(RawSource(SOURCE_TYPE_SPECIAL,4), screen.body.lines[0].source[1]); 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) bool loadFile(QByteArray & filedata, const QString & filename)
{ {
@ -136,13 +236,13 @@ TEST(Conversions, ConversionX10From22)
EXPECT_STREQ("en", settings.ttsLanguage); EXPECT_STREQ("en", settings.ttsLanguage);
EXPECT_STREQ("model1.bin", settings.currModelFilename); EXPECT_STREQ("model1.bin", settings.currModelFilename);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), settings.customFn[0].swtch);
EXPECT_EQ(FuncLogs, settings.customFn[0].func); EXPECT_EQ(FuncLogs, settings.customFn[0].func);
EXPECT_EQ(20, settings.customFn[0].param); EXPECT_EQ(20, settings.customFn[0].param);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch);
EXPECT_EQ(FuncVolume, settings.customFn[1].func); EXPECT_EQ(FuncVolume, settings.customFn[1].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK,4+5+1).toValue(), settings.customFn[1].param); // RS EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_STREQ("Tes", settings.switchName[0]); EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]); EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
@ -163,21 +263,98 @@ TEST(Conversions, ConversionX10From22)
EXPECT_EQ(0, model.beepANACenter); EXPECT_EQ(0, model.beepANACenter);
EXPECT_EQ(80, model.mixData[0].weight); EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX 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_STICK, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[5].srcRaw); EXPECT_EQ(RawSource(SOURCE_TYPE_PPM, 0), model.mixData[5].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[5].swtch); EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[5].swtch);
EXPECT_EQ(900, model.limitData[0].max); // -100 EXPECT_EQ(900, model.limitData[0].max); // -100
EXPECT_EQ(80, model.expoData[0].weight); EXPECT_EQ(80, model.expoData[0].weight);
EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func); EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); // TR1 EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); // TR1
EXPECT_EQ(0, model.logicalSw[0].val2); EXPECT_EQ(0, model.logicalSw[0].val2);
EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,19*3).toValue(), model.logicalSw[1].val1); // TELE:20 EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY, 19*3).toValue(), model.logicalSw[1].val1); // TELE:20
EXPECT_EQ(20, model.logicalSw[1].val2); EXPECT_EQ(20, model.logicalSw[1].val2);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1).toValue(), model.logicalSw[1].andsw); EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1).toValue(), model.logicalSw[1].andsw);
EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type); EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type);
EXPECT_STREQ("Tes", model.flightModeData[0].name); EXPECT_STREQ("Tes", model.flightModeData[0].name);
EXPECT_EQ(10, model.flightModeData[0].gvars[0]); EXPECT_EQ(10, model.flightModeData[0].gvars[0]);
EXPECT_STREQ("Tes", model.gvarData[0].name); 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(PULSES_PXX_R9M, model.moduleData[1].protocol);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType); EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType);
EXPECT_STREQ("Rud", model.inputNames[0]); 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 class AppMessages
{ {
Q_DECLARE_TR_FUNCTIONS("AppMessages") Q_DECLARE_TR_FUNCTIONS("AppMessages")
public: public:
// These are used for saving "[don't] show this message again" user preferences. // These are used for saving "[don't] show this message again" user preferences.
enum MessageCodes { enum MessageCodes {

Binary file not shown.

View file

@ -320,7 +320,7 @@ local function fieldCommandLoad(field, data, offset)
field.status = data[offset] field.status = data[offset]
field.timeout = data[offset+1] field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2) field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then if field.status == 0 then
fieldPopup = nil fieldPopup = nil
end end
end end
@ -406,8 +406,7 @@ local function refreshNext()
local time = getTime() local time = getTime()
if fieldPopup then if fieldPopup then
if time > fieldTimeout then if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id } crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
crossfireTelemetryPush(0x2D, frame)
fieldTimeout = time + fieldPopup.timeout fieldTimeout = time + fieldPopup.timeout
end end
elseif time > fieldTimeout and not edit then elseif time > fieldTimeout and not edit then
@ -435,7 +434,7 @@ local function runDevicePage(event)
else else
return "crossfire.lua" return "crossfire.lua"
end 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) local field = getField(lineIndex)
if field.name then if field.name then
if field.type == 10 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 end
local TailFields = { 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, 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, 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 {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 if fields[1][5] == 2 then
lcd.drawBitmap(ImgTail, 252, 100) lcd.drawBitmap(ImgTail, 252, 100)
lcd.drawBitmap(ImgTailRud, 340, 100) lcd.drawBitmap(ImgTailRud, 340, 100)
drawMark(415, 150, "A") drawMark(415, 150, "C")
drawMark(380, 120, "C") drawMark(380, 120, "A")
drawMark(390, 185, "B") drawMark(390, 185, "B")
lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR) lcd.drawFilledRectangle(40, 122, 100, 30, CUSTOM_COLOR)
drawMark(152, 124, "A") drawMark(152, 124, "A")
@ -332,7 +332,7 @@ end
local lineIndex local lineIndex
local function drawNextLine(text, text2) local function drawNextLine(text, text2)
lcd.drawText(40, lineIndex, text, TEXT_COLOR) 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 lineIndex = lineIndex + 20
end end
@ -354,38 +354,35 @@ local function runConfigSummary(event)
lineIndex = 40 lineIndex = 40
-- motors -- motors
if(MotorFields[1][5] == 1) then if(MotorFields[1][5] == 1) then
drawNextLine("Motor chan :", MotorFields[2][5]) drawNextLine("Motor channel", MotorFields[2][5])
elseif (MotorFields[1][5] == 2) then
drawNextLine("Motor 1 chan :", MotorFields[2][5])
drawNextLine("Motor 2 chan :", MotorFields[3][5])
end end
-- ail -- ail
if(AilFields[1][5] == 1) then if(AilFields[1][5] == 1) then
drawNextLine("Aileron chan :",AilFields[2][5]) drawNextLine("Aileron channel",AilFields[2][5])
elseif (AilFields[1][5] == 2) then elseif (AilFields[1][5] == 2) then
drawNextLine("Aileron 1 chan :",AilFields[2][5]) drawNextLine("Aileron Right channel",AilFields[2][5])
drawNextLine("Aileron 2 chan :",AilFields[3][5]) drawNextLine("Aileron Left channel",AilFields[3][5])
end end
-- flaps -- flaps
if(FlapsFields[1][5] == 1) then if(FlapsFields[1][5] == 1) then
drawNextLine("Flaps chan :",FlapsFields[2][5]) drawNextLine("Flaps channel",FlapsFields[2][5])
elseif (FlapsFields[1][5] == 2) then elseif (FlapsFields[1][5] == 2) then
drawNextLine("Flaps 1 chan :",FlapsFields[2][5]) drawNextLine("Flaps Right channel",FlapsFields[2][5])
drawNextLine("Flaps 2 chan :",FlapsFields[3][5]) drawNextLine("Flaps Left channel",FlapsFields[3][5])
end end
-- tail -- tail
if(TailFields[1][5] == 0) then if(TailFields[1][5] == 0) then
drawNextLine("Elevator chan :",TailFields[2][5]) drawNextLine("Elevator channel",TailFields[2][5])
elseif (TailFields[1][5] == 1) then elseif (TailFields[1][5] == 1) then
drawNextLine("Elevator chan :",TailFields[2][5]) drawNextLine("Elevator channel",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5]) drawNextLine("Rudder channel",TailFields[3][5])
elseif (TailFields[1][5] == 2) then elseif (TailFields[1][5] == 2) then
drawNextLine("Elevator 1 chan :",TailFields[2][5]) drawNextLine("Elevator Right channel",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5]) drawNextLine("Rudder channel",TailFields[3][5])
drawNextLine("Elevator 2 chan :",TailFields[4][5]) drawNextLine("Elevator Left channel",TailFields[4][5])
elseif (TailFields[1][5] == 3) then elseif (TailFields[1][5] == 3) then
drawNextLine("V-Tail elevator :", TailFields[2][5]) drawNextLine("V-Tail Right", TailFields[2][5])
drawNextLine("V-Tail rudder :", TailFields[3][5]) drawNextLine("V-Tail Left", TailFields[3][5])
end end
local result = runFieldsPage(event) local result = runFieldsPage(event)
if(fields[1][5] == 1 and edit == false) then if(fields[1][5] == 1 and edit == false) then
@ -414,23 +411,20 @@ local function createModel(event)
-- motor -- motor
if(MotorFields[1][5] == 1) then if(MotorFields[1][5] == 1) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor") 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 end
-- Ailerons -- Ailerons
if(AilFields[1][5] == 1) then if(AilFields[1][5] == 1) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail") addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif (AilFields[1][5] == 2) then elseif (AilFields[1][5] == 2) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL") addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100) addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
end end
-- Flaps -- Flaps
if(FlapsFields[1][5] == 1) then if(FlapsFields[1][5] == 1) then
addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps") addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps")
elseif (FlapsFields[1][5] == 2) then elseif (FlapsFields[1][5] == 2) then
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsL") addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsR") addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsL")
end end
-- Tail -- Tail
if(TailFields[1][5] == 0) then 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[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "Elev")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder") addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
elseif (TailFields[1][5] == 2) then 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[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 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(1), "V-EleR", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1) addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50) addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1) addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
end end
lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR) lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR)
lcd.drawText(100, 130, "Press RTN to exit", TEXT_COLOR) lcd.drawText(100, 130, "Press RTN to exit", TEXT_COLOR)

View file

@ -258,7 +258,7 @@ local function runFlapsConfig(event)
end end
local TailFields = { 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, 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, 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 {50, 207, COMBO, 0, 5, { "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8" } }, --ele2
@ -332,7 +332,7 @@ end
local lineIndex local lineIndex
local function drawNextLine(text, text2) local function drawNextLine(text, text2)
lcd.drawText(40, lineIndex, text, TEXT_COLOR) 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 lineIndex = lineIndex + 20
end end
@ -354,38 +354,35 @@ local function runConfigSummary(event)
lineIndex = 40 lineIndex = 40
-- motors -- motors
if(MotorFields[1][5] == 1) then if(MotorFields[1][5] == 1) then
drawNextLine("Motor chan :", MotorFields[2][5]) drawNextLine("Motor channel", MotorFields[2][5])
elseif (MotorFields[1][5] == 2) then
drawNextLine("Motor 1 chan :", MotorFields[2][5])
drawNextLine("Motor 2 chan :", MotorFields[3][5])
end end
-- ail -- ail
if(AilFields[1][5] == 1) then if(AilFields[1][5] == 1) then
drawNextLine("Aileron chan :",AilFields[2][5]) drawNextLine("Aileron channel",AilFields[2][5])
elseif (AilFields[1][5] == 2) then elseif (AilFields[1][5] == 2) then
drawNextLine("Aileron 1 chan :",AilFields[2][5]) drawNextLine("Aileron Right channel",AilFields[2][5])
drawNextLine("Aileron 2 chan :",AilFields[3][5]) drawNextLine("Aileron Left channel",AilFields[3][5])
end end
-- flaps -- flaps
if(FlapsFields[1][5] == 1) then if(FlapsFields[1][5] == 1) then
drawNextLine("Flaps chan :",FlapsFields[2][5]) drawNextLine("Flaps channel",FlapsFields[2][5])
elseif (FlapsFields[1][5] == 2) then elseif (FlapsFields[1][5] == 2) then
drawNextLine("Flaps 1 chan :",FlapsFields[2][5]) drawNextLine("Flaps Right channel",FlapsFields[2][5])
drawNextLine("Flaps 2 chan :",FlapsFields[3][5]) drawNextLine("Flaps Left channel",FlapsFields[3][5])
end end
-- tail -- tail
if(TailFields[1][5] == 0) then if(TailFields[1][5] == 0) then
drawNextLine("Elevator chan :",TailFields[2][5]) drawNextLine("Elevator channel",TailFields[2][5])
elseif (TailFields[1][5] == 1) then elseif (TailFields[1][5] == 1) then
drawNextLine("Elevator chan :",TailFields[2][5]) drawNextLine("Elevator channel",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5]) drawNextLine("Rudder channel",TailFields[3][5])
elseif (TailFields[1][5] == 2) then elseif (TailFields[1][5] == 2) then
drawNextLine("Elevator 1 chan :",TailFields[2][5]) drawNextLine("Elevator Right channel",TailFields[2][5])
drawNextLine("Rudder chan :",TailFields[3][5]) drawNextLine("Rudder channel",TailFields[3][5])
drawNextLine("Elevator 2 chan :",TailFields[4][5]) drawNextLine("Elevator Left channel",TailFields[4][5])
elseif (TailFields[1][5] == 3) then elseif (TailFields[1][5] == 3) then
drawNextLine("V-Tail elevator :", TailFields[2][5]) drawNextLine("V-Tail Right", TailFields[2][5])
drawNextLine("V-Tail rudder :", TailFields[3][5]) drawNextLine("V-Tail Left", TailFields[3][5])
end end
local result = runFieldsPage(event) local result = runFieldsPage(event)
if(fields[1][5] == 1 and edit == false) then if(fields[1][5] == 1 and edit == false) then
@ -414,23 +411,20 @@ local function createModel(event)
-- motor -- motor
if(MotorFields[1][5] == 1) then if(MotorFields[1][5] == 1) then
addMix(MotorFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(2), "Motor") 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 end
-- Ailerons -- Ailerons
if(AilFields[1][5] == 1) then if(AilFields[1][5] == 1) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail") addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif (AilFields[1][5] == 2) then elseif (AilFields[1][5] == 2) then
addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL") addMix(AilFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100) addMix(AilFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
end end
-- Flaps -- Flaps
if(FlapsFields[1][5] == 1) then if(FlapsFields[1][5] == 1) then
addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps") addMix(FlapsFields[2][5], MIXSRC_SA, "Flaps")
elseif (FlapsFields[1][5] == 2) then elseif (FlapsFields[1][5] == 2) then
addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsL") addMix(FlapsFields[2][5], MIXSRC_SA, "FlapsR")
addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsR") addMix(FlapsFields[3][5], MIXSRC_SA, "FlapsL")
end end
-- Tail -- Tail
if(TailFields[1][5] == 0) then 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[2][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "Elev")
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder") addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder")
elseif (TailFields[1][5] == 2) then 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[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 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(1), "V-EleR", 50)
addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", 50, 1) addMix(TailFields[2][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", 50, 1)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleR", 50) addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50)
addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudR", -50, 1) addMix(TailFields[3][5], MIXSRC_FIRST_INPUT+defaultChannel(0), "V-RudL", -50, 1)
end end
lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR) lcd.drawText(70, 90, "Model successfully created !", TEXT_COLOR)
lcd.drawText(100, 130, "Press RTN to exit", 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.status = data[offset]
field.timeout = data[offset+1] field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2) field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then if field.status == 0 then
fieldPopup = nil fieldPopup = nil
end end
end end
@ -401,8 +401,7 @@ local function refreshNext()
local time = getTime() local time = getTime()
if fieldPopup then if fieldPopup then
if time > fieldTimeout then if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id } crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
crossfireTelemetryPush(0x2D, frame)
fieldTimeout = time + fieldPopup.timeout fieldTimeout = time + fieldPopup.timeout
end end
elseif time > fieldTimeout and not edit then 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) local function drawNextLine(x, y, label, channel)
lcd.drawText(x, y, label, 0); lcd.drawText(x, y, label, 0);
lcd.drawText(x+48, y, ":", 0);
lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0) lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0)
y = y + 8 y = y + 8
if y > 50 then if y > 50 then
@ -327,12 +328,12 @@ local function drawConfirmationMenu()
lcd.drawText(48, 1, "Ready to go?", 0); lcd.drawText(48, 1, "Ready to go?", 0);
lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0) lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
if engineMode == 1 then if engineMode == 1 then
x, y = drawNextLine(x, y, "Thr:", thrCH1) x, y = drawNextLine(x, y, "Throttle", thrCH1)
end end
x, y = drawNextLine(x, y, "Ele L:", elevCH1) x, y = drawNextLine(x, y, "Elevon L", elevCH1)
x, y = drawNextLine(x, y, "Ele R:", elevCH2) x, y = drawNextLine(x, y, "Elevon R", elevCH2)
if rudderMode == 1 then if rudderMode == 1 then
drawNextLine(x, y, "Rudder:", rudCH1) drawNextLine(x, y, "Rudder", rudCH1)
end end
lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0); lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0) lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)

View file

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

View file

@ -429,6 +429,7 @@ end
-- Confirmation Menu -- Confirmation Menu
local function drawNextLine(x, y, label, channel) local function drawNextLine(x, y, label, channel)
lcd.drawText(x, y, label, 0); lcd.drawText(x, y, label, 0);
lcd.drawText(x+26, y, ":", 0);
lcd.drawSource(x+30, y, MIXSRC_CH1+channel, 0) lcd.drawSource(x+30, y, MIXSRC_CH1+channel, 0)
y = y + 8 y = y + 8
if y > 50 then if y > 50 then
@ -502,8 +503,8 @@ local function applySettings()
if aileronsMode == 1 then if aileronsMode == 1 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail") addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif aileronsMode == 2 then elseif aileronsMode == 2 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL") addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100) addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
end end
if flapsMode == 1 then if flapsMode == 1 then
addMix(flapsCH1, MIXSRC_SA, "Flap") addMix(flapsCH1, MIXSRC_SA, "Flap")
@ -519,9 +520,9 @@ local function applySettings()
end end
if tailMode == 3 then if tailMode == 3 then
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50) 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(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 else
if tailMode > 0 then if tailMode > 0 then
addMix(rudCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder") 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.status = data[offset]
field.timeout = data[offset+1] field.timeout = data[offset+1]
field.info, offset = fieldGetString(data, offset+2) field.info, offset = fieldGetString(data, offset+2)
if field.status < 2 or field.status > 3 then if field.status == 0 then
fieldPopup = nil fieldPopup = nil
end end
end end
@ -401,8 +401,7 @@ local function refreshNext()
local time = getTime() local time = getTime()
if fieldPopup then if fieldPopup then
if time > fieldTimeout then if time > fieldTimeout then
local frame = { deviceId, 0xEA, fieldPopup.id } crossfireTelemetryPush(0x2D, { deviceId, 0xEA, fieldPopup.id, 6 })
crossfireTelemetryPush(0x2D, frame)
fieldTimeout = time + fieldPopup.timeout fieldTimeout = time + fieldPopup.timeout
end end
elseif time > fieldTimeout and not edit then 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 if engineMode == 1 then
x, y = drawNextLine(x, y, "Throttle", thrCH1) x, y = drawNextLine(x, y, "Throttle", thrCH1)
end end
x, y = drawNextLine(x, y, "Elev L", elevCH1) x, y = drawNextLine(x, y, "Elevon L", elevCH1)
x, y = drawNextLine(x, y, "Elev R", elevCH2) x, y = drawNextLine(x, y, "Elevon R", elevCH2)
if rudderMode == 1 then if rudderMode == 1 then
drawNextLine(x, y, "Rudder:", rudCH1) drawNextLine(x, y, "Rudder", rudCH1)
end end
lcd.drawText(48, LCD_H-8, "Long [ENT] to confirm", 0); lcd.drawText(48, LCD_H-8, "Long [ENT] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 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 PITCH_PAGE = 2
local YAW_PAGE = 3 local YAW_PAGE = 3
local ARM_PAGE = 4 local ARM_PAGE = 4
local MODE_PAGE = 5 local BEEPER_PAGE = 5
local BEEPER_PAGE = 6 local MODE_PAGE = 6
local CONFIRMATION_PAGE = 7 local CONFIRMATION_PAGE = 7
-- Navigation variables -- Navigation variables
@ -340,6 +340,7 @@ end
-- Confirmation Menu -- Confirmation Menu
local function drawNextCHLine(x, y, label, channel) local function drawNextCHLine(x, y, label, channel)
lcd.drawText(x, y, label, 0); lcd.drawText(x, y, label, 0);
lcd.drawText(x+48, y, ":", 0);
lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0) lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0)
y = y + 8 y = y + 8
if y > 50 then if y > 50 then
@ -351,6 +352,7 @@ end
local function drawNextSWLine(x, y, label, switch) local function drawNextSWLine(x, y, label, switch)
lcd.drawText(x, y, label, 0); lcd.drawText(x, y, label, 0);
lcd.drawText(x+76, y, ":", 0);
lcd.drawText(x+80, y, switches[switch], 0) lcd.drawText(x+80, y, switches[switch], 0)
y = y + 8 y = y + 8
if y > 50 then if y > 50 then
@ -366,15 +368,15 @@ local function drawConfirmationMenu()
lcd.clear() lcd.clear()
lcd.drawText(48, 1, "Ready to go?", 0); lcd.drawText(48, 1, "Ready to go?", 0);
lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0) lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
x, y = drawNextCHLine(x, y, "Throttle:", thrCH1) x, y = drawNextCHLine(x, y, "Throttle", thrCH1)
x, y = drawNextCHLine(x, y, "Roll:", rollCH1) x, y = drawNextCHLine(x, y, "Roll", rollCH1)
x, y = drawNextCHLine(x, y, "Pitch:", pitchCH1) x, y = drawNextCHLine(x, y, "Pitch", pitchCH1)
x, y = drawNextCHLine(x, y, "Yaw:", yawCH1) x, y = drawNextCHLine(x, y, "Yaw", yawCH1)
x = 95 x = 95
y = 12 y = 12
x, y = drawNextSWLine(x, y, "Arm switch:", armSW1) 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, "Beeper switch:", beeperSW1) x, y = drawNextSWLine(x, y, "Mode switch", modeSW1)
lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0); lcd.drawText(48, LCD_H-8, "[Enter Long] to confirm", 0);
lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0) lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)
lcd.drawPixmap(LCD_W-18, 0, "confirm-tick.bmp") lcd.drawPixmap(LCD_W-18, 0, "confirm-tick.bmp")
@ -396,7 +398,7 @@ end
local function applySettings() local function applySettings()
model.defaultInputs() model.defaultInputs()
model.deleteMixes() 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(rollCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Roll")
addMix(yawCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Yaw") addMix(yawCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Yaw")
addMix(pitchCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "Pitch") addMix(pitchCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "Pitch")

View file

@ -509,8 +509,8 @@ local function applySettings()
if aileronsMode == 1 then if aileronsMode == 1 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail") addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "Ail")
elseif aileronsMode == 2 then elseif aileronsMode == 2 then
addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL") addMix(ailCH1, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilL", -100)
addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR", -100) addMix(ailCH2, MIXSRC_FIRST_INPUT+defaultChannel(3), "AilR")
end end
if flapsMode == 1 then if flapsMode == 1 then
addMix(flapsCH1, MIXSRC_SA, "Flaps") addMix(flapsCH1, MIXSRC_SA, "Flaps")
@ -526,9 +526,9 @@ local function applySettings()
end end
if tailMode == 3 then if tailMode == 3 then
addMix(eleCH1, MIXSRC_FIRST_INPUT+defaultChannel(1), "V-EleL", 50) 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(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 else
if tailMode > 0 then if tailMode > 0 then
addMix(rudCH1, MIXSRC_FIRST_INPUT+defaultChannel(0), "Rudder") 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(AUTOSWITCH "Automatic switch detection in menus" ON)
option(SEMIHOSTING "Enable debugger semihosting" OFF) option(SEMIHOSTING "Enable debugger semihosting" OFF)
option(JITTER_MEASURE "Enable ADC jitter measurement" 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) if(SDL_FOUND)
option(SIMU_AUDIO "Enable simulator audio." ON) option(SIMU_AUDIO "Enable simulator audio." ON)
endif() endif()
@ -232,8 +232,8 @@ if(JITTER_MEASURE)
add_definitions(-DJITTER_MEASURE) add_definitions(-DJITTER_MEASURE)
endif() endif()
if(WATCHDOG_DISABLED) if(WATCHDOG)
add_definitions(-DWATCHDOG_DISABLED) add_definitions(-DWATCHDOG)
endif() endif()
if(SIMU_AUDIO) if(SIMU_AUDIO)

View file

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

View file

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

View file

@ -191,8 +191,8 @@ enum TrainerMode {
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
#endif
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
#endif
#if defined(BLUETOOTH) #if defined(BLUETOOTH)
TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_MASTER_BLUETOOTH,
TRAINER_MODE_SLAVE_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH,
@ -482,7 +482,6 @@ enum SwitchSources {
SWSRC_SR2, SWSRC_SR2,
#endif #endif
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
SWSRC_ID0 = SWSRC_FIRST_SWITCH, SWSRC_ID0 = SWSRC_FIRST_SWITCH,
SWSRC_ID1, SWSRC_ID1,
@ -501,7 +500,7 @@ enum SwitchSources {
#if NUM_XPOTS > 0 #if NUM_XPOTS > 0
SWSRC_FIRST_MULTIPOS_SWITCH, 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 #endif
SWSRC_FIRST_TRIM, SWSRC_FIRST_TRIM,

View file

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

View file

@ -41,7 +41,7 @@ void loadFonts();
extern const unsigned char font_5x7[]; extern const unsigned char font_5x7[];
extern const unsigned char font_10x14[]; extern const unsigned char font_10x14[];
#if defined(BOLD_FONT) && !defined(BOOT) #if defined(BOLD_FONT) && !defined(BOOT)
#define BOLD_SPECIFIC_FONT #define BOLD_SPECIFIC_FONT
extern const unsigned char font_5x7_B[]; extern const unsigned char font_5x7_B[];
#endif #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); memset(dest, 0, BITMAP_BUFFER_SIZE(w, h) - 2);
uint8_t rowSize = (w + 7) / 8; uint8_t rowSize;
switch (depth) { switch (depth) {
case 1: case 1:
rowSize = ((w + 31) / 32) * 4;
for (int8_t i=h-1; i>=0; i--) { for (int8_t i=h-1; i>=0; i--) {
result = f_read(&bmpFile, buf, rowSize, &read); result = f_read(&bmpFile, buf, rowSize, &read);
if (result != FR_OK || read != rowSize) { if (result != FR_OK || read != rowSize) {

View file

@ -183,8 +183,7 @@ void title(const char * s);
title(name) title(name)
typedef int choice_t; 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, IsValueAvailable isValueAvailable = nullptr);
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);
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char * label, LcdFlags attr, event_t event); 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); 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() #define drawStatusLine()
#endif #endif
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(event_t event); void menuTextView(event_t event);
void pushMenuTextView(const char *filename); void pushMenuTextView(const char *filename);
void pushModelNotes(); void pushModelNotes();
void readModelNotes(); 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_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) #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; const uint8_t * q = img;
uint8_t w = *q++; uint8_t w = *q++;
uint8_t hb = ((*q++) + 7) / 8; uint8_t hb = ((*q++) + 7) / 8;
uint8_t yShift = y % 8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false); bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb; q += idx*w*hb;
for (uint8_t yb = 0; yb < hb; yb++) { for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[(y / 8 + yb) * LCD_W + x]; uint8_t *p = &displayBuf[(y / 8 + yb) * LCD_W + x];
for (coord_t i=0; i<w; i++){ for (coord_t i=0; i<w; i++){
uint8_t b = *q++;
uint8_t b = inv ? ~(*q++) : *q++;
if (p < DISPLAY_END) { 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) uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay)
{ {
lcdDrawTextAlignedLeft(y, str); 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); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX);
return delay; return delay;
} }

View file

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

View file

@ -22,6 +22,15 @@
#define MODELSEL_W LCD_W #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) void onModelSelectMenu(const char * result)
{ {
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
@ -45,13 +54,14 @@ void onModelSelectMenu(const char * result)
POPUP_WARNING(eeBackupModel(sub)); POPUP_WARNING(eeBackupModel(sub));
} }
else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { 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); POPUP_WARNING(STR_NO_MODELS_ON_SD);
}
} }
#endif #endif
else if (result == STR_DELETE_MODEL) { 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); SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR);
} }
#if defined(SDCARD) #if defined(SDCARD)
@ -68,14 +78,6 @@ void onModelSelectMenu(const char * result)
void menuModelSelect(event_t event) 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; 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)) { 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; _event_ = 0;

View file

@ -90,7 +90,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS, ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS,
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND, ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM, 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, ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA,
#endif #endif
ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE, 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 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) #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) #if defined(PCBX7) || defined(PCBX9LITE)
#define ANTENNA_ROW
#if defined(BLUETOOTH) #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)), #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 #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_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 #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PPM_PARAMS_ROW
#elif defined(PCBXLITES) #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_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_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 #define TRAINER_ROWS LABEL(Trainer), 0, IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), TRAINER_CHANNELS_ROW, TRAINER_PPM_PARAMS_ROW
#elif defined(PCBXLITE) #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_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 */ #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 #else
@ -274,7 +289,7 @@ void onBluetoothConnectMenu(const char * result)
INTERNAL_MODULE_CHANNELS_ROWS, \ 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_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 */ \ IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* RxNum */ \
ANTENNA_ROW \ EXTERNAL_ANTENNA_ROW \
IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* Failsafe */ \ IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* Failsafe */ \
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* Range check and Register buttons */ \ IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* Range check and Register buttons */ \
IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* Module options */ \ IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* Module options */ \
@ -285,16 +300,6 @@ void onBluetoothConnectMenu(const char * result)
#define INTERNAL_MODULE_ROWS #define INTERNAL_MODULE_ROWS
#endif #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) void menuModelSetup(event_t event)
{ {
int8_t old_editMode = s_editMode; int8_t old_editMode = s_editMode;
@ -372,6 +377,9 @@ void menuModelSetup(event_t event)
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) { if (event == EVT_ENTRY || event == EVT_ENTRY_UP) {
memclear(&reusableBuffer.moduleSetup, sizeof(reusableBuffer.moduleSetup)); memclear(&reusableBuffer.moduleSetup, sizeof(reusableBuffer.moduleSetup));
reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; 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)) #if (defined(DSM2) || defined(PXX))
@ -910,16 +918,16 @@ void menuModelSetup(event_t event)
if (isModuleR9MNonAccess(EXTERNAL_MODULE)) { if (isModuleR9MNonAccess(EXTERNAL_MODULE)) {
if (g_model.moduleData[EXTERNAL_MODULE].subType > MODULE_SUBTYPE_R9M_EU) { if (g_model.moduleData[EXTERNAL_MODULE].subType > MODULE_SUBTYPE_R9M_EU) {
POPUP_WARNING(STR_MODULE_PROTOCOL_FLEX_WARN_LINE1); 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 #if POPUP_LEVEL >= 3
else if (g_model.moduleData[EXTERNAL_MODULE].subType == MODULE_SUBTYPE_R9M_EU) { else if (g_model.moduleData[EXTERNAL_MODULE].subType == MODULE_SUBTYPE_R9M_EU) {
POPUP_WARNING(STR_R9M_PROTO_EU_WARN_LINE1); POPUP_WARNING(STR_MODULE_PROTOCOL_EU_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);
} }
else { else {
POPUP_WARNING(STR_R9M_PROTO_FCC_WARN_LINE1); POPUP_WARNING(STR_MODULE_PROTOCOL_FCC_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);
} }
#endif #endif
} }
@ -1379,20 +1387,23 @@ void menuModelSetup(event_t event)
} }
break; break;
#if defined(EXTERNAL_ANTENNA) #if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA: case ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA:
{ reusableBuffer.moduleSetup.antennaMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_ANTENNA, STR_ANTENNA_MODES,
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); reusableBuffer.moduleSetup.antennaMode == ANTENNA_MODE_PER_MODEL ? ANTENNA_MODE_INTERNAL : reusableBuffer.moduleSetup.antennaMode,
if (newAntennaSel != g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna && newAntennaSel == XJT_EXTERNAL_ANTENNA) { ANTENNA_MODE_INTERNAL, ANTENNA_MODE_EXTERNAL, attr, event,
POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onAntennaSwitchConfirm); [](int value) { return value != ANTENNA_MODE_PER_MODEL; });
const char * w = STR_ANTENNACONFIRM2; if (event && !s_editMode && reusableBuffer.moduleSetup.antennaMode != g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode) {
SET_WARNING_INFO(w, strlen(w), 0); if (reusableBuffer.moduleSetup.antennaMode == ANTENNA_MODE_EXTERNAL && !isExternalAntennaEnabled()) {
} POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onModelAntennaSwitchConfirm);
else { SET_WARNING_INFO(STR_ANTENNACONFIRM2, sizeof(TR_ANTENNACONFIRM2), 0);
g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna = newAntennaSel; }
else {
g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode = reusableBuffer.moduleSetup.antennaMode;
checkExternalAntenna();
}
} }
break; break;
}
#endif #endif
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS: case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS:

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