From 88841f63ca118f089331f3ebc9f547c743c5b68b Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 21 Dec 2015 23:32:23 +0100 Subject: [PATCH] Switch to CMake --- .travis.yml | 2 +- CMakeLists.txt | 21 + cmake/Bitmaps.cmake | 25 + .../src/cmake => cmake}/FindLupdate.cmake | 0 .../src/cmake => cmake}/FindPhonon.cmake | 0 {companion/src/cmake => cmake}/FindSdl.cmake | 0 .../src/cmake => cmake}/FindXercesC.cmake | 0 {companion/src/cmake => cmake}/FindXsd.cmake | 0 cmake/Macros.cmake | 38 ++ companion/src/CMakeLists.txt | 469 +++++++-------- companion/src/cmake/Macros.cmake | 38 -- .../firmwares/opentx/simulator/CMakeLists.txt | 139 +---- companion/src/mainwindow.cpp | 2 +- companion/src/mainwindow.h | 14 +- companion/src/modeledit/CMakeLists.txt | 6 +- companion/src/simulation/CMakeLists.txt | 2 +- radio/src/CMakeLists.txt | 569 ++++++++++++++++++ radio/src/Makefile | 22 +- radio/src/audio_arm.h | 1 + radio/src/bitmaps/9x/CMakeLists.txt | 4 + radio/src/bitmaps/horus/CMakeLists.txt | 12 + radio/src/bitmaps/taranis/CMakeLists.txt | 4 + radio/src/crc16.cpp | 2 + radio/src/debug.h | 10 +- radio/src/fonts/horus/font_dblsize.png | Bin 27740 -> 28101 bytes radio/src/fonts/horus/font_dblsize.specs | 2 +- radio/src/fonts/horus/font_midsize.png | Bin 20959 -> 20959 bytes radio/src/fonts/horus/font_smlsize.png | Bin 11541 -> 11541 bytes radio/src/fonts/horus/font_stdsize.png | Bin 17377 -> 17377 bytes radio/src/fonts/horus/font_tinsize.png | Bin 7451 -> 7451 bytes radio/src/fonts/horus/font_xxlsize.png | Bin 42906 -> 42906 bytes radio/src/gui/9x/menu_general.cpp | 30 - radio/src/gui/9x/menu_general_setup.cpp | 2 +- radio/src/gui/9x/popups.cpp | 4 + radio/src/gui/horus/bitmaps.cpp | 90 +-- radio/src/gui/horus/curves.cpp | 2 + radio/src/gui/horus/fonts.cpp | 24 +- radio/src/gui/horus/gui.h | 8 +- radio/src/gui/horus/lcd.cpp | 4 +- radio/src/gui/horus/menu_general.cpp | 53 -- .../src/gui/horus/menu_general_sdmanager.cpp | 1 + radio/src/gui/horus/menu_general_setup.cpp | 4 +- radio/src/gui/horus/menu_model.cpp | 80 +-- radio/src/gui/horus/menu_model_curves.cpp | 1 + .../src/gui/horus/menu_model_flightmodes.cpp | 3 +- .../src/gui/horus/menu_model_inputs_mixes.cpp | 1 + radio/src/gui/horus/menu_model_limits.cpp | 2 +- .../gui/horus/menu_model_logical_switches.cpp | 8 +- radio/src/gui/horus/menu_model_setup.cpp | 8 - radio/src/gui/horus/menus.h | 124 +++- radio/src/gui/horus/widgets.cpp | 6 +- radio/src/gui/taranis/gui.h | 25 +- radio/src/gui/taranis/menu_general.cpp | 64 -- .../gui/taranis/menu_general_sdmanager.cpp | 2 +- radio/src/gui/taranis/menu_general_setup.cpp | 2 +- radio/src/gui/taranis/menu_model.cpp | 87 +-- .../gui/taranis/menu_model_flightmodes.cpp | 2 +- radio/src/gui/taranis/menu_model_limits.cpp | 2 +- .../taranis/menu_model_logical_switches.cpp | 7 +- radio/src/gui/taranis/menus.h | 144 ++++- radio/src/gui/taranis/navigation.cpp | 2 +- radio/src/gui/taranis/popups.cpp | 4 + radio/src/gui/taranis/view_statistics.cpp | 2 +- radio/src/gui/taranis/widgets.cpp | 2 +- radio/src/lua/CMakeLists.txt | 12 + radio/src/lua/api_general.cpp | 7 +- radio/src/lua/lua_api.h | 11 +- radio/src/myeeprom.h | 5 +- radio/src/opentx.cpp | 13 +- radio/src/opentx.h | 3 +- radio/src/sdcard.cpp | 11 +- radio/src/sdcard.h | 8 +- radio/src/simu.cpp | 11 +- radio/src/storage/sdcard_raw.cpp | 4 - radio/src/storage/sdcard_raw.h | 24 + radio/src/targets/horus/board_horus.h | 4 +- radio/src/targets/horus/diskio.cpp | 5 +- radio/src/targets/horus/pulses_driver.cpp | 8 + radio/src/targets/horus/telemetry_driver.cpp | 2 - radio/src/targets/horus/usbd_cdc.cpp | 4 +- radio/src/targets/horus/usbd_desc.c | 6 +- radio/src/targets/simu/CMakeLists.txt | 11 + radio/src/targets/simu/simpgmspace.cpp | 2 +- radio/src/targets/taranis/board_taranis.h | 7 +- radio/src/targets/taranis/diskio.cpp | 6 +- radio/src/tasks_arm.cpp | 17 - radio/src/tasks_arm.h | 30 +- radio/src/telemetry/frsky.h | 4 +- radio/src/telemetry/telemetry.h | 4 + radio/src/thirdparty/Lua/src/lvm.c | 1 - radio/src/trainer_input.h | 8 +- radio/src/translations.h | 69 ++- radio/src/translations/CMakeLists.txt | 14 + radio/util/commit-tests.sh | 16 +- 94 files changed, 1553 insertions(+), 956 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmake/Bitmaps.cmake rename {companion/src/cmake => cmake}/FindLupdate.cmake (100%) rename {companion/src/cmake => cmake}/FindPhonon.cmake (100%) rename {companion/src/cmake => cmake}/FindSdl.cmake (100%) rename {companion/src/cmake => cmake}/FindXercesC.cmake (100%) rename {companion/src/cmake => cmake}/FindXsd.cmake (100%) create mode 100644 cmake/Macros.cmake delete mode 100644 companion/src/cmake/Macros.cmake create mode 100644 radio/src/CMakeLists.txt create mode 100644 radio/src/bitmaps/9x/CMakeLists.txt create mode 100644 radio/src/bitmaps/horus/CMakeLists.txt create mode 100644 radio/src/bitmaps/taranis/CMakeLists.txt create mode 100644 radio/src/lua/CMakeLists.txt create mode 100644 radio/src/targets/simu/CMakeLists.txt create mode 100644 radio/src/translations/CMakeLists.txt diff --git a/.travis.yml b/.travis.yml index 4b5ca6a54..ca3b3b153 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ install: script: - radio/util/commit-tests.sh - - mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug ../companion/src && cmake --build . + - mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DPCB=TARANIS .. && cmake --build . diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..23d414cad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +project(OpenTX) + +set(VERSION_MAJOR "2") +set(VERSION_MINOR "2") +set(VERSION_REVISION "0") +set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) +set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) +message(STATUS "OpenTX ${VERSION}") + +cmake_minimum_required(VERSION 2.8) + +set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio) +set(RADIO_SRC_DIRECTORY ${RADIO_DIRECTORY}/src) +set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) +include(Bitmaps) + +add_subdirectory(${RADIO_SRC_DIRECTORY}) +add_subdirectory(${COMPANION_SRC_DIRECTORY}) diff --git a/cmake/Bitmaps.cmake b/cmake/Bitmaps.cmake new file mode 100644 index 000000000..9702c8e0a --- /dev/null +++ b/cmake/Bitmaps.cmake @@ -0,0 +1,25 @@ +macro(add_bitmaps_target targetname filter width format) + file(GLOB bitmaps ${filter}) + foreach(bitmap ${bitmaps}) + get_filename_component(target ${bitmap} NAME_WE) + set(target ${target}.lbm) + add_custom_command( + OUTPUT ${target} + COMMAND python ${RADIO_DIRECTORY}/util/img2lbm.py ${bitmap} ${target} ${width} ${format} + DEPENDS ${bitmap} + ) + list(APPEND bitmaps_files ${target}) + endforeach() + add_custom_target(${targetname} DEPENDS ${bitmaps_files}) +endmacro(add_bitmaps_target) + +macro(add_truetype_font_target radio name font size) + set(target ${RADIO_SRC_DIRECTORY}/fonts/${radio}/font_${name}) + add_custom_command( + OUTPUT ${target}.png + OUTPUT ${target}.specs + COMMAND ${RADIO_DIRECTORY}/util/font2png.py ${font} ${size} False ${target} + WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY} + ) + add_custom_target(ttf_${radio}_${name} DEPENDS ${target}.png ${target}.specs) +endmacro(add_truetype_font_target) \ No newline at end of file diff --git a/companion/src/cmake/FindLupdate.cmake b/cmake/FindLupdate.cmake similarity index 100% rename from companion/src/cmake/FindLupdate.cmake rename to cmake/FindLupdate.cmake diff --git a/companion/src/cmake/FindPhonon.cmake b/cmake/FindPhonon.cmake similarity index 100% rename from companion/src/cmake/FindPhonon.cmake rename to cmake/FindPhonon.cmake diff --git a/companion/src/cmake/FindSdl.cmake b/cmake/FindSdl.cmake similarity index 100% rename from companion/src/cmake/FindSdl.cmake rename to cmake/FindSdl.cmake diff --git a/companion/src/cmake/FindXercesC.cmake b/cmake/FindXercesC.cmake similarity index 100% rename from companion/src/cmake/FindXercesC.cmake rename to cmake/FindXercesC.cmake diff --git a/companion/src/cmake/FindXsd.cmake b/cmake/FindXsd.cmake similarity index 100% rename from companion/src/cmake/FindXsd.cmake rename to cmake/FindXsd.cmake diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake new file mode 100644 index 000000000..4ca5ad9b4 --- /dev/null +++ b/cmake/Macros.cmake @@ -0,0 +1,38 @@ +macro(today RESULT) + if(WIN32) + execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(..)/(..)/(....).*" "\\1.\\2.\\3" ${RESULT} ${${RESULT}}) + elseif(UNIX) + execute_process(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(....)-(..)-(..).*" "\\1-\\2-\\3" ${RESULT} ${${RESULT}}) + else(WIN32) + message(SEND_ERROR "date not implemented") + set(${RESULT} 00.00.0000) + endif(WIN32) +endmacro(today) + +macro(now RESULT) + if(WIN32) + execute_process(COMMAND "cmd" " /C time /T" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(..):(..).*" "\\1:\\2:00" ${RESULT} ${${RESULT}}) + elseif(UNIX) + execute_process(COMMAND "date" "+%H:%M:%S" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(..):(..):(..).*" "\\1:\\2:\\3" ${RESULT} ${${RESULT}}) + else(WIN32) + message(SEND_ERROR "time not implemented") + set(${RESULT} 00:00:00) + endif(WIN32) +endmacro(now) + +macro(git_id RESULT) + if(WIN32) + execute_process(COMMAND "cmd" " /C git --git-dir=${PROJECT_SOURCE_DIR}/.git rev-parse HEAD" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}}) + elseif(UNIX) + execute_process(COMMAND "git" "--git-dir=${PROJECT_SOURCE_DIR}/.git" "rev-parse" "HEAD" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}}) + else(WIN32) + message(SEND_ERROR "Git ID implemented") + set(${RESULT} 0) + endif(WIN32) +endmacro(git_id) diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index cb27601d1..02efceffc 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -1,134 +1,121 @@ -PROJECT( companion ) - -SET(VERSION_MAJOR "2") -SET(VERSION_MINOR "2") -SET(VERSION_REVISION "0") -SET(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) - -SET(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) -SET(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) -MESSAGE(STATUS "OpenTX Companion ${VERSION}") - -CMAKE_MINIMUM_REQUIRED( VERSION 2.8.12 ) - -SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(Macros) -IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - SET(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR}) - SET(COMPANION_NAME "companion${C9X_NAME_SUFFIX}") - SET(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}") - SET( SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX} ) -ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - SET(COMPANION_NAME "companion") - SET(SIMULATOR_NAME "simulator") -ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR}) + set(COMPANION_NAME "companion${C9X_NAME_SUFFIX}") + set(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}") + set(SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX}) +else(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(COMPANION_NAME "companion") + set(SIMULATOR_NAME "simulator") +endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") -OPTION(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default -IF(ALLOW_NIGHTLY_BUILDS) - ADD_DEFINITIONS(-DALLOW_NIGHTLY_BUILDS) -ENDIF(ALLOW_NIGHTLY_BUILDS) +option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default +if(ALLOW_NIGHTLY_BUILDS) + add_definitions(-DALLOW_NIGHTLY_BUILDS) +endif(ALLOW_NIGHTLY_BUILDS) -OPTION(DEBUG_IMPORT "Turn on debug output for EEPROM import") # Disabled by default -IF(DEBUG_IMPORT) - ADD_DEFINITIONS( -DDEBUG_MODEL_IMPORT) - MESSAGE( STATUS "EEPROM import debugging enabled" ) -ENDIF(DEBUG_IMPORT) +option(DEBUG_IMPORT "Turn on debug output for EEPROM import") # Disabled by default +if(DEBUG_IMPORT) + add_definitions(-DDEBUG_MODEL_IMPORT) + message(STATUS "EEPROM import debugging enabled") +endif(DEBUG_IMPORT) -OPTION(TABLE_LAYOUT "Use QTableWidget for grid layouts") # Disabled by default -IF(TABLE_LAYOUT) - ADD_DEFINITIONS( -DTABLE_LAYOUT) - MESSAGE( STATUS "Using QTableWidget" ) -ENDIF(TABLE_LAYOUT) +option(TABLE_LAYOUT "Use QTableWidget for grid layouts") # Disabled by default +if(TABLE_LAYOUT) + add_definitions(-DTABLE_LAYOUT) + message(STATUS "Using QTableWidget") +endif(TABLE_LAYOUT) -MESSAGE( STATUS "Looking for XercesC " ) -FIND_PACKAGE(XercesC) -IF ( XERCESC_FOUND ) - INCLUDE_DIRECTORIES( ${XERCESC_INCLUDE_DIR} ) - SET(LidarFormat_LIBRAIRIES ${LidarFormat_LIBRAIRIES} ${XERCESC_LIBRARIES}) -ELSE() - MESSAGE( FATAL_ERROR "XercesC not found! Please set XercesC path ..." ) -ENDIF() +message(STATUS "Looking for XercesC ") +find_package(XercesC) +if(XERCESC_FOUND) + include_directories(${XERCESC_INCLUDE_DIR}) + set(LidarFormat_LIBRAIRIES ${LidarFormat_LIBRAIRIES} ${XERCESC_LIBRARIES}) +else() + message(FATAL_ERROR "XercesC not found! Please set XercesC path ...") +endif() -MESSAGE( STATUS "Looking for Xsd " ) -FIND_PACKAGE(Xsd) -IF ( XSD_FOUND ) - INCLUDE_DIRECTORIES( ${XSD_INCLUDE_DIR} ) - MESSAGE("XSD Include Path: " ${XSD_INCLUDE_DIR} ) -ELSE() - MESSAGE( FATAL_ERROR "XSD not found! Please set XSD path ..." ) -ENDIF() +message(STATUS "Looking for Xsd ") +find_package(Xsd) +if(XSD_FOUND) + include_directories(${XSD_INCLUDE_DIR}) + message("XSD Include Path: " ${XSD_INCLUDE_DIR}) +else() + message(FATAL_ERROR "XSD not found! Please set XSD path ...") +endif() -MESSAGE( STATUS "Looking for SDL " ) -FIND_PACKAGE(Sdl) -IF ( SDL_FOUND ) - INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} ) - MESSAGE("SDL Include Path: " ${SDL_INCLUDE_DIR} ) - ADD_DEFINITIONS( -DJOYSTICKS ) - ADD_DEFINITIONS( -DSIMU_AUDIO ) -ELSE() - MESSAGE( "SDL not found! Joysticks support will be disabled. Simulator audio will not work." ) -ENDIF() +message(STATUS "Looking for SDL ") +find_package(Sdl) +if(SDL_FOUND) + include_directories(${SDL_INCLUDE_DIR}) + message("SDL Include Path: " ${SDL_INCLUDE_DIR}) + add_definitions(-DJOYSTICKS) + add_definitions(-DSIMU_AUDIO) +else() + message("SDL not found! Joysticks support will be disabled. Simulator audio will not work.") +endif() -FIND_PACKAGE(Qt4 4.8.1 REQUIRED) -SET( QT_USE_QTNETWORK True ) -SET( QT_USE_QTXML True ) -INCLUDE( ${QT_USE_FILE} ) +find_package(Qt4 4.8.1 REQUIRED) +set(QT_USE_QTNETWORK True) +set(QT_USE_QTXML True) +include(${QT_USE_FILE}) -MESSAGE( STATUS "Looking for PHONON " ) -FIND_PACKAGE(Phonon) -IF ( PHONON_FOUND ) - INCLUDE_DIRECTORIES( ${PHONO_INCLUDE_DIR} ) - MESSAGE("PHONON Include Path: " ${PHONON_INCLUDE_DIR} ) - ADD_DEFINITIONS( -DPHONON ) -ELSE() - MESSAGE( "PHONON not found!" ) -ENDIF() +message(STATUS "Looking for PHONON ") +find_package(Phonon) +if(PHONON_FOUND) + include_directories(${PHONO_INCLUDE_DIR}) + message("PHONON Include Path: " ${PHONON_INCLUDE_DIR}) + add_definitions(-DPHONON) +else() + message("PHONON not found!") +endif() -MESSAGE( STATUS "Looking for QT lupdate " ) -FIND_PACKAGE(Lupdate) -if( LUPDATE_FOUND ) - MESSAGE( "QT lupdate: " ${LUPDATE_EXECUTABLE} ) -ELSE() - MESSAGE( "QT lupdate not found!" ) -ENDIF() +message(STATUS "Looking for QT lupdate ") +find_package(Lupdate) +if(LUPDATE_FOUND) + message("QT lupdate: " ${LUPDATE_EXECUTABLE}) +else() + message("QT lupdate not found!") +endif() -ADD_DEFINITIONS(-DQXT_STATIC) +add_definitions(-DQXT_STATIC) -ADD_CUSTOM_COMMAND( +add_custom_command( COMMAND ${XSDCXX_EXECUTABLE} cxx-tree --root-element-all --generate-serialization --output-dir ${PROJECT_BINARY_DIR}/ ${PROJECT_SOURCE_DIR}/radio.xsd OUTPUT ${PROJECT_BINARY_DIR}/radio.hxx ${PROJECT_BINARY_DIR}/radio.cxx DEPENDS ${PROJECT_SOURCE_DIR}/radio.xsd ) -IF( MSVC ) - SET(CMAKE_CXX_FLAGS "/EHsc /LD") +if(MSVC) + set(CMAKE_CXX_FLAGS "/EHsc /LD") set(INTTYPES_INCLUDE_OPTION -IC:/Programs/msinttypes) - INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/winbuild C:/Programs/pthreads/Pre-built.2/include C:/Programs/msinttypes) - LINK_DIRECTORIES( C:/Programs/pthreads/Pre-built.2/lib/ ) - SET( PTHREAD_LIBRARY pthreadVC2.lib ) -ELSE( ) - SET( PTHREAD_LIBRARY pthread ) - ADD_DEFINITIONS( -Wall ) - LINK_DIRECTORIES( /usr/local/lib ) -ENDIF( ) + include_directories(${PROJECT_SOURCE_DIR}/winbuild C:/Programs/pthreads/Pre-built.2/include C:/Programs/msinttypes) + link_directories(C:/Programs/pthreads/Pre-built.2/lib/) + set(PTHREAD_LIBRARY pthreadVC2.lib) +else() + set(PTHREAD_LIBRARY pthread) + add_definitions(-Wall) + link_directories(/usr/local/lib) +endif() -IF( MSVC ) - MESSAGE( STATUS "Adding include C:/Programs/dirent/include for dirent.h" ) - INCLUDE_DIRECTORIES( C:/Programs/dirent/include ) -ENDIF( ) +if(MSVC) + message(STATUS "Adding include C:/Programs/dirent/include for dirent.h") + include_directories(C:/Programs/dirent/include) +endif() -set(RADIO_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/../../radio/src) -set(SIMU_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/simulation) -set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}) +set(RADIO_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/radio/src) +set(SIMU_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src/simulation) +set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src) include_directories( + ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} - ${PROJECT_SOURCE_DIR}/../.. - ${PROJECT_SOURCE_DIR}/shared + ${COMPANION_SRC_DIRECTORY} + ${COMPANION_SRC_DIRECTORY}/shared ${SIMU_SRC_DIRECTORY} ${XSD_INCLUDE_DIR} - ${PROJECT_SOURCE_DIR}/qxtcommandoptions + ${COMPANION_SRC_DIRECTORY}/qxtcommandoptions ) add_subdirectory(shared) @@ -156,7 +143,7 @@ set(common_SRCS firmwares/opentx/opentxinterface.cpp file.cpp appdata.cpp -) + ) qt4_wrap_cpp(common_SRCS) @@ -201,7 +188,7 @@ set(companion_SRCS radionotfound.cpp wizarddata.cpp wizarddialog.cpp -) + ) set(companion_MOC_HDRS apppreferencesdialog.h @@ -233,7 +220,7 @@ set(companion_MOC_HDRS wizarddialog.h modelprinter.h multimodelprinter.h -) + ) set(companion_UIS mdichild.ui @@ -253,51 +240,51 @@ set(companion_UIS flashfirmwaredialog.ui flasheepromdialog.ui radionotfound.ui -) + ) set(companion_RCS companion.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc -) + ) -TODAY(DATE) -NOW(TIME) +today(DATE) +now(TIME) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc @ONLY) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY) +configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY) +configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc @ONLY) +configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY) +configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY) -IF( WIN32 ) - SET( companion_SRCS ${companion_SRCS} icon.rc ) - IF ( NOT MSVC ) - SET(CMAKE_EXE_LINKER_FLAGS -mwindows) - ENDIF( ) -ENDIF( ) +if(WIN32) + set(companion_SRCS ${companion_SRCS} icon.rc) + if(NOT MSVC) + set(CMAKE_EXE_LINKER_FLAGS -mwindows) + endif() +endif() -INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ) -INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ) +include_directories(${CMAKE_BINARY_DIR}) +include_directories(${CMAKE_SOURCE_DIR}) -SET( LANGUAGES he pl pt ru de fr es it sv cs fi nl) -FOREACH( language ${LANGUAGES} ) - SET( companion_TS ${companion_TS} translations/companion_${language}.ts ) -ENDFOREACH( language ) +set(LANGUAGES he pl pt ru de fr es it sv cs fi nl) +foreach(language ${LANGUAGES}) + set(companion_TS ${companion_TS} translations/companion_${language}.ts) +endforeach(language) -set( companion_SRCS ${companion_SRCS} ) -QT4_WRAP_UI( companion_SRCS ${companion_UIS} ) -QT4_WRAP_CPP( companion_SRCS ${companion_MOC_HDRS} ) -QT4_ADD_TRANSLATION( companion_QM ${companion_TS} ) -QT4_ADD_RESOURCES( companion_SRCS ${companion_RCS} ) +set(companion_SRCS ${companion_SRCS}) +qt4_wrap_ui(companion_SRCS ${companion_UIS}) +qt4_wrap_cpp(companion_SRCS ${companion_MOC_HDRS}) +qt4_add_translation(companion_QM ${companion_TS}) +qt4_add_resources(companion_SRCS ${companion_RCS}) -ADD_DEFINITIONS( -DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}" ) +add_definitions(-DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}") -IF( APPLE ) - ADD_EXECUTABLE( ${COMPANION_NAME} MACOSX_BUNDLE ${companion_SRCS} ${companion_QM} ) - # OS X compiler no longer automatically includes /Library/Frameworks in search path - SET( CMAKE_EXE_LINKER_FLAGS -F/Library/Frameworks ) -ELSE( ) - ADD_EXECUTABLE( ${COMPANION_NAME} WIN32 ${companion_SRCS} ${companion_QM} ) -ENDIF( ) +if(APPLE) + add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${companion_SRCS} ${companion_QM}) + # OS X compiler no longer automatically includes /Library/Frameworks in search path + set(CMAKE_EXE_LINKER_FLAGS -F/Library/Frameworks) +else() + add_executable(${COMPANION_NAME} WIN32 ${companion_SRCS} ${companion_QM}) +endif() target_link_libraries(${COMPANION_NAME} generaledit modeledit simulation common qcustomplot shared ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS}) @@ -307,14 +294,14 @@ set(simu_SRCS modeledit/node.cpp modeledit/edge.cpp # TODO not needed simulator.cpp -) + ) set(simu_MOC_HDRS modeledit/node.h -) + ) -set( simu_SRCS ${simu_SRCS} ) -qt4_wrap_cpp(simu_SRCS ${simu_MOC_HDRS} ) +set(simu_SRCS ${simu_SRCS}) +qt4_wrap_cpp(simu_SRCS ${simu_MOC_HDRS}) qt4_add_resources(simu_SRCS companion.qrc) # TODO not needed if(WIN32) @@ -331,136 +318,136 @@ target_link_libraries(${SIMULATOR_NAME} simulation common qxtcommandoptions ${QT ############# Packaging #################### -IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - INSTALL( TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) - INSTALL( TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) - INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop DESTINATION share/applications RENAME companion${C9X_NAME_SUFFIX}.desktop) - INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop DESTINATION share/applications RENAME simulator${C9X_NAME_SUFFIX}.desktop) - INSTALL( FILES images/linuxicons/16x16/companion.png DESTINATION /usr/share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/22x22/companion.png DESTINATION /usr/share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/24x24/companion.png DESTINATION /usr/share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/32x32/companion.png DESTINATION /usr/share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/48x48/companion.png DESTINATION /usr/share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/128x128/companion.png DESTINATION /usr/share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/256x256/companion.png DESTINATION /usr/share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/512x512/companion.png DESTINATION /usr/share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png ) - INSTALL( FILES images/linuxicons/scalable/companion.svg DESTINATION /usr/share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg ) - INSTALL( FILES ../targets/linux/45-companion-taranis.rules DESTINATION /lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules) - # Linux specific code - SET(OperatingSystem "Linux") -ELSE (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - INSTALL( TARGETS ${COMPANION_NAME} DESTINATION ${QT_BINARY_DIR} ) -ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop DESTINATION share/applications RENAME companion${C9X_NAME_SUFFIX}.desktop) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop DESTINATION share/applications RENAME simulator${C9X_NAME_SUFFIX}.desktop) + install(FILES images/linuxicons/16x16/companion.png DESTINATION /usr/share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/22x22/companion.png DESTINATION /usr/share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/24x24/companion.png DESTINATION /usr/share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/32x32/companion.png DESTINATION /usr/share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/48x48/companion.png DESTINATION /usr/share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/128x128/companion.png DESTINATION /usr/share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/256x256/companion.png DESTINATION /usr/share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/512x512/companion.png DESTINATION /usr/share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png) + install(FILES images/linuxicons/scalable/companion.svg DESTINATION /usr/share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg) + install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION /lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules) + # Linux specific code + set(OperatingSystem "Linux") +else(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + install(TARGETS ${COMPANION_NAME} DESTINATION ${QT_BINARY_DIR}) +endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") -IF( WIN32 ) - IF( MSVC ) - SET(COMPANION_NSI_IN_FILE companion-vs.nsi.in) - SET(SIMULATOR_NSI_IN_FILE simulator-vs.nsi.in) - ELSE( ) - SET(COMPANION_NSI_IN_FILE companion-msys.nsi.in) - SET(SIMULATOR_NSI_IN_FILE simulator-msys.nsi.in) - ENDIF( ) +if(WIN32) + if(MSVC) + set(COMPANION_NSI_IN_FILE companion-vs.nsi.in) + set(SIMULATOR_NSI_IN_FILE simulator-vs.nsi.in) + else() + set(COMPANION_NSI_IN_FILE companion-msys.nsi.in) + set(SIMULATOR_NSI_IN_FILE simulator-msys.nsi.in) + endif() - SET( SYSDIR "$ENV{windir}/system32" ) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${COMPANION_NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/companion.nsi @ONLY) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${SIMULATOR_NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/simulator.nsi @ONLY) + set(SYSDIR "$ENV{windir}/system32") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${COMPANION_NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/companion.nsi @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${SIMULATOR_NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/simulator.nsi @ONLY) - FIND_PROGRAM(NSIS_EXE makensis.exe PATHS + find_program(NSIS_EXE makensis.exe PATHS "C:/Program Files/NSIS" "C:/Program Files (x86)/NSIS" "C:/Programs/NSIS" - ) + ) - ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/companion-windows.exe - COMMAND "${NSIS_EXE}" ARGS companion.nsi - DEPENDS companion simulator opentx-simulators ${PROJECT_BINARY_DIR}/companion.nsi - COMMENT "Companion Windows NSIS Installer") + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/companion-windows.exe + COMMAND "${NSIS_EXE}" ARGS companion.nsi + DEPENDS companion simulator opentx-simulators ${PROJECT_BINARY_DIR}/companion.nsi + COMMENT "Companion Windows NSIS Installer") - ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/simulator-install.exe - COMMAND "${NSIS_EXE}" ARGS simulator.nsi - DEPENDS simulator opentx-simulators ${PROJECT_BINARY_DIR}/simulator.nsi - COMMENT "Simulator Windows NSIS Installer") + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/simulator-install.exe + COMMAND "${NSIS_EXE}" ARGS simulator.nsi + DEPENDS simulator opentx-simulators ${PROJECT_BINARY_DIR}/simulator.nsi + COMMENT "Simulator Windows NSIS Installer") - ADD_CUSTOM_TARGET( installer + add_custom_target(installer DEPENDS ${PROJECT_BINARY_DIR}/companion-windows.exe DEPENDS ${PROJECT_BINARY_DIR}/simulator-windows.exe SOURCES ${PROJECT_BINARY_DIR}/companion.nsi SOURCES ${PROJECT_BINARY_DIR}/simulator.nsi - ) -ENDIF( ) + ) +endif() -IF( APPLE ) - SET(MACOSX_BUNDLE_ICON_FILE iconmac.icns) - IF( CMAKE_GENERATOR STREQUAL Xcode ) - SET( WORK_DIR ${CMAKE_BINARY_DIR}/Debug ) - ELSE( ) - SET( WORK_DIR ${PROJECT_BINARY_DIR} ) - ENDIF() +if(APPLE) + set(MACOSX_BUNDLE_ICON_FILE iconmac.icns) + if(CMAKE_GENERATOR STREQUAL Xcode) + set(WORK_DIR ${CMAKE_BINARY_DIR}/Debug) + else() + set(WORK_DIR ${PROJECT_BINARY_DIR}) + endif() - ADD_CUSTOM_TARGET( addframeworks - COMMAND mkdir -p companion.app/Contents/Frameworks - COMMAND mkdir -p companion.app/Contents/Resources - COMMAND mkdir -p companion.app/Contents/translations - COMMAND rsync ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} companion.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE} # Copy the icon files - COMMAND rsync -r --exclude=.svn ${PROJECT_SOURCE_DIR}/../targets/mac/qt_menu.nib companion.app/Contents/Resources/ - COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations - COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations - COMMAND rsync -r ${XSD_INCLUDE_DIR}/.. companion.app/Contents/Frameworks/ - COMMAND rsync -r /Library/Frameworks/SDL.framework companion.app/Contents/Frameworks/ - COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app - COMMAND install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL companion.app/Contents/MacOS/companion - WORKING_DIRECTORY ${WORK_DIR} - DEPENDS ${COMPANION_NAME} ) + add_custom_target(addframeworks + COMMAND mkdir -p companion.app/Contents/Frameworks + COMMAND mkdir -p companion.app/Contents/Resources + COMMAND mkdir -p companion.app/Contents/translations + COMMAND rsync ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} companion.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE} # Copy the icon files + COMMAND rsync -r --exclude=.svn ${PROJECT_SOURCE_DIR}/../targets/mac/qt_menu.nib companion.app/Contents/Resources/ + COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations + COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations + COMMAND rsync -r ${XSD_INCLUDE_DIR}/.. companion.app/Contents/Frameworks/ + COMMAND rsync -r /Library/Frameworks/SDL.framework companion.app/Contents/Frameworks/ + COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app + COMMAND install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL companion.app/Contents/MacOS/companion + WORKING_DIRECTORY ${WORK_DIR} + DEPENDS ${COMPANION_NAME}) - ADD_CUSTOM_TARGET( makedmg - COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app -dmg -no-plugins - WORKING_DIRECTORY ${WORK_DIR} - DEPENDS addframeworks opentx-simulators-bundle) -ENDIF( ) + add_custom_target(makedmg + COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app -dmg -no-plugins + WORKING_DIRECTORY ${WORK_DIR} + DEPENDS addframeworks opentx-simulators-bundle) +endif() -ADD_CUSTOM_TARGET( stamp - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/version.h ${CMAKE_SOURCE_DIR}/../companion.stamp - DEPENDS ${CMAKE_BINARY_DIR}/version.h ) +add_custom_target(stamp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/version.h ${CMAKE_SOURCE_DIR}/../companion.stamp + DEPENDS ${CMAKE_BINARY_DIR}/version.h) -IF( LUPDATE_FOUND ) - ADD_CUSTOM_TARGET( translations +if(LUPDATE_FOUND) + add_custom_target(translations WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS} - ) -ELSE() - ADD_CUSTOM_TARGET( translations + ) +else() + add_custom_target(translations COMMAND echo "Sorry, QT lupdate was not found." - ) -ENDIF() + ) +endif() -SET(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}") -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTx open source firmware") +set(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTx open source firmware") string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE) # The file stripping is deliberately disabled, with the stripped file we get # very poor trace-backs from the users when they report Companion crash -SET(CPACK_STRIP_FILES FALSE) +set(CPACK_STRIP_FILES FALSE) find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") if(DPKG_PROGRAM) - SET(CPACK_GENERATOR "DEB") + set(CPACK_GENERATOR "DEB") execute_process( COMMAND ${DPKG_PROGRAM} --print-architecture OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE ) - SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}_${VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") - SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Bertrand Songis ") - SET(CPACK_DEBIAN_PACKAGE_VERSION ${VERSION}) - SET(CPACK_DEBIAN_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) - SET(CPACK_DEBIAN_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) - SET(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR)) - SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}_${VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Bertrand Songis ") + set(CPACK_DEBIAN_PACKAGE_VERSION ${VERSION}) + set(CPACK_DEBIAN_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) + set(CPACK_DEBIAN_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) + set(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR)) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) else(DPKG_PROGRAM) - SET(CPACK_GENERATOR "RPM") - SET(CPACK_RPM_PACKAGE_VERSION ${VERSION}) - SET(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) - SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}-${CMAKE_SYSTEM_PROCESSOR}") + set(CPACK_GENERATOR "RPM") + set(CPACK_RPM_PACKAGE_VERSION ${VERSION}) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}-${CMAKE_SYSTEM_PROCESSOR}") endif(DPKG_PROGRAM) -INCLUDE(CPack) +include(CPack) diff --git a/companion/src/cmake/Macros.cmake b/companion/src/cmake/Macros.cmake deleted file mode 100644 index a39618558..000000000 --- a/companion/src/cmake/Macros.cmake +++ /dev/null @@ -1,38 +0,0 @@ -MACRO (TODAY RESULT) - IF (WIN32) - EXECUTE_PROCESS(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(..)/(..)/(....).*" "\\1.\\2.\\3" ${RESULT} ${${RESULT}}) - ELSEIF(UNIX) - EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(....)-(..)-(..).*" "\\1-\\2-\\3" ${RESULT} ${${RESULT}}) - ELSE (WIN32) - MESSAGE(SEND_ERROR "date not implemented") - SET(${RESULT} 00.00.0000) - ENDIF (WIN32) -ENDMACRO (TODAY) - -MACRO (NOW RESULT) - IF (WIN32) - EXECUTE_PROCESS(COMMAND "cmd" " /C time /T" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(..):(..).*" "\\1:\\2:00" ${RESULT} ${${RESULT}}) - ELSEIF(UNIX) - EXECUTE_PROCESS(COMMAND "date" "+%H:%M:%S" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(..):(..):(..).*" "\\1:\\2:\\3" ${RESULT} ${${RESULT}}) - ELSE (WIN32) - MESSAGE(SEND_ERROR "time not implemented") - SET(${RESULT} 00:00:00) - ENDIF (WIN32) -ENDMACRO (NOW) - -MACRO (GIT_ID RESULT) - IF (WIN32) - EXECUTE_PROCESS(COMMAND "cmd" " /C git --git-dir=${PROJECT_SOURCE_DIR}/../../.git rev-parse HEAD" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}}) - ELSEIF(UNIX) - EXECUTE_PROCESS(COMMAND "git" "--git-dir=${PROJECT_SOURCE_DIR}/../../.git" "rev-parse" "HEAD" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}}) - ELSE (WIN32) - MESSAGE(SEND_ERROR "Git ID implemented") - SET(${RESULT} 0) - ENDIF (WIN32) -ENDMACRO (GIT_ID) diff --git a/companion/src/firmwares/opentx/simulator/CMakeLists.txt b/companion/src/firmwares/opentx/simulator/CMakeLists.txt index 50a62e6ab..27d229230 100644 --- a/companion/src/firmwares/opentx/simulator/CMakeLists.txt +++ b/companion/src/firmwares/opentx/simulator/CMakeLists.txt @@ -1,109 +1,30 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -set(RADIO_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/../../radio/src) - -macro(add_bitmaps_target targetname filter width format) - file(GLOB bitmaps ${filter}) - foreach(bitmap ${bitmaps}) - get_filename_component(target ${bitmap} NAME_WE) - get_filename_component(path ${bitmap} DIRECTORY) - set(target ${path}/${target}.lbm) - add_custom_command( - OUTPUT ${target} - COMMAND python ../util/img2lbm.py ${bitmap} ${target} ${width} ${format} - DEPENDS ${bitmap} - WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY} - ) - list(APPEND bitmaps_files ${target}) - endforeach() - add_custom_target(${targetname} DEPENDS ${bitmaps_files}) -endmacro(add_bitmaps_target) - -add_bitmaps_target(lbm_xbm_1bit ${RADIO_SRC_DIRECTORY}/bitmaps/*.xbm 128 1bit) -add_bitmaps_target(lbm_fonts_1bit ${RADIO_SRC_DIRECTORY}/fonts/std/*.png 128 "") -add_bitmaps_target(lbm_9x_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/9x/*.png 128 1bit) -add_bitmaps_target(lbm_taranis_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/taranis/*.png 212 4bits) - -add_dependencies(lbm_9x_bitmaps lbm_fonts_1bit lbm_xbm_1bit) -add_dependencies(lbm_taranis_bitmaps lbm_fonts_1bit lbm_xbm_1bit) - -macro(add_truetype_font_target radio name font size) - set(target ${RADIO_SRC_DIRECTORY}/fonts/${radio}/font_${name}) - add_custom_command( - OUTPUT ${target}.png - OUTPUT ${target}.specs - COMMAND ../util/font2png.py ${font} ${size} False ${target} - WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY} - ) - add_custom_target(ttf_${radio}_${name} DEPENDS ${target}.png ${target}.specs) -endmacro(add_truetype_font_target) - -add_truetype_font_target(horus tinsize "DejaVu Sans" 9) -add_truetype_font_target(horus smlsize "DejaVu Sans" 13) -add_truetype_font_target(horus stdsize "DejaVu Sans" 16) -add_truetype_font_target(horus midsize "DejaVu Sans" 24) -add_truetype_font_target(horus dblsize "DejaVu Sans" 32) -add_truetype_font_target(horus xxlsize "DejaVu Sans" 48) - -add_bitmaps_target(lbm_horus_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/????[^_]*.png" 480 5/6/5/8) -add_bitmaps_target(lbm_horus_masks ${RADIO_SRC_DIRECTORY}/bitmaps/horus/mask_*.png 480 8bits) -add_bitmaps_target(lbm_horus_fonts ${RADIO_SRC_DIRECTORY}/fonts/horus/*.png 480 8bits) -add_dependencies(lbm_horus_fonts ttf_horus_tinsize ttf_horus_smlsize ttf_horus_stdsize ttf_horus_midsize ttf_horus_dblsize ttf_horus_xxlsize) -add_dependencies(lbm_horus_bitmaps lbm_horus_masks lbm_horus_fonts) - -file(GLOB translations ${RADIO_SRC_DIRECTORY}/translations/*.h.txt) -foreach(translation ${translations}) - get_filename_component(language ${translation} NAME_WE) - get_filename_component(path ${translation} DIRECTORY) - set(target ${path}/${language}.h) - add_custom_command( - OUTPUT ${target} - COMMAND python ../util/translate.py ${translation} ${target} ${language} - DEPENDS ${translation} - WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY} - ) - list(APPEND translations_files ${target}) -endforeach() - -add_custom_target(firmware_translations DEPENDS ${translations_files}) - -TODAY(DATE) -NOW(TIME) -GIT_ID(GIT_STR) +today(DATE) +now(TIME) +git_id(GIT_STR) configure_file(${RADIO_SRC_DIRECTORY}/stamp.h.in ${RADIO_SRC_DIRECTORY}/stamp.h @ONLY) -macro(add_lua_export_target target) - add_custom_command( - OUTPUT ${RADIO_SRC_DIRECTORY}/lua/lua_exports_${target}.inc - COMMAND ${CMAKE_C_COMPILER} -E ${ARGN} -DEXPORT ${INTTYPES_INCLUDE_OPTION} myeeprom.h | grep LEXP > lua/lua_exports_${target}.txt - COMMAND python ../util/luaexport.py ${VERSION} lua/lua_exports_${target}.txt lua/lua_exports_${target}.inc lua/lua_fields_${target}.txt - WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY} - ) - add_custom_target(lua_export_${target} DEPENDS ${RADIO_SRC_DIRECTORY}/lua/lua_exports_${target}.inc) -endmacro(add_lua_export_target) - -add_lua_export_target(taranis -DPCBTARANIS -DLUA -DVIRTUALINPUTS) -add_lua_export_target(taranis_x9e -DPCBTARANIS -DREVPLUS -DREV9E -DLUA -DVIRTUALINPUTS) -add_lua_export_target(horus -DPCBHORUS -DLUA -DVIRTUALINPUTS) - set(OPENTX_SRC_FILES opentxsimulator.cpp -) + ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/firmwares/opentx + ${COMPANION_SRC_DIRECTORY}/firmwares/opentx ${RADIO_SRC_DIRECTORY} ${RADIO_SRC_DIRECTORY}/fonts/std + ${RADIO_BIN_DIRECTORY} ${RADIO_SRC_DIRECTORY}/lua/src ${RADIO_SRC_DIRECTORY}/thirdparty ${RADIO_SRC_DIRECTORY}/thirdparty/FatFs ${RADIO_SRC_DIRECTORY}/thirdparty/FatFs/option ${RADIO_SRC_DIRECTORY}/thirdparty/CoOS ${RADIO_SRC_DIRECTORY}/thirdparty/Lua/src + ${CMAKE_BINARY_DIR}/radio/src ) if(APPLE) @@ -119,21 +40,21 @@ endif() set(COMMON_DEFINITIONS ${COMMON_DEFINITIONS} - SUFFIX="${SUFFIX}" + SUFFIX="${SUFFIX}" HELI GVARS FLIGHT_MODES PPM_CENTER_ADJUSTABLE PPM_LIMITS_SYMETRICAL - OVERRIDE_CHANNEL_FUNCTION + OVERRIDE_CHANNEL_FUNCTION FAI_CHOICE -) + ) set(COMMON_LIBRARIES ${QT_LIBRARIES} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} -) + ) add_library(opentx-9x${SUFFIX}-simulator SHARED ${OPENTX_SRC_FILES}) add_library(opentx-9xr${SUFFIX}-simulator SHARED ${OPENTX_SRC_FILES}) @@ -149,7 +70,7 @@ add_library(opentx-taranisplus${SUFFIX}-simulator SHARED ${OPENTX_SRC_FILES}) add_library(opentx-taranisx9e${SUFFIX}-simulator SHARED ${OPENTX_SRC_FILES}) add_library(opentx-horus${SUFFIX}-simulator SHARED ${OPENTX_SRC_FILES}) -set(dependencies_9x lbm_9x_bitmaps firmware_translations stamp) +set(dependencies_9x 9x_bitmaps firmware_translations stamp) add_dependencies(opentx-9x${SUFFIX}-simulator ${dependencies_9x}) add_dependencies(opentx-9xr${SUFFIX}-simulator ${dependencies_9x}) add_dependencies(opentx-9x128${SUFFIX}-simulator ${dependencies_9x}) @@ -159,12 +80,12 @@ add_dependencies(opentx-mega2560${SUFFIX}-simulator ${dependencies_9x}) add_dependencies(opentx-sky9x${SUFFIX}-simulator ${dependencies_9x}) add_dependencies(opentx-9xrpro${SUFFIX}-simulator ${dependencies_9x}) add_dependencies(opentx-ar9x${SUFFIX}-simulator ${dependencies_9x}) -set(dependencies_taranis lbm_taranis_bitmaps firmware_translations stamp) +set(dependencies_taranis taranis_bitmaps firmware_translations stamp) add_dependencies(opentx-taranis${SUFFIX}-simulator ${dependencies_taranis} lua_export_taranis) add_dependencies(opentx-taranisplus${SUFFIX}-simulator ${dependencies_taranis} lua_export_taranis) add_dependencies(opentx-taranisx9e${SUFFIX}-simulator ${dependencies_taranis} lua_export_taranis_x9e) -add_dependencies(opentx-horus${SUFFIX}-simulator lbm_horus_bitmaps lbm_horus_fonts firmware_translations lua_export_horus) +add_dependencies(opentx-horus${SUFFIX}-simulator horus_bitmaps horus_fonts firmware_translations lua_export_horus) set(OPENTX_LIBRARIES opentx-9x${SUFFIX}-simulator @@ -180,80 +101,80 @@ set(OPENTX_LIBRARIES opentx-taranisplus${SUFFIX}-simulator opentx-taranisx9e${SUFFIX}-simulator opentx-horus${SUFFIX}-simulator -) + ) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") install(TARGETS ${OPENTX_LIBRARIES} LIBRARY DESTINATION ${SIMULATOR_LIB_PATH}) endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # 9X with ATmega64 -target_include_directories(opentx-9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x) +target_include_directories(opentx-9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-9x${SUFFIX}-simulator PRIVATE PCBSTD PCB9X CPUM64 EEPROM EEPROM_RLC ${COMMON_DEFINITIONS}) target_link_libraries(opentx-9x${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # 9XR with ATmega64 -target_include_directories(opentx-9xr${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x) +target_include_directories(opentx-9xr${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-9xr${SUFFIX}-simulator PRIVATE PCBSTD PCB9XR CPUM64 EEPROM EEPROM_RLC ${COMMON_DEFINITIONS}) target_link_libraries(opentx-9xr${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # 9X with ATmega128 -target_include_directories(opentx-9x128${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x) +target_include_directories(opentx-9x128${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-9x128${SUFFIX}-simulator PRIVATE PCBSTD PCB9X CPUM128 EEPROM EEPROM_RLC ${COMMON_DEFINITIONS}) target_link_libraries(opentx-9x128${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # 9XR with ATmega128 -target_include_directories(opentx-9xr128${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x) +target_include_directories(opentx-9xr128${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-9xr128${SUFFIX}-simulator PRIVATE PCBSTD PCB9XR CPUM128 EEPROM EEPROM_RLC ${COMMON_DEFINITIONS}) target_link_libraries(opentx-9xr128${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Gruvin9x -target_include_directories(opentx-gruvin9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/gruvin9x) +target_include_directories(opentx-gruvin9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/gruvin9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-gruvin9x${SUFFIX}-simulator PRIVATE PCBGRUVIN9X CPUM2560 EEPROM EEPROM_RLC VOICE SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-gruvin9x${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Mega2560 -target_include_directories(opentx-mega2560${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/mega2560) +target_include_directories(opentx-mega2560${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/mega2560 PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-mega2560${SUFFIX}-simulator PRIVATE PCBMEGA2560 CPUM2560 EEPROM EEPROM_RLC SDCARD ROTARY_ENCODERS=2 ${COMMON_DEFINITIONS}) target_link_libraries(opentx-mega2560${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Sky9x -target_include_directories(opentx-sky9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x) +target_include_directories(opentx-sky9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-sky9x${SUFFIX}-simulator PRIVATE PCBSKY9X CPUARM VOICE EEPROM SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-sky9x${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # 9XR-PRO -target_include_directories(opentx-9xrpro${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x) +target_include_directories(opentx-9xrpro${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-9xrpro${SUFFIX}-simulator PRIVATE PCBSKY9X REVX CPUARM VOICE EEPROM SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-9xrpro${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # AR9X -target_include_directories(opentx-ar9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x) +target_include_directories(opentx-ar9x${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/sky9x PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/9x) target_compile_definitions(opentx-ar9x${SUFFIX}-simulator PRIVATE PCBSKY9X AR9X CPUARM VOICE EEPROM SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-ar9x${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Taranis standard -target_include_directories(opentx-taranis${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis) +target_include_directories(opentx-taranis${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/taranis) target_compile_definitions(opentx-taranis${SUFFIX}-simulator PRIVATE PCBTARANIS CPUARM CPUSTM32 EEPROM EEPROM_RLC VOICE SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-taranis${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Taranis Plus -target_include_directories(opentx-taranisplus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis) +target_include_directories(opentx-taranisplus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/taranis) target_compile_definitions(opentx-taranisplus${SUFFIX}-simulator PRIVATE PCBTARANIS REVPLUS CPUARM CPUSTM32 EEPROM EEPROM_RLC VOICE SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-taranisplus${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Taranis X9E -target_include_directories(opentx-taranisx9e${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis) +target_include_directories(opentx-taranisx9e${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/taranis PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/taranis) target_compile_definitions(opentx-taranisx9e${SUFFIX}-simulator PRIVATE PCBTARANIS REVPLUS REV9E CPUARM CPUSTM32 STM32F40_41xxx EEPROM EEPROM_RLC VOICE SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-taranisx9e${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) # Horus -target_include_directories(opentx-horus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/horus) +target_include_directories(opentx-horus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/horus PRIVATE ${RADIO_SRC_DIRECTORY}/fonts/horus PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/horus) target_compile_definitions(opentx-horus${SUFFIX}-simulator PRIVATE PCBHORUS CPUARM CPUSTM32 STM32F40_41xxx COLORLCD VOICE SDCARD ${COMMON_DEFINITIONS}) target_link_libraries(opentx-horus${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES}) add_custom_target(opentx-simulators DEPENDS ${OPENTX_LIBRARIES} -) + ) if(APPLE) set(SIMULATOR_BUNDLES) @@ -269,7 +190,7 @@ if(APPLE) COMMAND pwd COMMAND cp lib${_file}.dylib companion.app/Contents/Resources/ DEPENDS ${_file} - ) + ) list(APPEND SIMULATOR_BUNDLES ${SIMULATOR_BUNDLE}) endforeach() add_custom_target(opentx-simulators-bundle DEPENDS ${SIMULATOR_BUNDLES}) diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 52e63ea80..76b276da4 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -822,7 +822,7 @@ void MainWindow::writeBackup() cd->exec(); } -int MainWindow::getFileType(const QString &fullFileName) +int MainWindow::getFileType(const QString & fullFileName) { if(QFileInfo(fullFileName).suffix().toUpper()=="HEX") return FILE_TYPE_HEX; if(QFileInfo(fullFileName).suffix().toUpper()=="BIN") return FILE_TYPE_BIN; diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h index ba4b7c760..14a7b9e2e 100644 --- a/companion/src/mainwindow.h +++ b/companion/src/mainwindow.h @@ -184,19 +184,19 @@ class MainWindow : public QMainWindow void updateLanguageActions(); void updateIconThemeActions(); - int getFileType(const QString &fullFileName); + int getFileType(const QString & fullFileName); QString Theme; QString ISize; - QString strippedName(const QString &fullFileName); + QString strippedName(const QString & fullFileName); MdiChild *activeMdiChild(); - QMdiSubWindow *findMdiChild(const QString &fileName); + QMdiSubWindow *findMdiChild(const QString & fileName); int getEpromVersion(QString fileName); - bool readEepromFromRadio(const QString &filename); - bool writeEepromToRadio(const QString &filename); - bool readFirmwareFromRadio(const QString &filename); - bool writeFirmwareToRadio(const QString &filename); + bool readEepromFromRadio(const QString & filename); + bool writeEepromToRadio(const QString & filename); + bool readFirmwareFromRadio(const QString & filename); + bool writeFirmwareToRadio(const QString & filename); QMdiArea *mdiArea; QSignalMapper *windowMapper; diff --git a/companion/src/modeledit/CMakeLists.txt b/companion/src/modeledit/CMakeLists.txt index bf2acb401..3f64a2c8a 100644 --- a/companion/src/modeledit/CMakeLists.txt +++ b/companion/src/modeledit/CMakeLists.txt @@ -1,4 +1,8 @@ -include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories( + ${CMAKE_SOURCE_DIR} + ${COMPANION_SRC_DIRECTORY} + ${CMAKE_CURRENT_BINARY_DIR} +) set(modeledit_NAMES modeledit diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index 8a6249219..c2de4c69f 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -48,8 +48,8 @@ endif() include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/../.. ${COMPANION_SRC_DIRECTORY} + ${COMPANION_SRC_DIRECTORY}/simulation ${RADIO_SRC_DIRECTORY}/fonts/std ) diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt new file mode 100644 index 000000000..8ad9495c3 --- /dev/null +++ b/radio/src/CMakeLists.txt @@ -0,0 +1,569 @@ +option(PCB "Radio type") +option(HELI "Heli menu" ON) +option(FLIGHT_MODES "Flight Modes" ON) +option(CURVES "Curves" ON) +option(GVARS "Global variables") +option(LUA "Lua scripts") +option(GUI "GUI enabled" ON) +option(SPLASH "Splash enabled" ON) +option(PPM_UNIT "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)" PERCENT_PREC0) +option(PPM_CENTER_ADJUSTABLE "PPM center adjustable" OFF) +option(PPM_LIMITS_SYMETRICAL "PPM limits symetrical" OFF) +option(OVERRIDE_CHANNEL_FUNCTION "OverrideChannel function available" OFF) +option(DANGEROUS_MODULE_FUNCTIONS "Dangerous module functions (RangeCheck / Bind / Module OFF, etc.) available" OFF) +option(FAI "Competition mode (no telemetry)" OFF) +option(AUTOSOURCE "Automatic source detection in menus" ON) +option(AUTOSWITCH "Automatic switch detection in menus" ON) + +set(OPT s) + +enable_language(ASM) + +set(THIRDPARTY_DIR thirdparty) +set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src) +set(COOS_DIR ${THIRDPARTY_DIR}/CoOS) +set(FATFS_DIR ${THIRDPARTY_DIR}/FatFs) +set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +add_subdirectory(translations) +add_subdirectory(bitmaps/9x) +add_subdirectory(bitmaps/taranis) +add_subdirectory(bitmaps/horus) +add_subdirectory(lua) + +set(FIRMWARE_DEPENDENCIES firmware_translations) + +if(PCB STREQUAL HORUS) + include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus) + set(CPU_TYPE STM32F4) + set(HSE_VALUE 12000000) + set(GUI_DIR horus) + set(TARGET_DIR horus) + set(SDCARD YES) + set(LINKER_SCRIPT targets/horus/stm32f4_flash.ld) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} horus_bitmaps) + set(LUA_EXPORT lua_export_horus) + add_definitions(-DFLAVOUR="horus") + add_definitions(-DPCBHORUS -DCOLORLCD -DSTM32F429_439xx) + add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK) + add_definitions(-DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DVARIO) + set(EEPROM SDCARD) + set(HAPTIC YES) + set(SRC ${SRC} bmp.cpp debug.cpp) + set(GUI_SRC + ${GUI_SRC} + curves.cpp + bitmaps.cpp + view_channels.cpp + view_about.cpp + view_text.cpp + view_telemetry.cpp # TODO remove it + ) + set(SRC ${SRC} targets/taranis/rtc_driver.cpp) + set(TARGET_SRC ${TARGET_SRC} board_horus.cpp) + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + sdio_sd.c + lcd_driver.cpp + delays.c + i2c_driver.cpp + usb_driver.c + pwr_driver.c + sdram_driver.c + led_driver.cpp + ) + set(STM32LIB_SRC + STM32F4xx_StdPeriph_Driver/src/misc.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fmc.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_ltdc.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma2d.c + ) +elseif(PCB STREQUAL TARANIS) + option(SHUTDOWN_CONFIRMATION "Shutdown confirmation" OFF) + option(LCD_DUAL_BUFFER "Dual LCD Buffer" OFF) + option(TARANIS_INTERNAL_PPM "Taranis internal module hack to output PPM" OFF) + if(PCBREV STREQUAL REV9E) + set(CPU_TYPE STM32F4) + set(LINKER_SCRIPT targets/taranis/stm32f4_flash.ld) + add_definitions(-DSTM32F40_41xxx -DEEPROM_VARIANT=32768) + add_definitions(-DREVPLUS -DREV9E) + add_definitions(-DFLAVOUR="taranis-x9e") + set(HAPTIC YES) + set(LUA_EXPORT lua_export_taranis_x9e) + elseif(PCBREV STREQUAL REVPLUS) + set(CPU_TYPE STM32F2) + set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) + add_definitions(-DEEPROM_VARIANT=0) + add_definitions(-DREVPLUS) + add_definitions(-DFLAVOUR="taranis-plus") + set(HAPTIC YES) + set(LUA_EXPORT lua_export_taranis) + else() + set(CPU_TYPE STM32F2) + set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) + add_definitions(-DEEPROM_VARIANT=0) + add_definitions(-DFLAVOUR="taranis") + set(HAPTIC NO) + set(LUA_EXPORT lua_export_taranis) + endif() + set(HSE_VALUE 12000000) + add_definitions(-DPCBTARANIS) + add_definitions(-DAUDIO -DVOICE -DRTCLOCK) + add_definitions(-DDBLKEYS -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DVARIO) + set(EEPROM EEPROM_RLC) + set(GUI_DIR taranis) + set(TARGET_DIR taranis) + set(SDCARD YES) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} taranis_bitmaps) + set(SRC ${SRC} bmp.cpp debug.cpp) + set(GUI_SRC ${GUI_SRC} menu_general_diagkeys.cpp menu_general_diaganas.cpp menu_general_hardware.cpp view_channels.cpp view_telemetry.cpp view_text.cpp view_about.cpp) + set(TARGET_SRC ${TARGET_SRC} board_taranis.cpp rtc_driver.cpp) + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + lcd_driver.cpp + delays.c + i2c_driver.cpp + usb_driver.c + pwr_driver.c + configure_pins.cpp + flash_driver.cpp + aspi.c + ) + if(LCD_DUAL_BUFFER) + add_definitions(-DLCD_DUAL_BUFFER) + endif() + if(TARANIS_INTERNAL_PPM) + add_definitions(-DTARANIS_INTERNAL_PPM) + endif() +else() + message(FATAL_ERROR "Unknown PCB '${PCB}'") +endif() + +if(CPU_TYPE STREQUAL STM32F4) + set(MCU cortex-m4) + set(CPU_FAMILY STM32) + set(STM32LIB_DIR ${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries) + include_directories(${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/inc) + include_directories(${STM32LIB_DIR}/CMSIS/Device/ST/STM32F4xx/Include) + include_directories(${STM32LIB_DIR}/CMSIS/include) + set(STM32LIB_SRC + ${STM32LIB_SRC} + CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f40_41xxx.s + ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} system_stm32f4xx.c) +endif() + +if(CPU_TYPE STREQUAL STM32F2) + set(MCU cortex-m3) + set(CPU_FAMILY STM32) + set(STM32LIB_DIR ${THIRDPARTY_DIR}/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries) + include_directories(${STM32LIB_DIR}/STM32F2xx_StdPeriph_Driver/inc) + include_directories(${STM32LIB_DIR}/CMSIS/Device/ST/STM32F2xx/Include) + include_directories(${STM32LIB_DIR}/CMSIS/include) + set(STM32LIB_SRC + ${STM32LIB_SRC} + CMSIS/Device/ST/STM32F2xx/Source/Templates/gcc_ride7/startup_stm32f2xx.s + STM32F2xx_StdPeriph_Driver/src/misc.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_gpio.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dbgmcu.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rcc.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_spi.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_i2c.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dma.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rtc.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_pwr.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_usart.c + ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} system_stm32f2xx.c) +endif() + +if(CPU_FAMILY STREQUAL STM32) + option(USB "USB option (JOYSTICK/MASSSTORAGE/SERIAL)" JOYSTICK) + set(ARCH ARM) + set(STM32USB_DIR ${THIRDPARTY_DIR}/STM32_USB-Host-Device_Lib_V2.1.0/Libraries) + add_definitions(-DCPUSTM32) + add_definitions(-DFRSKY -DFRSKY_SPORT -DFRSKY_HUB -DGPS -DPXX -DDSM2 -DSBUS -DCROSSFIRE) + include_directories(${STM32USB_DIR}/STM32_USB_OTG_Driver/inc) + include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Core/inc) + include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/msc/inc) + include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/hid/inc) + include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/cdc/inc) + set(STM32USB_SRC + STM32_USB_OTG_Driver/src/usb_core.c + STM32_USB_OTG_Driver/src/usb_dcd.c + STM32_USB_OTG_Driver/src/usb_dcd_int.c + STM32_USB_Device_Library/Core/src/usbd_core.c + STM32_USB_Device_Library/Core/src/usbd_ioreq.c + STM32_USB_Device_Library/Core/src/usbd_req.c + ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} usb_bsp.c usbd_desc.c usbd_usr.cpp) + if(${EEPROM} STREQUAL SDCARD) + set(SRC ${SRC} storage/storage_common.cpp storage/sdcard_raw.cpp) + elseif(${EEPROM} STREQUAL EEPROM_RLC) + set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp storage/eeprom_conversions.cpp) + add_definitions(-DEEPROM -DEEPROM_RLC) + else() + set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_raw.cpp storage/eeprom_conversions.cpp) + add_definitions(-DEEPROM) + endif() + if(USB STREQUAL SERIAL) + add_definitions(-DUSB_SERIAL) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} usbd_cdc.cpp) + set(STM32USB_SRC ${STM32USB_SRC} STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c) + elseif(USB STREQUAL MASSSTORAGE) + add_definitions(-DUSB_MASS_STORAGE) + set(STM32USB_SRC + ${STM32USB_SRC} + STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c + STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c + STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c + STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c + ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} usbd_storage_msd.cpp) + else() + add_definitions(-DUSB_JOYSTICK) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} usbd_hid_joystick.c) + endif() + set(FIRMWARE_SRC + ${FIRMWARE_SRC} + serial.cpp + ${FATFS_DIR}/ff.c + ${FATFS_DIR}/fattime.c + ${FATFS_DIR}/option/ccsbcs.c + ${COOS_DIR}/kernel/core.c + ${COOS_DIR}/kernel/hook.c + ${COOS_DIR}/kernel/task.c + ${COOS_DIR}/kernel/event.c + ${COOS_DIR}/kernel/time.c + ${COOS_DIR}/kernel/timer.c + ${COOS_DIR}/kernel/flag.c + ${COOS_DIR}/kernel/mutex.c + ${COOS_DIR}/kernel/serviceReq.c + ${COOS_DIR}/portable/GCC/port.c + ${COOS_DIR}/portable/arch.c + syscalls.c + targets/taranis/configure_pins.cpp + ) + foreach(FILE ${STM32LIB_SRC}) + set(FIRMWARE_SRC ${FIRMWARE_SRC} ${STM32LIB_DIR}/${FILE}) + endforeach() + foreach(FILE ${STM32USB_SRC}) + set(FIRMWARE_SRC ${FIRMWARE_SRC} ${STM32USB_DIR}/${FILE}) + endforeach() +endif() + +if(ARCH STREQUAL ARM) + option(TIMERS "Timers count" 2) + option(SPORT_FILE_LOG "S.PORT Logs on SD card" OFF) + option(TRACE_SD_CARD "SD Logs" OFF) + option(TRACE_FATFS "FatFS Logs" OFF) + option(TRACE_AUDIO "Audio Logs" OFF) + option(DEBUG_TRACE_BUFFER "Debug Trace Screen" OFF) + option(SUPPORT_D16_EU_ONLY "XJT module only supports D16-EU and LR12-EU" OFF) # TODO rename to XJT_EU_ONLY + if(TIMERS EQUAL 3) + add_definitions(-DTIMERS=3) + else() + add_definitions(-DTIMERS=2) + endif() + if(SPORT_FILE_LOG) + add_definitions(-DSPORT_FILE_LOG) + endif() + if(TRACE_SD_CARD) + add_definitions(-DTRACE_SD_CARD) + # DEBUG = YES + # DEBUG_TRACE_BUFFER = YES + endif() + if(TRACE_FATFS) + add_definitions(-DTRACE_FATFS) + # DEBUG = YES + # DEBUG_TRACE_BUFFER = YES + endif() + if(TRACE_AUDIO) + add_definitions(-DTRACE_AUDIO) + # DEBUG = YES + # DEBUG_TRACE_BUFFER = YES + endif() + if(DEBUG_TRACE_BUFFER) + add_definitions(-DDEBUG_TRACE_BUFFER) + endif() + if(SUPPORT_D16_EU_ONLY) + add_definitions(-DMODULE_D16_EU_ONLY_SUPPORT) + endif() + if(HAPTIC) + add_definitions(-DHAPTIC) + set(SRC ${SRC} haptic.cpp) + set(TARGET_SRC ${TARGET_SRC} haptic_driver.cpp) + endif() + add_definitions(-DCPUARM) + include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR}) + include_directories(${COOS_DIR} ${COOS_DIR}/kernel ${COOS_DIR}/portable) + foreach(LANGUAGE cz de en es fr it pt sk se pl hu) # TODO add nl + set(SRC ${SRC} translations/tts_${LANGUAGE}.cpp) + string(TOUPPER LANGUAGE_UPPER LANGUAGE) + if(TRANSLATIONS STREQUAL LANGUAGE_CAPITALIZED) + add_definitions(-DTRANSLATIONS_${LANGUAGE_UPPER}) + endif() + endforeach() + set(SRC + ${SRC} + main_arm.cpp + tasks_arm.cpp + audio_arm.cpp + sbus.cpp + telemetry/telemetry.cpp + telemetry/frsky.cpp + telemetry/frsky_d_arm.cpp + telemetry/frsky_sport.cpp + telemetry/telemetry.cpp + crc16.cpp + vario.cpp + ) + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + diskio.cpp + ) + set(TARGET_SRC + ${TARGET_SRC} + pulses_driver.cpp + keys_driver.cpp + adc_driver.cpp + trainer_driver.cpp + audio_driver.cpp + serial2_driver.cpp + telemetry_driver.cpp + ) + set(PULSES_SRC + pulses_arm.cpp + ppm_arm.cpp + pxx_arm.cpp + dsm2_arm.cpp + crossfire.cpp + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR}) + +if(NOT LUA STREQUAL OFF) + add_definitions(-DLUA) + include_directories(${LUA_DIR}) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${LUA_EXPORT}) + if(LUA STREQUAL ON) + add_definitions(-DLUA_MODEL_SCRIPTS) + set(GUI_SRC ${GUI_SRC} menu_model_custom_scripts.cpp) + endif() + set(SRC ${SRC} lua/interface.cpp lua/api_general.cpp lua/api_lcd.cpp lua/api_model.cpp) + set(LUA_SRC + lapi.c + lcode.c + lctype.c + ldebug.c + ldo.c + ldump.c + lfunc.c + lgc.c + llex.c + lmem.c + lobject.c + lopcodes.c + lparser.c + lstate.c + lstring.c + ltable.c + lrotable.c + ltm.c + lundump.c + lvm.c + lzio.c + lbaselib.c + linit.c + lmathlib.c + lbitlib.c + loadlib.c + lauxlib.c + ltablib.c + lcorolib.c + liolib.c + lstrlib.c + ) + foreach(FILE ${LUA_SRC}) + set(SRC ${SRC} ${LUA_DIR}/${FILE}) + endforeach() +endif() + +if(HELI) + add_definitions(-DHELI) + set(GUI_SRC ${GUI_SRC} menu_model_heli.cpp) +endif() + +if(FLIGHT_MODES) + add_definitions(-DFLIGHT_MODES) + set(GUI_SRC ${GUI_SRC} menu_model_flightmodes.cpp) +endif() + +if(CURVES) + add_definitions(-DCURVES) + set(GUI_SRC ${GUI_SRC} menu_model_curves.cpp) +endif() + +if(GVARS) + add_definitions(-DGVARS) + set(GUI_SRC ${GUI_SRC} menu_model_gvars.cpp) +endif() + +if(FAI STREQUAL YES) + add_definitions(-DFAI) +elseif(FAI STREQUAL CHOICE) + add_definitions(-DFAI_CHOICE) +endif() + +if(AUTOSOURCE) + add_definitions(-DAUTOSOURCE) +endif() + +if(AUTOSWITCH) + add_definitions(-DAUTOSWITCH) +endif() + +if(SDCARD STREQUAL YES) + add_definitions(-DSDCARD) + set(SRC ${SRC} sdcard.cpp rtc.cpp logs.cpp) + set(GUI_SRC ${GUI_SRC} menu_general_sdmanager.cpp) + include_directories(${FATFS_DIR} ${FATFS_DIR}/option) +endif() + +if(SHUTDOWN_CONFIRMATION) + add_definitions(-DSHUTDOWN_CONFIRMATION) +endif() + +if(PPM_UNIT STREQUAL US) + add_definitions(-DPPM_UNIT_US) +elseif(PPM_UNIT STREQUAL PERCENT_PREC1) + add_definitions(-DPPM_UNIT_PERCENT_PREC1) +else() + add_definitions(-DPPM_UNIT_PERCENT_PREC0) +endif() + +if(PPM_CENTER_ADJUSTABLE) + add_definitions(-DPPM_CENTER_ADJUSTABLE) +endif() + +if(PPM_LIMITS_SYMETRICAL) + add_definitions(-DPPM_LIMITS_SYMETRICAL) +endif() + +if(OVERRIDE_CHANNEL_FUNCTION) + add_definitions(-DOVERRIDE_CHANNEL_FUNCTION) +endif() + +if(DANGEROUS_MODULE_FUNCTIONS) + add_definitions(-DDANGEROUS_MODULE_FUNCTIONS) +endif() + +set(GUI_SRC + ${GUI_SRC} + lcd.cpp + splash.cpp + fonts.cpp + helpers.cpp + navigation.cpp + popups.cpp + widgets.cpp + menus.cpp + ) + +set(GUI_SRC + ${GUI_SRC} + menu_model.cpp + menu_model_select.cpp + menu_model_setup.cpp + menu_model_inputs_mixes.cpp + menu_model_limits.cpp + menu_model_logical_switches.cpp + menu_model_custom_functions.cpp + menu_model_telemetry.cpp + menu_general.cpp + menu_general_setup.cpp + menu_general_trainer.cpp + menu_general_version.cpp + menu_general_calib.cpp + view_main.cpp + view_statistics.cpp + ) + +set(SRC + ${SRC} + opentx.cpp + functions.cpp + strhelpers.cpp + switches.cpp + curves.cpp + mixer.cpp + stamp.cpp + timers.cpp + trainer_input.cpp + ) + +if(SPLASH) + add_definitions(-DSPLASH) +endif() + +if(GUI) + add_definitions(-DGUI) + set(SRC + ${SRC} + keys.cpp + maths.cpp + translations.cpp + gui/gui_helpers.cpp + ) + foreach(FILE ${GUI_SRC}) + set(SRC ${SRC} gui/${GUI_DIR}/${FILE}) + endforeach() +endif() + +foreach(FILE ${TARGET_SRC}) + set(SRC ${SRC} targets/${TARGET_DIR}/${FILE}) +endforeach() + +foreach(FILE ${FIRMWARE_TARGET_SRC}) + set(FIRMWARE_SRC ${FIRMWARE_SRC} targets/${TARGET_DIR}/${FILE}) +endforeach() + +foreach(FILE ${PULSES_SRC}) + set(SRC ${SRC} pulses/${FILE}) +endforeach() + +add_subdirectory(targets/simu) + +include(CMakeForceCompiler) +cmake_force_c_compiler(arm-none-eabi-gcc GNU) +cmake_force_cxx_compiler(arm-none-eabi-gcc GNU) +set(CMAKE_ASM_COMPILER arm-none-eabi-as) + +set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_ASM_COMPILE_OBJECT " -o ") + +set(COMMON_FLAGS "-mcpu=${MCU} -mthumb -fomit-frame-pointer -fverbose-asm -Wa,-ahlms=opentx.lst -DRUN_FROM_FLASH=1 -O${OPT} -gdwarf-2 -DHSE_VALUE=${HSE_VALUE} -Wall -fno-exceptions -Wno-strict-aliasing -Wformat -Wreturn-type -Wunused -Wuninitialized -Wunknown-pragmas -Wno-switch -Wtype-limits -fdata-sections -ffunction-sections") +set(CMAKE_C_FLAGS "${COMMON_FLAGS} -Wimplicit") +set(CMAKE_CXX_FLAGS "${COMMON_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=opentx.map,--cref,--no-warn-mismatch,--gc-sections") + +add_executable(firmware ${SRC} ${FIRMWARE_SRC}) +add_dependencies(firmware ${FIRMWARE_DEPENDENCIES}) diff --git a/radio/src/Makefile b/radio/src/Makefile index dfd87b3d3..49fab6ca5 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -444,7 +444,7 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR)) OPT = s SDCARD = NO THR_TRACE = NO - INCDIRS += targets/9x + INCDIRS += targets/9x bitmaps bitmaps/9x CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM64 -DEEPROM -DEEPROM_RLC -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) BOARDSRC = main_avr.cpp targets/9x/board_stock.cpp EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/common_avr/telemetry_driver.cpp @@ -527,7 +527,7 @@ ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128)) THR_TRACE = NO EEPROM_VARIANT += ${M128_VARIANT} CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM128 -DEEPROM -DEEPROM_RLC -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) - INCDIRS += targets/9x + INCDIRS += targets/9x bitmaps bitmaps/9x BOARDSRC = main_avr.cpp targets/9x/board_stock.cpp EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/9x/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp @@ -602,7 +602,7 @@ ifeq ($(PCB), $(filter $(PCB), 9X2561)) THR_TRACE = YES EEPROM_VARIANT += ${M2561_VARIANT} CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM2561 -DEEPROM -DEEPROM_RLC -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) - INCDIRS += targets/9x + INCDIRS += targets/9x bitmaps bitmaps/9x BOARDSRC = main_avr.cpp targets/9x/board_stock.cpp EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/9x/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp @@ -675,7 +675,7 @@ ifeq ($(PCB), GRUVIN9X) SDCARD = NO BUZZER = NO THR_TRACE = YES - INCDIRS += targets/gruvin9x targets/9x $(FATFSDIR) $(FATFSDIR)/option + INCDIRS += targets/gruvin9x targets/9x bitmaps bitmaps/9x $(FATFSDIR) $(FATFSDIR)/option BOARDSRC = main_avr.cpp targets/gruvin9x/board_gruvin9x.cpp EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/9x/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp @@ -721,7 +721,7 @@ ifeq ($(PCB), MEGA2560) BUZZER = YES THR_TRACE = YES PWRMANAGE = NO - INCDIRS += targets/mega2560 targets/9x $(FATFSDIR) $(FATFSDIR)/option + INCDIRS += targets/mega2560 targets/9x bitmaps bitmaps/9x $(FATFSDIR) $(FATFSDIR)/option BOARDSRC = main_avr.cpp targets/mega2560/board_mega2560.cpp EEPROMSRC = storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp PULSESSRC = pulses/pulses_avr.cpp @@ -817,7 +817,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO AR9X)) ifeq ($(SPORT_FILE_LOG), YES) CPPDEFS += -DSPORT_FILE_LOG endif - INCDIRS += targets/sky9x $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable + INCDIRS += targets/sky9x bitmaps bitmaps/9x $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp BOARDSRC = main_arm.cpp targets/sky9x/board_sky9x.cpp EXTRABOARDSRC = targets/sky9x/lcd_driver.cpp @@ -935,7 +935,7 @@ ifeq ($(PCB), TARANIS) PPM_CENTER_ADJUSTABLE = YES DSM2 = PPM CPPDEFS += -DPCBTARANIS -DCPUARM -DCPUSTM32 -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DEEPROM -DEEPROM_RLC -DAUDIO -DPXX -DSBUS -DCROSSFIRE - INCDIRS += targets/taranis $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable + INCDIRS += targets/taranis bitmaps bitmaps/taranis $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable CPPDEFS += -DHSE_VALUE=12000000 ifeq ($(PCBREV), REV9E) STM32LIBPATH = $(THIRDPARTY)/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries @@ -1100,7 +1100,7 @@ ifeq ($(PCB), FLAMENCO) TIMERS = 2 CPPDEFS += -DTIMERS=$(TIMERS) CPPDEFS += -DPCBFLAMENCO -DCPUARM -DCPUSTM32 -DEEPROM -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DEEPROM_VARIANT=0 -DAUDIO -DPXX - INCDIRS += targets/flamenco $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable + INCDIRS += targets/flamenco bitmaps/flamenco $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable INCDIRS += $(STM32LIBPATH)/STM32F4xx_StdPeriph_Driver/inc $(STM32LIBPATH)/CMSIS/Device/ST/STM32F4xx/Include $(STM32LIBPATH)/CMSIS/include STM32USBPATH = $(THIRDPARTY)/STM32_USB-Host-Device_Lib_V2.1.0/Libraries INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc @@ -1223,7 +1223,7 @@ ifeq ($(PCB), HORUS) TIMERS = 2 CPPDEFS += -DTIMERS=$(TIMERS) CPPDEFS += -DPCBHORUS -DCPUARM -DCPUSTM32 -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DEEPROM_VARIANT=0 -DAUDIO -DPXX - INCDIRS += targets/horus $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable + INCDIRS += targets/horus bitmaps/horus fonts/horus $(THIRDPARTY) $(COOSDIR) $(COOSDIR)/kernel $(COOSDIR)/portable INCDIRS += $(STM32LIBPATH)/STM32F4xx_StdPeriph_Driver/inc $(STM32LIBPATH)/CMSIS/Device/ST/STM32F4xx/Include $(STM32LIBPATH)/CMSIS/include STM32USBPATH = $(THIRDPARTY)/STM32_USB-Host-Device_Lib_V2.1.0/Libraries INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc @@ -2026,7 +2026,7 @@ ifeq ($(SIMU_DISKIO), YES) endif simu: $(LUADEP) stamp.h allsimusrc.cpp Makefile simu.cpp targets/simu/simpgmspace.cpp *.h tra lbm eeprom.bin - g++ $(CPPFLAGS) $(SIMUCPPFLAGS) $(INCFLAGS) simu.cpp allsimusrc.cpp $(LUASRC) targets/simu/simpgmspace.cpp -MD $(SIMUDEFS) -O0 -o simu $(FOXINC) $(FOXLIB) $(AUDIOINC) $(AUDIOLIB) -pthread -fexceptions + gcc $(CPPFLAGS) $(SIMUCPPFLAGS) $(INCFLAGS) simu.cpp allsimusrc.cpp $(LUASRC) targets/simu/simpgmspace.cpp -MD $(SIMUDEFS) -O0 -o simu $(FOXINC) $(FOXLIB) $(AUDIOINC) $(AUDIOLIB) -pthread -fexceptions -lstdc++ -lm eeprom.bin: dd if=/dev/zero of=$@ bs=1 count=2048 @@ -2203,5 +2203,5 @@ gtest-all.o : $(GTEST_SRCS) GTEST_TESTS_SRCS = $(shell find tests/ -type f -name '*.cpp') gtests: allsimusrc.cpp $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp *.h tests/gtests.h gtest-all.o - g++ -std=gnu++0x $(CPPFLAGS) $(SIMUCPPFLAGS) allsimusrc.cpp $(LUASRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp ${INCFLAGS} -I$(GTEST_INCDIR) -I/usr/include/qt4 -o gtests -lpthread -MD -DSIMU -lQtCore -lQtGui gtest-all.o -fexceptions + gcc -std=gnu++0x $(CPPFLAGS) $(SIMUCPPFLAGS) allsimusrc.cpp $(LUASRC) $(GTEST_TESTS_SRCS) targets/simu/simpgmspace.cpp ${INCFLAGS} -I$(GTEST_INCDIR) -I/usr/include/qt4 -o gtests -lpthread -MD -DSIMU -lQtCore -lQtGui gtest-all.o -fexceptions -lstdc++ -lm diff --git a/radio/src/audio_arm.h b/radio/src/audio_arm.h index 6fe1d342a..16d94d2f8 100644 --- a/radio/src/audio_arm.h +++ b/radio/src/audio_arm.h @@ -358,6 +358,7 @@ enum AutomaticPromptsEvents { }; void pushPrompt(uint16_t prompt, uint8_t id=0); +void playModelName(); #define I18N_PLAY_FUNCTION(lng, x, ...) void lng ## _ ## x(__VA_ARGS__, uint8_t id) #define PLAY_FUNCTION(x, ...) void x(__VA_ARGS__, uint8_t id) diff --git a/radio/src/bitmaps/9x/CMakeLists.txt b/radio/src/bitmaps/9x/CMakeLists.txt new file mode 100644 index 000000000..862df0458 --- /dev/null +++ b/radio/src/bitmaps/9x/CMakeLists.txt @@ -0,0 +1,4 @@ +add_bitmaps_target(9x_xbm_1bit ${RADIO_SRC_DIRECTORY}/bitmaps/*.xbm 128 1bit) +add_bitmaps_target(9x_fonts_1bit ${RADIO_SRC_DIRECTORY}/fonts/std/*.png 128 "") +add_bitmaps_target(9x_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/9x/*.png 128 1bit) +add_dependencies(9x_bitmaps 9x_fonts_1bit 9x_xbm_1bit) diff --git a/radio/src/bitmaps/horus/CMakeLists.txt b/radio/src/bitmaps/horus/CMakeLists.txt new file mode 100644 index 000000000..2541fb9c9 --- /dev/null +++ b/radio/src/bitmaps/horus/CMakeLists.txt @@ -0,0 +1,12 @@ +add_truetype_font_target(horus tinsize "DejaVu Sans" 9) +add_truetype_font_target(horus smlsize "DejaVu Sans" 13) +add_truetype_font_target(horus stdsize "DejaVu Sans" 16) +add_truetype_font_target(horus midsize "DejaVu Sans" 24) +add_truetype_font_target(horus dblsize "DejaVu Sans" 32) +add_truetype_font_target(horus xxlsize "DejaVu Sans" 48) + +add_bitmaps_target(horus_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/????[^_]*.png" 480 5/6/5/8) +add_bitmaps_target(horus_masks ${RADIO_SRC_DIRECTORY}/bitmaps/horus/mask_*.png 480 8bits) +add_bitmaps_target(horus_fonts ${RADIO_SRC_DIRECTORY}/fonts/horus/*.png 480 8bits) +add_dependencies(horus_fonts ttf_horus_tinsize ttf_horus_smlsize ttf_horus_stdsize ttf_horus_midsize ttf_horus_dblsize ttf_horus_xxlsize) +add_dependencies(horus_bitmaps horus_masks horus_fonts) diff --git a/radio/src/bitmaps/taranis/CMakeLists.txt b/radio/src/bitmaps/taranis/CMakeLists.txt new file mode 100644 index 000000000..97f2f2f06 --- /dev/null +++ b/radio/src/bitmaps/taranis/CMakeLists.txt @@ -0,0 +1,4 @@ +add_bitmaps_target(taranis_xbm_1bit ${RADIO_SRC_DIRECTORY}/bitmaps/*.xbm 128 1bit) +add_bitmaps_target(taranis_fonts_1bit ${RADIO_SRC_DIRECTORY}/fonts/std/*.png 128 "") +add_bitmaps_target(taranis_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/taranis/*.png 212 4bits) +add_dependencies(taranis_bitmaps taranis_fonts_1bit taranis_xbm_1bit) \ No newline at end of file diff --git a/radio/src/crc16.cpp b/radio/src/crc16.cpp index 301b45760..37b861f0e 100644 --- a/radio/src/crc16.cpp +++ b/radio/src/crc16.cpp @@ -34,6 +34,8 @@ * */ +#include + /* CRC16 implementation according to CCITT standards */ static const unsigned short crc16tab[256]= { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, diff --git a/radio/src/debug.h b/radio/src/debug.h index db2591144..a0c67e3f4 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -49,10 +49,6 @@ #if defined(__cplusplus) extern "C" { #endif -uint8_t serial2TracesEnabled(); -#if defined(__cplusplus) -} -#endif #if defined(SIMU) typedef void (*traceCallbackFunc)(const char * text); @@ -61,13 +57,19 @@ void debugPrintf(const char * format, ...); #elif defined(DEBUG) && defined(CLI) && defined(USB_SERIAL) #define debugPrintf(...) do { if (cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0) #elif defined(DEBUG) && defined(CLI) +uint8_t serial2TracesEnabled(); #define debugPrintf(...) do { if (serial2TracesEnabled() && cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0) #elif defined(DEBUG) && defined(CPUARM) +uint8_t serial2TracesEnabled(); #define debugPrintf(...) do { if (serial2TracesEnabled()) serialPrintf(__VA_ARGS__); } while(0) #else #define debugPrintf(...) #endif +#if defined(__cplusplus) +} +#endif + #define TRACE(...) do { debugPrintf(__VA_ARGS__); debugPrintf("\r\n"); } while(0) #define DUMP(data, size) dump(data, size) #define TRACE_DEBUG(...) debugPrintf("-D- " __VA_ARGS__) diff --git a/radio/src/fonts/horus/font_dblsize.png b/radio/src/fonts/horus/font_dblsize.png index d617ab223b5a6e479dc575710c4d4f1f8e5b091b..2eb8ec6a2c454b44dd192e371b8bec41d1046d8d 100644 GIT binary patch literal 28101 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�)WCH&mEG-sx#;TAp3$?;2n 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 diff --git a/radio/src/fonts/horus/font_dblsize.specs b/radio/src/fonts/horus/font_dblsize.specs index 8129cf4ed..44eca3c72 100644 --- a/radio/src/fonts/horus/font_dblsize.specs +++ b/radio/src/fonts/horus/font_dblsize.specs @@ -1 +1 @@ -{ 0,4,14,28,54,76,110,139,146,160,173,193,217,228,242,251,266,289,310,331,352,375,397,420,441,464,487,497,508,532,556,580,598,613,641,665,689,715,736,757,783,808,818,832,859,880,910,935,963,987,1015,1040,1062,1087,1112,1140,1178,1206,1234,1258,1272,1287,1300,1324,1343,1356,1378,1401,1420,1443,1466,1484,1507,1529,1539,1553,1576,1586,1618,1640,1663,1686,1709,1726,1746,1764,1786,1810,1841,1865,1889,1909,1933,1936,1960,1988,2015,2033,2051,2074,2097,2120,2143,2171 } \ No newline at end of file +{ 0,4,11,23,49,68,99,124,130,141,152,171,195,204,216,223,237,257,275,294,313,334,353,373,392,412,432,440,449,473,497,521,537,550,575,595,618,641,660,677,702,723,730,742,764,782,807,828,854,873,899,921,941,965,987,1012,1045,1069,1093,1116,1127,1141,1151,1175,1196,1208,1227,1247,1265,1285,1305,1320,1340,1359,1365,1375,1395,1401,1431,1450,1470,1490,1510,1525,1543,1558,1577,1598,1625,1646,1667,1685,1709,1712,1736,1764,1791,1809,1827,1849,1871,1893,1915,1943 } \ No newline at end of file diff --git a/radio/src/fonts/horus/font_midsize.png b/radio/src/fonts/horus/font_midsize.png index f1bc88d935d21d241a0e5ad3ecc316ae3e7a7f25..bac14ea4e2e6b9ac43fa9030b5f7a23b627e43c5 100644 GIT binary patch delta 24 gcmcb=nDPE%#tBy3d`B1<_>M46)#j7l=sGJ90C5}$O8@`> delta 24 gcmcb=nDPE%#tBy3{D}+<{E3V!?3ZV5be$Cl0B$Y_l>h($ diff --git a/radio/src/fonts/horus/font_smlsize.png b/radio/src/fonts/horus/font_smlsize.png index 338e064bb5e48cb147f480a74f591cd2df68568e..c64e6b721ac6f658274d9acfa92529b6a01df262 100644 GIT binary patch delta 22 ecmbOlH8pC26*u1z1_r((j8nDwq&K==&;bBdCI>VC delta 22 ecmbOlH8pC26*qq(0|S2|;|lxbnHya%=l}pxI0t?J diff --git a/radio/src/fonts/horus/font_stdsize.png b/radio/src/fonts/horus/font_stdsize.png index 02cdc828424535f9d34eda0afecfe5089c12f5cf..53e33e02e7d672050a220009ec4e0ab649685cdb 100644 GIT binary patch delta 24 gcmaFZ&iJsMae@^$-w_4|z9WoNwfUqsy3TP10BpDj3jhEB delta 24 gcmaFZ&iJsMae@^$eM46)#j7l=o-2l0BlqUEC2ui delta 24 gcmbPro@v&3rU_Qu{D}+<{E3V!?3ZV5bPZh&0BL3jb^rhX diff --git a/radio/src/gui/9x/menu_general.cpp b/radio/src/gui/9x/menu_general.cpp index 89c8a8203..14fc042a2 100644 --- a/radio/src/gui/9x/menu_general.cpp +++ b/radio/src/gui/9x/menu_general.cpp @@ -36,36 +36,6 @@ #include "../../opentx.h" -#if defined(CPUARM) -extern LP_CONST LanguagePack czLanguagePack; -extern LP_CONST LanguagePack enLanguagePack; -extern LP_CONST LanguagePack esLanguagePack; -extern LP_CONST LanguagePack frLanguagePack; -extern LP_CONST LanguagePack deLanguagePack; -extern LP_CONST LanguagePack itLanguagePack; -extern LP_CONST LanguagePack plLanguagePack; -extern LP_CONST LanguagePack ptLanguagePack; -extern LP_CONST LanguagePack skLanguagePack; -extern LP_CONST LanguagePack seLanguagePack; -extern LP_CONST LanguagePack huLanguagePack; - -const LanguagePack * LP_CONST languagePacks[] = { - // alphabetical order - &czLanguagePack, - &deLanguagePack, - &enLanguagePack, - &esLanguagePack, - &frLanguagePack, - &huLanguagePack, - &itLanguagePack, - &plLanguagePack, - &ptLanguagePack, - &seLanguagePack, - &skLanguagePack, - NULL -}; -#endif - void menuGeneralSetup(uint8_t event); void menuGeneralSdManager(uint8_t event); void menuGeneralCustomFunctions(uint8_t event); diff --git a/radio/src/gui/9x/menu_general_setup.cpp b/radio/src/gui/9x/menu_general_setup.cpp index f0bb13a3e..f4aaa1a86 100644 --- a/radio/src/gui/9x/menu_general_setup.cpp +++ b/radio/src/gui/9x/menu_general_setup.cpp @@ -37,7 +37,7 @@ #include "../../opentx.h" const pm_uchar sticks[] PROGMEM = { -#include "../../bitmaps/sticks.lbm" +#include "sticks.lbm" }; #define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH) diff --git a/radio/src/gui/9x/popups.cpp b/radio/src/gui/9x/popups.cpp index 90689af67..cd02dce1f 100644 --- a/radio/src/gui/9x/popups.cpp +++ b/radio/src/gui/9x/popups.cpp @@ -69,6 +69,10 @@ void displayPopup(const pm_char * pstr) lcdRefresh(); } +const pm_uchar asterisk_lbm[] PROGMEM = { +#include "asterisk.lbm" +}; + void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SOUND_ARG) { lcdClear(); diff --git a/radio/src/gui/horus/bitmaps.cpp b/radio/src/gui/horus/bitmaps.cpp index 6667eaaab..f1d11b53c 100644 --- a/radio/src/gui/horus/bitmaps.cpp +++ b/radio/src/gui/horus/bitmaps.cpp @@ -41,23 +41,23 @@ */ const uint8_t LBM_TOPMENU_POLYGON[] = { -#include "../../bitmaps/horus/mask_topmenu_polygon.lbm" +#include "mask_topmenu_polygon.lbm" }; const uint8_t LBM_DOT[] = { -#include "../../bitmaps/horus/mask_dot.lbm" +#include "mask_dot.lbm" }; const uint8_t LBM_CURRENT_BG[] = { -#include "../../bitmaps/horus/mask_current_bg.lbm" +#include "mask_current_bg.lbm" }; const uint8_t LBM_CURRENT_SHADOW[] = { -#include "../../bitmaps/horus/mask_current_shadow.lbm" +#include "mask_current_shadow.lbm" }; const uint8_t LBM_CURRENT_DOT[] = { -#include "../../bitmaps/horus/mask_current_dot.lbm" +#include "mask_current_dot.lbm" }; /* @@ -65,35 +65,35 @@ const uint8_t LBM_CURRENT_DOT[] = { */ const uint8_t LBM_MAINVIEW_BACKGROUND[] = { -#include "../../bitmaps/horus/background.lbm" +#include "background.lbm" }; const uint8_t LBM_TOPMENU_OPENTX[] = { -#include "../../bitmaps/horus/mask_topmenu_opentx.lbm" +#include "mask_topmenu_opentx.lbm" }; const uint8_t LBM_TOPMENU_USB[] = { -#include "../../bitmaps/horus/mask_topmenu_usb.lbm" +#include "mask_topmenu_usb.lbm" }; const uint8_t LBM_HTRIM_FRAME[] = { -#include "../../bitmaps/horus/mask_htrim_frame.lbm" +#include "mask_htrim_frame.lbm" }; const uint8_t LBM_VTRIM_FRAME[] = { -#include "../../bitmaps/horus/mask_vtrim_frame.lbm" +#include "mask_vtrim_frame.lbm" }; const uint8_t LBM_TRIM_SHADOW[] = { -#include "../../bitmaps/horus/mask_trim_shadow.lbm" +#include "mask_trim_shadow.lbm" }; const uint8_t LBM_TIMER_BACKGROUND[] = { -#include "../../bitmaps/horus/mask_timer_bg.lbm" +#include "mask_timer_bg.lbm" }; const uint8_t LBM_RSCALE[] = { -#include "../../bitmaps/horus/mask_rscale.lbm" +#include "mask_rscale.lbm" }; /* @@ -101,31 +101,31 @@ const uint8_t LBM_RSCALE[] = { */ const uint8_t LBM_RADIO_ICON[] = { -#include "../../bitmaps/horus/mask_menu_radio.lbm" +#include "mask_menu_radio.lbm" }; const uint8_t LBM_RADIO_SETUP_ICON[] = { -#include "../../bitmaps/horus/mask_radio_setup.lbm" +#include "mask_radio_setup.lbm" }; const uint8_t LBM_SD_BROWSER_ICON[] = { -#include "../../bitmaps/horus/mask_sd_browser.lbm" +#include "mask_sd_browser.lbm" }; const uint8_t LBM_GLOBAL_FUNCTIONS_ICON[] = { -#include "../../bitmaps/horus/mask_global_functions.lbm" +#include "mask_global_functions.lbm" }; const uint8_t LBM_TRAINER_ICON[] = { -#include "../../bitmaps/horus/mask_trainer.lbm" +#include "mask_trainer.lbm" }; const uint8_t LBM_CALIBRATION_ICON[] = { -#include "../../bitmaps/horus/mask_calibration.lbm" +#include "mask_calibration.lbm" }; const uint8_t LBM_VERSION_ICON[] = { -#include "../../bitmaps/horus/mask_version.lbm" +#include "mask_version.lbm" }; const uint8_t * const LBM_RADIO_ICONS[] = { @@ -143,55 +143,55 @@ const uint8_t * const LBM_RADIO_ICONS[] = { */ const uint8_t LBM_MODEL_ICON[] = { -#include "../../bitmaps/horus/mask_menu_model.lbm" +#include "mask_menu_model.lbm" }; const uint8_t LBM_MODEL_SETUP_ICON[] = { -#include "../../bitmaps/horus/mask_model_setup.lbm" +#include "mask_model_setup.lbm" }; const uint8_t LBM_HELI_ICON[] = { -#include "../../bitmaps/horus/mask_heli.lbm" +#include "mask_heli.lbm" }; const uint8_t LBM_FLIGHT_MODES_ICON[] = { -#include "../../bitmaps/horus/mask_flight_modes.lbm" +#include "mask_flight_modes.lbm" }; const uint8_t LBM_INPUTS_ICON[] = { -#include "../../bitmaps/horus/mask_inputs.lbm" +#include "mask_inputs.lbm" }; const uint8_t LBM_MIXER_ICON[] = { -#include "../../bitmaps/horus/mask_mixer.lbm" +#include "mask_mixer.lbm" }; const uint8_t LBM_OUTPUTS_ICON[] = { -#include "../../bitmaps/horus/mask_outputs.lbm" +#include "mask_outputs.lbm" }; const uint8_t LBM_CURVES_ICON[] = { -#include "../../bitmaps/horus/mask_curves.lbm" +#include "mask_curves.lbm" }; const uint8_t LBM_GVARS_ICON[] = { -#include "../../bitmaps/horus/mask_gvars.lbm" +#include "mask_gvars.lbm" }; const uint8_t LBM_LOGICAL_SWITCHES_ICON[] = { -#include "../../bitmaps/horus/mask_logical_switches.lbm" +#include "mask_logical_switches.lbm" }; const uint8_t LBM_SPECIAL_FUNCTIONS_ICON[] = { -#include "../../bitmaps/horus/mask_special_functions.lbm" +#include "mask_special_functions.lbm" }; const uint8_t LBM_LUA_SCRIPTS_ICON[] = { -#include "../../bitmaps/horus/mask_lua_scripts.lbm" +#include "mask_lua_scripts.lbm" }; const uint8_t LBM_TELEMETRY_ICON[] = { -#include "../../bitmaps/horus/mask_telemetry.lbm" +#include "mask_telemetry.lbm" }; const uint8_t * const LBM_MODEL_ICONS[] = { @@ -217,31 +217,31 @@ const uint8_t * const LBM_MODEL_ICONS[] = { */ const uint8_t LBM_LIBRARY_ICON[] = { -#include "../../bitmaps/horus/mask_library.lbm" +#include "mask_library.lbm" }; const uint8_t LBM_LIBRARY_SLOT[] = { -#include "../../bitmaps/horus/mask_library_slot.lbm" +#include "mask_library_slot.lbm" }; const uint8_t LBM_LIBRARY_CURSOR[] = { -#include "../../bitmaps/horus/mask_library_category_index.lbm" +#include "mask_library_category_index.lbm" }; const uint8_t LBM_SCORE0[] = { -#include "../../bitmaps/horus/mask_library_score_0.lbm" +#include "mask_library_score_0.lbm" }; const uint8_t LBM_SCORE1[] = { -#include "../../bitmaps/horus/mask_library_score_1.lbm" +#include "mask_library_score_1.lbm" }; const uint8_t LBM_STAR0[] = { -#include "../../bitmaps/horus/mask_library_star_0.lbm" +#include "mask_library_star_0.lbm" }; const uint8_t LBM_STAR1[] = { -#include "../../bitmaps/horus/mask_library_star_1.lbm" +#include "mask_library_star_1.lbm" }; /* @@ -249,21 +249,21 @@ const uint8_t LBM_STAR1[] = { */ const uint8_t LBM_ASTERISK[] = { -#include "../../bitmaps/horus/asterisk.lbm" +#include "asterisk.lbm" }; const uint8_t LBM_POINT[] = { -#include "../../bitmaps/horus/mask_point.lbm" +#include "mask_point.lbm" }; const uint8_t LBM_CURVE_POINT[] = { -#include "../../bitmaps/horus/mask_cvpoint.lbm" +#include "mask_cvpoint.lbm" }; const uint8_t LBM_CURVE_POINT_CENTER[] = { -#include "../../bitmaps/horus/mask_cvpoint_center.lbm" +#include "mask_cvpoint_center.lbm" }; const uint8_t LBM_CURVE_COORD_SHADOW[] = { -#include "../../bitmaps/horus/mask_coord_shadow.lbm" +#include "mask_coord_shadow.lbm" }; diff --git a/radio/src/gui/horus/curves.cpp b/radio/src/gui/horus/curves.cpp index 63799a425..4782d2711 100644 --- a/radio/src/gui/horus/curves.cpp +++ b/radio/src/gui/horus/curves.cpp @@ -34,6 +34,8 @@ * */ +#include "../../opentx.h" + coord_t getCurveYCoord(FnFuncP fn, coord_t x) { return limit(0, CURVE_CENTER_Y - divRoundClosest(fn(divRoundClosest(x * RESX, CURVE_SIDE_WIDTH)) * CURVE_SIDE_WIDTH, RESX), LCD_H-1); diff --git a/radio/src/gui/horus/fonts.cpp b/radio/src/gui/horus/fonts.cpp index be7b0b770..a3d7a1402 100644 --- a/radio/src/gui/horus/fonts.cpp +++ b/radio/src/gui/horus/fonts.cpp @@ -37,51 +37,51 @@ #include "../../opentx.h" const uint16_t font_tinsize_specs[] PROGMEM = -#include "../../fonts/horus/font_tinsize.specs" +#include "font_tinsize.specs" ; const pm_uchar font_tinsize[] PROGMEM = { -#include "fonts/horus/font_tinsize.lbm" +#include "font_tinsize.lbm" }; const uint16_t font_smlsize_specs[] PROGMEM = -#include "../../fonts/horus/font_smlsize.specs" +#include "font_smlsize.specs" ; const pm_uchar font_smlsize[] PROGMEM = { -#include "fonts/horus/font_smlsize.lbm" +#include "font_smlsize.lbm" }; const uint16_t font_stdsize_specs[] PROGMEM = -#include "../../fonts/horus/font_stdsize.specs" +#include "font_stdsize.specs" ; const pm_uchar font_stdsize[] PROGMEM = { -#include "fonts/horus/font_stdsize.lbm" +#include "font_stdsize.lbm" }; const uint16_t font_midsize_specs[] PROGMEM = -#include "../../fonts/horus/font_midsize.specs" +#include "font_midsize.specs" ; const pm_uchar font_midsize[] PROGMEM = { -#include "fonts/horus/font_midsize.lbm" +#include "font_midsize.lbm" }; const uint16_t font_dblsize_specs[] PROGMEM = -#include "../../fonts/horus/font_dblsize.specs" +#include "font_dblsize.specs" ; const pm_uchar font_dblsize[] PROGMEM = { -#include "fonts/horus/font_dblsize.lbm" +#include "font_dblsize.lbm" }; const uint16_t font_xxlsize_specs[] PROGMEM = -#include "../../fonts/horus/font_xxlsize.specs" +#include "font_xxlsize.specs" ; const pm_uchar font_xxlsize[] PROGMEM = { -#include "fonts/horus/font_xxlsize.lbm" +#include "font_xxlsize.lbm" }; const uint16_t *fontspecsTable[16] = { font_stdsize_specs, font_tinsize_specs, font_smlsize_specs, font_midsize_specs, font_dblsize_specs, font_xxlsize_specs }; diff --git a/radio/src/gui/horus/gui.h b/radio/src/gui/horus/gui.h index 79633aa28..410383452 100644 --- a/radio/src/gui/horus/gui.h +++ b/radio/src/gui/horus/gui.h @@ -34,8 +34,8 @@ * */ -#include "../horus/lcd.h" -#include "../horus/menus.h" +#include "lcd.h" +#include "menus.h" #define MENU_HEADER_HEIGHT 45 #define MENU_TITLE_TOP 48 @@ -84,11 +84,15 @@ void displayScreenIndex(uint8_t index, uint8_t count); void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); void drawHorizontalScrollbar(coord_t x, coord_t y, coord_t w, uint16_t offset, uint16_t count, uint8_t visible); void drawHeader(int index); +void drawColumnHeader(const char * const * headers, uint8_t index); void drawFooter(); #define drawStatusLine(...) void drawProgressBar(const char *label); void updateProgressBar(int num, int den); void drawTopmenuDatetime(); +void drawSubmenuTemplate(const char * name, uint16_t scrollbar_X); +void drawStick(coord_t centrex, int16_t xval, int16_t yval); +void drawSticks(); // Curve functions coord_t getCurveYCoord(FnFuncP fn, coord_t x); diff --git a/radio/src/gui/horus/lcd.cpp b/radio/src/gui/horus/lcd.cpp index 8d4cc3e31..14f413968 100644 --- a/radio/src/gui/horus/lcd.cpp +++ b/radio/src/gui/horus/lcd.cpp @@ -34,6 +34,8 @@ * */ +#include +#include #include "../../opentx.h" #if defined(SIMU) @@ -608,7 +610,6 @@ void putsSwitches(coord_t x, coord_t y, int8_t idx, LcdFlags att) } } -#if defined(FLIGHT_MODES) void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att) { if (idx==0) { @@ -618,7 +619,6 @@ void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att) putsStrIdx(x, y, STR_FP, abs(idx)-1, att); } } -#endif void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att) { diff --git a/radio/src/gui/horus/menu_general.cpp b/radio/src/gui/horus/menu_general.cpp index 2f3fcd351..34293d3f3 100644 --- a/radio/src/gui/horus/menu_general.cpp +++ b/radio/src/gui/horus/menu_general.cpp @@ -36,59 +36,6 @@ #include "../../opentx.h" -extern LP_CONST LanguagePack czLanguagePack; -extern LP_CONST LanguagePack enLanguagePack; -extern LP_CONST LanguagePack esLanguagePack; -extern LP_CONST LanguagePack frLanguagePack; -extern LP_CONST LanguagePack deLanguagePack; -extern LP_CONST LanguagePack itLanguagePack; -extern LP_CONST LanguagePack plLanguagePack; -extern LP_CONST LanguagePack ptLanguagePack; -extern LP_CONST LanguagePack skLanguagePack; -extern LP_CONST LanguagePack seLanguagePack; -extern LP_CONST LanguagePack huLanguagePack; - -const LanguagePack * LP_CONST languagePacks[] = { - // alphabetical order - &czLanguagePack, - &deLanguagePack, - &enLanguagePack, - &esLanguagePack, - &frLanguagePack, - &huLanguagePack, - &itLanguagePack, - &plLanguagePack, - &ptLanguagePack, - &seLanguagePack, - &skLanguagePack, - NULL -}; - -bool menuGeneralSetup(evt_t event); -bool menuGeneralSdManager(evt_t event); -bool menuGeneralCustomFunctions(evt_t event); -bool menuGeneralTrainer(evt_t event); -bool menuGeneralVersion(evt_t event); -bool menuGeneralCalib(evt_t event); - -enum EnumTabDiag { - e_Setup, - e_Sd, - e_GeneralCustomFunctions, - e_Trainer, - e_Calib, - e_Vers, -}; - -const MenuHandlerFunc menuTabGeneral[] PROGMEM = { - menuGeneralSetup, - menuGeneralSdManager, - menuGeneralCustomFunctions, - menuGeneralTrainer, - menuGeneralCalib, - menuGeneralVersion, -}; - bool menuGeneralCustomFunctions(evt_t event) { MENU(STR_MENUGLOBALFUNCS, menuTabGeneral, e_GeneralCustomFunctions, NUM_CFN, DEFAULT_SCROLLBAR_X, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); diff --git a/radio/src/gui/horus/menu_general_sdmanager.cpp b/radio/src/gui/horus/menu_general_sdmanager.cpp index 6a335b523..68b76c247 100644 --- a/radio/src/gui/horus/menu_general_sdmanager.cpp +++ b/radio/src/gui/horus/menu_general_sdmanager.cpp @@ -34,6 +34,7 @@ * */ +#include #include "../../opentx.h" #define REFRESH_FILES() do { reusableBuffer.sdmanager.offset = 65535; lastBitmap = -1; } while (0) diff --git a/radio/src/gui/horus/menu_general_setup.cpp b/radio/src/gui/horus/menu_general_setup.cpp index 85a876961..6d2440c21 100644 --- a/radio/src/gui/horus/menu_general_setup.cpp +++ b/radio/src/gui/horus/menu_general_setup.cpp @@ -59,8 +59,8 @@ #endif enum menuGeneralSetupItems { - CASE_RTCLOCK(ITEM_SETUP_DATE) - CASE_RTCLOCK(ITEM_SETUP_TIME) + ITEM_SETUP_DATE, + ITEM_SETUP_TIME, // ITEM_SETUP_BATT_RANGE, ITEM_SETUP_SOUND_LABEL, ITEM_SETUP_BEEP_MODE, diff --git a/radio/src/gui/horus/menu_model.cpp b/radio/src/gui/horus/menu_model.cpp index 9b506e774..c71d876c2 100644 --- a/radio/src/gui/horus/menu_model.cpp +++ b/radio/src/gui/horus/menu_model.cpp @@ -35,48 +35,10 @@ #include "../../opentx.h" -enum EnumTabModel { - // e_ModelSelect, - e_ModelSetup, - CASE_HELI(e_Heli) - CASE_FLIGHT_MODES(e_FlightModesAll) - e_InputsAll, - e_MixAll, - e_Limits, - CASE_CURVES(e_CurvesAll) - CASE_GVARS(e_GVars) - e_LogicalSwitches, - e_CustomFunctions, -#if defined(LUA_MODEL_SCRIPTS) - e_CustomScripts, -#endif - CASE_FRSKY(e_Telemetry) -}; - -bool menuModelSelect(evt_t event); -bool menuModelSetup(evt_t event); -bool menuModelHeli(evt_t event); -bool menuModelFlightModesAll(evt_t event); -bool menuModelExposAll(evt_t event); -bool menuModelMixAll(evt_t event); -bool menuModelLimits(evt_t event); -bool menuModelCurvesAll(evt_t event); -bool menuModelCurveOne(evt_t event); -bool menuModelGVars(evt_t event); -bool menuModelLogicalSwitches(evt_t event); -bool menuModelCustomFunctions(evt_t event); -bool menuModelCustomScripts(evt_t event); -bool menuModelTelemetry(evt_t event); -bool menuModelExpoOne(evt_t event); - extern uint8_t s_curveChan; -#define FlightModesType uint16_t - void editCurveRef(coord_t x, coord_t y, CurveRef & curve, evt_t event, uint8_t attr); -#define MIXES_2ND_COLUMN 100 - uint8_t editDelay(const coord_t x, const coord_t y, const evt_t event, const uint8_t attr, uint8_t delay) { lcdDrawNumber(x+MIXES_2ND_COLUMN, y, (10/DELAY_STEP)*delay, attr|PREC1|LEFT); @@ -84,35 +46,11 @@ uint8_t editDelay(const coord_t x, const coord_t y, const evt_t event, const uin return delay; } -const MenuHandlerFunc menuTabModel[] = { -// menuModelSelect, - menuModelSetup, - CASE_HELI(menuModelHeli) - CASE_FLIGHT_MODES(menuModelFlightModesAll) - menuModelExposAll, - menuModelMixAll, - menuModelLimits, - CASE_CURVES(menuModelCurvesAll) -#if defined(GVARS) && defined(FLIGHT_MODES) - CASE_GVARS(menuModelGVars) -#endif - menuModelLogicalSwitches, - menuModelCustomFunctions, -#if defined(LUA_MODEL_SCRIPTS) - menuModelCustomScripts, -#endif - CASE_FRSKY(menuModelTelemetry) - CASE_MAVLINK(menuTelemetryMavlinkSetup) - CASE_TEMPLATES(menuModelTemplates) -}; +uint8_t s_copyMode = 0; +int8_t s_copySrcRow; +int8_t s_copyTgtOfs; -#define COPY_MODE 1 -#define MOVE_MODE 2 -static uint8_t s_copyMode = 0; -static int8_t s_copySrcRow; -static int8_t s_copyTgtOfs; - -static uint8_t editNameCursorPos = 0; +uint8_t editNameCursorPos = 0; void editName(coord_t x, coord_t y, char * name, uint8_t size, evt_t event, uint8_t active, LcdFlags flags) { @@ -216,4 +154,12 @@ void editName(coord_t x, coord_t y, char * name, uint8_t size, evt_t event, uint } } -static uint8_t s_currIdx; +uint8_t s_currIdx; + +void copySelection(char * dst, const char * src, uint8_t size) +{ + if (memcmp(src, "---", 3) == 0) + memset(dst, 0, size); + else + memcpy(dst, src, size); +} diff --git a/radio/src/gui/horus/menu_model_curves.cpp b/radio/src/gui/horus/menu_model_curves.cpp index bc852d4b4..0bb229f8f 100644 --- a/radio/src/gui/horus/menu_model_curves.cpp +++ b/radio/src/gui/horus/menu_model_curves.cpp @@ -33,6 +33,7 @@ * */ +#include #include "../../opentx.h" uint8_t s_curveChan; diff --git a/radio/src/gui/horus/menu_model_flightmodes.cpp b/radio/src/gui/horus/menu_model_flightmodes.cpp index bd8ac6900..cfc8f1aef 100644 --- a/radio/src/gui/horus/menu_model_flightmodes.cpp +++ b/radio/src/gui/horus/menu_model_flightmodes.cpp @@ -33,6 +33,7 @@ * */ +#include #include "../../opentx.h" enum FlightModesItems { @@ -73,7 +74,7 @@ bool menuModelFlightModesAll(evt_t event) } if (sub=0) { - displayColumnHeader(STR_PHASES_HEADERS, posHorz); + drawColumnHeader(STR_PHASES_HEADERS, posHorz); } for (int i=0; i #include "../../opentx.h" #define EXPO_ONE_2ND_COLUMN 110 diff --git a/radio/src/gui/horus/menu_model_limits.cpp b/radio/src/gui/horus/menu_model_limits.cpp index e0102d19a..67fc3e5a1 100644 --- a/radio/src/gui/horus/menu_model_limits.cpp +++ b/radio/src/gui/horus/menu_model_limits.cpp @@ -137,7 +137,7 @@ bool menuModelLimits(evt_t event) } if (sub=0) { - displayColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition); + drawColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition); } if (warningResult) { diff --git a/radio/src/gui/horus/menu_model_logical_switches.cpp b/radio/src/gui/horus/menu_model_logical_switches.cpp index 06198ee95..13222c788 100644 --- a/radio/src/gui/horus/menu_model_logical_switches.cpp +++ b/radio/src/gui/horus/menu_model_logical_switches.cpp @@ -33,6 +33,7 @@ * */ +#include #include "../../opentx.h" enum LogicalSwitchFields { @@ -54,11 +55,6 @@ enum LogicalSwitchFields { #define CSW_5TH_COLUMN 245 #define CSW_6TH_COLUMN 300 -#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL -#define INCDEC_SET_FLAG(f) incdecFlag = (f) -#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn -#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) - void putsEdgeDelayParam(coord_t x, coord_t y, LogicalSwitchData *cs, uint8_t lattr, uint8_t rattr) { char s[32]; @@ -106,7 +102,7 @@ bool menuModelLogicalSwitches(evt_t event) horzpos_t horz = menuHorizontalPosition; if (sub>= 0 && horz>=0) { - displayColumnHeader(STR_CSW_HEADERS, horz); + drawColumnHeader(STR_CSW_HEADERS, horz); } if (horz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { diff --git a/radio/src/gui/horus/menu_model_setup.cpp b/radio/src/gui/horus/menu_model_setup.cpp index 6eb118305..5c74c4831 100644 --- a/radio/src/gui/horus/menu_model_setup.cpp +++ b/radio/src/gui/horus/menu_model_setup.cpp @@ -94,14 +94,6 @@ enum menuModelSetupItems { #define MODEL_SETUP_RANGE_OFS 40 #define MODEL_SETUP_SET_FAILSAFE_OFS 60 -void copySelection(char *dst, const char *src, uint8_t size) -{ - if (memcmp(src, "---", 3) == 0) - memset(dst, 0, size); - else - memcpy(dst, src, size); -} - void onModelSetupBitmapMenu(const char *result) { if (result == STR_UPDATE_LIST) { diff --git a/radio/src/gui/horus/menus.h b/radio/src/gui/horus/menus.h index 8d40f4816..80a4b8742 100644 --- a/radio/src/gui/horus/menus.h +++ b/radio/src/gui/horus/menus.h @@ -47,6 +47,8 @@ #endif #define MENU_COLUMN2_X 280 +#define MIXES_2ND_COLUMN 100 +#define COLUMN_HEADER_X 150 typedef int16_t vertpos_t; @@ -69,8 +71,6 @@ extern uint8_t noHighlightCounter; void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); typedef bool (*MenuHandlerFunc)(evt_t event); -extern const MenuHandlerFunc menuTabModel[]; -extern const MenuHandlerFunc menuTabGeneral[]; extern MenuHandlerFunc menuHandlers[5]; extern uint8_t menuVerticalPositions[4]; @@ -84,16 +84,90 @@ void pushMenu(MenuHandlerFunc newMenu); /// return to last menu in menustack void popMenu(); -bool menuFirstCalib(evt_t event); +enum EnumTabModel { + // e_ModelSelect, + e_ModelSetup, + CASE_HELI(e_Heli) + CASE_FLIGHT_MODES(e_FlightModesAll) + e_InputsAll, + e_MixAll, + e_Limits, + CASE_CURVES(e_CurvesAll) + CASE_GVARS(e_GVars) + e_LogicalSwitches, + e_CustomFunctions, +#if defined(LUA_MODEL_SCRIPTS) + e_CustomScripts, +#endif + CASE_FRSKY(e_Telemetry) +}; + +bool menuModelSetup(evt_t event); +bool menuModelHeli(evt_t event); +bool menuModelFlightModesAll(evt_t event); +bool menuModelExposAll(evt_t event); +bool menuModelMixAll(evt_t event); +bool menuModelLimits(evt_t event); +bool menuModelCurvesAll(evt_t event); +bool menuModelCurveOne(evt_t event); +bool menuModelGVars(evt_t event); +bool menuModelLogicalSwitches(evt_t event); +bool menuModelCustomFunctions(evt_t event); +bool menuModelCustomScripts(evt_t event); +bool menuModelTelemetry(evt_t event); +bool menuModelExpoOne(evt_t event); + +const MenuHandlerFunc menuTabModel[] = { +// menuModelSelect, + menuModelSetup, + CASE_HELI(menuModelHeli) + CASE_FLIGHT_MODES(menuModelFlightModesAll) + menuModelExposAll, + menuModelMixAll, + menuModelLimits, + CASE_CURVES(menuModelCurvesAll) +#if defined(GVARS) && defined(FLIGHT_MODES) + CASE_GVARS(menuModelGVars) +#endif + menuModelLogicalSwitches, + menuModelCustomFunctions, +#if defined(LUA_MODEL_SCRIPTS) + menuModelCustomScripts, +#endif + CASE_FRSKY(menuModelTelemetry) + CASE_MAVLINK(menuTelemetryMavlinkSetup) + CASE_TEMPLATES(menuModelTemplates) +}; + +enum EnumTabDiag { + e_Setup, + e_Sd, + e_GeneralCustomFunctions, + e_Trainer, + e_Calib, + e_Vers, +}; -bool menuMainView(evt_t event); -bool menuGeneralDiagAna(evt_t event); bool menuGeneralSetup(evt_t event); +bool menuGeneralSdManager(evt_t event); +bool menuGeneralCustomFunctions(evt_t event); +bool menuGeneralTrainer(evt_t event); +bool menuGeneralVersion(evt_t event); bool menuGeneralCalib(evt_t event); + +static const MenuHandlerFunc menuTabGeneral[] PROGMEM = { + menuGeneralSetup, + menuGeneralSdManager, + menuGeneralCustomFunctions, + menuGeneralTrainer, + menuGeneralCalib, + menuGeneralVersion, +}; + +bool menuFirstCalib(evt_t event); +bool menuMainView(evt_t event); bool menuCustomFunctions(evt_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext); bool menuModelSelect(evt_t event); -bool menuModelSetup(evt_t event); -bool menuModelCustomFunctions(evt_t event); bool menuStatisticsView(evt_t event); bool menuStatisticsDebug(evt_t event); bool menuAboutView(evt_t event); @@ -106,6 +180,8 @@ bool menuTextView(evt_t event); void menuTraceBuffer(evt_t event); #endif +typedef uint16_t FlightModesType; + extern int8_t checkIncDec_Ret; // global helper vars #define EDIT_SELECT_MENU -1 @@ -190,10 +266,15 @@ int8_t checkIncDecMovedSwitch(int8_t val); #define CHECK_INCDEC_GENVAR(event, var, min, max) \ var = checkIncDecGen(event, var, min, max) -#define NAVIGATION_LINE_BY_LINE 0x40 -#define CURSOR_ON_LINE() (menuHorizontalPosition<0) +#define NAVIGATION_LINE_BY_LINE 0x40 +#define CURSOR_ON_LINE() (menuHorizontalPosition<0) + +#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL +#define INCDEC_SET_FLAG(f) incdecFlag = (f) +#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn +#define CHECK_INCDEC_PARAM(event, var, min, max) \ + checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) -#define CHECK_FLAG_NO_SCREEN_INDEX 1 bool navigate(evt_t event, int count, int rows, int columns=1); bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags=0); bool check_simple(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, vertpos_t maxrow); @@ -249,8 +330,14 @@ int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, evt_t e #define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v) #endif +extern uint8_t editNameCursorPos; void editName(coord_t x, coord_t y, char *name, uint8_t size, evt_t event, uint8_t active, LcdFlags flags=ZCHAR); +uint8_t editDelay(const coord_t x, const coord_t y, const evt_t event, const uint8_t attr, uint8_t delay); +void editCurveRef(coord_t x, coord_t y, CurveRef & curve, evt_t event, uint8_t attr); + +extern uint8_t s_curveChan; + #define WARNING_TYPE_ASTERISK 0 #define WARNING_TYPE_CONFIRM 1 #define WARNING_TYPE_INPUT 2 @@ -261,6 +348,14 @@ extern uint8_t warningInfoLength; extern uint8_t warningResult; extern uint8_t warningType; +#define COPY_MODE 1 +#define MOVE_MODE 2 +extern uint8_t s_copyMode; + +extern int8_t s_copySrcRow; +extern int8_t s_copyTgtOfs; +extern uint8_t s_currIdx; + #define MENU_X 80 #define MENU_W LCD_W-(2*MENU_X) #define POPUP_X 130 @@ -272,11 +367,12 @@ extern uint8_t warningType; #define WARNING_LINE_Y (POPUP_Y+9) #define WARNING_INFOLINE_Y (WARNING_LINE_Y+68) -void displayBox(); -void displayPopup(const char *title); +void copySelection(char * dst, const char * src, uint8_t size); + +void displayPopup(const char * title); void displayWarning(evt_t event); -extern void (*popupFunc)(evt_t event); +extern void (* popupFunc)(evt_t event); extern int16_t warningInputValue; extern int16_t warningInputValueMin; extern int16_t warningInputValueMax; @@ -322,4 +418,6 @@ void pushModelNotes(); typedef int (*FnFuncP) (int x); void drawFunction(FnFuncP fn, int offset=0); +uint8_t switchToMix(uint8_t source); + #endif // _MENUS_H_ diff --git a/radio/src/gui/horus/widgets.cpp b/radio/src/gui/horus/widgets.cpp index 8e792e5a1..2c010cf7f 100644 --- a/radio/src/gui/horus/widgets.cpp +++ b/radio/src/gui/horus/widgets.cpp @@ -37,14 +37,12 @@ #include "../../opentx.h" #include -#define COLUMN_HEADER_X 150 - -void displayHeader(const char *header) +void drawHeader(const char * header) { // TODO ? lcdDrawText(COLUMN_HEADER_X, MENU_FOOTER_TOP, header, HEADER_COLOR); } -void displayColumnHeader(const char * const *headers, uint8_t index) +void drawColumnHeader(const char * const * headers, uint8_t index) { // TODO ? displayHeader(headers[index]); } diff --git a/radio/src/gui/taranis/gui.h b/radio/src/gui/taranis/gui.h index 9df15c662..e086beb0c 100644 --- a/radio/src/gui/taranis/gui.h +++ b/radio/src/gui/taranis/gui.h @@ -45,13 +45,28 @@ #define BITMAP_BUFFER_SIZE(width, height) (2 + (width) * (((height)+7)/8)*4) #define MODEL_BITMAP_WIDTH 64 #define MODEL_BITMAP_HEIGHT 32 + +#define WCHART (LCD_H/2) +#define X0 (LCD_W-WCHART-2) +#define Y0 (LCD_H/2) + +#define MENUS_SCROLLBAR_WIDTH 2 +#define MENU_COLUMN2_X (8 + LCD_W / 2) + +#if MENU_COLUMNS < 2 + #define MIXES_2ND_COLUMN (18*FW) +#else + #define MIXES_2ND_COLUMN (9*FW) +#endif + #define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT) -extern uint8_t modelBitmap[MODEL_BITMAP_SIZE]; -bool loadModelBitmap(char * name, uint8_t * bitmap); #define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap) +extern uint8_t modelBitmap[MODEL_BITMAP_SIZE]; +bool loadModelBitmap(char * name, uint8_t * bitmap); + struct MenuItem { - const char *name; + const char * name; const MenuHandlerFunc action; }; @@ -63,7 +78,11 @@ void displayMenuBar(const MenuItem *menu, int index); void drawProgressBar(const char *label); void updateProgressBar(int num, int den); void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); +void drawColumnHeader(const char * const * headers, uint8_t index); +void drawStick(coord_t centrex, int16_t xval, int16_t yval); extern coord_t scrollbar_X; #define SET_SCROLLBAR_X(x) scrollbar_X = (x); +extern const pm_uchar sticks[] PROGMEM; + diff --git a/radio/src/gui/taranis/menu_general.cpp b/radio/src/gui/taranis/menu_general.cpp index e6086a478..0427351bf 100644 --- a/radio/src/gui/taranis/menu_general.cpp +++ b/radio/src/gui/taranis/menu_general.cpp @@ -36,70 +36,6 @@ #include "../../opentx.h" -extern LP_CONST LanguagePack czLanguagePack; -extern LP_CONST LanguagePack enLanguagePack; -extern LP_CONST LanguagePack esLanguagePack; -extern LP_CONST LanguagePack frLanguagePack; -extern LP_CONST LanguagePack deLanguagePack; -extern LP_CONST LanguagePack itLanguagePack; -extern LP_CONST LanguagePack nlLanguagePack; -extern LP_CONST LanguagePack plLanguagePack; -extern LP_CONST LanguagePack ptLanguagePack; -extern LP_CONST LanguagePack skLanguagePack; -extern LP_CONST LanguagePack seLanguagePack; -extern LP_CONST LanguagePack huLanguagePack; - -const LanguagePack * LP_CONST languagePacks[] = { - // alphabetical order - &czLanguagePack, - &deLanguagePack, - &enLanguagePack, - &esLanguagePack, - &frLanguagePack, - &huLanguagePack, - &itLanguagePack, - &nlLanguagePack, - &plLanguagePack, - &ptLanguagePack, - &seLanguagePack, - &skLanguagePack, - NULL -}; - -void menuGeneralSetup(uint8_t event); -void menuGeneralSdManager(uint8_t event); -void menuGeneralCustomFunctions(uint8_t event); -void menuGeneralTrainer(uint8_t event); -void menuGeneralVersion(uint8_t event); -void menuGeneralDiagKeys(uint8_t event); -void menuGeneralDiagAna(uint8_t event); -void menuGeneralHardware(uint8_t event); -void menuGeneralCalib(uint8_t event); - -enum EnumTabDiag { - e_Setup, - e_Sd, - e_GeneralCustomFunctions, - e_Trainer, - e_Vers, - e_Keys, - e_Ana, - e_Hardware, - e_Calib -}; - -const MenuHandlerFunc menuTabGeneral[] = { - menuGeneralSetup, - menuGeneralSdManager, - menuGeneralCustomFunctions, - menuGeneralTrainer, - menuGeneralVersion, - menuGeneralDiagKeys, - menuGeneralDiagAna, - menuGeneralHardware, - menuGeneralCalib -}; - void menuGeneralCustomFunctions(uint8_t event) { MENU(STR_MENUGLOBALFUNCS, menuTabGeneral, e_GeneralCustomFunctions, NUM_CFN, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); diff --git a/radio/src/gui/taranis/menu_general_sdmanager.cpp b/radio/src/gui/taranis/menu_general_sdmanager.cpp index d8d8f148a..beab39bf1 100644 --- a/radio/src/gui/taranis/menu_general_sdmanager.cpp +++ b/radio/src/gui/taranis/menu_general_sdmanager.cpp @@ -77,7 +77,7 @@ inline bool isFilenameLower(bool isfile, const char * fn, const char * line) return (!isfile && IS_FILE(line)) || (isfile==IS_FILE(line) && strcasecmp(fn, line) < 0); } -bool isBootloader(const char *filename) +bool isBootloader(const char * filename) { FIL file; f_open(&file, filename, FA_READ); diff --git a/radio/src/gui/taranis/menu_general_setup.cpp b/radio/src/gui/taranis/menu_general_setup.cpp index 8eacae7d2..cbf3c0e96 100644 --- a/radio/src/gui/taranis/menu_general_setup.cpp +++ b/radio/src/gui/taranis/menu_general_setup.cpp @@ -37,7 +37,7 @@ #include "../../opentx.h" const pm_uchar sticks[] PROGMEM = { -#include "../../bitmaps/sticks.lbm" +#include "sticks.lbm" }; #define RADIO_SETUP_2ND_COLUMN (LCD_W-10*FW-MENUS_SCROLLBAR_WIDTH) diff --git a/radio/src/gui/taranis/menu_model.cpp b/radio/src/gui/taranis/menu_model.cpp index 9611408fb..967f17109 100644 --- a/radio/src/gui/taranis/menu_model.cpp +++ b/radio/src/gui/taranis/menu_model.cpp @@ -35,59 +35,6 @@ #include "../../opentx.h" -// TODO elsewhere! -#define WCHART (LCD_H/2) -#define X0 (LCD_W-WCHART-2) -#define Y0 (LCD_H/2) - -enum EnumTabModel { - e_ModelSelect, - e_ModelSetup, - CASE_HELI(e_Heli) - CASE_FLIGHT_MODES(e_FlightModesAll) - e_InputsAll, - e_MixAll, - e_Limits, - CASE_CURVES(e_CurvesAll) - CASE_GVARS(e_GVars) - e_LogicalSwitches, - e_CustomFunctions, -#if defined(LUA_MODEL_SCRIPTS) - e_CustomScripts, -#endif - CASE_FRSKY(e_Telemetry) - CASE_MAVLINK(e_MavSetup) - CASE_TEMPLATES(e_Templates) -}; - -void menuModelSelect(uint8_t event); -void menuModelSetup(uint8_t event); -void menuModelHeli(uint8_t event); -void menuModelFlightModesAll(uint8_t event); -void menuModelExposAll(uint8_t event); -void menuModelMixAll(uint8_t event); -void menuModelLimits(uint8_t event); -void menuModelCurvesAll(uint8_t event); -void menuModelCurveOne(uint8_t event); -void menuModelGVars(uint8_t event); -void menuModelLogicalSwitches(uint8_t event); -void menuModelCustomFunctions(uint8_t event); -void menuModelCustomScripts(uint8_t event); -void menuModelTelemetry(uint8_t event); -void menuModelExpoOne(uint8_t event); - -extern uint8_t s_curveChan; - -#define FlightModesType uint16_t - -void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t attr); - -#if MENU_COLUMNS < 2 - #define MIXES_2ND_COLUMN (18*FW) -#else - #define MIXES_2ND_COLUMN (9*FW) -#endif - #if MENU_COLUMNS > 1 uint8_t editDelay(const coord_t x, const coord_t y, const uint8_t event, const uint8_t attr, const pm_char *str, uint8_t delay) { @@ -96,7 +43,6 @@ uint8_t editDelay(const coord_t x, const coord_t y, const uint8_t event, const u if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX); return delay; } -#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(x, y, event, attr, str, delay) #else uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, const pm_char *str, uint8_t delay) { @@ -105,38 +51,15 @@ uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, cons if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX); return delay; } -#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay) #endif -const MenuHandlerFunc menuTabModel[] = { - menuModelSelect, - menuModelSetup, - CASE_HELI(menuModelHeli) - CASE_FLIGHT_MODES(menuModelFlightModesAll) - menuModelExposAll, - menuModelMixAll, - menuModelLimits, - CASE_CURVES(menuModelCurvesAll) -#if defined(GVARS) && defined(FLIGHT_MODES) - CASE_GVARS(menuModelGVars) -#endif - menuModelLogicalSwitches, - menuModelCustomFunctions, -#if defined(LUA_MODEL_SCRIPTS) - menuModelCustomScripts, -#endif - CASE_FRSKY(menuModelTelemetry) - CASE_MAVLINK(menuTelemetryMavlinkSetup) - CASE_TEMPLATES(menuModelTemplates) -}; - #define COPY_MODE 1 #define MOVE_MODE 2 -static uint8_t s_copyMode = 0; -static int8_t s_copySrcRow; -static int8_t s_copyTgtOfs; +uint8_t s_copyMode = 0; +int8_t s_copySrcRow; +int8_t s_copyTgtOfs; -static uint8_t editNameCursorPos = 0; +uint8_t editNameCursorPos = 0; void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr) { @@ -232,4 +155,4 @@ void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint editName(x, y, name, size, event, active); } -static uint8_t s_currIdx; +uint8_t s_currIdx; diff --git a/radio/src/gui/taranis/menu_model_flightmodes.cpp b/radio/src/gui/taranis/menu_model_flightmodes.cpp index d08f38a6b..b97e1a0c0 100644 --- a/radio/src/gui/taranis/menu_model_flightmodes.cpp +++ b/radio/src/gui/taranis/menu_model_flightmodes.cpp @@ -73,7 +73,7 @@ void menuModelFlightModesAll(uint8_t event) if (sub==0 && posHorz > 0) { posHorz += 1; } if (sub=0) { - displayColumnHeader(STR_PHASES_HEADERS, posHorz); + drawColumnHeader(STR_PHASES_HEADERS, posHorz); } for (uint8_t i=0; i=0) { - displayColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition); + drawColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition); } if (warningResult) { diff --git a/radio/src/gui/taranis/menu_model_logical_switches.cpp b/radio/src/gui/taranis/menu_model_logical_switches.cpp index 47deaf986..5847e7981 100644 --- a/radio/src/gui/taranis/menu_model_logical_switches.cpp +++ b/radio/src/gui/taranis/menu_model_logical_switches.cpp @@ -54,11 +54,6 @@ enum LogicalSwitchFields { #define CSW_5TH_COLUMN (26*FW+3) #define CSW_6TH_COLUMN (31*FW+1) -#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL -#define INCDEC_SET_FLAG(f) incdecFlag = (f) -#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn -#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) - void putsEdgeDelayParam(coord_t x, coord_t y, LogicalSwitchData *cs, uint8_t lattr, uint8_t rattr) { lcdDrawChar(x-4, y, '['); @@ -103,7 +98,7 @@ void menuModelLogicalSwitches(uint8_t event) horzpos_t horz = menuHorizontalPosition; if (horz>=0) { - displayColumnHeader(STR_CSW_HEADERS, horz); + drawColumnHeader(STR_CSW_HEADERS, horz); } if (horz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { diff --git a/radio/src/gui/taranis/menus.h b/radio/src/gui/taranis/menus.h index a958cf43a..48ca38a5f 100644 --- a/radio/src/gui/taranis/menus.h +++ b/radio/src/gui/taranis/menus.h @@ -43,8 +43,6 @@ #define MENU_COLUMNS 2 #endif -#define MENUS_SCROLLBAR_WIDTH 2 -#define MENU_COLUMN2_X (8 + LCD_W / 2) #define lcd_putsColumnLeft(x, y, str) lcdDrawText((x > (LCD_W-10*FW-MENUS_SCROLLBAR_WIDTH)) ? MENU_COLUMN2_X : 0, y, str) // Menus related stuff ... @@ -68,8 +66,6 @@ extern uint8_t noHighlightCounter; void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr); typedef void (*MenuHandlerFunc)(uint8_t event); -extern const MenuHandlerFunc menuTabModel[]; -extern const MenuHandlerFunc menuTabGeneral[]; extern MenuHandlerFunc menuHandlers[5]; extern uint8_t menuVerticalPositions[4]; @@ -87,21 +83,41 @@ void doMainScreenGraphics(); void menuFirstCalib(uint8_t event); void onMainViewMenu(const char *result); -void menuMainView(uint8_t event); + +void menuModelSelect(uint8_t event); +void menuModelSetup(uint8_t event); +void menuModelHeli(uint8_t event); +void menuModelFlightModesAll(uint8_t event); +void menuModelExposAll(uint8_t event); +void menuModelMixAll(uint8_t event); +void menuModelLimits(uint8_t event); +void menuModelCurvesAll(uint8_t event); +void menuModelCurveOne(uint8_t event); +void menuModelGVars(uint8_t event); +void menuModelLogicalSwitches(uint8_t event); +void menuModelCustomFunctions(uint8_t event); +void menuModelCustomScripts(uint8_t event); +void menuModelTelemetry(uint8_t event); +void menuModelExpoOne(uint8_t event); + +void menuGeneralSetup(uint8_t event); +void menuGeneralSdManager(uint8_t event); +void menuGeneralCustomFunctions(uint8_t event); +void menuGeneralTrainer(uint8_t event); +void menuGeneralVersion(uint8_t event); +void menuGeneralDiagKeys(uint8_t event); void menuGeneralDiagAna(uint8_t event); +void menuGeneralHardware(uint8_t event); +void menuGeneralCalib(uint8_t event); + +void menuMainViewChannelsMonitor(uint8_t event); +void menuChannelsView(uint8_t event); +void menuMainView(uint8_t event); #if defined(FRSKY) void menuTelemetryFrsky(uint8_t event); #endif -void menuModelSetup(uint8_t event); -void menuModelNotes(uint8_t event); -void menuGeneralSetup(uint8_t event); -void menuGeneralSdManager(uint8_t event); -void menuGeneralCalib(uint8_t event); -void menuGeneralVersion(uint8_t event); void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); - -void menuModelSelect(uint8_t event); -void menuModelCustomFunctions(uint8_t event); +void menuModelNotes(uint8_t event); void menuStatisticsView(uint8_t event); void menuStatisticsDebug(uint8_t event); void menuAboutView(uint8_t event); @@ -109,10 +125,75 @@ void menuAboutView(uint8_t event); void menuTraceBuffer(uint8_t event); #endif +enum EnumTabDiag { + e_Setup, + e_Sd, + e_GeneralCustomFunctions, + e_Trainer, + e_Vers, + e_Keys, + e_Ana, + e_Hardware, + e_Calib +}; + +const MenuHandlerFunc menuTabGeneral[] = { + menuGeneralSetup, + menuGeneralSdManager, + menuGeneralCustomFunctions, + menuGeneralTrainer, + menuGeneralVersion, + menuGeneralDiagKeys, + menuGeneralDiagAna, + menuGeneralHardware, + menuGeneralCalib +}; + +enum EnumTabModel { + e_ModelSelect, + e_ModelSetup, + CASE_HELI(e_Heli) + CASE_FLIGHT_MODES(e_FlightModesAll) + e_InputsAll, + e_MixAll, + e_Limits, + CASE_CURVES(e_CurvesAll) + CASE_GVARS(e_GVars) + e_LogicalSwitches, + e_CustomFunctions, +#if defined(LUA_MODEL_SCRIPTS) + e_CustomScripts, +#endif + CASE_FRSKY(e_Telemetry) + CASE_MAVLINK(e_MavSetup) + CASE_TEMPLATES(e_Templates) +}; + +const MenuHandlerFunc menuTabModel[] = { + menuModelSelect, + menuModelSetup, + CASE_HELI(menuModelHeli) + CASE_FLIGHT_MODES(menuModelFlightModesAll) + menuModelExposAll, + menuModelMixAll, + menuModelLimits, + CASE_CURVES(menuModelCurvesAll) +#if defined(GVARS) && defined(FLIGHT_MODES) + CASE_GVARS(menuModelGVars) +#endif + menuModelLogicalSwitches, + menuModelCustomFunctions, +#if defined(LUA_MODEL_SCRIPTS) + menuModelCustomScripts, +#endif + CASE_FRSKY(menuModelTelemetry) + CASE_MAVLINK(menuTelemetryMavlinkSetup) + CASE_TEMPLATES(menuModelTemplates) +}; + void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); -void menuMainViewChannelsMonitor(uint8_t event); -void menuChannelsView(uint8_t event); +typedef uint16_t FlightModesType; extern int8_t checkIncDec_Ret; // global helper vars @@ -131,6 +212,11 @@ extern int8_t s_editMode; // global editmode #define INCDEC_REP10 0x40 #define NO_DBLKEYS 0x80 +#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL +#define INCDEC_SET_FLAG(f) incdecFlag = (f) +#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn +#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) + // mawrow special values #define TITLE_ROW ((uint8_t)-1) #define HIDDEN_ROW ((uint8_t)-2) @@ -265,18 +351,40 @@ swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8 #define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) #endif +extern uint8_t s_curveChan; +void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t attr); + +extern uint8_t editNameCursorPos; void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr=ZCHAR); +void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint8_t size, uint8_t event, uint8_t active); + +#if MENU_COLUMNS > 1 +uint8_t editDelay(const coord_t x, const coord_t y, const uint8_t event, const uint8_t attr, const pm_char *str, uint8_t delay); +#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(x, y, event, attr, str, delay) +#else +uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, const pm_char *str, uint8_t delay); +#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay) +#endif #define WARNING_TYPE_ASTERISK 0 #define WARNING_TYPE_CONFIRM 1 #define WARNING_TYPE_INPUT 2 +void copySelection(char * dst, const char * src, uint8_t size); + extern const pm_char * warningText; extern const pm_char * warningInfoText; extern uint8_t warningInfoLength; extern uint8_t warningResult; extern uint8_t warningType; +#define COPY_MODE 1 +#define MOVE_MODE 2 +extern uint8_t s_copyMode; +extern int8_t s_copySrcRow; +extern int8_t s_copyTgtOfs; +extern uint8_t s_currIdx; + #define MENU_X 30 #define MENU_Y 16 #define MENU_W LCD_W-(2*MENU_X) @@ -360,4 +468,8 @@ void menuChannelsView(uint8_t event); typedef int16_t (*FnFuncP) (int16_t x); void drawFunction(FnFuncP fn, uint8_t offset=0); +void onSourceLongEnterPress(const char *result); + +uint8_t switchToMix(uint8_t source); + #endif // _MENUS_H_ diff --git a/radio/src/gui/taranis/navigation.cpp b/radio/src/gui/taranis/navigation.cpp index 5e1de2506..398ad078e 100644 --- a/radio/src/gui/taranis/navigation.cpp +++ b/radio/src/gui/taranis/navigation.cpp @@ -71,7 +71,7 @@ INIT_STOPS(stops100, 3, -100, 0, 100) INIT_STOPS(stops1000, 3, -1000, 0, 1000) INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST) -void onSourceLongEnterPress(const char *result) +void onSourceLongEnterPress(const char * result) { if (result == STR_MENU_INPUTS) checkIncDecSelection = getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable)+1; diff --git a/radio/src/gui/taranis/popups.cpp b/radio/src/gui/taranis/popups.cpp index 480c9cdb2..b8f129cef 100644 --- a/radio/src/gui/taranis/popups.cpp +++ b/radio/src/gui/taranis/popups.cpp @@ -67,6 +67,10 @@ void displayPopup(const char *title) lcdRefresh(); } +const pm_uchar asterisk_lbm[] PROGMEM = { +#include "asterisk.lbm" +}; + void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SOUND_ARG) { lcdClear(); diff --git a/radio/src/gui/taranis/view_statistics.cpp b/radio/src/gui/taranis/view_statistics.cpp index 9c5b95a0d..3269935ba 100644 --- a/radio/src/gui/taranis/view_statistics.cpp +++ b/radio/src/gui/taranis/view_statistics.cpp @@ -178,7 +178,7 @@ void menuStatisticsDebug(uint8_t event) lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT); lcdDrawText(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms"); -#if defined(USB_SERIAL) +#if !defined(SIMU) && defined(USB_SERIAL) lcd_putsLeft(MENU_DEBUG_Y_USB, "Usb"); lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_USB, charsWritten, LEFT); lcdDrawText(lcdLastPos, MENU_DEBUG_Y_USB, " "); diff --git a/radio/src/gui/taranis/widgets.cpp b/radio/src/gui/taranis/widgets.cpp index 303e2d7c8..c36cd990a 100644 --- a/radio/src/gui/taranis/widgets.cpp +++ b/radio/src/gui/taranis/widgets.cpp @@ -59,7 +59,7 @@ void drawStick(coord_t centrex, int16_t xval, int16_t yval) #undef MARKER_WIDTH } -void displayColumnHeader(const char * const *headers, uint8_t index) +void drawColumnHeader(const char * const *headers, uint8_t index) { lcdDrawText(17*FW, 0, headers[index], 0); } diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt new file mode 100644 index 000000000..75aab23de --- /dev/null +++ b/radio/src/lua/CMakeLists.txt @@ -0,0 +1,12 @@ +macro(add_lua_export_target target) + add_custom_command( + OUTPUT lua_exports_${target}.inc + COMMAND ${CMAKE_C_COMPILER} -E ${ARGN} -DEXPORT ${INTTYPES_INCLUDE_OPTION} ${RADIO_SRC_DIRECTORY}/myeeprom.h | grep LEXP > lua_exports_${target}.txt + COMMAND python ${RADIO_DIRECTORY}/util/luaexport.py ${VERSION} lua_exports_${target}.txt lua_exports_${target}.inc lua_fields_${target}.txt + ) + add_custom_target(lua_export_${target} DEPENDS lua_exports_${target}.inc) +endmacro(add_lua_export_target) + +add_lua_export_target(taranis -DPCBTARANIS -DLUA -DVIRTUALINPUTS) +add_lua_export_target(taranis_x9e -DPCBTARANIS -DREVPLUS -DREV9E -DLUA -DVIRTUALINPUTS) +add_lua_export_target(horus -DPCBHORUS -DLUA -DVIRTUALINPUTS) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 03681069d..058664fc5 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -71,11 +71,6 @@ #define FIND_FIELD_DESC 0x01 -struct LuaField { - uint16_t id; - char desc[50]; -}; - /*luadoc @function getVersion() @@ -255,7 +250,7 @@ void luaGetValueAndPush(int src) /** Return field data for a given field name */ -bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags=0) +bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags) { // TODO better search method (binary lookup) for (unsigned int n=0; n #include #include #include -#if !defined(SIMU) } -#endif extern lua_State *L; extern bool luaLcdAllowed; @@ -149,10 +145,13 @@ extern "C" { #elif defined(PCBHORUS) #define IS_MASKABLE(key) ((key) != KEY_EXIT && (key) != KEY_ENTER) #endif + struct LuaField { + uint16_t id; + char desc[50]; + }; + bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags=0); #else // #if defined(LUA) - #define LUA_LOAD_MODEL_SCRIPTS() - #endif // #if defined(LUA) #endif // #ifndef lua_api_h diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index e04c7cd90..1302a4ea8 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -1383,7 +1383,8 @@ enum TelemetrySensorFormula TELEM_FORMULA_LAST = TELEM_FORMULA_DIST }; -PACK(typedef struct { +PACK(class TelemetrySensor { + public: union { uint16_t id; // data identifier, for FrSky we can reuse existing ones. Source unit is derived from type. uint16_t persistentValue; @@ -1434,7 +1435,7 @@ PACK(typedef struct { bool isPrecConfigurable() const; int32_t getPrecMultiplier() const; int32_t getPrecDivisor() const; -}) TelemetrySensor; +}) ; #endif #if !defined(CPUARM) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 4b2199ffb..84f47e514 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -37,17 +37,6 @@ #include "opentx.h" #include "timers.h" -#if defined(COLORLCD) -#elif defined(PCBTARANIS) - const pm_uchar asterisk_lbm[] PROGMEM = { - #include "bitmaps/taranis/asterisk.lbm" - }; -#else - const pm_uchar asterisk_lbm[] PROGMEM = { - #include "bitmaps/9x/asterisk.lbm" - }; -#endif - EEGeneral g_eeGeneral; ModelData g_model; @@ -1600,7 +1589,7 @@ uint16_t s_cnt_samples_thr_10s; uint16_t s_sum_samples_thr_10s; #endif -FORCEINLINE void evalTrims() +void evalTrims() { uint8_t phase = mixerCurrentFlightMode; for (uint8_t i=0; i #include "diskio.h" -#include "ff.h" - -#define LIST_NONE_SD_FILE 1 +#include "opentx.h" const char * sdCheckAndCreateDirectory(const char * path) { @@ -72,8 +70,7 @@ bool isFileAvailable(const char * filename, const char * directory) return isFileAvailable(path); } -#define LEN_FILE_EXTENSION 4 -char * getFileExtension(char * filename, int size=0) +char * getFileExtension(char * filename, int size) { int len = strlen(filename); if (size != 0 && size < len) { @@ -122,11 +119,11 @@ int findNextFileIndex(char * filename, const char * directory) return 0; } -bool sdListFiles(const char *path, const char *extension, const uint8_t maxlen, const char *selection, uint8_t flags=0) +bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen, const char * selection, uint8_t flags) { FILINFO fno; DIR dir; - char *fn; /* This function is assuming non-Unicode cfg. */ + char * fn; /* This function is assuming non-Unicode cfg. */ #if _USE_LFN TCHAR lfn[_MAX_LFN + 1]; fno.lfname = lfn; diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index fc835b1dc..003b81b94 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -92,6 +92,9 @@ inline const pm_char * SDCARD_ERROR(FRESULT result) } #endif +#define LEN_FILE_EXTENSION 4 +char * getFileExtension(char * filename, int size=0); + #if defined(PCBTARANIS) #define O9X_FOURCC 0x3378396F // o9x for Taranis #elif defined(PCBSKY9X) @@ -104,7 +107,10 @@ bool isFileAvailable(const char * filename); int findNextFileIndex(char * filename, const char * directory); const char * sdCopyFile(const char * src, const char * dest); -const char * sdCopyFile(const char * filename, const char * srcDir, const char * destDir); +const char * sdCopyFile(const char * srcFilename, const char * srcDir, const char * destFilename, const char * destDir); + +#define LIST_NONE_SD_FILE 1 +bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen, const char * selection, uint8_t flags=0); #endif diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index 04e4847c8..3fa93d7d8 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -109,20 +109,17 @@ Open9xSim::Open9xSim(FXApp* a): for (int i=0; i<4; i++) { switch (i) { #define L LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FIX_X|LAYOUT_FIX_Y -#undef X0 -#define X0 10 -#define Y0 10 case 0: - sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_HORIZONTAL,X0+0,Y0+100,100,20); + sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_HORIZONTAL,10,110,100,20); break; case 1: - sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_VERTICAL,X0+100,Y0+0,20,100); + sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_VERTICAL,110,10,20,100); break; case 2: - sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_VERTICAL,X0+120,Y0+0,20,100); + sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_VERTICAL,130,10,20,100); break; case 3: - sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_HORIZONTAL,X0+140,Y0+100,100,20); + sliders[i]=new FXSlider(hf1,NULL,0,L|SLIDER_HORIZONTAL,150,110,100,20); break; default:; } diff --git a/radio/src/storage/sdcard_raw.cpp b/radio/src/storage/sdcard_raw.cpp index da67a43bb..f473dc04d 100644 --- a/radio/src/storage/sdcard_raw.cpp +++ b/radio/src/storage/sdcard_raw.cpp @@ -228,10 +228,6 @@ void storageFormat() storageCreateModelsList(); } -struct StorageModelsList { - FIL file; -}; - const char * storageOpenModelsList(StorageModelsList * storage) { FRESULT result = f_open(&storage->file, RADIO_MODELSLIST_PATH, FA_OPEN_EXISTING | FA_READ); diff --git a/radio/src/storage/sdcard_raw.h b/radio/src/storage/sdcard_raw.h index 6ce72093e..647653744 100644 --- a/radio/src/storage/sdcard_raw.h +++ b/radio/src/storage/sdcard_raw.h @@ -34,6 +34,11 @@ * */ +#ifndef _SDCARD_RAW_H_ +#define _SDCARD_RAW_H_ + +#include "ff.h" + #define DEFAULT_CATEGORY "Models" #define DEFAULT_MODEL_FILENAME "model01.bin" @@ -42,3 +47,22 @@ const char * loadModel(const char * filename); const char * createModel(int category); +struct StorageModelsList { + FIL file; +}; + +const char * storageOpenModelsList(StorageModelsList * storage); +bool storageReadNextModel(StorageModelsList * storage, char * line, int maxlen); +const char * storageInsertModel(const char * name, int category, int position); +const char * storageRemoveModel(int category, int position); +const char * storageRenameModel(const char * name, int category, int position); + +const char * storageInsertCategory(const char * name, int position); +const char * storageRenameCategory(int category, const char * name); +const char * storageRemoveCategory(int category); +bool storageReadNextCategory(StorageModelsList * storage, char * line, int maxlen); +bool storageSeekCategory(StorageModelsList * storage, int category); + +#endif + + diff --git a/radio/src/targets/horus/board_horus.h b/radio/src/targets/horus/board_horus.h index 7e2c043fe..f0af5eacf 100644 --- a/radio/src/targets/horus/board_horus.h +++ b/radio/src/targets/horus/board_horus.h @@ -180,6 +180,8 @@ void init_pxx( uint32_t module_index ); void disable_pxx( uint32_t module_index ); void init_dsm2( uint32_t module_index ); void disable_dsm2( uint32_t module_index ); +void init_crossfire( uint32_t module_index ); +void disable_crossfire( uint32_t module_index ); // Trainer driver void init_trainer_ppm(void); @@ -217,7 +219,7 @@ void watchdogInit(unsigned int duration); // ADC driver void adcInit(void); void adcRead(void); -inline uint16_t getAnalogValue(uint32_t value); +uint16_t getAnalogValue(uint32_t value); #if defined(REV3) #define BATT_SCALE 120 diff --git a/radio/src/targets/horus/diskio.cpp b/radio/src/targets/horus/diskio.cpp index da5b31ef4..1c17c8cb2 100644 --- a/radio/src/targets/horus/diskio.cpp +++ b/radio/src/targets/horus/diskio.cpp @@ -7,9 +7,8 @@ #include "diskio.h" #include // memcpy - -#include "../horus/sdio_sd.h" -#include "stm32f4xx.h" +#include "../../opentx.h" +#include "sdio_sd.h" #define BLOCK_SIZE 512 /* Block Size in Bytes */ diff --git a/radio/src/targets/horus/pulses_driver.cpp b/radio/src/targets/horus/pulses_driver.cpp index 7daa3f516..d4d9303e9 100644 --- a/radio/src/targets/horus/pulses_driver.cpp +++ b/radio/src/targets/horus/pulses_driver.cpp @@ -92,6 +92,14 @@ void disable_no_pulses(uint32_t port) TIM1->CR1 &= ~TIM_CR1_CEN ; } +void init_crossfire(uint32_t port) +{ +} + +void disable_crossfire(uint32_t port) +{ +} + void init_pxx(uint32_t port) { EXTERNAL_MODULE_ON(); diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index 1ce9c880a..8f9e0dd66 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -36,8 +36,6 @@ #include "../../opentx.h" -extern Fifo<512> telemetryFifo; - void telemetryPortInit(uint32_t baudrate) { if (baudrate == 0) { diff --git a/radio/src/targets/horus/usbd_cdc.cpp b/radio/src/targets/horus/usbd_cdc.cpp index d3c3f1d40..ef8d4933d 100644 --- a/radio/src/targets/horus/usbd_cdc.cpp +++ b/radio/src/targets/horus/usbd_cdc.cpp @@ -29,12 +29,12 @@ #pragma data_alignment = 4 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -#include "opentx.h" +#include "../../opentx.h" extern "C" { /* Includes ------------------------------------------------------------------*/ -#include "../horus/usb_conf.h" +#include "usb_conf.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ diff --git a/radio/src/targets/horus/usbd_desc.c b/radio/src/targets/horus/usbd_desc.c index d71600eef..a2a60f0ab 100644 --- a/radio/src/targets/horus/usbd_desc.c +++ b/radio/src/targets/horus/usbd_desc.c @@ -26,12 +26,12 @@ */ /* Includes ------------------------------------------------------------------*/ -#include "../horus/usbd_desc.h" +#include "usbd_desc.h" #include -#include "../horus/board_horus.h" -#include "../horus/usbd_conf.h" +#include "board_horus.h" +#include "usbd_conf.h" #include "usbd_core.h" #include "usbd_req.h" #include "usb_regs.h" diff --git a/radio/src/targets/simu/CMakeLists.txt b/radio/src/targets/simu/CMakeLists.txt new file mode 100644 index 000000000..215e7c9b0 --- /dev/null +++ b/radio/src/targets/simu/CMakeLists.txt @@ -0,0 +1,11 @@ +set(SRC ${SRC} simu.cpp targets/simu/simpgmspace.cpp) +foreach(FILE ${SRC}) + set(SIMU_SRC ${SIMU_SRC} ../../${FILE}) +endforeach() + +add_definitions(-DSIMU) +add_executable(simu WIN32 ${SIMU_SRC} ) +add_dependencies(simu ${FIRMWARE_DEPENDENCIES}) + +target_include_directories(simu PUBLIC /usr/local/include/fox-1.6 PUBLIC /usr/include/fox-1.6 /opt/local/include/fox-1.6) +target_link_libraries(simu FOX-1.6 pthread) \ No newline at end of file diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 6f9e8bef4..68a115123 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -34,7 +34,7 @@ * */ -#include "opentx.h" +#include "../../opentx.h" #include #include #include diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index 2cea55c5f..06e9318a6 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -242,8 +242,8 @@ void checkRotaryEncoder(void); #if !defined(SIMU) #define wdt_disable() void watchdogInit(unsigned int duration); -#define wdt_enable(x) watchdogInit(1500) -#define wdt_reset() IWDG->KR = 0xAAAA +#define wdt_enable(x) watchdogInit(1500) +#define wdt_reset() IWDG->KR = 0xAAAA #define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF) #define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF)) #define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF)) @@ -252,7 +252,7 @@ void watchdogInit(unsigned int duration); // ADC driver void adcInit(void); void adcRead(void); -inline uint16_t getAnalogValue(uint32_t value); +uint16_t getAnalogValue(uint32_t value); #define BATT_SCALE 150 @@ -372,6 +372,7 @@ void setTopBatteryValue(uint32_t volts); void usbJoystickUpdate(void); #endif +extern uint8_t currentTrainerMode; void checkTrainerSettings(void); #endif diff --git a/radio/src/targets/taranis/diskio.cpp b/radio/src/targets/taranis/diskio.cpp index d57bd284e..8e6459bc3 100644 --- a/radio/src/targets/taranis/diskio.cpp +++ b/radio/src/targets/taranis/diskio.cpp @@ -34,13 +34,9 @@ * */ -#include +#include "../../opentx.h" #include "../../thirdparty/FatFs/diskio.h" #include "../../thirdparty/FatFs/ff.h" -#include "../../thirdparty/CoOS/kernel/CoOS.h" -#include "../../debug.h" -#include "board_taranis.h" -#include "hal.h" /* Definitions for MMC/SDC command */ #define CMD0 (0x40+0) /* GO_IDLE_STATE */ diff --git a/radio/src/tasks_arm.cpp b/radio/src/tasks_arm.cpp index 640dca234..53a925404 100644 --- a/radio/src/tasks_arm.cpp +++ b/radio/src/tasks_arm.cpp @@ -36,17 +36,6 @@ #include "opentx.h" -#define MENUS_STACK_SIZE 2000 -#define MIXER_STACK_SIZE 500 -#define AUDIO_STACK_SIZE 500 -#define BLUETOOTH_STACK_SIZE 500 - -#if defined(_MSC_VER) - #define _ALIGNED(x) __declspec(align(x)) -#elif defined(__GNUC__) - #define _ALIGNED(x) __attribute__ ((aligned(x))) -#endif - OS_TID menusTaskId; // menus stack must be aligned to 8 bytes otherwise printf for %f does not work! TaskStack _ALIGNED(8) menusStack; @@ -102,12 +91,6 @@ uint16_t getStackAvailable(void * address, uint16_t size) #endif } -template -uint16_t TaskStack::available() -{ - return getStackAvailable(stack, SIZE); -} - void stackPaint() { menusStack.paint(); diff --git a/radio/src/tasks_arm.h b/radio/src/tasks_arm.h index e4d61db91..ffe3d055e 100644 --- a/radio/src/tasks_arm.h +++ b/radio/src/tasks_arm.h @@ -43,6 +43,19 @@ extern "C" { } #endif +#define MENUS_STACK_SIZE 2000 +#define MIXER_STACK_SIZE 500 +#define AUDIO_STACK_SIZE 500 +#define BLUETOOTH_STACK_SIZE 500 + +#if defined(_MSC_VER) +#define _ALIGNED(x) __declspec(align(x)) +#elif defined(__GNUC__) +#define _ALIGNED(x) __attribute__ ((aligned(x))) +#endif + +uint16_t getStackAvailable(void * address, uint16_t size); + template class TaskStack { @@ -50,7 +63,10 @@ class TaskStack TaskStack() { } void paint(); uint16_t size(); - uint16_t available(); + uint16_t available() + { + return getStackAvailable(stack, SIZE); + } OS_STK stack[SIZE]; }; @@ -58,4 +74,16 @@ void stackPaint(); uint16_t stackSize(); uint16_t stackAvailable(); +extern OS_TID menusTaskId; +// menus stack must be aligned to 8 bytes otherwise printf for %f does not work! +extern TaskStack _ALIGNED(8) menusStack; + +extern OS_TID mixerTaskId; +extern TaskStack mixerStack; + +extern OS_TID audioTaskId; +extern TaskStack audioStack; + +void tasksStart(); + #endif // _TASKS_ARM_H_ diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index 1cc274db7..c44ede300 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -491,7 +491,7 @@ enum FrSkyDataState { #endif }; -#if defined(CPUARM) || defined(PCBFLAMENCO) +#if defined(CPUARM) #define frskySendAlarms() #else #define SEND_RSSI_ALARMS 6 @@ -550,6 +550,8 @@ void frskySetCellVoltage(uint8_t battnumber, frskyCellVoltage_t cellVolts); void frskyUpdateCells(void); #endif +void processSerialData(uint8_t data); + #if defined(PCBTARANIS) inline uint8_t modelTelemetryProtocol() { diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 64cf25b19..37b8f559d 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -37,6 +37,8 @@ #ifndef TELEMETRY_H #define TELEMETRY_H +extern Fifo<512> telemetryFifo; + enum TelemetryProtocol { TELEM_PROTO_FRSKY_D, @@ -167,6 +169,8 @@ class TelemetryItem extern TelemetryItem telemetryItems[MAX_SENSORS]; extern uint8_t allowNewSensors; +bool isGPSSensor(int sensor); + inline bool isTelemetryFieldAvailable(int index) { TelemetrySensor & sensor = g_model.telemetrySensors[index]; diff --git a/radio/src/thirdparty/Lua/src/lvm.c b/radio/src/thirdparty/Lua/src/lvm.c index ac7b51c68..26dbe52dc 100644 --- a/radio/src/thirdparty/Lua/src/lvm.c +++ b/radio/src/thirdparty/Lua/src/lvm.c @@ -145,7 +145,6 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) { - TRACE("ERREUR ICI"); luaG_typeerror(L, t, "index"); } if (ttisfunction(tm) || ttislightfunction(tm)) { diff --git a/radio/src/trainer_input.h b/radio/src/trainer_input.h index c84264ffc..1ea2a42c9 100644 --- a/radio/src/trainer_input.h +++ b/radio/src/trainer_input.h @@ -34,10 +34,10 @@ * */ -#ifndef trainer_input_h -#define trainer_input_h +#ifndef _TRAINER_INPUT_H_ +#define _TRAINER_INPUT_H_ -#include "myeeprom.h" +#include "opentx.h" // Trainer input channels extern int16_t ppmInput[NUM_TRAINER]; @@ -86,4 +86,4 @@ inline void captureTrainerPulses(uint16_t capture) } } -#endif +#endif // _TRAINER_INPUT_H_ diff --git a/radio/src/translations.h b/radio/src/translations.h index 6ee196e44..ace86963f 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -597,11 +597,11 @@ extern const pm_char STR_CURRENT[]; #if defined(NAVIGATION_MENUS) extern const pm_char STR_SELECT_MODEL[]; - extern const pm_char STR_CREATE_CATEGORY[]; - extern const pm_char STR_RENAME_CATEGORY[]; -extern const pm_char STR_DELETE_CATEGORY[]; + extern const pm_char STR_CREATE_CATEGORY[]; + extern const pm_char STR_RENAME_CATEGORY[]; +extern const pm_char STR_DELETE_CATEGORY[]; extern const pm_char STR_CREATE_MODEL[]; - extern const pm_char STR_DUPLICATE_MODEL[]; + extern const pm_char STR_DUPLICATE_MODEL[]; extern const pm_char STR_COPY_MODEL[]; extern const pm_char STR_MOVE_MODEL[]; extern const pm_char STR_DELETE_MODEL[]; @@ -669,10 +669,10 @@ extern const pm_char STR_NO_SOUNDS_ON_SD[]; extern const pm_char STR_NO_MODELS_ON_SD[]; extern const pm_char STR_NO_BITMAPS_ON_SD[]; extern const pm_char STR_NO_SCRIPTS_ON_SD[]; -extern const pm_char STR_SCRIPT_SYNTAX_ERROR[]; -extern const pm_char STR_SCRIPT_PANIC[]; -extern const pm_char STR_SCRIPT_KILLED[]; -extern const pm_char STR_SCRIPT_ERROR[]; +extern const pm_char STR_SCRIPT_SYNTAX_ERROR[]; +extern const pm_char STR_SCRIPT_PANIC[]; +extern const pm_char STR_SCRIPT_KILLED[]; +extern const pm_char STR_SCRIPT_ERROR[]; extern const pm_char STR_PLAY_FILE[]; extern const pm_char STR_ASSIGN_BITMAP[]; extern const pm_char STR_EXECUTE_FILE[]; @@ -724,15 +724,48 @@ extern const pm_char STR_BLCOLOR[]; #endif struct LanguagePack { - const char *id; - const char *name; + const char * id; + const char * name; void (*playNumber)(getvalue_t number, uint8_t unit, uint8_t flags, uint8_t id); void (*playDuration)(int seconds, uint8_t flags, uint8_t id); }; - extern const LanguagePack * LP_CONST languagePacks[]; + extern const LanguagePack * currentLanguagePack; extern uint8_t currentLanguagePackIdx; + + extern LP_CONST LanguagePack czLanguagePack; + extern LP_CONST LanguagePack enLanguagePack; + extern LP_CONST LanguagePack esLanguagePack; + extern LP_CONST LanguagePack frLanguagePack; + extern LP_CONST LanguagePack deLanguagePack; + extern LP_CONST LanguagePack itLanguagePack; + extern LP_CONST LanguagePack plLanguagePack; + extern LP_CONST LanguagePack ptLanguagePack; + extern LP_CONST LanguagePack skLanguagePack; + extern LP_CONST LanguagePack seLanguagePack; + extern LP_CONST LanguagePack huLanguagePack; + + static const LanguagePack * LP_CONST languagePacks[] = { + // alphabetical order + &czLanguagePack, + &deLanguagePack, + &enLanguagePack, + &esLanguagePack, + &frLanguagePack, + &huLanguagePack, + &itLanguagePack, + &plLanguagePack, + &ptLanguagePack, + &seLanguagePack, + &skLanguagePack, + NULL + }; + +#if defined(SIMU) #define LANGUAGE_PACK_DECLARE(lng, name) LP_CONST LanguagePack lng ## LanguagePack = { #lng, name, lng ## _ ## playNumber, lng ## _ ## playDuration } +#else + #define LANGUAGE_PACK_DECLARE(lng, name) extern LP_CONST LanguagePack lng ## LanguagePack = { #lng, name, lng ## _ ## playNumber, lng ## _ ## playDuration } +#endif #define LANGUAGE_PACK_DECLARE_DEFAULT(lng, name) LANGUAGE_PACK_DECLARE(lng, name); const LanguagePack * currentLanguagePack = & lng ## LanguagePack; uint8_t currentLanguagePackIdx inline PLAY_FUNCTION(playNumber, getvalue_t number, uint8_t unit, uint8_t flags) { currentLanguagePack->playNumber(number, unit, flags, id); } inline PLAY_FUNCTION(playDuration, int seconds, uint8_t flags) { currentLanguagePack->playDuration(seconds, flags, id); } @@ -773,7 +806,7 @@ extern const pm_char STR_BLCOLOR[]; extern const pm_char STR_PREFLIGHT[]; extern const pm_char STR_CHECKLIST[]; extern const pm_char STR_VIEW_NOTES[]; -extern const pm_char STR_MODEL_SELECT[]; + extern const pm_char STR_MODEL_SELECT[]; extern const pm_char STR_RESET_SUBMENU[]; extern const pm_char STR_LOWALARM[]; extern const pm_char STR_CRITICALALARM[]; @@ -800,10 +833,10 @@ extern const pm_char STR_MODEL_SELECT[]; extern const pm_char STR_TELEMETRYFULL[]; extern const pm_char STR_INVERTED_SERIAL[]; extern const pm_char STR_IGNORE_INSTANCE[]; - extern const pm_char STR_DISCOVER_SENSORS[]; + extern const pm_char STR_DISCOVER_SENSORS[]; extern const pm_char STR_STOP_DISCOVER_SENSORS[]; extern const pm_char STR_DELETE_ALL_SENSORS[]; - extern const pm_char STR_CONFIRMDELETE[]; + extern const pm_char STR_CONFIRMDELETE[]; #endif #if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS) @@ -823,10 +856,10 @@ extern const pm_char STR_MODEL_SELECT[]; extern const pm_char STR_SMOOTH[]; extern const pm_char STR_COPY_STICKS_TO_OFS[]; extern const pm_char STR_COPY_TRIMS_TO_OFS[]; - extern const pm_char STR_INCDEC[]; - extern const pm_char STR_GLOBALVAR[]; - extern const pm_char STR_MIXSOURCE[]; - extern const pm_char STR_CONSTANT[]; + extern const pm_char STR_INCDEC[]; + extern const pm_char STR_GLOBALVAR[]; + extern const pm_char STR_MIXSOURCE[]; + extern const pm_char STR_CONSTANT[]; extern const pm_char STR_TOP_BAR[]; extern const pm_char STR_ALTITUDE[]; extern const pm_char STR_SCALE[]; diff --git a/radio/src/translations/CMakeLists.txt b/radio/src/translations/CMakeLists.txt new file mode 100644 index 000000000..9f2aafb9d --- /dev/null +++ b/radio/src/translations/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB translations *.h.txt) +foreach(translation ${translations}) + get_filename_component(language ${translation} NAME_WE) + get_filename_component(path ${translation} DIRECTORY) + set(target ${language}.h) + add_custom_command( + OUTPUT ${target} + COMMAND python ${RADIO_DIRECTORY}/util/translate.py ${translation} ${target} ${language} + DEPENDS ${translation} + ) + list(APPEND translations_files ${target}) +endforeach() + +add_custom_target(firmware_translations DEPENDS ${translations_files}) \ No newline at end of file diff --git a/radio/util/commit-tests.sh b/radio/util/commit-tests.sh index 957b69039..bf256f4b2 100755 --- a/radio/util/commit-tests.sh +++ b/radio/util/commit-tests.sh @@ -20,29 +20,29 @@ make PCB=9X EXT=MAVLINK HELI=YES # OpenTX on Taranis X9E make clean make PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES WARNINGS_AS_ERRORS=YES -make simu PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES WARNINGS_AS_ERRORS=YES -make gtests PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES WARNINGS_AS_ERRORS=YES +make simu PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES +make gtests PCB=TARANIS PCBREV=REV9E HELI=YES GVARS=YES LUA=YES ./gtests # OpenTX on Taranis Plus make clean make PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES -make simu PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES -make gtests PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES +make simu PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES +make gtests PCB=TARANIS PCBREV=REVPLUS HELI=YES LUA=YES ./gtests # OpenTX on Taranis make clean make PCB=TARANIS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES -make simu PCB=TARANIS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES -make gtests PCB=TARANIS HELI=YES LUA=YES WARNINGS_AS_ERRORS=YES +make simu PCB=TARANIS HELI=YES LUA=YES +make gtests PCB=TARANIS HELI=YES LUA=YES ./gtests # OpenTX on Sky9x make clean make PCB=SKY9X HELI=YES WARNINGS_AS_ERRORS=YES -make simu PCB=SKY9X HELI=YES WARNINGS_AS_ERRORS=YES -make gtests PCB=SKY9X HELI=YES WARNINGS_AS_ERRORS=YES +make simu PCB=SKY9X HELI=YES +make gtests PCB=SKY9X HELI=YES ./gtests # OpenTX on Gruvin9x