Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 90e4ecf605 |
@@ -1,69 +0,0 @@
|
||||
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference
|
||||
version: 2.1
|
||||
|
||||
# Define a job to be invoked later in a workflow.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
|
||||
jobs:
|
||||
build-elrsv2:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=NO LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO PCBI6_ELRSV2=YES" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-elrsv2-<< pipeline.git.tag >>.bin
|
||||
build-gvars:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=YES LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-gvars-<< pipeline.git.tag >>.bin
|
||||
build-heli:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=YES GVARS=YES LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-heli-<< pipeline.git.tag >>.bin
|
||||
publish-github-release:
|
||||
docker:
|
||||
- image: cibuilds/github:0.13
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ./artifacts
|
||||
- run:
|
||||
name: "Publish Release on GitHub"
|
||||
command: |
|
||||
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete latest ./artifacts/
|
||||
# Invoke jobs via workflows
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
|
||||
workflows:
|
||||
openi6x-workflow:
|
||||
jobs:
|
||||
- build-elrsv2
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- build-gvars
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- build-heli
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- publish-github-release:
|
||||
requires:
|
||||
- build-elrsv2
|
||||
- build-gvars
|
||||
- build-heli
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
# Handle line endings automatically for files detected as text
|
||||
# and leave all files detected as binary untouched.
|
||||
* text=auto
|
||||
|
||||
#
|
||||
# The above will handle all files NOT found below
|
||||
#
|
||||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
|
||||
# Source files
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx text
|
||||
*.cpp text
|
||||
*.c++ text
|
||||
*.hpp text
|
||||
*.h text
|
||||
*.h++ text
|
||||
*.hh text
|
||||
*.lua text
|
||||
*.pxd text
|
||||
*.py text
|
||||
*.py3 text
|
||||
*.pyw text
|
||||
*.pyx text
|
||||
*.pl text
|
||||
*.pm text
|
||||
*.sln text eol=crlf
|
||||
*.csproj text eol=crlf
|
||||
*.vbproj text eol=crlf
|
||||
*.vcxproj text eol=crlf
|
||||
*.vcproj text eol=crlf
|
||||
*.dbproj text eol=crlf
|
||||
*.fsproj text eol=crlf
|
||||
*.lsproj text eol=crlf
|
||||
*.wixproj text eol=crlf
|
||||
*.modelproj text eol=crlf
|
||||
*.sqlproj text eol=crlf
|
||||
*.wmaproj text eol=crlf
|
||||
*.xproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.filters text eol=crlf
|
||||
*.vcxitems text eol=crlf
|
||||
*.sh eol=lf
|
||||
|
||||
# Compiled Object files
|
||||
*.slo binary
|
||||
*.lo binary
|
||||
*.o binary
|
||||
*.obj binary
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch binary
|
||||
*.pch binary
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so binary
|
||||
*.dylib binary
|
||||
*.dll binary
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai binary
|
||||
*.la binary
|
||||
*.a binary
|
||||
*.lib binary
|
||||
|
||||
# Executables
|
||||
*.exe binary
|
||||
*.out binary
|
||||
*.app binary
|
||||
|
||||
# Binary files
|
||||
*.db binary
|
||||
*.p binary
|
||||
*.pkl binary
|
||||
*.pyc binary
|
||||
*.pyd binary
|
||||
*.pyo binary
|
||||
|
||||
# Documents
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
*.md text
|
||||
*.adoc text
|
||||
*.textile text
|
||||
*.mustache text
|
||||
*.csv text
|
||||
*.tab text
|
||||
*.tsv text
|
||||
*.sql text
|
||||
|
||||
# Graphics
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.ico binary
|
||||
# SVG treated as an asset (binary) by default. If you want to treat it as text,
|
||||
# comment-out the following line and uncomment the line after.
|
||||
*.svg binary
|
||||
#*.svg text
|
||||
*.eps binary
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help the OpenTX team to improve OpenTX
|
||||
|
||||
---
|
||||
*Before submitting, search the open issue if there is already a report of the bug*
|
||||
|
||||
Also often minor bugs are already fixed in nightly builds, often it is
|
||||
a good idea to test (in a controlled environment like a bench setup)
|
||||
with a nightly firmware to see if the bug still exists.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**General information**
|
||||
- OpenTX version (e.g. 2.1.23 or N123)
|
||||
- Hardware (e.g. Frsky X9D+ or 9X Pro)
|
||||
- OpenTX Companion (e.g. 2.1.23 on Ubuntu 16.04)
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
name: Help
|
||||
about: Problems or question of using OpenTX
|
||||
|
||||
---
|
||||
|
||||
The issue tracker here is for devlopment of OpenTX. This is not a
|
||||
support site, only a bug tracking system. Please use support groups
|
||||
like [rcgroups](https://rcgroups.com/) or
|
||||
[openrcforum](https://www.openrcforums.com/forum/). See also our
|
||||
[manual](https://opentx.gitbooks.io/manual-for-opentx-2-2/).
|
||||
|
||||
For quick questions you can also join our general chat.
|
||||
|
||||
Issues that fall into the category of asking for help, will be
|
||||
generally closed as invalid without an answer.
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project to make OpenTX even better
|
||||
|
||||
---
|
||||
*Before suggesting a new feature here, please search the open issue if there is already a request for the feature*
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/.idea/
|
||||
/.*project
|
||||
/.settings
|
||||
/.autotools
|
||||
/*.user
|
||||
/*.user.*
|
||||
build*/
|
||||
cmake-build-*/
|
||||
/debian/
|
||||
/CMakeFiles/*
|
||||
radio/src/CmakeFiles/*
|
||||
/.vscode/
|
||||
*.cmake
|
||||
*.make
|
||||
*.marks
|
||||
/nbproject/
|
||||
*.bin
|
||||
/radio/src/CMakeFiles/firmware.dir/link.txt
|
||||
.push.settings.jsonc
|
||||
build.sh
|
||||
firm.sh
|
||||
flash.sh
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "radio/src/thirdparty/GCS_MAVLink/include_v1.0"]
|
||||
path = radio/src/thirdparty/GCS_MAVLink/include_v1.0
|
||||
url = https://github.com/mavlink/c_library_v1.git
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
|
||||
env:
|
||||
global:
|
||||
# - QT_BASE=53
|
||||
# - QT_BASE=54
|
||||
# - QT_BASE=55
|
||||
# - QT_BASE=56
|
||||
- QT_BASE=57
|
||||
# - GCC_ARM=/opt/gcc-arm-none-eabi/bin
|
||||
- PYTHONPATH=${PYTHONPATH}:/usr/lib/python3/dist-packages
|
||||
matrix:
|
||||
#
|
||||
# ALL will build every individual board & DEFAULT, sequentially.
|
||||
# DEFAULT is "make all" (including Companion & Simulator), with default settings
|
||||
#
|
||||
# - FLAVOR=ALL
|
||||
- FLAVOR=DEFAULT
|
||||
- FLAVOR=ARM9X
|
||||
# - FLAVOR=AR9X
|
||||
# - FLAVOR=SKY9X
|
||||
# - FLAVOR=9XRPRO
|
||||
- FLAVOR=X7
|
||||
- FLAVOR=XLITE
|
||||
- FLAVOR=X9
|
||||
# - FLAVOR=X9D
|
||||
# - FLAVOR=X9D+
|
||||
# - FLAVOR=X9E
|
||||
- FLAVOR=HORUS
|
||||
# - FLAVOR=X10
|
||||
# - FLAVOR=X12Sr10
|
||||
# - FLAVOR=X12S
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository ppa:ubuntu-sdk-team/ppa --yes
|
||||
- sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded --yes
|
||||
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test --yes
|
||||
- if [ "$QT_BASE" = "53" ]; then sudo add-apt-repository ppa:beineri/opt-qt532-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "54" ]; then sudo add-apt-repository ppa:beineri/opt-qt542-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "55" ]; then sudo add-apt-repository ppa:beineri/opt-qt551-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "56" ]; then sudo add-apt-repository ppa:beineri/opt-qt562-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "57" ]; then sudo add-apt-repository ppa:beineri/opt-qt571-trusty -y; fi
|
||||
- sudo apt-get update -qq
|
||||
- pyenv uninstall -f 2.7.6 && pyenv install 3.5.4 && pyenv global 3.5.4
|
||||
- pip install pillow
|
||||
|
||||
install:
|
||||
- sudo apt-get --yes --force-yes install curl libmpfr4 libmpc3 libfox-1.6-dev libgtest-dev
|
||||
- sudo apt-get --yes --force-yes install gcc-arm-none-eabi
|
||||
# Trying to build with gcc-arm 4.7 isn't working because it can't find the compiler, despite adding to PATH (in commit-tests.sh) by defining GCC_ARM above
|
||||
# - wget --quiet https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q3-update/+download/gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2
|
||||
# - tar xjf gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2
|
||||
# - mv gcc-arm-none-eabi-4_7-2013q3 /opt/gcc-arm-none-eabi
|
||||
- sudo apt-get install --yes --force-yes -qq qt${QT_BASE}base qt${QT_BASE}multimedia qt${QT_BASE}svg qt${QT_BASE}tools; source /opt/qt${QT_BASE}/bin/qt${QT_BASE}-env.sh
|
||||
|
||||
script:
|
||||
- ./tools/commit-tests.sh
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
project(OpenTX)
|
||||
|
||||
set(VERSION_MAJOR "2")
|
||||
set(VERSION_MINOR "3")
|
||||
set(VERSION_REVISION "0")
|
||||
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
|
||||
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
|
||||
set(SDCARD_REVISION "0018")
|
||||
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
cmake_policy(SET CMP0023 OLD)
|
||||
if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0043)
|
||||
cmake_policy(SET CMP0043 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0058)
|
||||
cmake_policy(SET CMP0058 NEW) # for ninja
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio)
|
||||
set(RADIO_SRC_DIRECTORY ${RADIO_DIRECTORY}/src)
|
||||
set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src)
|
||||
set(SIMU_SRC_DIRECTORY ${COMPANION_SRC_DIRECTORY}/simulation)
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include(Macros)
|
||||
today(DATE)
|
||||
now(TIME)
|
||||
git_id(GIT_STR)
|
||||
|
||||
message(STATUS "OpenTX ${VERSION} @${GIT_STR}")
|
||||
|
||||
# options shared by all targets
|
||||
|
||||
option(APP_CUSTOM_DBG_HANDLER "Use custom message handler for debug output in all Qt apps." ON)
|
||||
set(APP_CUSTOM_DBG_LEVEL "0" CACHE STRING
|
||||
"Debug output level: 0=debug+; 1=info+; 2=warn+; 3=critical+; 4=fatal only.")
|
||||
set(APP_CUSTOM_DBG_SHOW_FILE "DEFAULT" CACHE STRING
|
||||
"Show source file names in debug output. 1/0/DEFAULT (default is ON with DEBUG builds).")
|
||||
|
||||
option(VERBOSE_CMAKELISTS "Show extra information while processing CMakeLists.txt files." OFF)
|
||||
option(WARNINGS_AS_ERRORS "Treat any compiler warning as an error (adds -Werror flag)." OFF)
|
||||
|
||||
if(WIN32)
|
||||
set(WIN_EXTRA_LIBS_PATH "C:/Programs" CACHE PATH
|
||||
"Base path to extra libs/headers on Windows (SDL & pthreads folders should be in here).")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/SDL") # hints for FindSDL
|
||||
endif()
|
||||
|
||||
# Python check
|
||||
find_package("PythonInterp")
|
||||
if(PYTHONINTERP_FOUND)
|
||||
message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
|
||||
get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY)
|
||||
else()
|
||||
message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
|
||||
set(LUA NO)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # regular Clang or AppleClang
|
||||
set(CLANG TRUE)
|
||||
endif()
|
||||
|
||||
option(DISABLE_COMPANION "Disable building companion and simulators" OFF)
|
||||
|
||||
if(NOT DISABLE_COMPANION) # FIXME cosmetics/style
|
||||
find_package(Qt5Core)
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
find_package(Qt5LinguistTools)
|
||||
find_package(Qt5PrintSupport)
|
||||
find_package(Qt5Multimedia)
|
||||
find_package(Qt5Svg)
|
||||
|
||||
if(Qt5Core_FOUND)
|
||||
message(STATUS "Qt Version: ${Qt5Core_VERSION}")
|
||||
|
||||
### Get locations of Qt binary executables & libs (libs are for distros, not for linking)
|
||||
# first set up some hints
|
||||
get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
|
||||
get_filename_component(qt_core_path ${QtCore_LOCATION} PATH)
|
||||
if(APPLE)
|
||||
get_filename_component(qt_core_path "${qt_core_path}/.." ABSOLUTE)
|
||||
endif()
|
||||
|
||||
set(QT_LIB_DIR ${qt_core_path} CACHE PATH "Path to Qt libraries (.dll|.framework|.so).")
|
||||
find_path(QT_BIN_DIR NAMES "qmake" "qmake.exe" HINTS "${CMAKE_PREFIX_PATH}/bin" "${qt_core_path}/../bin" "${qt_core_path}" DOC "Path to Qt binaries (qmake, lupdate, etc.).")
|
||||
find_program(QT_QMAKE_EXECUTABLE qmake HINTS "${QT_BIN_DIR}" DOC "Location of qmake program.")
|
||||
find_program(QT_LUPDATE_EXECUTABLE lupdate HINTS "${QT_BIN_DIR}" DOC "Location of Qt's 'lupdate' program for updating translation files.")
|
||||
|
||||
# Try to find Qt translations
|
||||
if(QT_QMAKE_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
|
||||
OUTPUT_VARIABLE qt_translations_hint
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
find_path(QT_TRANSLATIONS_DIR NAMES "qt_en.qm" HINTS "${qt_translations_hint}" DOC "Path to prebuilt Qt translations (qt_*.qm).")
|
||||
|
||||
### Common definitions for the Qt-based apps
|
||||
list(APPEND APP_COMMON_DEFINES -DSIMU)
|
||||
list(APPEND APP_COMMON_DEFINES -DQXT_STATIC)
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_USE_QSTRINGBUILDER) # more efficient QString construction using % operator
|
||||
|
||||
if(MSVC)
|
||||
list(APPEND APP_COMMON_DEFINES -D__STDC_LIMIT_MACROS)
|
||||
endif()
|
||||
if(APP_CUSTOM_DBG_HANDLER)
|
||||
# provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=1)
|
||||
if(APP_CUSTOM_DBG_LEVEL GREATER -1 AND APP_CUSTOM_DBG_LEVEL LESS 5)
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_DEFAULT_LEVEL=${APP_CUSTOM_DBG_LEVEL})
|
||||
endif()
|
||||
if(NOT APP_CUSTOM_DBG_SHOW_FILE STREQUAL "DEFAULT" AND (APP_CUSTOM_DBG_SHOW_FILE STREQUAL "1" OR APP_CUSTOM_DBG_SHOW_FILE STREQUAL "0"))
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_SHOW_SRC_PATH=${APP_CUSTOM_DBG_SHOW_FILE})
|
||||
endif()
|
||||
else()
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0)
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Qt not found! Companion and Simulator builds disabled.")
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package(Fox QUIET) # QUIET not working on WIN32?
|
||||
if (FOX_FOUND)
|
||||
message(STATUS "Foxlib found at ${FOX_LIBRARY}")
|
||||
else() # if(NOT WIN32)
|
||||
message("Libfox not found, simu target will not be available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5Core_FOUND OR FOX_FOUND)
|
||||
set(SDL_BUILDING_LIBRARY YES) # this prevents FindSDL from appending SDLmain lib to the results, which we don't want
|
||||
find_package("SDL")
|
||||
if(SDL_FOUND)
|
||||
message(STATUS "SDL Lib: ${SDL_LIBRARY}; Headers: ${SDL_INCLUDE_DIR}; Version: ${SDL_VERSION_STRING}")
|
||||
if (NOT ${SDL_VERSION_STRING} VERSION_LESS "2.0")
|
||||
message(FATAL_ERROR "OpenTX requires SDL 1.x, not 2.x")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.")
|
||||
endif()
|
||||
endif()
|
||||
endif(NOT DISABLE_COMPANION)
|
||||
|
||||
# Check for a file that is typically left from a OpenTX 2.1 build and abort if found
|
||||
if (EXISTS ${RADIO_SRC_DIRECTORY}/stamp.h OR EXISTS ${RADIO_SRC_DIRECTORY}/translations/en.h)
|
||||
message(FATAL_ERROR "Source directory contains files leftover from a OpenTX 2.1 build. Please run `git clean -f` in source directory (Careful: Will remove any extra files) or do a new clean git checkout")
|
||||
endif()
|
||||
|
||||
# Windows-specific includes and libs shared by sub-projects
|
||||
if(WIN32)
|
||||
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/dirent")
|
||||
if(MSVC)
|
||||
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/msinttypes")
|
||||
set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2" CACHE PATH "Where to find pthreads include and lib folders.")
|
||||
list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include")
|
||||
find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH)
|
||||
find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH)
|
||||
if(WIN_PTHREAD_LIB)
|
||||
list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}")
|
||||
else()
|
||||
message(SEND_ERROR "pthreadVC2.lib not found!")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(${RADIO_SRC_DIRECTORY})
|
||||
|
||||
if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)
|
||||
add_subdirectory(${COMPANION_SRC_DIRECTORY})
|
||||
endif()
|
||||
-1493
File diff suppressed because it is too large
Load Diff
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -1,52 +0,0 @@
|
||||
# FlySky i6x port of OpenTX
|
||||
|
||||
This is a port of OpenTX for the venerable Flysky I6X RC radio transmitter. You can find the latest build and some instructions and videos contributed by fellow early adopters in the [RCGroups thread](https://www.rcgroups.com/forums/showthread.php?3916435-FlySky-I6X-port-of-OpenTX)
|
||||
|
||||
## Implemented features
|
||||
|
||||
* AFHDS2A protocol
|
||||
* PPM out
|
||||
* CRSF working with ExpressLRS and Crossfire modules at rates from 115k to 3.75M bauds, CRSFshot enabled
|
||||
* Telemetry
|
||||
* Audio tones, alarms and vario custom implementation (Janek)
|
||||
* USB (To enable on standard cable: General Settings > USB Detect set to "Once") (Janek)
|
||||
* Joystick mode (Janek)
|
||||
* Mass Storage to backup/restore eeprom (Janek)
|
||||
* ExpressLRS V1.x configuration in model setup
|
||||
|
||||
## Users Telegram group
|
||||
|
||||
https://t.me/otx_flysky_i6x
|
||||
|
||||
## Navigation:
|
||||
|
||||
| Key | Function |
|
||||
| --- | --- |
|
||||
| UP | Hold for stats |
|
||||
| DOWN | Hold for telemetry |
|
||||
| OK | Hold for Model menu |
|
||||
| CANCEL | EXIT. Hold for graceful shutdown (Needed to save timers) |
|
||||
| BIND | Go RIGHT. Go to next PAGE. Hold for general menu. |
|
||||
| RIGHT POT | Scroll right or left |
|
||||
|
||||
## ST-Link pinout
|
||||
|
||||

|
||||
|
||||
## Linux instructions
|
||||
### Compile
|
||||
`docker run --rm -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=NO LUA_COMPILER=NO MULTIMODULE=NO DEBUG=YES" -v $PWD:/opentx vitass/opentx-fw-build`
|
||||
|
||||
### Flash
|
||||
`sudo st-flash write <file_to_flash>.bin 0x08000000`
|
||||
|
||||
### Debug tty:
|
||||
`sudo cat /dev/ttyUSB0 115200`
|
||||
|
||||
## Contributors
|
||||
|
||||
* Janek (@ajjjjjjjj) ongoing collaboration.
|
||||
* All the RF code was taken from the great KotelloRC's erfly6: Er9X for i6 and i6x. You can find his project here: https://bitbucket.org/KotelloRC/erfly6/src/master/
|
||||
* ADC code taken from OpenGround: https://github.com/fishpepper/OpenGround
|
||||
* This work is based on Jakub's (qba667) work and is forked from his repo.
|
||||
* All the contributors of OpenTX.
|
||||
@@ -0,0 +1,5 @@
|
||||
TODO list (no particular order)
|
||||
|
||||
- DSM2 channel order (Cam)
|
||||
- Variometer (rate as cm/sec)
|
||||
- Trace telemetry data
|
||||
@@ -0,0 +1,206 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page
|
||||
#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program
|
||||
#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from
|
||||
#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application
|
||||
|
||||
#define TWI_CMD_REBOOT 0x55 // TWI Command to restart back in the bootloader
|
||||
|
||||
#define TWI_SUBCMD_SETDATETIME 0x74 // TWI Command to set the date and time
|
||||
//#define TWI_CMD_BVERSION 0x04 // TWI Command to get the bootloader revision identifier
|
||||
//#define TWI_CMD_ERASEFLASH 0x05 // TWI Command to erase the entire application section of flash memory
|
||||
//#define TWI_CMD_GETERRCONDN 0x07 // TWI Command to get Error condition
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
//#define BOOT_SETTLE_DELAY 100 // Debounce delay for the boot pin in MCU cycles
|
||||
//#define SLAVE_ADDRESS 0xb0 // The address identifier of this slave device on the TWI (I2C) bus
|
||||
#define INTVECT_PAGE_ADDRESS 0x000 // The location of the start of the interrupt vector table address
|
||||
|
||||
|
||||
|
||||
// Select the communcation interfacing type: TWI or USI
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
|
||||
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
|
||||
defined(__ATTINY261__) | defined(__ATTINY261A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
|
||||
defined(__ATTINY43U__) | \
|
||||
defined(__ATTINY87__) | \
|
||||
defined(__ATTINY167__)
|
||||
#define __USI__ // set the communication type as USI
|
||||
#endif */
|
||||
|
||||
#define __USI__ // set the communication type as USI
|
||||
|
||||
|
||||
/*#if defined(__ATTINY48__) | defined(__ATTINY88__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__) | \
|
||||
defined(__ATMEGA48__)
|
||||
#define __TWI__
|
||||
#endif */
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
// Page size selection for the controller with 2K flash
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY261__) | defined(__ATTINY261A__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 32
|
||||
|
||||
// Page 32, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X0400
|
||||
|
||||
// 2KB of flash divided by pages of size 32 bytes
|
||||
#define TOTAL_NO_OF_PAGES 64
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
#endif */
|
||||
|
||||
// Page size selection for the controller with 4K flash
|
||||
|
||||
/*#if defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY43U__) | \
|
||||
defined(__ATTINY48__) | \
|
||||
defined(__ATMEGA48__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 64
|
||||
|
||||
// Page 48, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X0C00
|
||||
|
||||
// 4KB of flash divided by pages of size 64 bytes
|
||||
#define TOTAL_NO_OF_PAGES 64
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
#endif */
|
||||
|
||||
|
||||
// Page size selection for the controller with 8K flash
|
||||
/*#if defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
|
||||
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
|
||||
defined(__ATTINY87__) | \
|
||||
defined(__ATTINY88__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 64
|
||||
|
||||
// Page 112, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X1C00
|
||||
|
||||
// 8KB of flash divided by pages of size 64 bytes
|
||||
#define TOTAL_NO_OF_PAGES 128
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// // For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
// #define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
//#endif*/
|
||||
|
||||
// Page size selection for the controller with 16K flash
|
||||
//#if defined(__ATTINY167__)
|
||||
|
||||
// The flash memory page size for Atiny167
|
||||
#define PAGE_SIZE 128
|
||||
|
||||
// Page 120, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X3800
|
||||
|
||||
// 16KB of flash divided by pages of size 128 bytes
|
||||
#define TOTAL_NO_OF_PAGES 128
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// Select the correct Bit name of to SELFPROGRAMming
|
||||
/*#if defined(__ATTINY48__) | defined(__ATTINY48A__) | \
|
||||
defined(__ATTINY88__) | defined(__ATTINY88A__) | \
|
||||
defined(__ATMEGA48__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
|
||||
|
||||
#define SELFPROGEN SELFPRGEN
|
||||
|
||||
#endif */
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY87__) | defined(__ATTINY167__) */
|
||||
|
||||
#define SELFPROGEN SPMEN
|
||||
|
||||
//#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#define WDT_TIMEOUT_8s ( _BV( WDP3 ) | _BV( WDP0 ) ) // Watchdog timeout for inactivity in the boot section
|
||||
#define WDT_TIMEOUT_16ms 0 // Watchdog timeout for system reset (cleanup) before jump to application
|
||||
#define WDT_TIMEOUT_min WDT_TIMEOUT_16ms // The minimum watchdog reset time interval for jump to application
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define STATUSMASK_SPMBUSY 0x01 // The mask bit for SPM busy status code
|
||||
#define STATUSMASK_BLSCERR 0x02 // The mask bit for attempt to override bootloader section
|
||||
#define STATUSMASK_TWIABORT 0x04 // The mask bit for indicating TWI abort fn called
|
||||
#define STATUSMASK_SLTR_BUSY 0x08 // The mask bit for slave transmit
|
||||
#define STATUSMASK_SLRBAA_BUSY 0x10 // The mask bit for slave receive and ack
|
||||
#define STATUSMASK_SLRBAN_BUSY 0x20 // The mask bit for slave receive and Nack
|
||||
#define STATUSMASK_EEPROM_BUSY 0x40 // The mask bit for EEPROM busy
|
||||
#define STATUSMASK_BOOTLOADER 0x80 // The mask bit for bootloader operations
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EEMEM_ADDR_AVERSION 0x05 // The address in EEPROM where application revision identifier will be stored
|
||||
#define BVERSION 0x96 // This bootloader revision identifier
|
||||
|
||||
|
||||
//static void UpdatePage (uint16_t);
|
||||
|
||||
#ifndef _BV
|
||||
#define _BV( __BIT_POSITION__ ) ( 1 << __BIT_POSITION__ )
|
||||
#endif
|
||||
|
||||
//#ifdef _BV
|
||||
//#warning _BV now stands defined
|
||||
//#endif
|
||||
@@ -0,0 +1,624 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile
|
||||
#
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude.
|
||||
# Please customize the avrdude settings below first!
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# MCU name
|
||||
MCU = attiny167
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
# Typical values are:
|
||||
# F_CPU = 1000000
|
||||
# F_CPU = 1843200
|
||||
# F_CPU = 2000000
|
||||
# F_CPU = 3686400
|
||||
# F_CPU = 4000000
|
||||
# F_CPU = 7372800
|
||||
# F_CPU = 8000000
|
||||
# F_CPU = 11059200
|
||||
# F_CPU = 14745600
|
||||
# F_CPU = 16000000
|
||||
# F_CPU = 18432000
|
||||
# F_CPU = 20000000
|
||||
F_CPU = 8000000
|
||||
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = TinyApp
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
OBJDIR = .
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
CPPSRC =
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = s
|
||||
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
# AVR Studio 4.10 requires dwarf-2.
|
||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
||||
#DEBUG = stabs
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS = c:\progs\iccv7avr\include
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here for C sources
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
||||
|
||||
|
||||
# Place -D or -U options here for ASM sources
|
||||
ADEFS = -DF_CPU=$(F_CPU)
|
||||
|
||||
|
||||
# Place -D or -U options here for C++ sources
|
||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
||||
|
||||
|
||||
|
||||
#---------------- Compiler Options C ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char
|
||||
CFLAGS += -funsigned-bitfields
|
||||
CFLAGS += -fpack-struct
|
||||
CFLAGS += -fshort-enums
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wno-main
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
#CFLAGS += -mshort-calls
|
||||
#CFLAGS += -fno-unit-at-a-time
|
||||
#CFLAGS += -Wundef
|
||||
#CFLAGS += -Wunreachable-code
|
||||
#CFLAGS += -Wsign-compare
|
||||
CFLAGS += -Wa,-adlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
# Next line dumps rtl file
|
||||
#CFLAGS += -dr
|
||||
#CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
#---------------- Compiler Options C++ ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CPPFLAGS = -g$(DEBUG)
|
||||
CPPFLAGS += $(CPPDEFS)
|
||||
CPPFLAGS += -O$(OPT)
|
||||
CPPFLAGS += -funsigned-char
|
||||
CPPFLAGS += -funsigned-bitfields
|
||||
CPPFLAGS += -fpack-struct
|
||||
CPPFLAGS += -fshort-enums
|
||||
CPPFLAGS += -fno-exceptions
|
||||
CPPFLAGS += -Wall
|
||||
CFLAGS += -Wundef
|
||||
#CPPFLAGS += -mshort-calls
|
||||
#CPPFLAGS += -fno-unit-at-a-time
|
||||
#CPPFLAGS += -Wstrict-prototypes
|
||||
#CPPFLAGS += -Wunreachable-code
|
||||
#CPPFLAGS += -Wsign-compare
|
||||
CPPFLAGS += -Wa,-adlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
#CPPFLAGS += $(CSTANDARD)
|
||||
#CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
||||
# dump that will be displayed for a given single line of source input.
|
||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
||||
|
||||
|
||||
#---------------- Library Options ----------------
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard printf version.
|
||||
PRINTF_LIB =
|
||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
||||
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard scanf version.
|
||||
SCANF_LIB =
|
||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
||||
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
|
||||
# List any extra directories to look for libraries here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRALIBDIRS =
|
||||
|
||||
|
||||
|
||||
#---------------- External Memory Options ----------------
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
LDFLAGS += -Wl,--section-start=.text=0x00D0
|
||||
LDFLAGS += -Wl,--section-start=.vectors=0x0080
|
||||
LDFLAGS += -T avr3-167.ld
|
||||
LDFLAGS += -N
|
||||
|
||||
|
||||
|
||||
#---------------- Programming Options (avrdude) ----------------
|
||||
|
||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||
#
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = stk500
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = com3
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
#---------------- Debugging Options ----------------
|
||||
|
||||
# For simulavr only - target MCU frequency.
|
||||
DEBUG_MFREQ = $(F_CPU)
|
||||
|
||||
# Set the DEBUG_UI to either gdb or insight.
|
||||
# DEBUG_UI = gdb
|
||||
DEBUG_UI = insight
|
||||
|
||||
# Set the debugging back-end to either avarice, simulavr.
|
||||
DEBUG_BACKEND = avarice
|
||||
#DEBUG_BACKEND = simulavr
|
||||
|
||||
# GDB Init Filename.
|
||||
GDBINIT_FILE = __avr_gdbinit
|
||||
|
||||
# When using avarice settings for the JTAG
|
||||
JTAG_DEV = /dev/com1
|
||||
|
||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
||||
DEBUG_PORT = 4242
|
||||
|
||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
||||
# just set to localhost unless doing some sort of crazy debugging when
|
||||
# avarice is running on a different computer.
|
||||
DEBUG_HOST = localhost
|
||||
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
AR = avr-ar rcs
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -rf
|
||||
COPY = cp
|
||||
WINSHELL = cmd
|
||||
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling C:
|
||||
MSG_COMPILING_CPP = Compiling C++:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_CREATING_LIBRARY = Creating library:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter end
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
build: elf hex eep lss sym bin
|
||||
#build: lib
|
||||
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
bin: $(TARGET).bin
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
LIBNAME=lib$(TARGET).a
|
||||
lib: $(LIBNAME)
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
|
||||
# Generate avr-gdb config/init file which does the following:
|
||||
# define the reset signal, load the target file, connect to target, and set
|
||||
# a breakpoint at main().
|
||||
gdb-config:
|
||||
@$(REMOVE) $(GDBINIT_FILE)
|
||||
@echo define reset >> $(GDBINIT_FILE)
|
||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
||||
@echo end >> $(GDBINIT_FILE)
|
||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
||||
@echo load >> $(GDBINIT_FILE)
|
||||
endif
|
||||
@echo break main >> $(GDBINIT_FILE)
|
||||
|
||||
debug: gdb-config $(TARGET).elf
|
||||
ifeq ($(DEBUG_BACKEND), avarice)
|
||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
||||
@$(WINSHELL) /c pause
|
||||
|
||||
else
|
||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
||||
endif
|
||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT = $(OBJCOPY) --debugging
|
||||
COFFCONVERT += --change-section-address .data-0x800000
|
||||
COFFCONVERT += --change-section-address .bss-0x800000
|
||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Create library from object files.
|
||||
.SECONDARY : $(TARGET).a
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.a: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_CREATING_LIBRARY) $@
|
||||
$(AR) $@ $(OBJ)
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
$(OBJDIR)/%.o : %.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C++ source files.
|
||||
%.s : %.cpp
|
||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
%.i : %.c
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).bin
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) $(SRC:.c=.i)
|
||||
$(REMOVEDIR) .dep
|
||||
|
||||
|
||||
# Create object files directory
|
||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff \
|
||||
clean clean_list program debug gdb-config
|
||||
|
||||
|
||||
|
||||
|
||||
+1070
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,174 @@
|
||||
#ifdef __USI__
|
||||
|
||||
/****************************************************************************/
|
||||
static void USI_TWI_SLAVE_Init( void );
|
||||
static void USI_TWI_SLAVE_Abort(void);
|
||||
static void USI_TWI_SLAVE_ReadAndProcessPacket(void);
|
||||
static void USI_TWI_SLAVE_Process_Start_Condition(void);
|
||||
void USI_TWI_SLAVE_Process_Overflow_Condition(void);
|
||||
|
||||
// void prog_buffer_set_byte(uint8_t );
|
||||
|
||||
// uint8_t bootloader_exit;
|
||||
uint8_t Run_boot ;
|
||||
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// TWI write states.
|
||||
#define USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE (0x00)
|
||||
#define USI_TWI_SLAVE_WRITE_ADDR_LO_BYTE (0x01)
|
||||
#define USI_TWI_SLAVE_WRITE_DATA_BYTE (0x02)
|
||||
|
||||
// TWI overflow states.
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_NONE (0x00)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX (0x01)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_RX (0x02)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX (0x03)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX (0x04)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX (0x05)
|
||||
|
||||
// newly added ..
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_CMD_RX (0x06)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION (0x07)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_BVERSION (0x08)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_GETERRCONDN (0x09)
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// typedef unsigned char uint8_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
///////////////// Driver Buffer Definitions //////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
|
||||
|
||||
#define TWI_RX_BUFFER_SIZE (16)
|
||||
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
|
||||
|
||||
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
|
||||
#error TWI RX buffer size is not a power of 2
|
||||
#endif
|
||||
|
||||
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
|
||||
|
||||
#define TWI_TX_BUFFER_SIZE (16)
|
||||
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
|
||||
|
||||
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
|
||||
#error TWI TX buffer size is not a power of 2
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define USI_SLAVE_CHECK_ADDRESS (0x00)
|
||||
#define USI_SLAVE_SEND_DATA (0x01)
|
||||
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
|
||||
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
|
||||
#define USI_SLAVE_REQUEST_DATA (0x04)
|
||||
#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*#if defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) */
|
||||
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB5
|
||||
// #define PORT_USI_SCL PORTB7
|
||||
// #define PIN_USI_SDA PINB5
|
||||
// #define PIN_USI_SCL PINB7
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_STRT_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
// defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
// defined(__ATTINY85__) | defined(__ATTINY85V__) */
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB0
|
||||
// #define PORT_USI_SCL PORTB2
|
||||
// #define PIN_USI_SDA PINB0
|
||||
// #define PIN_USI_SCL PINB2
|
||||
// #define USI_START_COND_INT USICIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
/*#if defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84V__) */
|
||||
|
||||
// #define DDR_USI DDRA
|
||||
// #define PORT_USI PORTA
|
||||
// #define PIN_USI PINA
|
||||
// #define PORT_USI_SDA PORTA6
|
||||
// #define PORT_USI_SCL PORTA4
|
||||
// #define PIN_USI_SDA PINA6
|
||||
// #define PIN_USI_SCL PINA4
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
/*#if defined(__ATTINY261__) | defined(__ATTINY261A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY861A__) | defined(__ATTINY861A__) */
|
||||
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB0
|
||||
// #define PORT_USI_SCL PORTB2
|
||||
// #define PIN_USI_SDA PINB0
|
||||
// #define PIN_USI_SCL PINB2
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
//#if defined(__ATTINY43U__)
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB4
|
||||
// #define PORT_USI_SCL PORTB6
|
||||
// #define PIN_USI_SDA PINB4
|
||||
// #define PIN_USI_SCL PINB6
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
//#if defined(__ATTINY87__) | defined(__ATTINY167__)
|
||||
|
||||
#define DDR_USI DDRB
|
||||
#define PORT_USI PORTB
|
||||
#define PIN_USI PINB
|
||||
#define PORT_USI_SDA PORTB0
|
||||
#define PORT_USI_SCL PORTB2
|
||||
#define PIN_USI_SDA PINB0
|
||||
#define PIN_USI_SCL PINB2
|
||||
#define USI_START_COND_INT USISIF
|
||||
#define USI_START_VECTOR USI_START_vect
|
||||
#define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/* Default linker script, for normal executables */
|
||||
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
|
||||
OUTPUT_ARCH(avr:3)
|
||||
MEMORY
|
||||
{
|
||||
text (rx) : ORIGIN = 0, LENGTH = 16K
|
||||
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
|
||||
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
|
||||
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
|
||||
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
|
||||
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text :
|
||||
{
|
||||
*(.rel.text)
|
||||
*(.rel.text.*)
|
||||
*(.rel.gnu.linkonce.t*)
|
||||
}
|
||||
.rela.text :
|
||||
{
|
||||
*(.rela.text)
|
||||
*(.rela.text.*)
|
||||
*(.rela.gnu.linkonce.t*)
|
||||
}
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata :
|
||||
{
|
||||
*(.rel.rodata)
|
||||
*(.rel.rodata.*)
|
||||
*(.rel.gnu.linkonce.r*)
|
||||
}
|
||||
.rela.rodata :
|
||||
{
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata.*)
|
||||
*(.rela.gnu.linkonce.r*)
|
||||
}
|
||||
.rel.data :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.gnu.linkonce.d*)
|
||||
}
|
||||
.rela.data :
|
||||
{
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.gnu.linkonce.d*)
|
||||
}
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
/* Internal text space or external memory. */
|
||||
.vectors :
|
||||
{
|
||||
*(.vectors)
|
||||
KEEP(*(.vectors))
|
||||
}
|
||||
.text :
|
||||
{
|
||||
/* For data that needs to reside in the lower 64k of progmem. */
|
||||
*(.progmem.gcc*)
|
||||
*(.progmem*)
|
||||
. = ALIGN(2);
|
||||
__trampolines_start = . ;
|
||||
/* The jump trampolines for the 16-bit limited relocs will reside here. */
|
||||
*(.trampolines)
|
||||
*(.trampolines*)
|
||||
__trampolines_end = . ;
|
||||
/* For future tablejump instruction arrays for 3 byte pc devices.
|
||||
We don't relax jump/call instructions within these sections. */
|
||||
*(.jumptables)
|
||||
*(.jumptables*)
|
||||
/* For code that needs to reside in the lower 128k progmem. */
|
||||
*(.lowtext)
|
||||
*(.lowtext*)
|
||||
__ctors_start = . ;
|
||||
*(.ctors)
|
||||
__ctors_end = . ;
|
||||
__dtors_start = . ;
|
||||
*(.dtors)
|
||||
__dtors_end = . ;
|
||||
KEEP(SORT(*)(.ctors))
|
||||
KEEP(SORT(*)(.dtors))
|
||||
/* From this point on, we don't bother about wether the insns are
|
||||
below or above the 16 bits boundary. */
|
||||
*(.init0) /* Start here after reset. */
|
||||
KEEP (*(.init0))
|
||||
*(.init1)
|
||||
KEEP (*(.init1))
|
||||
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
|
||||
KEEP (*(.init2))
|
||||
*(.init3)
|
||||
KEEP (*(.init3))
|
||||
*(.init4) /* Initialize data and BSS. */
|
||||
KEEP (*(.init4))
|
||||
*(.init5)
|
||||
KEEP (*(.init5))
|
||||
*(.init6) /* C++ constructors. */
|
||||
KEEP (*(.init6))
|
||||
*(.init7)
|
||||
KEEP (*(.init7))
|
||||
*(.init8)
|
||||
KEEP (*(.init8))
|
||||
*(.init9) /* Call main(). */
|
||||
KEEP (*(.init9))
|
||||
*(.text)
|
||||
. = ALIGN(2);
|
||||
*(.text.*)
|
||||
. = ALIGN(2);
|
||||
*(.fini9) /* _exit() starts here. */
|
||||
KEEP (*(.fini9))
|
||||
*(.fini8)
|
||||
KEEP (*(.fini8))
|
||||
*(.fini7)
|
||||
KEEP (*(.fini7))
|
||||
*(.fini6) /* C++ destructors. */
|
||||
KEEP (*(.fini6))
|
||||
*(.fini5)
|
||||
KEEP (*(.fini5))
|
||||
*(.fini4)
|
||||
KEEP (*(.fini4))
|
||||
*(.fini3)
|
||||
KEEP (*(.fini3))
|
||||
*(.fini2)
|
||||
KEEP (*(.fini2))
|
||||
*(.fini1)
|
||||
KEEP (*(.fini1))
|
||||
*(.fini0) /* Infinite loop after program termination. */
|
||||
KEEP (*(.fini0))
|
||||
_etext = . ;
|
||||
} > text
|
||||
.data : AT (ADDR (.text) + SIZEOF (.text))
|
||||
{
|
||||
PROVIDE (__data_start = .) ;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.rodata) /* We need to include .rodata here if gcc is used */
|
||||
*(.rodata*) /* with -fdata-sections. */
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(2);
|
||||
_edata = . ;
|
||||
PROVIDE (__data_end = .) ;
|
||||
} > data
|
||||
.bss : AT (ADDR (.bss))
|
||||
{
|
||||
PROVIDE (__bss_start = .) ;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
PROVIDE (__bss_end = .) ;
|
||||
} > data
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
/* Global data not cleared after reset. */
|
||||
.noinit :
|
||||
{
|
||||
PROVIDE (__noinit_start = .) ;
|
||||
*(.noinit*)
|
||||
PROVIDE (__noinit_end = .) ;
|
||||
_end = . ;
|
||||
PROVIDE (__heap_start = .) ;
|
||||
} > data
|
||||
.eeprom :
|
||||
{
|
||||
*(.eeprom*)
|
||||
__eeprom_end = . ;
|
||||
} > eeprom
|
||||
.fuse :
|
||||
{
|
||||
KEEP(*(.fuse))
|
||||
KEEP(*(.lfuse))
|
||||
KEEP(*(.hfuse))
|
||||
KEEP(*(.efuse))
|
||||
} > fuse
|
||||
.lock :
|
||||
{
|
||||
KEEP(*(.lock*))
|
||||
} > lock
|
||||
.signature :
|
||||
{
|
||||
KEEP(*(.signature*))
|
||||
} > signature
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# ATMEL Microcontroller Software Support
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 2011, Atmel Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the disclaimer below.
|
||||
#
|
||||
# Atmel's name may not be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Makefile for compiling the applet-serial flash project
|
||||
|
||||
# Chip & board used for compilation
|
||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||
CHIP = atsam3s4
|
||||
BOARD = atsam3s4_ek
|
||||
DYN = OFF
|
||||
|
||||
# Makefile for compiling applet-serialflash applet.
|
||||
|
||||
ifeq (atsam3s4,$(CHIP))
|
||||
BOARD_DIR = at91sam3s4-ek
|
||||
endif
|
||||
|
||||
ifeq (atsam3s2,$(CHIP))
|
||||
BOARD_DIR = at91sam3s2-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g15,$(CHIP))
|
||||
BOARD =sam9g15_ek
|
||||
BOARD_DIR = at91sam9g15-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g25,$(CHIP))
|
||||
BOARD =sam9g25_ek
|
||||
BOARD_DIR = at91sam9g25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g35,$(CHIP))
|
||||
BOARD =sam9g35_ek
|
||||
BOARD_DIR = at91sam9g35-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x25,$(CHIP))
|
||||
BOARD =sam9x25_ek
|
||||
BOARD_DIR = at91sam9x25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x35,$(CHIP))
|
||||
BOARD =sam9x35_ek
|
||||
BOARD_DIR = at91sam9x35-ek
|
||||
endif
|
||||
|
||||
# Defines which are the available memory targets for the AT91SAM3S-EK board.
|
||||
MEMORIES = sram
|
||||
|
||||
# Trace level used for compilation
|
||||
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||
# TRACE_LEVEL_DEBUG 5
|
||||
# TRACE_LEVEL_INFO 4
|
||||
# TRACE_LEVEL_WARNING 3
|
||||
# TRACE_LEVEL_ERROR 2
|
||||
# TRACE_LEVEL_FATAL 1
|
||||
# TRACE_LEVEL_NO_TRACE 0
|
||||
|
||||
# Info traces allowed by default
|
||||
TR_LEV = 0
|
||||
|
||||
# Optimization level, put in comment for debugging
|
||||
OPTIMIZATION = -Os
|
||||
|
||||
# Output file basename
|
||||
OUTPUT = applet-coprocessor-$(CHIP)
|
||||
|
||||
# Output directories
|
||||
BIN = bin
|
||||
OBJ = obj
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Tools
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Tool suffix when cross-compiling
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
# Libraries
|
||||
LIBRARIES = ../../libraries
|
||||
# Chip library directory
|
||||
CHIP_LIB = $(LIBRARIES)/libchip_atsam3s
|
||||
# Board library directory
|
||||
BOARD_LIB = $(LIBRARIES)/libboard_atsam3s-ek
|
||||
# Spiflash library directory
|
||||
#SPIFLASH_LIB = $(LIBRARIES)/libspiflash
|
||||
|
||||
# ISP directory
|
||||
ISP = ..
|
||||
# tcl_lib directory
|
||||
|
||||
#INSTALLDIR = "../../../../tcl_lib/$(BOARD_DIR)/"
|
||||
|
||||
LIBS = -Wl,--start-group -lgcc -lc -Wl,--end-group
|
||||
|
||||
#-lchip_$(CHIP)_gcc_rel -lboard_$(BOARD)_gcc_rel -lspiflash_gcc_rel -Wl,--end-group
|
||||
|
||||
LIB_PATH = -L$(CHIP_LIB)/lib
|
||||
LIB_PATH += -L$(BOARD_LIB)/lib
|
||||
#LIB_PATH += -L$(SPIFLASH_LIB)/lib
|
||||
#LIB_PATH+=-L=/lib
|
||||
#LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.4.1
|
||||
|
||||
# Compilation tools
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
GDB = $(CROSS_COMPILE)gdb
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
CLSS = $(CROSS_COMPILE)objdump
|
||||
|
||||
# Flags
|
||||
INCLUDES = -I$(CHIP_LIB)
|
||||
INCLUDES += -I$(BOARD_LIB)
|
||||
INCLUDES += -I$(SPIFLASH_LIB)
|
||||
INCLUDES += -I$(LIBRARIES)
|
||||
|
||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
|
||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
|
||||
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
|
||||
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
||||
CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes
|
||||
CFLAGS += -Wmissing-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
|
||||
CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
|
||||
CFLAGS += -Wunreachable-code
|
||||
CFLAGS += -Wcast-align
|
||||
#CFLAGS += -Wmissing-noreturn
|
||||
#CFLAGS += -Wconversion
|
||||
|
||||
# To reduce application size use only integer printf function.
|
||||
CFLAGS += -Dprintf=iprintf
|
||||
TRACE_LEVEL = 4
|
||||
#CFLAGS += -DTRACE_LEVEL=$(TR_LEV)
|
||||
#-DDYN_TRACES
|
||||
# -mlong-calls -Wall
|
||||
CFLAGS += -ffunction-sections -D$(MEMORIES)
|
||||
#CFLAGS += -DNDEBUG
|
||||
CFLAGS += -mthumb -g -gdwarf-2 $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDYN_TRACES
|
||||
ASFLAGS = -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||
LDFLAGS= -nostartfiles -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=entry -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
|
||||
LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Files
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Directories where source files can be found
|
||||
|
||||
VPATH += ../..
|
||||
VPATH += $(ISP)/common
|
||||
|
||||
|
||||
# Objects built from Asm source files
|
||||
//ASM_OBJECTS = applet_cstartup.o
|
||||
|
||||
# Objects built from C source files
|
||||
C_OBJECTS += main.o
|
||||
C_OBJECTS += applet_cstartup.o
|
||||
|
||||
# Append OBJ and BIN directories to output filename
|
||||
OUTPUT := $(BIN)/$(OUTPUT)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Rules
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all: $(BIN) $(OBJ) $(MEMORIES)
|
||||
|
||||
$(BIN) $(OBJ):
|
||||
mkdir $@
|
||||
|
||||
define RULES
|
||||
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
|
||||
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
||||
|
||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||
$(CC) $(LIB_PATH) $(LDFLAGS) $(LD_OPTIONAL) -T"$(BOARD_LIB)/resources/gcc/$(CHIP)/$$@_samba.lds" -Wl,-Map,$(OUTPUT).map -o $(OUTPUT).elf $$^ $(LIBS)
|
||||
$(NM) $(OUTPUT).elf >$(OUTPUT).elf.txt
|
||||
$(OBJCOPY) -O binary $(OUTPUT).elf $(OUTPUT).bin
|
||||
$(SIZE) $$^ $(OUTPUT).elf
|
||||
$(CLSS) -h -S $(OUTPUT).elf >$(OUTPUT).lss
|
||||
# @[ -e $(INSTALLDIR) ] || mkdir $(INSTALLDIR)
|
||||
# @cp -f $(OUTPUT).bin $(INSTALLDIR)
|
||||
|
||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
debug_$(1): $(1)
|
||||
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
||||
endef
|
||||
|
||||
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
|
||||
|
||||
clean:
|
||||
-del $(OBJ)\*.o $(BIN)\*.bin $(BIN)\*.elf $(BIN)\*.map
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,101 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef APPLET_H
|
||||
#define APPLET_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Refers to the Version of SAM-BA */
|
||||
#define SAM_BA_APPLETS_VERSION "2.11"
|
||||
|
||||
/** Applet initialization command code.*/
|
||||
#define APPLET_CMD_INIT 0x00
|
||||
/** Applet full erase command code.*/
|
||||
#define APPLET_CMD_FULL_ERASE 0x01
|
||||
/** Applet write command code.*/
|
||||
#define APPLET_CMD_WRITE 0x02
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_READ 0x03
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_LOCK 0x04
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_UNLOCK 0x05
|
||||
/** Applet set/clear GPNVM command code.*/
|
||||
#define APPLET_CMD_GPNVM 0x06
|
||||
/** Applet set security bit command code.*/
|
||||
#define APPLET_CMD_SECURITY 0x07
|
||||
/** Applet buffer erase command code.*/
|
||||
#define APPLET_CMD_BUFFER_ERASE 0x08
|
||||
/** Applet binary page command code for Dataflash.*/
|
||||
#define APPLET_CMD_BINARY_PAGE 0x09
|
||||
/** List Bad Blocks of a Nandflash*/
|
||||
#define APPLET_CMD_LIST_BAD_BLOCKS 0x10
|
||||
/** Tag a Nandflash Block*/
|
||||
#define APPLET_CMD_TAG_BLOCK 0x11
|
||||
/** Read the Unique ID bits (on SAM3)*/
|
||||
#define APPLET_CMD_READ_UNIQUE_ID 0x12
|
||||
/** Applet blocks erase command code. */
|
||||
#define APPLET_CMD_ERASE_BLOCKS 0x13
|
||||
/** Applet batch full erase command code. */
|
||||
#define APPLET_CMD_BATCH_ERASE 0x14
|
||||
|
||||
/** Operation was successful.*/
|
||||
#define APPLET_SUCCESS 0x00
|
||||
/** Device unknown.*/
|
||||
#define APPLET_DEV_UNKNOWN 0x01
|
||||
/** Write operation failed.*/
|
||||
#define APPLET_WRITE_FAIL 0x02
|
||||
/** Read operation failed.*/
|
||||
#define APPLET_READ_FAIL 0x03
|
||||
/** Protect operation failed.*/
|
||||
#define APPLET_PROTECT_FAIL 0x04
|
||||
/** Unprotect operation failed.*/
|
||||
#define APPLET_UNPROTECT_FAIL 0x05
|
||||
/** Erase operation failed.*/
|
||||
#define APPLET_ERASE_FAIL 0x06
|
||||
/** No device defined in board.h*/
|
||||
#define APPLET_NO_DEV 0x07
|
||||
/** Read / write address is not aligned*/
|
||||
#define APPLET_ALIGN_ERROR 0x08
|
||||
/** Read / write found bad block*/
|
||||
#define APPLET_BAD_BLOCK 0x09
|
||||
/** Applet failure.*/
|
||||
#define APPLET_FAIL 0x0f
|
||||
|
||||
|
||||
/** Communication link identification*/
|
||||
#define USB_COM_TYPE 0x00
|
||||
#define DBGU_COM_TYPE 0x01
|
||||
#define JTAG_COM_TYPE 0x02
|
||||
|
||||
#endif //#ifndef APPLET_H
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "board.h"
|
||||
#include "board_lowlevel.h"
|
||||
typedef void( *IntFunc )( void );
|
||||
/*----------------------------------------------------------------------------
|
||||
* Prototypes
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Stack top */
|
||||
extern unsigned long _sstack;
|
||||
|
||||
/** Initialize segments*/
|
||||
extern unsigned int _sidata;
|
||||
extern unsigned int _sdata, _edata;
|
||||
extern unsigned int _szero, _ezero;
|
||||
|
||||
/** Default link entry */
|
||||
extern int main(int argc, char **argv);
|
||||
|
||||
/** Reset entry */
|
||||
void ResetException(void) ;//__attribute__((__interrupt__));
|
||||
|
||||
/** Exception Table */
|
||||
__attribute__((section(".isr_vector")))
|
||||
//IntFunc exception_table[] = {
|
||||
//__attribute__ ((section(".vectors"), used))
|
||||
void (* const gVectors[])(void) =
|
||||
{
|
||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||
(void (*)(void))((unsigned long)&_sstack),
|
||||
// /*(IntFunc)&*/_sstack,
|
||||
ResetException, /* Initial PC, set to entry point */
|
||||
(unsigned int) 0 /*NMIException*/,
|
||||
(unsigned int) 0 /*HardFaultException*/,
|
||||
(unsigned int) 0 /*MemManageException*/,
|
||||
(unsigned int) 0 /*BusFaultException*/,
|
||||
(unsigned int) 0 /*UsageFaultException*/,
|
||||
0, 0, 0, 0, /* Reserved */
|
||||
(unsigned int) 0 /*SVCHandler*/,
|
||||
(unsigned int) 0 /*DebugMonitor*/,
|
||||
0, /* Reserved */
|
||||
(unsigned int) 0 /*PendSVC*/,
|
||||
(unsigned int) 0 /*SysTickHandler*/,
|
||||
/*
|
||||
:
|
||||
*/
|
||||
};
|
||||
|
||||
/** Applet Mailbox and initialization flag */
|
||||
#define MAILBOX_SIZE 32
|
||||
__attribute__((section(".mailbox")))
|
||||
unsigned int mailbox[MAILBOX_SIZE];
|
||||
volatile unsigned int isInitialized = 0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Reset Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief This is the code that gets called on processor reset. To initialize the
|
||||
* device. And call the main() routine.
|
||||
*
|
||||
*/
|
||||
__attribute__ ((section(".text"), used))
|
||||
void ResetException(void)
|
||||
{
|
||||
unsigned int *pSrc, *pDest;
|
||||
// { asm volatile ("cpsid i"); }
|
||||
|
||||
// Initialize data
|
||||
// Zero fill bss
|
||||
if (isInitialized == 0) {
|
||||
pSrc = &_sidata;
|
||||
for(pDest = &_sdata; pDest < &_edata;) {
|
||||
|
||||
*(pDest ++) = *(pSrc ++);
|
||||
}
|
||||
|
||||
for (pDest = &_szero; pDest < &_ezero;) {
|
||||
|
||||
*(pDest ++) = 0;
|
||||
}
|
||||
isInitialized = 1;
|
||||
}
|
||||
|
||||
/* LowLevelInit(); */
|
||||
|
||||
/* Save original SP. */
|
||||
__asm("mov r4, sp");
|
||||
/* Change SP to current stack point. */
|
||||
__asm("ldr r5, =_sstack");
|
||||
__asm(" mov sp, r5");
|
||||
main(1, (char**)mailbox);
|
||||
/* Restore previous SP point. */
|
||||
__asm("mov sp, r4");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Interface for the low-level initialization function.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BOARD_LOWLEVEL_H
|
||||
#define BOARD_LOWLEVEL_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern void LowLevelInit( void ) ;
|
||||
|
||||
#endif /* BOARD_LOWLEVEL_H */
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# ATMEL Microcontroller Software Support
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 2011, Atmel Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the disclaimer below.
|
||||
#
|
||||
# Atmel's name may not be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Makefile for compiling the applet-serial flash project
|
||||
|
||||
# Chip & board used for compilation
|
||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||
CHIP = atsam3s4
|
||||
BOARD = atsam3s4_ek
|
||||
DYN = OFF
|
||||
|
||||
# Makefile for compiling applet-serialflash applet.
|
||||
|
||||
ifeq (atsam3s4,$(CHIP))
|
||||
BOARD_DIR = at91sam3s4-ek
|
||||
endif
|
||||
|
||||
ifeq (atsam3s2,$(CHIP))
|
||||
BOARD_DIR = at91sam3s2-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g15,$(CHIP))
|
||||
BOARD =sam9g15_ek
|
||||
BOARD_DIR = at91sam9g15-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g25,$(CHIP))
|
||||
BOARD =sam9g25_ek
|
||||
BOARD_DIR = at91sam9g25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g35,$(CHIP))
|
||||
BOARD =sam9g35_ek
|
||||
BOARD_DIR = at91sam9g35-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x25,$(CHIP))
|
||||
BOARD =sam9x25_ek
|
||||
BOARD_DIR = at91sam9x25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x35,$(CHIP))
|
||||
BOARD =sam9x35_ek
|
||||
BOARD_DIR = at91sam9x35-ek
|
||||
endif
|
||||
|
||||
# Defines which are the available memory targets for the AT91SAM3S-EK board.
|
||||
MEMORIES = sram
|
||||
|
||||
# Trace level used for compilation
|
||||
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||
# TRACE_LEVEL_DEBUG 5
|
||||
# TRACE_LEVEL_INFO 4
|
||||
# TRACE_LEVEL_WARNING 3
|
||||
# TRACE_LEVEL_ERROR 2
|
||||
# TRACE_LEVEL_FATAL 1
|
||||
# TRACE_LEVEL_NO_TRACE 0
|
||||
|
||||
# Info traces allowed by default
|
||||
TR_LEV = 0
|
||||
|
||||
# Optimization level, put in comment for debugging
|
||||
OPTIMIZATION = -Os
|
||||
|
||||
# Output file basename
|
||||
OUTPUT = applet-serialflash-$(CHIP)
|
||||
|
||||
# Output directories
|
||||
BIN = bin
|
||||
OBJ = obj
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Tools
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Tool suffix when cross-compiling
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
# Libraries
|
||||
LIBRARIES = ../../libraries
|
||||
# Chip library directory
|
||||
CHIP_LIB = $(LIBRARIES)/libchip_atsam3s
|
||||
# Board library directory
|
||||
BOARD_LIB = $(LIBRARIES)/libboard_atsam3s-ek
|
||||
# Spiflash library directory
|
||||
#SPIFLASH_LIB = $(LIBRARIES)/libspiflash
|
||||
|
||||
# ISP directory
|
||||
ISP = ..
|
||||
# tcl_lib directory
|
||||
|
||||
#INSTALLDIR = "../../../../tcl_lib/$(BOARD_DIR)/"
|
||||
|
||||
LIBS = -Wl,--start-group -lgcc -lc -Wl,--end-group
|
||||
|
||||
#-lchip_$(CHIP)_gcc_rel -lboard_$(BOARD)_gcc_rel -lspiflash_gcc_rel -Wl,--end-group
|
||||
|
||||
LIB_PATH = -L$(CHIP_LIB)/lib
|
||||
LIB_PATH += -L$(BOARD_LIB)/lib
|
||||
#LIB_PATH += -L$(SPIFLASH_LIB)/lib
|
||||
#LIB_PATH+=-L=/lib
|
||||
#LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.4.1
|
||||
|
||||
# Compilation tools
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
GDB = $(CROSS_COMPILE)gdb
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
CLSS = $(CROSS_COMPILE)objdump
|
||||
|
||||
# Flags
|
||||
INCLUDES = -I$(CHIP_LIB)
|
||||
INCLUDES += -I$(BOARD_LIB)
|
||||
INCLUDES += -I$(SPIFLASH_LIB)
|
||||
INCLUDES += -I$(LIBRARIES)
|
||||
|
||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
|
||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
|
||||
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
|
||||
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
||||
CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes
|
||||
CFLAGS += -Wmissing-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
|
||||
CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
|
||||
CFLAGS += -Wunreachable-code
|
||||
CFLAGS += -Wcast-align
|
||||
#CFLAGS += -Wmissing-noreturn
|
||||
#CFLAGS += -Wconversion
|
||||
|
||||
# To reduce application size use only integer printf function.
|
||||
CFLAGS += -Dprintf=iprintf
|
||||
TRACE_LEVEL = 4
|
||||
#CFLAGS += -DTRACE_LEVEL=$(TR_LEV)
|
||||
#-DDYN_TRACES
|
||||
# -mlong-calls -Wall
|
||||
CFLAGS += -ffunction-sections -D$(MEMORIES)
|
||||
#CFLAGS += -DNDEBUG
|
||||
CFLAGS += -mthumb -g -gdwarf-2 $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDYN_TRACES
|
||||
ASFLAGS = -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||
LDFLAGS= -nostartfiles -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=entry -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
|
||||
LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Files
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Directories where source files can be found
|
||||
|
||||
VPATH += ../..
|
||||
VPATH += $(ISP)/common
|
||||
|
||||
|
||||
# Objects built from Asm source files
|
||||
//ASM_OBJECTS = applet_cstartup.o
|
||||
|
||||
# Objects built from C source files
|
||||
C_OBJECTS += main.o
|
||||
C_OBJECTS += applet_cstartup.o
|
||||
|
||||
# Append OBJ and BIN directories to output filename
|
||||
OUTPUT := $(BIN)/$(OUTPUT)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Rules
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all: $(BIN) $(OBJ) $(MEMORIES)
|
||||
|
||||
$(BIN) $(OBJ):
|
||||
mkdir $@
|
||||
|
||||
define RULES
|
||||
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
|
||||
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
||||
|
||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||
$(CC) $(LIB_PATH) $(LDFLAGS) $(LD_OPTIONAL) -T"$(BOARD_LIB)/resources/gcc/$(CHIP)/$$@_samba.lds" -Wl,-Map,$(OUTPUT).map -o $(OUTPUT).elf $$^ $(LIBS)
|
||||
$(NM) $(OUTPUT).elf >$(OUTPUT).elf.txt
|
||||
$(OBJCOPY) -O binary $(OUTPUT).elf $(OUTPUT).bin
|
||||
$(SIZE) $$^ $(OUTPUT).elf
|
||||
$(CLSS) -h -S $(OUTPUT).elf >$(OUTPUT).lss
|
||||
# @[ -e $(INSTALLDIR) ] || mkdir $(INSTALLDIR)
|
||||
# @cp -f $(OUTPUT).bin $(INSTALLDIR)
|
||||
|
||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
debug_$(1): $(1)
|
||||
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
||||
endef
|
||||
|
||||
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
|
||||
|
||||
clean:
|
||||
-del $(OBJ)\*.o $(BIN)\*.bin $(BIN)\*.elf $(BIN)\*.map
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
@@ -0,0 +1,971 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "../common/applet.h"
|
||||
#include <board.h>
|
||||
//#include "libspiflash.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef DYN_TRACES
|
||||
#define DYN_TRACES 0
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Internal definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** SPI clock frequency in Hz. */
|
||||
#define SPCK 8000000
|
||||
|
||||
|
||||
/** Stack size in SRAM */
|
||||
#define STACK_SIZE 0x100
|
||||
|
||||
/** Last erased sector id, this will avoid to erase if the block is already erased. */
|
||||
//static unsigned short lastErasedBlock = 0xFFFF;
|
||||
|
||||
/** Indicate the farthest memory offset ever erase, if current write address is less
|
||||
than the address, the related block should be erase again before write. */
|
||||
//static uint32_t writtenAddress = 0;
|
||||
|
||||
|
||||
/** Max size of data we can tranfsert in one shot */
|
||||
#define MAX_COUNT 0x6000
|
||||
|
||||
/** Chip select value used to select the AT25 chip. */
|
||||
#define SPI_CS 0
|
||||
/** SPI peripheral pins to configure to access the serial flash. */
|
||||
#define SPI_PINS PINS_SPI0, PIN_SPI0_NPCS0
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Types
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Structure for storing parameters for each command that can be performed by
|
||||
the applet. */
|
||||
struct _Mailbox {
|
||||
|
||||
/** Command send to the monitor to be executed. */
|
||||
uint32_t command;
|
||||
/** Returned status, updated at the end of the monitor execution.*/
|
||||
uint32_t status;
|
||||
|
||||
/** Input Arguments in the argument area*/
|
||||
union {
|
||||
|
||||
/** Input arguments for the Init command.*/
|
||||
struct {
|
||||
|
||||
/** Communication link used.*/
|
||||
uint32_t comType;
|
||||
/**Trace level.*/
|
||||
uint32_t traceLevel;
|
||||
/** Serial flash index.*/
|
||||
uint32_t at25Idx;
|
||||
|
||||
} inputInit;
|
||||
|
||||
/** Output arguments for the Init command.*/
|
||||
struct {
|
||||
|
||||
/** Memory size.*/
|
||||
uint32_t memorySize;
|
||||
/** Buffer address.*/
|
||||
uint32_t bufferAddress;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
|
||||
} outputInit;
|
||||
|
||||
/** Input arguments for the Write command.*/
|
||||
struct {
|
||||
|
||||
/** Buffer address.*/
|
||||
uint32_t bufferAddr;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputWrite;
|
||||
|
||||
/** Output arguments for the Write command.*/
|
||||
struct {
|
||||
|
||||
/** Bytes written.*/
|
||||
uint32_t bytesWritten;
|
||||
|
||||
uint32_t bufferSize; // temp
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset; // temp
|
||||
uint32_t debug1 ;
|
||||
uint32_t debug2 ;
|
||||
|
||||
} outputWrite;
|
||||
|
||||
/** Input arguments for the Read command.*/
|
||||
struct {
|
||||
|
||||
/** Buffer address. */
|
||||
uint32_t bufferAddr;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputRead;
|
||||
|
||||
/** Output arguments for the Read command.*/
|
||||
struct {
|
||||
|
||||
/** Bytes read.*/
|
||||
uint32_t bytesRead;
|
||||
|
||||
} outputRead;
|
||||
|
||||
/** Input arguments for the Full Erase command.*/
|
||||
// NONE
|
||||
|
||||
/** Output arguments for the Full Erase command.*/
|
||||
// NONE
|
||||
/** Input arguments for the Buffer Erase command.*/
|
||||
struct {
|
||||
|
||||
/** Memory offset to be erase.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputBufferErase;
|
||||
|
||||
/** Output arguments for the Buffer Erase command.*/
|
||||
struct {
|
||||
|
||||
/** Memory offset to be erase.*/
|
||||
uint32_t bytesErased;
|
||||
|
||||
} outputBufferErase;
|
||||
} argument;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** End of program space (code + data). */
|
||||
extern int end;
|
||||
extern int _sstack;
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Global DMA driver instance for all DMA transfers in application. */
|
||||
//static sDmad dmad;
|
||||
|
||||
/** SPI driver instance. */
|
||||
//static Spid spid;
|
||||
|
||||
/** Serial flash driver instance. */
|
||||
//static At25 at25;
|
||||
|
||||
/** Pins to configure for the application. */
|
||||
//static Pin pins[] = {SPI_PINS};
|
||||
|
||||
/** Size of one page in the serial flash, in bytes. */
|
||||
static uint32_t pageSize;
|
||||
|
||||
/** Size of one block in the serial flash, in bytes. */
|
||||
static uint32_t blockSize;
|
||||
|
||||
/**Size of the buffer used for read/write operations in bytes. */
|
||||
static uint32_t bufferSize;
|
||||
|
||||
/** Depending on DYN_TRACES, dwTraceLevel is a modifable runtime variable or a define */
|
||||
uint32_t dwTraceLevel;
|
||||
|
||||
uint32_t Spi_init_done = 0 ;
|
||||
struct _Mailbox *Pmailbox = 0 ;
|
||||
|
||||
uint8_t Spi_tx_buf[24] ;
|
||||
uint8_t Spi_rx_buf[24] ;
|
||||
|
||||
uint8_t Block_buffer[4096] ;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
uint32_t eeprom_write_one( uint8_t byte, uint8_t count ) ;
|
||||
uint32_t eeprom_read_status( void ) ;
|
||||
void eeprom_write_enable( void ) ;
|
||||
void eeprom_wait_busy( void ) ;
|
||||
uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count ) ;
|
||||
void init_spi( void ) ;
|
||||
uint32_t unprotect_eeprom( void ) ;
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count ) ;
|
||||
uint32_t eeprom_block_erased( register uint8_t *p) ;
|
||||
uint32_t eeprom_page_erased( register uint8_t *p) ;
|
||||
void AT25D_Read( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset) ;
|
||||
void AT25D_Write( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset ) ;
|
||||
uint32_t AT25D_EraseBlock( uint32_t memoryOffset ) ;
|
||||
//uint32_t min( uint32_t a, uint32_t b ) ;
|
||||
|
||||
|
||||
uint32_t eeprom_write_one( uint8_t byte, uint8_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
register uint32_t result ;
|
||||
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
|
||||
spiptr->SPI_TDR = byte ;
|
||||
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( count == 0 )
|
||||
{
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
return spiptr->SPI_RDR ;
|
||||
}
|
||||
(void) spiptr->SPI_RDR ; // Dump the rx data
|
||||
spiptr->SPI_TDR = 0 ;
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
return spiptr->SPI_RDR ;
|
||||
}
|
||||
|
||||
|
||||
uint32_t eeprom_read_status()
|
||||
{
|
||||
return eeprom_write_one( 5, 1 ) ;
|
||||
}
|
||||
|
||||
|
||||
void eeprom_write_enable()
|
||||
{
|
||||
eeprom_write_one( 6, 0 ) ;
|
||||
}
|
||||
|
||||
void eeprom_wait_busy()
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t y ;
|
||||
|
||||
y = 0 ;
|
||||
do
|
||||
{
|
||||
y += 1 ;
|
||||
if ( y > 1000000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
x = eeprom_read_status() ;
|
||||
} while ( x & 1 ) ;
|
||||
|
||||
Pmailbox->argument.outputWrite.debug2 = y ;
|
||||
}
|
||||
|
||||
uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
register uint32_t result ;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
result = 0 ;
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
while( count )
|
||||
{
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 )
|
||||
{
|
||||
// wait
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
result = 0xFFFF ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
// if ( count == 1 )
|
||||
// {
|
||||
// spiptr->SPI_CR = SPI_CR_LASTXFER ; // LastXfer bit
|
||||
// }
|
||||
spiptr->SPI_TDR = *tx++ ;
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
result = 0x2FFFF ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
*rx++ = spiptr->SPI_RDR ;
|
||||
count -= 1 ;
|
||||
}
|
||||
if ( result <= 10000 )
|
||||
{
|
||||
result = 0 ;
|
||||
}
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
|
||||
// Power save
|
||||
// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
// register uint32_t result ;
|
||||
register uint32_t condition ;
|
||||
static uint8_t discard_rx_command[4] ;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
// Spi_complete = 0 ;
|
||||
if ( comlen > 4 )
|
||||
{
|
||||
// Spi_complete = 1 ;
|
||||
return 0x4FFFF ;
|
||||
}
|
||||
condition = SPI_SR_TXEMPTY ;
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_RPR = (uint32_t)discard_rx_command ;
|
||||
spiptr->SPI_RCR = comlen ;
|
||||
if ( rx )
|
||||
{
|
||||
spiptr->SPI_RNPR = (uint32_t)rx ;
|
||||
spiptr->SPI_RNCR = count ;
|
||||
condition = SPI_SR_RXBUFF ;
|
||||
}
|
||||
spiptr->SPI_TPR = (uint32_t)command ;
|
||||
spiptr->SPI_TCR = comlen ;
|
||||
if ( tx )
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)tx ;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)rx ;
|
||||
}
|
||||
spiptr->SPI_TNCR = count ;
|
||||
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers
|
||||
|
||||
// Wait for things to get started, avoids early interrupt
|
||||
for ( count = 0 ; count < 1000 ; count += 1 )
|
||||
{
|
||||
if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
count = 0 ;
|
||||
while( ( spiptr->SPI_SR & condition ) == 0 )
|
||||
{
|
||||
if ( ++count > 1000000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS ; // Stop tramsfers
|
||||
|
||||
if ( count > 1000000 )
|
||||
{
|
||||
return 1 ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
uint32_t unprotect_eeprom()
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 0x39 ; // Unprotect sector command
|
||||
*(p+1) = 0 ;
|
||||
*(p+2) = 0 ;
|
||||
*(p+3) = 0 ; // 3 bytes address
|
||||
|
||||
return spi_operation( p, Spi_rx_buf, 4 ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void init_spi()
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
register Spi *spiptr ;
|
||||
register uint32_t timer ;
|
||||
register uint8_t *p ;
|
||||
uint8_t spi_buf[4] ;
|
||||
|
||||
if ( !Spi_init_done)
|
||||
{
|
||||
PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
/* Configure PIO */
|
||||
pioptr = PIOA ;
|
||||
pioptr->PIO_ABCDSR[0] &= ~0x00007800 ; // Peripheral A bits 14,13,12,11
|
||||
pioptr->PIO_ABCDSR[1] &= ~0x00007800 ; // Peripheral A
|
||||
pioptr->PIO_PDR = 0x00007800 ; // Assign to peripheral
|
||||
|
||||
spiptr = SPI ;
|
||||
timer = ( 64000000 / 3000000 ) << 8 ;
|
||||
spiptr->SPI_MR = 0x14000011 ; // 0001 0100 0000 0000 0000 0000 0001 0001 Master
|
||||
spiptr->SPI_CSR[0] = 0x01180009 | timer ; // 0000 0001 0001 1000 xxxx xxxx 0000 1001
|
||||
// NVIC_EnableIRQ(SPI_IRQn) ;
|
||||
|
||||
p = spi_buf ;
|
||||
|
||||
// *p = 0x39 ; // Unprotect sector command
|
||||
// *(p+1) = 0 ;
|
||||
// *(p+2) = 0 ;
|
||||
// *(p+3) = 0 ; // 3 bytes address
|
||||
|
||||
// spi_operation( p, spi_buf, 4 ) ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
*p = 1 ; // Write status register command
|
||||
*(p+1) = 0 ;
|
||||
spi_operation( p, spi_buf, 2 ) ;
|
||||
Spi_init_done = 1 ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t eeprom_block_erased( register uint8_t *p)
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t result ;
|
||||
|
||||
result = 1 ;
|
||||
|
||||
for ( x = 0 ; x < 4096 ; x += 1 )
|
||||
{
|
||||
if ( *p++ != 0xFF )
|
||||
{
|
||||
result = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
uint32_t eeprom_page_erased( register uint8_t *p)
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t result ;
|
||||
|
||||
result = 1 ;
|
||||
|
||||
for ( x = 0 ; x < 256 ; x += 1 )
|
||||
{
|
||||
if ( *p++ != 0xFF )
|
||||
{
|
||||
result = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
|
||||
void AT25D_Read( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset)
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 3 ; // Read command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
|
||||
spi_PDC_action( p, 0, BufferAddr, 4, size ) ;
|
||||
}
|
||||
|
||||
void AT25D_Write( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset )
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 2 ; // Write command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
|
||||
spi_PDC_action( p, BufferAddr, 0, 4, size ) ;
|
||||
|
||||
eeprom_wait_busy() ;
|
||||
|
||||
}
|
||||
|
||||
uint32_t AT25D_EraseBlock( uint32_t memoryOffset )
|
||||
{
|
||||
register uint8_t *p ;
|
||||
register uint32_t x ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
p = Spi_tx_buf ;
|
||||
*p = 0x20 ; // Block Erase command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
x = spi_operation( p, Spi_rx_buf, 4 ) ;
|
||||
|
||||
eeprom_wait_busy() ;
|
||||
return x ;
|
||||
}
|
||||
|
||||
//uint32_t min( uint32_t a, uint32_t b )
|
||||
//{
|
||||
// if ( a < b )
|
||||
// {
|
||||
// return a ;
|
||||
// }
|
||||
// return b ;
|
||||
//}
|
||||
|
||||
/**
|
||||
* \brief Applet main entry. This function decodes received command and executes it.
|
||||
* \param argc always 1
|
||||
* \param argv Address of the argument area.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct _Mailbox *pMailbox = (struct _Mailbox *) argv;
|
||||
Pmailbox = pMailbox ;
|
||||
/* Communication type with SAM-BA GUI. */
|
||||
// uint8_t comType;
|
||||
|
||||
// uint32_t jedecId;
|
||||
uint32_t bytesToWrite, bytesToRead, bufferAddr, startMemoryOffset, memoryOffset, packetSize;
|
||||
/* index on read/write buffer */
|
||||
uint8_t *pBuffer;
|
||||
/* Temporary buffer used for non block aligned read/write */
|
||||
// uint32_t tempBufferAddr;
|
||||
/* Offset in destination buffer during buffer copy */
|
||||
// uint32_t bufferOffset;
|
||||
|
||||
uint32_t block_address ;
|
||||
uint32_t x ;
|
||||
/* INIT */
|
||||
/* Save communication link type */
|
||||
// comType = pMailbox->argument.inputInit.comType;
|
||||
|
||||
init_spi() ;
|
||||
|
||||
if (pMailbox->command == APPLET_CMD_INIT)
|
||||
{
|
||||
#if (DYN_TRACES == 1)
|
||||
dwTraceLevel = pMailbox->argument.inputInit.traceLevel;
|
||||
#endif
|
||||
|
||||
// TRACE_INFO("-- SerialFlash AT25/AT26 applet %s --\n\r", SAM_BA_APPLETS_VERSION);
|
||||
// TRACE_INFO("-- %s\n\r", BOARD_NAME);
|
||||
// TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
|
||||
/* Configure pins */
|
||||
// PIO_Configure(pins, PIO_LISTSIZE(pins));
|
||||
/* Initialize DMA driver instance with polling mode */
|
||||
// DMAD_Initialize( &dmad, 1 );
|
||||
|
||||
/* Initialize the SPI and serial flash */
|
||||
init_spi() ;
|
||||
|
||||
|
||||
|
||||
// SPID_Configure(&spid, SPI0, ID_SPI0, &dmad);
|
||||
// AT25_Configure(&at25, &spid, SPI_CS, 1);
|
||||
// TRACE_INFO("SPI and AT25/AT25 drivers initialized\n\r");
|
||||
pMailbox->argument.outputInit.bufferAddress = (uint32_t) &end ;
|
||||
/* Read the JEDEC ID of the device to identify it */
|
||||
// jedecId = AT25D_ReadJedecId(&at25);
|
||||
// if (AT25_FindDevice(&at25, jedecId) == 0) {
|
||||
// pMailbox->status = APPLET_DEV_UNKNOWN;
|
||||
// pMailbox->argument.outputInit.bufferSize = 0;
|
||||
// pMailbox->argument.outputInit.memorySize = 0;
|
||||
// TRACE_INFO("Device Unknown\n\r");
|
||||
// goto exit;
|
||||
// }
|
||||
// else {
|
||||
/* Get device parameters */
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
pageSize = 256 ;
|
||||
// pageSize = AT25_PageSize(&at25);
|
||||
blockSize = 4096 ;
|
||||
// blockSize = AT25_BlockSize(&at25);
|
||||
|
||||
/* Program page */
|
||||
// if (AT25_ManId(&at25) == SST_SPI_FLASH) {
|
||||
/* SST Flash write is slower, we reduce buffer size to avoid USB timeout */
|
||||
// bufferSize = 10 * pageSize;
|
||||
// }
|
||||
// else {
|
||||
bufferSize = 2 * blockSize;
|
||||
// }
|
||||
/* integer number of pages can be contained in each buffer */
|
||||
bufferSize -= bufferSize % pageSize;
|
||||
if ( bufferSize < pageSize) {
|
||||
// TRACE_INFO("No enought memory to load buffer.\n\r");
|
||||
goto exit;
|
||||
}
|
||||
pMailbox->argument.outputInit.bufferSize = bufferSize;
|
||||
pMailbox->argument.outputInit.memorySize = 128*4096;
|
||||
// TRACE_INFO("%s blockSize : 0x%lx bufferAddr : 0x%lx\n\r",
|
||||
// "sky9x", blockSize, pMailbox->argument.outputInit.bufferAddress);
|
||||
// }
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// WRITE:
|
||||
// ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_WRITE)
|
||||
{
|
||||
startMemoryOffset = pMailbox->argument.inputWrite.memoryOffset;
|
||||
memoryOffset = startMemoryOffset;
|
||||
bufferAddr = pMailbox->argument.inputWrite.bufferAddr;
|
||||
// tempBufferAddr = bufferAddr + bufferSize;
|
||||
bytesToWrite = pMailbox->argument.inputWrite.bufferSize;
|
||||
// TRACE_INFO("WRITE at offset: 0x%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
|
||||
// memoryOffset, bufferAddr, bytesToWrite);
|
||||
/* Check word alignment */
|
||||
if (memoryOffset % 4) {
|
||||
|
||||
pMailbox->status = APPLET_ALIGN_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
unprotect_eeprom() ;
|
||||
// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
// goto exit;
|
||||
// }
|
||||
|
||||
pBuffer = (uint8_t *) bufferAddr;
|
||||
|
||||
block_address = memoryOffset &0xFFFFF000 ; // 4k boundary
|
||||
AT25D_Read( Block_buffer, 4096, block_address ) ; // read block to write to
|
||||
// Check to see if it is blank
|
||||
x = eeprom_block_erased( Block_buffer ) ;
|
||||
if ( x == 0 )
|
||||
{
|
||||
AT25D_EraseBlock( block_address ) ;
|
||||
}
|
||||
|
||||
if (bytesToWrite)
|
||||
{
|
||||
uint32_t bytes_to_copy ;
|
||||
uint32_t i ;
|
||||
uint32_t j ;
|
||||
uint8_t *s ;
|
||||
uint8_t *dest ;
|
||||
|
||||
dest = Block_buffer + (memoryOffset & 0x0FFF ) ;
|
||||
s = pBuffer ;
|
||||
bytes_to_copy = 4096 - ( memoryOffset - block_address ) ;
|
||||
if ( bytes_to_copy > bytesToWrite )
|
||||
{
|
||||
bytes_to_copy = bytesToWrite ;
|
||||
}
|
||||
for ( i = 0 ; i < bytes_to_copy ; i += 1 )
|
||||
{
|
||||
*dest++ = *s++ ;
|
||||
}
|
||||
memoryOffset += bytes_to_copy ;
|
||||
bytesToWrite -= bytes_to_copy ;
|
||||
s = Block_buffer ;
|
||||
j = 0 ;
|
||||
for ( i = 0 ; i < 16 ; i += 1 ) // pages in block
|
||||
{
|
||||
j <<= 1 ;
|
||||
x = eeprom_page_erased( s ) ;
|
||||
if ( x == 0 ) // Not blank
|
||||
{
|
||||
AT25D_Write( s, 256, block_address ) ;
|
||||
j |= 1 ;
|
||||
}
|
||||
s += 256 ;
|
||||
block_address += 256 ;
|
||||
}
|
||||
pMailbox->argument.outputWrite.debug1 = j ;
|
||||
}
|
||||
|
||||
|
||||
// if ((memoryOffset % pageSize) != 0) {
|
||||
|
||||
// /* We are not page aligned, retrieve first page content to update it*/
|
||||
// if (memoryOffset < writtenAddress) {
|
||||
// lastErasedBlock = 0xFFFF;
|
||||
// }
|
||||
// /* Flush temp buffer */
|
||||
// memset((uint32_t *)tempBufferAddr, 0xFF, pageSize);
|
||||
|
||||
// bufferOffset = (memoryOffset % pageSize);
|
||||
// packetSize = pageSize - bufferOffset;
|
||||
// memoryOffset -= bufferOffset;
|
||||
// /* Read page to be updated*/
|
||||
// AT25D_Read( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// /* Fill retrieved page with data to be programmed */
|
||||
// memcpy((uint8_t *)(tempBufferAddr + bufferOffset), pBuffer, packetSize);
|
||||
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
|
||||
// /* Write the page contents */
|
||||
//// AT25D_Write( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// bytesToWrite = (bytesToWrite > packetSize) ? (bytesToWrite - packetSize) : 0;
|
||||
// pBuffer += packetSize;
|
||||
// memoryOffset += pageSize;
|
||||
// writtenAddress = memoryOffset;
|
||||
// }
|
||||
|
||||
// /* If it remains more than one page to write */
|
||||
// while (bytesToWrite >= pageSize)
|
||||
// {
|
||||
// if (memoryOffset < writtenAddress)
|
||||
// {
|
||||
// lastErasedBlock = 0xFFFF;
|
||||
// }
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
// /* Write the page contents */
|
||||
// AT25D_Write( (uint8_t *) pBuffer, pageSize, memoryOffset);
|
||||
// pBuffer += pageSize;
|
||||
// memoryOffset += pageSize;
|
||||
// bytesToWrite -= pageSize;
|
||||
// writtenAddress = memoryOffset;
|
||||
// }
|
||||
|
||||
// /* Write remaining data */
|
||||
// if (bytesToWrite > 0) {
|
||||
|
||||
// /* Read previous content of page */
|
||||
// AT25D_Read( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// /* Fill retrieved block with data to be programmed */
|
||||
// memcpy((uint8_t *)tempBufferAddr, pBuffer, bytesToWrite);
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
// /* Write the page contents */;
|
||||
//// AT25D_Write( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// writtenAddress = memoryOffset + bytesToWrite;
|
||||
// /* No more bytes to write */
|
||||
// bytesToWrite = 0;
|
||||
// }
|
||||
|
||||
//// TRACE_INFO("WRITE return byte written : 0x%lx Bytes\n\r",
|
||||
//// pMailbox->argument.inputWrite.bufferSize - bytesToWrite);
|
||||
|
||||
pMailbox->argument.outputWrite.bytesWritten = pMailbox->argument.inputWrite.bufferSize - bytesToWrite;
|
||||
// pMailbox->argument.outputWrite.bytesWritten = bytesToWrite;
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
|
||||
// // ----------------------------------------------------------
|
||||
// // READ:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_READ)
|
||||
{
|
||||
memoryOffset = pMailbox->argument.inputRead.memoryOffset;
|
||||
bufferAddr = pMailbox->argument.inputRead.bufferAddr;
|
||||
bytesToRead = pMailbox->argument.inputRead.bufferSize;
|
||||
|
||||
// TRACE_INFO("READ at offset: 0x%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
|
||||
// memoryOffset, bufferAddr, bytesToRead);
|
||||
/* Check word alignment */
|
||||
if (memoryOffset % 4) {
|
||||
|
||||
pMailbox->status = APPLET_ALIGN_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
pBuffer = (uint8_t *) bufferAddr;
|
||||
|
||||
/* Read packet after packets */
|
||||
while (((uint32_t)pBuffer < (bufferAddr + bufferSize)) && (bytesToRead > 0))
|
||||
{
|
||||
packetSize = bytesToRead ;
|
||||
if ( packetSize > MAX_COUNT )
|
||||
{
|
||||
packetSize = MAX_COUNT ;
|
||||
}
|
||||
AT25D_Read( pBuffer, packetSize, memoryOffset);
|
||||
pBuffer += packetSize;
|
||||
bytesToRead -= packetSize;
|
||||
memoryOffset += packetSize;
|
||||
}
|
||||
|
||||
// TRACE_INFO("READ return byte read : 0x%lx Bytes\n\r",
|
||||
// pMailbox->argument.inputRead.bufferSize - bytesToRead);
|
||||
|
||||
pMailbox->argument.outputRead.bytesRead = pMailbox->argument.inputRead.bufferSize - bytesToRead;
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
|
||||
// // ----------------------------------------------------------
|
||||
// // FULL ERASE:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_FULL_ERASE)
|
||||
{
|
||||
pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// TRACE_INFO("FULL ERASE\n\r");
|
||||
|
||||
// unprotect_eeprom() ;
|
||||
|
||||
// /* Unprotected the flash */
|
||||
//// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
//// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
//// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
//// goto exit;
|
||||
//// }
|
||||
|
||||
// TRACE_INFO("Flash unprotected\n\r");
|
||||
|
||||
// /* Erase the chip */
|
||||
// TRACE_INFO("Chip is being erased...\n\r");
|
||||
|
||||
//// if (AT25D_EraseChip()) {
|
||||
|
||||
// // NOT IMPLEMENTED (YET?)
|
||||
|
||||
// TRACE_INFO("Erasing error\n\r");
|
||||
// pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// goto exit;
|
||||
//// }
|
||||
|
||||
// TRACE_INFO("Full Erase achieved\n\r");
|
||||
// pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
// // ----------------------------------------------------------
|
||||
// // BUFFER ERASE:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_BUFFER_ERASE)
|
||||
{
|
||||
|
||||
// TRACE_INFO("BUFFER ERASE \n\r");
|
||||
/* Unprotected the flash */
|
||||
unprotect_eeprom() ;
|
||||
|
||||
// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
// goto exit;
|
||||
// }
|
||||
|
||||
memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset;
|
||||
|
||||
if (AT25D_EraseBlock( memoryOffset))
|
||||
{
|
||||
pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// TRACE_INFO("Block erasing error\n\r");
|
||||
goto exit;
|
||||
}
|
||||
pMailbox->argument.outputBufferErase.bytesErased = 4096;
|
||||
|
||||
// TRACE_INFO("Buffer Erase achieved\n\r");
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
exit:
|
||||
/* Acknowledge the end of command */
|
||||
// TRACE_INFO("\tEnd of applet (command : %lx --- status : %lx)\n\r", pMailbox->command, pMailbox->status);
|
||||
|
||||
/* Notify the host application of the end of the command processing */
|
||||
pMailbox->command = ~(pMailbox->command);
|
||||
/* Send ACK character */
|
||||
// if (comType == DBGU_COM_TYPE)
|
||||
// {
|
||||
/* Wait for the transmitter to be ready */
|
||||
// while ( (DBGU->DBGU_SR & DBGU_SR_TXEMPTY) == 0 ) ;
|
||||
/* Send character */
|
||||
// DBGU->DBGU_THR= 0x06 ;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,734 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page sam3s_ek_board_desc SAM3S-EK - Board Description
|
||||
*
|
||||
* \section Purpose
|
||||
*
|
||||
* A file is dedicated to descibe the AT91SAM3S-EK board.
|
||||
*
|
||||
* \section Contents
|
||||
*
|
||||
* - For AT91SAM3S-EK information, see \subpage sam3s_ek_board_info.
|
||||
* - For operating frequency information, see \subpage sam3s_ek_opfreq.
|
||||
* - For using portable PIO definitions, see \subpage sam3s_ek_piodef.
|
||||
* - For on-board memories, see \subpage sam3s_ek_mem.
|
||||
* - Several USB definitions are included here, see \subpage sam3s_ek_usb.
|
||||
* - For External components, see \subpage sam3s_ek_extcomp.
|
||||
* - For Individual chip definition, see \subpage sam3s_ek_chipdef.
|
||||
*
|
||||
* To get more software details and the full list of parameters related to the
|
||||
* SAM3S-EK board configuration, please have a look at the source file:
|
||||
* \ref board.h\n
|
||||
*
|
||||
* \section Usage
|
||||
*
|
||||
* - The code for booting the board is provided by board_cstartup_xxx.c and
|
||||
* board_lowlevel.c.
|
||||
* - For using board PIOs, board characteristics (clock, etc.) and external
|
||||
* components, see board.h.
|
||||
* - For manipulating memories, see board_memories.h.
|
||||
*
|
||||
* This file can be used as a template and modified to fit a custom board, with
|
||||
* specific PIOs usage or memory connections.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file board.h
|
||||
*
|
||||
* Definition of AT91SAM3S-EK characteristics, AT91SAM3S-dependant PIOs and
|
||||
* external components interfacing.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_
|
||||
#define _BOARD_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <chip.h>
|
||||
|
||||
|
||||
//#include <include/at45d.h>
|
||||
//#include <include/at45_spi.h>
|
||||
#include <include/board_lowlevel.h>
|
||||
//#include <include/board_memories.h>
|
||||
//#include <include/hamming.h>
|
||||
//#include <include/math.h>
|
||||
//#include <include/uart_console.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_board_info "SAM3S-EK - Board informations"
|
||||
* This page lists several definition related to the board description.
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_NAME
|
||||
*/
|
||||
|
||||
/** Name of the board */
|
||||
#define BOARD_NAME "ATSAM3S-EK"
|
||||
/** Board definition */
|
||||
#define atsam3sek
|
||||
/** Family definition (already defined) */
|
||||
#define atsam3s
|
||||
/** Core definition */
|
||||
#define cortexm3
|
||||
|
||||
/*
|
||||
#define BOARD_REV_A
|
||||
*/
|
||||
#define BOARD_REV_B
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_opfreq "SAM3S-EK - Operating frequencies"
|
||||
* This page lists several definition related to the board operating frequency
|
||||
* (when using the initialization done by board_lowlevel.c).
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_MAINOSC
|
||||
* - \ref BOARD_MCK
|
||||
*/
|
||||
|
||||
/** Frequency of the board main oscillator */
|
||||
#define BOARD_MAINOSC 12000000
|
||||
|
||||
/** Master clock frequency (when using board_lowlevel.c) */
|
||||
// #define BOARD_MCK 64000000
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_piodef "SAM3S-EK - PIO definitions"
|
||||
* This pages lists all the pio definitions contained in board.h. The constants
|
||||
* are named using the following convention: PIN_* for a constant which defines
|
||||
* a single Pin instance (but may include several PIOs sharing the same
|
||||
* controller), and PINS_* for a list of Pin instances.
|
||||
*
|
||||
* ADC
|
||||
* - \ref PIN_ADC0_AD0
|
||||
* - \ref PIN_ADC0_AD1
|
||||
* - \ref PIN_ADC0_AD2
|
||||
* - \ref PIN_ADC0_AD3
|
||||
* - \ref PIN_ADC0_AD4
|
||||
* - \ref PIN_ADC0_AD5
|
||||
* - \ref PIN_ADC0_AD6
|
||||
* - \ref PIN_ADC0_AD7
|
||||
* - \ref PINS_ADC
|
||||
*
|
||||
* UART
|
||||
* - \ref PINS_UART
|
||||
*
|
||||
* EBI
|
||||
* - \ref PIN_EBI_DATA_BUS
|
||||
* - \ref PIN_EBI_NRD
|
||||
* - \ref PIN_EBI_NWE
|
||||
* - \ref PIN_EBI_NCS0
|
||||
* - \ref PIN_EBI_PSRAM_ADDR_BUS
|
||||
* - \ref PIN_EBI_PSRAM_NBS
|
||||
* - \ref PIN_EBI_A1
|
||||
* - \ref PIN_EBI_NCS1
|
||||
* - \ref PIN_EBI_LCD_RS
|
||||
*
|
||||
* LEDs
|
||||
* - \ref PIN_LED_0
|
||||
* - \ref PIN_LED_1
|
||||
* - \ref PIN_LED_2
|
||||
* - \ref PINS_LEDS
|
||||
*
|
||||
* MCI
|
||||
* - \ref PINS_MCI
|
||||
*
|
||||
* Push buttons
|
||||
* - \ref PIN_PUSHBUTTON_1
|
||||
* - \ref PIN_PUSHBUTTON_2
|
||||
* - \ref PINS_PUSHBUTTONS
|
||||
* - \ref PUSHBUTTON_BP1
|
||||
* - \ref PUSHBUTTON_BP2
|
||||
*
|
||||
* PWMC
|
||||
* - \ref PIN_PWMC_PWMH0
|
||||
* - \ref PIN_PWMC_PWML0
|
||||
* - \ref PIN_PWMC_PWMH1
|
||||
* - \ref PIN_PWMC_PWML1
|
||||
* - \ref PIN_PWMC_PWMH2
|
||||
* - \ref PIN_PWMC_PWML2
|
||||
* - \ref PIN_PWMC_PWMH3
|
||||
* - \ref PIN_PWMC_PWML3
|
||||
* - \ref PIN_PWM_LED0
|
||||
* - \ref PIN_PWM_LED1
|
||||
* - \ref PIN_PWM_LED2
|
||||
* - \ref CHANNEL_PWM_LED0
|
||||
* - \ref CHANNEL_PWM_LED1
|
||||
* - \ref CHANNEL_PWM_LED2
|
||||
*
|
||||
* SPI
|
||||
* - \ref PIN_SPI_MISO
|
||||
* - \ref PIN_SPI_MOSI
|
||||
* - \ref PIN_SPI_SPCK
|
||||
* - \ref PINS_SPI
|
||||
* - \ref PIN_SPI_NPCS0_PA11
|
||||
*
|
||||
* SSC
|
||||
* - \ref PIN_SSC_TD
|
||||
* - \ref PIN_SSC_TK
|
||||
* - \ref PIN_SSC_TF
|
||||
* - \ref PINS_SSC_CODEC
|
||||
*
|
||||
* PCK0
|
||||
* - \ref PIN_PCK0
|
||||
*
|
||||
* PIO PARALLEL CAPTURE
|
||||
* - \ref PIN_PIODCEN1
|
||||
* - \ref PIN_PIODCEN2
|
||||
*
|
||||
* TWI
|
||||
* - \ref TWI_V3XX
|
||||
* - \ref PIN_TWI_TWD0
|
||||
* - \ref PIN_TWI_TWCK0
|
||||
* - \ref PINS_TWI0
|
||||
* - \ref PIN_TWI_TWD1
|
||||
* - \ref PIN_TWI_TWCK1
|
||||
* - \ref PINS_TWI1
|
||||
*
|
||||
* USART0
|
||||
* - \ref PIN_USART0_RXD
|
||||
* - \ref PIN_USART0_TXD
|
||||
* - \ref PIN_USART0_CTS
|
||||
* - \ref PIN_USART0_RTS
|
||||
* - \ref PIN_USART0_SCK
|
||||
*
|
||||
* USB
|
||||
* - \ref PIN_USB_VBUS
|
||||
*
|
||||
* NandFlash
|
||||
* - \ref PIN_EBI_NANDOE
|
||||
* - \ref PIN_EBI_NANDWE
|
||||
* - \ref PIN_EBI_NANDCLE
|
||||
* - \ref PIN_EBI_NANDALE
|
||||
* - \ref PIN_EBI_NANDIO
|
||||
* - \ref BOARD_NF_CE_PIN
|
||||
* - \ref BOARD_NF_RB_PIN
|
||||
* - \ref PINS_NANDFLASH
|
||||
*
|
||||
* QTouch
|
||||
* PIO definitions for Slider
|
||||
* \ref SLIDER_IOMASK_SNS
|
||||
* \ref SLIDER_IOMASK_SNSK
|
||||
* \ref PINS_SLIDER_SNS
|
||||
* \ref PINS_SLIDER_SNSK
|
||||
*
|
||||
* PIO definitions for keys
|
||||
* \ref KEY_IOMASK_SNS
|
||||
* \ref KEY_IOMASK_SNSK
|
||||
* \ref PINS_KEY_SNS
|
||||
* \ref PINS_KEY_SNSK
|
||||
*
|
||||
* PIOS for QTouch
|
||||
* \ref PINS_QTOUCH
|
||||
*/
|
||||
|
||||
/** ADC_AD0 pin definition. */
|
||||
#define PIN_ADC0_AD0 {1 << 21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD1 pin definition. */
|
||||
#define PIN_ADC0_AD1 {1 << 30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD2 pin definition. */
|
||||
#define PIN_ADC0_AD2 {1 << 3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD3 pin definition. */
|
||||
#define PIN_ADC0_AD3 {1 << 4, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD4 pin definition. */
|
||||
#define PIN_ADC0_AD4 {1 << 15, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD5 pin definition. */
|
||||
#define PIN_ADC0_AD5 {1 << 16, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD6 pin definition. */
|
||||
#define PIN_ADC0_AD6 {1 << 17, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD7 pin definition. */
|
||||
#define PIN_ADC0_AD7 {1 << 18, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/** Pins ADC */
|
||||
#define PINS_ADC PIN_ADC0_AD0, PIN_ADC0_AD1, PIN_ADC0_AD2, PIN_ADC0_AD3, PIN_ADC0_AD4, PIN_ADC0_AD5, PIN_ADC0_AD6, PIN_ADC0_AD7
|
||||
|
||||
/** Startup time max, return from Idle mode (in µs) */
|
||||
#define ADC_STARTUP_TIME_MAX 15
|
||||
/** Track and hold Acquisition Time min (in ns) */
|
||||
#define ADC_TRACK_HOLD_TIME_MIN 1200
|
||||
/** ADC clock frequence */
|
||||
#define BOARD_ADC_FREQ (6000000)
|
||||
|
||||
/** UART pins (UTXD0 and URXD0) definitions, PA9,10. */
|
||||
#define PINS_UART {0x00000600, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** EBI Data Bus pins */
|
||||
#define PIN_EBI_DATA_BUS {0xFF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NRD pin */
|
||||
#define PIN_EBI_NRD {1 << 11, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NWE pin */
|
||||
#define PIN_EBI_NWE {1 << 8, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NCS0 pin */
|
||||
#define PIN_EBI_NCS0 {1 << 20, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI pins for PSRAM address bus */
|
||||
#define PIN_EBI_PSRAM_ADDR_BUS {0x3f00fff, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI pins for PSRAM NBS pins */
|
||||
#define PIN_EBI_PSRAM_NBS {1 << 7, PIOB, ID_PIOB, PIO_PERIPH_B, PIO_PULLUP}, \
|
||||
{1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI A1 pin */
|
||||
#define PIN_EBI_A1 {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NCS1 pin */
|
||||
#define PIN_EBI_NCS1 {1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD CS pin */
|
||||
/** EBI pin for LCD RS */
|
||||
#define PIN_EBI_LCD_RS {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD RS pin */
|
||||
|
||||
#define LED_BLUE 0
|
||||
#define LED_GREEN 1
|
||||
#define LED_RED 2
|
||||
|
||||
#ifdef BOARD_REV_A
|
||||
/** LED #0 pin definition (BLUE). */
|
||||
#define PIN_LED_0 {PIO_PC20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #1 pin definition (GREEN). */
|
||||
#define PIN_LED_1 {PIO_PC21, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #2 pin definition (RED). */
|
||||
#define PIN_LED_2 {PIO_PC22, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
/** LED #0 pin definition (BLUE). */
|
||||
#define PIN_LED_0 {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #1 pin definition (GREEN). */
|
||||
#define PIN_LED_1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #2 pin definition (RED). */
|
||||
#define PIN_LED_2 {PIO_PC20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
|
||||
#endif
|
||||
|
||||
/** List of all LEDs definitions. */
|
||||
#define PINS_LEDS PIN_LED_0, PIN_LED_1, PIN_LED_2
|
||||
|
||||
/** MCI pins definition. */
|
||||
#define PINS_MCI {0x3fUL << 26, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_PULLUP}
|
||||
/** MCI pin Card Detect. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_MCI_CD {PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_MCI_CD {PIO_PA6, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** Push button #0 definition. Attributes = pull-up + debounce + interrupt on rising edge. */
|
||||
#define PIN_PUSHBUTTON_1 {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE}
|
||||
/** Push button #1 definition. Attributes = pull-up + debounce + interrupt on falling edge. */
|
||||
#define PIN_PUSHBUTTON_2 {PIO_PC12, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE}
|
||||
/** List of all push button definitions. */
|
||||
#define PINS_PUSHBUTTONS PIN_PUSHBUTTON_1, PIN_PUSHBUTTON_2
|
||||
|
||||
/** Push button #1 index. */
|
||||
#define PUSHBUTTON_BP1 0
|
||||
/** Push button #2 index. */
|
||||
#define PUSHBUTTON_BP2 1
|
||||
|
||||
/** Simulated joystick LEFT index. */
|
||||
#define JOYSTICK_LEFT 0
|
||||
/** Simulated joystick RIGHT index. */
|
||||
#define JOYSTICK_RIGHT 1
|
||||
|
||||
/** PWMC PWM0 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH0 {PIO_PC18B_PWMH0, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM0 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML0 {PIO_PA19B_PWML0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM1 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH1 {PIO_PC19B_PWMH1, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM1 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML1 {PIO_PA20B_PWML1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM2 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH2 {PIO_PC20B_PWMH2, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM2 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML2 {PIO_PA16C_PWML2, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
|
||||
/** PWMC PWM3 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH3 {PIO_PC21B_PWMH3, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM3 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML3 {PIO_PA15C_PWML3, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
|
||||
/** PWM pins definition for LED0 */
|
||||
#define PIN_PWM_LED0 PIN_PWMC_PWMH0, PIN_PWMC_PWML0
|
||||
/** PWM pins definition for LED1 */
|
||||
#define PIN_PWM_LED1 PIN_PWMC_PWMH1, PIN_PWMC_PWML1
|
||||
/** PWM pins definition for LED2 */
|
||||
#define PIN_PWM_LED2 PIN_PWMC_PWMH2, PIN_PWMC_PWML2
|
||||
/** PWM channel for LED0 */
|
||||
#define CHANNEL_PWM_LED0 0
|
||||
/** PWM channel for LED1 */
|
||||
#define CHANNEL_PWM_LED1 1
|
||||
/** PWM channel for LED2 */
|
||||
#define CHANNEL_PWM_LED2 2
|
||||
|
||||
/** SPI MISO pin definition. */
|
||||
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI MOSI pin definition. */
|
||||
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI SPCK pin definition. */
|
||||
#define PIN_SPI_SPCK {PIO_PA14A_SPCK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI chip select pin definition. */
|
||||
#define PIN_SPI_NPCS0_PA11 {PIO_PA11A_NPCS0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** List of SPI pin definitions (MISO, MOSI & SPCK). */
|
||||
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
|
||||
|
||||
/** SSC pin Transmitter Data (TD) */
|
||||
#define PIN_SSC_TD {PIO_PA17A_TD, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pin Transmitter Clock (TK) */
|
||||
#define PIN_SSC_TK {PIO_PA16A_TK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pin Transmitter FrameSync (TF) */
|
||||
#define PIN_SSC_TF {PIO_PA15A_TF, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pins definition for codec. */
|
||||
#define PINS_SSC_CODEC PIN_SSC_TD, PIN_SSC_TK, PIN_SSC_TF
|
||||
|
||||
/** PCK0 */
|
||||
#define PIN_PCK0 {PIO_PA6B_PCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
#define PIN_PCK1 {PIO_PA17B_PCK1,PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
|
||||
/** PIO PARALLEL CAPTURE */
|
||||
/** Parallel Capture Mode Data Enable1 */
|
||||
#define PIN_PIODCEN1 PIO_PA15
|
||||
/** Parallel Capture Mode Data Enable2 */
|
||||
#define PIN_PIODCEN2 PIO_PA16
|
||||
|
||||
/** TWI ver 3.xx */
|
||||
#define TWI_V3XX
|
||||
/** TWI0 data pin */
|
||||
#define PIN_TWI_TWD0 {PIO_PA3A_TWD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI0 clock pin */
|
||||
#define PIN_TWI_TWCK0 {PIO_PA4A_TWCK0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI0 pins */
|
||||
#define PINS_TWI0 PIN_TWI_TWD0, PIN_TWI_TWCK0
|
||||
/** TWI1 data pin */
|
||||
#define PIN_TWI_TWD1 {PIO_PB4A_TWD1, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI1 clock pin */
|
||||
#define PIN_TWI_TWCK1 {PIO_PB5A_TWCK1, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI1 pins */
|
||||
#define PINS_TWI1 PIN_TWI_TWD1, PIN_TWI_TWCK1
|
||||
|
||||
/** USART0 pin RX */
|
||||
#define PIN_USART0_RXD {PIO_PA5A_RXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin TX */
|
||||
#define PIN_USART0_TXD {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin CTS */
|
||||
#define PIN_USART0_CTS {PIO_PA8A_CTS0, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin RTS */
|
||||
#define PIN_USART0_RTS {PIO_PA7A_RTS0, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin SCK */
|
||||
#define PIN_USART0_SCK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** USART1 pin RX */
|
||||
#define PIN_USART1_RXD {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin TX */
|
||||
#define PIN_USART1_TXD {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin CTS */
|
||||
#define PIN_USART1_CTS {PIO_PA25A_CTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin RTS */
|
||||
#define PIN_USART1_RTS {PIO_PA24A_RTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin ENABLE */
|
||||
#define PIN_USART1_EN {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/** USART1 pin SCK */
|
||||
#define PIN_USART1_SCK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** USB VBus monitoring pin definition. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_USB_VBUS {PIO_PC23, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_USB_VBUS {PIO_PC21, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** NandFlash pins definition: OE. */
|
||||
#define PIN_EBI_NANDOE {PIO_PC9, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: WE. */
|
||||
#define PIN_EBI_NANDWE {PIO_PC10, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: CLE. */
|
||||
#define PIN_EBI_NANDCLE {PIO_PC17, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: ALE. */
|
||||
#define PIN_EBI_NANDALE {PIO_PC16, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: DATA. */
|
||||
#define PIN_EBI_NANDIO {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
|
||||
/** Nandflash chip enable pin definition. */
|
||||
#define BOARD_NF_CE_PIN {PIO_PC14, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
|
||||
/** Nandflash controller peripheral pins definition. */
|
||||
#define PINS_NANDFLASH PIN_EBI_NANDIO, BOARD_NF_CE_PIN, PIN_EBI_NANDOE, \
|
||||
PIN_EBI_NANDWE, PIN_EBI_NANDCLE, PIN_EBI_NANDALE
|
||||
|
||||
/* PIO definitions for Slider */
|
||||
#define SLIDER_IOMASK_SNS (uint32_t)(PIO_PA0 | PIO_PA2 | PIO_PA4)
|
||||
#define SLIDER_IOMASK_SNSK (uint32_t)(PIO_PA1 | PIO_PA3 | PIO_PA5)
|
||||
#define PINS_SLIDER_SNS {SLIDER_IOMASK_SNS, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
#define PINS_SLIDER_SNSK {SLIDER_IOMASK_SNSK, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/* PIO definitions for keys */
|
||||
#define KEY_IOMASK_SNS (uint32_t)(PIO_PC22 | PIO_PC24 | PIO_PC26 | PIO_PC28 | PIO_PC30)
|
||||
#define KEY_IOMASK_SNSK (uint32_t)(PIO_PC23 | PIO_PC25 | PIO_PC27 | PIO_PC29 | PIO_PC31)
|
||||
#define PINS_KEY_SNS {KEY_IOMASK_SNS, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
#define PINS_KEY_SNSK {KEY_IOMASK_SNSK, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/* PIOS for QTouch */
|
||||
#define PINS_QTOUCH PINS_SLIDER_SNS, PINS_SLIDER_SNSK, PINS_KEY_SNS, PINS_KEY_SNSK
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_usb "SAM3S-EK - USB device"
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_USB_BMATTRIBUTES
|
||||
* - \ref CHIP_USB_UDP
|
||||
* - \ref CHIP_USB_PULLUP_INTERNAL
|
||||
* - \ref CHIP_USB_NUMENDPOINTS
|
||||
* - \ref CHIP_USB_ENDPOINTS_MAXPACKETSIZE
|
||||
* - \ref CHIP_USB_ENDPOINTS_BANKS
|
||||
*/
|
||||
|
||||
/** USB attributes configuration descriptor (bus or self powered, remote wakeup) */
|
||||
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
|
||||
|
||||
/** Indicates chip has an UDP Full Speed. */
|
||||
#define CHIP_USB_UDP
|
||||
|
||||
/** Indicates chip has an internal pull-up. */
|
||||
#define CHIP_USB_PULLUP_INTERNAL
|
||||
|
||||
/** Number of USB endpoints */
|
||||
#define CHIP_USB_NUMENDPOINTS 8
|
||||
|
||||
/** Endpoints max paxcket size */
|
||||
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
|
||||
((i == 0) ? 64 : \
|
||||
((i == 1) ? 64 : \
|
||||
((i == 2) ? 64 : \
|
||||
((i == 3) ? 64 : \
|
||||
((i == 4) ? 512 : \
|
||||
((i == 5) ? 512 : \
|
||||
((i == 6) ? 64 : \
|
||||
((i == 7) ? 64 : 0 ))))))))
|
||||
|
||||
/** Endpoints Number of Bank */
|
||||
#define CHIP_USB_ENDPOINTS_BANKS(i) \
|
||||
((i == 0) ? 1 : \
|
||||
((i == 1) ? 2 : \
|
||||
((i == 2) ? 2 : \
|
||||
((i == 3) ? 1 : \
|
||||
((i == 4) ? 2 : \
|
||||
((i == 5) ? 2 : \
|
||||
((i == 6) ? 2 : \
|
||||
((i == 7) ? 2 : 0 ))))))))
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_extcomp "SAM3S-EK - External components"
|
||||
* This page lists the definitions related to external on-board components
|
||||
* located in the board.h file for the AT91SAM3S-EK.
|
||||
*
|
||||
* SD Card
|
||||
* - \ref BOARD_SD_PINS
|
||||
* - \ref BOARD_SD_PIN_CD
|
||||
*
|
||||
* LCD
|
||||
* - \ref BOARD_LCD_ILI9325
|
||||
* - \ref BOARD_LCD_PINS
|
||||
* - \ref BOARD_BACKLIGHT_PIN
|
||||
* - \ref BOARD_LCD_BASE
|
||||
* - \ref BOARD_LCD_RS
|
||||
* - \ref BOARD_LCD_WIDTH
|
||||
* - \ref BOARD_LCD_HEIGHT
|
||||
*
|
||||
* TouchScreen
|
||||
* - \ref BOARD_TSC_ADS7843
|
||||
* - \ref PIN_TCS_IRQ
|
||||
* - \ref PIN_TCS_BUSY
|
||||
* - \ref BOARD_TSC_SPI_BASE
|
||||
* - \ref BOARD_TSC_SPI_ID
|
||||
* - \ref BOARD_TSC_SPI_PINS
|
||||
* - \ref BOARD_TSC_NPCS
|
||||
* - \ref BOARD_TSC_NPCS_PIN
|
||||
*
|
||||
* SmartCard
|
||||
* - \ref SMARTCARD_CONNECT_PIN
|
||||
* - \ref PIN_ISO7816_RSTMC
|
||||
* - \ref PINS_ISO7816
|
||||
*/
|
||||
|
||||
/** MCI pins that shall be configured to access the SD card. */
|
||||
#define BOARD_SD_PINS PINS_MCI
|
||||
/** MCI Card Detect pin. */
|
||||
#define BOARD_SD_PIN_CD PIN_MCI_CD
|
||||
|
||||
/** Indicates board has an ILI9325 external component to manage LCD. */
|
||||
#define BOARD_LCD_ILI9325
|
||||
|
||||
/** LCD pins definition. */
|
||||
#define BOARD_LCD_PINS PIN_EBI_DATA_BUS, PIN_EBI_NRD, PIN_EBI_NWE, PIN_EBI_NCS1, PIN_EBI_LCD_RS
|
||||
/** Backlight pin definition. */
|
||||
#define BOARD_BACKLIGHT_PIN {PIO_PC13, PIOC, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/** Define ILI9325 base address. */
|
||||
#define BOARD_LCD_BASE 0x61000000
|
||||
/** Define ILI9325 register select signal. */
|
||||
#define BOARD_LCD_RS (1 << 1)
|
||||
/** Display width in pixels. */
|
||||
#define BOARD_LCD_WIDTH 240
|
||||
/** Display height in pixels. */
|
||||
#define BOARD_LCD_HEIGHT 320
|
||||
|
||||
/** Indicates board has an ADS7843 external component to manage Touch Screen */
|
||||
#define BOARD_TSC_ADS7843
|
||||
|
||||
/** Touchscreen controller IRQ pin definition. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_TSC_IRQ {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#define PIN_TSC_IRQ_WUP_ID (1 << 3)
|
||||
/** Touchscreen controller Busy pin definition. */
|
||||
#define PIN_TSC_BUSY {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_TSC_IRQ {PIO_PA16, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#define PIN_TSC_IRQ_WUP_ID (1 << 15)
|
||||
/** Touchscreen controller Busy pin definition. */
|
||||
#define PIN_TSC_BUSY {PIO_PA17, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** Base address of SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_BASE SPI
|
||||
/** Identifier of SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_ID ID_SPI
|
||||
/** Pins of the SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_PINS PINS_SPI
|
||||
/** Chip select connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_NPCS 0
|
||||
/** Chip select pin connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_NPCS_PIN PIN_SPI_NPCS0_PA11
|
||||
|
||||
/// Smartcard detection pin
|
||||
//#define SMARTCARD_CONNECT_PIN {1 << 13, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/// PIN used for reset the smartcard
|
||||
#define PIN_ISO7816_RSTMC {1 << 11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/// Pins used for connect the smartcard
|
||||
#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_mem "SAM3S-EK - Memories"
|
||||
* This page lists definitions related to internal & external on-board memories.
|
||||
*
|
||||
* \section SRAM
|
||||
* - \ref AT91C_ISRAM
|
||||
* - \ref AT91C_ISRAM_SIZE
|
||||
*
|
||||
* \section Flash
|
||||
* - \ref AT91C_IFLASH_SIZE
|
||||
* - \ref AT91C_IFLASH_PAGE_SIZE
|
||||
* - \ref AT91C_IFLASH_NB_OF_PAGES
|
||||
* - \ref AT91C_IFLASH_LOCK_REGION_SIZE
|
||||
* - \ref AT91C_IFLASH_NB_OF_LOCK_BITS
|
||||
*
|
||||
* \section NandFlash
|
||||
* - \ref BOARD_NF_COMMAND_ADDR
|
||||
* - \ref BOARD_NF_ADDRESS_ADDR
|
||||
* - \ref BOARD_NF_DATA_ADDR
|
||||
*
|
||||
* \section NorFlash
|
||||
* - \ref BOARD_NORFLASH_ADDR
|
||||
* - \ref BOARD_NORFLASH_DFT_BUS_SIZE
|
||||
*/
|
||||
|
||||
/** Address for transferring command bytes to the nandflash. */
|
||||
#define BOARD_NF_COMMAND_ADDR 0x60400000
|
||||
/** Address for transferring address bytes to the nandflash. */
|
||||
#define BOARD_NF_ADDRESS_ADDR 0x60200000
|
||||
/** Address for transferring data bytes to the nandflash. */
|
||||
#define BOARD_NF_DATA_ADDR 0x60000000
|
||||
|
||||
/** Address for transferring command bytes to the norflash. */
|
||||
#define BOARD_NORFLASH_ADDR 0x63000000
|
||||
/** Default NOR bus size after power up reset */
|
||||
#define BOARD_NORFLASH_DFT_BUS_SIZE 8
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_chipdef "SAM3S-EK - Individual chip definition"
|
||||
* This page lists the definitions related to different chip's definition
|
||||
* located in the board.h file for the SAM3S-EK.
|
||||
*
|
||||
* \section USART
|
||||
* - \ref BOARD_PIN_USART_RXD
|
||||
* - \ref BOARD_PIN_USART_TXD
|
||||
* - \ref BOARD_PIN_USART_CTS
|
||||
* - \ref BOARD_PIN_USART_RTS
|
||||
* - \ref BOARD_PIN_USART_EN
|
||||
* - \ref BOARD_USART_BASE
|
||||
* - \ref BOARD_ID_USART
|
||||
*/
|
||||
|
||||
/** Rtc */
|
||||
#define BOARD_RTC_ID ID_RTC
|
||||
|
||||
/** TWI ID for EEPROM application to use */
|
||||
#define BOARD_ID_TWI_EEPROM ID_TWI1
|
||||
/** TWI ID for SLAVE application to use */
|
||||
#define BOARD_ID_TWI_SLAVE ID_TWI1
|
||||
/** TWI Base for TWI EEPROM application to use */
|
||||
#define BOARD_BASE_TWI_EEPROM TWI1
|
||||
/** TWI Base for TWI SLAVE application to use */
|
||||
#define BOARD_BASE_TWI_SLAVE TWI1
|
||||
/** TWI pins for EEPROM application to use */
|
||||
#define BOARD_PINS_TWI_EEPROM PINS_TWI1
|
||||
/** TWI pins for TWI SLAVE application to use */
|
||||
#define BOARD_PINS_TWI_SLAVE PINS_TWI1
|
||||
|
||||
/** USART RX pin for application */
|
||||
#define BOARD_PIN_USART_RXD PIN_USART1_RXD
|
||||
/** USART TX pin for application */
|
||||
#define BOARD_PIN_USART_TXD PIN_USART1_TXD
|
||||
/** USART CTS pin for application */
|
||||
#define BOARD_PIN_USART_CTS PIN_USART1_CTS
|
||||
/** USART RTS pin for application */
|
||||
#define BOARD_PIN_USART_RTS PIN_USART1_RTS
|
||||
/** USART ENABLE pin for application */
|
||||
#define BOARD_PIN_USART_EN PIN_USART1_EN
|
||||
/** USART Base for application */
|
||||
#define BOARD_USART_BASE USART1
|
||||
/** USART ID for application */
|
||||
#define BOARD_ID_USART ID_USART1
|
||||
|
||||
#endif /* #ifndef _BOARD_ */
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Interface for the low-level initialization function.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BOARD_LOWLEVEL_H
|
||||
#define BOARD_LOWLEVEL_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern void LowLevelInit( void ) ;
|
||||
|
||||
#endif /* BOARD_LOWLEVEL_H */
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S1
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(ResetException)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.fixed :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sfixed = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text*)
|
||||
*(.ramfunc)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
_efixed = .; /* End of text section */
|
||||
} > sram
|
||||
|
||||
.relocate : AT (_efixed)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_srelocate = .;
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
_erelocate = .;
|
||||
} >sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in the end of SRAM */
|
||||
_estack = 0x20003FFC;
|
||||
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S1
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00003800 /* sram, 16K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x20003FFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S2
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(ResetException)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.fixed :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sfixed = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text*)
|
||||
*(.ramfunc)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
_efixed = .; /* End of text section */
|
||||
} > sram
|
||||
|
||||
.relocate : AT (_efixed)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_srelocate = .;
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
_erelocate = .;
|
||||
} >sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in the end of SRAM */
|
||||
_estack = 0x20007FFC;
|
||||
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S2
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00007800 /* sram, 32K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x20007FFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,215 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S4
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3micro)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0000C000 /* sram, 48K */
|
||||
}
|
||||
|
||||
/* These force the linker to search for particular symbols from
|
||||
* the start of the link process and thus ensure the user's
|
||||
* overrides are picked up
|
||||
*/
|
||||
EXTERN(__cs3_reset_generic_m)
|
||||
INCLUDE atsam3s.inc
|
||||
EXTERN(__cs3_interrupt_vector_micro)
|
||||
EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
|
||||
|
||||
PROVIDE(__cs3_heap_start = _end);
|
||||
PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
|
||||
PROVIDE(__cs3_region_num = (__cs3_regions_end - __cs3_regions) / 20);
|
||||
PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__cs3_region_start_ram = .;
|
||||
*(.cs3.region-head.ram)
|
||||
ASSERT (. == __cs3_region_start_ram, ".cs3.region-head.ram not permitted");
|
||||
__cs3_interrupt_vector = __cs3_interrupt_vector_micro;
|
||||
*(.cs3.interrupt_vector)
|
||||
/* Make sure we pulled in an interrupt vector. */
|
||||
ASSERT (. != __cs3_interrupt_vector_micro, "No interrupt vector");
|
||||
|
||||
_start = __cs3_reset_generic_m;
|
||||
__cs3_reset = __cs3_reset_generic_m;
|
||||
*(.cs3.reset)
|
||||
/* Make sure we pulled in some reset code. */
|
||||
ASSERT (. != __cs3_reset, "No reset code");
|
||||
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
} >ram
|
||||
.eh_frame_hdr : ALIGN (4)
|
||||
{
|
||||
KEEP (*(.eh_frame_hdr))
|
||||
} >ram
|
||||
.eh_frame : ALIGN (4)
|
||||
{
|
||||
KEEP (*(.eh_frame))
|
||||
} >ram
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >ram
|
||||
__exidx_end = .;
|
||||
.rodata : ALIGN (4)
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
__fini_array_start = .;
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
__fini_array_end = .;
|
||||
|
||||
. = ALIGN(0x4);
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
|
||||
. = ALIGN(0x4);
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
. = ALIGN(4);
|
||||
__cs3_regions = .;
|
||||
LONG (0)
|
||||
LONG (__cs3_region_init_ram)
|
||||
LONG (__cs3_region_start_ram)
|
||||
LONG (__cs3_region_init_size_ram)
|
||||
LONG (__cs3_region_zero_size_ram)
|
||||
__cs3_regions_end = .;
|
||||
|
||||
. = ALIGN (8);
|
||||
_etext = .;
|
||||
} >ram
|
||||
|
||||
.data : ALIGN (8)
|
||||
{
|
||||
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (8);
|
||||
*(.ram)
|
||||
_edata = .;
|
||||
} >ram
|
||||
.bss :
|
||||
{
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
*(.ram.b)
|
||||
_end = .;
|
||||
__end = .;
|
||||
} >ram
|
||||
__cs3_region_init_ram = __cs3_region_start_ram;
|
||||
__cs3_region_init_size_ram = _edata - __cs3_region_start_ram;
|
||||
__cs3_region_zero_size_ram = _end - _edata;
|
||||
/* Default to 1M of heap */
|
||||
__cs3_region_size_ram = ALIGN (1024) - __cs3_region_start_ram + 1M;
|
||||
|
||||
.stab 0 (NOLOAD) : { *(.stab) }
|
||||
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||
/* DWARF debug sections.
|
||||
* Symbols in the DWARF debugging sections are relative to the beginning
|
||||
* of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* DWARF 2.1 */
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
||||
/* checksum: 576d003e2604ff7a1b02791267 */
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S4
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x01000
|
||||
sram (W!RX) : ORIGIN = 0x20001000, LENGTH = 0x0000B000 /* sram, 48K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x2000BFFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef _LIB_ATSAM3S_
|
||||
#define _LIB_ATSAM3S_
|
||||
|
||||
/*
|
||||
* Peripherals registers definitions
|
||||
*/
|
||||
#if defined atsam3s4
|
||||
#include <include/ATSAM3S4.h>
|
||||
#elif defined atsam3s2
|
||||
#include <include/ATSAM3S2.h>
|
||||
#elif defined atsam3s1
|
||||
#include <include/ATSAM3S1.h>
|
||||
#else
|
||||
#warning Library does not support the specified chip, specifying atsam3s4.
|
||||
#define atsam3s4
|
||||
#include <include/ATSAM3S4.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Define attribute */
|
||||
#if defined ( __CC_ARM ) /* Keil µVision 4 */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
|
||||
#define WEAK __weak
|
||||
#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#endif
|
||||
|
||||
/* Define NO_INIT attribute */
|
||||
#if defined ( __CC_ARM )
|
||||
#define NO_INIT
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define NO_INIT __no_init
|
||||
#elif defined ( __GNUC__ )
|
||||
#define NO_INIT
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
/*
|
||||
* Peripherals
|
||||
*/
|
||||
//#include <include/async.h>
|
||||
//#include <include/efc.h>
|
||||
//#include <include/flashd.h>
|
||||
//#include <include/pio.h>
|
||||
//#include <include/pmc.h>
|
||||
//#include <include/spi.h>
|
||||
//#include <include/spi_pdc.h>
|
||||
//#include <include/twi.h>
|
||||
//#include <include/twid.h>
|
||||
//#include <include/usart.h>
|
||||
|
||||
/*
|
||||
#include <USBD_Config.h>
|
||||
*/
|
||||
|
||||
//#include <include/trace.h>
|
||||
//#include <include/wdt.h>
|
||||
|
||||
#endif /* _LIB_ATSAM3S_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+235
@@ -0,0 +1,235 @@
|
||||
******************************************
|
||||
CHANGELOG: 07-05-2012 BSS
|
||||
AutoSwitch feature added
|
||||
Mix Warning was not so regular (sometime 2 ticks instead of 3)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 06-05-2012 BSS
|
||||
FW options now stored in a byte of the EEPROM
|
||||
[Arm] getSwitch() problem with Custom Switches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 05-05-2012 BSS
|
||||
[FrSky] Speed in Gauges configuration was buggy
|
||||
[FrSky] We stored Min Speed instead of Max Speed
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-05-2012 BSS
|
||||
Momentary Switches in Function Switches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 03-05-2012 BSS
|
||||
[Arm] Audio / Haptic refactoring
|
||||
[Arm] Timer blocked at 10:55
|
||||
[V4] SDcard menu reworked
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 02-05-2012 BSS
|
||||
[V4/Arm] Problem in Models Move
|
||||
[stock] Flash saving (840bytes)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-05-2012 BSS
|
||||
[FrSky] GPS distance bug fix
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 29-04-2012 BSS
|
||||
[V4/Arm] EEPROM marked as dirty on reboot
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-04-2012 BSS
|
||||
Vario feature added
|
||||
New EEPROM format 205
|
||||
[FrSky] Telemetry offset for A1/A2 on 12bits
|
||||
[V4] Models with empty name bug when SDcard backup
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 26-04-2012 BSS
|
||||
[Arm] 32Channels 9Phases 64Mixes 32Expos 32VSwitches 32FSwitches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 23-04-2012 BSS
|
||||
[V4] SDcard Models storage implemented
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 20-04-2012 BSS
|
||||
[Stock] 400bytes flash saving
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 15-03-2012 BSS
|
||||
FAAST option in protocol to enable startPulses before the splash screen
|
||||
Telemetry configurable screen
|
||||
Confirmation before applying templates
|
||||
Used channels cleaned before applying a template
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 14-03-2012 BSS
|
||||
Potscroll option added
|
||||
|
||||
******************************************
|
||||
|
||||
Version 364:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-03-2012 BSS
|
||||
New EEPROM format 205
|
||||
Introduction of differential in Mixers
|
||||
Introduction of Switches as Mixer Source (FULL now removed)
|
||||
Negative curves in Mixers
|
||||
Optimizations in Mixer
|
||||
Extended chars for localization
|
||||
Swedish translations
|
||||
Beep length updated
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-03-2012 BSS
|
||||
Feature "Use THR trim as a slider" now finished
|
||||
[FrSky] Jitter (2us) introduced by last optimization removed
|
||||
Trim parameter in Mixer is OFF if the source is not a stick
|
||||
GPS distance fixed
|
||||
|
||||
******************************************
|
||||
|
||||
Version 304:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 28-02-2012 BSS
|
||||
Flash saving (600bytes)
|
||||
[FrSky] NO DATA displayed on the status line when nothing received
|
||||
Sticks/Pots center beep now more accurate
|
||||
Beeps length for center beep and inactivity reduced
|
||||
Vibration when MIN/MID/MAX trim position reached
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-02-2012 BSS
|
||||
Flash saving (idea from er9x)
|
||||
Trims2Offsets function removed
|
||||
A "Safety CHxx" function is not applied when it is currently edited
|
||||
The Stick Mode needs confirmation before being applied
|
||||
|
||||
******************************************
|
||||
|
||||
Version 288:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 24-02-2012 BSS
|
||||
Throttle Trace bug solved when using P1-P3
|
||||
New way of dealing with recursive mixers in Flight Phases (with FadeIn / FadeOut)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 23-02-2012 BSS
|
||||
PXX updates + optimizations pulled from er9x
|
||||
FrSky TELEMETRY menu is now moved to [DOWN long]
|
||||
Optimizations
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 22-02-2012 BSS
|
||||
Blades count may now be 4
|
||||
V4: New mixers/expos fields inflight modifiable through RE1
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 21-02-2012 BSS
|
||||
V4: Logs format ported from gruvin9x
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 20-02-2012 BSS
|
||||
Last GPS coords displayed even when streaming stops (model lost)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 19-02-2012 BSS
|
||||
V4: Inflight fields modification through RE1 feature added
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 17-02-2012 BSS
|
||||
RSSI thresholds on a per model basis
|
||||
Flash Saving
|
||||
FrSky Hub variometer + cells voltage fix
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 16-02-2012 BSS
|
||||
Beeper mode splitted from Beeper length
|
||||
Haptic redesigned
|
||||
No FrSky alarms when Tx asked to be quiet
|
||||
Flash Saving
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 14-02-2012 BSS
|
||||
Blades count configuration for RPMs
|
||||
Instant trim bug fixed for stick modes != RETA
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 1O-02-2012 BSS
|
||||
Copyright updated
|
||||
GPS distance and speed bug fixes
|
||||
|
||||
******************************************
|
||||
|
||||
Version 232:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 09-02-2012 BSS
|
||||
Multiplier added for telemetry A1/A2 => 204.0v!
|
||||
GPS distance added
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 08-02-2012 BSS
|
||||
Telemetry bars screen
|
||||
Add individual cell voltages from FrSky Hub 2.0
|
||||
New units for A1/A2
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 06-02-2012 BSS
|
||||
Flash saving
|
||||
Telemetry screens redesigned
|
||||
|
||||
******************************************
|
||||
|
||||
Version 213:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 05-02-2012 BSS
|
||||
Add GPS speed display, with max speed
|
||||
GPS screen redesigned
|
||||
|
||||
******************************************
|
||||
|
||||
Version 205:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-02-2012 BSS
|
||||
New way of configuring A1 and A2 using Range and Offset
|
||||
Named sounds in Func Switches
|
||||
Haptic only sounds skipped when HAPTIC option disable
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 03-02-2012 BSS
|
||||
Safety switches screen removed (moved to Func Switches)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 02-02-2012 BSS
|
||||
French translations updated
|
||||
AUDIO optimizations
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-02-2012 BSS
|
||||
AUDIO and HAPTIC may be enabled separately
|
||||
AUDIO bug fixes
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 31-01-2012 BSS
|
||||
HAPTIC now working
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 29-01-2012 BSS
|
||||
Inactivity timer reset on Keys and Trims press
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 28-01-2012 BSS
|
||||
New splash
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-01-2012 BSS
|
||||
NMEA and ARDUPILOT ported from er9x
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
macro(add_bitmaps_target targetname filter width format)
|
||||
set(bitmaps_files)
|
||||
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_EXECUTABLE} ${RADIO_DIRECTORY}/util/img2lbm.py ${bitmap} ${target} ${width} ${format} ${ARGN}
|
||||
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 offset)
|
||||
set(target ${RADIO_SRC_DIRECTORY}/fonts/${radio}/font_${name})
|
||||
add_custom_target(ttf_${radio}_${name}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/font2png.py ${font} ${size} ${offset} ${target}
|
||||
WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
|
||||
)
|
||||
set(ttf_${radio}_fonts_targets ${ttf_${radio}_fonts_targets} ttf_${radio}_${name})
|
||||
endmacro(add_truetype_font_target)
|
||||
@@ -1,63 +0,0 @@
|
||||
# Imported from the DeskVox project (LPGL 2.1)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(hints
|
||||
$ENV{LIB_BASE_PATH}/fox
|
||||
)
|
||||
|
||||
set(paths
|
||||
/usr
|
||||
/usr/local
|
||||
)
|
||||
|
||||
find_path(FOX_INCLUDE_DIR
|
||||
NAMES
|
||||
fx.h
|
||||
HINTS
|
||||
${hints}
|
||||
PATHS
|
||||
${paths}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
include/fox
|
||||
include/fox-1.6
|
||||
)
|
||||
|
||||
find_library(FOX_LIBRARY
|
||||
NAMES
|
||||
FOX-1.6
|
||||
fox-1.6
|
||||
HINTS
|
||||
${hints}
|
||||
PATHS
|
||||
${paths}
|
||||
PATH_SUFFIXES
|
||||
lib64
|
||||
lib
|
||||
)
|
||||
|
||||
find_library(FOX_LIBRARY_DEBUG
|
||||
NAMES
|
||||
FOXD-1.6
|
||||
foxd-1.6
|
||||
HINTS
|
||||
${hints}
|
||||
PATHS
|
||||
${paths}
|
||||
PATH_SUFFIXES
|
||||
lib64
|
||||
lib
|
||||
)
|
||||
|
||||
if(FOX_LIBRARY_DEBUG)
|
||||
set(FOX_LIBRARIES optimized ${FOX_LIBRARY} debug ${FOX_LIBRARY_DEBUG})
|
||||
else()
|
||||
set(FOX_LIBRARIES ${FOX_LIBRARY})
|
||||
endif()
|
||||
|
||||
find_package_handle_standard_args(FOX
|
||||
DEFAULT_MSG
|
||||
FOX_INCLUDE_DIR
|
||||
FOX_LIBRARY
|
||||
)
|
||||
@@ -1,71 +0,0 @@
|
||||
# Find libphonon
|
||||
# Once done this will define
|
||||
#
|
||||
# PHONON_FOUND - system has Phonon Library
|
||||
# PHONON_INCLUDES - the Phonon include directory
|
||||
# PHONON_LIBS - link these to use Phonon
|
||||
# PHONON_VERSION - the version of the Phonon Library
|
||||
|
||||
# Copyright (c) 2008, Matthias Kretz <kretz@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro(_phonon_find_version)
|
||||
set(_phonon_namespace_header_file "${PHONON_INCLUDE_DIR}/phonon/phononnamespace.h")
|
||||
if (APPLE AND EXISTS "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h")
|
||||
set(_phonon_namespace_header_file "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h")
|
||||
endif (APPLE AND EXISTS "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h")
|
||||
file(READ ${_phonon_namespace_header_file} _phonon_header LIMIT 5000 OFFSET 1000)
|
||||
string(REGEX MATCH "define PHONON_VERSION_STR \"(4\\.[0-9]+\\.[0-9a-z]+)\"" _phonon_version_match "${_phonon_header}")
|
||||
set(PHONON_VERSION "${CMAKE_MATCH_1}")
|
||||
message(STATUS "Phonon Version: ${PHONON_VERSION}")
|
||||
endmacro(_phonon_find_version)
|
||||
|
||||
if(PHONON_FOUND)
|
||||
# Already found, nothing more to do except figuring out the version
|
||||
_phonon_find_version()
|
||||
else(PHONON_FOUND)
|
||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
set(PHONON_FIND_QUIETLY TRUE)
|
||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
|
||||
# As discussed on kde-buildsystem: first look at CMAKE_PREFIX_PATH, then at the suggested PATHS (kde4 install dir)
|
||||
find_library(PHONON_LIBRARY NAMES phonon phonon4 PATHS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
|
||||
# then at the default system locations (CMAKE_SYSTEM_PREFIX_PATH, i.e. /usr etc.)
|
||||
find_library(PHONON_LIBRARY NAMES phonon)
|
||||
|
||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h PATHS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} ${QT_LIBRARY_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
|
||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h)
|
||||
|
||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
set(PHONON_LIBS ${phonon_LIB_DEPENDS} ${PHONON_LIBRARY})
|
||||
set(PHONON_INCLUDES ${PHONON_INCLUDE_DIR}/KDE ${PHONON_INCLUDE_DIR})
|
||||
set(PHONON_FOUND TRUE)
|
||||
_phonon_find_version()
|
||||
else(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
set(PHONON_FOUND FALSE)
|
||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
|
||||
if(PHONON_FOUND)
|
||||
if(NOT PHONON_FIND_QUIETLY)
|
||||
message(STATUS "Found Phonon: ${PHONON_LIBRARY}")
|
||||
message(STATUS "Found Phonon Includes: ${PHONON_INCLUDES}")
|
||||
endif(NOT PHONON_FIND_QUIETLY)
|
||||
else(PHONON_FOUND)
|
||||
if(Phonon_FIND_REQUIRED)
|
||||
if(NOT PHONON_INCLUDE_DIR)
|
||||
message(STATUS "Phonon includes NOT found!")
|
||||
endif(NOT PHONON_INCLUDE_DIR)
|
||||
if(NOT PHONON_LIBRARY)
|
||||
message(STATUS "Phonon library NOT found!")
|
||||
endif(NOT PHONON_LIBRARY)
|
||||
message(FATAL_ERROR "Phonon library or includes NOT found!")
|
||||
else(Phonon_FIND_REQUIRED)
|
||||
message(STATUS "Unable to find Phonon")
|
||||
endif(Phonon_FIND_REQUIRED)
|
||||
endif(PHONON_FOUND)
|
||||
|
||||
|
||||
mark_as_advanced(PHONON_INCLUDE_DIR PHONON_LIBRARY PHONON_INCLUDES)
|
||||
endif(PHONON_FOUND)
|
||||
@@ -1,256 +0,0 @@
|
||||
#.rst:
|
||||
# FindSDL
|
||||
# -------
|
||||
#
|
||||
# Locate SDL library
|
||||
#
|
||||
# This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDL_FOUND, if false, do not try to link to SDL
|
||||
# SDL_LIBRARY, the name(s) of the library(ies) to link against
|
||||
# SDL_LIBSDL, the full path and name of libSDL (or SDL.[lib|dll].
|
||||
# SDL_LIBSDLMAIN, full path and name of libSDLmain (or SDLmain.lib).
|
||||
# SDL_LIBRARY_PATH, the full path to the found libSDL
|
||||
# SDL_INCLUDE_DIR, where to find SDL.h
|
||||
# SDL_VERSION_STRING, human-readable string containing the version of SDL
|
||||
#
|
||||
#
|
||||
#
|
||||
# This module responds to the flag:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDL_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL_main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the proper link flags
|
||||
# as part of the returned SDL_LIBRARY variable.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDLmain which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL_LIBSDL in your
|
||||
# configuration and no SDL_LIBRARY, it means CMake did not find your SDL
|
||||
# library (SDL.dll, libsdl.so, SDL.framework, etc). Set
|
||||
# SDL_LIBSDL to point to your SDL library, and configure again.
|
||||
# Similarly, if you see an empty SDL_LIBSDLMAIN, you should set this
|
||||
# value as appropriate. These values are used to generate the final
|
||||
# SDL_LIBRARY variable, but when these values are unset, SDL_LIBRARY
|
||||
# does not get created.
|
||||
#
|
||||
#
|
||||
#
|
||||
# $SDLDIR is an environment variable that would correspond to the
|
||||
# ./configure --prefix=$SDLDIR used in building SDL. l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing. Added code to assist with automated building
|
||||
# by using environmental variables and providing a more
|
||||
# controlled/consistent search behavior. Added new modifications to
|
||||
# recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL
|
||||
# guidelines. Added a search for SDLmain which is needed by some
|
||||
# platforms. Added a search for threads which is needed by some
|
||||
# platforms. Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of SDL_LIBRARY to
|
||||
# override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention is #include
|
||||
# "SDL.h", not <SDL/SDL.h>. This is done for portability reasons
|
||||
# because not all systems place things in SDL/ (see FreeBSD).
|
||||
|
||||
#
|
||||
# Modified for OpenTx by Maxim Paperno 19-Dec-2016
|
||||
# Added SDL_LIBSDL, SDL_LIBSDLMAIN & SDL_LIBRARY_PATH, removed SDLMAIN_LIBRARY,
|
||||
# SDL_LIBRARY_TEMP, and fixed bug with recursive appending of supporting
|
||||
# libraries to cached SDL_LIBRARY_TEMP variable.
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
#CMake - Cross Platform Makefile Generator
|
||||
#Copyright 2000-2015 Kitware, Inc.
|
||||
#Copyright 2000-2011 Insight Software Consortium
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions
|
||||
#are met:
|
||||
#
|
||||
#* Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#* Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
#The above copyright and license notice applies to distributions of
|
||||
#CMake in source and binary form. Some source files contain additional
|
||||
#notices of original copyright by their contributors; see each source
|
||||
#for details. Third-party software packages supplied with CMake under
|
||||
#compatible licenses provide their own copyright notices documented in
|
||||
#corresponding subdirectories.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
#CMake was initially developed by Kitware with the following sponsorship:
|
||||
#
|
||||
# * National Library of Medicine at the National Institutes of Health
|
||||
# as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||
#
|
||||
# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||
# Visualization Initiative.
|
||||
#
|
||||
# * National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||
# National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||
# Grant U54 EB005149.
|
||||
#
|
||||
# * Kitware, Inc.
|
||||
#=============================================================================
|
||||
|
||||
|
||||
find_path(SDL_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
# path suffixes to search inside ENV{SDLDIR}
|
||||
include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
|
||||
# SDL-1.1 is the name used by FreeBSD ports...
|
||||
# don't confuse it for the version number.
|
||||
find_library(SDL_LIBSDL
|
||||
NAMES SDL SDL-1.1
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
)
|
||||
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDLmain for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
find_library(SDL_LIBSDLMAIN
|
||||
NAMES SDLmain SDLmain-1.1
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
# SDL may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
if(NOT APPLE)
|
||||
find_package(Threads)
|
||||
endif()
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL
|
||||
if(MINGW)
|
||||
set(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
endif()
|
||||
|
||||
if(SDL_LIBSDL)
|
||||
# For SDLmain
|
||||
if(SDL_LIBSDLMAIN AND NOT SDL_BUILDING_LIBRARY AND NOT SDL_INCLUDE_DIR MATCHES ".framework")
|
||||
list(FIND SDL_LIBSDL "${SDL_LIBSDLMAIN}" _SDL_MAIN_INDEX)
|
||||
if(_SDL_MAIN_INDEX EQUAL -1)
|
||||
list(APPEND _SDL_LIBRARY_TEMP "${SDL_LIBSDLMAIN}")
|
||||
endif()
|
||||
unset(_SDL_MAIN_INDEX)
|
||||
endif()
|
||||
|
||||
list(APPEND _SDL_LIBRARY_TEMP "${SDL_LIBSDL}")
|
||||
|
||||
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
if(APPLE)
|
||||
list(APPEND _SDL_LIBRARY_TEMP "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
if(Threads_FOUND)
|
||||
list(APPEND _SDL_LIBRARY_TEMP ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL
|
||||
if(MINGW)
|
||||
list(INSERT 0 _SDL_LIBRARY_TEMP mingw32)
|
||||
endif()
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
set(SDL_LIBRARY ${_SDL_LIBRARY_TEMP} CACHE STRING "Full list of required SDL & supporting libraries.")
|
||||
unset(_SDL_LIBRARY_TEMP)
|
||||
|
||||
get_filename_component(_SDL_LIBRARY_TEMP ${SDL_LIBSDL} PATH)
|
||||
set(SDL_LIBRARY_PATH ${_SDL_LIBRARY_TEMP} CACHE PATH "Path to SDL library.")
|
||||
unset(_SDL_LIBRARY_TEMP)
|
||||
endif()
|
||||
|
||||
if(SDL_INCLUDE_DIR AND EXISTS "${SDL_INCLUDE_DIR}/SDL_version.h")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
|
||||
set(SDL_VERSION_STRING ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
|
||||
unset(SDL_VERSION_MAJOR_LINE)
|
||||
unset(SDL_VERSION_MINOR_LINE)
|
||||
unset(SDL_VERSION_PATCH_LINE)
|
||||
unset(SDL_VERSION_MAJOR)
|
||||
unset(SDL_VERSION_MINOR)
|
||||
unset(SDL_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
|
||||
REQUIRED_VARS SDL_LIBRARY SDL_LIBRARY_PATH SDL_INCLUDE_DIR
|
||||
VERSION_VAR SDL_VERSION_STRING)
|
||||
@@ -1,68 +0,0 @@
|
||||
# Find Xerces-C
|
||||
# The following setings are defined
|
||||
# XERCESC_ROOT_DIR, the root of the include and lib directory
|
||||
# XERCESC_INCLUDE_DIR, the full path of the include dir (ADVANCED)
|
||||
# XERCESC_LIBRARIES, the name of the xerces-c library (ADVANCED)
|
||||
|
||||
# Look for a root installation
|
||||
IF( MSVC )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces-vc )
|
||||
ELSE( )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PATH(XERCESC_ROOT_DIR include/xercesc/parsers/SAXParser.hpp
|
||||
${XERCES_WINDIR}
|
||||
"C:/mingw/msys/1.0/local"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2"
|
||||
/usr
|
||||
/usr/local
|
||||
"C:/MinGW"
|
||||
$ENV{CODESYNTH}
|
||||
DOC "The root of an installed xerces-c installation"
|
||||
)
|
||||
|
||||
# try to find the header
|
||||
FIND_PATH(XERCESC_INCLUDE_DIR xercesc/parsers/SAXParser.hpp
|
||||
${XERCESC_ROOT_DIR}/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Find the library
|
||||
FIND_LIBRARY(XERCESC_LIBRARY
|
||||
NAMES xerces-c xerces-c_3
|
||||
PATHS
|
||||
${XERCESC_ROOT_DIR}/lib
|
||||
${XERCESC_ROOT_DIR}/lib/vc-9.0
|
||||
${XERCESC_ROOT_DIR}/lib64/vc-9.0
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
DOC "The name of the xerces-c library"
|
||||
)
|
||||
|
||||
IF (XERCESC_ROOT_DIR)
|
||||
IF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
SET (XERCESC_FOUND TRUE)
|
||||
SET (XERCESC_LIBRARIES "${XERCESC_LIBRARY}")
|
||||
# FIXME: There should be a better way of handling this?
|
||||
# FIXME: How can we test to see if the lib dir isn't
|
||||
# FIXME: one of the default dirs?
|
||||
LINK_DIRECTORIES(${XERCESC_ROOT_DIR}/lib)
|
||||
ENDIF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
ENDIF (XERCESC_ROOT_DIR)
|
||||
|
||||
IF (XERCESC_FOUND)
|
||||
IF (NOT XERCESC_FIND_QUIETLY)
|
||||
MESSAGE (STATUS " found xerces-c: ${XERCESC_LIBRARY}")
|
||||
ENDIF (NOT XERCESC_FIND_QUIETLY)
|
||||
ELSE (XERCESC_FOUND)
|
||||
IF (XERCESC_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Xerces-C")
|
||||
ENDIF (XERCESC_FIND_REQUIRED)
|
||||
ENDIF (XERCESC_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XERCESC_INCLUDE_DIR
|
||||
XERCESC_LIBRARY
|
||||
)
|
||||
@@ -1,54 +0,0 @@
|
||||
# Locate Xsd from code synthesis include paths and binary
|
||||
# Xsd can be found at http://codesynthesis.com/products/xsd/
|
||||
# Written by Frederic Heem, frederic.heem _at_ telsey.it
|
||||
|
||||
# This module defines
|
||||
# XSD_INCLUDE_DIR, where to find elements.hxx, etc.
|
||||
# XSD_EXECUTABLE, where is the xsd compiler
|
||||
# XSD_FOUND, If false, don't try to use xsd
|
||||
|
||||
FIND_PATH( XSD_INCLUDE_DIR xsd/cxx/parser/elements.hxx
|
||||
"/opt/local/xsd-3.3.0-i686-macosx/libxsd"
|
||||
"C:/Programs/xsd-3.3.0/libxsd"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2/include"
|
||||
"C:/mingw/xsd-3.3.0-i686-windows/libxsd"
|
||||
$ENV{XSDDIR}/include
|
||||
$ENV{CODESYNTH}/include
|
||||
/usr/local/include /usr/include
|
||||
$ENV{XSDDIR}/libxsd
|
||||
)
|
||||
|
||||
IF( WIN32 )
|
||||
SET( XSDCXX_FILENAME1 xsd-cxx.exe )
|
||||
ELSE( )
|
||||
SET( XSDCXX_FILENAME1 xsdcxx )
|
||||
SET( XSDCXX_FILENAME2 xsd )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PROGRAM( XSDCXX_EXECUTABLE
|
||||
NAMES
|
||||
${XSDCXX_FILENAME1} ${XSDCXX_FILENAME2}
|
||||
PATHS
|
||||
"/opt/local/xsd-3.3.0-i686-macosx/bin"
|
||||
"C:/Programs/xsd-3.3.0/bin"
|
||||
"C:/mingw/xsd-3.3.0-i686-windows/bin"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2/bin"
|
||||
$ENV{XSDDIR}/bin
|
||||
/usr/local/bin
|
||||
/usr/bin
|
||||
$ENV{XSDDIR}/xsd
|
||||
)
|
||||
|
||||
MESSAGE(STATUS ${XSDCXX_EXECUTABLE})
|
||||
|
||||
# if the include and the program are found then we have it
|
||||
IF( XSD_INCLUDE_DIR )
|
||||
IF( XSDCXX_EXECUTABLE )
|
||||
SET( XSD_FOUND "YES" )
|
||||
ENDIF( XSDCXX_EXECUTABLE )
|
||||
ENDIF( XSD_INCLUDE_DIR )
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XSD_INCLUDE_DIR
|
||||
XSDCXX_EXECUTABLE
|
||||
)
|
||||
@@ -1,75 +0,0 @@
|
||||
macro(today RESULT)
|
||||
if(WIN32)
|
||||
execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "[^0-9]*([0-9]+)[^0-9]([0-9]+)[^0-9]([0-9]+).*" "\\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(WARNING "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(WARNING "time not implemented")
|
||||
set(${RESULT} 00:00:00)
|
||||
endif(WIN32)
|
||||
endmacro(now)
|
||||
|
||||
find_package(Git)
|
||||
|
||||
macro(git_id RESULT)
|
||||
set(${RESULT} 0)
|
||||
if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" "--git-dir=${PROJECT_SOURCE_DIR}/.git" "rev-parse" "--short=8" "HEAD" OUTPUT_VARIABLE proc_out ERROR_VARIABLE proc_err)
|
||||
if(proc_err)
|
||||
message(WARNING "Git failed with error: ${proc_err}")
|
||||
else()
|
||||
string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${proc_out})
|
||||
endif()
|
||||
elseif(NOT GIT_FOUND)
|
||||
message(WARNING "Git executable not found, revision number not available.")
|
||||
else()
|
||||
message(STATUS "Git repository not found, revision number not available.")
|
||||
endif()
|
||||
endmacro(git_id)
|
||||
|
||||
macro(use_cxx11)
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
|
||||
endif ()
|
||||
endmacro(use_cxx11)
|
||||
|
||||
macro(PrintTargetReport targetName)
|
||||
if(CMAKE_CXX_COMPILER MATCHES "/(clang-)?cl\\.exe$")
|
||||
set(cpp_version ${CMAKE_CXX_COMPILER_VERSION})
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE cpp_version)
|
||||
endif()
|
||||
if(cpp_version)
|
||||
string(STRIP "v${cpp_version}" cpp_version)
|
||||
else()
|
||||
set(cpp_version "WARNING: COMPILER NOT FOUND!")
|
||||
endif()
|
||||
message("TARGET ${targetName}: cpp compiler ${CMAKE_CXX_COMPILER} ${cpp_version}")
|
||||
|
||||
if(VERBOSE_CMAKELISTS)
|
||||
get_directory_property(DirOpts COMPILE_OPTIONS)
|
||||
get_directory_property(DirDefs COMPILE_DEFINITIONS)
|
||||
string(REPLACE ";" " " DirOpts "${DirOpts}")
|
||||
string(REPLACE ";" "; " DirDefs "${DirDefs}")
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
|
||||
message("\twith cpp flags: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type}} ${DirOpts}")
|
||||
message("\twith link flags: ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
message("\twith defs: ${DirDefs}")
|
||||
message("--------------")
|
||||
endif()
|
||||
endmacro(PrintTargetReport)
|
||||
@@ -1,484 +0,0 @@
|
||||
<h2>Version 2.2.1 / 2017-12-17</h2>
|
||||
|
||||
Please see <a href=http://www.open-tx.org/2017/12/16/opentx-2.2.1>this page</a> for details.
|
||||
|
||||
<h2>Version 2.2.0 / 2017-05-30</h2>
|
||||
|
||||
Major release! Please see <a href=http://www.open-tx.org/2017/05/30/opentx-2.2.0>this page</a> for details.
|
||||
|
||||
<h2>Version 2.1.9 / 2016-09-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>SD sync fixes (<a href=https://github.com/opentx/opentx/issues/3351>#3351</a>)</li>
|
||||
<li>Fixed: Telemetry mode "FrSky D (cable)" choice was missing for Taranis (<a href=https://github.com/opentx/opentx/issues/3372>#3372</a>)</li>
|
||||
<li>Show persistent option only for calculated sensors (<a href=https://github.com/opentx/opentx/issues/3454>#3454</a>)</li>
|
||||
<li>Fixed Flight mode clear command (<a href=https://github.com/opentx/opentx/issues/3214>#3214</a>)</li>
|
||||
<li>Fixed a problem with Rotary encoders linked to flight mode (could freeze Companion) (<a href=https://github.com/opentx/opentx/issues/3459>#3459</a>, <a href=https://github.com/opentx/opentx/issues/3470>#3470</a>)</li>
|
||||
<li>Telemetry simulator improvements: added fuel quantity sensor, increased RPM range (<a href=https://github.com/opentx/opentx/issues/3505>#3505</a>, <a href=https://github.com/opentx/opentx/issues/3506>#3506</a>)</li>
|
||||
<li>Implemented minimal support for the DYI Multimodule (<a href=https://github.com/opentx/opentx/issues/3526>#3526</a>)</li>
|
||||
<li>Fixed: GVar combo-box not being refreshed when GV check-box (re-)selected (<a href=https://github.com/opentx/opentx/issues/3518>#3518</a>)</li>
|
||||
<li>Fixed: Heli inversion not correctly shown/saved from Companion on Radios without virtual inputs (<a href=https://github.com/opentx/opentx/issues/3510>#3510</a>)</li>
|
||||
<li>Implemented print functions for the Heli setup screen (<a href=https://github.com/opentx/opentx/issues/3554>#3554</a>)</li>
|
||||
<li>Fixed: Flight modes linked trims display value (<a href=https://github.com/opentx/opentx/issues/3547>#3547</a>, <a href=https://github.com/opentx/opentx/issues/3568>#3568</a>)</li>
|
||||
<li>Fixed: New model global variables and rotary encoders initialisation (<a href=https://github.com/opentx/opentx/issues/3473>#3473</a>)</li>
|
||||
<li>Fixed: Prevent circular linked global variables and rotary encoders (<a href=https://github.com/opentx/opentx/issues/3472>#3472</a>)</li>
|
||||
<li>Fixed wrong log replay speed issue in Telemetry simulator (<a href=https://github.com/opentx/opentx/issues/3708>#3708</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.8 / 2016-04-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>Telemetry Simulator sensor instance number fixed (<a href=https://github.com/opentx/opentx/issues/3207>#3207</a>)</li>
|
||||
<li>Fixed: Throttle Source combo-box was populated multiple times (<a href=https://github.com/opentx/opentx/issues/3222>#3222</a>)</li>
|
||||
<li>RTC option tool-tip corrected (<a href=https://github.com/opentx/opentx/issues/3225>#3225</a>)</li>
|
||||
<li>Fixed: Companion was looking for custom scripts at the wrong place (<a href=https://github.com/opentx/opentx/issues/3237>#3237</a>)</li>
|
||||
<li>Offset displayed in inputs screen (<a href=https://github.com/opentx/opentx/issues/3248>#3248</a>)</li>
|
||||
<li>Import/export handling was broken for Average formula telemetry sensors (<a href=https://github.com/opentx/opentx/issues/3262>#3262</a>)</li>
|
||||
<li>Fixed: Hardware Setup control types and names were not stored in profile (<a href=https://github.com/opentx/opentx/issues/3260>#3260</a>)</li>
|
||||
<li>Fixed voice language list (<a href=https://github.com/opentx/opentx/issues/3338>#3338</a>)</li>
|
||||
<li>Fixed data overflow in Special Functions Override Channel (<a href=https://github.com/opentx/opentx/issues/3347>#3347</a>)</li>
|
||||
<li>Fixed: Sync dialog new line problem (only present for some UI languages) (<a href=https://github.com/opentx/opentx/issues/3350>#3350</a>)</li>
|
||||
<li>Removed a few legacy timer limitations, fix non-working limit (<a href=https://github.com/opentx/opentx/issues/3301>#3301</a>)</li>
|
||||
<li>Default AVR fuse settings changed to disable JTAG interface (<a href=https://github.com/opentx/opentx/issues/3379>#3379</a>)</li>
|
||||
<li>Channel range fix (Start, Channels) in Model Settings, Setup page, int/ext module settings</li>
|
||||
<li>Use friendly GVAR names in dialogs (if available) (<a href=https://github.com/opentx/opentx/issues/3353>#3353</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.7 / 2016-01-04</h2>
|
||||
|
||||
<ul>
|
||||
<li>Lua 'execute' failed in non-root directory (in Simulator) (<a href=https://github.com/opentx/opentx/issues/3024>#3024</a>)</li>
|
||||
<!-- this is disabled until the speed problem is fixed <li>Header line always visible in Outputs, Logical Switches and Special Functions (<a href=https://github.com/opentx/opentx/issues/2861>#2861</a>)</li> -->
|
||||
<li>LR12 changes: removed option for remote failsafe configuration, added in EU firmware variant</li>
|
||||
<li>Added Clear option to the flight mode context menu (right click on the Name label) (<a href=https://github.com/opentx/opentx/issues/3026>#3026</a>)</li>
|
||||
<li>New features for Telemetry Simulator: log replay, user friendly sensor values (<a href=https://github.com/opentx/opentx/issues/3124>#3124</a>)</li>
|
||||
<li>Added F7 key to reload LUA permanent scripts in radio simulator (<a href=https://github.com/opentx/opentx/issues/3141>#3141</a>)</li>
|
||||
<li>AR9X firmware flashing fall-back was wrong</li>
|
||||
<li>Command line options support added to standalone simulator (try "./simulator21 --help" on Linux and "simulator.exe /help" on Windows for usage) (<a href=https://github.com/opentx/opentx/issues/3160>#3160</a>)</li>
|
||||
<li>Various rounding problem fixed: Telemetry sensor Ratio parameter (<a href=https://github.com/opentx/opentx/issues/3117>#3117</a>),
|
||||
Outputs Sub-trim, Min and Max values (<a href=https://github.com/opentx/opentx/issues/3156>#3156</a>)</li>
|
||||
<li>Fixed: telemetry sensors Ratio and Offset value increment/decrement step (<a href=https://github.com/opentx/opentx/issues/3121>#3121</a>)</li>
|
||||
<li>Hardware/Calibration tab split int two tabs (<a href=https://github.com/opentx/opentx/issues/2974>#2974</a>)</li>
|
||||
<li>Fixed Fahrenheit temperature conversion error (if PREC was not 0) (<a href=https://github.com/opentx/opentx/issues/3146>#3146</a>)</li>
|
||||
<li>Application Setting 'Enable automatic backup before writing firmware' was not saved (<a href=https://github.com/opentx/opentx/issues/3040>#3040</a>)</li>
|
||||
<li>Fixed RPM package problem on Fedora (<a href=https://github.com/opentx/opentx/issues/3130>#3130</a>)</li>
|
||||
<li>Fixed conversion errors when loading 2.0.x EEPE (<a href=https://github.com/opentx/opentx/issues/3177>#3177</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.6 / 2015-11-11</h2>
|
||||
|
||||
<ul>
|
||||
<li>Telemetry custom screen changes didn't emit modified signal (<a href=https://github.com/opentx/opentx/issues/3029>#3029</a>)</li>
|
||||
<li>Hide D8/LR12 when eu firmware option is selected</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.5 / 2015-11-05</h2>
|
||||
|
||||
Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrSky's release of OpenTX 2.1.4
|
||||
|
||||
<ul>
|
||||
<li>Fixed: changing any setting on the telemetry panel does not set the file as being modified (<a href=https://github.com/opentx/opentx/issues/2875>#2875</a>)</li>
|
||||
<li>Print model fix for "Play value.... not on startup" (<a href=https://github.com/opentx/opentx/issues/2736>#2736</a>)</li>
|
||||
<li>Top LCD Timer could not be selected for X9E (<a href=https://github.com/opentx/opentx/issues/2850>#2850</a>)</li>
|
||||
<li>More informative error/info messages when openin eepe files (<a href=https://github.com/opentx/opentx/issues/2778>#2778</a>)</li>
|
||||
<li>Print model fix for curves (<a href=https://github.com/opentx/opentx/issues/2896>#2896</a>)</li>
|
||||
<li>Added missing special functions (bind, range check, set failsafe) (<a href=https://github.com/opentx/opentx/issues/2753>#2753</a>)</li>
|
||||
<li>Some defaults missing when changing telemetry formula, update propagation issues (<a href=https://github.com/opentx/opentx/issues/2928>#2928</a>)</li>
|
||||
<li>Fixed wrong import of Logical switches from OpenTX 2.0.x version (<a href=https://github.com/opentx/opentx/issues/2942>#2942</a>)</li>
|
||||
<li>Fixed a problem with updates path on Windows (<a href=https://github.com/opentx/opentx/issues/2876>#2876</a>)</li>
|
||||
<li>Edge representation unified (changed from "no release" to "instant") (<a href=https://github.com/opentx/opentx/issues/2837>#2837</a>)</li>
|
||||
<li>Added channel names on failsafe sliders (<a href=https://github.com/opentx/opentx/issues/3021>#3021</a>)</li>
|
||||
<li>Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
|
||||
Users with such setups are advised to re-check their failsafe settings (<a href=https://github.com/opentx/opentx/issues/2975>#2975</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Various small bug-fixes: <a href=https://github.com/opentx/opentx/issues/2994>#2994</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/3016>#3016</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/3012>#3012</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.3 / 2015-09-09</h2>
|
||||
|
||||
<ul>
|
||||
<li>Fix missing translations in inputs/mixes tabs, print and compare dialogs (<a href=https://github.com/opentx/opentx/issues/2847>#2847</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.2 / 2015-09-07</h2>
|
||||
|
||||
<ul>
|
||||
<li>Fixed: Lua model scripts outputs not working in a simulator (<a href=https://github.com/opentx/opentx/issues/2684>#2684</a>)</li>
|
||||
<li>Fixed a problem of Companion 2.1 trying to install into 2.0 path.
|
||||
The effect will only be visible for the users that did not install any of the previous 2.1.x versions.
|
||||
(<a href=https://github.com/opentx/opentx/issues/2645>#2645</a>)</li>
|
||||
<li>Added missing SDL libraries to MAC package (<a href=https://github.com/opentx/opentx/issues/2678>#2678</a>)</li>
|
||||
<li>Added used channels check/warning in Wizard (<a href=https://github.com/opentx/opentx/issues/2091>#2091</a>)</li>
|
||||
<li>Model Print and Model Compare improvements and fixes (<a href=https://github.com/opentx/opentx/issues/2734>#2734</a>, <a href=https://github.com/opentx/opentx/issues/2737>#2737</a>, <a href=https://github.com/opentx/opentx/issues/2576>#2576</a>)</li>
|
||||
<li>Negative telemetry offset value was reset when writing back to radio (<a href=https://github.com/opentx/opentx/issues/2738>#2738</a>)</li>
|
||||
<li>Telemetry sensor names were not displayed (<a href=https://github.com/opentx/opentx/issues/2807>#2807</a>)</li>
|
||||
<li>Mixes multiplex representation now the same as on the radio (<a href=https://github.com/opentx/opentx/issues/2808>#2808</a>)</li>
|
||||
<li>Fixed language-related startup crash on Mac (<a href=https://github.com/opentx/opentx/issues/2815>#2815</a>)</li>
|
||||
<li>Fixed issues with conversion from 2.0 (<a href=https://github.com/opentx/opentx/issues/2809>#2809</a>, <a href=https://github.com/opentx/opentx/issues/2800>#2800</a>)</li>
|
||||
<li>Fixed Throttle source export issue on X9E (<a href=https://github.com/opentx/opentx/issues/2844>#2844</a>)</li>
|
||||
<li>Added support for the AR9X replacement board (prototype) for the Turnigy 9X radio, info <a href=http://www.rcgroups.com/forums/showthread.php?t=2479552>here</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.1 / 2015-08-06</h2>
|
||||
<ul>
|
||||
<li>Vario source and center silent options were not saved(<a href=https://github.com/opentx/opentx/issues/2476>#2476</a>)</li>
|
||||
<li>DSM receiver numbers for external module were not converted from previous version EEPROM (<a href=https://github.com/opentx/opentx/issues/2474>#2474</a>)</li>
|
||||
<li>Precision incorrectly set for Calculated->Cells sensor (<a href=https://github.com/opentx/opentx/issues/2479>#2479</a>)</li>
|
||||
<li>Unit incorrectly set for Calculated->Cells sensor (<a href=https://github.com/opentx/opentx/issues/2485>#2485</a>)</li>
|
||||
<li>Fixed import/export of trim values (<a href=https://github.com/opentx/opentx/issues/2484>#2484</a>)</li>
|
||||
<li>Removed constant access to floppy disk (<a href=https://github.com/opentx/opentx/issues/2160>#2160</a>)</li>
|
||||
<li>Telemetry view script combo box list was empty (<a href=https://github.com/opentx/opentx/issues/2465>#2465</a>)</li>
|
||||
<li>Telemetry view bars ranges not transfered to radio (<a href=https://github.com/opentx/opentx/issues/2491>#2491</a>)</li>
|
||||
<li>Fixed Standalone simulator radio selection display problem (<a href=https://github.com/opentx/opentx/issues/2503>#2503</a>)</li>
|
||||
<li>Added missing simulation libraries and enabled side by side installation of Companion 2.0 and 2.1 on Linux (<a href=https://github.com/opentx/opentx/issues/2500>#2500</a>)</li>
|
||||
<li>Standalone simulator now remembers which radio was simulated in previous session (<a href=https://github.com/opentx/opentx/issues/2503>#2503</a>)</li>
|
||||
<li>Radio calibration value were not displayed (<a href=https://github.com/opentx/opentx/issues/2502>#2502</a>)</li>
|
||||
<li>Fixed Vario / Voltage / Current sources export problem</li>
|
||||
<li>Writing model settings to 9XR-PRO did not work (<a href=https://github.com/opentx/opentx/issues/2402>#2402</a>, <a href=https://github.com/opentx/opentx/issues/2517>#2517</a>)</li>
|
||||
<li>Model Print and Model Compare improvements</li>
|
||||
<li>Fixed Companion OSX version (<a href=https://github.com/opentx/opentx/issues/2549>#2549</a>)</li>
|
||||
<li>Firmware nightly builds are now downloadable from nightly builds of Companion (<a href=https://github.com/opentx/opentx/issues/2526>#2526</a>, <a href=https://github.com/opentx/opentx/issues/2634>#2634</a>)</li>
|
||||
<li>Fixed telemetry item lists (<a href=https://github.com/opentx/opentx/issues/2541>#2541</a>)</li>
|
||||
<li>Fixed missing pots P1..P3 for 9X (<a href=https://github.com/opentx/opentx/issues/2543>#2543</a>)</li>
|
||||
<li>Fixed "Invalid model and settings" error message when writing models and settings to the radio (<a href=https://github.com/opentx/opentx/issues/2544>#2544</a>)</li>
|
||||
<li>Global Functions fixes (<a href=https://github.com/opentx/opentx/issues/2558>#2558</a>)</li>
|
||||
<li>Export to Google Earth now working (only) with the new telemetry fields (GPS, GAlt and GSpd) (<a href=https://github.com/opentx/opentx/issues/2546>#2546</a>)</li>
|
||||
<li>Fixed unsuccessful writing of setting to the radio for 9XR PRO (<a href=https://github.com/opentx/opentx/issues/2605>#2605</a>)</li>
|
||||
<li>Fixed missing LUA script outputs in special function "Play Value" (<a href=https://github.com/opentx/opentx/issues/2649>#2649</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Various small bug-fixes</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.0 / 2015-07-16</h2>
|
||||
<ul>
|
||||
<li>SD card synchronizaton tool</li>
|
||||
<li>Added session duraton information in Log Viewer</li>
|
||||
<li>Enabled <i>Mixers monitor</i> in Taranis simulator</li>
|
||||
<li>Better support for multi-axes in Log Viewer (<a href=https://github.com/opentx/opentx/issues/2267>#2267</a>)</li>
|
||||
<li>File path issue in Taranis simulator function <i>findTrueFileName()</i> on Windows (<a href=https://github.com/opentx/opentx/issues/2301>#2301</a>)</li>
|
||||
<li>Added simulator volume gain setting (<a href=https://github.com/opentx/opentx/issues/2260>#2260</a>)</li>
|
||||
<li>Added GPS glitch filtering and Latitude/Longitude position synchronization to Google Earth export (<a href=https://github.com/opentx/opentx/issues/2326>#2326</a>)</li>
|
||||
<li>Fixed a rare program crash when editing Input for 9X radio (<a href=https://github.com/opentx/opentx/issues/2420>#2420</a>)</li>
|
||||
<li>Fixed missing RSSI audio warnings if simulator was started multiple times (<a href=https://github.com/opentx/opentx/issues/2446>#2446</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.17 / 2015-05-04</h2>
|
||||
<ul>
|
||||
<li>Simulator crash (<a href=https://github.com/opentx/opentx/issues/2253>#2253</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.16 / 2015-05-03</h2>
|
||||
<ul>
|
||||
<li><i>nooverridech</i> firmware option was not working</li>
|
||||
<li>Fixed setting Expo from gvars for 9XR-Pro (<a href=https://github.com/opentx/opentx/issues/2040>#2040</a>)</li>
|
||||
<li>Added Mixers Monitor screen option <i>mixersmon</i> (<a href=https://github.com/opentx/opentx/issues/1945>#1945</a>)</li>
|
||||
<li>Added audio playing in simulator (<a href=https://github.com/opentx/opentx/issues/457>#457</a>)</li>
|
||||
<li>Fixed sorting of audio tracks (<a href=https://github.com/opentx/opentx/issues/2002>#2002</a>)</li>
|
||||
<li>Model wizard fixes (<a href=https://github.com/opentx/opentx/issues/2091>#2091</a>)</li>
|
||||
<li>GVAR names removed for 9x, radio doesn't support them (<a href=https://github.com/opentx/opentx/issues/2150>#2150</a>)</li>
|
||||
<li>Some LS sources didn't follow the Imperial units setting (<a href=https://github.com/opentx/opentx/issues/2180>#2180</a>)</li>
|
||||
<li>Added more fields to the telemetry simulator (<a href=https://github.com/opentx/opentx/issues/2171>#2171</a>)</li>
|
||||
<li>Log viewer improvements and massive speed increase (<a href=https://github.com/opentx/opentx/issues/1863>#1863</a>, <a href=https://github.com/opentx/opentx/issues/2163>#2163</a>)</li>
|
||||
<li>Added Battery meter range setting (<a href=https://github.com/opentx/opentx/issues/2195>#2195</a>)</li>
|
||||
<li>Improvements in Print and Compare dialogs (<a href=https://github.com/opentx/opentx/issues/2219>#2219</a>)</li>
|
||||
<li>Reset pots to the middle by right double clicking them in Simulator (<a href=https://github.com/opentx/opentx/issues/1939>#1939</a>)</li>
|
||||
<li>Minor fixes: <a href=https://github.com/opentx/opentx/issues/2153>#2153</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2138>#2138</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2090>#2090</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2122>#2122</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.15 / 2015-01-13</h2>
|
||||
<ul>
|
||||
<li>Firmware was not written correctly on radio when compatibility warning check enabled</li>
|
||||
<li>Time format for Special Functions Set Timers</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.14 / 2015-01-12</h2>
|
||||
<ul>
|
||||
<li>OpenTX Companion and Companion9x can now be installed side by side on Linux</li>
|
||||
<li>Improved TAB order in dialogs</li>
|
||||
<li>Special Function <i>Start Logs</i> renamed to more appropriate <i>SD Logs</i></li>
|
||||
<li>Improvements for MAC build</li>
|
||||
<li>Fixes to Google Earth logs export</li>
|
||||
<li>Firmware compatibility warning check added when flashing new firmware to radio</li>
|
||||
<li>Fixed issue with Telemetry Type setting on 9XR-PRO</li>
|
||||
<li>Added Telemetry simulator</li>
|
||||
<li>Added Trainer simulator</li>
|
||||
<li>Added Debug Output window</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Various small bug-fixes</li>
|
||||
<li>More reliable method of writing EEPROM.BIN and FIRMWARE.BIN to radio</li>
|
||||
<li>Fixed issue with Edge function INSTANT for V1>2s</li>
|
||||
<li>Fixed buffer overflow in Joystick code</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.13 / 2014-11-20</h2>
|
||||
<ul>
|
||||
<li>Too many curves shown on non ARM boards</li>
|
||||
<li>Fixed vario limits</li>
|
||||
<li>Fixes in compare dialog</li>
|
||||
<li>Fixed receiver number range</li>
|
||||
<li>Virtual inputs not selectable in SF Volume and heli Collective Source</li>
|
||||
<li>Joystick calibration crash after channel assignment</li>
|
||||
<li>Gvar import error for limits</li>
|
||||
<li>Companion shows too many curve types in input/mixer for 9x</li>
|
||||
<li>NOT curves removed from inputs (for non ARM platforms)</li>
|
||||
<li>Companion again builds on OS X (Mac)</li>
|
||||
<li>Companion simulator Lua crash on OS X 64bit (Mac)</li>
|
||||
<li>Companion didn't take care of PlayScript functions</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.12 / 2014-09-15</h2>
|
||||
<ul>
|
||||
<li>Typos & Translations updated</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.11 / 2014-09-10</h2>
|
||||
<ul>
|
||||
<li>Limits EEPROM export was broken (all boards except Taranis)</li>
|
||||
<li>Fix issue when a GVAR was used as Offset</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.10 / 2014-09-08</h2>
|
||||
<ul>
|
||||
<li>Taranis is now the default board in General Settings</li>
|
||||
<li>GVARS allowed in Limits min/max/offset</li>
|
||||
<li>Limits displayed in us when ppmus option selected
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.8 / 2014-07-23</h2>
|
||||
<ul>
|
||||
<li>Compare dialog bugfixes</li>
|
||||
<li>Curve index correctly resetted when type changed</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.7</h2>
|
||||
<ul>
|
||||
<li>SafetyCH function was missing in simulator</li>
|
||||
<li>EEPROM export warning when exporting logical switches > L12 on 9X128</li>
|
||||
<li>FAS offset was not exported on 9X/9XR boards</li>
|
||||
<li>Trims modes bugfix on non Taranis boards</li>
|
||||
<li>It was impossible to open a backuped model from the Tx</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.6</h2>
|
||||
<ul>
|
||||
<li>Fix Mix curves bug on Sky9x boards</li>
|
||||
<li>Channels 17-32 are displayed in the simulator</li>
|
||||
<li>Backlight simulation bugfix</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.5</h2>
|
||||
<ul>
|
||||
<li>Fix crash on startup</li>
|
||||
<li>Fix version number in simu</li>
|
||||
<li>9XR-Pro now supported on Mac</li>
|
||||
<li>Fix loss of settings in telemetry custom screens</li>
|
||||
<li>Fix 10000% bug when using GVs in mixer weithg or offset</li>
|
||||
<li>Fix Cnsp range in logical switches (up to 30000mAh)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.4</h2>
|
||||
<ul>
|
||||
<li>Sound should be ok on all platforms</li>
|
||||
<li>Min/Max reviewed in Logical switches (for the whole telemetry)</li>
|
||||
<li>Various bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.3</h2>
|
||||
<ul>
|
||||
<li>EEPROM import bug on AdjustGVAR function</li>
|
||||
<li>Timers correctly displayed in logical switches tab</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.2</h2>
|
||||
<ul>
|
||||
<li>Mouse scroll wheel behaves differently</li>
|
||||
<li>Play Sounds should now work on all platforms</li>
|
||||
<li>A lot of small bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.1</h2>
|
||||
<ul>
|
||||
<li>Fix on recursive GVars</li>
|
||||
<li>Sky9x EEPROM read/write fix</li>
|
||||
<li>Translations updated
|
||||
<li>Wizard fixes
|
||||
<li>Fix on invalid splashes bitmaps
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.0</h2>
|
||||
<ul>
|
||||
<li>Companion now merged into OpenTX</li>
|
||||
<li>Too many changes to list them all!</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.52</h2>
|
||||
<ul>
|
||||
<li>Fix crash when writing certain EEPROMS</li>
|
||||
<li>Google Earth export of logs containing GPS positions</li>
|
||||
<li>DSM2 added for Taranis</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.51</h2>
|
||||
<ul>
|
||||
<li>Wrong DFU-Util default path (MAC)</li>
|
||||
<li>new voices download server (ip address changed to new fiber connection)</li>
|
||||
<li>Fixed contributor list</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.50</h2>
|
||||
<ul>
|
||||
<li>solved issue with taranis radio with some linux distributions</li>
|
||||
<li>blank eeprom created using a radio profile that holds calibration data, will contain calibration data from the profile</li>
|
||||
<li>new opentx compilation server (ip address changed to new fiber connection)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.49</h2>
|
||||
<ul>
|
||||
<li>Stack usage optimizations</li>
|
||||
<li>Playsound order is misaligned between companion9x and the TX</li>
|
||||
<li>Model image could not be reset.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.48</h2>
|
||||
<ul>
|
||||
<li>Interface fixes</li>
|
||||
<li>Hide include dr/expo when not applicable</li>
|
||||
<li>Fix extraction of grayscale images from taranis firmwares</li>
|
||||
<li>No TX and RX in Taranis telemetry fields</li>
|
||||
<li>Issue 255 fixed - "No GVAR selection possible for PLAY VALUE"</li>
|
||||
<li>Issue 254 fixed - "SE Language for building opentx"</li>
|
||||
<li>Issue 253 fixed - "OpenTX doesn't accept this protocol (DSM2 on Sky9x)"</li>
|
||||
<li>Prevent segfault while parsing wrong log files or files with broken lines</li>
|
||||
<li>Small bug in model printout</li>
|
||||
<li>Fixed wrong display of values in custom functions</li>
|
||||
<li>Image in preferences was saved only black & white</li>
|
||||
<li>Issue 247 fixed - "Labelled items on radio should not be translated."</li>
|
||||
<li>Added support of tstick (taranis like stick) compile option for sky9x opentx firmware</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.47</h2>
|
||||
<ul>
|
||||
<li>Interface fixes (issues 232,233,238,241)</li>
|
||||
<li>Fix for print/compare models</li>
|
||||
<li>Function switch parameter on screen different than printout.</li>
|
||||
<li>Translations fixes</li>
|
||||
<li>Command line print mode</li>
|
||||
<li>Better mavlink support</li>
|
||||
<li>SE tts language added for taranis</li>
|
||||
<li>Alternate font option for opentx added</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.46</h2>
|
||||
<ul>
|
||||
<li>Interface fixes (issues 224,225)</li>
|
||||
<li>Show persistent timers value in modeledit</li>
|
||||
<li>Consistent naming of Custom Switches in c9x</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.45</h2>
|
||||
<ul>
|
||||
<li>Various fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.44</h2>
|
||||
<ul>
|
||||
<li>Fix regression on AND parameter in custom functions</li>
|
||||
<li>Add mavlink support for stock and m128 boards</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.43</h2>
|
||||
<ul>
|
||||
<li>Copy Malfunctions in Custom Functions (Issue 205)</li>
|
||||
<li>Enable repeat parameter in functions for all boards</li>
|
||||
<li>Remove sink tones from vario for stock/m128 board</li>
|
||||
<li>Fix for wrongly named channels in mixerlist (Issue 210)</li>
|
||||
<li>Fix badly exported gvars in mixers</li>
|
||||
<li>Fix while editing custom switches</li>
|
||||
<li>Add access to the release notes of currently selected firmware</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.42</h2>
|
||||
<ul>
|
||||
<li>Add Companion9X changelog</li>
|
||||
<li>Add Fw release notes browser</li>
|
||||
<li>Simplify burn menu for sky9x and Taranis.</li>
|
||||
<li>Fix in telemetry conversion (rssi alarm) for stock board</li>
|
||||
<li>Drop support of sky9x boards on MacOS due to missing SAM-BA tool.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.41</h2>
|
||||
<ul>
|
||||
<li>Fix unneeded rescaling of splash images</li>
|
||||
<li>Fix for telemetry screens for Taranis</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.40</h2>
|
||||
<ul>
|
||||
<li>Log dialog - Split of logging sessions.</li>
|
||||
<li>Telemetry screen 1 as default (issue 206)</li>
|
||||
<li>Rename all channels in mixer tab accordingly to limits names</li>
|
||||
<li>Fix a segfault in phases tabs (Issue 203 regression introduced in release 2140)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.39</h2>
|
||||
<ul>
|
||||
<li>Custom functions cut&paste </li>
|
||||
<li>Custom switches cut&paste </li>
|
||||
<li>Color button text in curve editor for MACOSX</li>
|
||||
<li>Adjust name lengths for Taranis</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.38</h2>
|
||||
<ul>
|
||||
<li>Core when model names were > 10 chars</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.37</h2>
|
||||
<ul>
|
||||
<li>Fix OpenTX segfault in Taranis simulator</li>
|
||||
<li>Implement brightness control for Taranis</li>
|
||||
<li>Reduce modeledit windows size</li>
|
||||
<li>Taranis splash screen in grayscale</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.36</h2>
|
||||
<ul>
|
||||
<li>Burning windows (with progress bar) now in foreground (Issue 197)</li>
|
||||
<li>Allow a selection of tracks for Background Music (Issue 199)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 1.35</h2>
|
||||
<ul>
|
||||
<li>Country names mismatch between Taranis and Companion 9X (Issue 198)</li>
|
||||
<li>TIM function in custom switches</li>
|
||||
<li>Fix timer switches.</li>
|
||||
<li>Taranis LCD adjustment in general settings.</li>
|
||||
<li>New tool in curve editor</li>
|
||||
<li>Minor fixes</li>
|
||||
<li>Expo move bug + invalid chars in channels, expo and mixer names</li>
|
||||
<li>Try to reduce modeledit window form MAC</li>
|
||||
<li>Wrong init of RF-Module data</li>
|
||||
<li>Read flash from TX didn't worked for Taranis</li>
|
||||
</ul>
|
||||
@@ -1,586 +0,0 @@
|
||||
set(SIMULATOR_INSTALL_PREFIX "" CACHE STRING "Alternative simulator library search path")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(Linux|FreeBSD)")
|
||||
set(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR})
|
||||
set(COMPANION_NAME "companion${C9X_NAME_SUFFIX}")
|
||||
set(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}")
|
||||
if (NOT ${SIMULATOR_INSTALL_PREFIX} STREQUAL "")
|
||||
set(SIMULATOR_LIB_PATH ${SIMULATOR_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
else()
|
||||
set(SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
endif()
|
||||
message(STATUS "Simulators library search path: " ${SIMULATOR_LIB_PATH})
|
||||
set(SIMULATOR_LIB_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
else()
|
||||
set(COMPANION_NAME "companion")
|
||||
set(SIMULATOR_NAME "simulator")
|
||||
endif()
|
||||
|
||||
# This the name that the user will see in the generated DMG and what the application
|
||||
# will be called under /Applications. We include the version string to make installing
|
||||
# different versions for different eeproms easier, i.e. without manually renaming
|
||||
set(COMPANION_OSX_APP_BUNDLE_NAME "OpenTX Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
|
||||
# On OS X we copy dfu-util to the application bundle. This the path from which we copy
|
||||
# the binary (default homebrew path)
|
||||
set(DFU_UTIL_PATH "/usr/local/bin/dfu-util")
|
||||
set(AVRDUDE_PATH "/usr/local/bin/avrdude")
|
||||
set(AVRDUDE_CONF "/usr/local/etc/avrdude.conf")
|
||||
|
||||
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_STORAGE_IMPORT "Turn on debug output for storage import") # Disabled by default
|
||||
if(DEBUG_STORAGE_IMPORT)
|
||||
add_definitions(-DDEBUG_STORAGE_IMPORT)
|
||||
message(STATUS "Storage import debugging enabled")
|
||||
endif()
|
||||
if(DEBUG)
|
||||
add_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
option(TABLE_LAYOUT "Use QTableWidget for grid layouts") # Disabled by default
|
||||
if(TABLE_LAYOUT)
|
||||
add_definitions(-DTABLE_LAYOUT)
|
||||
message(STATUS "Using QTableWidget")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(WIN_DO_FULL_INSTALL "'install' target will perform a full installation into CMAKE_INSTALL_PREFIX path, otherwise only supporting DLLs are copied to binaries folder (default)" OFF)
|
||||
option(WIN_USE_CONSOLE "Open a Windows command console for Simulator debug output." OFF)
|
||||
if(WIN_USE_CONSOLE)
|
||||
add_definitions(-DWIN_USE_CONSOLE_STDIO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL_FOUND)
|
||||
include_directories(${SDL_INCLUDE_DIR})
|
||||
add_definitions(-DJOYSTICKS)
|
||||
endif()
|
||||
|
||||
add_definitions(${APP_COMMON_DEFINES}) # set in top-level CMakeLists
|
||||
|
||||
if(NOT MSVC)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Wall")
|
||||
if(WARNINGS_AS_ERRORS)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
|
||||
endif()
|
||||
else()
|
||||
# silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
|
||||
if(WARNINGS_AS_ERRORS)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} /WX")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
include_directories(SYSTEM ${WIN_INCLUDE_DIRS})
|
||||
if(NOT WIN_USE_CONSOLE)
|
||||
set(WIN_EXECUTABLE_TYPE WIN32) # GUI (WinMain) app
|
||||
endif()
|
||||
if(MSVC)
|
||||
if(NOT CLANG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /LD /MP")
|
||||
endif()
|
||||
if(NOT WIN_USE_CONSOLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,5.01") # is this even needed?
|
||||
endif()
|
||||
elseif(MINGW)
|
||||
get_filename_component(MINGW_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
|
||||
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields")
|
||||
endif()
|
||||
else()
|
||||
set(PTHREAD_LIBRARY pthread)
|
||||
link_directories(/usr/local/lib)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
|
||||
use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${COMPANION_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/shared
|
||||
${SIMU_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/qcustomplot
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/miniz
|
||||
${COMPANION_SRC_DIRECTORY}/storage
|
||||
)
|
||||
|
||||
############# Do macro replacements on input files #############
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @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)
|
||||
|
||||
############# Translations ###############
|
||||
|
||||
### Generate .qm files and assemble resource (qrc) file.
|
||||
|
||||
# available Companion translations (src/translations/*.ts)
|
||||
set(LANGUAGES cs de en es fi fr it pl sv zh_CN)
|
||||
foreach(language ${LANGUAGES})
|
||||
list(APPEND companion_TS translations/companion_${language}.ts)
|
||||
endforeach(language)
|
||||
# .ts -> .qm
|
||||
qt5_add_translation(companion_QM ${companion_TS})
|
||||
|
||||
# add Qt translations if found
|
||||
if(QT_TRANSLATIONS_DIR)
|
||||
# Some languages have all translations in one qt_*.qm file and others break them up into modules, in which case we need qt_base_*.qm
|
||||
file(GLOB qtbase_QM "${QT_TRANSLATIONS_DIR}/qtbase_*.qm")
|
||||
file(GLOB qt_QM "${QT_TRANSLATIONS_DIR}/qt_??.qm") # don't want to match "qt_help_*.qm"
|
||||
list(APPEND qt_QM "${QT_TRANSLATIONS_DIR}/qt_zh_CN.qm" "${QT_TRANSLATIONS_DIR}/qt_zh_TW.qm") # exceptions not matched by the GLOB
|
||||
else()
|
||||
message(STATUS "QT_TRANSLATIONS_DIR not found, unable to package pre-built Qt translations with application.")
|
||||
endif()
|
||||
|
||||
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc")
|
||||
|
||||
# Dynamically create translations.qrc file (XML) from all collected translation files.
|
||||
foreach(qm_file ${companion_QM} ${qt_QM} ${qtbase_QM})
|
||||
get_filename_component(qm_file_name ${qm_file} NAME)
|
||||
# Add file with full path and file name (w/out path) as alias to be used in actual code
|
||||
set(TRANSLATION_FILES_LIST "${TRANSLATION_FILES_LIST} <file alias=\"${qm_file_name}\">${qm_file}</file>\n")
|
||||
endforeach()
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${TRANSLATIONS_QRC} @ONLY)
|
||||
|
||||
### Add optional "translations" target for updating .ts files
|
||||
if(QT_LUPDATE_EXECUTABLE)
|
||||
add_custom_target(translations
|
||||
WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY}
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS}
|
||||
)
|
||||
else()
|
||||
message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.")
|
||||
endif()
|
||||
|
||||
############# Common lib ###############
|
||||
|
||||
set(common_SRCS
|
||||
appdebugmessagehandler.cpp
|
||||
customdebug.cpp
|
||||
helpers.cpp
|
||||
translations.cpp
|
||||
modeledit/node.cpp # used in simulator
|
||||
modeledit/edge.cpp # used by node
|
||||
)
|
||||
|
||||
set(common_MOC_HDRS
|
||||
appdebugmessagehandler.h
|
||||
helpers.h
|
||||
modeledit/node.h
|
||||
)
|
||||
|
||||
set(common_RESOURCES
|
||||
companion.qrc
|
||||
${TRANSLATIONS_QRC}
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
|
||||
qt5_add_resources(common_RCC ${common_RESOURCES})
|
||||
|
||||
add_library(common ${common_SRCS} ${common_RCC})
|
||||
|
||||
target_link_libraries(common
|
||||
firmwares
|
||||
storage
|
||||
simulation
|
||||
maxLibQtWidgets
|
||||
Qt5::Core
|
||||
Qt5::Xml
|
||||
Qt5::Widgets
|
||||
${PTHREAD_LIBRARY}
|
||||
${SDL_LIBRARY}
|
||||
${WIN_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
set(CPN_COMMON_LIB common)
|
||||
|
||||
############# Supporting libraries ###############
|
||||
|
||||
add_subdirectory(datamodels)
|
||||
add_subdirectory(firmwares)
|
||||
add_subdirectory(shared)
|
||||
add_subdirectory(modeledit)
|
||||
add_subdirectory(generaledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(thirdparty/qcustomplot)
|
||||
add_subdirectory(thirdparty/maxlibqt/src/widgets)
|
||||
|
||||
############# Companion ###############
|
||||
|
||||
set(companion_SRCS
|
||||
helpers_html.cpp
|
||||
mdichild.cpp
|
||||
modelslist.cpp
|
||||
apppreferencesdialog.cpp
|
||||
fwpreferencesdialog.cpp
|
||||
burnconfigdialog.cpp
|
||||
multimodelprinter.cpp
|
||||
comparedialog.cpp
|
||||
creditsdialog.cpp
|
||||
releasenotesdialog.cpp
|
||||
releasenotesfirmwaredialog.cpp
|
||||
customizesplashdialog.cpp
|
||||
radiointerface.cpp
|
||||
progresswidget.cpp
|
||||
progressdialog.cpp
|
||||
process_copy.cpp
|
||||
process_flash.cpp
|
||||
process_sync.cpp
|
||||
flashfirmwaredialog.cpp
|
||||
flasheepromdialog.cpp
|
||||
printdialog.cpp
|
||||
modelprinter.cpp
|
||||
fusesdialog.cpp
|
||||
logsdialog.cpp
|
||||
downloaddialog.cpp
|
||||
splashlibrarydialog.cpp
|
||||
mainwindow.cpp
|
||||
companion.cpp
|
||||
radionotfound.cpp
|
||||
wizarddata.cpp
|
||||
wizarddialog.cpp
|
||||
styleeditdialog.cpp
|
||||
dialogs/filesyncdialog.cpp # TODO move to own lib with other dialogs
|
||||
)
|
||||
|
||||
set(companion_MOC_HDRS
|
||||
apppreferencesdialog.h
|
||||
fwpreferencesdialog.h
|
||||
burnconfigdialog.h
|
||||
comparedialog.h
|
||||
printdialog.h
|
||||
fusesdialog.h
|
||||
logsdialog.h
|
||||
creditsdialog.h
|
||||
releasenotesdialog.h
|
||||
releasenotesfirmwaredialog.h
|
||||
customizesplashdialog.h
|
||||
splashlibrarydialog.h
|
||||
splashlabel.h
|
||||
progresswidget.h
|
||||
progressdialog.h
|
||||
process_copy.h
|
||||
process_flash.h
|
||||
process_sync.h
|
||||
flashfirmwaredialog.h
|
||||
flasheepromdialog.h
|
||||
downloaddialog.h
|
||||
mdichild.h
|
||||
mainwindow.h
|
||||
radionotfound.h
|
||||
wizarddialog.h
|
||||
modelprinter.h
|
||||
multimodelprinter.h
|
||||
modelslist.h
|
||||
styleeditdialog.h
|
||||
helpers_html.h
|
||||
dialogs/filesyncdialog.h
|
||||
)
|
||||
|
||||
set(companion_UIS
|
||||
mdichild.ui
|
||||
comparedialog.ui
|
||||
fusesdialog.ui
|
||||
logsdialog.ui
|
||||
apppreferencesdialog.ui
|
||||
fwpreferencesdialog.ui
|
||||
burnconfigdialog.ui
|
||||
downloaddialog.ui
|
||||
printdialog.ui
|
||||
htmldialog.ui
|
||||
customizesplashdialog.ui
|
||||
splashlibrarydialog.ui
|
||||
progresswidget.ui
|
||||
progressdialog.ui
|
||||
flashfirmwaredialog.ui
|
||||
flasheepromdialog.ui
|
||||
radionotfound.ui
|
||||
styleeditdialog.ui
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(icon_RC images/winicons/icon.rc)
|
||||
endif()
|
||||
|
||||
qt5_wrap_ui(companion_SRCS ${companion_UIS})
|
||||
qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})
|
||||
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${icon_RC})
|
||||
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit qcustomplot shared ${CPN_COMMON_LIB})
|
||||
|
||||
PrintTargetReport("${COMPANION_NAME}")
|
||||
|
||||
############# Standalone simulator ###############
|
||||
|
||||
set(simu_SRCS simulator.cpp )
|
||||
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB})
|
||||
|
||||
############# Install ####################
|
||||
|
||||
# Generate list of simulator plugins, used by all platforms
|
||||
file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/*opentx-*simulator${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
# the current flavour is not automatically added if build in the current cmake iteration, so always
|
||||
# add its library name to be sure
|
||||
string(TOLOWER ${PCB} FLAVOUR)
|
||||
if(POLICY CMP0026)
|
||||
cmake_policy(SET CMP0026 OLD) # https://cmake.org/cmake/help/v3.0/policy/CMP0026.html
|
||||
endif()
|
||||
if(SIMU_TARGET)
|
||||
get_property(current_plugin TARGET opentx-${FLAVOUR}-simulator PROPERTY LOCATION)
|
||||
list(APPEND simulator_plugins "${current_plugin}")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
message(STATUS "install " ${CMAKE_BINARY_DIR} " to " ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(FILES ${simulator_plugins} DESTINATION "${SIMULATOR_LIB_INSTALL_PATH}")
|
||||
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)
|
||||
if(${CMAKE_INSTALL_PREFIX} MATCHES "/usr/local")
|
||||
set(INSTALL_TEMP_SHR_PFX "/usr/")
|
||||
set(INSTALL_TEMP_LIB_PFX "/")
|
||||
endif()
|
||||
install(FILES images/linuxicons/16x16/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/22x22/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/24x24/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/32x32/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/48x48/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/128x128/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/256x256/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/512x512/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/scalable/companion.svg DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg)
|
||||
install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules)
|
||||
install(FILES ../targets/linux/45-usbasp.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-usbasp.rules)
|
||||
# Linux specific code
|
||||
set(OperatingSystem "Linux")
|
||||
|
||||
elseif(WIN32)
|
||||
|
||||
if(NOT WIN_DO_FULL_INSTALL)
|
||||
# Just copy supporting DLLs to build folder
|
||||
set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
message(STATUS "Partial install to " ${INSTALL_DESTINATION})
|
||||
else()
|
||||
# Full Windows installation with all supporting files
|
||||
set(INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
message(STATUS "Full install to " ${INSTALL_DESTINATION})
|
||||
# companion & simulator binaries
|
||||
install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION})
|
||||
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION})
|
||||
install(FILES ${simulator_plugins} DESTINATION "${INSTALL_DESTINATION}")
|
||||
# supporting utilities
|
||||
set(INSTALL_TEMP_FILES avrdude.exe avrdude.conf dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
|
||||
foreach(tmpfile ${INSTALL_TEMP_FILES})
|
||||
install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/${tmpfile}" DESTINATION ${INSTALL_DESTINATION})
|
||||
endforeach()
|
||||
endif() # WIN_DO_FULL_INSTALL
|
||||
|
||||
# Qt dlls (using windeployqt)
|
||||
## Qt translations are already packaged into our custom qrc. Also don't need software rendering engines.
|
||||
set(wdqtopts --no-translations --no-opengl-sw --no-system-d3d-compiler --no-angle)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(wdqtopts ${wdqtopts} --release) # release builds aren't always properly detected with mingw
|
||||
endif()
|
||||
if(MSVC)
|
||||
set(wdqtopts ${wdqtopts} --no-compiler-runtime) # --compiler-runtime includes vcredist_x86, but we just copy the required DLLs manually
|
||||
endif()
|
||||
set(wdqtopts ${wdqtopts} -dir "${INSTALL_DESTINATION}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${COMPANION_NAME}.exe" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${SIMULATOR_NAME}.exe")
|
||||
# Add installer command to execute windeployqt
|
||||
install(CODE "execute_process(COMMAND \"${QT_BIN_DIR}/windeployqt.exe\" ${wdqtopts})")
|
||||
|
||||
# SDL dll
|
||||
if(SDL_FOUND AND EXISTS "${SDL_LIBRARY_PATH}/SDL.dll")
|
||||
set(SDL_DIR ${SDL_LIBRARY_PATH}) # this is also used by NSIS installer script
|
||||
install(FILES ${SDL_DIR}/SDL.dll DESTINATION ${INSTALL_DESTINATION})
|
||||
elseif(SDL_FOUND)
|
||||
message(WARNING "Installer: SDL.dll not found, set SDL_LIBRARY_PATH manually.")
|
||||
endif()
|
||||
|
||||
# libeay (SSL) dlls (used by QtNetwork) -- not strictly required but avoids possible issues with downloads and Qt warnings.
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" WIN_PROGRAM_FILES)
|
||||
find_path(EAY_LIB_DIR libeay32.dll HINTS
|
||||
"${WIN_PROGRAM_FILES}/OpenSSL" "${WIN_PROGRAM_FILES}/OpenSSL-Win32"
|
||||
"C:/OpenSSL/" "C:/OpenSSL-Win32/"
|
||||
"${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/OpenSSL" "${WIN_EXTRA_LIBS_PATH}/OpenSSL-Win32"
|
||||
"${MINGW_DIR}/../opt/bin"
|
||||
"${PYTHON_DIRECTORY}/lib/site-packages/PyQt4"
|
||||
PATH_SUFFIXES bin
|
||||
DOC "Path to libeay32.dll and ssleay32.dll (OpenSSL)"
|
||||
)
|
||||
if (EAY_LIB_DIR)
|
||||
install(FILES "${EAY_LIB_DIR}/libeay32.dll" "${EAY_LIB_DIR}/ssleay32.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
|
||||
else()
|
||||
message(WARNING "Installer: SSL libs not found, set EAY_LIB_DIR manually.")
|
||||
endif()
|
||||
|
||||
# C++/system dlls, depends on compiler
|
||||
if(MSVC)
|
||||
file(TO_CMAKE_PATH "$ENV{windir}/SysWOW64" WIN_SYSDIR) # This would be "system32" for a 64-bit build or on x86... but how to tell?
|
||||
if (NOT EXISTS "${WIN_SYSDIR}")
|
||||
file(TO_CMAKE_PATH "$ENV{windir}/system32" WIN_SYSDIR) # Must be 32-bit Windows.
|
||||
endif()
|
||||
install(FILES "${WIN_SYSDIR}/msvcp140.dll" "${WIN_SYSDIR}/vcruntime140.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
|
||||
if(WIN_PTHREAD_DLL)
|
||||
install(FILES "${WIN_PTHREAD_DLL}" DESTINATION ${INSTALL_DESTINATION})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif() # WIN32 install
|
||||
|
||||
############# Packaging ####################
|
||||
|
||||
# Create Windows installer with NSIS
|
||||
if(WIN32)
|
||||
|
||||
find_program(NSIS_EXE makensis.exe PATHS
|
||||
"C:/Program Files/NSIS"
|
||||
"C:/Program Files (x86)/NSIS"
|
||||
"C:/Programs/NSIS"
|
||||
"${WIN_EXTRA_LIBS_PATH}/NSIS"
|
||||
)
|
||||
|
||||
if (NSIS_EXE)
|
||||
file(TO_NATIVE_PATH "${INSTALL_DESTINATION}" NSIS_DISTRO) # all files in here will be included in installer
|
||||
set(NSI_FILE "${PROJECT_BINARY_DIR}/companion/companion.nsi")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/companion.nsi.in" "${NSI_FILE}" @ONLY)
|
||||
|
||||
add_custom_target(installer
|
||||
# The 'install' target prepares all the distro files, make sure it has been executed first.
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install
|
||||
COMMAND "${NSIS_EXE}" "${NSI_FILE}"
|
||||
DEPENDS "${NSI_FILE}"
|
||||
COMMENT "Building Windows NSIS installer..."
|
||||
)
|
||||
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")
|
||||
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)
|
||||
|
||||
# Qt5 + Cmake + Mac is poorly documented. A lot of this is guesswork
|
||||
# and trial and error. Do not hesitate to fix it for the better
|
||||
IF(APPLE)
|
||||
set(plugin_dest_dir ${COMPANION_NAME}.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir ${COMPANION_NAME}.app/Contents/Resources)
|
||||
set(APPS "\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app")
|
||||
set(companion_res_dir ${COMPANION_NAME}.app/Contents/Resources)
|
||||
|
||||
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simulator ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
|
||||
# Use a non standard Info.plist that adds Retina support flags
|
||||
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
|
||||
INSTALL(TARGETS ${COMPANION_NAME}
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
RUNTIME DESTINATION bin COMPONENT Runtime
|
||||
)
|
||||
|
||||
install(FILES ${simulator_plugins} DESTINATION "${companion_res_dir}" COMPONENT Runtime)
|
||||
|
||||
# Write qt.conf to tell qt where to find it plugins
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||
"[Paths]\nPlugins = Plugins\n")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||
DESTINATION "${companion_res_dir}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
# menu file
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/companion/targets/mac/qt_menu.nib DESTINATION "${companion_res_dir}" COMPONENT Runtime)
|
||||
|
||||
# manually add the required plugins
|
||||
foreach (plugin ${Qt5Multimedia_PLUGINS} ${Qt5PrintSupport_PLUGINS} ${Qt5Gui_PLUGINS} ${Qt5Svg_PLUGINS})
|
||||
get_target_property(QPA_PLUGIN ${plugin} LOCATION)
|
||||
get_filename_component(QPA_PLUGIN_FILENAME ${QPA_PLUGIN} NAME)
|
||||
# Todo is there a nicer way to get the QT Plugin directory name?!
|
||||
get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN} DIRECTORY)
|
||||
get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN_DIRECTORY} NAME)
|
||||
|
||||
install(FILES ${QPA_PLUGIN} DESTINATION "${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/" COMPONENT Runtime)
|
||||
|
||||
list(APPEND bundle_qt_libs "\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/${QPA_PLUGIN_FILENAME}")
|
||||
endforeach()
|
||||
|
||||
# Add icon
|
||||
set(MACOSX_BUNDLE_ICON_FILE iconmac.icns)
|
||||
set(MAC_ICON_FILE ${COMPANION_SRC_DIRECTORY}/images/${MACOSX_BUNDLE_ICON_FILE})
|
||||
SET_SOURCE_FILES_PROPERTIES(${MAC_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
|
||||
install(FILES ${MAC_ICON_FILE} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
|
||||
# Copy dfu-util and avrdude, resolve symlink first
|
||||
get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDE_ABSOLUTE_PATH ${AVRDUDE_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDECONF_ABSOLUTE_PATH ${AVRDUDE_CONF} REALPATH)
|
||||
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
install(FILES ${AVRDUDECONF_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
|
||||
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")
|
||||
|
||||
|
||||
# Include depencies (adding frameworks, fixing the embbeded libraries)
|
||||
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
|
||||
# technically a hack (that is already is in the Bundle library ...)
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
file(GLOB bundle_simulator_libs \"\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS on)
|
||||
fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_tools_path}\" \"${QT_LIB_DIR}\")
|
||||
file(RENAME \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\")
|
||||
" COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
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 <bsongis-nosp@m-gmail.com>")
|
||||
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_DEPENDS "libqt5multimedia5-plugins")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
elseif(APPLE)
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
# set(CPACK_GENERATOR "TGZ") # for quick testing
|
||||
set(CPACK_BINARY_DRAGNDROP ON)
|
||||
set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash22_3_dmg.png)
|
||||
set(CPACK_DMG_VOLUME_NAME "OpenTX Companion")
|
||||
set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store)
|
||||
set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}")
|
||||
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_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib /lib/udev /lib/udev/rules.d")
|
||||
endif(DPKG_PROGRAM)
|
||||
|
||||
include(CPack)
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
|
||||
#include <QFileDevice>
|
||||
|
||||
AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) :
|
||||
QObject(parent),
|
||||
m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL),
|
||||
m_showSourcePath(APP_DBG_HANDLER_SHOW_SRC_PATH),
|
||||
m_showFunctionDeclarations(APP_DBG_HANDLER_SHOW_FUNCTION_DECL)
|
||||
{
|
||||
m_srcPathFilter = QRegularExpression("^" APP_DBG_HANDLER_SRC_PATH "[\\\\\\/](.*?)$", QRegularExpression::InvertedGreedinessOption);
|
||||
m_functionFilter = QRegularExpression("^.+?(\\w+\\().+$");
|
||||
}
|
||||
|
||||
AppDebugMessageHandler * AppDebugMessageHandler::instance()
|
||||
{
|
||||
static AppDebugMessageHandler * _instance = NULL;
|
||||
#if APP_DBG_HANDLER_ENABLE
|
||||
if(_instance == NULL && !qApp->closingDown())
|
||||
_instance = new AppDebugMessageHandler(qApp); // Ensure this object is cleaned up when the QApplication exits.
|
||||
#endif
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setAppDebugOutputLevel(const quint8 & appDebugOutputLevel)
|
||||
{
|
||||
m_appDebugOutputLevel = appDebugOutputLevel;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setShowSourcePath(bool showSourcePath)
|
||||
{
|
||||
m_showSourcePath = showSourcePath;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclarations)
|
||||
{
|
||||
m_showFunctionDeclarations = showFunctionDeclarations;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::addOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device && !m_outputDevices.contains(device))
|
||||
m_outputDevices.append(device);
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::removeOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device) {
|
||||
// no QVector::removeAll() in Qt < 5.4
|
||||
int i = 0;
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d == device)
|
||||
m_outputDevices.remove(i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::installAppMessageHandler()
|
||||
{
|
||||
m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler);
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg)
|
||||
{
|
||||
static const char symbols[] = { 'D', 'W', 'E', 'X', 'I' }; // correspond to QtMsgType enum
|
||||
// normalize types, QtDebugMsg stays 0, QtInfoMsg becomes 1, rest are QtMsgType + 1
|
||||
quint8 lvl = type;
|
||||
if (type == QtInfoMsg)
|
||||
lvl = 1;
|
||||
else if (type > QtDebugMsg)
|
||||
++lvl;
|
||||
|
||||
if (lvl < m_appDebugOutputLevel && type != QtFatalMsg)
|
||||
return;
|
||||
|
||||
#if defined(Q_OS_LINUX) && (QT_VERSION < QT_VERSION_CHECK(5, 3, 0))
|
||||
// Filter out lots of QPainter warnings from undocked QDockWidgets... hackish but effective (only workaround found so far)
|
||||
if (lvl == 2 && QString(context.function).contains("QPainter::"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
QString msgPattern = QString("[%1] ").arg(symbols[type]);
|
||||
|
||||
if (m_showSourcePath) {
|
||||
QString file = QString("%1::").arg(context.file);
|
||||
file.replace(m_srcPathFilter, "\\1");
|
||||
msgPattern.append(file);
|
||||
}
|
||||
if (m_showFunctionDeclarations)
|
||||
msgPattern.append(context.function);
|
||||
else
|
||||
msgPattern.append("%{function}()");
|
||||
|
||||
msgPattern.append(":%{line} -%{if-category} [%{category}]%{endif} %{message}");
|
||||
|
||||
if (type == QtFatalMsg)
|
||||
msgPattern.append("\nBACKTRACE:\n%{backtrace depth=12 separator=\"\n\"}");
|
||||
|
||||
qSetMessagePattern(msgPattern);
|
||||
|
||||
if (!m_defaultHandler || m_outputDevices.size() || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
|
||||
msgPattern = qFormatLogMessage(type, context, msg);
|
||||
#else
|
||||
msgPattern.replace("%{line}", QString::number(context.line));
|
||||
msgPattern.replace("%{if-category} [%{category}]%{endif}", QString(context.category));
|
||||
msgPattern.replace("%{message}", msg);
|
||||
if (!m_showFunctionDeclarations) {
|
||||
QString func = context.function;
|
||||
msgPattern.replace("%{function}", func.replace(m_functionFilter, "\\1)"));
|
||||
}
|
||||
#endif
|
||||
|
||||
emit messageOutput(lvl, msgPattern);
|
||||
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d && d->isWritable() && (!d->property("level").isValid() || d->property("level").toInt() <= lvl)) {
|
||||
d->write(qPrintable(msgPattern % "\n"));
|
||||
if (QFileDevice * fd = qobject_cast<QFileDevice *>(d))
|
||||
fd->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (QThread::currentThread() == qApp->thread()) // gui thread
|
||||
|
||||
if (m_defaultHandler) {
|
||||
m_defaultHandler(type, context, msg);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s", qPrintable(msgPattern));
|
||||
if (type == QtFatalMsg)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
|
||||
void g_appDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->messageHandler(type, context, msg);
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef APPDEBUGMESSAGEHANDLER_H
|
||||
#define APPDEBUGMESSAGEHANDLER_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QIODevice>
|
||||
#include <QMessageLogContext>
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
|
||||
/*
|
||||
* Custom debug/message handler class to work in conjunction with qDebug() family of functions.
|
||||
* Formats all stderr output generated by the application in a consistent manner.
|
||||
* It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
|
||||
*
|
||||
* Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
|
||||
*
|
||||
* Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
|
||||
* see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
|
||||
*
|
||||
* This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
|
||||
* For example, at start of application:
|
||||
*
|
||||
* QApplication app(argc, argv);
|
||||
* AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
*
|
||||
* To connect to a signal:
|
||||
*
|
||||
* connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
|
||||
*
|
||||
* This singleton will self-destruct upon QApplication termination.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(QT_DEBUG) || defined(DEBUG)
|
||||
#define APP_DBG_HANDLER_IS_DBG_BUILD 1
|
||||
#else
|
||||
#define APP_DBG_HANDLER_IS_DBG_BUILD 0
|
||||
#endif
|
||||
|
||||
// Enable/disable this custom handler handler entirely
|
||||
#ifndef APP_DBG_HANDLER_ENABLE
|
||||
#define APP_DBG_HANDLER_ENABLE 1
|
||||
#endif
|
||||
|
||||
// Default log level (can also be set with setAppDebugOutputLevel()):
|
||||
// 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
|
||||
#ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
|
||||
#define APP_DBG_HANDLER_DEFAULT_LEVEL 0
|
||||
#endif
|
||||
|
||||
// Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
|
||||
#ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
|
||||
#define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
|
||||
#endif
|
||||
|
||||
// Show just the function Class::name vs. full declaration with return and param types
|
||||
#ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
|
||||
#define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
|
||||
#endif
|
||||
|
||||
// base path for source file name filter, everything after this is kept; RegEx, non-greedy
|
||||
#ifndef APP_DBG_HANDLER_SRC_PATH
|
||||
#define APP_DBG_HANDLER_SRC_PATH ".*src"
|
||||
#endif
|
||||
|
||||
// Make sure to include this header if using qInfo()
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
|
||||
#if defined(QT_NO_INFO_OUTPUT)
|
||||
#define qInfo QT_NO_QDEBUG_MACRO
|
||||
#else
|
||||
#define qInfo qDebug
|
||||
#endif
|
||||
#define QtInfoMsg QtMsgType(4)
|
||||
#endif
|
||||
|
||||
class AppDebugMessageHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// This class implements the singleton design pattern and is therefore publicly accessible only through instance().
|
||||
static AppDebugMessageHandler * instance();
|
||||
AppDebugMessageHandler(AppDebugMessageHandler const &) = delete;
|
||||
void operator = (AppDebugMessageHandler const &) = delete;
|
||||
|
||||
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
|
||||
void setShowSourcePath(bool showSourcePath);
|
||||
void setShowFunctionDeclarations(bool showFunctionDeclarations);
|
||||
void addOutputDevice(QIODevice * device);
|
||||
void removeOutputDevice(QIODevice * device);
|
||||
|
||||
void installAppMessageHandler();
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
|
||||
|
||||
private:
|
||||
// This class implements the singleton design pattern and therefore has only a private constructor.
|
||||
explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR);
|
||||
~AppDebugMessageHandler() { }
|
||||
|
||||
QtMessageHandler m_defaultHandler;
|
||||
QRegularExpression m_srcPathFilter;
|
||||
QRegularExpression m_functionFilter;
|
||||
quint8 m_appDebugOutputLevel;
|
||||
QVector<QIODevice *> m_outputDevices;
|
||||
bool m_showSourcePath;
|
||||
bool m_showFunctionDeclarations;
|
||||
|
||||
signals:
|
||||
void messageOutput(quint8 level, const QString & msg);
|
||||
};
|
||||
|
||||
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
|
||||
// Use AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
// instead of installing this function directly (it will verify this handler is enabled, etc).
|
||||
void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
|
||||
|
||||
#endif // APPDEBUGMESSAGEHANDLER_H
|
||||
@@ -1,560 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "apppreferencesdialog.h"
|
||||
#include "ui_apppreferencesdialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "storage.h"
|
||||
#if defined(JOYSTICKS)
|
||||
#include "joystick.h"
|
||||
#include "joystickdialog.h"
|
||||
#endif
|
||||
|
||||
AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AppPreferencesDialog),
|
||||
updateLock(false),
|
||||
mainWinHasDirtyChild(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("apppreferences.png"));
|
||||
|
||||
initSettings();
|
||||
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(onBaseFirmwareChanged()));
|
||||
connect(ui->opt_appDebugLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
connect(ui->opt_fwTraceLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
|
||||
#if !defined(JOYSTICKS)
|
||||
ui->joystickCB->hide();
|
||||
ui->joystickCB->setDisabled(true);
|
||||
ui->joystickcalButton->hide();
|
||||
ui->joystickChkB->hide();
|
||||
ui->label_11->hide();
|
||||
#endif
|
||||
|
||||
shrink();
|
||||
}
|
||||
|
||||
AppPreferencesDialog::~AppPreferencesDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::setMainWinHasDirtyChild(bool value)
|
||||
{
|
||||
mainWinHasDirtyChild = value;
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::accept()
|
||||
{
|
||||
Profile & profile = g.currentProfile();
|
||||
|
||||
g.autoCheckApp(ui->autoCheckCompanion->isChecked());
|
||||
g.OpenTxBranch(AppData::DownloadBranchType(ui->OpenTxBranch->currentIndex()));
|
||||
g.autoCheckFw(ui->autoCheckFirmware->isChecked());
|
||||
g.showSplash(ui->showSplash->isChecked());
|
||||
g.simuSW(ui->simuSW->isChecked());
|
||||
g.removeModelSlots(ui->opt_removeBlankSlots->isChecked());
|
||||
g.newModelAction(ui->opt_newMdl_useWizard->isChecked() ? AppData::MODEL_ACT_WIZARD : ui->opt_newMdl_useEditor->isChecked() ? AppData::MODEL_ACT_EDITOR : AppData::MODEL_ACT_NONE);
|
||||
g.historySize(ui->historySize->value());
|
||||
g.backLight(ui->backLightColor->currentIndex());
|
||||
profile.volumeGain(round(ui->volumeGain->value() * 10.0));
|
||||
g.libDir(ui->libraryPath->text());
|
||||
g.gePath(ui->ge_lineedit->text());
|
||||
g.embedSplashes(ui->splashincludeCB->currentIndex());
|
||||
g.enableBackup(ui->backupEnable->isChecked());
|
||||
|
||||
g.appDebugLog(ui->opt_appDebugLog->isChecked());
|
||||
g.fwTraceLog(ui->opt_fwTraceLog->isChecked());
|
||||
g.appLogsDir(ui->appLogsDir->text());
|
||||
|
||||
if (ui->joystickChkB ->isChecked() && ui->joystickCB->isEnabled()) {
|
||||
g.jsSupport(ui->joystickChkB ->isChecked());
|
||||
g.jsCtrl(ui->joystickCB ->currentIndex());
|
||||
}
|
||||
else {
|
||||
g.jsSupport(false);
|
||||
g.jsCtrl(0);
|
||||
}
|
||||
profile.channelOrder(ui->channelorderCB->currentIndex());
|
||||
profile.defaultMode(ui->stickmodeCB->currentIndex());
|
||||
profile.renameFwFiles(ui->renameFirmware->isChecked());
|
||||
profile.burnFirmware(ui->burnFirmware->isChecked());
|
||||
profile.sdPath(ui->sdPath->text());
|
||||
profile.pBackupDir(ui->profilebackupPath->text());
|
||||
profile.penableBackup(ui->pbackupEnable->isChecked());
|
||||
profile.splashFile(ui->SplashFileName->text());
|
||||
|
||||
// The profile name may NEVER be empty
|
||||
if (ui->profileNameLE->text().isEmpty())
|
||||
profile.name(tr("My Radio"));
|
||||
else
|
||||
profile.name(ui->profileNameLE->text());
|
||||
|
||||
bool fwchange = false;
|
||||
Firmware * newFw = getFirmwareVariant(); // always !null
|
||||
// If a new fw type has been choosen, several things need to reset
|
||||
if (Firmware::getCurrentVariant()->getId() != newFw->getId()) {
|
||||
// check if we're going to be converting to a new radio type and there are unsaved files in the main window
|
||||
if (mainWinHasDirtyChild && !Boards::isBoardCompatible(Firmware::getCurrentVariant()->getBoard(), newFw->getBoard())) {
|
||||
QString q = tr("<p><b>You cannot switch Radio Type or change Build Options while there are unsaved file changes. What do you wish to do?</b></p> <ul>" \
|
||||
"<li><i>Save All</i> - Save any open file(s) before saving Settings.<li>" \
|
||||
"<li><i>Reset</i> - Revert to the previous Radio Type and Build Options before saving Settings.</li>" \
|
||||
"<li><i>Cancel</i> - Return to the Settings editor dialog.</li></ul>");
|
||||
int resp = QMessageBox::question(this, windowTitle(), q, (QMessageBox::SaveAll | QMessageBox::Reset | QMessageBox::Cancel), QMessageBox::Cancel);
|
||||
if (resp == QMessageBox::SaveAll) {
|
||||
// signal main window to save files, need to do this before the fw actually changes
|
||||
emit firmwareProfileAboutToChange();
|
||||
}
|
||||
else if (resp == QMessageBox::Reset) {
|
||||
// bail out early before saving the radio type & firmware options
|
||||
QDialog::accept();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// we do not accept the dialog close
|
||||
return;
|
||||
}
|
||||
}
|
||||
Firmware::setCurrentVariant(newFw);
|
||||
profile.fwName("");
|
||||
profile.resetFwVariables();
|
||||
profile.fwType(newFw->getId());
|
||||
fwchange = true;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
|
||||
if (fwchange)
|
||||
emit firmwareProfileChanged(); // important to do this after the accepted() signal
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_snapshotPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select your snapshot folder"), g.snapshotDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
g.snapshotDir(fileName);
|
||||
g.snapToClpbrd(false);
|
||||
ui->snapshotPath->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::initSettings()
|
||||
{
|
||||
const Profile & profile = g.currentProfile();
|
||||
|
||||
ui->snapshotClipboardCKB->setChecked(g.snapToClpbrd());
|
||||
ui->burnFirmware->setChecked(profile.burnFirmware());
|
||||
ui->snapshotPath->setText(g.snapshotDir());
|
||||
ui->snapshotPath->setReadOnly(true);
|
||||
if (ui->snapshotClipboardCKB->isChecked()) {
|
||||
ui->snapshotPath->setDisabled(true);
|
||||
ui->snapshotPathButton->setDisabled(true);
|
||||
}
|
||||
|
||||
#if !defined(ALLOW_NIGHTLY_BUILDS)
|
||||
// remove nightly version option entirely unless it's the current one (because user might have nightly version also installed)
|
||||
if (g.OpenTxBranch() != AppData::BRANCH_NIGHTLY_UNSTABLE)
|
||||
ui->OpenTxBranch->removeItem(2);
|
||||
// if it's already selected, add a warning message
|
||||
else
|
||||
ui->updatesLayout->addWidget(new QLabel("<font color='red'>" % tr("Note: Nightly builds are not available in this version, Release/RC update channel will be used.") % "</font>", this));
|
||||
#endif
|
||||
ui->OpenTxBranch->setCurrentIndex(g.OpenTxBranch());
|
||||
|
||||
ui->autoCheckCompanion->setChecked(g.autoCheckApp());
|
||||
ui->autoCheckFirmware->setChecked(g.autoCheckFw());
|
||||
ui->showSplash->setChecked(g.showSplash());
|
||||
ui->historySize->setValue(g.historySize());
|
||||
ui->backLightColor->setCurrentIndex(g.backLight());
|
||||
ui->volumeGain->setValue(profile.volumeGain() / 10.0);
|
||||
|
||||
if (IS_TARANIS(getCurrentBoard())) {
|
||||
ui->backLightColor->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->simuSW->setChecked(g.simuSW());
|
||||
ui->opt_removeBlankSlots->setChecked(g.removeModelSlots());
|
||||
ui->opt_newMdl_useNone->setChecked(g.newModelAction() == AppData::MODEL_ACT_NONE);
|
||||
ui->opt_newMdl_useWizard->setChecked(g.newModelAction() == AppData::MODEL_ACT_WIZARD);
|
||||
ui->opt_newMdl_useEditor->setChecked(g.newModelAction() == AppData::MODEL_ACT_EDITOR);
|
||||
ui->libraryPath->setText(g.libDir());
|
||||
ui->ge_lineedit->setText(g.gePath());
|
||||
|
||||
if (!g.backupDir().isEmpty()) {
|
||||
if (QDir(g.backupDir()).exists()) {
|
||||
ui->backupPath->setText(g.backupDir());
|
||||
ui->backupEnable->setEnabled(true);
|
||||
ui->backupEnable->setChecked(g.enableBackup());
|
||||
}
|
||||
else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
ui->splashincludeCB->setCurrentIndex(g.embedSplashes());
|
||||
|
||||
ui->opt_appDebugLog->setChecked(g.appDebugLog());
|
||||
ui->opt_fwTraceLog->setChecked(g.fwTraceLog());
|
||||
ui->appLogsDir->setText(g.appLogsDir());
|
||||
toggleAppLogSettings();
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
ui->joystickChkB->setChecked(g.jsSupport());
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
joystickNames << tr("No joysticks found");
|
||||
joystick = new Joystick(0,false,0,0);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
ui->joystickCB->setDisabled(true);
|
||||
|
||||
if ( joystick ) {
|
||||
if ( joystick->joystickNames.count() > 0 ) {
|
||||
joystickNames = joystick->joystickNames;
|
||||
ui->joystickCB->setEnabled(true);
|
||||
ui->joystickcalButton->setEnabled(true);
|
||||
}
|
||||
joystick->close();
|
||||
}
|
||||
ui->joystickCB->clear();
|
||||
ui->joystickCB->insertItems(0, joystickNames);
|
||||
ui->joystickCB->setCurrentIndex(g.jsCtrl());
|
||||
}
|
||||
else {
|
||||
ui->joystickCB->clear();
|
||||
ui->joystickCB->setDisabled(true);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
}
|
||||
#endif
|
||||
// Profile Tab Inits
|
||||
ui->channelorderCB->setCurrentIndex(profile.channelOrder());
|
||||
ui->stickmodeCB->setCurrentIndex(profile.defaultMode());
|
||||
ui->renameFirmware->setChecked(profile.renameFwFiles());
|
||||
ui->sdPath->setText(profile.sdPath());
|
||||
if (!profile.pBackupDir().isEmpty()) {
|
||||
if (QDir(profile.pBackupDir()).exists()) {
|
||||
ui->profilebackupPath->setText(profile.pBackupDir());
|
||||
ui->pbackupEnable->setEnabled(true);
|
||||
ui->pbackupEnable->setChecked(profile.penableBackup());
|
||||
} else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
|
||||
ui->profileNameLE->setText(profile.name());
|
||||
|
||||
QString hwSettings;
|
||||
if (profile.stickPotCalib() == "" ) {
|
||||
hwSettings = tr("EMPTY: No radio settings stored in profile");
|
||||
}
|
||||
else {
|
||||
QString str = profile.timeStamp();
|
||||
if (str.isEmpty())
|
||||
hwSettings = tr("AVAILABLE: Radio settings of unknown age");
|
||||
else
|
||||
hwSettings = tr("AVAILABLE: Radio settings stored %1").arg(str);
|
||||
}
|
||||
ui->lblGeneralSettings->setText(hwSettings);
|
||||
|
||||
QString currType = QStringList(profile.fwType().split('-').mid(0, 2)).join('-');
|
||||
foreach(Firmware * firmware, Firmware::getRegisteredFirmwares()) {
|
||||
ui->downloadVerCB->addItem(firmware->getName(), firmware->getId());
|
||||
if (currType == firmware->getId()) {
|
||||
ui->downloadVerCB->setCurrentIndex(ui->downloadVerCB->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
onBaseFirmwareChanged();
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_libraryPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your library folder"), g.libDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
g.libDir(fileName);
|
||||
ui->libraryPath->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_snapshotClipboardCKB_clicked()
|
||||
{
|
||||
if (ui->snapshotClipboardCKB->isChecked()) {
|
||||
ui->snapshotPath->setDisabled(true);
|
||||
ui->snapshotPathButton->setDisabled(true);
|
||||
g.snapToClpbrd(true);
|
||||
}
|
||||
else {
|
||||
ui->snapshotPath->setEnabled(true);
|
||||
ui->snapshotPath->setReadOnly(true);
|
||||
ui->snapshotPathButton->setEnabled(true);
|
||||
g.snapToClpbrd(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_backupPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your Models and Settings backup folder"), g.backupDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
g.backupDir(fileName);
|
||||
ui->backupPath->setText(fileName);
|
||||
ui->backupEnable->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your Models and Settings backup folder"), g.backupDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->profilebackupPath->setText(fileName);
|
||||
ui->pbackupEnable->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppPreferencesDialog::on_btn_appLogsDir_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select a folder for application logs"), ui->appLogsDir->text());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->appLogsDir->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ge_pathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Google Earth executable"),ui->ge_lineedit->text());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->ge_lineedit->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
void AppPreferencesDialog::on_joystickChkB_clicked() {
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
joystickNames << tr("No joysticks found");
|
||||
joystick = new Joystick(0,false,0,0);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
ui->joystickCB->setDisabled(true);
|
||||
|
||||
if ( joystick ) {
|
||||
if ( joystick->joystickNames.count() > 0 ) {
|
||||
joystickNames = joystick->joystickNames;
|
||||
ui->joystickCB->setEnabled(true);
|
||||
ui->joystickcalButton->setEnabled(true);
|
||||
}
|
||||
joystick->close();
|
||||
}
|
||||
ui->joystickCB->clear();
|
||||
ui->joystickCB->insertItems(0, joystickNames);
|
||||
}
|
||||
else {
|
||||
ui->joystickCB->clear();
|
||||
ui->joystickCB->setDisabled(true);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_joystickcalButton_clicked() {
|
||||
joystickDialog * jd=new joystickDialog(this, ui->joystickCB->currentIndex());
|
||||
jd->exec();
|
||||
}
|
||||
#endif
|
||||
|
||||
// ******** Profile tab functions
|
||||
|
||||
void AppPreferencesDialog::on_sdPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select the folder replicating your SD structure"), g.currentProfile().sdPath());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->sdPath->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
bool AppPreferencesDialog::displayImage(const QString & fileName)
|
||||
{
|
||||
// Start by clearing the label
|
||||
ui->imageLabel->clear();
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
|
||||
QImage image(fileName);
|
||||
if (image.isNull())
|
||||
return false;
|
||||
|
||||
ui->imageLabel->setPixmap(makePixMap(image));
|
||||
ui->imageLabel->setFixedSize(getCurrentFirmware()->getCapability(LcdWidth), getCurrentFirmware()->getCapability(LcdHeight));
|
||||
return true;
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_SplashSelect_clicked()
|
||||
{
|
||||
QString supportedImageFormats;
|
||||
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
|
||||
supportedImageFormats += QLatin1String(" *.") + QImageReader::supportedImageFormats()[formatIndex];
|
||||
}
|
||||
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Image to load"), g.imagesDir(), tr("Images (%1)").arg(supportedImageFormats));
|
||||
|
||||
if (!fileName.isEmpty()){
|
||||
g.imagesDir(QFileInfo(fileName).dir().absolutePath());
|
||||
|
||||
displayImage(fileName);
|
||||
ui->SplashFileName->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_clearImageButton_clicked()
|
||||
{
|
||||
ui->imageLabel->clear();
|
||||
ui->SplashFileName->clear();
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::onBaseFirmwareChanged()
|
||||
{
|
||||
populateFirmwareOptions(getBaseFirmware());
|
||||
}
|
||||
|
||||
Firmware *AppPreferencesDialog::getBaseFirmware() const
|
||||
{
|
||||
return Firmware::getFirmwareForId(ui->downloadVerCB->currentData().toString());
|
||||
}
|
||||
|
||||
Firmware * AppPreferencesDialog::getFirmwareVariant() const
|
||||
{
|
||||
QString id = ui->downloadVerCB->currentData().toString();
|
||||
|
||||
foreach(QCheckBox *cb, optionsCheckBoxes.values()) {
|
||||
if (cb->isChecked())
|
||||
id += "-" + cb->text();
|
||||
}
|
||||
|
||||
if (ui->langCombo->count())
|
||||
id += "-" + ui->langCombo->currentText();
|
||||
|
||||
return Firmware::getFirmwareForId(id);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::onFirmwareOptionChanged(bool state)
|
||||
{
|
||||
QCheckBox *cb = qobject_cast<QCheckBox*>(sender());
|
||||
if (!(cb && state))
|
||||
return;
|
||||
|
||||
// This de-selects any mutually exlusive options (that is, members of the same QList<Option> list).
|
||||
const Firmware::OptionsList & fwOpts = getBaseFirmware()->optionGroups();
|
||||
for (const Firmware::OptionsGroup & optGrp : fwOpts) {
|
||||
for (const Firmware::Option & opt : optGrp) {
|
||||
if (cb->text() == opt.name) {
|
||||
QCheckBox *ocb = nullptr;
|
||||
foreach(const Firmware::Option & other, optGrp)
|
||||
if (other.name != opt.name && (ocb = optionsCheckBoxes.value(other.name, nullptr)))
|
||||
ocb->setChecked(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::toggleAppLogSettings()
|
||||
{
|
||||
bool vis = (ui->opt_appDebugLog->isChecked() || ui->opt_fwTraceLog->isChecked());
|
||||
ui->appLogsDir->setVisible(vis);
|
||||
ui->lbl_appLogsDir->setVisible(vis);
|
||||
ui->btn_appLogsDir->setVisible(vis);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
|
||||
{
|
||||
const Firmware * baseFw = firmware->getFirmwareBase();
|
||||
QStringList currVariant = Firmware::getCurrentVariant()->getId().split('-');
|
||||
const QString currLang = ui->langCombo->count() ? ui->langCombo->currentText() : currVariant.last();
|
||||
|
||||
updateLock = true;
|
||||
|
||||
ui->langCombo->clear();
|
||||
for (const char *lang : baseFw->languageList()) {
|
||||
ui->langCombo->addItem(lang);
|
||||
if (currLang == lang) {
|
||||
ui->langCombo->setCurrentIndex(ui->langCombo->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (optionsCheckBoxes.size()) {
|
||||
currVariant.clear();
|
||||
QMutableMapIterator<QString, QCheckBox *> it(optionsCheckBoxes);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QCheckBox * cb = it.value();
|
||||
if (cb->isChecked())
|
||||
currVariant.append(it.key()); // keep previous selections
|
||||
ui->optionsLayout->removeWidget(cb);
|
||||
cb->deleteLater();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
QWidget * prevFocus = ui->langCombo;
|
||||
for (const Firmware::OptionsGroup &optGrp : baseFw->optionGroups()) {
|
||||
for (const Firmware::Option &opt : optGrp) {
|
||||
QCheckBox * cb = new QCheckBox(ui->profileTab);
|
||||
cb->setText(opt.name);
|
||||
cb->setToolTip(opt.tooltip);
|
||||
cb->setChecked(currVariant.contains(opt.name));
|
||||
ui->optionsLayout->addWidget(cb, index / 4, index % 4);
|
||||
QWidget::setTabOrder(prevFocus, cb);
|
||||
// connect to duplicates check handler if this option is part of a group
|
||||
if (optGrp.size() > 1)
|
||||
connect(cb, &QCheckBox::toggled, this, &AppPreferencesDialog::onFirmwareOptionChanged);
|
||||
optionsCheckBoxes.insert(opt.name, cb);
|
||||
prevFocus = cb;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove once splash replacement supported on Horus
|
||||
// NOTE: 480x272 image causes issues on screens <800px high, needs a solution like scrolling once reinstated
|
||||
if (IS_HORUS(baseFw->getBoard())) {
|
||||
ui->widget_splashImage->hide();
|
||||
ui->SplashFileName->setText("");
|
||||
}
|
||||
else {
|
||||
ui->widget_splashImage->show();
|
||||
ui->SplashFileName->setText(g.currentProfile().splashFile());
|
||||
displayImage(g.currentProfile().splashFile());
|
||||
}
|
||||
|
||||
updateLock = false;
|
||||
QTimer::singleShot(50, this, &AppPreferencesDialog::shrink);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::shrink()
|
||||
{
|
||||
adjustSize();
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _APPPREFERENCESDIALOG_H_
|
||||
#define _APPPREFERENCESDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
#include "eeprominterface.h"
|
||||
|
||||
namespace Ui {
|
||||
class AppPreferencesDialog;
|
||||
}
|
||||
|
||||
class Joystick;
|
||||
|
||||
class AppPreferencesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AppPreferencesDialog(QWidget * parent = 0);
|
||||
~AppPreferencesDialog();
|
||||
|
||||
Joystick * joystick;
|
||||
|
||||
public slots:
|
||||
void accept() Q_DECL_OVERRIDE;
|
||||
void setMainWinHasDirtyChild(bool value);
|
||||
|
||||
signals:
|
||||
void firmwareProfileChanged();
|
||||
void firmwareProfileAboutToChange(bool saveFiles = true);
|
||||
|
||||
protected slots:
|
||||
void shrink();
|
||||
void onBaseFirmwareChanged();
|
||||
void onFirmwareOptionChanged(bool state);
|
||||
void toggleAppLogSettings();
|
||||
|
||||
void on_libraryPathButton_clicked();
|
||||
void on_snapshotPathButton_clicked();
|
||||
void on_snapshotClipboardCKB_clicked();
|
||||
void on_backupPathButton_clicked();
|
||||
void on_ProfilebackupPathButton_clicked();
|
||||
void on_ge_pathButton_clicked();
|
||||
|
||||
void on_sdPathButton_clicked();
|
||||
void on_SplashSelect_clicked();
|
||||
void on_clearImageButton_clicked();
|
||||
void on_btn_appLogsDir_clicked();
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
void on_joystickChkB_clicked();
|
||||
void on_joystickcalButton_clicked();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void initSettings();
|
||||
void populateFirmwareOptions(const Firmware *);
|
||||
Firmware * getBaseFirmware() const;
|
||||
Firmware * getFirmwareVariant() const;
|
||||
bool displayImage(const QString & fileName);
|
||||
|
||||
Ui::AppPreferencesDialog *ui;
|
||||
QMap<QString, QCheckBox *> optionsCheckBoxes;
|
||||
bool updateLock;
|
||||
bool mainWinHasDirtyChild;
|
||||
};
|
||||
|
||||
#endif // _APPPREFERENCESDIALOG_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "burnconfigdialog.h"
|
||||
#include "ui_burnconfigdialog.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "helpers.h"
|
||||
#include "appdata.h"
|
||||
#include "progressdialog.h"
|
||||
#include "process_flash.h"
|
||||
|
||||
#if !defined _MSC_VER && defined __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
burnConfigDialog::burnConfigDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::burnConfigDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("configure.png"));
|
||||
ui->avrdude_programmer->model()->sort(0);
|
||||
|
||||
getSettings();
|
||||
populateProgrammers();
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (IS_STM32(board)) {
|
||||
setWindowTitle(tr("DFU-UTIL Configuration"));
|
||||
ui->avrArgs->hide();
|
||||
ui->avrdude_location->hide();
|
||||
ui->avrdude_port->hide();
|
||||
ui->avrdude_programmer->hide();
|
||||
ui->label_av1->hide();
|
||||
ui->label_av2->hide();
|
||||
ui->label_av4->hide();
|
||||
ui->label_av5->hide();
|
||||
ui->pushButton->hide();
|
||||
ui->pushButton_3->hide();
|
||||
ui->pushButton_4->hide();
|
||||
ui->label_sb1->hide();
|
||||
ui->label_sb3->hide();
|
||||
ui->samba_location->hide();
|
||||
ui->samba_port->hide();
|
||||
ui->sb_browse->hide();
|
||||
}
|
||||
else if (IS_SKY9X(board)) {
|
||||
setWindowTitle(tr("SAM-BA Configuration"));
|
||||
ui->avrArgs->hide();
|
||||
ui->avrdude_location->hide();
|
||||
ui->avrdude_port->hide();
|
||||
ui->avrdude_programmer->hide();
|
||||
ui->label_av1->hide();
|
||||
ui->label_av2->hide();
|
||||
ui->label_av4->hide();
|
||||
ui->label_av5->hide();
|
||||
ui->pushButton->hide();
|
||||
ui->pushButton_3->hide();
|
||||
ui->pushButton_4->hide();
|
||||
ui->label_dfu1->hide();
|
||||
ui->dfu_location->hide();
|
||||
ui->dfu_browse->hide();
|
||||
}
|
||||
else {
|
||||
setWindowTitle(tr("AVRDUDE Configuration"));
|
||||
ui->label_sb1->hide();
|
||||
ui->label_sb3->hide();
|
||||
ui->samba_location->hide();
|
||||
ui->samba_port->hide();
|
||||
ui->sb_browse->hide();
|
||||
ui->label_dfu1->hide();
|
||||
ui->label_dfu2->hide();
|
||||
ui->dfu_location->hide();
|
||||
ui->dfu_browse->hide();
|
||||
}
|
||||
ui->label_av3->hide();
|
||||
ui->avrdude_mcu->hide();
|
||||
ui->label_sb2->hide();
|
||||
ui->arm_mcu->hide();
|
||||
ui->label_dfu2->hide();
|
||||
ui->dfuArgs->hide();
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(putSettings()));
|
||||
}
|
||||
|
||||
burnConfigDialog::~burnConfigDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QStringList burnConfigDialog::getAvrdudeArgs()
|
||||
{
|
||||
QStringList args = avrArgs;
|
||||
if (!avrPort.isEmpty())
|
||||
args << "-P" << avrPort;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
args << "-C" << QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude.conf").absoluteFilePath();
|
||||
#endif
|
||||
return args;
|
||||
}
|
||||
|
||||
void burnConfigDialog::getSettings()
|
||||
{
|
||||
avrLoc = g.avrdudeLocation();
|
||||
sambaLoc = g.sambaLocation();
|
||||
dfuLoc = g.dfuLocation();
|
||||
|
||||
#if defined WIN32 || !defined __GNUC__
|
||||
if ( avrLoc.isEmpty())
|
||||
avrLoc = QFileInfo("avrdude.exe").absoluteFilePath();
|
||||
if ( sambaLoc.isEmpty())
|
||||
sambaLoc = QFileInfo("sam-ba.exe").absoluteFilePath();
|
||||
if ( dfuLoc.isEmpty())
|
||||
dfuLoc = QFileInfo("dfu-util.exe").absoluteFilePath();
|
||||
#elif defined __APPLE__
|
||||
if ( avrLoc.isEmpty())
|
||||
avrLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude").absoluteFilePath();
|
||||
if ( sambaLoc.isEmpty())
|
||||
sambaLoc = "/usr/local/bin/sam-ba";
|
||||
if ( dfuLoc.isEmpty())
|
||||
dfuLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/dfu-util").absoluteFilePath();
|
||||
#elif defined __FreeBSD__
|
||||
if (avrLoc.isEmpty())
|
||||
avrLoc = "/usr/local/bin/avrdude";
|
||||
if (dfuLoc.isEmpty())
|
||||
dfuLoc = "/usr/local/bin/dfu-util";
|
||||
#else
|
||||
if ( avrLoc.isEmpty())
|
||||
avrLoc = "/usr/bin/avrdude";
|
||||
if ( sambaLoc.isEmpty())
|
||||
sambaLoc = "/usr/bin/sam-ba";
|
||||
if ( dfuLoc.isEmpty())
|
||||
dfuLoc = QFileInfo("/usr/bin/dfu-util").absoluteFilePath();
|
||||
#endif
|
||||
|
||||
dfuArgs = g.dfuArguments().split(" ", QString::SkipEmptyParts);
|
||||
avrArgs = g.avrArguments().split(" ", QString::SkipEmptyParts);
|
||||
avrProgrammer = g.programmer();
|
||||
avrPort = g.avrPort();
|
||||
avrMCU = g.mcu();
|
||||
armMCU = g.armMcu();
|
||||
sambaPort = g.sambaPort();
|
||||
|
||||
ui->avrdude_location->setText(getAVRDUDE());
|
||||
ui->avrArgs->setText(avrArgs.join(" "));
|
||||
|
||||
ui->samba_location->setText(getSAMBA());
|
||||
ui->samba_port->setText(getSambaPort());
|
||||
|
||||
ui->dfu_location->setText(getDFU());
|
||||
ui->dfuArgs->setText(getDFUArgs().join(" "));
|
||||
|
||||
int idx1 = ui->avrdude_programmer->findText(getProgrammer());
|
||||
int idx2 = ui->avrdude_port->findText(getPort());
|
||||
int idx3 = ui->avrdude_mcu->findText(getMCU());
|
||||
int idx4 = ui->arm_mcu->findText(getArmMCU());
|
||||
if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1);
|
||||
if(idx2>=0) ui->avrdude_port->setCurrentIndex(idx2);
|
||||
if(idx3>=0) ui->avrdude_mcu->setCurrentIndex(idx3);
|
||||
if(idx4>=0) ui->arm_mcu->setCurrentIndex(idx4);
|
||||
QFile file;
|
||||
if (file.exists(avrLoc)) {
|
||||
ui->pushButton_3->setEnabled(true);
|
||||
} else {
|
||||
ui->pushButton_3->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::putSettings()
|
||||
{
|
||||
g.avrdudeLocation( avrLoc );
|
||||
g.programmer( avrProgrammer);
|
||||
g.mcu( avrMCU );
|
||||
g.avrPort( avrPort );
|
||||
g.avrArguments( avrArgs.join(" ") );
|
||||
g.sambaLocation( sambaLoc );
|
||||
g.sambaPort( sambaPort );
|
||||
g.armMcu( armMCU );
|
||||
g.dfuLocation( dfuLoc );
|
||||
g.dfuArguments( dfuArgs.join(" ") );
|
||||
}
|
||||
|
||||
void burnConfigDialog::populateProgrammers()
|
||||
{
|
||||
QString fileName = QFileInfo(avrLoc).canonicalPath() + "/avrdude.conf"; //for windows
|
||||
if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude.conf"; //for linux
|
||||
if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude/avrdude.conf"; //for linux
|
||||
if(!QFileInfo(fileName).exists()) return; // not found avrdude.conf - returning
|
||||
|
||||
QFile file(fileName);
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||
|
||||
QStringList items;
|
||||
QString line = "";
|
||||
QString prevline = "";
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd())
|
||||
{
|
||||
prevline = line;
|
||||
line = in.readLine();
|
||||
|
||||
if(prevline.left(10).toLower()=="programmer")
|
||||
items << line.section('"',1,1);
|
||||
}
|
||||
file.close();
|
||||
|
||||
items.sort();
|
||||
|
||||
QString avrProgrammer_temp = avrProgrammer;
|
||||
ui->avrdude_programmer->clear();
|
||||
ui->avrdude_programmer->addItems(items);
|
||||
int idx1 = ui->avrdude_programmer->findText(avrProgrammer_temp);
|
||||
if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1);
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_avrdude_programmer_currentIndexChanged(QString )
|
||||
{
|
||||
avrProgrammer = ui->avrdude_programmer->currentText();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_avrdude_mcu_currentIndexChanged(QString )
|
||||
{
|
||||
avrMCU = ui->avrdude_mcu->currentText();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_avrdude_location_editingFinished()
|
||||
{
|
||||
avrLoc = ui->avrdude_location->text();
|
||||
if (avrLoc.isEmpty()) {
|
||||
ui->pushButton_3->setDisabled(true);
|
||||
} else {
|
||||
QFile file;
|
||||
if (file.exists(avrLoc)) {
|
||||
ui->pushButton_3->setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_avrArgs_editingFinished()
|
||||
{
|
||||
avrArgs = ui->avrArgs->text().split(" ", QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_avrdude_port_currentIndexChanged(QString )
|
||||
{
|
||||
avrPort = ui->avrdude_port->currentText();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_samba_location_editingFinished()
|
||||
{
|
||||
sambaLoc = ui->samba_location->text();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_samba_port_editingFinished()
|
||||
{
|
||||
sambaPort = ui->samba_port->text();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_arm_mcu_currentIndexChanged(QString )
|
||||
{
|
||||
armMCU = ui->arm_mcu->currentText();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_pushButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->avrdude_location->text());
|
||||
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
ui->avrdude_location->setText(fileName);
|
||||
avrLoc = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_sb_browse_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->samba_location->text());
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
ui->samba_location->setText(fileName);
|
||||
sambaLoc = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_dfu_browse_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->dfu_location->text());
|
||||
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
ui->dfu_location->setText(fileName);
|
||||
dfuLoc = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_dfu_location_editingFinished()
|
||||
{
|
||||
dfuLoc = ui->dfu_location->text();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_dfuArgs_editingFinished()
|
||||
{
|
||||
dfuArgs = ui->dfuArgs->text().split(" ", QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
void burnConfigDialog::listAvrdudeProgrammers()
|
||||
{
|
||||
ProgressDialog progressDialog(this, tr("List available programmers"), CompanionIcon("list.png"), true);
|
||||
FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-c?", progressDialog.progress());
|
||||
flashProcess.run();
|
||||
}
|
||||
|
||||
// TODO choose better name when no merge in progress....
|
||||
void burnConfigDialog::on_pushButton_3_clicked()
|
||||
{
|
||||
listAvrdudeProgrammers();
|
||||
}
|
||||
|
||||
// TODO choose better name when no merge in progress....
|
||||
void burnConfigDialog::on_pushButton_4_clicked()
|
||||
{
|
||||
ProgressDialog progressDialog(this, tr("Avrdude help"), CompanionIcon("configure.png"), true);
|
||||
FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-?", progressDialog.progress());
|
||||
flashProcess.run();
|
||||
}
|
||||
|
||||
void burnConfigDialog::on_advCtrChkB_toggled(bool checked)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (checked) {
|
||||
if (IS_STM32(board)) {
|
||||
ui->label_dfu2->show();
|
||||
ui->dfuArgs->show();
|
||||
}
|
||||
else if (IS_SKY9X(board)) {
|
||||
ui->label_sb2->show();
|
||||
ui->arm_mcu->show();
|
||||
}
|
||||
else {
|
||||
ui->label_av3->show();
|
||||
ui->avrdude_mcu->show();
|
||||
QMessageBox::warning(this, CPN_STR_APP_NAME,
|
||||
tr("<b><u>WARNING!</u></b><br>Normally CPU type is automatically selected according to the chosen firmware.<br>If you change the CPU type the resulting eeprom could be inconsistent."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (IS_STM32(board)) {
|
||||
ui->label_dfu2->hide();
|
||||
ui->dfuArgs->hide();
|
||||
}
|
||||
else if (IS_SKY9X(board)) {
|
||||
ui->label_sb2->hide();
|
||||
ui->arm_mcu->hide();
|
||||
}
|
||||
else {
|
||||
ui->label_av3->hide();
|
||||
ui->avrdude_mcu->hide();
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
}
|
||||
|
||||
|
||||
void burnConfigDialog::shrink()
|
||||
{
|
||||
resize(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BURNCONFIGDIALOG_H_
|
||||
#define _BURNCONFIGDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#define MEM_TYPE_EEPROM 1
|
||||
#define MEM_TYPE_FLASH 2
|
||||
|
||||
#define OPR_TYPE_READ 1
|
||||
#define OPR_TYPE_WRITE 2
|
||||
|
||||
namespace Ui {
|
||||
class burnConfigDialog;
|
||||
}
|
||||
|
||||
class burnConfigDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
burnConfigDialog(QWidget *parent = 0);
|
||||
~burnConfigDialog();
|
||||
|
||||
QString getAVRDUDE() {return avrLoc;}
|
||||
QString getSAMBA() {return sambaLoc;}
|
||||
QString getDFU() {return dfuLoc;}
|
||||
QStringList getAvrdudeArgs();
|
||||
QStringList getDFUArgs() {return dfuArgs;}
|
||||
QString getProgrammer() {return avrProgrammer;}
|
||||
QString getMCU() {return avrMCU;}
|
||||
QString getArmMCU() {return armMCU;}
|
||||
QString getPort() {return avrPort;}
|
||||
QString getSambaPort() {return sambaPort;}
|
||||
|
||||
void listAvrdudeProgrammers();
|
||||
|
||||
private:
|
||||
Ui::burnConfigDialog *ui;
|
||||
|
||||
void populateProgrammers();
|
||||
|
||||
QString avrLoc;
|
||||
QString sambaLoc;
|
||||
QString dfuLoc;
|
||||
QStringList avrArgs;
|
||||
QString avrProgrammer;
|
||||
QString avrMCU;
|
||||
QString armMCU;
|
||||
QString avrPort;
|
||||
QString sambaPort;
|
||||
QStringList dfuArgs;
|
||||
|
||||
private slots:
|
||||
void shrink();
|
||||
void on_avrArgs_editingFinished();
|
||||
void on_pushButton_4_clicked();
|
||||
void on_pushButton_3_clicked();
|
||||
void on_pushButton_clicked();
|
||||
void on_avrdude_location_editingFinished();
|
||||
void on_avrdude_programmer_currentIndexChanged(QString );
|
||||
void on_avrdude_mcu_currentIndexChanged(QString );
|
||||
void on_avrdude_port_currentIndexChanged(QString );
|
||||
void on_samba_location_editingFinished();
|
||||
void on_samba_port_editingFinished();
|
||||
void on_arm_mcu_currentIndexChanged(QString );
|
||||
void on_sb_browse_clicked();
|
||||
void on_dfu_browse_clicked();
|
||||
void on_dfu_location_editingFinished();
|
||||
void on_dfuArgs_editingFinished();
|
||||
void on_advCtrChkB_toggled(bool checked);
|
||||
void getSettings();
|
||||
void putSettings();
|
||||
};
|
||||
|
||||
#endif // _BURNCONFIGDIALOG_H_
|
||||
@@ -1,867 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>burnConfigDialog</class>
|
||||
<widget class="QDialog" name="burnConfigDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>531</width>
|
||||
<height>422</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>531</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Programmer Configuration</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="companion.qrc">
|
||||
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="9" column="2">
|
||||
<widget class="QLineEdit" name="dfu_location">
|
||||
<property name="toolTip">
|
||||
<string>Location of sam-ba executable</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>The location of the AVRDUDE executable.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">dfu-util</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_dfu1">
|
||||
<property name="text">
|
||||
<string>DFU-Util Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="avrdude_location">
|
||||
<property name="toolTip">
|
||||
<string>Location of AVRDUDE executable</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>The location of the AVRDUDE executable.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="2">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="whatsThis">
|
||||
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_av2">
|
||||
<property name="text">
|
||||
<string>Programmer</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="avrdude_programmer">
|
||||
<property name="whatsThis">
|
||||
<string>Programmer used for communicating with the controller.
|
||||
Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer.</string>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAlphabetically</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">c2n232i</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dasa3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dasa</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">siprog</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">ponyser</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">89isp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">frank-stk200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">blaster</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">ere-isp-avr</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">atisp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dapa</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">xil</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">futurlec</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">abcmini</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">picoweb</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">sp12</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">alf</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">bascom</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dt006</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">pony-stk200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">bsd</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">pavr</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_pdi</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_dw</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_hvsp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_pp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_isp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">dragon_jtag</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2pdi</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2avr32</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtagmkII_avr32</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2dw</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2isp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2fast</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag2slow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtagmkII</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag1slow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtag1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">jtagmkI</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avr911</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avr109</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">butterfly</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">usbtiny</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">usbasp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avr910</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk600hvsp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk600pp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk600</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk500hvsp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk500pp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk500v2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">mib510</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk500v1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">stk500</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">buspirate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avrisp2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avrispmkII</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avrispv2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avrisp</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">arduino</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="pushButton_3">
|
||||
<property name="whatsThis">
|
||||
<string>List all available programmers.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>List Available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLineEdit" name="avrArgs">
|
||||
<property name="toolTip">
|
||||
<string>Extra arguments that will be passed to AVRDUDE on every call</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Extra arguments used in AVRDUDE.
|
||||
This can be used for providing extra information to AVRDUDE.
|
||||
|
||||
Please only use this if you know what you are doing. There are no error checks and you could cripple your controller.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_av5">
|
||||
<property name="text">
|
||||
<string>Extra Arguments</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4">
|
||||
<widget class="QPushButton" name="pushButton_4">
|
||||
<property name="whatsThis">
|
||||
<string>Show AVRDUDE help</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Help</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QComboBox" name="avrdude_port">
|
||||
<property name="whatsThis">
|
||||
<string>Communication port to the programmer.
|
||||
</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">usb</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com8</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com9</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com10</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com11</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com12</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com13</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com14</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">com15</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">lpt1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">lpt2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">lpt3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">lpt4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">avrdoper</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">/dev/ttyUSB0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">/dev/ttyUSB1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_av4">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_av1">
|
||||
<property name="text">
|
||||
<string>AVRDUDE Location</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_av3">
|
||||
<property name="text">
|
||||
<string>MCU</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QComboBox" name="avrdude_mcu">
|
||||
<property name="toolTip">
|
||||
<string>CPU of your TX</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>CPU present on your 9x radio
|
||||
Should be m64 for stock radios
|
||||
m2560 for v4.1 boards</string>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAlphabetically</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">m64</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">m128</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">m2560</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QComboBox" name="arm_mcu">
|
||||
<property name="toolTip">
|
||||
<string>CPU of your TX</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>CPU present on your 9x radio
|
||||
Should be m64 for stock radios
|
||||
m2560 for v4.1 boards</string>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAlphabetically</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">at91sam3s4-9x</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>at91sam3s8-9xr</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_sb1">
|
||||
<property name="text">
|
||||
<string>SAM-BA Location</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLineEdit" name="samba_location">
|
||||
<property name="toolTip">
|
||||
<string>Location of sam-ba executable</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>The location of the AVRDUDE executable.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">sam-ba.exe</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_sb2">
|
||||
<property name="text">
|
||||
<string>ARM MCU</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_sb3">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLineEdit" name="samba_port">
|
||||
<property name="toolTip">
|
||||
<string>sam-ba serial port</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>The location of the AVRDUDE executable.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">\USBserial\COM23</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_dfu2">
|
||||
<property name="text">
|
||||
<string>Alternate device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLineEdit" name="dfuArgs">
|
||||
<property name="toolTip">
|
||||
<string>Extra arguments that will be passed to AVRDUDE on every call</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Extra arguments used in AVRDUDE.
|
||||
This can be used for providing extra information to AVRDUDE.
|
||||
|
||||
Please only use this if you know what you are doing. There are no error checks and you could cripple your controller.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4">
|
||||
<widget class="QPushButton" name="sb_browse">
|
||||
<property name="whatsThis">
|
||||
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="4">
|
||||
<widget class="QPushButton" name="dfu_browse">
|
||||
<property name="whatsThis">
|
||||
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QCheckBox" name="advCtrChkB">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Use advanced controls</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>avrdude_location</tabstop>
|
||||
<tabstop>pushButton</tabstop>
|
||||
<tabstop>avrdude_programmer</tabstop>
|
||||
<tabstop>pushButton_3</tabstop>
|
||||
<tabstop>avrdude_mcu</tabstop>
|
||||
<tabstop>avrdude_port</tabstop>
|
||||
<tabstop>avrArgs</tabstop>
|
||||
<tabstop>pushButton_4</tabstop>
|
||||
<tabstop>samba_location</tabstop>
|
||||
<tabstop>sb_browse</tabstop>
|
||||
<tabstop>arm_mcu</tabstop>
|
||||
<tabstop>samba_port</tabstop>
|
||||
<tabstop>dfu_location</tabstop>
|
||||
<tabstop>dfu_browse</tabstop>
|
||||
<tabstop>dfuArgs</tabstop>
|
||||
<tabstop>advCtrChkB</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="companion.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>burnConfigDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>burnConfigDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,285 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QSplashScreen>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
#include "customdebug.h"
|
||||
#include "mainwindow.h"
|
||||
#include "version.h"
|
||||
#include "appdata.h"
|
||||
#include "simulatorinterface.h"
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QProxyStyle>
|
||||
|
||||
class MyProxyStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
void polish ( QWidget * w ) {
|
||||
QMenu* mn = dynamic_cast<QMenu*>(w);
|
||||
QPushButton* pb = dynamic_cast<QPushButton*>(w);
|
||||
if(!(mn || pb) && !w->testAttribute(Qt::WA_MacNormalSize))
|
||||
w->setAttribute(Qt::WA_MacSmallSize);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
void importError()
|
||||
{
|
||||
QMessageBox::critical(nullptr, CPN_STR_APP_NAME, QCoreApplication::translate("Companion", "The saved settings could not be imported, please try again or continue with current settings."), QMessageBox::Ok, 0);
|
||||
}
|
||||
|
||||
void checkSettingsImport(bool force = false)
|
||||
{
|
||||
QString previousVersion;
|
||||
bool found;
|
||||
if (!(found = g.findPreviousVersionSettings(&previousVersion))) {
|
||||
found = QDir(CPN_SETTINGS_BACKUP_DIR).entryList(QStringList({"*.ini"}), QDir::Files).size() > 0;
|
||||
}
|
||||
if (!found && !force)
|
||||
return;
|
||||
|
||||
const QString impFileBtn = QCoreApplication::translate("Companion", "Import from File");
|
||||
const QString impPrevBtn = QCoreApplication::translate("Companion", "Import from v%1").arg(previousVersion);
|
||||
const QString impNoneBtn = QCoreApplication::translate("Companion", "Do not import");
|
||||
|
||||
QString msg;
|
||||
if (previousVersion.isEmpty()) {
|
||||
if (found)
|
||||
msg = QCoreApplication::translate("Companion", "We have found possible Companion settings backup file(s).\nDo you want to import settings from a file?");
|
||||
else
|
||||
msg = QCoreApplication::translate("Companion", "Import settings from a file, or start with current values.");
|
||||
}
|
||||
else {
|
||||
msg = QCoreApplication::translate("Companion", "We have found existing settings for Companion version: %1.\nDo you want to import them?\n\n" \
|
||||
"If you have a settings backup file, you may import that instead.").arg(previousVersion);
|
||||
}
|
||||
|
||||
const int ret = QMessageBox::question(nullptr, CPN_STR_APP_NAME, msg, impNoneBtn, impFileBtn, (previousVersion.isEmpty() ? QString() : impPrevBtn), 0, 0);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
// Import from previous version
|
||||
if (ret == 2) {
|
||||
if (!g.importSettings(previousVersion)) {
|
||||
// very unlikely, but just in case of unexpected error, restart the import
|
||||
importError();
|
||||
checkSettingsImport();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Import from file
|
||||
bool err = false;
|
||||
QString impFile = CPN_SETTINGS_BACKUP_DIR;
|
||||
impFile = QFileDialog::getOpenFileName(nullptr, QCoreApplication::translate("Companion", "Select %1:").arg(CPN_STR_APP_SETTINGS_FILES), impFile, CPN_STR_APP_SETTINGS_FILTER);
|
||||
|
||||
if (!impFile.isEmpty() && QFileInfo(impFile).isReadable()) {
|
||||
QSettings fromSettings(impFile, QSettings::IniFormat);
|
||||
if (g.importSettings(&fromSettings)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
importError();
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
// Restart the import prompt if user cancelled the file select dialog but we do have previous settings, or if we had a file import error.
|
||||
if (err || !previousVersion.isEmpty())
|
||||
checkSettingsImport();
|
||||
}
|
||||
|
||||
void printHelpText()
|
||||
{
|
||||
printf(qPrintable(QString(APP_COMPANION % " v%s\n\n")), VERSION);
|
||||
const char tmpl[] = " %s \t %s\n";
|
||||
printf(tmpl, "--export", QCoreApplication::translate("Companion", "Save application settings to file...").toUtf8().constData());
|
||||
printf(tmpl, "--import", QCoreApplication::translate("Companion", "Load application settings from file or previous version...").toUtf8().constData());
|
||||
printf(tmpl, "--defaults", QCoreApplication::translate("Companion", "Reset ALL application settings to default and remove radio profiles...").toUtf8().constData());
|
||||
printf(tmpl, "--quit ", QCoreApplication::translate("Companion", "Exit before settings initialization and application startup.").toUtf8().constData());
|
||||
printf(tmpl, "--version", QCoreApplication::translate("Companion", "Print version number and exit.").toUtf8().constData());
|
||||
printf(tmpl, "--help|-h", QCoreApplication::translate("Companion", "Print this help text.").toUtf8().constData());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
/* From doc: This attribute must be set before Q(Gui)Application is constructed. */
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName(APP_COMPANION);
|
||||
app.setOrganizationName(COMPANY);
|
||||
app.setOrganizationDomain(COMPANY_DOMAIN);
|
||||
app.setAttribute(Qt::AA_DontShowIconsInMenus, false);
|
||||
|
||||
const QStringList args(QApplication::arguments());
|
||||
|
||||
if (args.contains("--help") || args.contains("-h") || args.contains("/?")) {
|
||||
printHelpText();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (args.contains("--version")) {
|
||||
printf("%s\n", VERSION);
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Q_INIT_RESOURCE(companion);
|
||||
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
||||
CustomDebug::setFilterRules();
|
||||
|
||||
// handle settings export/import/reset via CLI
|
||||
|
||||
bool doExport = args.contains("--export");
|
||||
bool doImport = args.contains("--import");
|
||||
bool doReset = args.contains("--defaults");
|
||||
|
||||
if (doExport)
|
||||
Helpers::exportAppSettings();
|
||||
|
||||
if (doReset) {
|
||||
char ok;
|
||||
printf("%s [Y/N] ", QCoreApplication::translate("Companion", "Reset ALL application settings to default values and remove radio profiles, are you sure?").toUtf8().constData());
|
||||
std::cin >> ok;
|
||||
if (ok != 'Y' && ok != 'y')
|
||||
exit(0);
|
||||
if (!doExport) {
|
||||
printf("%s [Y/N] ", QCoreApplication::translate("Companion", "Would you like to perform a backup first?").toUtf8().constData());
|
||||
std::cin >> ok;
|
||||
if (ok == 'Y' || ok == 'y')
|
||||
Helpers::exportAppSettings();
|
||||
}
|
||||
g.resetAllSettings();
|
||||
g.storeAllSettings();
|
||||
std::cout << QCoreApplication::translate("Companion", "Application settings were reset and saved.").toUtf8().constData() << std::endl;
|
||||
}
|
||||
|
||||
if (doImport)
|
||||
checkSettingsImport(true);
|
||||
|
||||
// give option to quit before settings init
|
||||
if (args.contains("--quit"))
|
||||
exit(0);
|
||||
|
||||
// end CLI handling
|
||||
|
||||
if (!doImport && g.isFirstUse())
|
||||
checkSettingsImport(false);
|
||||
|
||||
g.init();
|
||||
|
||||
QFile dbgLog;
|
||||
if (AppDebugMessageHandler::instance() && g.appDebugLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
|
||||
QString fn = g.appLogsDir() % "/CompanionDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
|
||||
dbgLog.setFileName(fn);
|
||||
if (dbgLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
AppDebugMessageHandler::instance()->addOutputDevice(&dbgLog);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
app.setStyle(new MyProxyStyle);
|
||||
#endif
|
||||
|
||||
Translations::installTranslators();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
sdlFlags |= SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
#ifdef SIMU_AUDIO
|
||||
sdlFlags |= SDL_INIT_AUDIO;
|
||||
#endif
|
||||
if (SDL_Init(sdlFlags) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
registerStorageFactories();
|
||||
registerOpenTxFirmwares();
|
||||
SimulatorLoader::registerSimulators();
|
||||
|
||||
Profile & profile = g.currentProfile();
|
||||
if (profile.fwType().isEmpty()){
|
||||
profile.fwType(Firmware::getDefaultVariant()->getId());
|
||||
profile.fwName("");
|
||||
}
|
||||
|
||||
QString splashScreen;
|
||||
splashScreen = ":/images/splash.png";
|
||||
|
||||
QPixmap pixmap = QPixmap(splashScreen);
|
||||
QSplashScreen *splash = new QSplashScreen(pixmap);
|
||||
|
||||
Firmware::setCurrentVariant(Firmware::getFirmwareForId(g.profile[g.id()].fwType()));
|
||||
|
||||
MainWindow *mainWin = new MainWindow();
|
||||
if (g.showSplash()) {
|
||||
splash->show();
|
||||
QTimer::singleShot(1000*SPLASH_TIME, splash, SLOT(close()));
|
||||
QTimer::singleShot(1000*SPLASH_TIME, mainWin, SLOT(show()));
|
||||
}
|
||||
else {
|
||||
mainWin->show();
|
||||
}
|
||||
|
||||
int result = app.exec();
|
||||
|
||||
delete splash;
|
||||
delete mainWin;
|
||||
|
||||
SimulatorLoader::unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterStorageFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
qDebug() << "COMPANION EXIT" << result;
|
||||
|
||||
if (dbgLog.isOpen()) {
|
||||
AppDebugMessageHandler::instance()->removeOutputDevice(&dbgLog);
|
||||
dbgLog.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Encoding=UTF-8
|
||||
Name=Companion @VERSION@
|
||||
GenericName=Transmitter Companion App
|
||||
Comment=The Ultimate Transmitter Companion
|
||||
Icon=@COMPANION_NAME@
|
||||
Exec='@COMPANION_NAME@'
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
Categories=Application
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "comparedialog.h"
|
||||
#include "ui_comparedialog.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "modelslist.h"
|
||||
#include "styleeditdialog.h"
|
||||
#include <QPrinter>
|
||||
#include <QPrintDialog>
|
||||
|
||||
//class DragDropHeader {
|
||||
// public:
|
||||
// DragDropHeader():
|
||||
// general_settings(false),
|
||||
// models_count(0)
|
||||
// {
|
||||
// }
|
||||
// bool general_settings;
|
||||
// uint8_t models_count;
|
||||
// uint8_t models[CPN_MAX_MODELS];
|
||||
//};
|
||||
|
||||
CompareDialog::CompareDialog(QWidget * parent, Firmware * firmware):
|
||||
QDialog(parent, Qt::Window),
|
||||
multimodelprinter(new MultiModelPrinter(firmware)),
|
||||
ui(new Ui::CompareDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("compare.png"));
|
||||
setAcceptDrops(true);
|
||||
if (!g.compareWinGeo().isEmpty()) {
|
||||
restoreGeometry(g.compareWinGeo());
|
||||
}
|
||||
}
|
||||
|
||||
CompareDialog::~CompareDialog()
|
||||
{
|
||||
delete multimodelprinter;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CompareDialog::dragMoveEvent(QDragMoveEvent * event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat("application/x-companion-modeldata")) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::dragEnterEvent(QDragEnterEvent * event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat("application/x-companion-modeldata")) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::dragLeaveEvent(QDragLeaveEvent * event)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
|
||||
bool CompareDialog::handleMimeData(const QMimeData * mimeData)
|
||||
{
|
||||
QVector<ModelData> mList;
|
||||
GeneralSettings gs;
|
||||
if (!TreeModel::decodeMimeData(mimeData, &mList, &gs) || mList.isEmpty())
|
||||
return false;
|
||||
for (int i=0; i < mList.size(); ++i) {
|
||||
GMData data;
|
||||
data.model = mList[i];
|
||||
data.gs = gs;
|
||||
modelsList.append(data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompareDialog::closeEvent(QCloseEvent * event)
|
||||
{
|
||||
g.compareWinGeo(saveGeometry());
|
||||
}
|
||||
|
||||
void CompareDialog::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (handleMimeData(event->mimeData())) {
|
||||
event->accept();
|
||||
compare();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::compare()
|
||||
{
|
||||
QLayoutItem *child;
|
||||
while ((child = ui->layout_modelNames->takeAt(0))) {
|
||||
if (child->widget())
|
||||
delete child->widget();
|
||||
delete child;
|
||||
}
|
||||
|
||||
multimodelprinter->clearModels();
|
||||
ui->textEdit->clear();
|
||||
|
||||
for (int i=0; i < modelsList.size(); ++i) {
|
||||
multimodelprinter->setModel(i, &modelsList[i].model, &modelsList[i].gs);
|
||||
QString name(modelsList.at(i).model.name);
|
||||
if (name.isEmpty())
|
||||
name = tr("Unnamed Model %1").arg(i+1);
|
||||
|
||||
QWidget * hdr = new QWidget(this);
|
||||
hdr->setLayout(new QHBoxLayout());
|
||||
hdr->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
hdr->layout()->setSpacing(2);
|
||||
QToolButton * btn = new QToolButton(hdr);
|
||||
btn->setIcon(CompanionIcon("clear.png"));
|
||||
btn->setProperty("index", i);
|
||||
btn->setFixedSize(18, 18);
|
||||
btn->setToolTip(tr("Click to remove this model."));
|
||||
hdr->layout()->addWidget(btn);
|
||||
QLabel * lbl = new QLabel(name, this);
|
||||
lbl->setStyleSheet("font-weight: bold;");
|
||||
hdr->layout()->addWidget(lbl);
|
||||
connect(btn, &QToolButton::clicked, this, &CompareDialog::removeModelBtnClicked);
|
||||
|
||||
ui->layout_modelNames->addWidget(hdr);
|
||||
}
|
||||
if (modelsList.size())
|
||||
ui->textEdit->setHtml(multimodelprinter->print(ui->textEdit->document()));
|
||||
}
|
||||
|
||||
void CompareDialog::removeModel(int idx)
|
||||
{
|
||||
if (idx < modelsList.size()) {
|
||||
modelsList.remove(idx);
|
||||
compare();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::removeModelBtnClicked()
|
||||
{
|
||||
if (sender() && sender()->property("index").isValid())
|
||||
removeModel(sender()->property("index").toInt());
|
||||
}
|
||||
|
||||
void CompareDialog::on_printButton_clicked()
|
||||
{
|
||||
QPrinter printer;
|
||||
printer.setPageMargins(10.0, 10.0, 10.0, 10.0, printer.Millimeter);
|
||||
QPrintDialog * dialog = new QPrintDialog(&printer, this);
|
||||
dialog->setWindowTitle(tr("Print Document"));
|
||||
if (dialog->exec() != QDialog::Accepted)
|
||||
return;
|
||||
ui->textEdit->print(&printer);
|
||||
}
|
||||
|
||||
void CompareDialog::on_printFileButton_clicked()
|
||||
{
|
||||
QPrinter printer;
|
||||
QString filename = QFileDialog::getSaveFileName(this, tr("Select PDF output file"), QString(), "Pdf File(*.pdf)");
|
||||
printer.setPageMargins(10.0, 10.0, 10.0, 10.0, printer.Millimeter);
|
||||
printer.setOutputFormat(QPrinter::PdfFormat);
|
||||
printer.setOrientation(QPrinter::Landscape);
|
||||
printer.setColorMode(QPrinter::Color);
|
||||
if (!filename.isEmpty()) {
|
||||
if (QFileInfo(filename).suffix().isEmpty())
|
||||
filename.append(".pdf");
|
||||
printer.setOutputFileName(filename);
|
||||
ui->textEdit->print(&printer);
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::on_styleButton_clicked()
|
||||
{
|
||||
StyleEditDialog *g = new StyleEditDialog(this, MODEL_PRINT_CSS);
|
||||
if (g->exec() == QDialog::Accepted)
|
||||
compare();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _COMPAREDIALOG_H_
|
||||
#define _COMPAREDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "multimodelprinter.h"
|
||||
|
||||
namespace Ui {
|
||||
class CompareDialog;
|
||||
}
|
||||
|
||||
class CompareDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CompareDialog(QWidget *parent, Firmware * firmware);
|
||||
~CompareDialog();
|
||||
|
||||
protected:
|
||||
struct GMData {
|
||||
ModelData model;
|
||||
GeneralSettings gs;
|
||||
};
|
||||
|
||||
MultiModelPrinter * multimodelprinter;
|
||||
QVector<GMData> modelsList;
|
||||
QMap<int, GMData> modelsMap;
|
||||
Ui::CompareDialog * ui;
|
||||
|
||||
protected slots:
|
||||
void removeModelBtnClicked();
|
||||
void on_printButton_clicked();
|
||||
void on_printFileButton_clicked();
|
||||
void on_styleButton_clicked();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent * event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
bool handleMimeData(const QMimeData * mimeData);
|
||||
void compare();
|
||||
void removeModel(int idx);
|
||||
};
|
||||
|
||||
#endif // _COMPAREDIALOG_H_
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CompareDialog</class>
|
||||
<widget class="QDialog" name="CompareDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>580</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>780</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Compare Models</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>To compare models, drag and drop them anywhere in this window.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="styleButton">
|
||||
<property name="text">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="printButton">
|
||||
<property name="text">
|
||||
<string>Print</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="printFileButton">
|
||||
<property name="text">
|
||||
<string>Print to file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="layout_modelNames">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>CompareDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>739</x>
|
||||
<y>636</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>565</x>
|
||||
<y>623</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CONSTANTS_H_
|
||||
#define _CONSTANTS_H_
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#define CPN_MAX_MODELS 60
|
||||
#define CPN_MAX_TIMERS 3
|
||||
#define CPN_MAX_FLIGHT_MODES 9
|
||||
#define CPN_MAX_MIXERS 64
|
||||
#define CPN_MAX_INPUTS 32
|
||||
#define CPN_MAX_EXPOS 64
|
||||
#define CPN_MAX_CURVES 32
|
||||
#define CPN_MAX_POINTS 17
|
||||
#define CPN_MAX_GVARS 9
|
||||
#define CPN_MAX_ENCODERS 2 // rotary encoders
|
||||
#define CPN_MAX_CHNOUT 32 // number of real output channels
|
||||
#define CPN_MAX_LOGICAL_SWITCHES 64 // number of custom switches
|
||||
#define CPN_MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
|
||||
#define CPN_MAX_MODULES 2
|
||||
#define CPN_MAX_STICKS Board::STICK_AXIS_COUNT
|
||||
#define CPN_MAX_TRIMS Board::TRIM_AXIS_COUNT
|
||||
#define CPN_MAX_TRIM_SW Board::TRIM_SW_COUNT
|
||||
#define CPN_MAX_KNOBS 4
|
||||
#define CPN_MAX_SLIDERS 4
|
||||
#define CPN_MAX_POTS (CPN_MAX_KNOBS + CPN_MAX_SLIDERS)
|
||||
#define CPN_MAX_CYC 3
|
||||
#define CPN_MAX_SWITCHES 32
|
||||
#define CPN_MAX_KEYS 32
|
||||
#define CPN_MAX_MOUSE_ANALOGS 2
|
||||
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_MOUSE_ANALOGS)
|
||||
|
||||
#define CPN_STR_APP_NAME QCoreApplication::translate("Companion", "OpenTX Companion")
|
||||
#define CPN_STR_TTL_INFO QCoreApplication::translate("Companion", "Information") // shared Title Case words, eg. for a window title or section heading
|
||||
#define CPN_STR_TTL_WARNING QCoreApplication::translate("Companion", "Warning")
|
||||
#define CPN_STR_TTL_ERROR QCoreApplication::translate("Companion", "Error")
|
||||
#define CPN_STR_TTL_CONFIRM QCoreApplication::translate("Companion", "Please Confirm")
|
||||
|
||||
#define CPN_STR_FILES QCoreApplication::translate("Companion", "files")
|
||||
#define CPN_STR_RAD_MOD_SETTINGS QCoreApplication::translate("Companion", "Radio and Models settings")
|
||||
#define HEX_FILES_FILTER "HEX " % CPN_STR_FILES % " (*.hex);;"
|
||||
#define BIN_FILES_FILTER "BIN " % CPN_STR_FILES % " (*.bin);;"
|
||||
#define DFU_FILES_FILTER "DFU " % CPN_STR_FILES % " (*.dfu);;"
|
||||
#define EEPE_FILES_FILTER "EEPE " % CPN_STR_FILES % " (*.eepe);;"
|
||||
#define OTX_FILES_FILTER "OpenTX " % CPN_STR_FILES % " (*.otx);;"
|
||||
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.otx *.eepe *.bin *.hex);;" % OTX_FILES_FILTER % EEPE_FILES_FILTER % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define FLASH_FILES_FILTER "FLASH " % CPN_STR_FILES % " (*.bin *.hex *.dfu);;" % BIN_FILES_FILTER % HEX_FILES_FILTER % DFU_FILES_FILTER
|
||||
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " % CPN_STR_FILES % " (*.bin *.hex);;" % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
|
||||
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
|
||||
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
|
||||
|
||||
#define CPN_STR_APP_SETTINGS QCoreApplication::translate("Companion", "Application Settings")
|
||||
#define CPN_STR_APP_SETTINGS_FILES CPN_STR_APP_SETTINGS % " " % CPN_STR_FILES
|
||||
#define CPN_STR_APP_SETTINGS_FILTER CPN_STR_APP_SETTINGS_FILES % " (*.ini)"
|
||||
|
||||
#define CPN_STR_UNKNOWN_ITEM "???"
|
||||
|
||||
#define CPN_STR_SW_INDICATOR_UP QCoreApplication::translate("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_DN QCoreApplication::translate("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_NEUT QCoreApplication::translate("RawSwitch", "-") // Switch neutral (middle) position indicator.
|
||||
#define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
|
||||
|
||||
#endif // _CONSTANTS_H_
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "creditsdialog.h"
|
||||
#include "ui_htmldialog.h"
|
||||
#include "helpers.h"
|
||||
#include <QFile>
|
||||
|
||||
CreditsDialog::CreditsDialog(QWidget * parent):
|
||||
QDialog(parent),
|
||||
ui(new Ui::HtmlDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(tr("OpenTX Contributors"));
|
||||
setWindowIcon(CompanionIcon("contributors.png"));
|
||||
|
||||
QString str = "<html>" \
|
||||
"<head>" \
|
||||
" <style type=\"text/css\">" \
|
||||
" .normal { font-weight:normal;color:#000000;vertical-align:top;font-size:10px;text-align:left;font-family:arial,helvetica,sans-serif; }" \
|
||||
" .bold { font-weight:bold;color:#C00000;vertical-align:top;font-size:10px;text-align:left;font-family:arial,helvetica,sans-serif; }" \
|
||||
" .title { font-weight:bold;color:#000000;font-size:14px;text-align:left;font-family:arial,helvetica,sans-serif; }" \
|
||||
" </style>" \
|
||||
"</head>"
|
||||
"<body class=\"normal\">";
|
||||
|
||||
foreach(CreditsSection section, readCredits()) {
|
||||
str.append(formatTable(sectionTitle(section.title), section.names, 3));
|
||||
}
|
||||
|
||||
str.append("<table><tr><td class=\"normal\"> </td></tr>" \
|
||||
" <tr><td class=\"normal\">" + tr("Honors go to Rafal Tomczak (RadioClone), Thomas Husterer (th9x) and Erez Raviv (er9x and eePe)") + "<br/></td></tr>" \
|
||||
"</table>");
|
||||
|
||||
#if 0
|
||||
QFile blacklist(":/BLACKLIST.txt");
|
||||
if (blacklist.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
names << blacklist.readAll();
|
||||
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
str.append("</body></html>");
|
||||
ui->textEditor->setHtml(str);
|
||||
ui->textEditor->scroll(0, 0);
|
||||
ui->textEditor->setOpenExternalLinks(true);
|
||||
}
|
||||
|
||||
CreditsDialog::~CreditsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QList<CreditsDialog::CreditsSection> CreditsDialog::readCredits()
|
||||
{
|
||||
QFile credits(":/CREDITS.txt");
|
||||
QList<CreditsSection> result;
|
||||
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine().trimmed();
|
||||
if (line.size() >= 2) {
|
||||
if (line.startsWith("[") && line.endsWith("]")) {
|
||||
result.push_back(CreditsSection(line.mid(1, line.size() - 2)));
|
||||
} else {
|
||||
result.back().addName(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CreditsDialog::sectionTitle(const QString & title)
|
||||
{
|
||||
if (title == "Main developers")
|
||||
return tr("Main developers");
|
||||
else if (title == "Translators")
|
||||
return tr("Translators");
|
||||
else if (title == "Companies and projects who have donated to OpenTX")
|
||||
return tr("Companies and projects who have donated to OpenTX");
|
||||
else if (title == "People who have donated to OpenTX")
|
||||
return tr("People who have donated to OpenTX");
|
||||
else
|
||||
return tr("Other contributors");
|
||||
}
|
||||
|
||||
QString CreditsDialog::formatTable(const QString & title, const QStringList & names, int columns)
|
||||
{
|
||||
const float cwidth = 100.0 / columns;
|
||||
QString str = "<table width=\"100%\" border=0 cellspacing=0 cellpadding=2>" \
|
||||
" <tr><td class=\"normal\"> </td></tr>" \
|
||||
" <tr><td class=\"title\">" + title + "</td></tr>" \
|
||||
"</table>";
|
||||
|
||||
str.append("<table width=\"100%\" border=0 cellspacing=0 cellpadding=2>");
|
||||
|
||||
int column = 0;
|
||||
foreach(QString name, names) {
|
||||
if (column == 0) {
|
||||
str.append("<tr>");
|
||||
}
|
||||
QString trclass = name.contains("monthly") ? "bold" : "normal";
|
||||
str.append(QString("<td width=\"%1%\" class=\"%2\">%3</td>").arg(cwidth).arg(trclass).arg(name.trimmed().replace("monthly", tr("monthly"))));
|
||||
if (++column == columns) {
|
||||
str.append("</tr>");
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (column != 0) {
|
||||
str.append("</tr>");
|
||||
}
|
||||
|
||||
str.append("</table>");
|
||||
return str;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CREDITSDIALOG_H_
|
||||
#define _CREDITSDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class HtmlDialog;
|
||||
}
|
||||
|
||||
class CreditsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class CreditsSection
|
||||
{
|
||||
public:
|
||||
CreditsSection(const QString & title):
|
||||
title(title)
|
||||
{
|
||||
}
|
||||
|
||||
void addName(const QString & name)
|
||||
{
|
||||
names.push_back(name);
|
||||
}
|
||||
|
||||
QString title;
|
||||
QStringList names;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit CreditsDialog(QWidget * parent = 0);
|
||||
~CreditsDialog();
|
||||
|
||||
private:
|
||||
Ui::HtmlDialog * ui;
|
||||
QList<CreditsSection> readCredits();
|
||||
QString sectionTitle(const QString & title);
|
||||
QString formatTable(const QString & title, const QStringList & names, int colums);
|
||||
};
|
||||
|
||||
#endif // _CREDITSDIALOG_H_
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customdebug.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(eepromImport, "eeprom.import")
|
||||
|
||||
Q_LOGGING_CATEGORY(simulatorInterfaceLoader, "simulator.interface.loader")
|
||||
|
||||
void CustomDebug::setFilterRules()
|
||||
{
|
||||
QString rules;
|
||||
rules.append("eeprom.import=");
|
||||
#if defined(DEBUG_STORAGE_IMPORT)
|
||||
rules.append("true\n");
|
||||
#else
|
||||
rules.append("false\n");
|
||||
#endif
|
||||
|
||||
rules.append("simulator.interface.*=true\n");
|
||||
|
||||
QLoggingCategory::setFilterRules(rules);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CUSTOMDEBUG_H_
|
||||
#define _CUSTOMDEBUG_H_
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
// Controls the generation of debug output for EEPROM import
|
||||
Q_DECLARE_LOGGING_CATEGORY(eepromImport) // "eeprom.import"
|
||||
|
||||
// Controls the generation of debug output of SimulatorLoader class
|
||||
Q_DECLARE_LOGGING_CATEGORY(simulatorInterfaceLoader) // "simulator.interface.loader"
|
||||
|
||||
class CustomDebug
|
||||
{
|
||||
public:
|
||||
static void setFilterRules();
|
||||
};
|
||||
|
||||
#endif // _CUSTOMDEBUG_H_
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customizesplashdialog.h"
|
||||
#include "ui_customizesplashdialog.h"
|
||||
#include "flashfirmwaredialog.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "firmwareinterface.h"
|
||||
#include "splashlibrarydialog.h"
|
||||
|
||||
//*** Side Class ***
|
||||
|
||||
Side::Side(){
|
||||
imageLabel = 0;
|
||||
fileNameEdit = 0;
|
||||
saveButton = 0;
|
||||
loadFwButton=0;
|
||||
loadPictButton = 0;
|
||||
loadProfileButton = 0;
|
||||
saveToFileName = new QString("");
|
||||
source = new Source(UNDEFINED);
|
||||
format = new LCDFormat(LCDTARANIS);
|
||||
}
|
||||
|
||||
void Side::markSourceButton()
|
||||
{
|
||||
loadFwButton->setChecked(*source == FW ? true : false );
|
||||
loadPictButton->setChecked(*source == PICT ? true : false );
|
||||
loadProfileButton->setChecked(*source == PROFILE ? true : false );
|
||||
}
|
||||
|
||||
void Side::copyImage( Side side )
|
||||
{
|
||||
if ((*source!=UNDEFINED) && (*side.source!=UNDEFINED))
|
||||
imageLabel->setPixmap(*side.imageLabel->pixmap());
|
||||
}
|
||||
|
||||
bool Side::displayImage(QString fileName, Source pictSource)
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
|
||||
// Determine which picture format to use
|
||||
if (pictSource == FW) {
|
||||
FirmwareInterface firmware(fileName);
|
||||
if (!firmware.hasSplash())
|
||||
return false;
|
||||
else
|
||||
image = firmware.getSplash();
|
||||
*format = (firmware.getSplashWidth()==WIDTH_TARANIS ? LCDTARANIS : LCD9X);
|
||||
}
|
||||
else {
|
||||
image.load(fileName);
|
||||
if (pictSource== PICT)
|
||||
*format = image.width()>WIDTH_9X ? LCDTARANIS : LCD9X;
|
||||
else if (pictSource == PROFILE)
|
||||
*format = (g.profile[g.id()].fwType().contains("x9")) ? LCDTARANIS : LCD9X;
|
||||
}
|
||||
|
||||
if (image.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load image
|
||||
QPixmap pixmap = makePixMap(image);
|
||||
imageLabel->setPixmap(pixmap);
|
||||
imageLabel->setFixedSize(pixmap.width()*2, pixmap.height()*2);
|
||||
|
||||
switch (pictSource) {
|
||||
case FW:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("FW: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source = FW;
|
||||
break;
|
||||
case PICT:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("Pict: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source = PICT;
|
||||
break;
|
||||
case PROFILE:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("Profile image"));
|
||||
*saveToFileName = fileName;
|
||||
*source = PROFILE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
saveButton->setEnabled(true);
|
||||
libraryButton->setEnabled(true);
|
||||
invertButton->setEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Side::refreshImage()
|
||||
{
|
||||
return displayImage( *saveToFileName, *source );
|
||||
}
|
||||
|
||||
bool Side::saveImage()
|
||||
{
|
||||
if (*source == FW )
|
||||
{
|
||||
FirmwareInterface firmware(*saveToFileName);
|
||||
if (!firmware.hasSplash()) {
|
||||
return false;
|
||||
}
|
||||
QImage image = imageLabel->pixmap()->toImage().scaled(firmware.getSplashWidth(), firmware.getSplashHeight());
|
||||
if (firmware.setSplash(image) && (firmware.save(*saveToFileName) > 0)) {
|
||||
g.flashDir( QFileInfo(*saveToFileName).dir().absolutePath() );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (*source == PICT) {
|
||||
QImage image = imageLabel->pixmap()->toImage().scaled(imageLabel->width()/2, imageLabel->height()/2).convertToFormat(QImage::Format_Indexed8);
|
||||
if (image.save(*saveToFileName)) {
|
||||
g.imagesDir( QFileInfo(*saveToFileName).dir().absolutePath() );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (*source == PROFILE) {
|
||||
QImage image = imageLabel->pixmap()->toImage().scaled(imageLabel->width()/2, imageLabel->height()/2).convertToFormat(QImage::Format_Indexed8);
|
||||
if (!image.save(*saveToFileName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CustomizeSplashDialog::CustomizeSplashDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CustomizeSplashDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("paintbrush.png"));
|
||||
ui->leftLibraryButton->setIcon(CompanionIcon("library.png"));
|
||||
ui->rightLibraryButton->setIcon(CompanionIcon("library.png"));
|
||||
|
||||
left.imageLabel = ui->leftImageLabel;
|
||||
right.imageLabel = ui->rightImageLabel;
|
||||
left.fileNameEdit = ui->leftFileNameEdit;
|
||||
right.fileNameEdit = ui->rightFileNameEdit;
|
||||
left.saveButton = ui->leftSaveButton;
|
||||
right.saveButton = ui->rightSaveButton;
|
||||
left.libraryButton = ui->leftLibraryButton;
|
||||
right.libraryButton = ui->rightLibraryButton;
|
||||
left.invertButton = ui->leftInvertButton;
|
||||
right.invertButton = ui->rightInvertButton;
|
||||
|
||||
left.loadFwButton = ui->leftLoadFwButton;
|
||||
right.loadFwButton = ui->rightLoadFwButton;
|
||||
left.loadPictButton = ui->leftLoadPictButton;
|
||||
right.loadPictButton = ui->rightLoadPictButton;
|
||||
left.loadProfileButton = ui->leftLoadProfileButton;
|
||||
right.loadProfileButton = ui->rightLoadProfileButton;
|
||||
|
||||
loadProfile(left);
|
||||
left.markSourceButton();
|
||||
|
||||
resize(0,0);
|
||||
}
|
||||
|
||||
CustomizeSplashDialog::~CustomizeSplashDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_copyRightToLeftButton_clicked() {
|
||||
left.copyImage(right);
|
||||
}
|
||||
void CustomizeSplashDialog::on_copyLeftToRightButton_clicked() {
|
||||
right.copyImage(left);
|
||||
}
|
||||
|
||||
|
||||
void CustomizeSplashDialog::on_leftLoadFwButton_clicked() {loadFirmware(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadFwButton_clicked() {loadFirmware(right);}
|
||||
void CustomizeSplashDialog::loadFirmware(Side side)
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Firmware File"), g.flashDir(), FLASH_FILES_FILTER);
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, FW ))
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Can not load embedded image from firmware file %1.").arg(fileName));
|
||||
else
|
||||
g.flashDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_leftLoadPictButton_clicked() {loadPicture(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadPictButton_clicked() {loadPicture(right);}
|
||||
void CustomizeSplashDialog::loadPicture(Side side)
|
||||
{
|
||||
QString supportedImageFormats;
|
||||
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
|
||||
supportedImageFormats += QLatin1String(" *.") + QImageReader::supportedImageFormats()[formatIndex];
|
||||
}
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Image to load"), g.imagesDir(), tr("Images (%1)").arg(supportedImageFormats));
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, PICT ))
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load the image file %1.").arg(fileName));
|
||||
else
|
||||
g.imagesDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
|
||||
void CustomizeSplashDialog::loadProfile(Side side)
|
||||
{
|
||||
QString fileName=g.profile[g.id()].splashFile();
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, PROFILE ))
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load profile image %1.").arg(fileName));
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicked(right);}
|
||||
void CustomizeSplashDialog::libraryButton_clicked( Side side )
|
||||
{
|
||||
QString fileName;
|
||||
SplashLibraryDialog *ld = new SplashLibraryDialog(this,&fileName);
|
||||
ld->exec();
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, UNDEFINED ))
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load the library image %1.").arg(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
|
||||
void CustomizeSplashDialog::saveButton_clicked( Side side )
|
||||
{
|
||||
if (side.saveImage()){
|
||||
QMessageBox::information(this, tr("File Saved"), tr("The image was saved to the file %1").arg(*side.saveToFileName));
|
||||
if ( !side.refreshImage()){
|
||||
QMessageBox::critical(this, tr("Image Refresh Error"), tr("Failed to refresh image from file %1").arg(*side.saveToFileName));
|
||||
}
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(this, tr("File Save Error"), tr("Failed to write image to %1").arg(*side.saveToFileName));
|
||||
}
|
||||
|
||||
void CustomizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightInvertButton_clicked(){invertButton_clicked(right);}
|
||||
void CustomizeSplashDialog::invertButton_clicked(Side side)
|
||||
{
|
||||
QImage image = side.imageLabel->pixmap()->toImage();
|
||||
image.invertPixels();
|
||||
side.imageLabel->setPixmap(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CUSTOMIZESPLASHDIALOG_H_
|
||||
#define _CUSTOMIZESPLASHDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "firmwareinterface.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomizeSplashDialog;
|
||||
}
|
||||
|
||||
const int WIDTH_TARANIS = 212;
|
||||
const int HEIGHT_TARANIS = 64;
|
||||
const int WIDTH_9X = 128;
|
||||
const int HEIGHT_9X = 64;
|
||||
|
||||
enum Source {FW, PICT, PROFILE, UNDEFINED};
|
||||
enum LCDFormat {LCD9X, LCDTARANIS};
|
||||
|
||||
class Side
|
||||
{
|
||||
public:
|
||||
Side();
|
||||
void markSourceButton();
|
||||
void copyImage( Side );
|
||||
bool displayImage( QString fileName, Source source );
|
||||
bool saveImage();
|
||||
bool refreshImage();
|
||||
|
||||
QLabel *imageLabel;
|
||||
QLineEdit *fileNameEdit;
|
||||
QPushButton *saveButton;
|
||||
QPushButton *invertButton;
|
||||
QToolButton *libraryButton;
|
||||
QPushButton *loadFwButton;
|
||||
QPushButton *loadPictButton;
|
||||
QPushButton *loadProfileButton;
|
||||
|
||||
QString *saveToFileName;
|
||||
|
||||
private:
|
||||
Source *source;
|
||||
LCDFormat *format;
|
||||
};
|
||||
|
||||
class CustomizeSplashDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Side left;
|
||||
Side right;
|
||||
|
||||
public:
|
||||
explicit CustomizeSplashDialog(QWidget *parent = 0);
|
||||
~CustomizeSplashDialog();
|
||||
|
||||
private slots:
|
||||
void on_leftLoadFwButton_clicked();
|
||||
void on_leftLoadPictButton_clicked();
|
||||
void on_leftLoadProfileButton_clicked();
|
||||
void on_leftLibraryButton_clicked();
|
||||
void on_leftSaveButton_clicked();
|
||||
void on_leftInvertButton_clicked();
|
||||
|
||||
void on_rightLoadFwButton_clicked();
|
||||
void on_rightLoadPictButton_clicked();
|
||||
void on_rightLoadProfileButton_clicked();
|
||||
void on_rightLibraryButton_clicked();
|
||||
void on_rightSaveButton_clicked();
|
||||
void on_rightInvertButton_clicked();
|
||||
|
||||
void on_copyRightToLeftButton_clicked();
|
||||
void on_copyLeftToRightButton_clicked();
|
||||
|
||||
private:
|
||||
void loadFirmware( Side );
|
||||
void loadPicture( Side );
|
||||
void loadProfile( Side );
|
||||
void libraryButton_clicked( Side );
|
||||
void saveButton_clicked( Side );
|
||||
void invertButton_clicked( Side );
|
||||
|
||||
Ui::CustomizeSplashDialog *ui;
|
||||
enum sideEnum { LEFT, RIGHT };
|
||||
};
|
||||
|
||||
#endif // _CUSTOMIZESPLASHDIALOG_H_
|
||||
@@ -1,667 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomizeSplashDialog</class>
|
||||
<widget class="QDialog" name="CustomizeSplashDialog">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1087</width>
|
||||
<height>298</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Transmitter Splash Screen Editor</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="Line" name="line_13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leftFileNameEdit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>426</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_12">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="leftImageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="leftInvertButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invert</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="leftLibraryButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Open Splash Library</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="leftLoadProfileButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Profile</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="leftLoadFwButton">
|
||||
<property name="text">
|
||||
<string>Load FW</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="leftLoadPictButton">
|
||||
<property name="text">
|
||||
<string>Load Pict</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="leftSaveButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QToolButton" name="copyRightToLeftButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::LeftArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="copyLeftToRightButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::RightArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="Line" name="line_14">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="rightFileNameEdit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>426</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_12">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rightImageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>424</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QPushButton" name="rightInvertButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invert</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="rightLibraryButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Open Splash Library</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QPushButton" name="rightLoadProfileButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Profile</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rightLoadFwButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load FW</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rightLoadPictButton">
|
||||
<property name="text">
|
||||
<string>Load Pict</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rightSaveButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>leftFileNameEdit</tabstop>
|
||||
<tabstop>leftInvertButton</tabstop>
|
||||
<tabstop>leftLibraryButton</tabstop>
|
||||
<tabstop>leftLoadProfileButton</tabstop>
|
||||
<tabstop>leftLoadFwButton</tabstop>
|
||||
<tabstop>leftLoadPictButton</tabstop>
|
||||
<tabstop>leftSaveButton</tabstop>
|
||||
<tabstop>copyLeftToRightButton</tabstop>
|
||||
<tabstop>copyRightToLeftButton</tabstop>
|
||||
<tabstop>rightFileNameEdit</tabstop>
|
||||
<tabstop>rightInvertButton</tabstop>
|
||||
<tabstop>rightLibraryButton</tabstop>
|
||||
<tabstop>rightLoadProfileButton</tabstop>
|
||||
<tabstop>rightLoadFwButton</tabstop>
|
||||
<tabstop>rightLoadPictButton</tabstop>
|
||||
<tabstop>rightSaveButton</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="companion.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
set(datamodels_SRCS
|
||||
rawitemdatamodels.cpp
|
||||
rawitemfilteredmodel.cpp
|
||||
)
|
||||
|
||||
set(datamodels_HDRS
|
||||
rawitemdatamodels.h
|
||||
rawitemfilteredmodel.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(datamodels_SRCS ${datamodels_HDRS})
|
||||
|
||||
add_library(datamodels ${datamodels_SRCS} ${datamodels_HDRS})
|
||||
target_link_libraries(datamodels PRIVATE ${CPN_COMMON_LIB})
|
||||
|
||||
target_include_directories(datamodels
|
||||
PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${COMPANION_SRC_DIRECTORY}"
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
)
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemdatamodels.h"
|
||||
#include "generalsettings.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
const int anasCount = CPN_MAX_STICKS + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + board.getCapability(Board::MouseAnalogs);
|
||||
|
||||
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
|
||||
for (int i=0; i < fw->getCapability(LuaScripts); i++)
|
||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
|
||||
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, anasCount);
|
||||
addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->getCapability(RotaryEncoders));
|
||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board.getCapability(Board::NumTrims));
|
||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board.getCapability(Board::Switches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
|
||||
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
|
||||
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
|
||||
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3);
|
||||
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
|
||||
}
|
||||
|
||||
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
item->setText(src.toString(modelData, generalSettings, board));
|
||||
item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
|
||||
{
|
||||
for (int i = start; i < start + count; i++) {
|
||||
const RawSource src = RawSource(type, i);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(src.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(group, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, src);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSourceItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// RawSwitchItemModel
|
||||
//
|
||||
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, -fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_TRIM, -board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board.getCapability(Board::SwitchPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_TIMER_MODE, 5);
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board.getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
||||
addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_ON, 1);
|
||||
addItems(SWITCH_TYPE_ONE, 1);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
|
||||
{
|
||||
const Board::Type board = getCurrentBoard();
|
||||
item->setText(rsw.toString(board, generalSettings, modelData));
|
||||
item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
// handle exceptions in RawSwitch() index values
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
// determine cotext flags
|
||||
int context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
context &= ~RawSwitch::MixesContext;
|
||||
// fallthrough
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
context &= ~RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
context = RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
context &= ~RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
case SWITCH_TYPE_ONE:
|
||||
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(rs.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(context, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, rs);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMDATAMODELS_H
|
||||
#define RAWITEMDATAMODELS_H
|
||||
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
|
||||
class AbstractRawItemDataModel: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
|
||||
Q_ENUM(DataRoles)
|
||||
|
||||
explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
QStandardItemModel(parent),
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData)
|
||||
{}
|
||||
|
||||
public slots:
|
||||
virtual void update() const = 0;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
};
|
||||
|
||||
|
||||
class RawSourceItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
|
||||
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
|
||||
};
|
||||
|
||||
|
||||
class RawSwitchItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
|
||||
void addItems(const RawSwitchType & type, int count);
|
||||
};
|
||||
|
||||
|
||||
#endif // RAWITEMDATAMODELS_H
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemfilteredmodel.h"
|
||||
#include "rawitemdatamodels.h"
|
||||
|
||||
RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
|
||||
QSortFilterProxyModel(parent),
|
||||
filterFlags(0)
|
||||
{
|
||||
setFilterRole(AbstractRawItemDataModel::IsAvailableRole);
|
||||
setFilterKeyColumn(0);
|
||||
setFilterFlags(flags);
|
||||
setDynamicSortFilter(true);
|
||||
setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::setFilterFlags(int flags)
|
||||
{
|
||||
if (filterFlags != flags) {
|
||||
filterFlags = flags;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
||||
{
|
||||
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
|
||||
return false;
|
||||
|
||||
if (!filterFlags)
|
||||
return true;
|
||||
|
||||
bool ok;
|
||||
const int flags = sourceModel()->data(srcIdx, AbstractRawItemDataModel::ItemFlagsRole).toInt(&ok);
|
||||
return (ok && (!flags || (filterFlags & flags)));
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::update() const
|
||||
{
|
||||
AbstractRawItemDataModel * model = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
|
||||
if (model)
|
||||
model->update();
|
||||
}
|
||||
|
||||
|
||||
RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent)
|
||||
{
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMFILTEREDMODEL_H
|
||||
#define RAWITEMFILTEREDMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
class RawSourceItemModel;
|
||||
class RawSwitchItemModel;
|
||||
|
||||
class RawItemFilteredModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
|
||||
|
||||
public slots:
|
||||
void setFilterFlags(int flags);
|
||||
void update() const;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
|
||||
|
||||
int filterFlags;
|
||||
};
|
||||
|
||||
|
||||
// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established.
|
||||
// These proxy classes will automatically create a source model of the corresponding type.
|
||||
|
||||
class RawSwitchFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class RawSourceFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr);
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {}
|
||||
};
|
||||
|
||||
#endif // RAWITEMFILTEREDMODEL_H
|
||||
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "filesyncdialog.h"
|
||||
|
||||
#include "autobitsetcheckbox.h"
|
||||
#include "autocheckbox.h"
|
||||
#include "autocombobox.h"
|
||||
#include "autolineedit.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "progresswidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QCompleter>
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QFileSystemModel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QSpinBox>
|
||||
|
||||
FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) :
|
||||
QDialog(parent),
|
||||
m_syncOptions(syncOptions),
|
||||
m_running(false)
|
||||
{
|
||||
setWindowTitle(tr("Synchronize Files"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setSizeGripEnabled(true);
|
||||
|
||||
setupUi();
|
||||
toggleExtraOptions(false);
|
||||
validate();
|
||||
updateRunningState();
|
||||
}
|
||||
|
||||
void FileSyncDialog::reject()
|
||||
{
|
||||
// override close event via window system close or esc. key
|
||||
if (m_running) {
|
||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Are you sure you wish to abort the sync?")) == QMessageBox::No)
|
||||
return;
|
||||
emit stopSync();
|
||||
// Force termination if the sync hasn't finished within 5s
|
||||
QElapsedTimer tim;
|
||||
tim.start();
|
||||
while (!tim.hasExpired(5000) && m_running)
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 10);
|
||||
if (m_running)
|
||||
qWarning() << "Terminating thread while Sync process was still running.";
|
||||
}
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
// Create a widget with a line edit and folder select button and handles all interactions. Features autosuggest
|
||||
// path hints while typing, invalid paths shown in red.
|
||||
// This should probably be moved some place more reusable, esp. the QFileSystemModel.
|
||||
static QWidget * folderSelectorWidget(QLineEdit * le, QWidget * parent)
|
||||
{
|
||||
static QFileSystemModel fileModel;
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
init = true;
|
||||
fileModel.setFilter(QDir::Dirs);
|
||||
fileModel.setRootPath("/");
|
||||
}
|
||||
|
||||
QWidget * fsw = new QWidget(parent);
|
||||
//le = new QLineEdit(parent);
|
||||
QCompleter * fsc = new QCompleter(fsw);
|
||||
fsc->setModel(&fileModel);
|
||||
//fsc->setCompletionMode(QCompleter::InlineCompletion);
|
||||
le->setCompleter(fsc);
|
||||
|
||||
QToolButton * btn = new QToolButton(fsw);
|
||||
btn->setIcon(CompanionIcon("open.png"));
|
||||
QHBoxLayout * l = new QHBoxLayout(fsw);
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
l->setSpacing(3);
|
||||
l->addWidget(le);
|
||||
l->addWidget(btn);
|
||||
|
||||
QObject::connect(btn, &QToolButton::clicked, [=]() {
|
||||
QString dir = QFileDialog::getExistingDirectory(parent, fsw->property("fileDialogTitle").toString(), le->text(), 0);
|
||||
if (!dir.isEmpty()) {
|
||||
le->setText(QDir::toNativeSeparators(dir));
|
||||
le->setFocus();
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(le, &QLineEdit::textChanged, [=](const QString & text) {
|
||||
if (QFile::exists(text))
|
||||
le->setStyleSheet("");
|
||||
else
|
||||
le->setStyleSheet("QLineEdit {color: red;}");
|
||||
});
|
||||
|
||||
return fsw;
|
||||
}
|
||||
|
||||
void FileSyncDialog::setupUi()
|
||||
{
|
||||
const QString srcArw = CPN_STR_SW_INDICATOR_UP % " ";
|
||||
const QString dstArw = CPN_STR_SW_INDICATOR_DN % " ";
|
||||
int row = 0;
|
||||
|
||||
CompanionIcon playIcon("play.png");
|
||||
playIcon.addImage("stop.png", QIcon::Normal, QIcon::On);
|
||||
|
||||
QLabel * lblSrc = new QLabel(tr("Source Folder:"), this);
|
||||
AutoLineEdit * leSrc = new AutoLineEdit(this, true);
|
||||
leSrc->setField(m_syncOptions.folderA);
|
||||
leSrc->setText(QDir::toNativeSeparators(m_syncOptions.folderA));
|
||||
QWidget * wdgSrc = folderSelectorWidget(leSrc, this);
|
||||
|
||||
QLabel * lblDst = new QLabel(tr("Destination Folder:"), this);
|
||||
AutoLineEdit * leDst = new AutoLineEdit(this, true);
|
||||
leDst->setField(m_syncOptions.folderB);
|
||||
leDst->setText(QDir::toNativeSeparators(m_syncOptions.folderB));
|
||||
QWidget * wdgDst = folderSelectorWidget(leDst, this);
|
||||
|
||||
AutoComboBox * syncDir = new AutoComboBox(this);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to destination folder first").arg(dstArw, srcArw), SyncProcess::SYNC_A2B_B2A);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to source folder first").arg(srcArw, dstArw), SyncProcess::SYNC_B2A_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from source folder to destination folder").arg(dstArw), SyncProcess::SYNC_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from destination folder to source folder").arg(srcArw), SyncProcess::SYNC_B2A);
|
||||
syncDir->setCurrentIndex(-1); // we set the default option later
|
||||
|
||||
AutoComboBox * copyMode = new AutoComboBox(this);
|
||||
copyMode->setToolTip(tr("How to handle overwriting files which already exist in the destination folder."));
|
||||
copyMode->addItem(tr("Copy only if newer and different (compare contents)"), SyncProcess::OVERWR_NEWER_IF_DIFF);
|
||||
copyMode->addItem(tr("Copy only if newer (do not compare contents)"), SyncProcess::OVERWR_NEWER_ALWAYS);
|
||||
copyMode->addItem(tr("Copy only if different (ignore file time stamps)"), SyncProcess::OVERWR_IF_DIFF);
|
||||
copyMode->addItem(tr("Always copy (force overwite existing files)"), SyncProcess::OVERWR_ALWAYS);
|
||||
copyMode->setField(m_syncOptions.compareType);
|
||||
|
||||
QSpinBox * maxSize = new QSpinBox(this);
|
||||
maxSize->setRange(0, 100 * 1024);
|
||||
maxSize->setAccelerated(true);
|
||||
maxSize->setSpecialValueText(tr("Any size"));
|
||||
maxSize->setToolTip(tr("Skip files larger than this size. Enter zero for unlimited."));
|
||||
maxSize->setGroupSeparatorShown(true);
|
||||
maxSize->setValue(0); // we set the real default value later
|
||||
|
||||
AutoComboBox * logLevel = new AutoComboBox(this);
|
||||
logLevel->setToolTip(tr("Minimum reporting level. Events of this type and of higher importance are shown.\n" \
|
||||
"WARNING: High log rates may make the user interface temporarily unresponsive."));
|
||||
logLevel->addItem(tr("Skipped"), QtDebugMsg);
|
||||
logLevel->addItem(tr("Created"), QtInfoMsg);
|
||||
logLevel->addItem(tr("Updated"), QtWarningMsg);
|
||||
//logLevel->addItem(tr("Item Deleted"), QtCriticalMsg); // unused
|
||||
logLevel->addItem(tr("Errors Only"), QtFatalMsg);
|
||||
logLevel->setField(m_syncOptions.logLevel);
|
||||
|
||||
AutoBitsetCheckBox * testRun = new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_DRY_RUN, tr("Test-run only"), this);
|
||||
testRun->setToolTip(tr("Run as normal but do not actually copy anything. Useful for verifying results before real sync."));
|
||||
|
||||
// layout to hold size spinbox and checkbox option(s)
|
||||
QHBoxLayout * hlay1 = new QHBoxLayout();
|
||||
hlay1->addWidget(maxSize, 1);
|
||||
hlay1->addWidget(testRun);
|
||||
hlay1->addWidget(new QLabel(tr("Log Level:"), this));
|
||||
hlay1->addWidget(logLevel);
|
||||
|
||||
// "extra" options
|
||||
|
||||
QLabel * lbFilter = new QLabel(tr("Filters:"), this);
|
||||
lbFilter->setToolTip(tr("The \"Include\" filter will only copy files which match the pattern(s).\n" \
|
||||
"The \"Exclude\" filter will skip files matching the filter pattern(s).\n" \
|
||||
"The Include filter is evaluated first."));
|
||||
|
||||
AutoLineEdit * leFiltExc = new AutoLineEdit(this, true);
|
||||
leFiltExc->setField(m_syncOptions.excludeFilter);
|
||||
leFiltExc->setToolTip(tr("One or more file pattern(s) to exclude, separated by commas.\n" "Blank means exclude none. ?, *, and [...] wildcards accepted."));
|
||||
|
||||
AutoLineEdit * leFiltInc = new AutoLineEdit(this, true);
|
||||
leFiltInc->setField(m_syncOptions.includeFilter);
|
||||
leFiltInc->setToolTip(tr("One or more file pattern(s) to include, separated by commas.\n" "Blank means include all. ?, *, and [...] wildcards accepted."));
|
||||
|
||||
// layout to hold filter options
|
||||
QHBoxLayout * filtLo = new QHBoxLayout();
|
||||
filtLo->addWidget(new QLabel(tr("Include:"), this));
|
||||
filtLo->addWidget(leFiltInc, 1);
|
||||
filtLo->addWidget(new QLabel(tr("Exclude:"), this));
|
||||
filtLo->addWidget(leFiltExc, 1);
|
||||
|
||||
// file options
|
||||
QHBoxLayout * filOptsLo = new QHBoxLayout();
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::CaseSensitive, tr("Case sensitive"), this));
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::NoSymLinks, true, tr("Follow links"), this));
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::Hidden, tr("Include hidden"), this));
|
||||
|
||||
// folder options
|
||||
QHBoxLayout * dirOptsLo = new QHBoxLayout();
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_RECURSIVE, tr("Recursive"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_SKIP_DIR_LINKS, true, tr("Follow links"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::Dirs, true, tr("Skip empty"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::AllDirs, true, tr("Apply filters"), this));
|
||||
|
||||
// extra options container widget and layout
|
||||
ui_extraOptions = new QWidget(this);
|
||||
ui_extraOptions->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
||||
|
||||
QGridLayout * xOptsLay = new QGridLayout(ui_extraOptions);
|
||||
xOptsLay->setContentsMargins(0, 0, 0, 0);
|
||||
xOptsLay->addWidget(lbFilter, row, 0);
|
||||
xOptsLay->addLayout(filtLo, row++, 1);
|
||||
xOptsLay->addWidget(new QLabel(tr("Filter Options:"), this), row, 0);
|
||||
xOptsLay->addLayout(filOptsLo, row++, 1);
|
||||
xOptsLay->addWidget(new QLabel(tr("Folder Options:"), this), row, 0);
|
||||
xOptsLay->addLayout(dirOptsLo, row++, 1);
|
||||
|
||||
// status label
|
||||
ui_statusLabel = new QLabel(this);
|
||||
// progress widget
|
||||
ui_progress = new ProgressWidget(this);
|
||||
ui_progress->setMinimumWidth(0);
|
||||
ui_progress->setVisible(false);
|
||||
|
||||
// dialog buttons & menu
|
||||
|
||||
QMenu * optionsMenu = new QMenu(tr("Options"));
|
||||
QAction * xtrasAct = optionsMenu->addAction(CompanionIcon("fuses.png"), tr("Show extra options"), this, &FileSyncDialog::toggleExtraOptions);
|
||||
xtrasAct->setCheckable(true);
|
||||
connect(this, &FileSyncDialog::extraOptionsToggled, xtrasAct, &QAction::setChecked);
|
||||
optionsMenu->addAction(CompanionIcon("paintbrush.png"), tr("Reset to defaults"), this, &FileSyncDialog::resetOptions);
|
||||
|
||||
QToolButton * btnOpts = new QToolButton(this);
|
||||
btnOpts->setDefaultAction(xtrasAct);
|
||||
btnOpts->setMenu(optionsMenu);
|
||||
btnOpts->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
btnOpts->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
btnOpts->setToolTip(xtrasAct->text());
|
||||
|
||||
ui_btnStartStop = new QToolButton(this);
|
||||
ui_btnStartStop->setCheckable(true);
|
||||
ui_btnStartStop->setIcon(playIcon);
|
||||
ui_btnStartStop->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
|
||||
ui_btnClose = new QToolButton(this);
|
||||
ui_btnClose->setText(tr("Close"));
|
||||
ui_btnClose->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
ui_btnClose->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
|
||||
ui_buttonBox = new QDialogButtonBox(this);
|
||||
ui_buttonBox->addButton(btnOpts, QDialogButtonBox::ActionRole);
|
||||
ui_buttonBox->addButton(ui_btnStartStop, QDialogButtonBox::ActionRole);
|
||||
ui_buttonBox->addButton(ui_btnClose, QDialogButtonBox::RejectRole);
|
||||
|
||||
// The options group box.
|
||||
ui_optionsPanel = new QGroupBox(tr("Options"), this);
|
||||
QGridLayout * optsLay = new QGridLayout(ui_optionsPanel);
|
||||
row = 0;
|
||||
optsLay->addWidget(lblSrc, row, 0);
|
||||
optsLay->addWidget(wdgSrc, row++, 1);
|
||||
optsLay->addWidget(lblDst, row, 0);
|
||||
optsLay->addWidget(wdgDst, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Sync. Direction:"), this), row, 0);
|
||||
optsLay->addWidget(syncDir, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Existing Files:"), this), row, 0);
|
||||
optsLay->addWidget(copyMode, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Max. File Size:"), this), row, 0);
|
||||
optsLay->addLayout(hlay1, row++, 1);
|
||||
optsLay->addWidget(ui_extraOptions, row, 0, 1, 2);
|
||||
|
||||
// layout to hold warning label and button box
|
||||
QHBoxLayout * hlay2 = new QHBoxLayout();
|
||||
hlay2->addWidget(ui_statusLabel, 1);
|
||||
hlay2->addWidget(ui_buttonBox);
|
||||
|
||||
// Create main layout and add options, progress, buttons.
|
||||
QVBoxLayout * dlgL = new QVBoxLayout(this);
|
||||
dlgL->addWidget(ui_optionsPanel, 0, Qt::AlignTop);
|
||||
dlgL->addLayout(hlay2);
|
||||
dlgL->addWidget(ui_progress, 1);
|
||||
|
||||
// Connect all signal handlers
|
||||
|
||||
// source path
|
||||
connect(leSrc, &AutoLineEdit::textChanged, this, &FileSyncDialog::validate);
|
||||
// destination path
|
||||
connect(leDst, &AutoLineEdit::textChanged, this, &FileSyncDialog::validate);
|
||||
|
||||
// function to dis/enable the OVERWR_ALWAYS option depending on sync direction
|
||||
connect(syncDir, &AutoComboBox::currentDataChanged, [=](int dir) {
|
||||
int idx = copyMode->findData(SyncProcess::OVERWR_ALWAYS);
|
||||
int flg = (dir == SyncProcess::SYNC_A2B || dir == SyncProcess::SYNC_B2A) ? 33 : 0;
|
||||
if (!flg && idx == copyMode->currentIndex())
|
||||
copyMode->setCurrentIndex(copyMode->findData(SyncProcess::OVERWR_NEWER_IF_DIFF));
|
||||
copyMode->setItemData(idx, flg, Qt::UserRole - 1);
|
||||
});
|
||||
|
||||
// function to set magnitude of file size spinbox, KB or MB
|
||||
connect(maxSize, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
const QSignalBlocker blocker(maxSize);
|
||||
int multi = maxSize->property("multi").isValid() ? maxSize->property("multi").toInt() : 0;
|
||||
if (value >= 10 * 1024 && multi != 1024 * 1024) {
|
||||
// KB -> MB
|
||||
multi = 1024 * 1024;
|
||||
maxSize->setValue(value / 1024);
|
||||
maxSize->setMaximum(100);
|
||||
maxSize->setSingleStep(1);
|
||||
maxSize->setSuffix(tr(" MB"));
|
||||
}
|
||||
else if ((value < 10 && multi != 1024) || !multi) {
|
||||
// MB -> KB
|
||||
if (multi)
|
||||
value *= 1024;
|
||||
multi = 1024;
|
||||
if (value == 9 * 1024)
|
||||
value += 1024 - 32; // avoid large jump when stepping from 10MB to 10,208KB
|
||||
maxSize->setMaximum(100 * 1024);
|
||||
maxSize->setValue(value);
|
||||
maxSize->setSingleStep(32);
|
||||
maxSize->setSuffix(tr(" KB"));
|
||||
}
|
||||
maxSize->setProperty("multi", multi);
|
||||
m_syncOptions.maxFileSize = value * multi;
|
||||
});
|
||||
|
||||
// we set these after connections are made because we want the signal processors to run
|
||||
syncDir->setField(m_syncOptions.direction);
|
||||
maxSize->setValue(m_syncOptions.maxFileSize / 1024);
|
||||
|
||||
// connect Reset action to all fields
|
||||
for (AutoLineEdit * a : ui_optionsPanel->findChildren<AutoLineEdit *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoLineEdit::updateValue);
|
||||
for (AutoComboBox * a : ui_optionsPanel->findChildren<AutoComboBox *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoComboBox::updateValue);
|
||||
for (AutoBitsetCheckBox * a : ui_optionsPanel->findChildren<AutoBitsetCheckBox *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoBitsetCheckBox::updateValue);
|
||||
connect(this, &FileSyncDialog::optionsWereReset, [=]() { maxSize->setValue(m_syncOptions.maxFileSize / 1024); });
|
||||
|
||||
// React to name changes for source and destination path labels
|
||||
connect(this, &FileSyncDialog::folderNameAChanged, [=](const QString &text) {
|
||||
lblSrc->setText(text % ":");
|
||||
wdgSrc->setProperty("fileDialogTitle", text);
|
||||
});
|
||||
connect(this, &FileSyncDialog::folderNameBChanged, [=](const QString &text) {
|
||||
lblDst->setText(text % ":");
|
||||
wdgDst->setProperty("fileDialogTitle", text);
|
||||
});
|
||||
|
||||
// button actions
|
||||
connect(ui_btnStartStop, &QPushButton::clicked, this, &FileSyncDialog::toggleSync);
|
||||
connect(ui_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(ui_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(ui_progress, &ProgressWidget::detailsToggled, this, &FileSyncDialog::adjustSizeDelayed);
|
||||
}
|
||||
|
||||
void FileSyncDialog::toggleSync(bool)
|
||||
{
|
||||
if (m_running) {
|
||||
setCursor(Qt::WaitCursor);
|
||||
emit stopSync();
|
||||
return;
|
||||
}
|
||||
|
||||
ui_progress->clearDetails();
|
||||
ui_progress->setInfo("");
|
||||
SyncProcess * syncProcess = new SyncProcess(m_syncOptions);
|
||||
|
||||
// move sync process to separate thread, we only use signals/slots from here on...
|
||||
QThread * syncThread = new QThread(this);
|
||||
syncProcess->moveToThread(syncThread);
|
||||
|
||||
// ...and quite a few of them!
|
||||
connect(this, &FileSyncDialog::startSync, syncProcess, &SyncProcess::run);
|
||||
connect(this, &FileSyncDialog::stopSync, syncProcess, &SyncProcess::stop);
|
||||
connect(syncProcess, &SyncProcess::started, this, &FileSyncDialog::onSyncStarted);
|
||||
connect(syncProcess, &SyncProcess::finished, this, &FileSyncDialog::onSyncFinished);
|
||||
connect(syncProcess, &SyncProcess::statusMessage, this, &FileSyncDialog::setStatusText);
|
||||
connect(syncProcess, &SyncProcess::statusUpdate, this, &FileSyncDialog::onStatusUpdate);
|
||||
connect(syncProcess, &SyncProcess::fileCountChanged, ui_progress, &ProgressWidget::setMaximum);
|
||||
connect(syncProcess, &SyncProcess::progressMessage, ui_progress, &ProgressWidget::addMessage);
|
||||
connect(syncProcess, &SyncProcess::finished, syncThread, &QThread::quit);
|
||||
connect(syncThread, &QThread::finished, syncThread, &QThread::deleteLater);
|
||||
connect(syncThread, &QThread::destroyed, syncProcess, &SyncProcess::deleteLater);
|
||||
|
||||
// go
|
||||
syncThread->start(QThread::LowPriority);
|
||||
emit startSync();
|
||||
}
|
||||
|
||||
void FileSyncDialog::onSyncStarted()
|
||||
{
|
||||
m_running = true;
|
||||
updateRunningState();
|
||||
}
|
||||
|
||||
void FileSyncDialog::onSyncFinished()
|
||||
{
|
||||
m_running = false;
|
||||
updateRunningState();
|
||||
if (parentWidget())
|
||||
QApplication::alert(parentWidget());
|
||||
}
|
||||
|
||||
void FileSyncDialog::updateRunningState()
|
||||
{
|
||||
ui_btnStartStop->setChecked(m_running);
|
||||
ui_optionsPanel->setEnabled(!m_running);
|
||||
ui_btnClose->setEnabled(!m_running);
|
||||
ui_btnStartStop->setText(m_running ? tr("Abort") : tr("Start"));
|
||||
if (m_running) {
|
||||
ui_progress->setVisible(true); // don't hide after run
|
||||
}
|
||||
else {
|
||||
setCursor(Qt::ArrowCursor); // in case we set a wait cursor upon abort request
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::onStatusUpdate(const SyncProcess::SyncStatus & stat)
|
||||
{
|
||||
static const QString reportTemplate = tr("Total: <b>%1</b>; Created: <b>%2</b>; Updated: <b>%3</b>; Skipped: <b>%4</b>; Errors: <font color=%6><b>%5</b></font>;");
|
||||
ui_progress->setInfo((stat.index < stat.count ? tr("Current: <b>%1</b> of ").arg(stat.index) : "") % reportTemplate.arg(stat.count).arg(stat.created).arg(stat.updated).arg(stat.skipped).arg(stat.errored).arg(stat.errored ? "red" : "black"));
|
||||
ui_progress->setValue(stat.index);
|
||||
}
|
||||
|
||||
void FileSyncDialog::setSyncOptions(const SyncProcess::SyncOptions & syncOptions)
|
||||
{
|
||||
m_syncOptions = syncOptions;
|
||||
emit optionsWereReset();
|
||||
}
|
||||
|
||||
void FileSyncDialog::resetOptions()
|
||||
{
|
||||
m_syncOptions.reset();
|
||||
emit optionsWereReset();
|
||||
}
|
||||
|
||||
void FileSyncDialog::toggleExtraOptions(bool show)
|
||||
{
|
||||
ui_extraOptions->setVisible(show);
|
||||
if (!ui_progress->detailsVisible())
|
||||
adjustSizeDelayed();
|
||||
m_extraOptionsVisible = show;
|
||||
emit extraOptionsToggled(show);
|
||||
}
|
||||
|
||||
void FileSyncDialog::setFolderNameA(const QString & name)
|
||||
{
|
||||
if (m_folderNameA != name) {
|
||||
m_folderNameA = name;
|
||||
emit folderNameAChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::setFolderNameB(const QString & name)
|
||||
{
|
||||
if (m_folderNameB != name) {
|
||||
m_folderNameB = name;
|
||||
emit folderNameBChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::setStatusText(const QString & text, int type)
|
||||
{
|
||||
ui_statusLabel->setText(text);
|
||||
ui_statusLabel->setStyleSheet(type != QtInfoMsg && type >= QtWarningMsg ? "QLabel { color: red; }:" : "");
|
||||
}
|
||||
|
||||
bool FileSyncDialog::validate()
|
||||
{
|
||||
QString msg;
|
||||
if (m_syncOptions.folderA.isEmpty() || !QFileInfo(m_syncOptions.folderA).exists())
|
||||
msg = tr("Source folder not found.");
|
||||
else if (m_syncOptions.folderB.isEmpty() || !QFileInfo(m_syncOptions.folderB).exists())
|
||||
msg = tr("Destination folder not found.");
|
||||
else if (QFileInfo(m_syncOptions.folderA).canonicalFilePath() == QFileInfo(m_syncOptions.folderB).canonicalFilePath())
|
||||
msg = tr("Source and destination folders are the same.");
|
||||
|
||||
setStatusText(msg, QtCriticalMsg);
|
||||
ui_btnStartStop->setEnabled(msg.isEmpty());
|
||||
return msg.isEmpty();
|
||||
}
|
||||
|
||||
void FileSyncDialog::adjustSizeDelayed()
|
||||
{
|
||||
QTimer::singleShot(0, [=]() { adjustSize(); });
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef FILESYNCDIALOG_H
|
||||
#define FILESYNCDIALOG_H
|
||||
|
||||
#include "process_sync.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
|
||||
class ProgressWidget;
|
||||
|
||||
class FileSyncDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(SyncProcess::SyncOptions syncOptions READ syncOptions WRITE setSyncOptions RESET resetOptions NOTIFY optionsWereReset)
|
||||
Q_PROPERTY(bool extraOptionsVisible READ extraOptionsVisible WRITE toggleExtraOptions NOTIFY extraOptionsToggled)
|
||||
Q_PROPERTY(QString folderNameA READ folderNameA WRITE setFolderNameA NOTIFY folderNameAChanged)
|
||||
Q_PROPERTY(QString folderNameB READ folderNameB WRITE setFolderNameB NOTIFY folderNameBChanged)
|
||||
|
||||
public:
|
||||
FileSyncDialog(QWidget * parent = nullptr, const SyncProcess::SyncOptions & syncOptions = SyncProcess::SyncOptions());
|
||||
|
||||
inline SyncProcess::SyncOptions syncOptions() const { return m_syncOptions; }
|
||||
void setSyncOptions(const SyncProcess::SyncOptions & syncOptions);
|
||||
void resetOptions();
|
||||
|
||||
inline bool extraOptionsVisible() const { return m_extraOptionsVisible; }
|
||||
void toggleExtraOptions(bool show);
|
||||
|
||||
inline QString folderNameA() const { return m_folderNameA; }
|
||||
void setFolderNameA(const QString & name);
|
||||
|
||||
inline QString folderNameB() const { return m_folderNameB; }
|
||||
void setFolderNameB(const QString & name);
|
||||
|
||||
public slots:
|
||||
virtual void reject() override;
|
||||
void setStatusText(const QString & text, int type = QtWarningMsg);
|
||||
bool validate();
|
||||
|
||||
signals:
|
||||
void startSync();
|
||||
void stopSync();
|
||||
void folderNameAChanged(const QString & name);
|
||||
void folderNameBChanged(const QString & name);
|
||||
void extraOptionsToggled(bool show);
|
||||
void optionsWereReset();
|
||||
|
||||
private slots:
|
||||
void setupUi();
|
||||
void toggleSync(bool);
|
||||
void onSyncStarted();
|
||||
void onSyncFinished();
|
||||
void updateRunningState();
|
||||
void onStatusUpdate(const SyncProcess::SyncStatus & stat);
|
||||
void adjustSizeDelayed();
|
||||
|
||||
private:
|
||||
SyncProcess::SyncOptions m_syncOptions;
|
||||
QString m_folderNameA;
|
||||
QString m_folderNameB;
|
||||
bool m_running;
|
||||
bool m_extraOptionsVisible;
|
||||
|
||||
QGroupBox * ui_optionsPanel;
|
||||
QWidget * ui_extraOptions;
|
||||
ProgressWidget * ui_progress;
|
||||
QDialogButtonBox * ui_buttonBox;
|
||||
QToolButton * ui_btnStartStop;
|
||||
QToolButton * ui_btnClose;
|
||||
QLabel * ui_statusLabel;
|
||||
};
|
||||
|
||||
#endif // FILESYNCDIALOG_H
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "downloaddialog.h"
|
||||
#include "ui_downloaddialog.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
downloadDialog::downloadDialog(QWidget *parent, QString src, QString tgt):
|
||||
QDialog(parent),
|
||||
ui(new Ui::downloadDialog),
|
||||
reply(nullptr),
|
||||
file(nullptr),
|
||||
aborted(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("fwpreferences.png"));
|
||||
ui->progressBar->setValue(1);
|
||||
ui->progressBar->setMinimum(0);
|
||||
ui->progressBar->setMaximum(0);
|
||||
|
||||
if (tgt.isEmpty()) {
|
||||
setWindowTitle(src);
|
||||
return; // just show wait dialog.
|
||||
}
|
||||
|
||||
file = new QFile(tgt);
|
||||
if (!file->open(QIODevice::WriteOnly)) {
|
||||
QMessageBox::critical(this, CPN_STR_APP_NAME,
|
||||
tr("Unable to save the file %1: %2.")
|
||||
.arg(tgt).arg(file->errorString()));
|
||||
QTimer::singleShot(0, this, SLOT(fileError()));
|
||||
}
|
||||
else {
|
||||
reply = qnam.get(QNetworkRequest(QUrl(src)));
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
|
||||
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
|
||||
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64)));
|
||||
}
|
||||
}
|
||||
|
||||
downloadDialog::~downloadDialog()
|
||||
{
|
||||
delete ui;
|
||||
delete file;
|
||||
}
|
||||
|
||||
void downloadDialog::reject()
|
||||
{
|
||||
if (reply && reply->isRunning()) {
|
||||
aborted = true;
|
||||
reply->abort(); // this will call QNetworkReply::finished()
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void downloadDialog::httpFinished()
|
||||
{
|
||||
file->flush();
|
||||
file->close();
|
||||
|
||||
const bool ok = !(reply->error() || aborted);
|
||||
if (!ok) {
|
||||
file->remove();
|
||||
if (!aborted)
|
||||
QMessageBox::information(this, CPN_STR_APP_NAME, tr("Download failed: %1.").arg(reply->errorString()));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
file->deleteLater();
|
||||
file = nullptr;
|
||||
|
||||
if (ok)
|
||||
accept();
|
||||
else
|
||||
reject();
|
||||
}
|
||||
|
||||
void downloadDialog::httpReadyRead()
|
||||
{
|
||||
if (file) {
|
||||
file->write(reply->readAll());
|
||||
}
|
||||
}
|
||||
|
||||
void downloadDialog::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
|
||||
{
|
||||
ui->progressBar->setMaximum(totalBytes);
|
||||
ui->progressBar->setValue(bytesRead);
|
||||
}
|
||||
|
||||
void downloadDialog::fileError()
|
||||
{
|
||||
delete file;
|
||||
file = NULL;
|
||||
reject();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void downloadDialog::closeEvent( QCloseEvent * event)
|
||||
{
|
||||
// Delay closing 2 seconds to avoid unpleasant flashing download dialogs
|
||||
QTime closeTime= QTime::currentTime().addSecs(2);
|
||||
while( QTime::currentTime() < closeTime )
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
|
||||
event->accept();
|
||||
}
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DOWNLOADDIALOG_H_
|
||||
#define _DOWNLOADDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QFile>
|
||||
|
||||
namespace Ui {
|
||||
class downloadDialog;
|
||||
}
|
||||
|
||||
class downloadDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit downloadDialog(QWidget *parent = 0, QString src = "", QString tgt = "");
|
||||
~downloadDialog();
|
||||
|
||||
public slots:
|
||||
virtual void reject() override;
|
||||
|
||||
private slots:
|
||||
void fileError();
|
||||
void httpFinished();
|
||||
void httpReadyRead();
|
||||
void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes);
|
||||
|
||||
private:
|
||||
#if 0
|
||||
void closeEvent( QCloseEvent * event);
|
||||
#endif
|
||||
Ui::downloadDialog *ui;
|
||||
|
||||
QNetworkAccessManager qnam;
|
||||
QNetworkReply *reply;
|
||||
QFile *file;
|
||||
bool aborted;
|
||||
};
|
||||
|
||||
#endif // _DOWNLOADDIALOG_H_
|
||||
@@ -1,86 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>downloadDialog</class>
|
||||
<widget class="QDialog" name="downloadDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>562</width>
|
||||
<height>82</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Downloading: </string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="companion.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>downloadDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>downloadDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
set(firmwares_SRCS
|
||||
boards.cpp
|
||||
curvereference.cpp
|
||||
customfunctiondata.cpp
|
||||
eeprominterface.cpp
|
||||
generalsettings.cpp
|
||||
gvardata.cpp
|
||||
io_data.cpp
|
||||
logicalswitchdata.cpp
|
||||
modeldata.cpp
|
||||
moduledata.cpp
|
||||
multiprotocols.cpp
|
||||
radiodata.cpp
|
||||
radiodataconversionstate.cpp
|
||||
rawsource.cpp
|
||||
rawswitch.cpp
|
||||
sensordata.cpp
|
||||
telem_data.cpp
|
||||
er9x/er9xeeprom.cpp
|
||||
er9x/er9xinterface.cpp
|
||||
ersky9x/ersky9xeeprom.cpp
|
||||
ersky9x/ersky9xinterface.cpp
|
||||
opentx/opentxeeprom.cpp
|
||||
opentx/opentxinterface.cpp
|
||||
)
|
||||
|
||||
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
||||
|
||||
list(APPEND firmwares_HDRS
|
||||
eepromimportexport.h
|
||||
moduledata.h
|
||||
)
|
||||
|
||||
add_library(firmwares ${firmwares_SRCS} ${firmwares_HDRS})
|
||||
target_link_libraries(firmwares ${CPN_COMMON_LIB} Qt5::Core Qt5::Xml Qt5::Widgets)
|
||||
target_include_directories(firmwares
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/er9x"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ersky9x"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/opentx"
|
||||
)
|
||||
@@ -1,427 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "boards.h"
|
||||
#include "macros.h"
|
||||
|
||||
// TODO remove all those constants
|
||||
// Update: These are now all only used within this class.
|
||||
// External access is only via getEEpromSize() and getFlashSize()
|
||||
|
||||
#define EESIZE_STOCK 2048
|
||||
#define EESIZE_M128 4096
|
||||
#define EESIZE_GRUVIN9X 4096
|
||||
#define EESIZE_TARANIS (32*1024)
|
||||
#define EESIZE_SKY9X (128*4096)
|
||||
#define EESIZE_9XRPRO (128*4096)
|
||||
#define EESIZE_MAX EESIZE_9XRPRO
|
||||
|
||||
// getFlashSize() (and these macros) is only used by radiointerface::getDfuArgs (perhaps can find a better way?)
|
||||
#define FSIZE_STOCK (64*1024)
|
||||
#define FSIZE_M128 (128*1024)
|
||||
#define FSIZE_GRUVIN9X (256*1024)
|
||||
#define FSIZE_TARANIS (512*1024)
|
||||
#define FSIZE_SKY9X (256*1024)
|
||||
#define FSIZE_9XRPRO (512*1024)
|
||||
#define FSIZE_HORUS (2048*1024)
|
||||
#define FSIZE_MAX FSIZE_HORUS
|
||||
|
||||
using namespace Board;
|
||||
|
||||
void Boards::setBoardType(const Type & board)
|
||||
{
|
||||
if (board >= BOARD_UNKNOWN && board < BOARD_ENUM_COUNT)
|
||||
m_boardType = board;
|
||||
else
|
||||
m_boardType = BOARD_UNKNOWN;
|
||||
}
|
||||
|
||||
uint32_t Boards::getFourCC(Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_X12S:
|
||||
return 0x3478746F;
|
||||
case BOARD_X10:
|
||||
return 0x3778746F;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
return 0x3978746F;
|
||||
case BOARD_TARANIS_X7:
|
||||
return 0x3678746F;
|
||||
case BOARD_TARANIS_X9E:
|
||||
return 0x3578746F;
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
return 0x3378746F;
|
||||
case BOARD_SKY9X:
|
||||
case BOARD_AR9X:
|
||||
case BOARD_9XRPRO:
|
||||
return 0x3278746F;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return 0x3178746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const int Boards::getEEpromSize(Board::Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return EESIZE_STOCK;
|
||||
case BOARD_M128:
|
||||
return EESIZE_M128;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return EESIZE_GRUVIN9X;
|
||||
case BOARD_SKY9X:
|
||||
return EESIZE_SKY9X;
|
||||
case BOARD_9XRPRO:
|
||||
case BOARD_AR9X:
|
||||
return EESIZE_9XRPRO;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
case BOARD_TARANIS_X7:
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
case BOARD_TARANIS_X9E:
|
||||
return EESIZE_TARANIS;
|
||||
case BOARD_UNKNOWN:
|
||||
return EESIZE_MAX;
|
||||
default:
|
||||
return 0; // unlimited
|
||||
}
|
||||
}
|
||||
|
||||
const int Boards::getFlashSize(Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return FSIZE_STOCK;
|
||||
case BOARD_M128:
|
||||
return FSIZE_M128;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return FSIZE_GRUVIN9X;
|
||||
case BOARD_SKY9X:
|
||||
return FSIZE_SKY9X;
|
||||
case BOARD_9XRPRO:
|
||||
case BOARD_AR9X:
|
||||
return FSIZE_9XRPRO;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
case BOARD_TARANIS_X7:
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
case BOARD_TARANIS_X9E:
|
||||
return FSIZE_TARANIS;
|
||||
case BOARD_X12S:
|
||||
case BOARD_X10:
|
||||
return FSIZE_HORUS;
|
||||
case BOARD_UNKNOWN:
|
||||
return FSIZE_MAX;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
|
||||
|
||||
if (IS_TARANIS_XLITE(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_2POS, "SC"},
|
||||
{SWITCH_2POS, "SD"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
if (IS_TARANIS_X7(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_TOGGLE, "SH"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_HORUS_OR_TARANIS(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_3POS, "SE"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_3POS, "SG"},
|
||||
{SWITCH_TOGGLE, "SH"},
|
||||
{SWITCH_3POS, "SI"},
|
||||
{SWITCH_3POS, "SJ"},
|
||||
{SWITCH_3POS, "SK"},
|
||||
{SWITCH_3POS, "SL"},
|
||||
{SWITCH_3POS, "SM"},
|
||||
{SWITCH_3POS, "SN"},
|
||||
{SWITCH_3POS, "SO"},
|
||||
{SWITCH_3POS, "SP"},
|
||||
{SWITCH_3POS, "SQ"},
|
||||
{SWITCH_3POS, "SR"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "3POS"},
|
||||
{SWITCH_2POS, "THR"},
|
||||
{SWITCH_2POS, "RUD"},
|
||||
{SWITCH_2POS, "ELE"},
|
||||
{SWITCH_2POS, "AIL"},
|
||||
{SWITCH_2POS, "GEA"},
|
||||
{SWITCH_TOGGLE, "TRN"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
|
||||
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
|
||||
}
|
||||
|
||||
const int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Sticks:
|
||||
return 4;
|
||||
|
||||
case Pots:
|
||||
if (IS_TARANIS_SMALL(board))
|
||||
return 2;
|
||||
else if (IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else
|
||||
return 3;
|
||||
|
||||
case FactoryInstalledPots:
|
||||
if (IS_TARANIS_X9(board))
|
||||
return 2;
|
||||
else
|
||||
return getCapability(board, Pots);
|
||||
|
||||
case Sliders:
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case MouseAnalogs:
|
||||
if (IS_HORUS_X12S(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case MaxAnalogs:
|
||||
return getCapability(board, Board::Sticks) + getCapability(board, Board::Pots) + getCapability(board, Board::Sliders) + getCapability(board, Board::MouseAnalogs);
|
||||
|
||||
case MultiposPots:
|
||||
return IS_HORUS_OR_TARANIS(board) ? 3 : 0;
|
||||
|
||||
case MultiposPotsPositions:
|
||||
return IS_HORUS_OR_TARANIS(board) ? 6 : 0;
|
||||
|
||||
case Switches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 18;
|
||||
else if (IS_TARANIS_X7(board))
|
||||
return 6;
|
||||
else if (IS_TARANIS_XLITE(board))
|
||||
return 4;
|
||||
else if (IS_HORUS_OR_TARANIS(board))
|
||||
return 8;
|
||||
else
|
||||
return 7;
|
||||
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
else
|
||||
return getCapability(board, Switches);
|
||||
|
||||
case SwitchPositions:
|
||||
if (IS_HORUS_OR_TARANIS(board))
|
||||
return getCapability(board, Switches) * 3;
|
||||
else
|
||||
return 9;
|
||||
|
||||
case NumTrims:
|
||||
if (IS_HORUS(board))
|
||||
return 6;
|
||||
else
|
||||
return 4;
|
||||
|
||||
case NumTrimSwitches:
|
||||
return getCapability(board, NumTrims) * 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QString Boards::getAxisName(int index)
|
||||
{
|
||||
const QString axes[] = {
|
||||
tr("Left Horizontal"),
|
||||
tr("Left Vertical"),
|
||||
tr("Right Vertical"),
|
||||
tr("Right Horizontal"),
|
||||
tr("Aux. 1"),
|
||||
tr("Aux. 2"),
|
||||
};
|
||||
if (index < (int)DIM(axes))
|
||||
return axes[index];
|
||||
else
|
||||
return tr("Unknown");
|
||||
}
|
||||
|
||||
const QString Boards::getAnalogInputName(Board::Type board, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
|
||||
if (index < getBoardCapability(board, Board::Sticks)) {
|
||||
const QString sticks[] = {
|
||||
tr("Rud"),
|
||||
tr("Ele"),
|
||||
tr("Thr"),
|
||||
tr("Ail")
|
||||
};
|
||||
return sticks[index];
|
||||
}
|
||||
|
||||
index -= getCapability(board, Board::Sticks);
|
||||
|
||||
if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) {
|
||||
const QString pots[] = {
|
||||
"P1",
|
||||
"P2",
|
||||
"P3"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_TARANIS_X9E(board)) {
|
||||
const QString pots[] = {
|
||||
"F1",
|
||||
"F2",
|
||||
"F3",
|
||||
"F4",
|
||||
"S1",
|
||||
"S2",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"S2",
|
||||
"S3",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_HORUS_X12S(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"6P",
|
||||
"S2",
|
||||
"L1",
|
||||
"L2",
|
||||
"LS",
|
||||
"RS",
|
||||
"JSx",
|
||||
"JSy"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_HORUS_X10(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"6P",
|
||||
"S2",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const bool Boards::isBoardCompatible(Type board1, Type board2)
|
||||
{
|
||||
return (getFourCC(board1) == getFourCC(board2));
|
||||
}
|
||||
|
||||
const QString Boards::getBoardName(Board::Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return "9X";
|
||||
case BOARD_M128:
|
||||
return "9X128";
|
||||
case BOARD_GRUVIN9X:
|
||||
return "Gruvin9x";
|
||||
case BOARD_MEGA2560:
|
||||
return "MEGA2560";
|
||||
case BOARD_TARANIS_X7:
|
||||
return "Taranis X7/X7S";
|
||||
case BOARD_TARANIS_XLITE:
|
||||
return "Taranis X-Lite";
|
||||
case BOARD_TARANIS_X9D:
|
||||
return "Taranis X9D";
|
||||
case BOARD_TARANIS_X9DP:
|
||||
return "Taranis X9D+";
|
||||
case BOARD_TARANIS_X9E:
|
||||
return "Taranis X9E";
|
||||
case BOARD_SKY9X:
|
||||
return "Sky9x";
|
||||
case BOARD_9XRPRO:
|
||||
return "9XR-PRO";
|
||||
case BOARD_AR9X:
|
||||
return "AR9X";
|
||||
case BOARD_X12S:
|
||||
return "Horus X12S";
|
||||
case BOARD_X10:
|
||||
return "Horus X10/X10S";
|
||||
default:
|
||||
return tr("Unknown");
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BOARDS_H_
|
||||
#define _BOARDS_H_
|
||||
|
||||
#include <QtCore>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
// TODO create a Board class with all these functions
|
||||
|
||||
namespace Board {
|
||||
|
||||
enum Type
|
||||
{
|
||||
BOARD_UNKNOWN = -1,
|
||||
BOARD_STOCK = 0,
|
||||
BOARD_M128,
|
||||
BOARD_MEGA2560,
|
||||
BOARD_GRUVIN9X,
|
||||
BOARD_SKY9X,
|
||||
BOARD_9XRPRO,
|
||||
BOARD_AR9X,
|
||||
BOARD_TARANIS_X7,
|
||||
BOARD_TARANIS_X9D,
|
||||
BOARD_TARANIS_X9DP,
|
||||
BOARD_TARANIS_X9E,
|
||||
BOARD_X12S,
|
||||
BOARD_X10,
|
||||
BOARD_TARANIS_XLITE,
|
||||
BOARD_ENUM_COUNT
|
||||
};
|
||||
|
||||
enum PotType
|
||||
{
|
||||
POT_NONE,
|
||||
POT_WITH_DETENT,
|
||||
POT_MULTIPOS_SWITCH,
|
||||
POT_WITHOUT_DETENT
|
||||
};
|
||||
|
||||
enum SliderType
|
||||
{
|
||||
SLIDER_NONE,
|
||||
SLIDER_WITH_DETENT
|
||||
};
|
||||
|
||||
enum SwitchType
|
||||
{
|
||||
SWITCH_NOT_AVAILABLE,
|
||||
SWITCH_TOGGLE,
|
||||
SWITCH_2POS,
|
||||
SWITCH_3POS
|
||||
};
|
||||
|
||||
enum StickAxes {
|
||||
STICK_AXIS_LH = 0,
|
||||
STICK_AXIS_LV,
|
||||
STICK_AXIS_RV,
|
||||
STICK_AXIS_RH,
|
||||
STICK_AXIS_COUNT
|
||||
};
|
||||
|
||||
enum TrimAxes {
|
||||
TRIM_AXIS_LH = 0,
|
||||
TRIM_AXIS_LV,
|
||||
TRIM_AXIS_RV,
|
||||
TRIM_AXIS_RH,
|
||||
TRIM_AXIS_T5,
|
||||
TRIM_AXIS_T6,
|
||||
TRIM_AXIS_COUNT
|
||||
};
|
||||
|
||||
enum TrimSwitches
|
||||
{
|
||||
TRIM_SW_LH_DEC,
|
||||
TRIM_SW_LH_INC,
|
||||
TRIM_SW_LV_DEC,
|
||||
TRIM_SW_LV_INC,
|
||||
TRIM_SW_RV_DEC,
|
||||
TRIM_SW_RV_INC,
|
||||
TRIM_SW_RH_DEC,
|
||||
TRIM_SW_RH_INC,
|
||||
TRIM_SW_T5_DEC,
|
||||
TRIM_SW_T5_INC,
|
||||
TRIM_SW_T6_DEC,
|
||||
TRIM_SW_T6_INC,
|
||||
TRIM_SW_COUNT
|
||||
};
|
||||
|
||||
enum Capability {
|
||||
Sticks,
|
||||
Pots,
|
||||
FactoryInstalledPots,
|
||||
Sliders,
|
||||
MouseAnalogs,
|
||||
MaxAnalogs,
|
||||
MultiposPots,
|
||||
MultiposPotsPositions,
|
||||
Switches,
|
||||
SwitchPositions,
|
||||
FactoryInstalledSwitches,
|
||||
NumTrims,
|
||||
NumTrimSwitches
|
||||
};
|
||||
|
||||
struct SwitchInfo
|
||||
{
|
||||
SwitchType config;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct SwitchPosition {
|
||||
SwitchPosition(unsigned int index, unsigned int position):
|
||||
index(index),
|
||||
position(position)
|
||||
{
|
||||
}
|
||||
unsigned int index;
|
||||
unsigned int position;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class Boards
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Boards)
|
||||
|
||||
public:
|
||||
|
||||
Boards(Board::Type board)
|
||||
{
|
||||
setBoardType(board);
|
||||
}
|
||||
|
||||
void setBoardType(const Board::Type & board);
|
||||
Board::Type getBoardType() const { return m_boardType; }
|
||||
|
||||
const uint32_t getFourCC() const { return getFourCC(m_boardType); }
|
||||
const int getEEpromSize() const { return getEEpromSize(m_boardType); }
|
||||
const int getFlashSize() const { return getFlashSize(m_boardType); }
|
||||
const Board::SwitchInfo getSwitchInfo(int index) const { return getSwitchInfo(m_boardType, index); }
|
||||
const int getCapability(Board::Capability capability) const { return getCapability(m_boardType, capability); }
|
||||
const QString getAnalogInputName(int index) const { return getAnalogInputName(m_boardType, index); }
|
||||
const bool isBoardCompatible(Board::Type board2) const { return isBoardCompatible(m_boardType, board2); }
|
||||
|
||||
static uint32_t getFourCC(Board::Type board);
|
||||
static const int getEEpromSize(Board::Type board);
|
||||
static const int getFlashSize(Board::Type board);
|
||||
static const Board::SwitchInfo getSwitchInfo(Board::Type board, int index);
|
||||
static const int getCapability(Board::Type board, Board::Capability capability);
|
||||
static const QString getAxisName(int index);
|
||||
static const QString getAnalogInputName(Board::Type board, int index);
|
||||
static const bool isBoardCompatible(Board::Type board1, Board::Type board2);
|
||||
static const QString getBoardName(Board::Type board);
|
||||
|
||||
protected:
|
||||
|
||||
Board::Type m_boardType;
|
||||
};
|
||||
|
||||
// temporary aliases for transition period, use Boards class instead.
|
||||
#define getBoardCapability(b__, c__) Boards::getCapability(b__, c__)
|
||||
|
||||
#define IS_9X(board) (board==Board::BOARD_STOCK || board==Board::BOARD_M128)
|
||||
#define IS_STOCK(board) (board==Board::BOARD_STOCK)
|
||||
#define IS_M128(board) (board==Board::BOARD_M128)
|
||||
#define IS_2560(board) (board==Board::BOARD_GRUVIN9X || board==Board::BOARD_MEGA2560)
|
||||
#define IS_SKY9X(board) (board==Board::BOARD_SKY9X || board==Board::BOARD_9XRPRO || board==Board::BOARD_AR9X)
|
||||
#define IS_9XRPRO(board) (board==Board::BOARD_9XRPRO)
|
||||
#define IS_TARANIS_XLITE(board) (board==Board::BOARD_TARANIS_XLITE)
|
||||
#define IS_TARANIS_X7(board) (board==Board::BOARD_TARANIS_X7)
|
||||
#define IS_TARANIS_X9(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS_X9D(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP)
|
||||
#define IS_TARANIS_PLUS(board) (board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS_X9E(board) (board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board))
|
||||
#define IS_TARANIS_SMALL(board) (board==Board::BOARD_TARANIS_X7 || board==Board::BOARD_TARANIS_XLITE)
|
||||
#define IS_TARANIS_NOT_X9E(board) (IS_TARANIS(board) && !IS_TARANIS_X9E(board))
|
||||
#define IS_HORUS_X12S(board) (board==Board::BOARD_X12S)
|
||||
#define IS_HORUS_X10(board) (board==Board::BOARD_X10)
|
||||
#define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board))
|
||||
#define IS_HORUS_OR_TARANIS(board) (IS_HORUS(board) || IS_TARANIS(board))
|
||||
#define IS_STM32(board) (IS_TARANIS(board) || IS_HORUS(board))
|
||||
#define IS_ARM(board) (IS_STM32(board) || IS_SKY9X(board))
|
||||
#define HAS_LARGE_LCD(board) (IS_HORUS(board) || IS_TARANIS_X9(board))
|
||||
|
||||
#endif // _BOARDS_H_
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "curvereference.h"
|
||||
|
||||
#include "helpers.h" // for Helpers::getAdjustmentString()
|
||||
#include "radiodata.h" // for ModelData
|
||||
|
||||
QString CurveReference::toString(const ModelData * model, bool verbose) const
|
||||
{
|
||||
if (value == 0) {
|
||||
return "----";
|
||||
}
|
||||
|
||||
QString ret;
|
||||
unsigned idx = abs(value) - 1;
|
||||
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
ret = tr("Diff(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_EXPO:
|
||||
ret = tr("Expo(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_FUNC:
|
||||
ret = QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3);
|
||||
if (verbose)
|
||||
ret = tr("Function(%1)").arg(ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (model)
|
||||
ret = model->curves[idx].nameToString(idx);
|
||||
else
|
||||
ret = CurveData().nameToString(idx);
|
||||
if (verbose)
|
||||
ret = tr("Curve(%1)").arg(ret);
|
||||
if (value < 0)
|
||||
ret.prepend(CPN_STR_SW_INDICATOR_REV);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef CURVEREFERENCE_H
|
||||
#define CURVEREFERENCE_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class ModelData;
|
||||
|
||||
class CurveReference {
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveReference)
|
||||
|
||||
public:
|
||||
enum CurveRefType {
|
||||
CURVE_REF_DIFF,
|
||||
CURVE_REF_EXPO,
|
||||
CURVE_REF_FUNC,
|
||||
CURVE_REF_CUSTOM
|
||||
};
|
||||
|
||||
CurveReference() { clear(); }
|
||||
|
||||
CurveReference(CurveRefType type, int value):
|
||||
type(type),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
|
||||
void clear() { memset(this, 0, sizeof(CurveReference)); }
|
||||
|
||||
CurveRefType type;
|
||||
int value;
|
||||
|
||||
QString toString(const ModelData * model = NULL, bool verbose = true) const;
|
||||
};
|
||||
|
||||
#endif // CURVEREFERENCE_H
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customfunctiondata.h"
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void CustomFunctionData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(CustomFunctionData));
|
||||
if (!getCurrentFirmware()->getCapability(SafetyChannelCustomFunction)) {
|
||||
func = FuncTrainer;
|
||||
}
|
||||
}
|
||||
|
||||
bool CustomFunctionData::isEmpty() const
|
||||
{
|
||||
return (swtch.type == SWITCH_TYPE_NONE);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::nameToString(int index, bool globalContext) const
|
||||
{
|
||||
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index+1, 0, true);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
{
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
|
||||
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return tr("Trainer");
|
||||
else if (func == FuncTrainerRUD)
|
||||
return tr("Trainer RUD");
|
||||
else if (func == FuncTrainerELE)
|
||||
return tr("Trainer ELE");
|
||||
else if (func == FuncTrainerTHR)
|
||||
return tr("Trainer THR");
|
||||
else if (func == FuncTrainerAIL)
|
||||
return tr("Trainer AIL");
|
||||
else if (func == FuncInstantTrim)
|
||||
return tr("Instant Trim");
|
||||
else if (func == FuncPlaySound)
|
||||
return tr("Play Sound");
|
||||
else if (func == FuncPlayHaptic)
|
||||
return tr("Haptic");
|
||||
else if (func == FuncReset)
|
||||
return tr("Reset");
|
||||
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3)
|
||||
return tr("Set Timer %1").arg(func-FuncSetTimer1+1);
|
||||
else if (func == FuncVario)
|
||||
return tr("Vario");
|
||||
else if (func == FuncPlayPrompt)
|
||||
return tr("Play Track");
|
||||
else if (func == FuncPlayBoth)
|
||||
return tr("Play Both");
|
||||
else if (func == FuncPlayValue)
|
||||
return tr("Play Value");
|
||||
else if (func == FuncPlayScript)
|
||||
return tr("Play Script");
|
||||
else if (func == FuncLogs)
|
||||
return tr("SD Logs");
|
||||
else if (func == FuncVolume)
|
||||
return tr("Volume");
|
||||
else if (func == FuncBacklight)
|
||||
return tr("Backlight");
|
||||
else if (func == FuncScreenshot)
|
||||
return tr("Screenshot");
|
||||
else if (func == FuncBackgroundMusic)
|
||||
return tr("Background Music");
|
||||
else if (func == FuncBackgroundMusicPause)
|
||||
return tr("Background Music Pause");
|
||||
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
|
||||
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model));
|
||||
else if (func == FuncSetFailsafeInternalModule)
|
||||
return tr("SetFailsafe Int. Module");
|
||||
else if (func == FuncSetFailsafeExternalModule)
|
||||
return tr("SetFailsafe Ext. Module");
|
||||
else if (func == FuncRangeCheckInternalModule)
|
||||
return tr("RangeCheck Int. Module");
|
||||
else if (func == FuncRangeCheckExternalModule)
|
||||
return tr("RangeCheck Ext. Module");
|
||||
else if (func == FuncBindInternalModule)
|
||||
return tr("Bind Int. Module");
|
||||
else if (func == FuncBindExternalModule)
|
||||
return tr("Bind Ext. Module");
|
||||
else {
|
||||
return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is)
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox * b, unsigned int value = 0)
|
||||
{
|
||||
int val = 0;
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
b->addItem(tr("Timer1"), val++);
|
||||
b->addItem(tr("Timer2"), val++);
|
||||
if (IS_ARM(board)) {
|
||||
b->addItem( tr("Timer3"), val++);
|
||||
}
|
||||
b->addItem(tr("Flight"), val++);
|
||||
b->addItem(tr("Telemetry"), val++);
|
||||
int reCount = firmware->getCapability(RotaryEncoders);
|
||||
if (reCount == 1) {
|
||||
b->addItem(tr("Rotary Encoder"), val++);
|
||||
}
|
||||
else if (reCount == 2) {
|
||||
b->addItem(tr("REa"), val++);
|
||||
b->addItem(tr("REb"), val++);
|
||||
}
|
||||
if ((int)value < b->count()) {
|
||||
b->setCurrentIndex(value);
|
||||
}
|
||||
if (model && IS_ARM(board)) {
|
||||
for (int i=0; i<CPN_MAX_SENSORS; ++i) {
|
||||
if (model->sensorData[i].isAvailable()) {
|
||||
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i);
|
||||
b->addItem(item.toString(model), val+i);
|
||||
if ((int)value == val+i) {
|
||||
b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populatePlaySoundParams(QStringList & qs)
|
||||
{
|
||||
qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ;
|
||||
qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ;
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateHapticParams(QStringList & qs)
|
||||
{
|
||||
qs << "0" << "1" << "2" << "3";
|
||||
}
|
||||
|
||||
QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||
{
|
||||
QStringList qs;
|
||||
if (func <= FuncInstantTrim) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
else if (func==FuncLogs) {
|
||||
return QString("%1").arg(param/10.0) + tr("s");
|
||||
}
|
||||
else if (func==FuncPlaySound) {
|
||||
CustomFunctionData::populatePlaySoundParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if (func==FuncPlayHaptic) {
|
||||
CustomFunctionData::populateHapticParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if (func==FuncReset) {
|
||||
QComboBox cb;
|
||||
CustomFunctionData::populateResetParams(model, &cb);
|
||||
int pos = cb.findData(param);
|
||||
if (pos >= 0)
|
||||
return cb.itemText(pos);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if ((func==FuncVolume)|| (func==FuncPlayValue)) {
|
||||
RawSource item(param);
|
||||
return item.toString(model);
|
||||
}
|
||||
else if ((func==FuncPlayPrompt) || (func==FuncPlayBoth)) {
|
||||
if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
else {
|
||||
return paramarm;
|
||||
}
|
||||
}
|
||||
else if ((func>=FuncAdjustGV1) && (func<FuncCount)) {
|
||||
switch (adjustMode) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
return tr("Value ")+QString("%1").arg(param);
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
return RawSource(param).toString();
|
||||
case FUNC_ADJUST_GVAR_INCDEC:
|
||||
if (param==0) return tr("Decr:") + " -1";
|
||||
else return tr("Incr:") + " +1";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString CustomFunctionData::repeatToString() const
|
||||
{
|
||||
if (repeatParam == -1) {
|
||||
return tr("played once, not during startup");
|
||||
}
|
||||
else if (repeatParam == 0) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
unsigned int step = IS_ARM(getCurrentBoard()) ? 1 : 10;
|
||||
return tr("repeat(%1s)").arg(step*repeatParam);
|
||||
}
|
||||
}
|
||||
|
||||
QString CustomFunctionData::enabledToString() const
|
||||
{
|
||||
if ((func>=FuncOverrideCH1 && func<=FuncOverrideCH32) ||
|
||||
(func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) ||
|
||||
(func==FuncReset) ||
|
||||
(func>=FuncSetTimer1 && func<=FuncSetTimer2) ||
|
||||
(func==FuncVolume) ||
|
||||
(func <= FuncInstantTrim)) {
|
||||
if (!enabled) {
|
||||
return tr("DISABLED");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("CFN"), 8);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
||||
swtch.convert(cstate);
|
||||
if (func == FuncVolume || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
||||
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOMFUNCTIONDATA_H
|
||||
#define CUSTOMFUNCTIONDATA_H
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QComboBox>
|
||||
|
||||
class Firmware;
|
||||
class ModelData;
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum AssignFunc {
|
||||
FuncOverrideCH1 = 0,
|
||||
FuncOverrideCH32 = FuncOverrideCH1+CPN_MAX_CHNOUT-1,
|
||||
FuncTrainer,
|
||||
FuncTrainerRUD,
|
||||
FuncTrainerELE,
|
||||
FuncTrainerTHR,
|
||||
FuncTrainerAIL,
|
||||
FuncInstantTrim,
|
||||
FuncPlaySound,
|
||||
FuncPlayHaptic,
|
||||
FuncReset,
|
||||
FuncSetTimer1,
|
||||
FuncSetTimer2,
|
||||
FuncSetTimer3,
|
||||
FuncVario,
|
||||
FuncPlayPrompt,
|
||||
FuncPlayBoth,
|
||||
FuncPlayValue,
|
||||
FuncPlayScript,
|
||||
FuncLogs,
|
||||
FuncVolume,
|
||||
FuncBacklight,
|
||||
FuncScreenshot,
|
||||
FuncBackgroundMusic,
|
||||
FuncBackgroundMusicPause,
|
||||
FuncAdjustGV1,
|
||||
FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1,
|
||||
FuncSetFailsafeInternalModule,
|
||||
FuncSetFailsafeExternalModule,
|
||||
FuncRangeCheckInternalModule,
|
||||
FuncRangeCheckExternalModule,
|
||||
FuncBindInternalModule,
|
||||
FuncBindExternalModule,
|
||||
FuncCount,
|
||||
FuncReserve = -1
|
||||
};
|
||||
|
||||
enum GVarAdjustModes
|
||||
{
|
||||
FUNC_ADJUST_GVAR_CONSTANT,
|
||||
FUNC_ADJUST_GVAR_SOURCE,
|
||||
FUNC_ADJUST_GVAR_GVAR,
|
||||
FUNC_ADJUST_GVAR_INCDEC
|
||||
};
|
||||
|
||||
class CustomFunctionData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CustomFunctionData)
|
||||
|
||||
public:
|
||||
CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
|
||||
RawSwitch swtch;
|
||||
AssignFunc func;
|
||||
int param;
|
||||
char paramarm[10];
|
||||
unsigned int enabled; // TODO perhaps not any more the right name
|
||||
unsigned int adjustMode;
|
||||
int repeatParam;
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
QString nameToString(int index, bool globalContext = false) const;
|
||||
QString funcToString(const ModelData * model = NULL) const;
|
||||
QString paramToString(const ModelData * model) const;
|
||||
QString repeatToString() const;
|
||||
QString enabledToString() const;
|
||||
|
||||
static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value);
|
||||
static void populatePlaySoundParams(QStringList & qs);
|
||||
static void populateHapticParams(QStringList & qs);
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // CUSTOMFUNCTIONDATA_H
|
||||
@@ -1,805 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _EEPROMIMPORTEXPORT_H_
|
||||
#define _EEPROMIMPORTEXPORT_H_
|
||||
|
||||
#include "customdebug.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QBitArray>
|
||||
|
||||
class DataField {
|
||||
Q_DECLARE_TR_FUNCTIONS(DataField)
|
||||
|
||||
public:
|
||||
DataField(DataField * parent, const char * name=""):
|
||||
parent(parent),
|
||||
name(name)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DataField()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const QString & getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual unsigned int size() = 0;
|
||||
virtual void ExportBits(QBitArray & output) = 0;
|
||||
virtual void ImportBits(const QBitArray & input) = 0;
|
||||
|
||||
QBitArray bytesToBits(QByteArray bytes)
|
||||
{
|
||||
QBitArray bits(bytes.count()*8);
|
||||
// Convert from QByteArray to QBitArray
|
||||
for (int i=0; i<bytes.count(); ++i)
|
||||
for (int b=0; b<8; ++b)
|
||||
bits.setBit(i*8+b, bytes.at(i)&(1<<b));
|
||||
return bits;
|
||||
}
|
||||
|
||||
QByteArray bitsToBytes(QBitArray bits, int offset=0)
|
||||
{
|
||||
QByteArray bytes;
|
||||
bytes.resize((offset+bits.count()+7)/8);
|
||||
bytes.fill(0);
|
||||
// Convert from QBitArray to QByteArray
|
||||
for (int b=0; b<bits.count(); ++b)
|
||||
bytes[(b+offset)/8] = ( bytes.at((b+offset)/8) | ((bits[b]?1:0)<<((b+offset)%8)));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int Export(QByteArray & output)
|
||||
{
|
||||
QBitArray result;
|
||||
ExportBits(result);
|
||||
output = bitsToBytes(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Import(const QByteArray & input)
|
||||
{
|
||||
QBitArray bits = bytesToBits(input);
|
||||
if ((unsigned int)bits.size() < size()) {
|
||||
qDebug() << QString("Error importing %1: size to small %2/%3").arg(getName()).arg(input.size()).arg(size());
|
||||
return -1;
|
||||
}
|
||||
ImportBits(bits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int Dump(int level=0, int offset=0)
|
||||
{
|
||||
QBitArray bits;
|
||||
ExportBits(bits);
|
||||
QByteArray bytes = bitsToBytes(bits);
|
||||
int result = (offset+bits.count()) % 8;
|
||||
for (int i=0; i<level; i++) printf(" ");
|
||||
if (bits.count() % 8 == 0)
|
||||
printf("%s (%dbytes) ", getName().toLatin1().constData(), bytes.count());
|
||||
else
|
||||
printf("%s (%dbits) ", getName().toLatin1().constData(), bits.count());
|
||||
for (int i=0; i<bytes.count(); i++) {
|
||||
unsigned char c = bytes[i];
|
||||
if ((i==0 && offset) || (i==bytes.count()-1 && result!=0))
|
||||
printf("(%02x) ", c);
|
||||
else
|
||||
printf("%02x ", c);
|
||||
}
|
||||
printf("\n"); fflush(stdout);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void setError(const QString & error)
|
||||
{
|
||||
if (parent) {
|
||||
parent->setError(error);
|
||||
}
|
||||
else {
|
||||
qWarning() << qPrintable(error);
|
||||
}
|
||||
}
|
||||
|
||||
DataField * parent;
|
||||
QString name;
|
||||
};
|
||||
|
||||
class ProxyField: public DataField {
|
||||
public:
|
||||
explicit ProxyField(DataField * parent):
|
||||
DataField(parent, "Proxy")
|
||||
{
|
||||
}
|
||||
|
||||
virtual DataField * getField() = 0;
|
||||
|
||||
};
|
||||
|
||||
template<class container, int N>
|
||||
class BaseUnsignedField: public DataField {
|
||||
public:
|
||||
BaseUnsignedField(DataField * parent, container & field):
|
||||
DataField(parent, "Unsigned"),
|
||||
field(field),
|
||||
min(0),
|
||||
max(std::numeric_limits<container>::max())
|
||||
{
|
||||
}
|
||||
|
||||
BaseUnsignedField(DataField * parent, container & field, const char * name):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(0),
|
||||
max(std::numeric_limits<container>::max())
|
||||
{
|
||||
}
|
||||
|
||||
BaseUnsignedField(DataField * parent, container & field, container min, container max, const char * name="Unsigned"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(min),
|
||||
max(max)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
container value = field;
|
||||
if (value > max) value = max;
|
||||
if (value < min) value = min;
|
||||
|
||||
output.resize(N);
|
||||
for (int i=0; i<N; i++) {
|
||||
if (value & ((container)1<<i)) {
|
||||
output.setBit(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
field = 0;
|
||||
for (int i=0; i<N; i++) {
|
||||
if (input[i])
|
||||
field |= ((container)1<<i);
|
||||
}
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
protected:
|
||||
container & field;
|
||||
container min;
|
||||
container max;
|
||||
|
||||
private:
|
||||
BaseUnsignedField();
|
||||
};
|
||||
|
||||
template <int N>
|
||||
class UnsignedField : public BaseUnsignedField<unsigned int, N>
|
||||
{
|
||||
public:
|
||||
UnsignedField(DataField * parent, unsigned int & field):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field)
|
||||
{
|
||||
}
|
||||
|
||||
UnsignedField(DataField * parent, unsigned int & field, const char *name):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field, name)
|
||||
{
|
||||
}
|
||||
|
||||
UnsignedField(DataField * parent, unsigned int & field, unsigned int min, unsigned int max, const char *name="Unsigned"):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field, min, max, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<int N>
|
||||
class BoolField: public DataField {
|
||||
public:
|
||||
explicit BoolField(DataField * parent, bool & field):
|
||||
DataField(parent, "Bool"),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
output.resize(N);
|
||||
if (field) {
|
||||
output.setBit(0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
field = input[0] ? true : false;
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool & field;
|
||||
|
||||
private:
|
||||
BoolField();
|
||||
};
|
||||
|
||||
template<int N>
|
||||
class SignedField: public DataField {
|
||||
public:
|
||||
SignedField(DataField * parent, int & field):
|
||||
DataField(parent, "Signed"),
|
||||
field(field),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
SignedField(DataField * parent, int & field, const char *name):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
SignedField(DataField * parent, int & field, int min, int max, const char *name="Signed"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(min),
|
||||
max(max)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
int value = field;
|
||||
if (value > max) value = max;
|
||||
if (value < min) value = min;
|
||||
|
||||
output.resize(N);
|
||||
for (int i=0; i<N; i++) {
|
||||
if (((unsigned int)value) & (1<<i))
|
||||
output.setBit(i);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
unsigned int value = 0;
|
||||
for (int i=0; i<N; i++) {
|
||||
if (input[i])
|
||||
value |= (1<<i);
|
||||
}
|
||||
|
||||
if (input[N-1]) {
|
||||
for (unsigned int i=N; i<8*sizeof(int); i++) {
|
||||
value |= (1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
field = (int)value;
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
protected:
|
||||
int & field;
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
template<int N>
|
||||
class SpareBitsField: public UnsignedField<N> {
|
||||
public:
|
||||
SpareBitsField(DataField * parent):
|
||||
UnsignedField<N>(parent, spare, 0, 0, "Spare"),
|
||||
spare(0)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
unsigned int spare;
|
||||
};
|
||||
|
||||
template<int N>
|
||||
class CharField: public DataField {
|
||||
public:
|
||||
CharField(DataField * parent, char * field, bool truncate=true, const char * name="Char"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
truncate(truncate)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
output.resize(N*8);
|
||||
int b = 0;
|
||||
int len = truncate ? strlen(field) : N;
|
||||
for (int i=0; i<N; i++) {
|
||||
int idx = (i>=len ? 0 : field[i]);
|
||||
for (int j=0; j<8; j++, b++) {
|
||||
if (idx & (1<<j))
|
||||
output.setBit(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
unsigned int b = 0;
|
||||
for (int i=0; i<N; i++) {
|
||||
int8_t idx = 0;
|
||||
for (int j=0; j<8; j++) {
|
||||
if (input[b++])
|
||||
idx |= (1<<j);
|
||||
}
|
||||
field[i] = idx;
|
||||
}
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return 8*N;
|
||||
}
|
||||
|
||||
protected:
|
||||
char * field;
|
||||
bool truncate;
|
||||
};
|
||||
|
||||
static const char specialCharsTab[] = "_-.,";
|
||||
static inline int8_t char2idx(char c)
|
||||
{
|
||||
if (c==' ') return 0;
|
||||
if (c>='A' && c<='Z') return 1+c-'A';
|
||||
if (c>='a' && c<='z') return -1-c+'a';
|
||||
if (c>='0' && c<='9') return 27+c-'0';
|
||||
for (int8_t i=0;;i++) {
|
||||
char cc = specialCharsTab[i];
|
||||
if (cc==0) return 0;
|
||||
if (cc==c) return 37+i;
|
||||
}
|
||||
}
|
||||
|
||||
#define ZCHAR_MAX 40
|
||||
static inline char idx2char(int8_t idx)
|
||||
{
|
||||
if (idx == 0) return ' ';
|
||||
if (idx < 0) {
|
||||
if (idx > -27) return 'a' - idx - 1;
|
||||
idx = -idx;
|
||||
}
|
||||
if (idx < 27) return 'A' + idx - 1;
|
||||
if (idx < 37) return '0' + idx - 27;
|
||||
if (idx <= ZCHAR_MAX) return specialCharsTab[idx-37];
|
||||
return ' ';
|
||||
}
|
||||
|
||||
template<int N>
|
||||
class ZCharField: public DataField {
|
||||
public:
|
||||
ZCharField(DataField * parent, char * field, const char * name = "ZChar"):
|
||||
DataField(parent, name),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
output.resize(N*8);
|
||||
int b = 0;
|
||||
int len = strlen(field);
|
||||
for (int i=0; i<N; i++) {
|
||||
int idx = i>=len ? 0 : char2idx(field[i]);
|
||||
for (int j=0; j<8; j++, b++) {
|
||||
if (idx & (1<<j))
|
||||
output.setBit(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
unsigned int b = 0;
|
||||
for (int i=0; i<N; i++) {
|
||||
int8_t idx = 0;
|
||||
for (int j=0; j<8; j++) {
|
||||
if (input[b++])
|
||||
idx |= (1<<j);
|
||||
}
|
||||
field[i] = idx2char(idx);
|
||||
}
|
||||
|
||||
field[N] = '\0';
|
||||
for (int i=N-1; i>=0; i--) {
|
||||
if (field[i] == ' ')
|
||||
field[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return 8*N;
|
||||
}
|
||||
|
||||
protected:
|
||||
char * field;
|
||||
};
|
||||
|
||||
class StructField: public DataField {
|
||||
public:
|
||||
StructField(DataField * parent, const char * name="Struct"):
|
||||
DataField(parent, name)
|
||||
{
|
||||
}
|
||||
|
||||
~StructField() {
|
||||
foreach(DataField * field, fields) {
|
||||
delete field;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Append(DataField * field) {
|
||||
//qCDebug(eepromImport) << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
|
||||
fields.append(field);
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
int offset = 0;
|
||||
output.resize(size());
|
||||
foreach(DataField *field, fields) {
|
||||
QBitArray bits;
|
||||
field->ExportBits(bits);
|
||||
for (int i=0; i<bits.size(); i++)
|
||||
output[offset++] = bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
qCDebug(eepromImport) << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
|
||||
int offset = 0;
|
||||
foreach(DataField *field, fields) {
|
||||
unsigned int size = field->size();
|
||||
QBitArray bits(size);
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
bits[i] = input[offset++];
|
||||
}
|
||||
field->ImportBits(bits);
|
||||
}
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
foreach(DataField *field, fields) {
|
||||
result += field->size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual int Dump(int level=0, int offset=0)
|
||||
{
|
||||
for (int i=0; i<level; i++) printf(" ");
|
||||
printf("%s (%d bytes)\n", getName().toLatin1().constData(), size()/8);
|
||||
foreach(DataField *field, fields) {
|
||||
offset = field->Dump(level+1, offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected:
|
||||
QList<DataField *> fields;
|
||||
};
|
||||
|
||||
class TransformedField: public DataField {
|
||||
public:
|
||||
TransformedField(DataField * parent, DataField & field):
|
||||
DataField(parent),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TransformedField()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ExportBits(QBitArray & output)
|
||||
{
|
||||
beforeExport();
|
||||
field.ExportBits(output);
|
||||
}
|
||||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
qCDebug(eepromImport) << QString("\timporting TransformedField %1:").arg(field.getName());
|
||||
field.ImportBits(input);
|
||||
afterImport();
|
||||
}
|
||||
|
||||
|
||||
virtual const QString & getName()
|
||||
{
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
{
|
||||
return field.size();
|
||||
}
|
||||
|
||||
virtual void beforeExport() = 0;
|
||||
|
||||
virtual void afterImport() = 0;
|
||||
|
||||
virtual int Dump(int level=0, int offset=0)
|
||||
{
|
||||
beforeExport();
|
||||
return field.Dump(level, offset);
|
||||
}
|
||||
|
||||
protected:
|
||||
DataField & field;
|
||||
};
|
||||
|
||||
class ConversionTable {
|
||||
|
||||
public:
|
||||
bool exportValue(const int before, int &after)
|
||||
{
|
||||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=exportTable.begin(); it!=exportTable.end(); it++) {
|
||||
ConversionTuple & tuple = *it;
|
||||
if (before == tuple.a) {
|
||||
after = tuple.b;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool importValue(const int before, int &after)
|
||||
{
|
||||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=importTable.begin(); it!=importTable.end(); it++) {
|
||||
ConversionTuple & tuple = *it;
|
||||
if (before == tuple.b) {
|
||||
after = tuple.a;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
class ConversionTuple {
|
||||
public:
|
||||
ConversionTuple(const int a, const int b):
|
||||
a(a),
|
||||
b(b)
|
||||
{
|
||||
}
|
||||
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
void addConversion(const int a, const int b)
|
||||
{
|
||||
ConversionTuple conversion(a, b);
|
||||
importTable.push_back(conversion);
|
||||
exportTable.push_back(conversion);
|
||||
}
|
||||
|
||||
void addImportConversion(const int a, const int b)
|
||||
{
|
||||
importTable.push_back(ConversionTuple(a, b));
|
||||
}
|
||||
|
||||
void addExportConversion(const int a, const int b)
|
||||
{
|
||||
exportTable.push_back(ConversionTuple(a, b));
|
||||
}
|
||||
|
||||
std::list<ConversionTuple> importTable;
|
||||
std::list<ConversionTuple> exportTable;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class ConversionField: public TransformedField {
|
||||
public:
|
||||
ConversionField(DataField * parent, int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field, name),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(table),
|
||||
shift(0),
|
||||
scale(1),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX),
|
||||
exportFunc(NULL),
|
||||
importFunc(NULL),
|
||||
error(error)
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(DataField * parent, unsigned int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, (unsigned int &)_field, name),
|
||||
field((int &)field),
|
||||
_field(0),
|
||||
table(table),
|
||||
shift(0),
|
||||
scale(0),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX),
|
||||
exportFunc(NULL),
|
||||
importFunc(NULL),
|
||||
error(error)
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(DataField * parent, int & field, int (*exportFunc)(int), int (*importFunc)(int)):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
shift(0),
|
||||
scale(0),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX),
|
||||
exportFunc(exportFunc),
|
||||
importFunc(importFunc),
|
||||
error("")
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(DataField * parent, int & field, int shift, int scale=0, int min=INT_MIN, int max=INT_MAX, const char *name = "Signed shifted"):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field, name),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
shift(shift),
|
||||
scale(scale),
|
||||
min(min),
|
||||
max(max),
|
||||
exportFunc(NULL),
|
||||
importFunc(NULL),
|
||||
error("")
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(DataField * parent, unsigned int & field, int shift, int scale=0):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, (unsigned int &)_field),
|
||||
field((int &)field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
shift(shift),
|
||||
scale(scale),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX),
|
||||
exportFunc(NULL),
|
||||
importFunc(NULL),
|
||||
error("")
|
||||
{
|
||||
}
|
||||
|
||||
virtual void beforeExport()
|
||||
{
|
||||
_field = field;
|
||||
|
||||
if (scale) {
|
||||
_field /= scale;
|
||||
}
|
||||
|
||||
if (table) {
|
||||
if (!table->exportValue(_field, _field)) {
|
||||
setError(error.isEmpty() ? DataField::tr("Conversion error on field %1").arg(name) : error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
if (_field < min)
|
||||
_field = min + shift;
|
||||
else if (_field > max)
|
||||
_field = max + shift;
|
||||
else
|
||||
_field += shift;
|
||||
}
|
||||
|
||||
if (exportFunc) {
|
||||
_field = exportFunc(_field);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void afterImport()
|
||||
{
|
||||
field = _field;
|
||||
|
||||
if (table) {
|
||||
if (table->importValue(field, field))
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
field -= shift;
|
||||
}
|
||||
|
||||
if (importFunc) {
|
||||
field = importFunc(field);
|
||||
}
|
||||
|
||||
if (scale) {
|
||||
field *= scale;
|
||||
}
|
||||
qCDebug(eepromImport) << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
|
||||
}
|
||||
|
||||
protected:
|
||||
T internalField;
|
||||
int & field;
|
||||
int _field;
|
||||
ConversionTable * table;
|
||||
int shift;
|
||||
int scale;
|
||||
int min;
|
||||
int max;
|
||||
int (*exportFunc)(int);
|
||||
int (*importFunc)(int);
|
||||
const QString error;
|
||||
};
|
||||
|
||||
#endif // _EEPROMIMPORTEXPORT_H_
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "firmwares/opentx/opentxeeprom.h"
|
||||
#include "firmwareinterface.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QMessageBox>
|
||||
#include <bitset>
|
||||
|
||||
float ValToTim(int value)
|
||||
{
|
||||
return ((value < -109 ? 129+value : (value < 7 ? (113+value)*5 : (53+value)*10))/10.0);
|
||||
}
|
||||
|
||||
int TimToVal(float value)
|
||||
{
|
||||
int temp;
|
||||
if (value>60) {
|
||||
temp=136+round((value-60));
|
||||
}
|
||||
else if (value>2) {
|
||||
temp=20+round((value-2.0)*2.0);
|
||||
}
|
||||
else {
|
||||
temp=round(value*10.0);
|
||||
}
|
||||
return (temp-129);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EEpromInterface globals
|
||||
*/
|
||||
|
||||
// TODO: No globals
|
||||
|
||||
QList<EEPROMInterface *> eepromInterfaces;
|
||||
|
||||
void unregisterEEpromInterfaces()
|
||||
{
|
||||
foreach(EEPROMInterface * intf, eepromInterfaces) {
|
||||
// qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast<uint64_t>(intf), 16 );
|
||||
delete intf;
|
||||
}
|
||||
OpenTxEepromCleanup();
|
||||
}
|
||||
|
||||
#if 0 // TODO: remove if unused, currently commented out in mdiChild.cpp
|
||||
// TODO: No GUI here, e.g. return string list instead
|
||||
void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList errorsList;
|
||||
|
||||
errorsList << tr("Possible causes for this:");
|
||||
|
||||
if (errors.test(UNSUPPORTED_NEWER_VERSION)) { errorsList << tr("- Eeprom is from a newer version of OpenTX"); }
|
||||
if (errors.test(NOT_OPENTX)) { errorsList << tr("- Eeprom is not from OpenTX"); }
|
||||
if (errors.test(NOT_TH9X)) { errorsList << tr("- Eeprom is not from Th9X"); }
|
||||
if (errors.test(NOT_GRUVIN9X)) { errorsList << tr("- Eeprom is not from Gruvin9X"); }
|
||||
if (errors.test(NOT_ERSKY9X)) { errorsList << tr("- Eeprom is not from ErSky9X"); }
|
||||
if (errors.test(NOT_ER9X)) { errorsList << tr("- Eeprom is not from Er9X"); }
|
||||
if (errors.test(WRONG_SIZE)) { errorsList << tr("- Eeprom size is invalid"); }
|
||||
if (errors.test(WRONG_FILE_SYSTEM)) { errorsList << tr("- Eeprom file system is invalid"); }
|
||||
if (errors.test(UNKNOWN_BOARD)) { errorsList << tr("- Eeprom is from a unknown board"); }
|
||||
if (errors.test(WRONG_BOARD)) { errorsList << tr("- Eeprom is from the wrong board"); }
|
||||
if (errors.test(BACKUP_NOT_SUPPORTED)) { errorsList << tr("- Eeprom backup not supported"); }
|
||||
|
||||
if (errors.test(UNKNOWN_ERROR)) { errorsList << tr("- Something that couldn't be guessed, sorry"); }
|
||||
|
||||
if (errors.test(HAS_WARNINGS)) {
|
||||
errorsList << tr("Warning:");
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { errorsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
}
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(mainMessage);
|
||||
msgBox.setInformativeText(errorsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: No GUI here, e.g. return string list instead
|
||||
void EEPROMInterface::showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList warningsList;
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
if (errors.test(OLD_VERSION)) { warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); }
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setText(tr("Warnings!"));
|
||||
msgBox.setInformativeText(warningsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Firmware
|
||||
*/
|
||||
|
||||
// static
|
||||
QVector<Firmware *> Firmware::registeredFirmwares;
|
||||
Firmware * Firmware::defaultVariant = NULL;
|
||||
Firmware * Firmware::currentVariant = NULL;
|
||||
|
||||
// static
|
||||
Firmware * Firmware::getFirmwareForId(const QString & id)
|
||||
{
|
||||
foreach(Firmware * firmware, registeredFirmwares) {
|
||||
Firmware * result = firmware->getFirmwareVariant(id);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultVariant;
|
||||
}
|
||||
|
||||
unsigned int Firmware::getVariantNumber()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
const Firmware * base = getFirmwareBase();
|
||||
QStringList options = id.mid(base->getId().length()+1).split("-", QString::SkipEmptyParts);
|
||||
foreach(QString option, options) {
|
||||
foreach(OptionsGroup group, base->opts) {
|
||||
foreach(Option opt, group) {
|
||||
if (opt.name == option) {
|
||||
result += opt.variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Firmware::addLanguage(const char * lang)
|
||||
{
|
||||
languages.push_back(lang);
|
||||
}
|
||||
|
||||
//void Firmware::addTTSLanguage(const char * lang)
|
||||
//{
|
||||
// ttslanguages.push_back(lang);
|
||||
//}
|
||||
|
||||
void Firmware::addOption(const char * option, const QString & tooltip, unsigned variant)
|
||||
{
|
||||
addOption(Option(option, tooltip, variant));
|
||||
}
|
||||
|
||||
void Firmware::addOption(const Option & option)
|
||||
{
|
||||
addOptionsGroup({option});
|
||||
}
|
||||
|
||||
void Firmware::addOptionsGroup(const OptionsGroup & options)
|
||||
{
|
||||
this->opts.append(options);
|
||||
}
|
||||
@@ -1,424 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _EEPROMINTERFACE_H_
|
||||
#define _EEPROMINTERFACE_H_
|
||||
|
||||
#include "boards.h"
|
||||
#include "macros.h"
|
||||
#include "radiodata.h"
|
||||
#include "../../radio/src/definitions.h"
|
||||
#include "simulatorinterface.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QStringList>
|
||||
#include <QList>
|
||||
#include <QDebug>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
const uint8_t modn12x3[4][4]= {
|
||||
{1, 2, 3, 4},
|
||||
{1, 3, 2, 4},
|
||||
{4, 2, 3, 1},
|
||||
{4, 3, 2, 1} };
|
||||
|
||||
enum Capability {
|
||||
Models,
|
||||
ModelName,
|
||||
FlightModes,
|
||||
FlightModesName,
|
||||
FlightModesHaveFades,
|
||||
Imperial,
|
||||
Mixes,
|
||||
Timers,
|
||||
TimersName,
|
||||
VoicesAsNumbers,
|
||||
VoicesMaxLength,
|
||||
MultiLangVoice,
|
||||
ModelImage,
|
||||
CustomFunctions,
|
||||
SafetyChannelCustomFunction,
|
||||
LogicalSwitches,
|
||||
CustomAndSwitches,
|
||||
HasNegAndSwitches,
|
||||
LogicalSwitchesExt,
|
||||
RotaryEncoders,
|
||||
Outputs,
|
||||
ChannelsName,
|
||||
ExtraInputs,
|
||||
TrimsRange,
|
||||
ExtendedTrimsRange,
|
||||
NumCurves,
|
||||
NumCurvePoints,
|
||||
OffsetWeight,
|
||||
Simulation,
|
||||
SoundMod,
|
||||
SoundPitch,
|
||||
MaxVolume,
|
||||
MaxContrast,
|
||||
MinContrast,
|
||||
Haptic,
|
||||
HasBeeper,
|
||||
ModelTrainerEnable,
|
||||
HasExpoNames,
|
||||
HasNoExpo,
|
||||
HasMixerNames,
|
||||
HasCvNames,
|
||||
HasPxxCountry,
|
||||
HasPPMStart,
|
||||
HasGeneralUnits,
|
||||
HasFAIMode,
|
||||
OptrexDisplay,
|
||||
PPMExtCtrl,
|
||||
PPMFrameLength,
|
||||
Telemetry,
|
||||
TelemetryUnits,
|
||||
TelemetryBars,
|
||||
Heli,
|
||||
Gvars,
|
||||
GvarsInCS,
|
||||
GvarsAreNamed,
|
||||
GvarsFlightModes,
|
||||
GvarsName,
|
||||
NoTelemetryProtocol,
|
||||
TelemetryCustomScreens,
|
||||
TelemetryCustomScreensFieldsPerLine,
|
||||
TelemetryMaxMultiplier,
|
||||
HasVario,
|
||||
HasVarioSink,
|
||||
HasFailsafe,
|
||||
HasSoundMixer,
|
||||
NumModules,
|
||||
HasModuleR9MFlex,
|
||||
HasModuleR9MMini,
|
||||
PPMCenter,
|
||||
PPMUnitMicroseconds,
|
||||
SYMLimits,
|
||||
HastxCurrentCalibration,
|
||||
HasVolume,
|
||||
HasBrightness,
|
||||
PerModelTimers,
|
||||
SlowScale,
|
||||
SlowRange,
|
||||
PermTimers,
|
||||
HasSDLogs,
|
||||
CSFunc,
|
||||
LcdWidth,
|
||||
LcdHeight,
|
||||
LcdDepth,
|
||||
GetThrSwitch,
|
||||
HasDisplayText,
|
||||
HasTopLcd,
|
||||
GlobalFunctions,
|
||||
VirtualInputs,
|
||||
InputsLength,
|
||||
TrainerInputs,
|
||||
RtcTime,
|
||||
SportTelemetry,
|
||||
LuaScripts,
|
||||
LuaInputsPerScript,
|
||||
LuaOutputsPerScript,
|
||||
LimitsPer1000,
|
||||
EnhancedCurves,
|
||||
HasFasOffset,
|
||||
HasMahPersistent,
|
||||
SimulatorVariant,
|
||||
MavlinkTelemetry,
|
||||
HasInputDiff,
|
||||
HasMixerExpo,
|
||||
HasBatMeterRange,
|
||||
DangerousFunctions,
|
||||
HasModelCategories
|
||||
};
|
||||
|
||||
class EEPROMInterface
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(EEPROMInterface)
|
||||
|
||||
public:
|
||||
|
||||
EEPROMInterface(Board::Type board):
|
||||
board(board)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~EEPROMInterface() {}
|
||||
|
||||
inline Board::Type getBoard() { return board; }
|
||||
|
||||
virtual unsigned long load(RadioData &radioData, const uint8_t * eeprom, int size) = 0;
|
||||
|
||||
virtual unsigned long loadBackup(RadioData & radioData, const uint8_t * eeprom, int esize, int index) = 0;
|
||||
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0) = 0;
|
||||
|
||||
virtual int getSize(const ModelData &) = 0;
|
||||
|
||||
virtual int getSize(const GeneralSettings &) = 0;
|
||||
|
||||
//static void showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound);
|
||||
static void showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound);
|
||||
|
||||
protected:
|
||||
|
||||
Board::Type board;
|
||||
|
||||
private:
|
||||
|
||||
EEPROMInterface();
|
||||
|
||||
};
|
||||
|
||||
/* EEPROM string conversion function (used only by er9xeeprom and ersky9xeeprom) */
|
||||
inline void getEEPROMString(char *dst, const char *src, int size)
|
||||
{
|
||||
memcpy(dst, src, size);
|
||||
dst[size] = '\0';
|
||||
for (int i=size-1; i>=0; i--) {
|
||||
if (dst[i] == ' ')
|
||||
dst[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// (used only by er9xeeprom and ersky9xeeprom)
|
||||
inline int applyStickMode(int stick, unsigned int mode)
|
||||
{
|
||||
if (mode == 0 || mode > 4) {
|
||||
std::cerr << "Incorrect stick mode" << mode;
|
||||
return stick;
|
||||
}
|
||||
|
||||
if (stick >= 1 && stick <= 4)
|
||||
return modn12x3[mode-1][stick-1];
|
||||
else
|
||||
return stick;
|
||||
}
|
||||
|
||||
float ValToTim(int value);
|
||||
int TimToVal(float value);
|
||||
|
||||
void registerEEpromInterfaces();
|
||||
void unregisterEEpromInterfaces();
|
||||
void registerOpenTxFirmwares();
|
||||
void unregisterOpenTxFirmwares();
|
||||
|
||||
enum EepromLoadErrors {
|
||||
ALL_OK,
|
||||
UNKNOWN_ERROR,
|
||||
UNSUPPORTED_NEWER_VERSION,
|
||||
WRONG_SIZE,
|
||||
WRONG_FILE_SYSTEM,
|
||||
NOT_OPENTX,
|
||||
NOT_TH9X,
|
||||
NOT_GRUVIN9X,
|
||||
NOT_ERSKY9X,
|
||||
NOT_ER9X,
|
||||
UNKNOWN_BOARD,
|
||||
WRONG_BOARD,
|
||||
BACKUP_NOT_SUPPORTED,
|
||||
|
||||
HAS_WARNINGS,
|
||||
OLD_VERSION,
|
||||
WARNING_WRONG_FIRMWARE,
|
||||
|
||||
NUM_ERRORS
|
||||
};
|
||||
|
||||
class Firmware
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Firmware)
|
||||
|
||||
public:
|
||||
struct Option {
|
||||
const char * name = nullptr;
|
||||
QString tooltip;
|
||||
unsigned variant = 0;
|
||||
|
||||
explicit Option(const char * name, const QString & description, unsigned variant = 0) :
|
||||
name(name), tooltip(description), variant(variant) { }
|
||||
};
|
||||
typedef QList<Option> OptionsGroup;
|
||||
typedef QList<OptionsGroup> OptionsList;
|
||||
|
||||
|
||||
explicit Firmware(const QString & id, const QString & name, Board::Type board) :
|
||||
Firmware(nullptr, id, name, board)
|
||||
{ }
|
||||
|
||||
explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board) :
|
||||
id(id),
|
||||
name(name),
|
||||
board(board),
|
||||
variantBase(0),
|
||||
base(base),
|
||||
eepromInterface(nullptr)
|
||||
{ }
|
||||
|
||||
virtual ~Firmware() { }
|
||||
|
||||
inline const Firmware * getFirmwareBase() const
|
||||
{
|
||||
return base ? base : this;
|
||||
}
|
||||
|
||||
virtual Firmware * getFirmwareVariant(const QString & id) { return NULL; }
|
||||
|
||||
unsigned int getVariantNumber();
|
||||
|
||||
virtual void addLanguage(const char * lang);
|
||||
|
||||
//virtual void addTTSLanguage(const char * lang);
|
||||
|
||||
virtual void addOption(const char * option, const QString & tooltip = QString(), unsigned variant = 0);
|
||||
|
||||
virtual void addOption(const Option & option);
|
||||
|
||||
virtual void addOptionsGroup(const OptionsGroup & options);
|
||||
|
||||
virtual QString getStampUrl() = 0;
|
||||
|
||||
virtual QString getReleaseNotesUrl() = 0;
|
||||
|
||||
virtual QString getFirmwareUrl() = 0;
|
||||
|
||||
Board::Type getBoard() const
|
||||
{
|
||||
return board;
|
||||
}
|
||||
|
||||
void setEEpromInterface(EEPROMInterface * eeprom)
|
||||
{
|
||||
eepromInterface = eeprom;
|
||||
}
|
||||
|
||||
EEPROMInterface * getEEpromInterface()
|
||||
{
|
||||
return eepromInterface;
|
||||
}
|
||||
|
||||
QString getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
QString getId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
QList<const char *> languageList() const
|
||||
{
|
||||
return languages;
|
||||
}
|
||||
|
||||
OptionsList optionGroups() const
|
||||
{
|
||||
return opts;
|
||||
}
|
||||
|
||||
virtual int getCapability(Capability) = 0;
|
||||
|
||||
virtual QString getAnalogInputName(unsigned int index) = 0;
|
||||
|
||||
virtual QTime getMaxTimerStart() = 0;
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0) = 0;
|
||||
|
||||
const int getFlashSize();
|
||||
|
||||
static Firmware * getFirmwareForId(const QString & id);
|
||||
|
||||
static QVector<Firmware *> getRegisteredFirmwares()
|
||||
{
|
||||
return registeredFirmwares;
|
||||
}
|
||||
|
||||
static void addRegisteredFirmware(Firmware * fw)
|
||||
{
|
||||
registeredFirmwares.append(fw);
|
||||
}
|
||||
|
||||
static Firmware * getDefaultVariant()
|
||||
{
|
||||
return defaultVariant;
|
||||
}
|
||||
static void setDefaultVariant(Firmware * value)
|
||||
{
|
||||
defaultVariant = value;
|
||||
}
|
||||
|
||||
static Firmware * getCurrentVariant()
|
||||
{
|
||||
return currentVariant;
|
||||
}
|
||||
|
||||
static void setCurrentVariant(Firmware * value)
|
||||
{
|
||||
currentVariant = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
QString id;
|
||||
QString name;
|
||||
Board::Type board;
|
||||
unsigned int variantBase;
|
||||
Firmware * base;
|
||||
EEPROMInterface * eepromInterface;
|
||||
QList<const char *> languages;
|
||||
//QList<const char *> ttslanguages;
|
||||
OptionsList opts;
|
||||
|
||||
static QVector<Firmware *> registeredFirmwares;
|
||||
static Firmware * defaultVariant;
|
||||
static Firmware * currentVariant;
|
||||
};
|
||||
|
||||
inline Firmware * getCurrentFirmware()
|
||||
{
|
||||
return Firmware::getCurrentVariant();
|
||||
}
|
||||
|
||||
inline EEPROMInterface * getCurrentEEpromInterface()
|
||||
{
|
||||
return Firmware::getCurrentVariant()->getEEpromInterface();
|
||||
}
|
||||
|
||||
inline Board::Type getCurrentBoard()
|
||||
{
|
||||
return Firmware::getCurrentVariant()->getBoard();
|
||||
}
|
||||
|
||||
inline int divRoundClosest(const int n, const int d)
|
||||
{
|
||||
return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);
|
||||
}
|
||||
|
||||
inline int calcRESXto100(int x)
|
||||
{
|
||||
return divRoundClosest(x*100, 1024);
|
||||
}
|
||||
|
||||
extern QList<EEPROMInterface *> eepromInterfaces;
|
||||
|
||||
|
||||
#endif // _EEPROMINTERFACE_H_
|
||||
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "er9xeeprom.h"
|
||||
#include "helpers.h"
|
||||
#include <QObject>
|
||||
|
||||
RawSwitch er9xToSwitch(int8_t sw)
|
||||
{
|
||||
uint8_t swa = abs(sw);
|
||||
if (swa == 0)
|
||||
return RawSwitch(SWITCH_TYPE_NONE);
|
||||
else if (swa <= 9)
|
||||
return RawSwitch(SWITCH_TYPE_SWITCH, sw);
|
||||
else if (swa <= 21)
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-9 : sw+9);
|
||||
else if (sw == 22)
|
||||
return RawSwitch(SWITCH_TYPE_ON);
|
||||
else if (sw == -22)
|
||||
return RawSwitch(SWITCH_TYPE_OFF);
|
||||
else if (swa <= 22+9)
|
||||
return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-22 : sw+22);
|
||||
else
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9);
|
||||
}
|
||||
|
||||
t_Er9xTrainerMix::t_Er9xTrainerMix()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xTrainerMix));
|
||||
}
|
||||
|
||||
t_Er9xTrainerMix::operator TrainerMix()
|
||||
{
|
||||
TrainerMix c9x;
|
||||
c9x.src = srcChn;
|
||||
c9x.swtch = er9xToSwitch(swtch);
|
||||
c9x.weight = (25 * studWeight) / 8;
|
||||
c9x.mode = mode;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Er9xTrainerData::t_Er9xTrainerData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xTrainerData));
|
||||
}
|
||||
|
||||
t_Er9xTrainerData::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Er9xGeneral::t_Er9xGeneral()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xGeneral));
|
||||
}
|
||||
|
||||
Er9xGeneral::operator GeneralSettings ()
|
||||
{
|
||||
GeneralSettings result;
|
||||
result.version = myVers;
|
||||
for (int i=0; i<CPN_MAX_STICKSnPOTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
result.trainer = trainer;
|
||||
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
case 0:
|
||||
result.beeperMode = GeneralSettings::BEEPER_QUIET;
|
||||
break;
|
||||
case 1:
|
||||
result.beeperMode = GeneralSettings::BEEPER_NOKEYS;
|
||||
break;
|
||||
default:
|
||||
result.beeperMode = GeneralSettings::BEEPER_ALL;
|
||||
result.beeperLength = beeperVal - 4;
|
||||
break;
|
||||
}
|
||||
|
||||
result.disableAlarmWarning = disableAlarmWarning;
|
||||
result.stickMode = std::max((uint8_t)0, std::min(stickMode, (uint8_t)3));
|
||||
result.inactivityTimer = inactivityTimer + 10;
|
||||
result.minuteBeep = minuteBeep;
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
|
||||
result.backlightMode = 0;
|
||||
if (lightSw == 22) {
|
||||
result.backlightMode = 4;
|
||||
}
|
||||
else if (lightAutoOff) {
|
||||
result.backlightMode |= 1;
|
||||
result.backlightDelay = lightAutoOff;
|
||||
}
|
||||
else if (lightOnStickMove) {
|
||||
result.backlightMode |= 2;
|
||||
result.backlightDelay = lightOnStickMove;
|
||||
}
|
||||
|
||||
result.templateSetup = templateSetup;
|
||||
result.PPM_Multiplier = PPM_Multiplier;
|
||||
getEEPROMString(result.ownerName, ownerName, sizeof(ownerName));
|
||||
result.speakerPitch = speakerPitch;
|
||||
result.hapticStrength = hapticStrength - 3;
|
||||
result.speakerMode = speakerMode;
|
||||
return result;
|
||||
}
|
||||
|
||||
t_Er9xLimitData::t_Er9xLimitData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xLimitData));
|
||||
}
|
||||
|
||||
t_Er9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Er9xMixData::t_Er9xMixData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xMixData));
|
||||
}
|
||||
|
||||
t_Er9xMixData::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
c9x.destCh = destCh;
|
||||
if (abs(weight)>125) {
|
||||
int gvar;
|
||||
if (weight>0) {
|
||||
gvar=weight-125;
|
||||
} else {
|
||||
gvar=weight+131;
|
||||
}
|
||||
gvar+=10000;
|
||||
c9x.weight=gvar;
|
||||
} else {
|
||||
c9x.weight = weight;
|
||||
}
|
||||
if (abs(sOffset)>125) {
|
||||
int gvar;
|
||||
if (sOffset>0) {
|
||||
gvar=sOffset-125;
|
||||
} else {
|
||||
gvar=sOffset+131;
|
||||
}
|
||||
gvar+=10000;
|
||||
c9x.sOffset=gvar;
|
||||
} else {
|
||||
c9x.sOffset=sOffset;
|
||||
}
|
||||
c9x.swtch = er9xToSwitch(swtch);
|
||||
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw == 8) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 9) {
|
||||
if (swtch < 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch);
|
||||
c9x.weight = -weight;
|
||||
}
|
||||
else if (swtch > 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
if (mltpx != MLTPX_REP)
|
||||
c9x.swtch = RawSwitch(SWITCH_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 12) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw <= 20) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13);
|
||||
}
|
||||
else if (srcRaw <=37) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-38);
|
||||
}
|
||||
|
||||
if (differential==1) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_DIFF;
|
||||
c9x.curve.value = differential;
|
||||
}
|
||||
else if (curve > 6) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_CUSTOM;
|
||||
c9x.curve.value = curve - 6;
|
||||
}
|
||||
else if (curve > 0) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_FUNC;
|
||||
c9x.curve.value = curve;
|
||||
}
|
||||
|
||||
// c9x.lateOffset=lateOffset;
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
// c9x.enableFmTrim=enableFmTrim;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
RawSource er9xToSource(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value == 8) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value == 9) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value <= 12) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-10);
|
||||
}
|
||||
else if (value <= 20) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-13);
|
||||
}
|
||||
else if (value <= 36) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-21);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-36);
|
||||
}
|
||||
}
|
||||
|
||||
Er9xLogicalSwitchData::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = er9xToSource(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val2 = er9xToSource(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = er9xToSwitch(v1).toValue();
|
||||
c9x.val2 = er9xToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
|
||||
t_Er9xSafetySwData::t_Er9xSafetySwData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xSafetySwData));
|
||||
}
|
||||
|
||||
t_Er9xFrSkyChannelData::t_Er9xFrSkyChannelData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xFrSkyChannelData));
|
||||
}
|
||||
|
||||
t_Er9xFrSkyChannelData::operator FrSkyChannelData ()
|
||||
{
|
||||
FrSkyChannelData c9x;
|
||||
c9x.ratio = ratio;
|
||||
c9x.alarms[0].value = alarms_value[0];
|
||||
c9x.alarms[0].level = alarms_level & 3;
|
||||
c9x.alarms[0].greater = alarms_greater & 1;
|
||||
c9x.alarms[1].value = alarms_value[1];
|
||||
c9x.alarms[1].level = (alarms_level >> 2) & 3;
|
||||
c9x.alarms[1].greater = (alarms_greater >> 1) & 1;
|
||||
if (type==2) {
|
||||
c9x.type = 0;
|
||||
c9x.multiplier=1;
|
||||
} else {
|
||||
c9x.type = type;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Er9xFrSkyData::t_Er9xFrSkyData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Er9xFrSkyData));
|
||||
}
|
||||
|
||||
t_Er9xFrSkyData::operator FrSkyData ()
|
||||
{
|
||||
FrSkyData c9x;
|
||||
c9x.channels[0] = channels[0];
|
||||
c9x.channels[1] = channels[1];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
RawSwitch getEr9xTimerMode(int mode)
|
||||
{
|
||||
/*
|
||||
if (mode <= -33)
|
||||
return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+33));
|
||||
else if (mode <= -1)
|
||||
return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+1));
|
||||
else if (mode < 16)
|
||||
return TimerMode(mode);
|
||||
else if (mode < 16+21)
|
||||
return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16));
|
||||
else
|
||||
return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16-21));
|
||||
*/
|
||||
return RawSwitch();
|
||||
}
|
||||
|
||||
t_Er9xModelData::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0].mode = getEr9xTimerMode(tmrMode);
|
||||
c9x.timers[0].val = tmrVal;
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].ppm.frameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.customFn[0].func = FuncInstantTrim;
|
||||
if (trimSw) {
|
||||
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
|
||||
}
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.swashRingData.elevatorWeight = swashInvertELE ? -100 : 100;
|
||||
c9x.swashRingData.aileronWeight = swashInvertAIL ? -100 : 100;
|
||||
c9x.swashRingData.collectiveWeight = swashInvertCOL ? -100 : 100;
|
||||
c9x.swashRingData.type = swashType;
|
||||
c9x.swashRingData.collectiveSource = er9xToSource(swashCollectiveSource);
|
||||
c9x.swashRingData.value = swashRingValue;
|
||||
|
||||
for (int i=0; i<ER9X_MAX_MIXERS; i++) {
|
||||
Er9xMixData mix = mixData[i];
|
||||
c9x.mixData[i] = mix;
|
||||
}
|
||||
|
||||
for (int i=0; i<ER9X_NUM_CHNOUT; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
break;
|
||||
if (expoData[ch].drSw1 && !expoData[ch].drSw2) {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? expoData[ch].drSw1 : 0);
|
||||
pos = dr == 0 ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? -expoData[ch].drSw1 : (dr == 1 ? -expoData[ch].drSw2 : 0));
|
||||
}
|
||||
c9x.expoData[e].chn = ch;
|
||||
if (expoData[ch].expo[pos][0][0]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][0];
|
||||
}
|
||||
c9x.expoData[e].weight = 100 + expoData[ch].expo[pos][1][0];
|
||||
if (expoData[ch].expo[pos][0][0] == expoData[ch].expo[pos][0][1] && expoData[ch].expo[pos][1][0] == expoData[ch].expo[pos][1][1]) {
|
||||
c9x.expoData[e++].mode = 3;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
if (expoData[ch].expo[pos][0][1]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][1];
|
||||
}
|
||||
c9x.expoData[e++].weight = 100 + expoData[ch].expo[pos][1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ER9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ER9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[ER9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[ER9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[ER9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<ER9X_NUM_CSW; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
|
||||
// for (int i=0; i<ER9X_NUM_CHNOUT; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
|
||||
c9x.frsky = frsky;
|
||||
c9x.frsky.usrProto=FrSkyUsrProto;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -1,265 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ER9XEEPROM_H_
|
||||
#define _ER9XEEPROM_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eeprominterface.h"
|
||||
|
||||
//eeprom data
|
||||
#define ER9X_MAX_MIXERS 32
|
||||
#define ER9X_MAX_CURVE5 8
|
||||
#define ER9X_MAX_CURVE9 8
|
||||
#define ER9X_MAX_CSFUNC 13
|
||||
|
||||
#define MDVERS 10
|
||||
|
||||
#define ER9X_NUM_CHNOUT 16 //number of real outputchannels CH1-CH8
|
||||
#define ER9X_NUM_CSW 12 //number of custom switches
|
||||
#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots
|
||||
#define ER9X_MAX_GVARS 7
|
||||
|
||||
#define ER9X_MAX_MODES 4
|
||||
|
||||
PACK(typedef struct t_Er9xTrainerMix {
|
||||
uint8_t srcChn:3; //0-7 = ch1-8
|
||||
int8_t swtch:5;
|
||||
int8_t studWeight:6;
|
||||
uint8_t mode:2; // off, add-mode, subst-mode
|
||||
|
||||
operator TrainerMix();
|
||||
t_Er9xTrainerMix();
|
||||
}) Er9xTrainerMix; //
|
||||
|
||||
PACK(typedef struct t_Er9xTrainerData {
|
||||
int16_t calib[4];
|
||||
Er9xTrainerMix mix[4];
|
||||
|
||||
operator TrainerData();
|
||||
t_Er9xTrainerData();
|
||||
}) Er9xTrainerData;
|
||||
|
||||
PACK(typedef struct t_Er9xGeneral {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanPos[CPN_MAX_STICKSnPOTS];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
uint8_t vBatWarn;
|
||||
int8_t txVoltageCalibration;
|
||||
int8_t lightSw;
|
||||
Er9xTrainerData trainer;
|
||||
uint8_t view;
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t disableSwitchWarning:1;
|
||||
uint8_t disableMemoryWarning:1;
|
||||
uint8_t beeperVal:3;
|
||||
uint8_t reserveWarning:1;
|
||||
uint8_t disableAlarmWarning:1;
|
||||
uint8_t stickMode;
|
||||
int8_t inactivityTimer;
|
||||
uint8_t throttleReversed:1;
|
||||
uint8_t minuteBeep:1;
|
||||
uint8_t preBeep:1;
|
||||
uint8_t flashBeep:1;
|
||||
uint8_t disableSplashScreen:1;
|
||||
uint8_t disablePotScroll:1;
|
||||
uint8_t disableBG:1;
|
||||
uint8_t frskyinternalalarm:1;
|
||||
uint8_t spare_filter ; // No longer needed, left for eepe compatibility for now
|
||||
uint8_t lightAutoOff;
|
||||
uint8_t templateSetup; //RETA order according to chout_ar array
|
||||
int8_t PPM_Multiplier;
|
||||
uint8_t unused1;
|
||||
uint8_t unused2:4;
|
||||
uint8_t hideNameOnSplash:1;
|
||||
uint8_t enablePpmsim:1;
|
||||
uint8_t blightinv:1;
|
||||
uint8_t stickScroll:1;
|
||||
uint8_t speakerPitch;
|
||||
uint8_t hapticStrength;
|
||||
uint8_t speakerMode;
|
||||
uint8_t lightOnStickMove;
|
||||
|
||||
char ownerName[10];
|
||||
uint8_t switchWarningStates;
|
||||
uint8_t volume ;
|
||||
uint8_t res[3];
|
||||
uint8_t crosstrim:1;
|
||||
uint8_t spare1:7;
|
||||
|
||||
operator GeneralSettings();
|
||||
t_Er9xGeneral();
|
||||
}) Er9xGeneral;
|
||||
|
||||
PACK(typedef struct t_Er9xExpoData {
|
||||
int8_t expo[3][2][2];
|
||||
int8_t drSw1;
|
||||
int8_t drSw2;
|
||||
|
||||
t_Er9xExpoData() { memset(this, 0, sizeof(t_Er9xExpoData)); }
|
||||
}) Er9xExpoData;
|
||||
|
||||
|
||||
PACK(typedef struct t_Er9xLimitData {
|
||||
int8_t min;
|
||||
int8_t max;
|
||||
bool revert;
|
||||
int16_t offset;
|
||||
|
||||
operator LimitData();
|
||||
t_Er9xLimitData();
|
||||
}) Er9xLimitData;
|
||||
|
||||
#define MLTPX_ADD 0
|
||||
#define MLTPX_MUL 1
|
||||
#define MLTPX_REP 2
|
||||
|
||||
PACK(typedef struct t_Er9xMixData {
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
uint8_t curve; //0=symmetrisch 1=no neg 2=no pos
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint8_t carryTrim:1;
|
||||
uint8_t mltpx:2; // multiplex method 0=+ 1=* 2=replace
|
||||
uint8_t lateOffset:1; // Add offset later
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t enableFmTrim:1;
|
||||
uint8_t differential:1;
|
||||
int8_t sOffset;
|
||||
int8_t res;
|
||||
|
||||
operator MixData();
|
||||
t_Er9xMixData();
|
||||
}) Er9xMixData;
|
||||
|
||||
|
||||
PACK(typedef struct t_Er9xLogicalSwitchData { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func:4;
|
||||
uint8_t andsw:4;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Er9xLogicalSwitchData() { memset(this, 0, sizeof(t_Er9xLogicalSwitchData)); }
|
||||
}) Er9xLogicalSwitchData;
|
||||
|
||||
PACK(typedef struct t_Er9xSafetySwData { // Custom Switches data
|
||||
int8_t swtch;
|
||||
int8_t val;
|
||||
|
||||
t_Er9xSafetySwData();
|
||||
}) Er9xSafetySwData;
|
||||
|
||||
PACK(typedef struct t_Er9xFrSkyChannelData {
|
||||
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_level:4;
|
||||
uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>)
|
||||
uint8_t type:2; // future use: 0=volts, ...
|
||||
|
||||
operator FrSkyChannelData();
|
||||
t_Er9xFrSkyChannelData();
|
||||
}) Er9xFrSkyChannelData;
|
||||
|
||||
PACK(typedef struct t_Er9xFrSkyData {
|
||||
Er9xFrSkyChannelData channels[2];
|
||||
|
||||
operator FrSkyData();
|
||||
t_Er9xFrSkyData();
|
||||
}) Er9xFrSkyData;
|
||||
|
||||
PACK(typedef struct t_gvar {
|
||||
int8_t gvar ;
|
||||
uint8_t gvsource ;
|
||||
// int8_t gvswitch ;
|
||||
}) Er9xGvarData ;
|
||||
|
||||
PACK(typedef struct t_FlightModeData {
|
||||
// Trim store as -1001 to -1, trim value-501, 0-5 use trim of phase 0-5
|
||||
int16_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of modes 1|2|3|4 instead
|
||||
int8_t swtch; // Try 0-5 use trim of phase 0-5, 1000-2000, trim + 1500 ???
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
}) Er9xFlightModeData;
|
||||
|
||||
PACK(typedef struct t_Er9xModelData {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
uint8_t modelVoice ; // Index to model name voice (260+value)
|
||||
int8_t tmrMode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||
uint8_t tmrDir:1; //0=>Count Down, 1=>Count Up
|
||||
uint8_t traineron:1; // 0 disable trainer, 1 allow trainer
|
||||
uint8_t t2throttle:1 ; // Start timer2 using throttle
|
||||
uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh
|
||||
uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading
|
||||
uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units
|
||||
uint8_t FrSkyAltAlarm:2;
|
||||
uint16_t tmrVal;
|
||||
uint8_t protocol;
|
||||
int8_t ppmNCH;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
uint8_t xnumBlades:2; // RPM scaling
|
||||
uint8_t spare10:1;
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t ppmStart:3 ; // Start channel for PPM
|
||||
int8_t trimInc; // Trim Increments
|
||||
int8_t ppmDelay;
|
||||
int8_t trimSw;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t swashInvertELE:1;
|
||||
uint8_t swashInvertAIL:1;
|
||||
uint8_t swashInvertCOL:1;
|
||||
uint8_t swashType:3;
|
||||
uint8_t swashCollectiveSource;
|
||||
uint8_t swashRingValue;
|
||||
int8_t ppmFrameLength;
|
||||
Er9xMixData mixData[ER9X_MAX_MIXERS];
|
||||
Er9xLimitData limitData[ER9X_NUM_CHNOUT];
|
||||
Er9xExpoData expoData[4];
|
||||
int8_t trim[4];
|
||||
int8_t curves5[ER9X_MAX_CURVE5][5];
|
||||
int8_t curves9[ER9X_MAX_CURVE9][9];
|
||||
Er9xLogicalSwitchData logicalSw[ER9X_NUM_CSW];
|
||||
uint8_t frSkyVoltThreshold ;
|
||||
int8_t tmrModeB;
|
||||
uint8_t numVoice;
|
||||
Er9xSafetySwData safetySw[ER9X_NUM_CHNOUT];
|
||||
Er9xFrSkyData frsky;
|
||||
uint8_t numBlades ;
|
||||
uint8_t unused1[8] ;
|
||||
uint8_t CustomDisplayIndex[6] ;
|
||||
Er9xGvarData gvars[ER9X_MAX_GVARS] ;
|
||||
Er9xFlightModeData flightModeData[ER9X_MAX_MODES] ;
|
||||
|
||||
operator ModelData();
|
||||
t_Er9xModelData() { memset(this, 0, sizeof(t_Er9xModelData)); }
|
||||
}) Er9xModelData;
|
||||
|
||||
#endif // _ER9XEEPROM_H_
|
||||
@@ -1,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "er9xinterface.h"
|
||||
#include "er9xeeprom.h"
|
||||
#include "rlefile.h"
|
||||
// #include "appdata.h"
|
||||
// #include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
#define FILE_GENERAL 0
|
||||
#define FILE_MODEL(n) (1+n)
|
||||
|
||||
Er9xInterface::Er9xInterface():
|
||||
EEPROMInterface(Board::BOARD_STOCK),
|
||||
efile(new RleFile())
|
||||
{
|
||||
}
|
||||
|
||||
Er9xInterface::~Er9xInterface()
|
||||
{
|
||||
delete efile;
|
||||
}
|
||||
|
||||
const char * Er9xInterface::getName()
|
||||
{
|
||||
return "Er9x";
|
||||
}
|
||||
|
||||
inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
int stick = applyStickMode(i+1, mode) - 1;
|
||||
{
|
||||
int tmp = model.trim[i];
|
||||
model.trim[i] = model.trim[stick];
|
||||
model.trim[stick] = tmp;
|
||||
}
|
||||
{
|
||||
Er9xExpoData tmp = model.expoData[i];
|
||||
model.expoData[i] = model.expoData[stick];
|
||||
model.expoData[stick] = tmp;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ER9X_MAX_MIXERS; i++)
|
||||
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
|
||||
for (int i=0; i<ER9X_NUM_CSW; i++) {
|
||||
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
|
||||
case LS_FAMILY_VCOMP:
|
||||
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
|
||||
// no break
|
||||
case LS_FAMILY_VOFS:
|
||||
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Er9xGeneral er9xGeneral;
|
||||
memset(&er9xGeneral,0,sizeof(er9xGeneral));
|
||||
if (!loadRadioSettingsDataXML(&doc, &er9xGeneral)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=er9xGeneral;
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
}
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
memset(&er9xModel,0,sizeof(er9xModel));
|
||||
if(loadModelDataXML(&doc, &er9xModel, i)) {
|
||||
applyStickModeToModel(er9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_STOCK)) {
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_STOCK)) {
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Er9xGeneral er9xGeneral;
|
||||
|
||||
if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) {
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
|
||||
switch(er9xGeneral.myVers) {
|
||||
case 3:
|
||||
dbg << "(old gruvin9x) ";
|
||||
case 4:
|
||||
// case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
break;
|
||||
default:
|
||||
dbg << "not er9x";
|
||||
errors.set(NOT_ER9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) {
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
|
||||
}
|
||||
radioData.generalSettings = er9xGeneral;
|
||||
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
if (!efile->readRlc1((uint8_t*)&er9xModel, sizeof(Er9xModelData))) {
|
||||
radioData.models[i].clear();
|
||||
}
|
||||
else {
|
||||
applyStickModeToModel(er9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long Er9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Er9xInterface::getSize(const ModelData &model)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Er9xInterface::getSize(const GeneralSettings &settings)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Er9xInterface::isAvailable(PulsesProtocol prot, int port)
|
||||
{
|
||||
switch (prot) {
|
||||
case PULSES_PPM:
|
||||
case PULSES_DSM2:
|
||||
case PULSES_PXX_DJT:
|
||||
case PULSES_PPM16:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Er9xInterface::appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value)
|
||||
{
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(value);
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
|
||||
void Er9xInterface::appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite)
|
||||
{
|
||||
if(value || forceZeroWrite) {
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(QString("%1").arg(value));
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
}
|
||||
|
||||
void Er9xInterface::appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size)
|
||||
{
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomCDATASection t = qdoc->createCDATASection(name);
|
||||
t.setData(QByteArray(data, size).toBase64());
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
|
||||
QDomElement Er9xInterface::getGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen)
|
||||
{
|
||||
QDomElement gd = qdoc->createElement("GENERAL_DATA");
|
||||
appendNumberElement(qdoc, &gd, "Version", tgen->myVers, true); // have to write value here
|
||||
appendTextElement(qdoc, &gd, "Owner", QString::fromLatin1(tgen->ownerName,sizeof(tgen->ownerName)).trimmed());
|
||||
appendCDATAElement(qdoc, &gd, "Data", (const char *)tgen,sizeof(Er9xGeneral));
|
||||
return gd;
|
||||
}
|
||||
|
||||
QDomElement Er9xInterface::getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver)
|
||||
{
|
||||
QDomElement md = qdoc->createElement("MODEL_DATA");
|
||||
md.setAttribute("number", modelNum);
|
||||
appendNumberElement(qdoc, &md, "Version", mdver, true); // have to write value here
|
||||
appendTextElement(qdoc, &md, "Name", QString::fromLatin1(tmod->name,sizeof(tmod->name)).trimmed());
|
||||
appendCDATAElement(qdoc, &md, "Data", (const char *)tmod,sizeof(Er9xModelData));
|
||||
return md;
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen)
|
||||
{
|
||||
// look for "GENERAL_DATA" tag
|
||||
QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement();
|
||||
|
||||
if(gde.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
// load cdata into tgen
|
||||
QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
QString ds = n.toCDATASection().data();
|
||||
QByteArray ba = QByteArray::fromBase64(ds.toLatin1());
|
||||
const char * data = ba.data();
|
||||
memcpy(tgen, data, sizeof(Er9xGeneral));
|
||||
break;
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum)
|
||||
{
|
||||
// look for MODEL_DATA with modelNum attribute.
|
||||
// if modelNum = -1 then just pick the first one
|
||||
QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA");
|
||||
|
||||
// cycle through nodes to find correct model number
|
||||
QDomNode k = ndl.at(0);
|
||||
if(modelNum>=0) {
|
||||
while(!k.isNull()) {
|
||||
int a = k.toElement().attribute("number").toInt();
|
||||
if(a==modelNum)
|
||||
break;
|
||||
k = k.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
if (k.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
|
||||
// load cdata into tgen
|
||||
QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
QString ds = n.toCDATASection().data();
|
||||
QByteArray ba = QByteArray::fromBase64(ds.toLatin1());
|
||||
const char * data = ba.data();
|
||||
memcpy(tmod, data, sizeof(Er9xModelData));
|
||||
break;
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
int Er9xInterface::getCapability(Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Models:
|
||||
return 16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ER9XINTERFACE_H_
|
||||
#define _ER9XINTERFACE_H_
|
||||
|
||||
#include <QtXml>
|
||||
#include "eeprominterface.h"
|
||||
#include "er9xeeprom.h"
|
||||
|
||||
class RleFile;
|
||||
|
||||
class Er9xInterface : public EEPROMInterface
|
||||
{
|
||||
public:
|
||||
|
||||
Er9xInterface();
|
||||
|
||||
virtual ~Er9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getSize(const ModelData &);
|
||||
|
||||
virtual int getSize(const GeneralSettings &settings);
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0);
|
||||
|
||||
virtual int getCapability(Capability capability);
|
||||
|
||||
protected:
|
||||
|
||||
RleFile * efile;
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
|
||||
void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false);
|
||||
|
||||
void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size);
|
||||
|
||||
QDomElement getGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); //parse out data to XML format
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
bool loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); // get data from XML
|
||||
|
||||
bool loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum = -1); // get data from XML
|
||||
|
||||
};
|
||||
|
||||
#endif // _ER9XINTERFACE_H_
|
||||
@@ -1,730 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "helpers.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
#include <QObject>
|
||||
|
||||
extern RawSwitch er9xToSwitch(int8_t sw);
|
||||
|
||||
RawSwitch getErSky9xTimerMode(int mode)
|
||||
{
|
||||
if (mode<4)
|
||||
return RawSwitch(SWITCH_TYPE_TIMER_MODE, mode);
|
||||
else
|
||||
return RawSwitch();
|
||||
}
|
||||
|
||||
RawSwitch ersky9xToSwitch(int8_t sw)
|
||||
{
|
||||
uint8_t swa = abs(sw);
|
||||
if (swa == 0)
|
||||
return RawSwitch(SWITCH_TYPE_NONE);
|
||||
else if (swa <= 9)
|
||||
return RawSwitch(SWITCH_TYPE_SWITCH, sw);
|
||||
else if (swa <= 33)
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-9 : sw+9);
|
||||
else if (sw == 34)
|
||||
return RawSwitch(SWITCH_TYPE_ON);
|
||||
else if (sw == -34)
|
||||
return RawSwitch(SWITCH_TYPE_OFF);
|
||||
else if (swa <= 34+9)
|
||||
return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-34 : sw+34);
|
||||
else
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-34-9 : sw+34+9);
|
||||
}
|
||||
|
||||
t_Ersky9xTrainerMix::t_Ersky9xTrainerMix()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xTrainerMix));
|
||||
}
|
||||
|
||||
t_Ersky9xTrainerMix::operator TrainerMix()
|
||||
{
|
||||
TrainerMix c9x;
|
||||
c9x.src = srcChn;
|
||||
c9x.swtch = er9xToSwitch(swtch);
|
||||
c9x.weight = (25 * studWeight) / 8;
|
||||
c9x.mode = mode;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xTrainerData::t_Ersky9xTrainerData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xTrainerData));
|
||||
}
|
||||
|
||||
t_Ersky9xTrainerData::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xGeneral::t_Ersky9xGeneral()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xGeneral));
|
||||
}
|
||||
|
||||
Ersky9xGeneral::operator GeneralSettings ()
|
||||
{
|
||||
GeneralSettings result;
|
||||
|
||||
result.version = myVers;
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKSnPOTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
|
||||
result.backlightMode = 0;
|
||||
if (lightSw == 22) {
|
||||
result.backlightMode = 4;
|
||||
}
|
||||
else if (lightAutoOff) {
|
||||
result.backlightMode |= 1;
|
||||
result.backlightDelay = lightAutoOff;
|
||||
}
|
||||
else if (lightOnStickMove) {
|
||||
result.backlightMode |= 2;
|
||||
result.backlightDelay = lightOnStickMove;
|
||||
}
|
||||
|
||||
result.trainer = trainer;
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
case 0:
|
||||
result.beeperMode = GeneralSettings::BEEPER_QUIET;
|
||||
break;
|
||||
case 1:
|
||||
result.beeperMode = GeneralSettings::BEEPER_NOKEYS;
|
||||
break;
|
||||
default:
|
||||
result.beeperMode = GeneralSettings::BEEPER_ALL;
|
||||
result.beeperLength = beeperVal - 4;
|
||||
break;
|
||||
}
|
||||
|
||||
result.disableAlarmWarning = disableAlarmWarning;
|
||||
result.stickMode = std::max((uint8_t)0, std::min(stickMode, (uint8_t)3));
|
||||
result.inactivityTimer = inactivityTimer + 10;
|
||||
result.minuteBeep = minuteBeep;
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
result.templateSetup = templateSetup;
|
||||
result.PPM_Multiplier = PPM_Multiplier;
|
||||
getEEPROMString(result.ownerName, ownerName, sizeof(ownerName));
|
||||
result.optrexDisplay = optrexDisplay;
|
||||
result.speakerPitch = speakerPitch;
|
||||
result.hapticStrength = hapticStrength - 3;
|
||||
result.speakerMode = speakerMode;
|
||||
result.speakerVolume = volume;
|
||||
result.backlightBright = bright ;
|
||||
result.txCurrentCalibration = current_calib;
|
||||
return result;
|
||||
}
|
||||
|
||||
t_Ersky9xLimitData::t_Ersky9xLimitData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xLimitData));
|
||||
}
|
||||
|
||||
t_Ersky9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xMixData_v10::t_Ersky9xMixData_v10()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xMixData_v10));
|
||||
}
|
||||
|
||||
t_Ersky9xMixData_v10::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
c9x.destCh = destCh;
|
||||
c9x.weight = weight;
|
||||
c9x.swtch = er9xToSwitch(swtch);
|
||||
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw == 8) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 9) {
|
||||
if (swtch < 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch);
|
||||
c9x.weight = -weight;
|
||||
}
|
||||
else if (swtch > 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
if (mltpx != MLTPX_REP)
|
||||
c9x.swtch = RawSwitch(SWITCH_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw == 37) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0);
|
||||
}
|
||||
else if (srcRaw <= 12) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw <= 20) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21);
|
||||
}
|
||||
|
||||
if (curve > 6) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_CUSTOM;
|
||||
c9x.curve.value = curve - 6;
|
||||
}
|
||||
else if (curve > 0) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_FUNC;
|
||||
c9x.curve.value = curve;
|
||||
}
|
||||
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
// c9x.enableFmTrim=enableFmTrim;
|
||||
c9x.sOffset = sOffset;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
|
||||
t_Ersky9xMixData_v11::t_Ersky9xMixData_v11()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xMixData_v11));
|
||||
}
|
||||
|
||||
t_Ersky9xMixData_v11::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
c9x.destCh = destCh;
|
||||
c9x.weight = weight;
|
||||
c9x.swtch = ersky9xToSwitch(swtch);
|
||||
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw == 8) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 9) {
|
||||
if (swtch < 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch);
|
||||
c9x.weight = -weight;
|
||||
}
|
||||
else if (swtch > 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
if (mltpx != MLTPX_REP)
|
||||
c9x.swtch = RawSwitch(SWITCH_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw == 45) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0);
|
||||
}
|
||||
else if (srcRaw > 45) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-46);
|
||||
}
|
||||
else if (srcRaw <= 12) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw <= 20) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21);
|
||||
}
|
||||
|
||||
if (curve > 6) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_CUSTOM;
|
||||
c9x.curve.value = curve - 6;
|
||||
}
|
||||
else if (curve > 0) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_FUNC;
|
||||
c9x.curve.value = curve;
|
||||
}
|
||||
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
// c9x.enableFmTrim=enableFmTrim;
|
||||
c9x.sOffset = sOffset;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
RawSource ersky9xToSource_v10(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value == 8) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value == 9) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value <= 12) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-10);
|
||||
}
|
||||
else if (value <= 20) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-13);
|
||||
}
|
||||
else if (value <= 36) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-21);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-36);
|
||||
}
|
||||
}
|
||||
|
||||
RawSource ersky9xToSource_v11(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value == 8) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value == 9) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value <= 12) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-10);
|
||||
}
|
||||
else if (value <= 20) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-13);
|
||||
}
|
||||
else if (value <= 36) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-21);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-36);
|
||||
}
|
||||
}
|
||||
|
||||
Ersky9xLogicalSwitchData_v10::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = ersky9xToSource_v10(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val2 = ersky9xToSource_v10(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = er9xToSwitch(v1).toValue();
|
||||
c9x.val2 = er9xToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
Ersky9xLogicalSwitchData_v11::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = ersky9xToSource_v11(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val2 = ersky9xToSource_v11(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = er9xToSwitch(v1).toValue();
|
||||
c9x.val2 = er9xToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xSafetySwData_v10::t_Ersky9xSafetySwData_v10()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xSafetySwData_v10));
|
||||
}
|
||||
|
||||
t_Ersky9xSafetySwData_v11::t_Ersky9xSafetySwData_v11()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xSafetySwData_v11));
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyChannelData_v10::t_Ersky9xFrSkyChannelData_v10()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xFrSkyChannelData_v10));
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyChannelData_v10::operator FrSkyChannelData ()
|
||||
{
|
||||
FrSkyChannelData c9x;
|
||||
c9x.ratio = ratio;
|
||||
c9x.alarms[0].value = alarms_value[0];
|
||||
c9x.alarms[0].level = alarms_level & 3;
|
||||
c9x.alarms[0].greater = alarms_greater & 1;
|
||||
c9x.alarms[1].value = alarms_value[1];
|
||||
c9x.alarms[1].level = (alarms_level >> 2) & 3;
|
||||
c9x.alarms[1].greater = (alarms_greater >> 1) & 1;
|
||||
if (type==2) {
|
||||
c9x.type = 0;
|
||||
c9x.multiplier=1;
|
||||
} else {
|
||||
c9x.type = type;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyChannelData_v11::t_Ersky9xFrSkyChannelData_v11()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xFrSkyChannelData_v11));
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyChannelData_v11::operator FrSkyChannelData ()
|
||||
{
|
||||
FrSkyChannelData c9x;
|
||||
c9x.ratio = ratio;
|
||||
c9x.alarms[0].value = alarms_value[0];
|
||||
c9x.alarms[0].level = alarms_level & 3;
|
||||
c9x.alarms[0].greater = alarms_greater & 1;
|
||||
c9x.alarms[1].value = alarms_value[1];
|
||||
c9x.alarms[1].level = (alarms_level >> 2) & 3;
|
||||
c9x.alarms[1].greater = (alarms_greater >> 1) & 1;
|
||||
if (type==2) {
|
||||
c9x.type = 0;
|
||||
c9x.multiplier=1;
|
||||
} else {
|
||||
c9x.type = type;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyData_v10::t_Ersky9xFrSkyData_v10()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xFrSkyData_v10));
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyData_v10::operator FrSkyData ()
|
||||
{
|
||||
FrSkyData c9x;
|
||||
c9x.channels[0] = channels[0];
|
||||
c9x.channels[1] = channels[1];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyData_v11::t_Ersky9xFrSkyData_v11()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Ersky9xFrSkyData_v11));
|
||||
}
|
||||
|
||||
t_Ersky9xFrSkyData_v11::operator FrSkyData ()
|
||||
{
|
||||
FrSkyData c9x;
|
||||
c9x.channels[0] = channels[0];
|
||||
c9x.channels[1] = channels[1];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xModelData_v10::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++) {
|
||||
c9x.timers[i].mode = getErSky9xTimerMode(timer[i].tmrModeA);
|
||||
c9x.timers[i].val = timer[i].tmrVal;
|
||||
}
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].ppm.frameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.customFn[0].func = FuncInstantTrim;
|
||||
if (trimSw) {
|
||||
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
|
||||
}
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.swashRingData.elevatorWeight = swashInvertELE ? -100 : 100;
|
||||
c9x.swashRingData.aileronWeight = swashInvertAIL ? -100 : 100;
|
||||
c9x.swashRingData.collectiveWeight = swashInvertCOL ? -100 : 100;
|
||||
c9x.swashRingData.type = swashType;
|
||||
c9x.swashRingData.collectiveSource = ersky9xToSource_v10(swashCollectiveSource);
|
||||
c9x.swashRingData.value = swashRingValue;
|
||||
for (int i=0; i<ERSKY9X_MAX_MIXERS_V10; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<ERSKY9X_NUM_CHNOUT_V10; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
break;
|
||||
if (expoData[ch].drSw1 && !expoData[ch].drSw2) {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? expoData[ch].drSw1 : 0);
|
||||
pos = dr == 0 ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? -expoData[ch].drSw1 : (dr == 1 ? -expoData[ch].drSw2 : 0));
|
||||
}
|
||||
c9x.expoData[e].chn = ch;
|
||||
if (expoData[ch].expo[pos][0][0]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][0];
|
||||
}
|
||||
c9x.expoData[e].weight = 100 + expoData[ch].expo[pos][1][0];
|
||||
if (expoData[ch].expo[pos][0][0] == expoData[ch].expo[pos][0][1] && expoData[ch].expo[pos][1][0] == expoData[ch].expo[pos][1][1]) {
|
||||
c9x.expoData[e++].mode = 3;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
if (expoData[ch].expo[pos][0][1]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][1];
|
||||
}
|
||||
c9x.expoData[e++].weight = 100 + expoData[ch].expo[pos][1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<ERSKY9X_NUM_CSW_V10; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
|
||||
// for (int i=0; i<ERSKY9X_NUM_CHNOUT_V10; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
|
||||
c9x.frsky = frsky;
|
||||
c9x.frsky.usrProto=FrSkyUsrProto;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Ersky9xModelData_v11::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++) {
|
||||
c9x.timers[i].mode = getErSky9xTimerMode(timer[i].tmrModeA);
|
||||
c9x.timers[i].val = timer[i].tmrVal;
|
||||
}
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].ppm.frameLength=ppmFrameLength;
|
||||
c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH;
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.customFn[0].func = FuncInstantTrim;
|
||||
if (trimSw) {
|
||||
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
|
||||
}
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.swashRingData.elevatorWeight = swashInvertELE ? -100 : 100;
|
||||
c9x.swashRingData.aileronWeight = swashInvertAIL ? -100 : 100;
|
||||
c9x.swashRingData.collectiveWeight = swashInvertCOL ? -100 : 100;
|
||||
c9x.swashRingData.type = swashType;
|
||||
c9x.swashRingData.collectiveSource = ersky9xToSource_v11(swashCollectiveSource);
|
||||
c9x.swashRingData.value = swashRingValue;
|
||||
for (int i=0; i<ERSKY9X_MAX_MIXERS_V11; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<ERSKY9X_NUM_CHNOUT_V11; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
break;
|
||||
if (expoData[ch].drSw1 && !expoData[ch].drSw2) {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? expoData[ch].drSw1 : 0);
|
||||
pos = dr == 0 ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].swtch = er9xToSwitch(dr == 0 ? -expoData[ch].drSw1 : (dr == 1 ? -expoData[ch].drSw2 : 0));
|
||||
}
|
||||
c9x.expoData[e].chn = ch;
|
||||
if (expoData[ch].expo[pos][0][0]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][0];
|
||||
}
|
||||
c9x.expoData[e].weight = 100 + expoData[ch].expo[pos][1][0];
|
||||
if (expoData[ch].expo[pos][0][0] == expoData[ch].expo[pos][0][1] && expoData[ch].expo[pos][1][0] == expoData[ch].expo[pos][1][1]) {
|
||||
c9x.expoData[e++].mode = 3;
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
if (expoData[ch].expo[pos][0][1]) {
|
||||
c9x.expoData[e].curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.expoData[e].curve.value = expoData[ch].expo[pos][0][1];
|
||||
}
|
||||
c9x.expoData[e++].weight = 100 + expoData[ch].expo[pos][1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[ERSKY9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<ERSKY9X_NUM_CSW_V11; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
|
||||
c9x.frsky = frsky;
|
||||
c9x.frsky.usrProto=FrSkyUsrProto;
|
||||
for (int i=0; i<5;i++) {
|
||||
c9x.flightModeData[0].gvars[i]=gvars[i].gvar;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -1,436 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ERSKY9XEEPROM_H_
|
||||
#define _ERSKY9XEEPROM_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eeprominterface.h"
|
||||
|
||||
extern RawSwitch getEr9xTimerMode(int mode);
|
||||
|
||||
//eeprom data
|
||||
#define ERSKY9X_MAX_MIXERS_V10 32
|
||||
#define ERSKY9X_MAX_MIXERS_V11 48
|
||||
#define ERSKY9X_MAX_CURVE5 8
|
||||
#define ERSKY9X_MAX_CURVE9 8
|
||||
#define ERSKY9X_MAX_CSFUNC 13
|
||||
|
||||
#define ERSKY9X_MDVERS10 10
|
||||
#define ERSKY9X_MDVERS11 11
|
||||
|
||||
#define ERSKY9X_GENERAL_OWNER_NAME_LEN 10
|
||||
#define ERSKY9X_NUM_CHNOUT_V10 16 //number of real outputchannels CH1-CH8
|
||||
#define ERSKY9X_NUM_CHNOUT_V11 24 //number of real outputchannels CH1-CH8
|
||||
#define ERSKY9X_NUM_CSW_V10 12 //number of custom switches
|
||||
#define ERSKY9X_NUM_CSW_V11 24
|
||||
#define ERSKY9X_NUM_FSW 16
|
||||
#define ERSKY9X_NUM_VOICE 8
|
||||
#define ERSKY9X_MAX_GVARS 7
|
||||
|
||||
#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots
|
||||
|
||||
PACK(typedef struct t_Ersky9xTrainerMix {
|
||||
uint8_t srcChn:3; //0-7 = ch1-8
|
||||
int8_t swtch:5;
|
||||
int8_t studWeight:6;
|
||||
uint8_t mode:2; // off, add-mode, subst-mode
|
||||
|
||||
operator TrainerMix();
|
||||
t_Ersky9xTrainerMix();
|
||||
}) Ersky9xTrainerMix; //
|
||||
|
||||
PACK(typedef struct t_Ersky9xTrainerData {
|
||||
int16_t calib[4];
|
||||
Ersky9xTrainerMix mix[4];
|
||||
|
||||
operator TrainerData();
|
||||
t_Ersky9xTrainerData();
|
||||
}) Ersky9xTrainerData;
|
||||
|
||||
PACK(typedef struct t_Ersky9xGeneral {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanPos[CPN_MAX_STICKSnPOTS];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
uint8_t vBatWarn;
|
||||
int8_t txVoltageCalibration;
|
||||
int8_t lightSw;
|
||||
Ersky9xTrainerData trainer;
|
||||
uint8_t view;
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t disableSwitchWarning:1;
|
||||
uint8_t disableMemoryWarning:1;
|
||||
uint8_t beeperVal:3;
|
||||
uint8_t reserveWarning:1;
|
||||
uint8_t disableAlarmWarning:1;
|
||||
uint8_t stickMode;
|
||||
int8_t inactivityTimer;
|
||||
uint8_t throttleReversed:1;
|
||||
uint8_t minuteBeep:1;
|
||||
uint8_t preBeep:1;
|
||||
uint8_t flashBeep:1;
|
||||
uint8_t disableSplashScreen:1;
|
||||
uint8_t disablePotScroll:1;
|
||||
uint8_t disableBG:1;
|
||||
uint8_t res1:1;
|
||||
uint8_t filterInput;
|
||||
uint8_t lightAutoOff;
|
||||
uint8_t templateSetup; //RETA order according to chout_ar array
|
||||
int8_t PPM_Multiplier;
|
||||
uint8_t FRSkyYellow:4;
|
||||
uint8_t FRSkyOrange:4;
|
||||
uint8_t FRSkyRed:4; //mike please check these are correct
|
||||
uint8_t hideNameOnSplash:1;
|
||||
uint8_t optrexDisplay:1;
|
||||
uint8_t spare:2;
|
||||
uint8_t speakerPitch;
|
||||
uint8_t hapticStrength;
|
||||
uint8_t speakerMode;
|
||||
uint8_t lightOnStickMove;
|
||||
|
||||
char ownerName[10];
|
||||
uint8_t switchWarningStates;
|
||||
uint8_t volume ;
|
||||
uint8_t bright ; // backlight
|
||||
uint8_t stickGain;
|
||||
uint8_t mAh_alarm ;
|
||||
uint16_t mAh_used ;
|
||||
uint16_t run_time ;
|
||||
int8_t current_calib ;
|
||||
uint8_t bt_baudrate ;
|
||||
uint8_t rotaryDivisor ;
|
||||
operator GeneralSettings();
|
||||
t_Ersky9xGeneral();
|
||||
}) Ersky9xGeneral;
|
||||
|
||||
PACK(typedef struct t_Ersky9xExpoData {
|
||||
int8_t expo[3][2][2];
|
||||
int8_t drSw1;
|
||||
int8_t drSw2;
|
||||
|
||||
t_Ersky9xExpoData() { memset(this, 0, sizeof(t_Ersky9xExpoData)); }
|
||||
}) Ersky9xExpoData;
|
||||
|
||||
|
||||
PACK(typedef struct t_Ersky9xLimitData {
|
||||
int8_t min;
|
||||
int8_t max;
|
||||
bool revert;
|
||||
int16_t offset;
|
||||
|
||||
operator LimitData();
|
||||
t_Ersky9xLimitData() ;
|
||||
}) Ersky9xLimitData;
|
||||
|
||||
#define MLTPX_ADD 0
|
||||
#define MLTPX_MUL 1
|
||||
#define MLTPX_REP 2
|
||||
|
||||
PACK(typedef struct t_Ersky9xMixData_v10 {
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
uint8_t curve; //0=symmetrisch 1=no neg 2=no pos
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint8_t carryTrim:1;
|
||||
uint8_t mltpx:3; // multiplex method 0=+ 1=* 2=replace
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t enableFmTrim:1;
|
||||
uint8_t mixres:1;
|
||||
int8_t sOffset;
|
||||
int8_t res;
|
||||
|
||||
operator MixData();
|
||||
t_Ersky9xMixData_v10();
|
||||
}) Ersky9xMixData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xMixData_v11 {
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
uint8_t curve; //0=symmetrisch 1=no neg 2=no pos
|
||||
uint8_t delayUp;
|
||||
uint8_t delayDown;
|
||||
uint8_t speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown; // 0 nichts
|
||||
uint8_t carryTrim:1;
|
||||
uint8_t mltpx:3; // multiplex method 0=+ 1=* 2=replace
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t enableFmTrim:1;
|
||||
uint8_t mixres:1;
|
||||
int8_t sOffset;
|
||||
uint8_t res[4];
|
||||
operator MixData();
|
||||
t_Ersky9xMixData_v11();
|
||||
}) Ersky9xMixData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xLogicalSwitchData_v10 { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Ersky9xLogicalSwitchData_v10() { memset(this, 0, sizeof(t_Ersky9xLogicalSwitchData_v10)); }
|
||||
}) Ersky9xLogicalSwitchData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xLogicalSwitchData_v11 { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
uint8_t andsw;
|
||||
uint8_t res ;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Ersky9xLogicalSwitchData_v11() { memset(this, 0, sizeof(t_Ersky9xLogicalSwitchData_v11)); }
|
||||
}) Ersky9xLogicalSwitchData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xSafetySwData_v10 { // Custom Switches data
|
||||
int8_t swtch;
|
||||
int8_t val;
|
||||
|
||||
t_Ersky9xSafetySwData_v10();
|
||||
}) Ersky9xSafetySwData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xSafetySwData_v11 { // Custom Switches data
|
||||
union opt {
|
||||
struct ss {
|
||||
int8_t swtch ;
|
||||
uint8_t mode ;
|
||||
int8_t val ;
|
||||
uint8_t res ;
|
||||
} ss ;
|
||||
struct vs {
|
||||
uint8_t vswtch ;
|
||||
uint8_t vmode ; // ON, OFF, BOTH, 15Secs, 30Secs, 60Secs, Varibl
|
||||
uint8_t vval;
|
||||
uint8_t vres ;
|
||||
} vs ;
|
||||
} opt ;
|
||||
|
||||
t_Ersky9xSafetySwData_v11();
|
||||
}) Ersky9xSafetySwData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xgvar {
|
||||
int8_t gvar ;
|
||||
uint8_t gvsource ;
|
||||
// int8_t gvswitch ;
|
||||
}) Ersky9xGvarData ;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFlightModeData {
|
||||
int16_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of phases 1|2|3|4 instead
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
uint16_t spare ; // Future expansion
|
||||
}) Ersky9xFlightModeData;
|
||||
|
||||
PACK(typedef struct t_Ersky9xCustomFunctionData { // Function Switches data
|
||||
int8_t swtch; //input
|
||||
uint8_t func;
|
||||
char param[6];
|
||||
uint8_t delay;
|
||||
uint8_t spare;
|
||||
}) Ersky9xCustomFunctionData;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyChannelData_v10 {
|
||||
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_level:4;
|
||||
uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>)
|
||||
uint8_t type:2; // future use: 0=volts, ...
|
||||
|
||||
operator FrSkyChannelData();
|
||||
t_Ersky9xFrSkyChannelData_v10();
|
||||
}) Ersky9xFrSkyChannelData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyData_v10 {
|
||||
Ersky9xFrSkyChannelData_v10 channels[2];
|
||||
|
||||
operator FrSkyData();
|
||||
t_Ersky9xFrSkyData_v10();
|
||||
}) Ersky9xFrSkyData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyChannelData_v11 {
|
||||
uint8_t ratio ; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t offset ; //
|
||||
uint8_t gain ; //
|
||||
uint8_t alarms_value[2] ; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_level ;
|
||||
uint8_t alarms_greater ; // 0=LT(<), 1=GT(>)
|
||||
uint8_t type ; // 0=volts, 1=raw, 2=volts*2, 3=Amps
|
||||
|
||||
operator FrSkyChannelData();
|
||||
t_Ersky9xFrSkyChannelData_v11();
|
||||
}) Ersky9xFrSkyChannelData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyData_v11 {
|
||||
Ersky9xFrSkyChannelData_v11 channels[2];
|
||||
|
||||
operator FrSkyData();
|
||||
t_Ersky9xFrSkyData_v11();
|
||||
}) Ersky9xFrSkyData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyalarms_v11 {
|
||||
uint8_t frskyAlarmType ;
|
||||
uint8_t frskyAlarmLimit ;
|
||||
uint8_t frskyAlarmSound ;
|
||||
}) Ersky9xFrSkyAlData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xFrSkyAlarmData_v11 {
|
||||
Ersky9xFrSkyAlData_v11 alarmData[8] ;
|
||||
}) Ersky9xFrSkyAlarmData_v11;
|
||||
|
||||
PACK(typedef struct t_Ersky9xTimerMode_v10 {
|
||||
uint8_t tmrModeA:7 ; // timer trigger source -> off, abs, stk, stk%, cx%
|
||||
uint8_t tmrDir:1 ; // Timer direction
|
||||
int8_t tmrModeB ; // timer trigger source -> !sw, none, sw, m_sw
|
||||
uint16_t tmrVal ;
|
||||
}) Ersky9xTimerMode_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xTimerMode_v11 {
|
||||
uint8_t tmrModeA:7 ; // timer trigger source -> off, abs, stk, stk%, cx%
|
||||
uint8_t tmrDir:1 ; // Timer direction
|
||||
int8_t tmrModeB ; // timer trigger source -> !sw, none, sw, m_sw
|
||||
uint16_t tmrVal ;
|
||||
}) Ersky9xTimerMode_v11;
|
||||
|
||||
PACK(typedef struct te_Ersky9xswVoice {
|
||||
uint8_t swtch ;
|
||||
uint8_t mode ; // ON, OFF, BOTH, 15Secs, 30Secs, 60Secs
|
||||
uint8_t val ;
|
||||
uint8_t vres ;
|
||||
}) Ersky9xvoiceSwData ;
|
||||
|
||||
PACK(typedef struct t_Ersky9xModelData_v10 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
uint8_t reserved_spare; //used to be MDVERS - now depreciated
|
||||
int8_t spare21; // was timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||
// uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down
|
||||
uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down
|
||||
// uint8_t tmrDir:1; // was tmrDir, now use tmrVal>0 => count down
|
||||
uint8_t traineron:1; // 0 disable trainer, 1 allow trainer
|
||||
uint8_t spare22:1 ; // Start timer2 using throttle
|
||||
uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh
|
||||
uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading
|
||||
uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units
|
||||
uint8_t FrSkyAltAlarm:2;
|
||||
uint16_t spare_u16 ; // Was timerval
|
||||
uint8_t protocol;
|
||||
int8_t ppmNCH;
|
||||
int8_t thrTrim:4; // Enable Throttle Trim
|
||||
int8_t thrExpo:4; // Enable Throttle Expo
|
||||
int8_t trimInc; // Trim Increments
|
||||
int8_t ppmDelay;
|
||||
int8_t trimSw;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t swashInvertELE:1;
|
||||
uint8_t swashInvertAIL:1;
|
||||
uint8_t swashInvertCOL:1;
|
||||
uint8_t swashType:3;
|
||||
uint8_t swashCollectiveSource;
|
||||
uint8_t swashRingValue;
|
||||
int8_t ppmFrameLength; //0=22.5 (10msec-30msec) 0.5msec increments
|
||||
Ersky9xMixData_v10 mixData[ERSKY9X_MAX_MIXERS_V10];
|
||||
Ersky9xLimitData limitData[ERSKY9X_NUM_CHNOUT_V10];
|
||||
Ersky9xExpoData expoData[4];
|
||||
int8_t trim[4];
|
||||
int8_t curves5[ERSKY9X_MAX_CURVE5][5];
|
||||
int8_t curves9[ERSKY9X_MAX_CURVE9][9];
|
||||
Ersky9xLogicalSwitchData_v10 logicalSw[ERSKY9X_NUM_CSW_V10];
|
||||
uint8_t frSkyVoltThreshold ;
|
||||
uint8_t res3[2];
|
||||
Ersky9xSafetySwData_v10 safetySw[ERSKY9X_NUM_CHNOUT_V10];
|
||||
Ersky9xFrSkyData_v10 frsky;
|
||||
Ersky9xTimerMode_v10 timer[2] ;
|
||||
operator ModelData();
|
||||
t_Ersky9xModelData_v10() { memset(this, 0, sizeof(t_Ersky9xModelData_v10)); }
|
||||
}) Ersky9xModelData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xModelData_v11 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
uint8_t modelVoice ; // Index to model name voice (261+value)
|
||||
uint8_t RxNum ; // was timer trigger source, now RxNum for model match
|
||||
uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down
|
||||
uint8_t traineron:1; // 0 disable trainer, 1 allow trainer
|
||||
uint8_t spare22:1 ; // Start timer2 using throttle
|
||||
uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh
|
||||
uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading
|
||||
uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units
|
||||
uint8_t FrSkyAltAlarm:2;
|
||||
uint8_t version ;
|
||||
uint8_t protocol;
|
||||
int8_t ppmNCH;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
uint8_t numBlades:2; // RPM scaling
|
||||
uint8_t spare10:1;
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t spare11:3;
|
||||
int8_t trimInc; // Trim Increments
|
||||
int8_t ppmDelay;
|
||||
int8_t trimSw;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t swashInvertELE:1;
|
||||
uint8_t swashInvertAIL:1;
|
||||
uint8_t swashInvertCOL:1;
|
||||
uint8_t swashType:3;
|
||||
uint8_t swashCollectiveSource;
|
||||
uint8_t swashRingValue;
|
||||
int8_t ppmFrameLength; //0=22.5 (10msec-30msec) 0.5msec increments
|
||||
Ersky9xMixData_v11 mixData[ERSKY9X_MAX_MIXERS_V11];
|
||||
Ersky9xLimitData limitData[ERSKY9X_NUM_CHNOUT_V11];
|
||||
Ersky9xExpoData expoData[4];
|
||||
int8_t trim[4];
|
||||
int8_t curves5[ERSKY9X_MAX_CURVE5][5];
|
||||
int8_t curves9[ERSKY9X_MAX_CURVE9][9];
|
||||
int8_t curvexy[18];
|
||||
Ersky9xLogicalSwitchData_v11 logicalSw[ERSKY9X_NUM_CSW_V11];
|
||||
uint8_t frSkyVoltThreshold ;
|
||||
uint8_t bt_telemetry;
|
||||
uint8_t numVoice; // 0-16, rest are Safety switches
|
||||
Ersky9xSafetySwData_v11 safetySw[ERSKY9X_NUM_CHNOUT_V11];
|
||||
Ersky9xvoiceSwData voiceSwitches[ERSKY9X_NUM_VOICE] ;
|
||||
Ersky9xFrSkyData_v11 frsky;
|
||||
Ersky9xTimerMode_v11 timer[2] ;
|
||||
Ersky9xFrSkyAlarmData_v11 frskyAlarms ;
|
||||
// Add 6 bytes for custom telemetry screen
|
||||
uint8_t customDisplayIndex[6] ;
|
||||
Ersky9xCustomFunctionData customFn[ERSKY9X_NUM_FSW];
|
||||
Ersky9xFlightModeData flightModeData[6] ;
|
||||
Ersky9xGvarData gvars[ERSKY9X_MAX_GVARS] ;
|
||||
|
||||
operator ModelData();
|
||||
t_Ersky9xModelData_v11() { memset(this, 0, sizeof(t_Ersky9xModelData_v11)); }
|
||||
}) Ersky9xModelData_v11;
|
||||
|
||||
#endif // _ERSKY9XEEPROM_H_
|
||||
@@ -1,389 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "ersky9xinterface.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
#include "rlefile.h"
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
/// fileId of general file
|
||||
#define FILE_GENERAL 0
|
||||
/// convert model number 0..MAX_MODELS-1 int fileId
|
||||
#define FILE_MODEL(n) (1+n)
|
||||
#define FILE_TMP (1+16)
|
||||
|
||||
Ersky9xInterface::Ersky9xInterface():
|
||||
EEPROMInterface(Board::BOARD_SKY9X),
|
||||
efile(new RleFile())
|
||||
{
|
||||
}
|
||||
|
||||
Ersky9xInterface::~Ersky9xInterface()
|
||||
{
|
||||
delete efile;
|
||||
}
|
||||
|
||||
const char * Ersky9xInterface::getName()
|
||||
{
|
||||
return "Ersky9x";
|
||||
}
|
||||
|
||||
inline void applyStickModeToModel(Ersky9xModelData_v10 & model, unsigned int mode)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
int stick = applyStickMode(i+1, mode) - 1;
|
||||
{
|
||||
int tmp = model.trim[i];
|
||||
model.trim[i] = model.trim[stick];
|
||||
model.trim[stick] = tmp;
|
||||
}
|
||||
{
|
||||
Ersky9xExpoData tmp = model.expoData[i];
|
||||
model.expoData[i] = model.expoData[stick];
|
||||
model.expoData[stick] = tmp;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ERSKY9X_MAX_MIXERS_V10; i++)
|
||||
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
|
||||
for (int i=0; i<ERSKY9X_NUM_CSW_V10; i++) {
|
||||
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
|
||||
case LS_FAMILY_VCOMP:
|
||||
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
|
||||
// no break
|
||||
case LS_FAMILY_VOFS:
|
||||
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mode)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
int stick = applyStickMode(i+1, mode) - 1;
|
||||
{
|
||||
int tmp = model.trim[i];
|
||||
model.trim[i] = model.trim[stick];
|
||||
model.trim[stick] = tmp;
|
||||
}
|
||||
{
|
||||
Ersky9xExpoData tmp = model.expoData[i];
|
||||
model.expoData[i] = model.expoData[stick];
|
||||
model.expoData[stick] = tmp;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ERSKY9X_MAX_MIXERS_V11; i++)
|
||||
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
|
||||
for (int i=0; i<ERSKY9X_NUM_CSW_V11; i++) {
|
||||
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
|
||||
case LS_FAMILY_VCOMP:
|
||||
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
|
||||
// no break
|
||||
case LS_FAMILY_VOFS:
|
||||
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
memset(&ersky9xGeneral,0,sizeof(ersky9xGeneral));
|
||||
if(!loadRadioSettingsDataXML(&doc, &ersky9xGeneral)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=ersky9xGeneral;
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
}
|
||||
for(int i=0; i<getCapability(Models); i++) {
|
||||
if (ersky9xGeneral.myVers == 10) {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v10>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v11>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_SKY9X)) {
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_SKY9X)) {
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
|
||||
if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) {
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
|
||||
switch(ersky9xGeneral.myVers) {
|
||||
case 10:
|
||||
break;
|
||||
case 11:
|
||||
break;
|
||||
default:
|
||||
dbg << "not ersky9x";
|
||||
errors.set(NOT_ERSKY9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) {
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
radioData.generalSettings = ersky9xGeneral;
|
||||
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
uint8_t buffer[4096];
|
||||
uint size;
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
|
||||
// if (!efile->readRlc2((uint8_t*)&ersky9xModel, sizeof(Ersky9xModelData))) {
|
||||
size = efile->readRlc2(buffer, 4096);
|
||||
if (!size) {
|
||||
radioData.models[i].clear();
|
||||
}
|
||||
else {
|
||||
if (size<720) {
|
||||
Ersky9xModelData_v10 ersky9xModel;
|
||||
memcpy(&ersky9xModel, buffer, sizeof(ersky9xModel));
|
||||
applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = ersky9xModel;
|
||||
} else {
|
||||
Ersky9xModelData_v11 ersky9xModel;
|
||||
memcpy(&ersky9xModel, buffer, sizeof(ersky9xModel));
|
||||
applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = ersky9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long Ersky9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Ersky9xInterface::getSize(const ModelData & model)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Ersky9xInterface::getSize(const GeneralSettings & settings)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Ersky9xInterface::isAvailable(PulsesProtocol prot, int port)
|
||||
{
|
||||
switch (prot) {
|
||||
case PULSES_PPM:
|
||||
case PULSES_DSM2:
|
||||
case PULSES_PXX_DJT:
|
||||
case PULSES_PPM16:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Ersky9xInterface::appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value)
|
||||
{
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(value);
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
|
||||
void Ersky9xInterface::appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite)
|
||||
{
|
||||
if(value || forceZeroWrite) {
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(QString("%1").arg(value));
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
}
|
||||
|
||||
void Ersky9xInterface::appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size)
|
||||
{
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomCDATASection t = qdoc->createCDATASection(name);
|
||||
t.setData(QByteArray(data, size).toBase64());
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
|
||||
QDomElement Ersky9xInterface::getGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen)
|
||||
{
|
||||
QDomElement gd = qdoc->createElement("GENERAL_DATA");
|
||||
appendNumberElement(qdoc, &gd, "Version", tgen->myVers, true); // have to write value here
|
||||
appendTextElement(qdoc, &gd, "Owner", QString::fromLatin1(tgen->ownerName,sizeof(tgen->ownerName)).trimmed());
|
||||
appendCDATAElement(qdoc, &gd, "Data", (const char *)tgen,sizeof(Ersky9xGeneral));
|
||||
return gd;
|
||||
}
|
||||
|
||||
QDomElement Ersky9xInterface::getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver)
|
||||
{
|
||||
QDomElement md = qdoc->createElement("MODEL_DATA");
|
||||
md.setAttribute("number", modelNum);
|
||||
appendNumberElement(qdoc, &md, "Version", mdver, true); // have to write value here
|
||||
appendTextElement(qdoc, &md, "Name", QString::fromLatin1(tmod->name,sizeof(tmod->name)).trimmed());
|
||||
appendCDATAElement(qdoc, &md, "Data", (const char *)tmod,sizeof(Ersky9xModelData_v11));
|
||||
return md;
|
||||
}
|
||||
|
||||
bool Ersky9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen)
|
||||
{
|
||||
// look for "GENERAL_DATA" tag
|
||||
QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement();
|
||||
|
||||
if(gde.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
// load cdata into tgen
|
||||
QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
QString ds = n.toCDATASection().data();
|
||||
QByteArray ba = QByteArray::fromBase64(ds.toLatin1());
|
||||
const char * data = ba.data();
|
||||
memcpy(tgen, data, std::min((unsigned int)ba.size(), (unsigned int)sizeof(Ersky9xGeneral)));
|
||||
break;
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Ersky9xInterface::loadModelDataXML(QDomDocument * qdoc, ModelData *model, int modelNum, int stickMode)
|
||||
{
|
||||
T ersky9xModel;
|
||||
memset(&ersky9xModel, 0, sizeof(ersky9xModel));
|
||||
|
||||
// look for MODEL_DATA with modelNum attribute.
|
||||
//if modelNum = -1 then just pick the first one
|
||||
QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA");
|
||||
|
||||
// cycle through nodes to find correct model number
|
||||
QDomNode k = ndl.at(0);
|
||||
if (modelNum>=0) {
|
||||
while(!k.isNull()) {
|
||||
int a = k.toElement().attribute("number").toInt();
|
||||
if(a==modelNum)
|
||||
break;
|
||||
k = k.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
if (k.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
// load cdata into tgen
|
||||
QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
QString ds = n.toCDATASection().data();
|
||||
QByteArray ba = QByteArray::fromBase64(ds.toLatin1());
|
||||
const char * data = ba.data();
|
||||
memcpy(&ersky9xModel, data, std::min(ba.size(), (int)sizeof(ersky9xModel)));
|
||||
break;
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
|
||||
applyStickModeToModel(ersky9xModel, stickMode);
|
||||
*model = ersky9xModel;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Ersky9xInterface::getCapability(Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Models:
|
||||
return 20;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ERSKY9XINTERFACE_H_
|
||||
#define _ERSKY9XINTERFACE_H_
|
||||
|
||||
#include <QtXml>
|
||||
#include "eeprominterface.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
|
||||
class RleFile;
|
||||
|
||||
class Ersky9xInterface : public EEPROMInterface
|
||||
{
|
||||
public:
|
||||
|
||||
Ersky9xInterface();
|
||||
|
||||
virtual ~Ersky9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getSize(const ModelData &);
|
||||
|
||||
virtual int getSize(const GeneralSettings & settings);
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0);
|
||||
|
||||
virtual int getCapability(Capability capability);
|
||||
|
||||
protected:
|
||||
|
||||
RleFile * efile;
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
|
||||
void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false);
|
||||
|
||||
void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size);
|
||||
|
||||
QDomElement getGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); //parse out data to XML format
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
bool loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); // get data from XML
|
||||
|
||||
template <class T>
|
||||
bool loadModelDataXML(QDomDocument * qdoc, ModelData * model, int modelNum, int stickMode); // get data from XML
|
||||
|
||||
};
|
||||
|
||||
#endif // _ERSKY9XINTERFACE_H_
|
||||
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "generalsettings.h"
|
||||
|
||||
#include "appdata.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
const uint8_t chout_ar[] = { // First number is 0..23 -> template setup, Second is relevant channel out
|
||||
1,2,3,4 , 1,2,4,3 , 1,3,2,4 , 1,3,4,2 , 1,4,2,3 , 1,4,3,2,
|
||||
2,1,3,4 , 2,1,4,3 , 2,3,1,4 , 2,3,4,1 , 2,4,1,3 , 2,4,3,1,
|
||||
3,1,2,4 , 3,1,4,2 , 3,2,1,4 , 3,2,4,1 , 3,4,1,2 , 3,4,2,1,
|
||||
4,1,2,3 , 4,1,3,2 , 4,2,1,3 , 4,2,3,1 , 4,3,1,2 , 4,3,2,1
|
||||
};
|
||||
|
||||
bool GeneralSettings::switchPositionAllowedTaranis(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
|
||||
div_t qr = div(abs(index)-1, 3);
|
||||
|
||||
if (index < 0 && switchConfig[qr.quot] != Board::SWITCH_3POS)
|
||||
return false;
|
||||
else if (qr.rem == 1)
|
||||
return switchConfig[qr.quot] == Board::SWITCH_3POS;
|
||||
else
|
||||
return switchConfig[qr.quot] != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::switchSourceAllowedTaranis(int index) const
|
||||
{
|
||||
return switchConfig[index] != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isPotAvailable(int index) const
|
||||
{
|
||||
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Pots)) return false;
|
||||
return potConfig[index] != Board::POT_NONE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isSliderAvailable(int index) const
|
||||
{
|
||||
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Sliders)) return false;
|
||||
return sliderConfig[index] != Board::SLIDER_NONE;
|
||||
}
|
||||
|
||||
GeneralSettings::GeneralSettings()
|
||||
{
|
||||
memset(this, 0, sizeof(GeneralSettings));
|
||||
|
||||
contrast = 25;
|
||||
|
||||
for (int i=0; i < CPN_MAX_ANALOGS; ++i) {
|
||||
calibMid[i] = 0x200;
|
||||
calibSpanNeg[i] = 0x180;
|
||||
calibSpanPos[i] = 0x180;
|
||||
}
|
||||
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
// vBatWarn is voltage in 100mV, vBatMin is in 100mV but with -9V offset, vBatMax has a -12V offset
|
||||
vBatWarn = 90;
|
||||
if (IS_TARANIS_X9E(board) || IS_HORUS_X12S(board)) {
|
||||
// NI-MH 9.6V
|
||||
vBatWarn = 87;
|
||||
vBatMin = -5; //8,5V
|
||||
vBatMax = -5; //11,5V
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board)) {
|
||||
// Lipo 2S
|
||||
vBatWarn = 66;
|
||||
vBatMin = -23; // 6.7V
|
||||
vBatMax = -37; // 8.3V
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
// NI-MH 7.2V, X9D, X9D+ and X7
|
||||
vBatWarn = 65;
|
||||
vBatMin = -30; //6V
|
||||
vBatMax = -40; //8V
|
||||
}
|
||||
|
||||
setDefaultControlTypes(board);
|
||||
|
||||
backlightMode = 3; // keys and sticks
|
||||
// backlightBright = 0; // 0 = 100%
|
||||
|
||||
if (IS_HORUS(board)) {
|
||||
backlightOffBright = 20;
|
||||
}
|
||||
|
||||
if (IS_ARM(board)) {
|
||||
speakerVolume = 12;
|
||||
}
|
||||
|
||||
if (IS_HORUS(board)) {
|
||||
strcpy(bluetoothName, "Horus");
|
||||
}
|
||||
else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board)) {
|
||||
strcpy(bluetoothName, "Taranis");
|
||||
}
|
||||
|
||||
templateSetup = g.profile[g.sessionId()].channelOrder();
|
||||
stickMode = g.profile[g.sessionId()].defaultMode();
|
||||
|
||||
QString t_calib = g.profile[g.sessionId()].stickPotCalib();
|
||||
int potsnum = getBoardCapability(getCurrentBoard(), Board::Pots);
|
||||
if (!t_calib.isEmpty()) {
|
||||
QString t_trainercalib=g.profile[g.sessionId()].trainerCalib();
|
||||
int8_t t_txVoltageCalibration=(int8_t)g.profile[g.sessionId()].txVoltageCalibration();
|
||||
int8_t t_txCurrentCalibration=(int8_t)g.profile[g.sessionId()].txCurrentCalibration();
|
||||
int8_t t_PPM_Multiplier=(int8_t)g.profile[g.sessionId()].ppmMultiplier();
|
||||
uint8_t t_stickMode=(uint8_t)g.profile[g.sessionId()].gsStickMode();
|
||||
uint8_t t_vBatWarn=(uint8_t)g.profile[g.sessionId()].vBatWarn();
|
||||
QString t_DisplaySet=g.profile[g.sessionId()].display();
|
||||
QString t_BeeperSet=g.profile[g.sessionId()].beeper();
|
||||
QString t_HapticSet=g.profile[g.sessionId()].haptic();
|
||||
QString t_SpeakerSet=g.profile[g.sessionId()].speaker();
|
||||
QString t_CountrySet=g.profile[g.sessionId()].countryCode();
|
||||
|
||||
if ((t_calib.length()==(CPN_MAX_STICKS+potsnum)*12) && (t_trainercalib.length()==16)) {
|
||||
QString Byte;
|
||||
int16_t byte16;
|
||||
bool ok;
|
||||
for (int i=0; i<(CPN_MAX_STICKS+potsnum); i++) {
|
||||
Byte=t_calib.mid(i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibMid[i]=byte16;
|
||||
Byte=t_calib.mid(4+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanNeg[i]=byte16;
|
||||
Byte=t_calib.mid(8+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanPos[i]=byte16;
|
||||
}
|
||||
for (int i=0; i<4; i++) {
|
||||
Byte=t_trainercalib.mid(i*4,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
trainer.calib[i]=byte16;
|
||||
}
|
||||
txCurrentCalibration=t_txCurrentCalibration;
|
||||
txVoltageCalibration=t_txVoltageCalibration;
|
||||
vBatWarn=t_vBatWarn;
|
||||
PPM_Multiplier=t_PPM_Multiplier;
|
||||
stickMode = t_stickMode;
|
||||
}
|
||||
if ((t_DisplaySet.length()==6) && (t_BeeperSet.length()==4) && (t_HapticSet.length()==6) && (t_SpeakerSet.length()==6)) {
|
||||
uint8_t byte8u;
|
||||
int8_t byte8;
|
||||
bool ok;
|
||||
byte8=(int8_t)t_DisplaySet.mid(0,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
optrexDisplay=(byte8==1 ? true : false);
|
||||
byte8u=(uint8_t)t_DisplaySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
contrast=byte8u;
|
||||
byte8u=(uint8_t)t_DisplaySet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
backlightBright=byte8u;
|
||||
byte8=(int8_t)t_BeeperSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
beeperMode=(BeeperMode)byte8;
|
||||
byte8=(int8_t)t_BeeperSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
beeperLength=byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
hapticMode=(BeeperMode)byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
hapticStrength=byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(4,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
hapticLength=byte8;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerMode=byte8u;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerPitch=byte8u;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerVolume=byte8u;
|
||||
if (t_CountrySet.length()==6) {
|
||||
byte8u=(uint8_t)t_CountrySet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
countryCode=byte8u;
|
||||
byte8u=(uint8_t)t_CountrySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
imperial=byte8u;
|
||||
QString chars = t_CountrySet.mid(4, 2);
|
||||
ttsLanguage[0] = chars[0].toLatin1();
|
||||
ttsLanguage[1] = chars[1].toLatin1();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(themeName, "default");
|
||||
ThemeOptionData option1 = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 };
|
||||
memcpy(&themeOptionValue[0], option1, sizeof(ThemeOptionData));
|
||||
ThemeOptionData option2 = { 0x03, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 };
|
||||
memcpy(&themeOptionValue[1], option2, sizeof(ThemeOptionData));
|
||||
}
|
||||
|
||||
void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
||||
{
|
||||
for (int i=0; i<getBoardCapability(board, Board::FactoryInstalledSwitches); i++) {
|
||||
switchConfig[i] = Boards::getSwitchInfo(board, i).config;
|
||||
}
|
||||
|
||||
// TODO: move to Boards, like with switches
|
||||
if (IS_HORUS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_MULTIPOS_SWITCH;
|
||||
potConfig[2] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X7(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[2] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[3] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
}
|
||||
|
||||
int GeneralSettings::getDefaultStick(unsigned int channel) const
|
||||
{
|
||||
if (channel >= CPN_MAX_STICKS)
|
||||
return -1;
|
||||
else
|
||||
return chout_ar[4*templateSetup + channel] - 1;
|
||||
}
|
||||
|
||||
RawSource GeneralSettings::getDefaultSource(unsigned int channel) const
|
||||
{
|
||||
int stick = getDefaultStick(channel);
|
||||
if (stick >= 0)
|
||||
return RawSource(SOURCE_TYPE_STICK, stick);
|
||||
else
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
|
||||
int GeneralSettings::getDefaultChannel(unsigned int stick) const
|
||||
{
|
||||
for (int i=0; i<4; i++){
|
||||
if (getDefaultStick(i) == (int)stick)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void GeneralSettings::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
// Here we can add explicit conversions when moving from one board to another
|
||||
|
||||
cstate.setOrigin(tr("Radio Settings"));
|
||||
|
||||
setDefaultControlTypes(cstate.toType); // start with default switches/pots/sliders
|
||||
|
||||
// Try to intelligently copy any custom control names
|
||||
|
||||
// SE and SG are skipped on X7 board
|
||||
if (IS_TARANIS_X7(cstate.toType)) {
|
||||
if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) {
|
||||
strncpy(switchName[4], switchName[5], sizeof(switchName[4]));
|
||||
strncpy(switchName[5], switchName[7], sizeof(switchName[5]));
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS_X7(cstate.fromType)) {
|
||||
if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) {
|
||||
strncpy(switchName[5], switchName[4], sizeof(switchName[5]));
|
||||
strncpy(switchName[7], switchName[5], sizeof(switchName[7]));
|
||||
}
|
||||
}
|
||||
|
||||
// LS and RS sliders are after 2 aux sliders on X12 and X9E
|
||||
if ((IS_HORUS_X12S(cstate.toType) || IS_TARANIS_X9E(cstate.toType)) && !IS_HORUS_X12S(cstate.fromType) && !IS_TARANIS_X9E(cstate.fromType)) {
|
||||
strncpy(sliderName[0], sliderName[2], sizeof(sliderName[0]));
|
||||
strncpy(sliderName[1], sliderName[3], sizeof(sliderName[1]));
|
||||
}
|
||||
else if (!IS_TARANIS_X9E(cstate.toType) && !IS_HORUS_X12S(cstate.toType) && (IS_HORUS_X12S(cstate.fromType) || IS_TARANIS_X9E(cstate.fromType))) {
|
||||
strncpy(sliderName[2], sliderName[0], sizeof(sliderName[2]));
|
||||
strncpy(sliderName[3], sliderName[1], sizeof(sliderName[3]));
|
||||
}
|
||||
|
||||
if (IS_HORUS(cstate.toType)) {
|
||||
// 6P switch is only on Horus (by default)
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) == 2) {
|
||||
strncpy(potName[2], potName[1], sizeof(potName[2]));
|
||||
potName[1][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS(cstate.toType)) {
|
||||
// No S3 pot on Taranis boards by default
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) > 2)
|
||||
strncpy(potName[1], potName[2], sizeof(potName[1]));
|
||||
|
||||
contrast = qBound<int>(getCurrentFirmware()->getCapability(MinContrast), contrast, getCurrentFirmware()->getCapability(MaxContrast));
|
||||
}
|
||||
|
||||
// TODO: Would be nice at this point to have GUI pause and ask the user to set up any custom hardware they have on the destination radio.
|
||||
|
||||
// Convert all global functions (do this after HW adjustments)
|
||||
for (int i=0; i<CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
customFn[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef GENERALSETTINGS_H
|
||||
#define GENERALSETTINGS_H
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
#include "customfunctiondata.h"
|
||||
#include "rawsource.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class Firmware;
|
||||
class ModelData;
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum UartModes {
|
||||
UART_MODE_NONE,
|
||||
UART_MODE_TELEMETRY_MIRROR,
|
||||
UART_MODE_TELEMETRY,
|
||||
UART_MODE_SBUS_TRAINER,
|
||||
UART_MODE_DEBUG
|
||||
};
|
||||
|
||||
class TrainerMix {
|
||||
public:
|
||||
TrainerMix() { clear(); }
|
||||
unsigned int src; // 0-7 = ch1-8
|
||||
RawSwitch swtch;
|
||||
int weight;
|
||||
unsigned int mode; // off, add-mode, subst-mode
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TrainerMix)); }
|
||||
};
|
||||
|
||||
class TrainerData {
|
||||
public:
|
||||
TrainerData() { clear(); }
|
||||
int calib[4];
|
||||
TrainerMix mix[4];
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TrainerData)); }
|
||||
};
|
||||
|
||||
class GeneralSettings {
|
||||
Q_DECLARE_TR_FUNCTIONS(GeneralSettings)
|
||||
|
||||
public:
|
||||
|
||||
enum BeeperMode {
|
||||
BEEPER_QUIET = -2,
|
||||
BEEPER_ALARMS_ONLY = -1,
|
||||
BEEPER_NOKEYS = 0,
|
||||
BEEPER_ALL = 1
|
||||
};
|
||||
|
||||
GeneralSettings();
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
void setDefaultControlTypes(Board::Type board);
|
||||
int getDefaultStick(unsigned int channel) const;
|
||||
RawSource getDefaultSource(unsigned int channel) const;
|
||||
int getDefaultChannel(unsigned int stick) const;
|
||||
|
||||
unsigned int version;
|
||||
unsigned int variant;
|
||||
int calibMid[CPN_MAX_ANALOGS];
|
||||
int calibSpanNeg[CPN_MAX_ANALOGS];
|
||||
int calibSpanPos[CPN_MAX_ANALOGS];
|
||||
unsigned int currModelIndex;
|
||||
char currModelFilename[16+1];
|
||||
unsigned int contrast;
|
||||
unsigned int vBatWarn;
|
||||
int txVoltageCalibration;
|
||||
int txCurrentCalibration;
|
||||
int vBatMin;
|
||||
int vBatMax;
|
||||
int backlightMode;
|
||||
TrainerData trainer;
|
||||
unsigned int view; // main screen view // TODO enum
|
||||
bool disableThrottleWarning;
|
||||
bool fai;
|
||||
bool disableMemoryWarning;
|
||||
BeeperMode beeperMode;
|
||||
bool disableAlarmWarning;
|
||||
bool disableRssiPoweroffAlarm;
|
||||
unsigned int usbMode;
|
||||
BeeperMode hapticMode;
|
||||
unsigned int stickMode; // TODO enum
|
||||
int timezone;
|
||||
bool adjustRTC;
|
||||
bool optrexDisplay;
|
||||
unsigned int inactivityTimer;
|
||||
bool minuteBeep;
|
||||
bool preBeep;
|
||||
bool flashBeep;
|
||||
unsigned int splashMode;
|
||||
int splashDuration;
|
||||
unsigned int backlightDelay;
|
||||
unsigned int templateSetup; //RETA order according to chout_ar array
|
||||
int PPM_Multiplier;
|
||||
int hapticLength;
|
||||
unsigned int reNavigation;
|
||||
unsigned int stickReverse;
|
||||
unsigned int speakerPitch;
|
||||
int hapticStrength;
|
||||
unsigned int speakerMode;
|
||||
char ownerName[10+1];
|
||||
int beeperLength;
|
||||
unsigned int gpsFormat;
|
||||
int speakerVolume;
|
||||
unsigned int backlightBright;
|
||||
unsigned int backlightOffBright;
|
||||
int switchesDelay;
|
||||
int temperatureCalib;
|
||||
int temperatureWarn;
|
||||
unsigned int mAhWarn;
|
||||
unsigned int mAhUsed;
|
||||
unsigned int globalTimer;
|
||||
char bluetoothName[10+1];
|
||||
unsigned int bluetoothBaudrate;
|
||||
unsigned int bluetoothMode;
|
||||
unsigned int sticksGain;
|
||||
unsigned int rotarySteps;
|
||||
unsigned int countryCode;
|
||||
bool jitterFilter;
|
||||
unsigned int imperial;
|
||||
char ttsLanguage[2+1];
|
||||
int beepVolume;
|
||||
int wavVolume;
|
||||
int varioVolume;
|
||||
int varioPitch;
|
||||
int varioRange;
|
||||
int varioRepeat;
|
||||
int backgroundVolume;
|
||||
unsigned int mavbaud;
|
||||
unsigned int switchUnlockStates;
|
||||
unsigned int hw_uartMode; // UartModes
|
||||
unsigned int backlightColor;
|
||||
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||
char switchName[CPN_MAX_SWITCHES][3+1];
|
||||
unsigned int switchConfig[CPN_MAX_SWITCHES];
|
||||
char stickName[CPN_MAX_STICKS][3+1];
|
||||
char potName[CPN_MAX_KNOBS][3+1];
|
||||
unsigned int potConfig[CPN_MAX_KNOBS];
|
||||
char sliderName[CPN_MAX_SLIDERS][3+1];
|
||||
unsigned int sliderConfig[CPN_MAX_SLIDERS];
|
||||
|
||||
char themeName[8+1];
|
||||
typedef uint8_t ThemeOptionData[8+1];
|
||||
ThemeOptionData themeOptionValue[5];
|
||||
|
||||
bool switchPositionAllowedTaranis(int index) const;
|
||||
bool switchSourceAllowedTaranis(int index) const;
|
||||
bool isPotAvailable(int index) const;
|
||||
bool isSliderAvailable(int index) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // GENERALSETTINGS_H
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "gvardata.h"
|
||||
|
||||
#include "radiodata.h"
|
||||
|
||||
QString GVarData::unitToString() const
|
||||
{
|
||||
switch (unit) {
|
||||
case GVAR_UNIT_NUMBER:
|
||||
return tr("");
|
||||
case GVAR_UNIT_PERCENT:
|
||||
return tr("%");
|
||||
default:
|
||||
return tr("?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::precToString() const
|
||||
{
|
||||
switch (prec) {
|
||||
case GVAR_PREC_MUL10:
|
||||
return tr("0._");
|
||||
case GVAR_PREC_MUL1:
|
||||
return tr("0.0");
|
||||
default:
|
||||
return tr("?.?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("GV"), index + 1, name);
|
||||
}
|
||||
|
||||
int GVarData::multiplierSet()
|
||||
{
|
||||
return (prec == 0 ? 1 : 10);
|
||||
}
|
||||
|
||||
float GVarData::multiplierGet() const
|
||||
{
|
||||
return (prec == 0 ? 1 : 0.1);
|
||||
}
|
||||
|
||||
void GVarData::setMin(float val)
|
||||
{
|
||||
min = (val * multiplierSet()) - GVAR_MIN_VALUE;
|
||||
}
|
||||
|
||||
void GVarData::setMax(float val)
|
||||
{
|
||||
max = GVAR_MAX_VALUE - (val * multiplierSet());
|
||||
}
|
||||
|
||||
int GVarData::getMin() const
|
||||
{
|
||||
return GVAR_MIN_VALUE + min;
|
||||
}
|
||||
|
||||
int GVarData::getMax() const
|
||||
{
|
||||
return GVAR_MAX_VALUE - max;
|
||||
}
|
||||
|
||||
float GVarData::getMinPrec() const
|
||||
{
|
||||
return getMin() * multiplierGet();
|
||||
}
|
||||
|
||||
float GVarData::getMaxPrec() const
|
||||
{
|
||||
return getMax() * multiplierGet();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user