mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-25 01:05:08 +03:00
refact: ADC, switches and keys
Add "hardware_defs" target to dump hardware defines from hal.h per target Fixed hal.h definitions for switches & ADC inputs Tools to generate hardware definitions from current hal.h generator: add support for EXTx and analog switches WiP Add generated header to hardware_defs target Add support for ADC input direction and index per GPIO port Incredible: it compiles Removed StdPeriph ADC driver Works on QX7 Works on TX16S (VBat missing) Switch driver using generated switches for stm32 targets Switch driver with generated switches for simu Use switch names from switch driver Fixed single conversion handling Fixed horus VBat reading Added switch name Fix warnings about bitfield offsets and GCC 4.4 This is caused by bitfields that cross type boundaries. In this particular case, it happens as the bitfield is not defined the same in `rtc_backup.cpp`. Switches has already been moved to generic driver Jitter measurement for each sample, not just for oversampled values Moved periph clock init to the ADC driver ADC & GPIOs. Add switchInit() to init pins Fix NV14 CMake Fix taranis target Fix NV14 (again) Model audio files: use new interface for switch index Fix X9-lite Fix simu headers Fix getSwitchName() Add support for ADC switches Fix switch warning YAML Test only switches which are defined Conversions tests for QX7 only on QX7 Fix X12S Fix function switch names Enable ADC periph clock before initialising channels NV14: offset inputs for the sticks & fix switches WiP: get rid of VSRCRAW and some more Simu shall use normal ADC driver fix x7 fix nv14 Fix 9x nav fix 212x64 fix xlite fix x9e fix simu lib fix unit tests fix x7 tests PWM stick values should be written directly into adcValues ... just like FlySky sticks. fix x12s fix nv14 Add some support for SPI ADC (only unit tests) Remove `jq` usage fix generate_yaml.py for newer libclang fix pot config fix stick names Some YAML generator improvements Max 16 Pots on COLORLCD Fix some source names Use 10 bits for switches to prevent overflow Removed horus constants for switches & ADC inputs Fix unit tests Fix curve edit Fix libsimulator Fix function switches (tpro) Refine ADC & analog API Moved hardware definitions scripts and templates into own dir cleanup API refine Fix unit tests Mixer: apply calibration only on required inputs Place ADC switches after all other ADC inputs Fix X12S Remove useless TR_POTS_VSRCRAW, TR_SW_VSRCRAW, and TR_VSRCRAW Cleanup redundant generated YAML parsers Fixes Boxer rebase Add boxer to generate-hw-defs.sh Obsolete LUA exports Add boxer ADC_DIRECTION Split generate_hw_defs.py into multiple files Some cleanup (+ LUA switches) Fix AXIS definitions Fixed translation strings declarations Some rebase fixes Remove some useless StdPeriph drivers fix: set pin mode to reset state on usart deinit fix: use canonical names for calibration data fix: ADC driver does not care about unconfigured inputs fix X12S ADC Add support for ADC conversion chaining Better X12S ADC implem Moved X12S ADC driver to HAL/LL Improve ADC driver separation Fixed taranis & nv14 Moved PWM gimbals to HAL/LL Removed useless TR_EXTRA_VSRCRAW Fixed include guards Small fixes Renamed control inputs Moved internal and external module pulse driver def to boards Move more things to the generic_stm32 board Remove STR_VMIXTRIMS Added analog labels Generate main control names Misuse labels / short labels for main controls Backward compatibility: sliders and legacy names New keys driver Let's get rid of StdPeriph headers in simu Add jinja2 to CI workflows Use `grep` instead of `sed` chore: add python jinja2 oto msys setup script Removed more static definitions and use dynamic ones instead Fixes X9E Fix x7 nav too 212 switch display Fix default sliders Removed NUM_STICKS 212 switch display working nicely Surface radio 'stick' replacements fix: switch, trim & rotary pin init Remove old key drivers Removed VKEYS Removed ETX_FOURCC Fixed SURFACE_NAME Removed TR_VSWITCHES & TR_TRIMS_SWITCHES Fix xpot switches Store calibrated analogs in physical order Use getSourceString in drawSource Implement missing YAML read/write Fix isSourceAvailableInInputs() Fix isSourceAvailable() Some surface fixes Fix CLI debug Ported colour UI of analog diagnostics to new ADC API Small fixes Better input mapping Minor tpro fixes Fix trims available Remove TX mode choice on surface radio Rename surface controls Channel order alignement Fix throttle warning Fix checkTrims() Fix pot config casting issue Fix IS_SWITCH_FS() Fixed input mapping Fix fswitch auto-switch Fixed storing / reading function switches in YAML Fix enableVBatBridge() / disableVBatBridge() Fix interesting mode conversion Fix sources issues Fix special funnction list Proper function switch handling 128 GUI improvements Fix compilation Boxer cosmetics 128 hardware screen cosmetic Fix TX12 switches More switches fixes Simplify CPU type handling Fix flash size Fixed page-up / page-down in libopenui
This commit is contained in:
parent
b6dd3a0ef8
commit
2b100e0eb5
323 changed files with 12813 additions and 22302 deletions
2
.github/workflows/macosx_cpn.yml
vendored
2
.github/workflows/macosx_cpn.yml
vendored
|
@ -68,7 +68,7 @@ jobs:
|
|||
setup-python: 'false'
|
||||
|
||||
- name: Install dependencies
|
||||
run: python3 -m pip install --upgrade pip Pillow lz4 clang
|
||||
run: python3 -m pip install --upgrade pip Pillow lz4 clang jinja2
|
||||
|
||||
- name: Patch GitHub macOS build
|
||||
run: brew install pkg-config
|
||||
|
|
2
.github/workflows/win_cpn-64.yml
vendored
2
.github/workflows/win_cpn-64.yml
vendored
|
@ -71,7 +71,7 @@ jobs:
|
|||
mingw-w64-x86_64-SDL2 \
|
||||
mingw-w64-x86_64-clang \
|
||||
mingw-w64-x86_64-nsis
|
||||
python -m pip install clang
|
||||
python -m pip install clang jinja2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
|
|
|
@ -33,7 +33,6 @@ endif()
|
|||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
add_definitions(-D_GLIBCXX_USE_C99=1) # proper to_string definition
|
||||
|
||||
set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio)
|
||||
|
|
|
@ -16,11 +16,6 @@ macro(git_id RESULT)
|
|||
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$")
|
||||
|
@ -60,7 +55,6 @@ function(AddCompilerFlags output)
|
|||
endforeach()
|
||||
|
||||
# Add hotfix for arm64
|
||||
set(ARGS ${ARGS} -Wno-asm-operand-widths -Wno-pragma-once-outside-header)
|
||||
|
||||
set(${output} ${${output}} ${ARGS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
@ -73,6 +67,8 @@ function(GenerateDatacopy source output)
|
|||
# Fetch defines / include directories in use
|
||||
AddCompilerFlags(GEN_DATACOPY_ARGS)
|
||||
|
||||
# Hack to get rid of warnings in StdPeriph lib
|
||||
|
||||
set(GEN_DATACOPY_ARGS
|
||||
# source file MUST be the first argument
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${source}
|
||||
|
@ -86,5 +82,51 @@ function(GenerateDatacopy source output)
|
|||
COMMAND ${GEN_DATACOPY_CMD} > ${output}
|
||||
DEPENDS ${GEN_DATACOPY_DEPEND}
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
function(AddHardwareDefTarget output)
|
||||
|
||||
AddCompilerFlags(HW_DEF_ARGS)
|
||||
|
||||
set(HW_DEF_SRC ${RADIO_DIRECTORY}/src/targets/${TARGET_DIR}/hal.h)
|
||||
|
||||
separate_arguments(flags UNIX_COMMAND ${CMAKE_CXX_FLAGS})
|
||||
foreach(flag ${flags})
|
||||
set(HW_DEF_ARGS ${HW_DEF_ARGS} ${flag})
|
||||
endforeach()
|
||||
|
||||
set(GEN_HW_DEFS ${CMAKE_CXX_COMPILER} ${HW_DEF_ARGS} -x c++-header -E -dM ${HW_DEF_SRC})
|
||||
set(GEN_HW_DEFS ${GEN_HW_DEFS} | grep -v "^#define _" | sort)
|
||||
|
||||
set(GEN_JSON ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/hw_defs/generate_hw_def.py)
|
||||
set(GEN_JSON ${GEN_JSON} -i defines -T ${FLAVOUR} -)
|
||||
|
||||
add_custom_command(OUTPUT ${output}
|
||||
COMMAND ${GEN_HW_DEFS} | ${GEN_JSON} > ${output}
|
||||
DEPENDS ${HW_DEF_SRC} ${RADIO_DIRECTORY}/util/hw_defs/generate_hw_def.py
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${output}.h
|
||||
COMMAND ${GEN_HW_DEFS} > ${output}.h
|
||||
DEPENDS ${HW_DEF_SRC} ${RADIO_DIRECTORY}/util/hw_defs/generate_hw_def.py
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(AddHWGenTarget input template output)
|
||||
|
||||
# Script
|
||||
set(GEN_JSON ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/hw_defs/generate_hw_def.py)
|
||||
|
||||
# Inputs
|
||||
set(INPUT_JSON ${CMAKE_CURRENT_BINARY_DIR}/${input})
|
||||
set(TEMPLATE ${RADIO_DIRECTORY}/util/hw_defs/${template}.jinja)
|
||||
set(LEGACY_JSON ${RADIO_DIRECTORY}/util/hw_defs/legacy_names.py)
|
||||
|
||||
# Command
|
||||
set(GEN_JSON ${GEN_JSON} -t ${TEMPLATE} -T ${FLAVOUR} ${INPUT_JSON})
|
||||
|
||||
add_custom_command(OUTPUT ${output}
|
||||
COMMAND ${GEN_JSON} > ${output}
|
||||
DEPENDS ${INPUT_JSON} ${LEGACY_JSON} ${TEMPLATE}
|
||||
)
|
||||
endfunction()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# arm-none-eabi toolchain
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# Native toolchain
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_C_FLAGS "-Wno-asm-operand-widths -Wno-deprecated-declarations")
|
||||
set(CMAKE_CXX_FLAGS "-Wno-asm-operand-widths -Wno-deprecated-declarations")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wno-asm-operand-widths -Wno-deprecated-declarations")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wno-asm-operand-widths -Wno-deprecated-declarations")
|
||||
set(CMAKE_C_FLAGS "-Wno-deprecated-declarations")
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated-declarations")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wno-deprecated-declarations")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wno-deprecated-declarations")
|
||||
endif()
|
||||
|
||||
if(MINGW OR WIN32)
|
||||
|
|
|
@ -81,8 +81,6 @@ 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}
|
||||
|
|
|
@ -20,8 +20,6 @@ if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND)
|
|||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${WARNING_FLAGS}")
|
||||
|
||||
use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
|
||||
|
||||
add_executable(gtests-companion EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h.in)
|
||||
add_dependencies(gtests-companion gtests-companion-lib)
|
||||
target_link_libraries(gtests-companion gtests-companion-lib simulation firmwares storage common)
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
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 ()
|
||||
|
||||
find_package(Qt5Core)
|
||||
find_package(Qt5Widgets)
|
||||
|
|
|
@ -11,7 +11,7 @@ set(TRANSLATIONS "EN" CACHE STRING "Radio language, one of: ${RADIO_LANGUAGES}")
|
|||
set_property(CACHE TRANSLATIONS PROPERTY STRINGS ${RADIO_LANGUAGES})
|
||||
set(SPLASH "DEFAULT" CACHE STRING "Splash (DEFAULT/OFF/FRSKY)")
|
||||
set_property(CACHE SPLASH PROPERTY STRINGS DEFAULT OFF FRSKY)
|
||||
set(PPM_UNIT "PERCENT_PREC1" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)")
|
||||
set(PPM_UNIT "PERCENT_PREC0" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)")
|
||||
set_property(CACHE PPM_UNIT PROPERTY STRINGS US PERCENT_PREC1 PERCENT_PREC0)
|
||||
set(DEFAULT_MODE "" CACHE STRING "Default sticks mode")
|
||||
set(POPUP_LEVEL 2 CACHE STRING "Popup level")
|
||||
|
@ -48,7 +48,6 @@ option(DEBUG_SEGGER_RTT "Debug output to Segger RTT" OFF)
|
|||
option(DEBUG_WINDOWS "Turn on windows traces" OFF)
|
||||
option(DEBUG_YAML "Turn on YAML traces" OFF)
|
||||
option(DEBUG_LABELS "Turn on Labels traces" OFF)
|
||||
option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF)
|
||||
option(NANO "Use nano newlib and binalloc")
|
||||
option(TEST_BUILD_WARNING "Warn this is a test build" OFF)
|
||||
option(MODULE_PROTOCOL_FCC "Add support for FCC modules" ON)
|
||||
|
@ -73,15 +72,6 @@ set(FIRMWARE_C_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware targ
|
|||
set(FIRMWARE_CXX_FLAGS "" CACHE STRING "Additional flags for firmware target c++ compiler (note: all CMAKE_CXX_FLAGS[_*] are ignored for firmware/bootloader).")
|
||||
set(FIRMWARE_CXX_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c++ compiler (note: CMAKE_CXX_FLAGS_DEBUG is ignored for firmware/bootloader).")
|
||||
|
||||
set(GCC_ARM_PATH "" CACHE STRING "Alternative GCC ARM path")
|
||||
|
||||
set(FIRMWARE_C_COMPILER "${GCC_ARM_PATH}arm-none-eabi-gcc" CACHE STRING "Specific C compiler for firmware target.")
|
||||
set(FIRMWARE_CXX_COMPILER "${GCC_ARM_PATH}arm-none-eabi-g++" CACHE STRING "Specific C++ compiler for firmware target.")
|
||||
set(FIRMWARE_ASM_COMPILER "${GCC_ARM_PATH}arm-none-eabi-as" CACHE STRING "Specific assembler for firmware target.")
|
||||
set(FIRMWARE_OBJCOPY "${GCC_ARM_PATH}arm-none-eabi-objcopy" CACHE STRING "Specific objcopy for firmware target.")
|
||||
set(FIRMWARE_SIZE "${GCC_ARM_PATH}arm-none-eabi-size" CACHE STRING "Specific size for firmware target.")
|
||||
set(FIRMWARE_RANLIB "${GCC_ARM_PATH}arm-none-eabi-ranlib" CACHE STRING "Specific ranlib for firmware target.")
|
||||
|
||||
set(THIRDPARTY_DIR thirdparty)
|
||||
set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src)
|
||||
set(RTOS_DIR ${THIRDPARTY_DIR}/FreeRTOS)
|
||||
|
@ -111,16 +101,17 @@ else()
|
|||
message(FATAL_ERROR "Unknown PCB '${PCB}'")
|
||||
endif()
|
||||
|
||||
set(HW_DESC_JSON ${FLAVOUR}.json)
|
||||
AddHardwareDefTarget(${HW_DESC_JSON})
|
||||
|
||||
# enable generating JSON definition separately for debugging
|
||||
add_custom_target(hardware_defs DEPENDS ${HW_DESC_JSON} ${HW_DESC_JSON}.h)
|
||||
|
||||
include(hal/CMakeLists.txt)
|
||||
|
||||
add_subdirectory(bitmaps)
|
||||
add_subdirectory(fonts)
|
||||
|
||||
if(NOT PCB STREQUAL 9XRPRO)
|
||||
option(DBLKEYS "Double Keys" ON)
|
||||
if(DBLKEYS)
|
||||
add_definitions(-DDBLKEYS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CPU_TYPE STREQUAL STM32F4)
|
||||
include(targets/common/arm/stm32/f4/CMakeLists.txt)
|
||||
endif()
|
||||
|
@ -131,6 +122,7 @@ endif()
|
|||
|
||||
if(CPU_FAMILY STREQUAL STM32)
|
||||
include(targets/common/arm/stm32/CMakeLists.txt)
|
||||
include(boards/generic_stm32/CMakeLists.txt)
|
||||
endif()
|
||||
|
||||
if(ARCH STREQUAL ARM)
|
||||
|
@ -185,7 +177,7 @@ if(RTC_BACKUP_RAM)
|
|||
)
|
||||
|
||||
# Add custom target for debugging
|
||||
add_custom_target(datacopy DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/datacopy.cpp)
|
||||
add_custom_target(datacopy DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/datacopy.inc)
|
||||
endif()
|
||||
|
||||
if(LUA)
|
||||
|
@ -325,10 +317,6 @@ if(DEBUG_LABELS)
|
|||
add_definitions(-DDEBUG_LABELS)
|
||||
endif()
|
||||
|
||||
if(FRSKY_STICKS)
|
||||
add_definitions(-DFRSKY_STICKS)
|
||||
endif()
|
||||
|
||||
if(IMU_LSM6DS33)
|
||||
add_definitions(-DIMU_LSM6DS33)
|
||||
endif()
|
||||
|
@ -405,6 +393,7 @@ set(SRC
|
|||
functions.cpp
|
||||
strhelpers.cpp
|
||||
switches.cpp
|
||||
analogs.cpp
|
||||
mixer.cpp
|
||||
mixer_scheduler.cpp
|
||||
stamp.cpp
|
||||
|
@ -413,7 +402,8 @@ set(SRC
|
|||
model_init.cpp
|
||||
serial.cpp
|
||||
sbus.cpp
|
||||
hal/module_port.cpp
|
||||
input_mapping.cpp
|
||||
inactivity_timer.cpp
|
||||
tasks/mixer_task.cpp
|
||||
)
|
||||
|
||||
|
@ -556,7 +546,7 @@ endif()
|
|||
|
||||
add_definitions(-DFREE_RTOS)
|
||||
|
||||
add_executable(firmware ${SRC} ${FIRMWARE_HEADERS})
|
||||
add_executable(firmware ${SRC})
|
||||
link_libraries(firmware -lstdc++)
|
||||
add_dependencies(firmware ${RADIO_DEPENDENCIES})
|
||||
set_target_properties(firmware PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
|
@ -618,3 +608,5 @@ if(CPU_FAMILY STREQUAL STM32)
|
|||
endif()
|
||||
|
||||
PrintTargetReport("firmware")
|
||||
|
||||
AddHardwareDefTarget(hardware_defs ${RADIO_DIRECTORY}/src/targets/hw_defs/${FLAVOUR}.json)
|
||||
|
|
100
radio/src/analogs.cpp
Normal file
100
radio/src/analogs.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "analogs.h"
|
||||
#include "dataconstants.h"
|
||||
#include "opentx_helpers.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
static char _custom_names[MAX_ANALOG_INPUTS][LEN_ANA_NAME + 1] = { 0 };
|
||||
|
||||
void analogSetCustomLabel(uint8_t type, uint8_t idx, const char* str, size_t len)
|
||||
{
|
||||
if (idx >= adcGetMaxInputs(type)) return;
|
||||
idx += adcGetInputOffset(type);
|
||||
|
||||
strncpy(_custom_names[idx], str, min<size_t>(LEN_ANA_NAME, len));
|
||||
_custom_names[idx][LEN_ANA_NAME] = '\0';
|
||||
}
|
||||
|
||||
const char* analogGetCustomLabel(uint8_t type, uint8_t idx)
|
||||
{
|
||||
if (idx >= adcGetMaxInputs(type)) return "";
|
||||
idx += adcGetInputOffset(type);
|
||||
|
||||
return _custom_names[idx];
|
||||
}
|
||||
|
||||
bool analogHasCustomLabel(uint8_t type, uint8_t idx)
|
||||
{
|
||||
return *analogGetCustomLabel(type, idx) != 0;
|
||||
}
|
||||
|
||||
static int _lookup_input_idx(uint8_t type, const char* name, size_t len,
|
||||
const char* (*fct)(uint8_t,uint8_t))
|
||||
{
|
||||
auto max_inputs = adcGetMaxInputs(type);
|
||||
if (!max_inputs) return -1;
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
if (!strncmp(fct(type, i), name, len)) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int analogLookupPhysicalIdx(uint8_t type, const char* name, size_t len)
|
||||
{
|
||||
return _lookup_input_idx(type, name, len, adcGetInputName);
|
||||
}
|
||||
|
||||
static int analogLookupLabelIdx(uint8_t type, const char* name, size_t len)
|
||||
{
|
||||
return _lookup_input_idx(type, name, len, adcGetInputLabel);
|
||||
}
|
||||
|
||||
const char* analogGetPhysicalName(uint8_t type, uint8_t idx)
|
||||
{
|
||||
return adcGetInputName(type, idx);
|
||||
}
|
||||
|
||||
const char* analogGetCanonicalName(uint8_t type, uint8_t idx)
|
||||
{
|
||||
// Main controls are special cases here as
|
||||
// we use the label slot to place the specific names
|
||||
// (2-gimbal radios vs. surface radios)
|
||||
|
||||
if (type == ADC_INPUT_MAIN)
|
||||
return adcGetInputLabel(type, idx);
|
||||
|
||||
return adcGetInputName(type, idx);
|
||||
}
|
||||
|
||||
int analogLookupCanonicalIdx(uint8_t type, const char* name, size_t len)
|
||||
{
|
||||
if (type == ADC_INPUT_MAIN) {
|
||||
return analogLookupLabelIdx(type, name, len);
|
||||
}
|
||||
|
||||
return analogLookupPhysicalIdx(type, name, len);
|
||||
}
|
||||
|
35
radio/src/analogs.h
Normal file
35
radio/src/analogs.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void analogSetCustomLabel(uint8_t type, uint8_t idx, const char* str, size_t len);
|
||||
const char* analogGetCustomLabel(uint8_t type, uint8_t idx);
|
||||
bool analogHasCustomLabel(uint8_t type, uint8_t idx);
|
||||
|
||||
const char* analogGetPhysicalName(uint8_t type, uint8_t idx);
|
||||
int analogLookupPhysicalIdx(uint8_t type, const char* name, size_t len);
|
||||
|
||||
const char* analogGetCanonicalName(uint8_t type, uint8_t idx);
|
||||
int analogLookupCanonicalIdx(uint8_t type, const char* name, size_t len);
|
|
@ -22,6 +22,8 @@
|
|||
#include "opentx.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "switches.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
#include "libopenui.h"
|
||||
#endif
|
||||
|
@ -241,9 +243,12 @@ const char * const audioFilenames[] = {
|
|||
"timovr3"
|
||||
};
|
||||
|
||||
constexpr unsigned int MAX_SWITCH_POSITIONS =
|
||||
MAX_SWITCHES * 3 + MAX_POTS * XPOTS_MULTIPOS_COUNT;
|
||||
|
||||
BitField<(AU_SPECIAL_SOUND_FIRST)> sdAvailableSystemAudioFiles;
|
||||
BitField<(MAX_FLIGHT_MODES * 2/*on, off*/)> sdAvailableFlightmodeAudioFiles;
|
||||
BitField<(SWSRC_LAST_SWITCH+NUM_XPOTS*XPOTS_MULTIPOS_COUNT)> sdAvailableSwitchAudioFiles;
|
||||
BitField<MAX_SWITCH_POSITIONS> sdAvailableSwitchAudioFiles;
|
||||
BitField<(MAX_LOGICAL_SWITCHES * 2/*on, off*/)> sdAvailableLogicalSwitchAudioFiles;
|
||||
|
||||
char * getAudioPath(char * path)
|
||||
|
@ -330,22 +335,21 @@ void getSwitchAudioFile(char * filename, swsrc_t index)
|
|||
{
|
||||
char * str = getModelAudioPath(filename);
|
||||
|
||||
if (index <= SWSRC_LAST_SWITCH) {
|
||||
if (index <= MAX_SWITCHES * 3) {
|
||||
div_t swinfo = switchInfo(index);
|
||||
*str++ = 'S';
|
||||
*str++ = getRawSwitchFromIdx(swinfo.quot);
|
||||
*str++ = switchGetLetter(swinfo.quot);
|
||||
const char * positions[] = { "-up", "-mid", "-down" };
|
||||
strcpy(str, positions[swinfo.rem]);
|
||||
}
|
||||
#if NUM_XPOTS > 0
|
||||
else {
|
||||
div_t swinfo = div(int(index - SWSRC_FIRST_MULTIPOS_SWITCH), XPOTS_MULTIPOS_COUNT);
|
||||
index -= MAX_SWITCHES * 3;
|
||||
div_t swinfo = div((int)index, XPOTS_MULTIPOS_COUNT);
|
||||
*str++ = 'S';
|
||||
*str++ = '1' + swinfo.quot;
|
||||
*str++ = '1' + swinfo.rem;
|
||||
*str = '\0';
|
||||
}
|
||||
#endif
|
||||
strcat(str, SOUNDS_EXT);
|
||||
}
|
||||
|
||||
|
@ -407,11 +411,11 @@ void referenceModelAudioFiles()
|
|||
}
|
||||
|
||||
// Switches Audio Files <switchname>-[up|mid|down].wav
|
||||
for (int i=SWSRC_FIRST_SWITCH; i<=SWSRC_LAST_SWITCH+NUM_XPOTS*XPOTS_MULTIPOS_COUNT && !found; i++) {
|
||||
for (unsigned i = 0; i <= MAX_SWITCH_POSITIONS && !found; i++) {
|
||||
getSwitchAudioFile(path, i);
|
||||
// TRACE("referenceModelAudioFiles(): searching for %s in %s (%d)", path, fno.fname, i);
|
||||
if (!strcasecmp(filename, fno.fname)) {
|
||||
sdAvailableSwitchAudioFiles.setBit(i-SWSRC_FIRST_SWITCH);
|
||||
sdAvailableSwitchAudioFiles.setBit(i);
|
||||
found = true;
|
||||
TRACE("\tfound: %s", filename);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,10 @@
|
|||
Implements a bit field, number of bits is set by the template,
|
||||
each bit can be modified and read by the provided methods.
|
||||
*/
|
||||
template <unsigned int NUM_BITS> class BitField {
|
||||
template <unsigned int NUM_BITS> class BitField
|
||||
{
|
||||
private:
|
||||
uint8_t bits[(NUM_BITS+7)/8];
|
||||
uint8_t bits[(NUM_BITS + 7) / 8];
|
||||
public:
|
||||
BitField()
|
||||
{
|
||||
|
@ -54,7 +55,6 @@ template <unsigned int NUM_BITS> class BitField {
|
|||
|
||||
bool getBit(unsigned int bitNo) const
|
||||
{
|
||||
// assert(bitNo < NUM_BITS);
|
||||
if (bitNo >= NUM_BITS) return false;
|
||||
return bits[bitNo >> 3] & (1 << (bitNo & 0x07));
|
||||
}
|
||||
|
|
40
radio/src/boards/generic_stm32/CMakeLists.txt
Normal file
40
radio/src/boards/generic_stm32/CMakeLists.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
# Generate hardware struct defs
|
||||
AddHWGenTarget(${HW_DESC_JSON} stm32_keys stm32_keys.inc)
|
||||
AddHWGenTarget(${HW_DESC_JSON} stm32_switches stm32_switches.inc)
|
||||
AddHWGenTarget(${HW_DESC_JSON} stm32_adc_inputs stm32_adc_inputs.inc)
|
||||
AddHWGenTarget(${HW_DESC_JSON} hal_adc_inputs hal_adc_inputs.inc)
|
||||
|
||||
# Dependencies common to bootloader and firmware
|
||||
set(MINIMAL_BOARD_LIB_SRC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${HW_DESC_JSON}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/stm32_keys.inc
|
||||
|
||||
boards/generic_stm32/inputs.cpp
|
||||
)
|
||||
|
||||
# Dependencies only used in firmware
|
||||
set(BOARD_LIB_SRC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/stm32_switches.inc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/stm32_adc_inputs.inc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/hal_adc_inputs.inc
|
||||
|
||||
boards/generic_stm32/module_ports.cpp
|
||||
boards/generic_stm32/aux_ports.cpp
|
||||
boards/generic_stm32/sport_update.cpp
|
||||
boards/generic_stm32/intmodule_heartbeat.cpp
|
||||
boards/generic_stm32/analog_inputs.cpp
|
||||
boards/generic_stm32/switches.cpp
|
||||
)
|
||||
|
||||
add_library(minimal_board_lib OBJECT EXCLUDE_FROM_ALL ${MINIMAL_BOARD_LIB_SRC})
|
||||
add_library(board_lib OBJECT EXCLUDE_FROM_ALL ${BOARD_LIB_SRC})
|
||||
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC}
|
||||
$<TARGET_OBJECTS:minimal_board_lib>
|
||||
$<TARGET_OBJECTS:board_lib>
|
||||
)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
$<TARGET_OBJECTS:minimal_board_lib>
|
||||
)
|
85
radio/src/boards/generic_stm32/analog_inputs.cpp
Normal file
85
radio/src/boards/generic_stm32/analog_inputs.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTx
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "analog_inputs.h"
|
||||
#include "stm32_adc.h"
|
||||
#include "stm32_spi_adc.h"
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if defined(ADC_SPI)
|
||||
#include "ads79xx.h"
|
||||
#endif
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
#include "myeeprom.h"
|
||||
#include "translations.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// generated files
|
||||
#include "stm32_adc_inputs.inc"
|
||||
#include "hal_adc_inputs.inc"
|
||||
|
||||
constexpr uint8_t n_ADC = DIM(_ADC_adc);
|
||||
constexpr uint8_t n_ADC_spi = DIM(_ADC_spi);
|
||||
constexpr uint8_t n_GPIO = DIM(_ADC_GPIOs);
|
||||
constexpr uint8_t n_inputs = DIM(_ADC_inputs);
|
||||
|
||||
static bool adc_init()
|
||||
{
|
||||
bool success = stm32_hal_adc_init(_ADC_adc, n_ADC, _ADC_inputs, _ADC_GPIOs, n_GPIO);
|
||||
#if defined(ADC_SPI)
|
||||
if (n_ADC_spi > 0) ads79xx_init(&_ADC_spi[0]);
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool adc_start_read()
|
||||
{
|
||||
bool success = stm32_hal_adc_start_read(_ADC_adc, n_ADC, _ADC_inputs, n_inputs);
|
||||
#if defined(ADC_SPI)
|
||||
if (n_ADC_spi > 0) {
|
||||
success = success && ads79xx_adc_start_read(&_ADC_spi[0], _ADC_inputs);
|
||||
}
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
static void adc_wait_completion()
|
||||
{
|
||||
#if defined(ADC_SPI)
|
||||
// ADS79xx does all the work in the completion function
|
||||
// so it's probably better to poll it first
|
||||
if (n_ADC_spi > 0) ads79xx_adc_wait_completion(&_ADC_spi[0], _ADC_inputs);
|
||||
#endif
|
||||
stm32_hal_adc_wait_completion(_ADC_adc, n_ADC, _ADC_inputs, n_inputs);
|
||||
}
|
||||
|
||||
const etx_hal_adc_driver_t _adc_driver = {
|
||||
_hal_inputs,
|
||||
_pot_default_config,
|
||||
adc_init,
|
||||
adc_start_read,
|
||||
adc_wait_completion
|
||||
};
|
||||
|
24
radio/src/boards/generic_stm32/analog_inputs.h
Normal file
24
radio/src/boards/generic_stm32/analog_inputs.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/adc_driver.h"
|
||||
|
||||
extern const etx_hal_adc_driver_t _adc_driver;
|
48
radio/src/boards/generic_stm32/inputs.cpp
Normal file
48
radio/src/boards/generic_stm32/inputs.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTx
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/key_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
#include "stm32_keys.inc"
|
||||
|
||||
void keysInit()
|
||||
{
|
||||
_init_keys();
|
||||
_init_trims();
|
||||
}
|
||||
|
||||
uint32_t readKeys()
|
||||
{
|
||||
return _read_keys();
|
||||
}
|
||||
|
||||
uint32_t readTrims()
|
||||
{
|
||||
uint32_t trims = _read_trims();
|
||||
#if defined(PCBXLITE)
|
||||
if (_read_keys() & (1 << KEY_SHIFT))
|
||||
return ((trims & 0x03) << 6) | ((trims & 0x0c) << 2);
|
||||
#endif
|
||||
return trims;
|
||||
}
|
|
@ -64,13 +64,54 @@ DEFINE_STM32_SERIAL_PORT(InternalModule, intmoduleUSART, INTMODULE_FIFO_SIZE, 0)
|
|||
#include "stm32_pulse_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
extern const stm32_pulse_timer_t intmoduleTimer;
|
||||
static stm32_pulse_dma_tc_cb_t _int_timer_DMA_TC_Callback;
|
||||
|
||||
static const stm32_pulse_timer_t intmoduleTimer = {
|
||||
.GPIOx = INTMODULE_TX_GPIO,
|
||||
.GPIO_Pin = INTMODULE_TX_GPIO_PIN,
|
||||
.GPIO_Alternate = INTMODULE_TX_GPIO_AF,
|
||||
.TIMx = INTMODULE_TIMER,
|
||||
.TIM_Freq = INTMODULE_TIMER_FREQ,
|
||||
.TIM_Channel = INTMODULE_TIMER_Channel,
|
||||
.TIM_IRQn = INTMODULE_TIMER_IRQn,
|
||||
.DMAx = INTMODULE_TIMER_DMA,
|
||||
.DMA_Stream = INTMODULE_TIMER_DMA_STREAM,
|
||||
.DMA_Channel = INTMODULE_TIMER_DMA_CHANNEL,
|
||||
.DMA_IRQn = INTMODULE_TIMER_DMA_STREAM_IRQn,
|
||||
.DMA_TC_CallbackPtr = &_int_timer_DMA_TC_Callback,
|
||||
};
|
||||
|
||||
// Make sure the timer channel is supported
|
||||
static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(INTMODULE_TIMER_Channel),
|
||||
"Unsupported timer channel");
|
||||
|
||||
// Make sure the DMA channel is supported
|
||||
static_assert(__STM32_PULSE_IS_DMA_STREAM_SUPPORTED(INTMODULE_TIMER_DMA_STREAM),
|
||||
"Unsupported DMA stream");
|
||||
|
||||
#if !defined(INTMODULE_TIMER_DMA_IRQHandler)
|
||||
#error "Missing INTMODULE_TIMER_DMA_IRQHandler definition"
|
||||
#endif
|
||||
|
||||
extern "C" void INTMODULE_TIMER_DMA_IRQHandler()
|
||||
{
|
||||
stm32_pulse_dma_tc_isr(&intmoduleTimer);
|
||||
}
|
||||
|
||||
#if !defined(INTMODULE_TIMER_IRQHandler)
|
||||
#error "Missing INTMODULE_TIMER_IRQHandler definition"
|
||||
#endif
|
||||
|
||||
extern "C" void INTMODULE_TIMER_IRQHandler()
|
||||
{
|
||||
stm32_pulse_tim_update_isr(&intmoduleTimer);
|
||||
}
|
||||
|
||||
DEFINE_STM32_SOFTSERIAL_PORT(InternalModule, intmoduleTimer);
|
||||
|
||||
#endif
|
||||
|
||||
#include "module_timer_driver.h"
|
||||
#include "extmodule_driver.h"
|
||||
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
#if defined(EXTMODULE_USART)
|
||||
|
@ -135,6 +176,49 @@ DEFINE_STM32_SERIAL_PORT(ExternalModule, extmoduleUSART, INTMODULE_FIFO_SIZE, 0)
|
|||
|
||||
#endif
|
||||
|
||||
static stm32_pulse_dma_tc_cb_t _ext_timer_DMA_TC_Callback;
|
||||
|
||||
static const stm32_pulse_timer_t extmoduleTimer = {
|
||||
.GPIOx = EXTMODULE_TX_GPIO,
|
||||
.GPIO_Pin = EXTMODULE_TX_GPIO_PIN,
|
||||
.GPIO_Alternate = EXTMODULE_TIMER_TX_GPIO_AF,
|
||||
.TIMx = EXTMODULE_TIMER,
|
||||
.TIM_Freq = EXTMODULE_TIMER_FREQ,
|
||||
.TIM_Channel = EXTMODULE_TIMER_Channel,
|
||||
.TIM_IRQn = EXTMODULE_TIMER_IRQn,
|
||||
.DMAx = EXTMODULE_TIMER_DMA,
|
||||
.DMA_Stream = EXTMODULE_TIMER_DMA_STREAM_LL,
|
||||
.DMA_Channel = EXTMODULE_TIMER_DMA_CHANNEL,
|
||||
.DMA_IRQn = EXTMODULE_TIMER_DMA_STREAM_IRQn,
|
||||
.DMA_TC_CallbackPtr = &_ext_timer_DMA_TC_Callback,
|
||||
};
|
||||
|
||||
// Make sure the timer channel is supported
|
||||
static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(EXTMODULE_TIMER_Channel),
|
||||
"Unsupported timer channel");
|
||||
|
||||
// Make sure the DMA channel is supported
|
||||
static_assert(__STM32_PULSE_IS_DMA_STREAM_SUPPORTED(EXTMODULE_TIMER_DMA_STREAM_LL),
|
||||
"Unsupported DMA stream");
|
||||
|
||||
#if !defined(EXTMODULE_TIMER_DMA_IRQHandler)
|
||||
#error "Missing EXTMODULE_TIMER_DMA_IRQHandler definition"
|
||||
#endif
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_DMA_IRQHandler()
|
||||
{
|
||||
stm32_pulse_dma_tc_isr(&extmoduleTimer);
|
||||
}
|
||||
|
||||
#if !defined(EXTMODULE_TIMER_IRQHandler)
|
||||
#error "Missing EXTMODULE_TIMER_IRQHandler definition"
|
||||
#endif
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_IRQHandler()
|
||||
{
|
||||
stm32_pulse_tim_update_isr(&extmoduleTimer);
|
||||
}
|
||||
|
||||
DEFINE_STM32_SOFTSERIAL_PORT(ExternalModule, extmoduleTimer);
|
||||
#endif
|
||||
|
||||
|
|
110
radio/src/boards/generic_stm32/switches.cpp
Normal file
110
radio/src/boards/generic_stm32/switches.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/switch_driver.h"
|
||||
#include "stm32_switch_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
#include "definitions.h"
|
||||
#include "opentx_constants.h"
|
||||
#include "myeeprom.h"
|
||||
|
||||
// generated switch structs
|
||||
#include "stm32_switches.inc"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void switchInit()
|
||||
{
|
||||
_init_switches();
|
||||
}
|
||||
|
||||
swconfig_t switchGetDefaultConfig()
|
||||
{
|
||||
return _switch_default_config;
|
||||
}
|
||||
|
||||
switch_display_pos_t switchGetDisplayPosition(uint8_t idx)
|
||||
{
|
||||
if (idx >= DIM(_switch_display))
|
||||
return {0, 0};
|
||||
|
||||
return _switch_display[idx];
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxSwitches()
|
||||
{
|
||||
return n_switches;
|
||||
}
|
||||
|
||||
uint8_t getSwitchCount()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxRow(uint8_t col)
|
||||
{
|
||||
uint8_t lastrow = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.col == col)
|
||||
lastrow = switch_display.row > lastrow ? switch_display.row : lastrow;
|
||||
}
|
||||
}
|
||||
return lastrow;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxFctSwitches()
|
||||
{
|
||||
return n_fct_switches;
|
||||
}
|
||||
|
||||
// returns state (0 / 1) of a specific switch position
|
||||
uint32_t switchState(uint8_t pos_idx)
|
||||
{
|
||||
auto d = div(pos_idx, 3);
|
||||
return stm32_switch_get_state(&_switch_defs[d.quot], (SwitchHwPos)d.rem);
|
||||
}
|
||||
|
||||
SwitchHwPos switchGetPosition(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return SWITCH_HW_UP;
|
||||
return stm32_switch_get_position(&_switch_defs[idx]);
|
||||
}
|
||||
|
||||
const char* switchGetName(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return "";
|
||||
return _switch_defs[idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType switchGetHwType(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return SWITCH_HW_2POS;
|
||||
return _switch_defs[idx].type;
|
||||
}
|
|
@ -25,11 +25,13 @@
|
|||
#include "opentx.h"
|
||||
#include "diskio.h"
|
||||
#include "timers_driver.h"
|
||||
#include "watchdog_driver.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
#include "bluetooth_driver.h"
|
||||
#endif
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/module_port.h"
|
||||
|
||||
#include "tasks.h"
|
||||
|
@ -1254,6 +1256,9 @@ void printAudioVars()
|
|||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
int cliDisplay(const char ** argv)
|
||||
{
|
||||
long long int address = 0;
|
||||
|
@ -1266,32 +1271,32 @@ int cliDisplay(const char ** argv)
|
|||
}
|
||||
|
||||
if (!strcmp(argv[1], "keys")) {
|
||||
for (int i=0; i<TRM_BASE; i++) {
|
||||
cliSerialPrint("[%s] = %s", STR_VKEYS[i]+1, keys[i].state() ? "on" : "off");
|
||||
for (int i = 0; i <= MAX_KEYS; i++) {
|
||||
if (keysGetSupported() & (1 << i)) {
|
||||
cliSerialPrint("[Key %s] = %s",
|
||||
keysGetLabel((EnumKeys)i),
|
||||
keysGetState(i) ? "on" : "off");
|
||||
}
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
typedef int32_t rotenc_t;
|
||||
extern volatile rotenc_t rotencValue;
|
||||
cliSerialPrint("[Enc.] = %d", rotencValue / ROTARY_ENCODER_GRANULARITY);
|
||||
#endif
|
||||
for (int i=TRM_BASE; i<=TRM_LAST; i++) {
|
||||
cliSerialPrint("[Trim%d] = %s", i-TRM_BASE, keys[i].state() ? "on" : "off");
|
||||
}
|
||||
for (int i=MIXSRC_FIRST_SWITCH; i<=MIXSRC_LAST_SWITCH; i++) {
|
||||
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
|
||||
if (SWITCH_EXISTS(sw)) {
|
||||
static const char * const SWITCH_POSITIONS[] = { "down", "mid", "up" };
|
||||
cliSerialPrint("[%s] = %s", STR_VSWITCHES[sw]+1, SWITCH_POSITIONS[1 + getValue(i) / 1024]);
|
||||
for (int i = 0; i < keysGetMaxTrims(); i++) {
|
||||
cliSerialPrint("[Trim %s] = %s", getTrimLabel(i),
|
||||
keysGetTrimState(i) ? "on" : "off");
|
||||
}
|
||||
for (int i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
static const char * const SWITCH_POSITIONS[] = { "up", "mid", "down" };
|
||||
auto pos = switchGetPosition(i);
|
||||
cliSerialPrint("[%s] = %s", switchGetName(i), SWITCH_POSITIONS[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], "adc")) {
|
||||
for (int i=0; i<NUM_ANALOGS; i++) {
|
||||
cliSerialPrint("adc[%d] = %04X", i, (int)adcValues[i]);
|
||||
for (int i = 0; i < adcGetMaxInputs(ADC_INPUT_ALL); i++) {
|
||||
cliSerialPrint("adc[%d] = %04X", i, getAnalogValue(i));
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], "outputs")) {
|
||||
for (int i=0; i<MAX_OUTPUT_CHANNELS; i++) {
|
||||
for (int i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
|
||||
cliSerialPrint("outputs[%d] = %04d", i, (int)channelOutputs[i]);
|
||||
}
|
||||
}
|
||||
|
@ -1398,7 +1403,7 @@ int cliDebugVars(const char ** argv)
|
|||
cliSerialPrint("authenticateFrames=%d", authenticateFrames);
|
||||
#endif
|
||||
#elif defined(PCBTARANIS)
|
||||
cliSerialPrint("telemetryErrors=%d", telemetryErrors);
|
||||
//cliSerialPrint("telemetryErrors=%d", telemetryErrors);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -1436,11 +1441,13 @@ int cliRepeat(const char ** argv)
|
|||
int cliShowJitter(const char ** argv)
|
||||
{
|
||||
cliSerialPrint( "# anaIn rawJ avgJ");
|
||||
for (int i=0; i<NUM_ANALOGS; i++) {
|
||||
cliSerialPrint("A%02d %04X %04X %3d %3d", i, getAnalogValue(i), anaIn(i), rawJitter[i].get(), avgJitter[i].get());
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
|
||||
for (int j=0; j<calib->count; j++) {
|
||||
for (int i = 0; i < MAX_ANALOG_INPUTS; i++) {
|
||||
cliSerialPrint("A%02d %04X %04X %3d %3d", i, getAnalogValue(i), anaIn(i),
|
||||
rawJitter[i].get(), avgJitter[i].get());
|
||||
|
||||
if (i >= MAX_STICKS && IS_POT_MULTIPOS(i - MAX_STICKS)) {
|
||||
StepsCalibData *calib = (StepsCalibData *)&g_eeGeneral.calib[i];
|
||||
for (int j = 0; j < calib->count; j++) {
|
||||
cliSerialPrint(" s%d %04X", j, calib->steps[j]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "board.h"
|
||||
#include "storage/yaml/yaml_defs.h"
|
||||
|
||||
#define NUM_STICKS 4
|
||||
|
||||
#if defined(EXPORT)
|
||||
#define LUA_EXPORT(...) LEXP(__VA_ARGS__)
|
||||
|
@ -136,12 +135,7 @@ enum CurveType {
|
|||
#define MAX_CURVE_POINTS 512
|
||||
#endif
|
||||
|
||||
// TODO: remove this
|
||||
#if defined(PCBFRSKY) || defined(PCBNV14)
|
||||
#define NUM_MODULES 2
|
||||
#else
|
||||
#define NUM_MODULES 1
|
||||
#endif
|
||||
#define NUM_MODULES 2
|
||||
|
||||
#define XPOTS_MULTIPOS_COUNT 6
|
||||
|
||||
|
@ -315,11 +309,6 @@ enum TelemetryUnit {
|
|||
UNIT_KM,
|
||||
UNIT_DBM,
|
||||
UNIT_MAX = UNIT_DBM,
|
||||
UNIT_SPARE6,
|
||||
UNIT_SPARE7,
|
||||
UNIT_SPARE8,
|
||||
UNIT_SPARE9,
|
||||
UNIT_SPARE10,
|
||||
UNIT_HOURS,
|
||||
UNIT_MINUTES,
|
||||
UNIT_SECONDS,
|
||||
|
@ -339,6 +328,7 @@ enum TelemetryUnit {
|
|||
UNIT_DATETIME_SEC
|
||||
};
|
||||
|
||||
// TODO: move to stdlcd UI
|
||||
#if LCD_W >= 212
|
||||
#define NUM_LINE_ITEMS 3
|
||||
#else
|
||||
|
@ -360,9 +350,14 @@ enum TelemetryScreenType {
|
|||
TELEMETRY_SCREEN_TYPE_MAX = TELEMETRY_SCREEN_TYPE_BARS
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MAX_TELEMETRY_SCREENS 4
|
||||
#define TELEMETRY_SCREEN_TYPE(screenIndex) TelemetryScreenType((g_model.screensType >> (2*(screenIndex))) & 0x03)
|
||||
#define IS_BARS_SCREEN(screenIndex) (TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_BARS)
|
||||
|
||||
#define TELEMETRY_SCREEN_TYPE(screenIndex) \
|
||||
TelemetryScreenType((g_model.screensType >> (2 * (screenIndex))) & 0x03)
|
||||
|
||||
#define IS_BARS_SCREEN(screenIndex) \
|
||||
(TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_BARS)
|
||||
|
||||
constexpr int16_t FAILSAFE_CHANNEL_HOLD = 2000;
|
||||
constexpr int16_t FAILSAFE_CHANNEL_NOPULSE = 2001;
|
||||
|
@ -382,161 +377,47 @@ enum PotsWarnMode {
|
|||
#define GVAR_MAX 1024
|
||||
#define GVAR_MIN -GVAR_MAX
|
||||
|
||||
// we reserve the space inside the range of values, like offset, weight, etc.
|
||||
#define RESERVE_RANGE_FOR_GVARS 10
|
||||
// even we do not spend space in EEPROM for 10 GVARS, we reserve the space inside the range of values, like offset, weight, etc.
|
||||
|
||||
#define MAX_GVARS 9
|
||||
|
||||
// Maximum number analog inputs by type
|
||||
#define MAX_STICKS 4
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#define MAX_POTS 16
|
||||
#define MAX_AXIS 2
|
||||
#else
|
||||
#define MAX_POTS 8
|
||||
#define MAX_AXIS 0
|
||||
#endif
|
||||
|
||||
#define MAX_VBAT 1
|
||||
#define MAX_RTC_BAT 1
|
||||
|
||||
#define MAX_ANALOG_INPUTS (MAX_STICKS + MAX_POTS + MAX_AXIS + MAX_VBAT + MAX_RTC_BAT)
|
||||
#define MAX_CALIB_ANALOG_INPUTS (MAX_STICKS + MAX_POTS + MAX_AXIS)
|
||||
|
||||
#define MAX_SWITCHES 20
|
||||
#define MAX_TRIMS 6
|
||||
|
||||
#define MAX_XPOTS_POSITIONS (MAX_POTS * XPOTS_MULTIPOS_COUNT)
|
||||
|
||||
enum SwitchSources {
|
||||
SWSRC_NONE = 0,
|
||||
|
||||
SWSRC_FIRST_SWITCH SKIP,
|
||||
SWSRC_LAST_SWITCH SKIP = SWSRC_FIRST_SWITCH + (MAX_SWITCHES * 3) - 1,
|
||||
|
||||
#if defined(STORAGE_SWITCH_A)
|
||||
SWSRC_SA0 = SWSRC_FIRST_SWITCH,
|
||||
SWSRC_SA1,
|
||||
SWSRC_SA2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_B)
|
||||
SWSRC_SB0,
|
||||
SWSRC_SB1,
|
||||
SWSRC_SB2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_C)
|
||||
SWSRC_SC0,
|
||||
SWSRC_SC1,
|
||||
SWSRC_SC2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_D)
|
||||
SWSRC_SD0,
|
||||
SWSRC_SD1,
|
||||
SWSRC_SD2,
|
||||
#endif
|
||||
|
||||
#if defined(FUNCTION_SWITCHES) && defined(RADIO_TPRO)
|
||||
SWSRC_FIRST_FUNCTION_SWITCH SKIP,
|
||||
SWSRC_SE0 = SWSRC_FIRST_FUNCTION_SWITCH,
|
||||
SWSRC_SE1,
|
||||
SWSRC_SE2,
|
||||
#elif defined(STORAGE_SWITCH_E)
|
||||
SWSRC_SE0,
|
||||
SWSRC_SE1,
|
||||
SWSRC_SE2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_F)
|
||||
SWSRC_SF0,
|
||||
SWSRC_SF1,
|
||||
SWSRC_SF2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_G)
|
||||
SWSRC_SG0,
|
||||
SWSRC_SG1,
|
||||
SWSRC_SG2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_H)
|
||||
SWSRC_SH0,
|
||||
SWSRC_SH1,
|
||||
SWSRC_SH2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_I)
|
||||
SWSRC_SI0,
|
||||
SWSRC_SI1,
|
||||
SWSRC_SI2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_J)
|
||||
SWSRC_SJ0,
|
||||
SWSRC_SJ1,
|
||||
SWSRC_SJ2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_K)
|
||||
SWSRC_SK0,
|
||||
SWSRC_SK1,
|
||||
SWSRC_SK2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_L)
|
||||
SWSRC_SL0,
|
||||
SWSRC_SL1,
|
||||
SWSRC_SL2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_M)
|
||||
SWSRC_SM0,
|
||||
SWSRC_SM1,
|
||||
SWSRC_SM2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_N)
|
||||
SWSRC_SN0,
|
||||
SWSRC_SN1,
|
||||
SWSRC_SN2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_O)
|
||||
SWSRC_SO0,
|
||||
SWSRC_SO1,
|
||||
SWSRC_SO2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_P)
|
||||
SWSRC_SP0,
|
||||
SWSRC_SP1,
|
||||
SWSRC_SP2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_Q)
|
||||
SWSRC_SQ0,
|
||||
SWSRC_SQ1,
|
||||
SWSRC_SQ2,
|
||||
#endif
|
||||
|
||||
#if defined(STORAGE_SWITCH_R)
|
||||
SWSRC_SR0,
|
||||
SWSRC_SR1,
|
||||
SWSRC_SR2,
|
||||
#endif
|
||||
|
||||
SWSRC_LAST_SWITCH SKIP = SWSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES_POSITIONS - 1,
|
||||
|
||||
#if NUM_XPOTS > 0
|
||||
SWSRC_FIRST_MULTIPOS_SWITCH SKIP,
|
||||
SWSRC_LAST_MULTIPOS_SWITCH SKIP = SWSRC_FIRST_MULTIPOS_SWITCH + (NUM_XPOTS * XPOTS_MULTIPOS_COUNT) - 1,
|
||||
#endif
|
||||
SWSRC_LAST_MULTIPOS_SWITCH SKIP = SWSRC_FIRST_MULTIPOS_SWITCH + MAX_XPOTS_POSITIONS - 1,
|
||||
|
||||
SWSRC_FIRST_TRIM SKIP,
|
||||
SWSRC_TrimRudLeft = SWSRC_FIRST_TRIM,
|
||||
SWSRC_TrimRudRight,
|
||||
SWSRC_TrimEleDown,
|
||||
SWSRC_TrimEleUp,
|
||||
|
||||
#if NUM_TRIMS > 2
|
||||
SWSRC_TrimThrDown,
|
||||
SWSRC_TrimThrUp,
|
||||
SWSRC_TrimAilLeft,
|
||||
SWSRC_TrimAilRight,
|
||||
#endif
|
||||
|
||||
#if NUM_TRIMS > 4
|
||||
SWSRC_TrimT5Down,
|
||||
SWSRC_TrimT5Up,
|
||||
SWSRC_TrimT6Down,
|
||||
SWSRC_TrimT6Up,
|
||||
#endif
|
||||
SWSRC_LAST_TRIM SKIP = SWSRC_FIRST_TRIM + 2 * MAX_TRIMS - 1,
|
||||
|
||||
SWSRC_FIRST_LOGICAL_SWITCH SKIP,
|
||||
SWSRC_SW1 = SWSRC_FIRST_LOGICAL_SWITCH,
|
||||
SWSRC_SW2,
|
||||
// ...
|
||||
SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH+MAX_LOGICAL_SWITCHES-1,
|
||||
SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1,
|
||||
|
||||
SWSRC_ON,
|
||||
SWSRC_ONE,
|
||||
|
@ -571,247 +452,100 @@ enum SwitchSources {
|
|||
SWSRC_INVERT SKIP = SWSRC_COUNT+1,
|
||||
};
|
||||
|
||||
#if NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES >= 8
|
||||
#define SWSRC_TRAINER SWSRC_SH2
|
||||
#else
|
||||
#define SWSRC_TRAINER SWSRC_LAST_SWITCH,
|
||||
#endif
|
||||
|
||||
#define SWSRC_LAST_TRIM (SWSRC_FIRST_TRIM + 2 * NUM_TRIMS - 1)
|
||||
|
||||
enum MixSources {
|
||||
MIXSRC_NONE,
|
||||
|
||||
MIXSRC_FIRST_INPUT SKIP, LUA_EXPORT_MULTIPLE("input", "Input [I%d]", MAX_INPUTS)
|
||||
MIXSRC_LAST_INPUT SKIP = MIXSRC_FIRST_INPUT+MAX_INPUTS-1,
|
||||
MIXSRC_FIRST SKIP,
|
||||
MIXSRC_FIRST_INPUT SKIP = MIXSRC_FIRST,
|
||||
MIXSRC_LAST_INPUT SKIP = MIXSRC_FIRST_INPUT + MAX_INPUTS - 1,
|
||||
|
||||
#if defined(LUA_INPUTS)
|
||||
MIXSRC_FIRST_LUA SKIP, LUA_EXPORT_MULTIPLE("lua", "Lua mix output %d", MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)
|
||||
MIXSRC_LAST_LUA SKIP = MIXSRC_FIRST_LUA+(MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)-1,
|
||||
MIXSRC_FIRST_LUA SKIP,
|
||||
MIXSRC_LAST_LUA SKIP = MIXSRC_FIRST_LUA + (MAX_SCRIPTS * MAX_SCRIPT_OUTPUTS) - 1,
|
||||
#endif
|
||||
|
||||
// Semantic sticks
|
||||
MIXSRC_FIRST_STICK SKIP,
|
||||
MIXSRC_Rud = MIXSRC_FIRST_STICK, LUA_EXPORT("rud", "Rudder")
|
||||
MIXSRC_Ele, LUA_EXPORT("ele", "Elevator")
|
||||
MIXSRC_Thr, LUA_EXPORT("thr", "Throttle")
|
||||
MIXSRC_Ail, LUA_EXPORT("ail", "Aileron")
|
||||
MIXSRC_LAST_STICK SKIP = MIXSRC_FIRST_STICK + MAX_STICKS - 1,
|
||||
|
||||
MIXSRC_LAST_STICK SKIP = MIXSRC_Ail,
|
||||
MIXSRC_FIRST_POT SKIP,
|
||||
#if defined(PCBHORUS)
|
||||
MIXSRC_S1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer S1")
|
||||
MIXSRC_6POS, LUA_EXPORT("6pos", "Multipos Switch")
|
||||
MIXSRC_S2, LUA_EXPORT("s2", "Potentiometer S2")
|
||||
#if defined(PCBX10)
|
||||
MIXSRC_EXT1, LUA_EXPORT("ext1", "Ext 1")
|
||||
MIXSRC_EXT2, LUA_EXPORT("ext2", "Ext 2")
|
||||
MIXSRC_EXT3, LUA_EXPORT("ext3", "Ext 3")
|
||||
MIXSRC_EXT4, LUA_EXPORT("ext4", "Ext 4")
|
||||
#endif
|
||||
MIXSRC_FIRST_SLIDER SKIP,
|
||||
#if defined(PCBX12S)
|
||||
MIXSRC_S3 = MIXSRC_FIRST_SLIDER, LUA_EXPORT("s3", "Slider S3")
|
||||
MIXSRC_S4, LUA_EXPORT("s4", "Slider S4")
|
||||
MIXSRC_LS, LUA_EXPORT("ls", "Left rear slider")
|
||||
MIXSRC_RS, LUA_EXPORT("rs", "Right rear slider")
|
||||
#else
|
||||
MIXSRC_LS = MIXSRC_FIRST_SLIDER, LUA_EXPORT("ls", "Left slider")
|
||||
MIXSRC_RS, LUA_EXPORT("rs", "Right slider")
|
||||
#endif
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_RS,
|
||||
#elif defined(PCBX9E)
|
||||
MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1")
|
||||
MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2")
|
||||
MIXSRC_POT3, LUA_EXPORT("s3", "Potentiometer 3")
|
||||
MIXSRC_POT4, LUA_EXPORT("s4", "Potentiometer 4 (X9E only)")
|
||||
MIXSRC_FIRST_SLIDER SKIP,
|
||||
MIXSRC_SLIDER1 = MIXSRC_FIRST_SLIDER, LUA_EXPORT("ls", "Left slider")
|
||||
MIXSRC_SLIDER2, LUA_EXPORT("rs", "Right slider")
|
||||
MIXSRC_SLIDER3, LUA_EXPORT("lcs", "Left center slider (X9E only)")
|
||||
MIXSRC_SLIDER4, LUA_EXPORT("rcs", "Right center slider (X9E only)")
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_SLIDER4,
|
||||
#elif defined(RADIO_BOXER)
|
||||
MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1")
|
||||
MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2")
|
||||
MIXSRC_POT3, LUA_EXPORT("s3", "6 POS")
|
||||
MIXSRC_FIRST_SLIDER SKIP = MIXSRC_POT3,
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_POT3,
|
||||
#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBNV14)
|
||||
MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1")
|
||||
MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2")
|
||||
MIXSRC_FIRST_SLIDER SKIP = MIXSRC_POT2,
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_POT2,
|
||||
#elif defined(PCBX9LITE)
|
||||
MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1")
|
||||
MIXSRC_FIRST_SLIDER SKIP = MIXSRC_POT1,
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_POT1,
|
||||
#elif defined(PCBTARANIS)
|
||||
MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1")
|
||||
MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2")
|
||||
MIXSRC_POT3, LUA_EXPORT("s3", "Potentiometer 3")
|
||||
MIXSRC_FIRST_SLIDER SKIP,
|
||||
MIXSRC_SLIDER1 = MIXSRC_FIRST_SLIDER, LUA_EXPORT("ls", "Left slider")
|
||||
MIXSRC_SLIDER2, LUA_EXPORT("rs", "Right slider")
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_SLIDER2,
|
||||
#else
|
||||
MIXSRC_P1 = MIXSRC_FIRST_POT,
|
||||
MIXSRC_P2,
|
||||
MIXSRC_P3,
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_P3,
|
||||
#endif
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_FIRST_POT + MAX_POTS - 1,
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
MIXSRC_MOUSE1, LUA_EXPORT("jsx", "Joystick X")
|
||||
MIXSRC_MOUSE2, LUA_EXPORT("jsy", "Joystick Y")
|
||||
#if MAX_AXIS > 0
|
||||
MIXSRC_FIRST_AXIS SKIP,
|
||||
MIXSRC_LAST_AXIS SKIP = MIXSRC_FIRST_AXIS + MAX_AXIS - 1,
|
||||
#endif
|
||||
|
||||
#if defined(IMU)
|
||||
MIXSRC_TILT_X, LUA_EXPORT("tiltx", "Tilt X")
|
||||
MIXSRC_TILT_Y, LUA_EXPORT("tilty", "Tilt Y")
|
||||
MIXSRC_TILT_X,
|
||||
MIXSRC_TILT_Y,
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
MIXSRC_FIRST_SPACEMOUSE SKIP,
|
||||
MIXSRC_SPACEMOUSE_A = MIXSRC_FIRST_SPACEMOUSE, LUA_EXPORT("sma", "SpaceMouse A")
|
||||
MIXSRC_SPACEMOUSE_B, LUA_EXPORT("smb", "SpaceMouse B")
|
||||
MIXSRC_SPACEMOUSE_C, LUA_EXPORT("smc", "SpaceMouse C")
|
||||
MIXSRC_SPACEMOUSE_D, LUA_EXPORT("smd", "SpaceMouse D")
|
||||
MIXSRC_SPACEMOUSE_E, LUA_EXPORT("sme", "SpaceMouse E")
|
||||
MIXSRC_SPACEMOUSE_F, LUA_EXPORT("smf", "SpaceMouse F")
|
||||
MIXSRC_SPACEMOUSE_A = MIXSRC_FIRST_SPACEMOUSE,
|
||||
MIXSRC_SPACEMOUSE_B,
|
||||
MIXSRC_SPACEMOUSE_C,
|
||||
MIXSRC_SPACEMOUSE_D,
|
||||
MIXSRC_SPACEMOUSE_E,
|
||||
MIXSRC_SPACEMOUSE_F,
|
||||
MIXSRC_LAST_SPACEMOUSE SKIP = MIXSRC_SPACEMOUSE_F,
|
||||
#endif
|
||||
|
||||
MIXSRC_MAX, LUA_EXPORT("max", "MAX")
|
||||
MIXSRC_MAX,
|
||||
|
||||
MIXSRC_FIRST_HELI SKIP,
|
||||
MIXSRC_CYC1 = MIXSRC_FIRST_HELI, LUA_EXPORT("cyc1", "Cyclic 1")
|
||||
MIXSRC_CYC2, LUA_EXPORT("cyc2", "Cyclic 2")
|
||||
MIXSRC_CYC3, LUA_EXPORT("cyc3", "Cyclic 3")
|
||||
MIXSRC_LAST_HELI SKIP = MIXSRC_CYC3,
|
||||
MIXSRC_LAST_HELI SKIP = MIXSRC_FIRST_HELI + 2,
|
||||
|
||||
MIXSRC_FIRST_TRIM SKIP,
|
||||
MIXSRC_TrimRud = MIXSRC_FIRST_TRIM, LUA_EXPORT("trim-rud", "Rudder trim")
|
||||
MIXSRC_TrimEle, LUA_EXPORT("trim-ele", "Elevator trim")
|
||||
MIXSRC_TrimThr, LUA_EXPORT("trim-thr", "Throttle trim")
|
||||
MIXSRC_TrimAil, LUA_EXPORT("trim-ail", "Aileron trim")
|
||||
#if defined(PCBHORUS)
|
||||
MIXSRC_TrimT5, LUA_EXPORT("trim-t5", "Aux trim T5")
|
||||
MIXSRC_TrimT6, LUA_EXPORT("trim-t6", "Aux trim T6")
|
||||
MIXSRC_TrimRud = MIXSRC_FIRST_TRIM,
|
||||
MIXSRC_TrimEle,
|
||||
MIXSRC_TrimThr,
|
||||
MIXSRC_TrimAil,
|
||||
//#if defined(PCBHORUS)
|
||||
MIXSRC_TrimT5,
|
||||
MIXSRC_TrimT6,
|
||||
MIXSRC_LAST_TRIM SKIP = MIXSRC_TrimT6,
|
||||
#else
|
||||
MIXSRC_LAST_TRIM SKIP = MIXSRC_TrimAil,
|
||||
#endif
|
||||
//#else
|
||||
//MIXSRC_LAST_TRIM SKIP = MIXSRC_TrimAil,
|
||||
//#endif
|
||||
|
||||
MIXSRC_FIRST_SWITCH SKIP,
|
||||
MIXSRC_LAST_SWITCH SKIP = MIXSRC_FIRST_SWITCH + MAX_SWITCHES - 1,
|
||||
|
||||
#if defined(HARDWARE_SWITCH_A)
|
||||
MIXSRC_SA = MIXSRC_FIRST_SWITCH, LUA_EXPORT("sa", "Switch A")
|
||||
MIXSRC_SB, LUA_EXPORT("sb", "Switch B")
|
||||
MIXSRC_SC, LUA_EXPORT("sc", "Switch C")
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_D)
|
||||
MIXSRC_SD, LUA_EXPORT("sd", "Switch D")
|
||||
#elif defined(STORAGE_SWITCH_D)
|
||||
MIXSRC_SD,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_E)
|
||||
MIXSRC_SE, LUA_EXPORT("se", "Switch E")
|
||||
#elif defined(STORAGE_SWITCH_E)
|
||||
MIXSRC_SE,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_F)
|
||||
MIXSRC_SF, LUA_EXPORT("sf", "Switch F")
|
||||
#elif defined(STORAGE_SWITCH_F)
|
||||
MIXSRC_SF,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_G)
|
||||
MIXSRC_SG, LUA_EXPORT("sg", "Switch G")
|
||||
#elif defined(STORAGE_SWITCH_G)
|
||||
MIXSRC_SG,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_H)
|
||||
MIXSRC_SH, LUA_EXPORT("sh", "Switch H")
|
||||
#elif defined(STORAGE_SWITCH_H)
|
||||
MIXSRC_SH,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_I)
|
||||
MIXSRC_SI, LUA_EXPORT("si", "Switch I")
|
||||
#elif defined(STORAGE_SWITCH_I)
|
||||
MIXSRC_SI,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_J)
|
||||
MIXSRC_SJ, LUA_EXPORT("sj", "Switch J")
|
||||
#elif defined(STORAGE_SWITCH_J)
|
||||
MIXSRC_SJ,
|
||||
#endif
|
||||
#if defined(HARDWARE_SWITCH_K)
|
||||
MIXSRC_SK, LUA_EXPORT("sk", "Switch K")
|
||||
MIXSRC_SL, LUA_EXPORT("sl", "Switch L")
|
||||
MIXSRC_SM, LUA_EXPORT("sm", "Switch M")
|
||||
MIXSRC_SN, LUA_EXPORT("sn", "Switch N")
|
||||
MIXSRC_SO, LUA_EXPORT("so", "Switch O")
|
||||
MIXSRC_SP, LUA_EXPORT("sp", "Switch P")
|
||||
MIXSRC_SQ, LUA_EXPORT("sq", "Switch Q")
|
||||
MIXSRC_SR, LUA_EXPORT("sr", "Switch R")
|
||||
#endif
|
||||
MIXSRC_FIRST_LOGICAL_SWITCH SKIP,
|
||||
MIXSRC_SW1 = MIXSRC_FIRST_LOGICAL_SWITCH, LUA_EXPORT_MULTIPLE("ls", "Logical switch L%d", MAX_LOGICAL_SWITCHES)
|
||||
MIXSRC_LAST_LOGICAL_SWITCH SKIP = MIXSRC_FIRST_LOGICAL_SWITCH+MAX_LOGICAL_SWITCHES-1,
|
||||
MIXSRC_LAST_LOGICAL_SWITCH SKIP = MIXSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1,
|
||||
|
||||
MIXSRC_FIRST_TRAINER SKIP, LUA_EXPORT_MULTIPLE("trn", "Trainer input %d", MAX_TRAINER_CHANNELS)
|
||||
MIXSRC_LAST_TRAINER SKIP = MIXSRC_FIRST_TRAINER+MAX_TRAINER_CHANNELS-1,
|
||||
MIXSRC_FIRST_TRAINER SKIP,
|
||||
MIXSRC_LAST_TRAINER SKIP = MIXSRC_FIRST_TRAINER + MAX_TRAINER_CHANNELS - 1,
|
||||
|
||||
MIXSRC_FIRST_CH SKIP,
|
||||
MIXSRC_CH1 = MIXSRC_FIRST_CH, LUA_EXPORT_MULTIPLE("ch", "Channel CH%d", MAX_OUTPUT_CHANNELS)
|
||||
MIXSRC_CH2,
|
||||
MIXSRC_CH3,
|
||||
MIXSRC_CH4,
|
||||
MIXSRC_CH5,
|
||||
MIXSRC_CH6,
|
||||
MIXSRC_CH7,
|
||||
MIXSRC_CH8,
|
||||
MIXSRC_CH9,
|
||||
MIXSRC_CH10,
|
||||
MIXSRC_CH11,
|
||||
MIXSRC_CH12,
|
||||
MIXSRC_CH13,
|
||||
MIXSRC_CH14,
|
||||
MIXSRC_CH15,
|
||||
MIXSRC_CH16,
|
||||
MIXSRC_LAST_CH SKIP = MIXSRC_CH1+MAX_OUTPUT_CHANNELS-1,
|
||||
MIXSRC_LAST_CH SKIP = MIXSRC_FIRST_CH + MAX_OUTPUT_CHANNELS - 1,
|
||||
|
||||
MIXSRC_FIRST_GVAR SKIP,
|
||||
MIXSRC_GVAR1 = MIXSRC_FIRST_GVAR, LUA_EXPORT_MULTIPLE("gvar", "Global variable %d", MAX_GVARS)
|
||||
MIXSRC_LAST_GVAR SKIP = MIXSRC_FIRST_GVAR+MAX_GVARS-1,
|
||||
MIXSRC_LAST_GVAR SKIP = MIXSRC_FIRST_GVAR + MAX_GVARS - 1,
|
||||
|
||||
MIXSRC_TX_VOLTAGE, LUA_EXPORT("tx-voltage", "Transmitter battery voltage [volts]")
|
||||
MIXSRC_TX_TIME, LUA_EXPORT("clock", "RTC clock [minutes from midnight]")
|
||||
MIXSRC_TX_VOLTAGE,
|
||||
MIXSRC_TX_TIME,
|
||||
MIXSRC_TX_GPS,
|
||||
MIXSRC_FIRST_RESERVE SKIP,
|
||||
MIXSRC_RESERVE3 SKIP,
|
||||
MIXSRC_RESERVE4 SKIP,
|
||||
MIXSRC_LAST_RESERVE SKIP,
|
||||
MIXSRC_FIRST_TIMER SKIP,
|
||||
MIXSRC_TIMER1 = MIXSRC_FIRST_TIMER, LUA_EXPORT("timer1", "Timer 1 value [seconds]")
|
||||
MIXSRC_TIMER2, LUA_EXPORT("timer2", "Timer 2 value [seconds]")
|
||||
MIXSRC_TIMER3, LUA_EXPORT("timer3", "Timer 3 value [seconds]")
|
||||
MIXSRC_LAST_TIMER SKIP = MIXSRC_TIMER3,
|
||||
|
||||
MIXSRC_FIRST_TELEM SKIP, LUA_EXPORT_MULTIPLE("telem", "Telemetry sensor %d", MAX_TELEMETRY_SENSORS)
|
||||
MIXSRC_LAST_TELEM SKIP = MIXSRC_FIRST_TELEM+3*MAX_TELEMETRY_SENSORS-1
|
||||
MIXSRC_FIRST_TIMER SKIP,
|
||||
MIXSRC_LAST_TIMER SKIP = MIXSRC_FIRST_TIMER + MAX_TIMERS - 1,
|
||||
|
||||
MIXSRC_FIRST_TELEM SKIP,
|
||||
MIXSRC_LAST_TELEM SKIP = MIXSRC_FIRST_TELEM + 3 * MAX_TELEMETRY_SENSORS - 1,
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
static_assert(MIXSRC_FIRST_LOGICAL_SWITCH == MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES, "Wrong switches definition in MIXSRC list");
|
||||
#endif
|
||||
|
||||
#define MIXSRC_FIRST (MIXSRC_NONE + 1)
|
||||
#define MIXSRC_LAST MIXSRC_LAST_CH
|
||||
#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES - 1)
|
||||
#define INPUTSRC_FIRST MIXSRC_Rud
|
||||
#define INPUTSRC_FIRST MIXSRC_FIRST_STICK
|
||||
#define INPUTSRC_LAST MIXSRC_LAST_TELEM
|
||||
|
||||
// TODO: this won't work forever (what about ground radios?)
|
||||
#define MIXSRC_Thr (MIXSRC_FIRST_STICK + 2)
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
#define MIXSRC_LAST_REGULAR_SWITCH (MIXSRC_FIRST_SWITCH + NUM_REGULAR_SWITCHES - 1)
|
||||
#define MIXSRC_LAST_REGULAR_SWITCH (MIXSRC_FIRST_SWITCH + switchGetMaxSwitches() - 1)
|
||||
#define MIXSRC_FIRST_FS_SWITCH (MIXSRC_LAST_REGULAR_SWITCH + 1)
|
||||
#endif
|
||||
|
||||
|
@ -840,9 +574,7 @@ enum Functions {
|
|||
FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE,
|
||||
FUNC_PLAY_TRACK,
|
||||
FUNC_PLAY_VALUE,
|
||||
FUNC_RESERVE4,
|
||||
FUNC_PLAY_SCRIPT,
|
||||
FUNC_RESERVE5,
|
||||
FUNC_BACKGND_MUSIC,
|
||||
FUNC_BACKGND_MUSIC_PAUSE,
|
||||
FUNC_VARIO,
|
||||
|
|
|
@ -53,7 +53,7 @@ static inline void check_struct()
|
|||
CHKSIZE(LimitData, 11);
|
||||
CHKSIZE(LogicalSwitchData, 9);
|
||||
CHKSIZE(CustomFunctionData, 11);
|
||||
CHKSIZE(FlightModeData, 28 + 2*NUM_TRIMS);
|
||||
CHKSIZE(FlightModeData, 28 + 2 * MAX_TRIMS);
|
||||
CHKSIZE(TimerData, 12);
|
||||
CHKSIZE(SwashRingData, 8);
|
||||
CHKSIZE(FrSkyBarData, 6);
|
||||
|
@ -67,7 +67,7 @@ static inline void check_struct()
|
|||
CHKSIZE(LimitData, 13);
|
||||
CHKSIZE(LogicalSwitchData, 9);
|
||||
CHKSIZE(CustomFunctionData, 11);
|
||||
CHKSIZE(FlightModeData, 40);
|
||||
CHKSIZE(FlightModeData, 44);
|
||||
CHKSIZE(TimerData, 17);
|
||||
CHKSIZE(SwashRingData, 8);
|
||||
CHKSIZE(FrSkyBarData, 6);
|
||||
|
@ -117,37 +117,37 @@ static inline void check_struct()
|
|||
CHKSIZE(TrainerData, 16);
|
||||
|
||||
#if defined(PCBXLITES)
|
||||
CHKSIZE(RadioData, 864);
|
||||
CHKSIZE(ModelData, 6220);
|
||||
CHKSIZE(RadioData, 872);
|
||||
CHKSIZE(ModelData, 6265);
|
||||
#elif defined(PCBXLITE)
|
||||
CHKSIZE(RadioData, 862);
|
||||
CHKSIZE(ModelData, 6220);
|
||||
CHKSIZE(RadioData, 870);
|
||||
CHKSIZE(ModelData, 6265);
|
||||
#elif defined(RADIO_TPRO)
|
||||
CHKSIZE(RadioData, 845);
|
||||
CHKSIZE(ModelData, 6245);
|
||||
CHKSIZE(RadioData, 859);
|
||||
CHKSIZE(ModelData, 6292);
|
||||
#elif defined(RADIO_BOXER)
|
||||
CHKSIZE(RadioData, 877);
|
||||
CHKSIZE(ModelData, 6221);
|
||||
CHKSIZE(RadioData, 870);
|
||||
CHKSIZE(ModelData, 6265);
|
||||
#elif defined(PCBX7)
|
||||
CHKSIZE(RadioData, 868);
|
||||
CHKSIZE(ModelData, 6220);
|
||||
CHKSIZE(RadioData, 870);
|
||||
CHKSIZE(ModelData, 6265);
|
||||
#elif defined(PCBX9E)
|
||||
CHKSIZE(RadioData, 958);
|
||||
CHKSIZE(ModelData, 6672);
|
||||
CHKSIZE(RadioData, 870);
|
||||
CHKSIZE(ModelData, 6707);
|
||||
#elif defined(PCBX9D) || defined(PCBX9DP)
|
||||
CHKSIZE(RadioData, 900);
|
||||
CHKSIZE(ModelData, 6664);
|
||||
CHKSIZE(RadioData, 870);
|
||||
CHKSIZE(ModelData, 6706);
|
||||
#elif defined(PCBHORUS)
|
||||
#if defined(PCBX10)
|
||||
CHKSIZE(RadioData, 952);
|
||||
CHKSIZE(ModelData, 15454);
|
||||
CHKSIZE(RadioData, 916);
|
||||
CHKSIZE(ModelData, 15463);
|
||||
#else
|
||||
CHKSIZE(RadioData, 934);
|
||||
CHKSIZE(ModelData, 15452);
|
||||
CHKSIZE(RadioData, 916);
|
||||
CHKSIZE(ModelData, 15463);
|
||||
#endif
|
||||
#elif defined(PCBNV14)
|
||||
CHKSIZE(RadioData, 880);
|
||||
CHKSIZE(ModelData, 15268);
|
||||
CHKSIZE(RadioData, 916);
|
||||
CHKSIZE(ModelData, 15319);
|
||||
#endif
|
||||
|
||||
#undef CHKSIZE
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "globals.h"
|
||||
#include "serial.h"
|
||||
#include "usb_joystick.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define N_TARANIS_FIELD(x)
|
||||
|
@ -78,8 +79,8 @@ PACK(struct MixData {
|
|||
uint16_t mixWarn:2; // mixer warning
|
||||
uint16_t mltpx:2 ENUM(MixerMultiplex);
|
||||
uint16_t spare:1 SKIP;
|
||||
int32_t offset:14 CUST(in_read_weight,in_write_weight);
|
||||
int32_t swtch:9 CUST(r_swtchSrc,w_swtchSrc);
|
||||
int32_t offset:13 CUST(in_read_weight,in_write_weight);
|
||||
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
||||
uint32_t flightModes:9 CUST(r_flightModes, w_flightModes);
|
||||
CurveRef curve;
|
||||
uint8_t delayUp;
|
||||
|
@ -100,10 +101,9 @@ PACK(struct ExpoData {
|
|||
int16_t trimSource:6;
|
||||
uint16_t srcRaw:10 ENUM(MixSources) CUST(r_mixSrcRaw,w_mixSrcRaw);
|
||||
uint32_t chn:5;
|
||||
int32_t swtch:9 CUST(r_swtchSrc,w_swtchSrc);
|
||||
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
||||
uint32_t flightModes:9 CUST(r_flightModes, w_flightModes);
|
||||
int32_t weight:8 CUST(in_read_weight,in_write_weight);
|
||||
int32_t spare:1 SKIP;
|
||||
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
|
||||
int8_t offset CUST(in_read_weight,in_write_weight);
|
||||
CurveRef curve;
|
||||
|
@ -134,9 +134,9 @@ PACK(struct LogicalSwitchData {
|
|||
CUST_ATTR(def,r_logicSw,w_logicSw);
|
||||
int32_t v1:10 SKIP;
|
||||
int32_t v3:10 SKIP;
|
||||
int32_t andsw:9 CUST(r_swtchSrc,w_swtchSrc); // TODO rename to xswtch
|
||||
int32_t andsw:10 CUST(r_swtchSrc,w_swtchSrc); // TODO rename to xswtch
|
||||
uint32_t andswtype:1 SKIP; // TODO rename to xswtchType (AND / OR)
|
||||
uint32_t spare:2 SKIP; // anything else needed?
|
||||
uint32_t spare:1 SKIP; // anything else needed?
|
||||
int16_t v2 SKIP;
|
||||
uint8_t delay;
|
||||
uint8_t duration;
|
||||
|
@ -154,8 +154,8 @@ PACK(struct LogicalSwitchData {
|
|||
#endif
|
||||
|
||||
PACK(struct CustomFunctionData {
|
||||
int16_t swtch:9 CUST(r_swtchSrc,w_swtchSrc);
|
||||
uint16_t func:7 ENUM(Functions);
|
||||
int16_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
||||
uint16_t func:6 ENUM(Functions); // TODO: 6 bits for Functions?
|
||||
CUST_ATTR(def,r_customFn,w_customFn);
|
||||
PACK(union {
|
||||
NOBACKUP(PACK(struct {
|
||||
|
@ -192,10 +192,11 @@ PACK(struct trim_t {
|
|||
});
|
||||
|
||||
PACK(struct FlightModeData {
|
||||
trim_t trim[NUM_TRIMS];
|
||||
trim_t trim[MAX_TRIMS];
|
||||
NOBACKUP(char name[LEN_FLIGHT_MODE_NAME]);
|
||||
int16_t swtch:9 ENUM(SwitchSources) CUST(r_swtchSrc,w_swtchSrc); // swtch of phase[0] is not used
|
||||
int16_t spare:7 SKIP;
|
||||
// swtch of phase[0] is not used
|
||||
int16_t swtch:10 ENUM(SwitchSources) CUST(r_swtchSrc,w_swtchSrc);
|
||||
int16_t spare:6 SKIP;
|
||||
uint8_t fadeIn;
|
||||
uint8_t fadeOut;
|
||||
gvar_t gvars[MAX_GVARS] FUNC(gvar_is_active);
|
||||
|
@ -555,19 +556,20 @@ PACK(struct ModelHeader {
|
|||
#endif
|
||||
});
|
||||
|
||||
#if defined(COLORLCD)
|
||||
typedef uint32_t swconfig_t;
|
||||
typedef uint32_t swarnstate_t;
|
||||
#elif defined(PCBX9E)
|
||||
typedef uint64_t swconfig_t;
|
||||
typedef uint64_t swarnstate_t;
|
||||
#elif defined(PCBX9D) || defined(PCBX9DP)
|
||||
typedef uint32_t swconfig_t;
|
||||
typedef uint32_t swarnstate_t;
|
||||
#else
|
||||
typedef uint16_t swconfig_t;
|
||||
typedef uint32_t swarnstate_t;
|
||||
#endif
|
||||
// 2 bits per switch, max 32 switches
|
||||
static_assert(sizeof(swconfig_t) >= (MAX_SWITCHES * 2 + 7) / 8,
|
||||
"MAX_SWITCHES must fit swconfig_t");
|
||||
|
||||
static_assert(sizeof(swarnstate_t) >= (MAX_SWITCHES * 2 + 7) / 8,
|
||||
"MAX_SWITCHES must fit swarnstate_t");
|
||||
|
||||
// pot config: 4 bits per pot
|
||||
static_assert(sizeof(potconfig_t) * 8 >= ((MAX_POTS - 1) / 4) + 1,
|
||||
"MAX_POTS must fit potconfig_t");
|
||||
|
||||
// pot warning enabled: 1 bit per pot
|
||||
static_assert(sizeof(potwarnen_t) * 8 >= MAX_POTS,
|
||||
"MAX_POTS must fit potwarnen_t");
|
||||
|
||||
#if defined(COLORLCD) && defined(BACKUP)
|
||||
#define CUSTOM_SCREENS_DATA
|
||||
|
@ -606,7 +608,7 @@ PACK(struct CustomScreenData {
|
|||
#define SCRIPT_DATA
|
||||
#endif
|
||||
|
||||
#if defined(FUNCTION_SWITCHES) && NUM_FUNCTIONS_SWITCHES < 8
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
#define FUNCTION_SWITCHS_FIELDS \
|
||||
uint16_t functionSwitchConfig; \
|
||||
uint16_t functionSwitchGroup; \
|
||||
|
@ -719,8 +721,8 @@ PACK(struct ModelData {
|
|||
SCRIPT_DATA
|
||||
|
||||
NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]);
|
||||
NOBACKUP(uint16_t potsWarnEnabled);
|
||||
NOBACKUP(int8_t potsWarnPosition[STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS]);
|
||||
NOBACKUP(potwarnen_t potsWarnEnabled);
|
||||
NOBACKUP(int8_t potsWarnPosition[MAX_POTS]);
|
||||
|
||||
NOBACKUP(TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS];)
|
||||
|
||||
|
@ -734,30 +736,26 @@ PACK(struct ModelData {
|
|||
|
||||
uint8_t getThrottleStickTrimSource() const
|
||||
{
|
||||
// The order here is TERA, so that 0 (default) means Throttle
|
||||
switch (thrTrimSw) {
|
||||
case 0:
|
||||
return MIXSRC_TrimThr;
|
||||
case 2:
|
||||
return MIXSRC_TrimRud;
|
||||
default:
|
||||
return thrTrimSw + MIXSRC_FIRST_TRIM;
|
||||
// Makes Throttle the default (=0)
|
||||
auto thr = inputMappingGetThrottle();
|
||||
if (thrTrimSw == 0) {
|
||||
return MIXSRC_FIRST_TRIM + thr;
|
||||
} else if (thrTrimSw == thr) {
|
||||
return MIXSRC_FIRST_TRIM;
|
||||
} else {
|
||||
return MIXSRC_FIRST_TRIM + thrTrimSw;
|
||||
}
|
||||
}
|
||||
|
||||
void setThrottleStickTrimSource(int16_t src)
|
||||
{
|
||||
// The order here is TERA, so that 0 (default) means Throttle
|
||||
switch (src) {
|
||||
case MIXSRC_TrimThr:
|
||||
auto thr = inputMappingGetThrottle();
|
||||
if (src == MIXSRC_FIRST_TRIM + thr) {
|
||||
thrTrimSw = 0;
|
||||
break;
|
||||
case MIXSRC_TrimRud:
|
||||
thrTrimSw = 2;
|
||||
break;
|
||||
default:
|
||||
} else if (src == MIXSRC_FIRST_TRIM) {
|
||||
thrTrimSw = thr;
|
||||
} else {
|
||||
thrTrimSw = src - MIXSRC_FIRST_TRIM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -820,12 +818,6 @@ PACK(struct TrainerData {
|
|||
|
||||
#if defined(COLORLCD)
|
||||
#define EXTRA_GENERAL_FIELDS \
|
||||
CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \
|
||||
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \
|
||||
uint16_t potsConfig ARRAY(2,struct_potConfig,nullptr); /* two bits per pot */ \
|
||||
uint8_t slidersConfig ARRAY(1,struct_sliderConfig,nullptr); /* 1 bit per slider */ \
|
||||
NOBACKUP(char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME] SKIP); \
|
||||
NOBACKUP(char anaNames[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP); \
|
||||
NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
|
||||
NOBACKUP(uint8_t modelQuickSelect:1); \
|
||||
NOBACKUP(uint8_t blOffBright:7); \
|
||||
|
@ -839,14 +831,7 @@ PACK(struct TrainerData {
|
|||
#define BLUETOOTH_FIELDS
|
||||
#endif
|
||||
#define EXTRA_GENERAL_FIELDS \
|
||||
uint8_t slidersConfig:4 ARRAY(1,struct_sliderConfig,nullptr); \
|
||||
uint8_t spare5:4 SKIP; \
|
||||
uint8_t potsConfig ARRAY(2,struct_potConfig,nullptr); /* two bits per pot */\
|
||||
uint8_t backlightColor; \
|
||||
CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \
|
||||
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \
|
||||
char switchNames[STORAGE_NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME] SKIP; \
|
||||
char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP; \
|
||||
BLUETOOTH_FIELDS
|
||||
#endif
|
||||
|
||||
|
@ -873,7 +858,7 @@ PACK(struct RadioData {
|
|||
NOBACKUP(int8_t spare0:7 SKIP);
|
||||
CUST_ATTR(semver,nullptr,w_semver);
|
||||
CUST_ATTR(board,nullptr,w_board);
|
||||
CalibData calib[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS + STORAGE_NUM_MOUSE_ANALOGS] NO_IDX;
|
||||
CalibData calib[MAX_CALIB_ANALOG_INPUTS] NO_IDX;
|
||||
NOBACKUP(uint16_t chkSum SKIP);
|
||||
N_HORUS_FIELD(int8_t currModel);
|
||||
N_HORUS_FIELD(uint8_t contrast);
|
||||
|
@ -883,7 +868,7 @@ PACK(struct RadioData {
|
|||
int8_t antennaMode:2 ENUM(AntennaModes);
|
||||
uint8_t disableRtcWarning:1;
|
||||
uint8_t keysBacklight:1;
|
||||
NOBACKUP(uint8_t spare1:1 SKIP);
|
||||
uint8_t spare1:1 SKIP;
|
||||
uint8_t internalModule ENUM(ModuleType);
|
||||
NOBACKUP(TrainerData trainer);
|
||||
NOBACKUP(uint8_t view); // index of view in main screen
|
||||
|
@ -946,6 +931,11 @@ PACK(struct RadioData {
|
|||
CUST_ATTR(aux2SerialMode, r_serialMode, nullptr);
|
||||
NOBACKUP(uint32_t serialPort ARRAY(SERIAL_CONF_BITS_PER_PORT,struct_serialConfig,nullptr));
|
||||
|
||||
CUST_ARRAY(sticksConfig, struct_stickConfig, MAX_STICKS, stick_name_valid);
|
||||
CUST_ARRAY(slidersConfig, struct_sliderConfig, MAX_POTS, nullptr);
|
||||
potconfig_t potsConfig ARRAY(4,struct_potConfig,nullptr);
|
||||
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr);
|
||||
|
||||
EXTRA_GENERAL_FIELDS
|
||||
|
||||
THEME_DATA
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#define _DISK_CACHE_H_
|
||||
|
||||
#include "diskio.h"
|
||||
#include "sdio_sd.h"
|
||||
|
||||
// tunable parameters
|
||||
#define DISK_CACHE_BLOCKS_NUM 32 // no cache blocks
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "switches.h"
|
||||
|
||||
#if defined(COLORLCD)
|
||||
void setRequestedMainView(uint8_t view);
|
||||
|
@ -143,7 +144,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
|
|||
#endif
|
||||
|
||||
#if defined(GVARS)
|
||||
for (uint8_t i=0; i<NUM_TRIMS; i++) {
|
||||
for (uint8_t i=0; i<MAX_TRIMS; i++) {
|
||||
trimGvar[i] = -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -173,9 +174,9 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
|
|||
uint8_t param = CFN_CH_INDEX(cfn);
|
||||
if (param == 0)
|
||||
newActiveFunctions |= 0x0F;
|
||||
else if (param <= NUM_STICKS)
|
||||
else if (param <= MAX_STICKS)
|
||||
newActiveFunctions |= (1 << (param - 1));
|
||||
else if (param == NUM_STICKS + 1)
|
||||
else if (param == MAX_STICKS + 1)
|
||||
newActiveFunctions |= (1u << FUNCTION_TRAINER_CHANNELS);
|
||||
break;
|
||||
}
|
||||
|
@ -465,3 +466,76 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
|
|||
functionsContext.activeFunctions = newActiveFunctions;
|
||||
}
|
||||
|
||||
const char* funcGetLabel(uint8_t func)
|
||||
{
|
||||
switch(func) {
|
||||
case FUNC_OVERRIDE_CHANNEL:
|
||||
return STR_SF_SAFETY;
|
||||
case FUNC_TRAINER:
|
||||
return STR_SF_TRAINER;
|
||||
case FUNC_INSTANT_TRIM:
|
||||
return STR_SF_INST_TRIM;
|
||||
case FUNC_RESET:
|
||||
return STR_SF_RESET;
|
||||
case FUNC_SET_TIMER:
|
||||
return STR_SF_SET_TIMER;
|
||||
#if defined(GVARS)
|
||||
case FUNC_ADJUST_GVAR:
|
||||
return STR_ADJUST_GVAR;
|
||||
#endif
|
||||
case FUNC_VOLUME:
|
||||
return STR_SF_VOLUME;
|
||||
case FUNC_SET_FAILSAFE:
|
||||
return STR_SF_FAILSAFE;
|
||||
case FUNC_RANGECHECK:
|
||||
return STR_SF_RANGE_CHECK;
|
||||
case FUNC_BIND:
|
||||
return STR_SF_MOD_BIND;
|
||||
#if defined(AUDIO)
|
||||
case FUNC_PLAY_SOUND:
|
||||
return STR_SOUND;
|
||||
#endif
|
||||
#if defined(VOICE)
|
||||
case FUNC_PLAY_TRACK:
|
||||
return STR_PLAY_TRACK;
|
||||
case FUNC_PLAY_VALUE:
|
||||
return STR_PLAY_VALUE;
|
||||
#endif
|
||||
#if defined(LUA)
|
||||
case FUNC_PLAY_SCRIPT:
|
||||
return STR_SF_PLAY_SCRIPT;
|
||||
#endif
|
||||
case FUNC_BACKGND_MUSIC:
|
||||
return STR_SF_BG_MUSIC;
|
||||
case FUNC_BACKGND_MUSIC_PAUSE:
|
||||
return STR_SF_BG_MUSIC_PAUSE;
|
||||
#if defined(VARIO)
|
||||
case FUNC_VARIO:
|
||||
return STR_SF_VARIO;
|
||||
#endif
|
||||
#if defined(HAPTIC)
|
||||
case FUNC_HAPTIC:
|
||||
return STR_SF_HAPTIC;
|
||||
#endif
|
||||
case FUNC_LOGS:
|
||||
return STR_SF_LOGS;
|
||||
case FUNC_BACKLIGHT:
|
||||
return STR_SF_BACKLIGHT;
|
||||
case FUNC_SCREENSHOT:
|
||||
return STR_SF_SCREENSHOT;
|
||||
case FUNC_RACING_MODE:
|
||||
return STR_SF_RACING_MODE;
|
||||
#if defined(COLORLCD)
|
||||
case FUNC_DISABLE_TOUCH:
|
||||
return STR_SF_DISABLE_TOUCH;
|
||||
case FUNC_SET_SCREEN:
|
||||
return STR_SF_SET_SCREEN;
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
case FUNC_TEST:
|
||||
return STR_SF_TEST;
|
||||
#endif
|
||||
default:
|
||||
return STR_EMPTY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,7 @@ PACK(struct GlobalData {
|
|||
uint8_t authenticationCount:2;
|
||||
uint8_t upgradeModulePopup:1;
|
||||
uint8_t internalModuleVersionChecked:1;
|
||||
uint8_t flyskygimbals:1;
|
||||
uint8_t spare:1;
|
||||
uint8_t spare:2;
|
||||
});
|
||||
|
||||
extern GlobalData globalData;
|
||||
|
@ -81,7 +80,7 @@ extern int32_t act[MAX_MIXERS];
|
|||
extern int8_t virtualInputsTrims[MAX_INPUTS];
|
||||
|
||||
extern int16_t anas [MAX_INPUTS];
|
||||
extern int16_t trims[NUM_TRIMS];
|
||||
extern int16_t trims[MAX_TRIMS];
|
||||
extern int32_t chans[MAX_OUTPUT_CHANNELS];
|
||||
extern int16_t ex_chans[MAX_OUTPUT_CHANNELS]; // Outputs (before LIMITS) of the last perMain
|
||||
extern int16_t channelOutputs[MAX_OUTPUT_CHANNELS];
|
||||
|
@ -91,7 +90,7 @@ extern BeepANACenter bpanaCenter;
|
|||
|
||||
extern uint8_t s_mixer_first_run_done;
|
||||
|
||||
extern int16_t calibratedAnalogs[NUM_CALIBRATED_ANALOGS];
|
||||
extern int16_t calibratedAnalogs[MAX_ANALOG_INPUTS];
|
||||
|
||||
extern uint8_t g_beepCnt;
|
||||
extern uint8_t beepAgain;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "gui_common.h"
|
||||
#include "menus.h"
|
||||
#include "popups.h"
|
||||
|
||||
#include "navigation/navigation.h"
|
||||
#include "common/stdlcd/draw_functions.h"
|
||||
|
||||
#define MENUS_SCROLLBAR_WIDTH 0
|
||||
|
@ -57,147 +59,49 @@ extern uint8_t noHighlightCounter;
|
|||
void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr);
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
|
||||
|
||||
extern int8_t checkIncDec_Ret; // global helper vars
|
||||
|
||||
#define EDIT_SELECT_FIELD 0
|
||||
#define EDIT_MODIFY_FIELD 1
|
||||
#define EDIT_MODIFY_STRING 2
|
||||
extern int8_t s_editMode; // global editmode
|
||||
|
||||
// checkIncDec flags
|
||||
|
||||
// we leave room for EE_MODEL and EE_GENERAL
|
||||
#define NO_INCDEC_MARKS 0x04
|
||||
#define INCDEC_SWITCH 0x08
|
||||
#define INCDEC_SOURCE 0x10
|
||||
#define INCDEC_REP10 0x40
|
||||
#define NO_DBLKEYS 0x80
|
||||
|
||||
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = nullptr
|
||||
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
|
||||
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
|
||||
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
|
||||
|
||||
struct CheckIncDecStops {
|
||||
const int count;
|
||||
const int stops[];
|
||||
int min() const
|
||||
{
|
||||
return stops[0];
|
||||
}
|
||||
int max() const
|
||||
{
|
||||
return stops[count-1];
|
||||
}
|
||||
bool contains(int value) const
|
||||
{
|
||||
for (int i=0; i<count; ++i) {
|
||||
int stop = stops[i];
|
||||
if (value == stop)
|
||||
return true;
|
||||
else if (value < stop)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
extern const CheckIncDecStops &stops100;
|
||||
extern const CheckIncDecStops &stops1000;
|
||||
extern const CheckIncDecStops &stopsSwitch;
|
||||
#define INIT_STOPS(var, ...) \
|
||||
const int _ ## var[] = { __VA_ARGS__ }; \
|
||||
const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
|
||||
#define CATEGORY_END(val) \
|
||||
(val), (val+1)
|
||||
int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=nullptr, const CheckIncDecStops &stops=stops100);
|
||||
|
||||
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
|
||||
#define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
|
||||
#define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR(event, var, min, max) \
|
||||
var = checkIncDecModel(event, var, min, max)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
|
||||
var = checkIncDecModelZero(event, var, max)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
|
||||
var = checkIncDec(event, var, min, max, EE_MODEL, check)
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
|
||||
var = checkIncDec(event, var, 0, max, EE_MODEL, check)
|
||||
|
||||
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
|
||||
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
|
||||
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
|
||||
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
|
||||
|
||||
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
|
||||
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
|
||||
|
||||
#define CHECK_INCDEC_GENVAR(event, var, min, max) \
|
||||
var = checkIncDecGen(event, var, min, max)
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define CURSOR_ON_LINE() (menuHorizontalPosition < 0)
|
||||
#else
|
||||
#define CURSOR_ON_LINE() (0)
|
||||
#endif
|
||||
|
||||
void check(event_t event, uint8_t curr, const MenuHandler *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow);
|
||||
void check_simple(event_t event, uint8_t curr, const MenuHandler *menuTab, uint8_t menuTabSize, vertpos_t maxrow);
|
||||
void check_submenu_simple(event_t event, uint8_t maxrow);
|
||||
|
||||
void title(const char * s);
|
||||
|
||||
#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
|
||||
|
||||
#define MENU_CHECK(tab, menu, lines_count) \
|
||||
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE)
|
||||
|
||||
#define MENU(name, tab, menu, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
MENU_CHECK(tab, menu, lines_count); \
|
||||
title(name)
|
||||
|
||||
#define SUBMENU_NOTITLE(lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE)
|
||||
|
||||
#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
|
||||
check_simple(event, menu, tab, DIM(tab), (lines_count)-HEADER_LINE)
|
||||
|
||||
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
|
||||
check_submenu_simple(event, (lines_count)-HEADER_LINE)
|
||||
|
||||
#define SUBMENU(name, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE); \
|
||||
title(name)
|
||||
|
||||
#define SIMPLE_MENU(name, tab, menu, lines_count) \
|
||||
SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \
|
||||
title(name)
|
||||
|
||||
#define SIMPLE_SUBMENU(name, lines_count) \
|
||||
SIMPLE_SUBMENU_NOTITLE(lines_count); \
|
||||
title(name)
|
||||
|
||||
typedef int choice_t;
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, IsValueAvailable isValueAvailable = nullptr);
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char * label, LcdFlags attr, event_t event);
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event);
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable = nullptr);
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event);
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr,
|
||||
event_t event);
|
||||
|
||||
#if defined(GVARS)
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event);
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags=0);
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags);
|
||||
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
#else
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event);
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event)
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, uint8_t editflags,
|
||||
event_t event);
|
||||
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value,
|
||||
LcdFlags flags = 0);
|
||||
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar,
|
||||
uint8_t flightMode, LcdFlags flags);
|
||||
|
||||
#define displayGVar(x, y, v, min, max) \
|
||||
GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
|
||||
#else // GVARS
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, event_t event);
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, attr, event)
|
||||
|
||||
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
|
||||
|
||||
#endif
|
||||
|
||||
void gvarWeightItem(coord_t x, coord_t y, MixData * md, LcdFlags attr, event_t event);
|
||||
|
@ -210,10 +114,12 @@ void editSingleName(coord_t x, coord_t y, const char *label, char *name,
|
|||
uint8_t old_editMode);
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay);
|
||||
|
||||
#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
|
||||
extern uint8_t s_copyMode;
|
||||
extern int8_t s_copySrcRow;
|
||||
extern int8_t s_copyTgtOfs;
|
||||
|
@ -243,33 +149,9 @@ void readModelNotes();
|
|||
void menuChannelsView(event_t event);
|
||||
void menuChannelsViewCommon(event_t event);
|
||||
|
||||
#define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
|
||||
#define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)
|
||||
void repeatLastCursorMove(event_t event);
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
#define IS_ROTARY_LEFT(evt) (evt == EVT_ROTARY_LEFT)
|
||||
#define IS_ROTARY_RIGHT(evt) (evt == EVT_ROTARY_RIGHT)
|
||||
#define IS_ROTARY_BREAK(evt) (evt == EVT_ROTARY_BREAK)
|
||||
#define IS_ROTARY_LONG(evt) (evt == EVT_ROTARY_LONG)
|
||||
#define IS_ROTARY_EVENT(evt) (EVT_KEY_MASK(evt) >= 0x0e)
|
||||
void repeatLastCursorMove(event_t event);
|
||||
#define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) pushEvent(event); else repeatLastCursorMove(event); }
|
||||
#else
|
||||
#define IS_ROTARY_LEFT(evt) (0)
|
||||
#define IS_ROTARY_RIGHT(evt) (0)
|
||||
#define IS_ROTARY_BREAK(evt) (0)
|
||||
#define IS_ROTARY_LONG(evt) (0)
|
||||
#define IS_ROTARY_EVENT(evt) (0)
|
||||
void repeatLastCursorMove(event_t event);
|
||||
#define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event)
|
||||
#endif
|
||||
|
||||
// TODO enum
|
||||
#if defined(PCBX7) || defined(PCBX9LITE)
|
||||
#define EDIT_MODE_INIT 0
|
||||
#else
|
||||
#define EDIT_MODE_INIT -1
|
||||
#endif
|
||||
|
||||
extern uint8_t editNameCursorPos;
|
||||
|
||||
|
@ -280,6 +162,7 @@ uint8_t getMixesCount();
|
|||
void insertMix(uint8_t idx);
|
||||
void deleteMix(uint8_t idx);
|
||||
|
||||
void onSwitchLongEnterPress(const char *result);
|
||||
void onSourceLongEnterPress(const char *result);
|
||||
|
||||
uint8_t switchToMix(uint8_t source);
|
||||
|
@ -291,6 +174,8 @@ extern const unsigned char sticks[] ;
|
|||
void drawSplash();
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval);
|
||||
void drawWheel(coord_t centrex, int16_t wval);
|
||||
void drawThrottle(coord_t centrex, int16_t tval);
|
||||
void drawPotsBars();
|
||||
void doMainScreenGraphics();
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
#if !defined(BOOT)
|
||||
#include "opentx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "switches.h"
|
||||
#endif
|
||||
|
||||
pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA;
|
||||
|
@ -707,7 +710,7 @@ void putsVBat(coord_t x, coord_t y, LcdFlags att)
|
|||
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
|
||||
{
|
||||
if (idx == MIXSRC_NONE) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
|
||||
lcdDrawText(x, y, STR_EMPTY, att);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_INPUT) {
|
||||
lcdDrawChar(x+2, y+1, CHR_INPUT, TINSIZE);
|
||||
|
@ -734,98 +737,14 @@ void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
else if (idx <= MIXSRC_LAST_POT) {
|
||||
idx = idx - MIXSRC_Rud;
|
||||
if (g_eeGeneral.anaNames[idx][0]) {
|
||||
if (idx < MIXSRC_FIRST_POT-MIXSRC_Rud )
|
||||
lcdDrawSizedText(x, y, STR_CHAR_STICK, 2, att);
|
||||
else if (idx <= MIXSRC_LAST_POT-MIXSRC_Rud )
|
||||
lcdDrawSizedText(x, y, STR_CHAR_POT, 2, att);
|
||||
else
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SLIDER, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, att);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + 1, att);
|
||||
}
|
||||
}
|
||||
else if (idx >= MIXSRC_FIRST_SWITCH && idx <= MIXSRC_LAST_SWITCH) {
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
if(idx >= MIXSRC_FIRST_FS_SWITCH) {
|
||||
idx = idx-(MIXSRC_FIRST_SWITCH+NUM_REGULAR_SWITCHES);
|
||||
if (ZEXIST(g_model.switchNames[idx])) {
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SWITCH, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, g_model.switchNames[idx], LEN_SWITCH_NAME, att);
|
||||
}
|
||||
else {
|
||||
char s[LEN_SWITCH_NAME] = {'S', 'W'};
|
||||
s[LEN_SWITCH_NAME-1] = '1' + idx;
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SWITCH, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, s, LEN_SWITCH_NAME, att);
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx = idx-MIXSRC_FIRST_SWITCH;
|
||||
if (ZEXIST(g_eeGeneral.switchNames[idx])) {
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SWITCH, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME, att);
|
||||
}
|
||||
else
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1, att);
|
||||
}
|
||||
#else
|
||||
idx = idx-MIXSRC_FIRST_SWITCH;
|
||||
if (ZEXIST(g_eeGeneral.switchNames[idx])) {
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SWITCH, 2, att); //switch symbol
|
||||
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME, att);
|
||||
}
|
||||
else
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1, att);
|
||||
#endif
|
||||
|
||||
}
|
||||
else if (idx < MIXSRC_SW1)
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
|
||||
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
|
||||
drawSwitch(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
|
||||
else if (idx < MIXSRC_CH1)
|
||||
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
|
||||
else if (idx <= MIXSRC_LAST_CH) {
|
||||
if (ZEXIST(g_model.limitData[idx-MIXSRC_CH1].name) && (att & STREXPANDED)) {
|
||||
char s[LEN_CHANNEL_NAME + 3];
|
||||
strcpy(s, STR_CHAR_CHANNEL);
|
||||
strcat(s, g_model.limitData[idx-MIXSRC_CH1].name);
|
||||
lcdDrawSizedText(x, y, s, LEN_CHANNEL_NAME+2, att);
|
||||
} else {
|
||||
drawStringWithIndex(x, y, STR_CH, idx-MIXSRC_CH1+1, att);
|
||||
}
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_GVAR) {
|
||||
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
|
||||
}
|
||||
else if (idx < MIXSRC_FIRST_TIMER) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_TIMER) {
|
||||
if(ZEXIST(g_model.timers[idx-MIXSRC_FIRST_TIMER].name)) {
|
||||
lcdDrawSizedText(x, y, g_model.timers[idx-MIXSRC_FIRST_TIMER].name, LEN_TIMER_NAME, att);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx -= MIXSRC_FIRST_TELEM;
|
||||
div_t qr = div(idx, 3);
|
||||
lcdDrawSizedText(x, y, g_model.telemetrySensors[qr.quot].label, TELEM_LABEL_LEN, att);
|
||||
if (qr.rem) lcdDrawChar(lcdLastRightPos, y, qr.rem==2 ? '+' : '-', att);
|
||||
lcdDrawText(x, y, getSourceString(idx), att);
|
||||
}
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, idx-1, att);
|
||||
lcdDrawText(x, y, getAnalogShortLabel(idx), att);
|
||||
}
|
||||
|
||||
void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
|
||||
|
@ -873,10 +792,10 @@ void drawShortTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags a
|
|||
uint8_t mode = v.mode;
|
||||
uint8_t p = v.mode >> 1;
|
||||
if (mode == TRIM_MODE_NONE) {
|
||||
putsChnLetter(x, y, idx+1, att);
|
||||
putsChnLetter(x, y, idx, att);
|
||||
}
|
||||
else {
|
||||
lcdDrawChar(x, y, '0'+p, att);
|
||||
lcdDrawChar(x, y, '0' + p, att);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
|
|||
|
||||
void drawShortTrimMode(coord_t x, coord_t y, uint8_t mode, uint8_t idx, LcdFlags att);
|
||||
|
||||
#define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_CH1+idx-1, att)
|
||||
#define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_FIRST_CH + idx - 1, att)
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
|
||||
|
|
|
@ -70,6 +70,7 @@ void menuRadioTrainer(event_t event);
|
|||
void menuRadioVersion(event_t event);
|
||||
void menuRadioDiagKeys(event_t event);
|
||||
void menuRadioDiagAnalogs(event_t event);
|
||||
void menuRadioDiagFS(event_t event);
|
||||
void menuRadioHardware(event_t event);
|
||||
void menuRadioTools(event_t event);
|
||||
void menuRadioSpectrumAnalyser(event_t event);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
void runPopupCurvePreset(event_t event)
|
||||
{
|
||||
|
@ -122,9 +123,7 @@ void menuModelCurveOne(event_t event)
|
|||
lcdDrawNumber(INDENT_WIDTH, 6*FH+1, 5+crv.points, LEFT|attr);
|
||||
lcdDrawText(lcdLastRightPos, 6*FH+1, STR_PTS, attr);
|
||||
if (attr) {
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
#endif
|
||||
rotaryEncoderResetAccel();
|
||||
int8_t count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
|
||||
if (checkIncDec_Ret) {
|
||||
int8_t newPoints[MAX_POINTS_PER_CURVE];
|
||||
|
@ -174,7 +173,7 @@ void menuModelCurveOne(event_t event)
|
|||
break;
|
||||
#elif defined(NAVIGATION_XLITE)
|
||||
case EVT_KEY_FIRST(KEY_ENTER):
|
||||
if (IS_SHIFT_PRESSED()) {
|
||||
if (keysGetState(KEY_SHIFT)) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ void menuModelCustomScriptOne(event_t event)
|
|||
scriptInputsOutputs[s_currIdx].inputsCount + 1) {
|
||||
lcdDrawTextAlignedLeft(y, STR_OUTPUTS);
|
||||
if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
} else if (i <= ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL +
|
||||
scriptInputsOutputs[s_currIdx].inputsCount +
|
||||
|
|
|
@ -262,7 +262,7 @@ void menuModelDisplay(event_t event)
|
|||
}
|
||||
}
|
||||
if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -111,17 +111,16 @@ void menuModelFlightModeOne(event_t event)
|
|||
|
||||
case ITEM_MODEL_FLIGHT_MODE_TRIMS:
|
||||
lcdDrawTextAlignedLeft(y, STR_TRIMS);
|
||||
for (uint8_t t = 0; t < NUM_STICKS; t++) {
|
||||
{
|
||||
auto trims = keysGetMaxTrims();
|
||||
for (uint8_t t = 0; t < trims; t++) {
|
||||
drawTrimMode(MIXES_2ND_COLUMN + (t*2*FW), y, s_currIdx, t, menuHorizontalPosition == t ? attr : 0);
|
||||
#if defined(NAVIGATION_9X)
|
||||
if (s_editMode > 0 && attr && menuHorizontalPosition == t) {
|
||||
#else
|
||||
if (s_editMode >= 0 && attr && menuHorizontalPosition == t) {
|
||||
#endif
|
||||
trim_t & v = fm->trim[t];
|
||||
v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_FLIGHT_MODE_FADE_IN:
|
||||
|
@ -188,64 +187,41 @@ void menuModelFlightModeOne(event_t event)
|
|||
|
||||
void menuModelFlightModesAll(event_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUFLIGHTMODES, menuTabModel, MENU_MODEL_FLIGHT_MODES, HEADER_LINE+MAX_FLIGHT_MODES+1);
|
||||
SIMPLE_MENU(STR_MENUFLIGHTMODES, menuTabModel, MENU_MODEL_FLIGHT_MODES,
|
||||
HEADER_LINE+MAX_FLIGHT_MODES+1);
|
||||
|
||||
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||
|
||||
switch (event) {
|
||||
case EVT_KEY_FIRST(KEY_ENTER):
|
||||
if (sub == MAX_FLIGHT_MODES) {
|
||||
// "Check trims" button
|
||||
if (sub == MAX_FLIGHT_MODES && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
s_editMode = 0;
|
||||
trimsCheckTimer = 200; // 2 seconds
|
||||
}
|
||||
// no break
|
||||
#if !defined(PCBX7)
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
#endif
|
||||
if (sub >= 0 && sub < MAX_FLIGHT_MODES) {
|
||||
|
||||
// Flight mode lines
|
||||
if (sub >= 0 && sub < MAX_FLIGHT_MODES &&
|
||||
(event == EVT_KEY_FIRST(KEY_ENTER) || event == EVT_KEY_FIRST(KEY_RIGHT))) {
|
||||
s_currIdx = sub;
|
||||
pushMenu(menuModelFlightModeOne);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t att;
|
||||
for (uint8_t i=0; i<MAX_FLIGHT_MODES; i++) {
|
||||
int8_t y = 1 + (1+i-menuVerticalOffset)*FH;
|
||||
if (y<1*FH+1 || y>(LCD_LINES-1)*FH+1) continue;
|
||||
att = (i==sub ? INVERS : 0);
|
||||
FlightModeData * p = flightModeAddress(i);
|
||||
drawFlightMode(0, y, i+1, att|(getFlightMode()==i ? BOLD : 0));
|
||||
#if defined(PCBTARANIS)
|
||||
for (uint8_t i = 0; i < MAX_FLIGHT_MODES; i++) {
|
||||
int8_t y = 1 + (1 + i - menuVerticalOffset) * FH;
|
||||
if (y < 1 * FH + 1 || y > (LCD_LINES - 1) * FH + 1) continue;
|
||||
att = (i == sub ? INVERS : 0);
|
||||
FlightModeData* p = flightModeAddress(i);
|
||||
drawFlightMode(0, y, i + 1, att | (getFlightMode() == i ? BOLD : 0));
|
||||
lcdDrawSizedText(NAME_POS, y, p->name, sizeof(p->name), 0);
|
||||
#else
|
||||
lcdDrawSizedText(4*FW+NAME_OFS, y, p->name, sizeof(p->name), 0);
|
||||
#endif
|
||||
if (i == 0) {
|
||||
for (uint8_t t=0; t<NUM_STICKS; t++) {
|
||||
#if defined(PCBTARANIS)
|
||||
drawTrimMode(TRIMS_POS+t*FW*2, y, i, t, 0);
|
||||
#else
|
||||
drawShortTrimMode((9+LEN_FLIGHT_MODE_NAME+t)*FW+TRIMS_OFS, y, i, t, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if defined(PCBTARANIS)
|
||||
drawSwitch(SWITCH_POS, y, p->swtch, 0);
|
||||
for (uint8_t t=0; t<NUM_STICKS; t++) {
|
||||
drawTrimMode(TRIMS_POS+t*FW*2, y, i, t, 0);
|
||||
}
|
||||
#else
|
||||
drawSwitch((4+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, p->swtch, 0);
|
||||
for (uint8_t t=0; t<NUM_STICKS; t++) {
|
||||
drawShortTrimMode((9+LEN_FLIGHT_MODE_NAME+t)*FW+TRIMS_OFS, y, i, t, 0);
|
||||
}
|
||||
#endif
|
||||
auto trims = min(keysGetMaxTrims(), (uint8_t)MAX_STICKS);
|
||||
if (i > 0) drawSwitch(SWITCH_POS, y, p->swtch, 0);
|
||||
for (uint8_t t = 0; t < trims; t++) {
|
||||
drawTrimMode(TRIMS_POS + t * FW * 2, y, i, t, 0);
|
||||
}
|
||||
|
||||
if (p->fadeIn || p->fadeOut) {
|
||||
lcdDrawChar(LCD_W-FW, y, (p->fadeIn && p->fadeOut) ? '*' : (p->fadeIn ? 'I' : 'O'));
|
||||
lcdDrawChar(LCD_W - FW, y,
|
||||
(p->fadeIn && p->fadeOut) ? '*' : (p->fadeIn ? 'I' : 'O'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ void menuModelExpoOne(event_t event)
|
|||
killEvents(event);
|
||||
}
|
||||
#elif defined(NAVIGATION_XLITE)
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && IS_SHIFT_PRESSED()) {
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && keysGetState(KEY_SHIFT)) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
|
@ -159,12 +159,20 @@ void menuModelExpoOne(event_t event)
|
|||
break;
|
||||
|
||||
case EXPO_FIELD_TRIM:
|
||||
uint8_t notStick = (ed->srcRaw > MIXSRC_Ail);
|
||||
int8_t trimSource = -ed->trimSource;
|
||||
lcdDrawTextAlignedLeft(y, STR_TRIM);
|
||||
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (notStick && trimSource == 0) ? 0 : trimSource + 1, RIGHT | (menuHorizontalPosition==0 ? attr : 0));
|
||||
if (attr)
|
||||
ed->trimSource = -checkIncDecModel(event, trimSource, notStick ? TRIM_ON : -TRIM_OFF, -TRIM_LAST);
|
||||
{
|
||||
const char* trim_str = getTrimSourceLabel(ed->srcRaw, ed->trimSource);
|
||||
LcdFlags flags = RIGHT | (menuHorizontalPosition==0 ? attr : 0);
|
||||
lcdDrawText(EXPO_ONE_2ND_COLUMN, y, trim_str, flags);
|
||||
|
||||
if (attr) {
|
||||
int8_t min = TRIM_ON;
|
||||
if (ed->srcRaw >= MIXSRC_FIRST_STICK && ed->srcRaw <= MIXSRC_LAST_STICK) {
|
||||
min = -TRIM_OFF;
|
||||
}
|
||||
ed->trimSource = -checkIncDecModel(event, -ed->trimSource, min, keysGetMaxTrims());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
y += FH;
|
||||
|
|
|
@ -60,7 +60,7 @@ void menuModelLogicalSwitchOne(event_t event)
|
|||
|
||||
LogicalSwitchData * cs = lswAddress(s_currIdx);
|
||||
|
||||
uint8_t sw = SWSRC_SW1+s_currIdx;
|
||||
uint8_t sw = SWSRC_FIRST_LOGICAL_SWITCH+s_currIdx;
|
||||
uint8_t cstate = lswFamily(cs->func);
|
||||
|
||||
drawSwitch(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0));
|
||||
|
@ -209,7 +209,7 @@ void menuModelLogicalSwitchOne(event_t event)
|
|||
if (cstate == LS_FAMILY_EDGE) {
|
||||
lcdDrawText(CSWONE_2ND_COLUMN, y, STR_NA);
|
||||
if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ void menuModelLogicalSwitches(event_t event)
|
|||
LogicalSwitchData * cs = lswAddress(k);
|
||||
|
||||
// CSW name
|
||||
uint8_t sw = SWSRC_SW1+k;
|
||||
uint8_t sw = SWSRC_FIRST_LOGICAL_SWITCH+k;
|
||||
|
||||
drawSwitch(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw) ? BOLD : 0));
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void menuModelMixOne(event_t event)
|
|||
killEvents(event);
|
||||
}
|
||||
#elif defined(NAVIGATION_XLITE)
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && IS_SHIFT_PRESSED()) {
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && keysGetState(KEY_SHIFT)) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
|
|
|
@ -90,10 +90,35 @@ void onModelSelectMenu(const char * result)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void moveToFreeModelSlot(bool forward, int8_t& sub, int8_t oldSub)
|
||||
{
|
||||
int8_t next_ofs = s_copyTgtOfs + oldSub - menuVerticalPosition;
|
||||
if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS) next_ofs = 0;
|
||||
|
||||
if (s_copySrcRow < 0 && s_copyMode == COPY_MODE) {
|
||||
s_copySrcRow = oldSub;
|
||||
// find a hole (in the first empty slot above / below)
|
||||
sub = findEmptyModel(s_copySrcRow, forward);
|
||||
if (sub < 0) {
|
||||
// no free room for duplicating the model
|
||||
AUDIO_ERROR();
|
||||
sub = oldSub;
|
||||
s_copyMode = 0;
|
||||
}
|
||||
next_ofs = 0;
|
||||
menuVerticalPosition = sub;
|
||||
}
|
||||
s_copyTgtOfs = next_ofs;
|
||||
}
|
||||
|
||||
void menuModelSelect(event_t event)
|
||||
{
|
||||
// Suppress "edit mode": model select has none
|
||||
// Suppress exit in "copy mode": handled in this function
|
||||
event_t _event_ = event;
|
||||
if ((s_copyMode && IS_KEY_EVT(event, KEY_EXIT)) || event == EVT_KEY_BREAK(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event)) {
|
||||
if ((s_copyMode && IS_KEY_EVT(event, KEY_EXIT)) ||
|
||||
event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER) ||
|
||||
event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
_event_ = 0;
|
||||
}
|
||||
|
||||
|
@ -179,7 +204,9 @@ void menuModelSelect(event_t event)
|
|||
s_copyMode = 0;
|
||||
event = EVT_ENTRY_UP;
|
||||
}
|
||||
else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) {
|
||||
else if (event == EVT_KEY_BREAK(KEY_ENTER) ||
|
||||
event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
|
||||
s_copyMode = 0;
|
||||
killEvents(event);
|
||||
if (g_eeGeneral.currModel != sub) {
|
||||
|
@ -232,57 +259,25 @@ void menuModelSelect(event_t event)
|
|||
chainMenu(menuModelSetup);
|
||||
break;
|
||||
#else
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
case EVT_ROTARY_LEFT:
|
||||
case EVT_ROTARY_RIGHT:
|
||||
#endif
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
if ((!IS_ROTARY_RIGHT(event) && !IS_ROTARY_LEFT(event)) || s_editMode < 0) {
|
||||
#endif
|
||||
if (sub == g_eeGeneral.currModel) {
|
||||
chainMenu((IS_ROTARY_RIGHT(event) || event == EVT_KEY_FIRST(KEY_RIGHT)) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1].menuFunc);
|
||||
}
|
||||
else {
|
||||
bool forward = (event == EVT_KEY_FIRST(KEY_RIGHT));
|
||||
chainMenu(forward ? menuModelSetup
|
||||
: menuTabModel[DIM(menuTabModel) - 1].menuFunc);
|
||||
} else {
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
break;
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
#endif
|
||||
}
|
||||
// no break
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && defined(NAVIGATION_X7)
|
||||
case EVT_ROTARY_LEFT:
|
||||
case EVT_ROTARY_RIGHT:
|
||||
#endif
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_REPT(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_REPT(KEY_DOWN):
|
||||
if (s_copyMode) {
|
||||
int8_t next_ofs = s_copyTgtOfs + oldSub - menuVerticalPosition;
|
||||
if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS)
|
||||
next_ofs = 0;
|
||||
|
||||
if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) {
|
||||
s_copySrcRow = oldSub;
|
||||
// find a hole (in the first empty slot above / below)
|
||||
sub = findEmptyModel(s_copySrcRow, IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_DOWN));
|
||||
if (sub < 0) {
|
||||
// no free room for duplicating the model
|
||||
AUDIO_ERROR();
|
||||
sub = oldSub;
|
||||
s_copyMode = 0;
|
||||
if (IS_PREVIOUS_EVENT(event)) {
|
||||
moveToFreeModelSlot(false, sub, oldSub);
|
||||
} else if (IS_NEXT_EVENT(event)) {
|
||||
moveToFreeModelSlot(true, sub, oldSub);
|
||||
}
|
||||
next_ofs = 0;
|
||||
menuVerticalPosition = sub;
|
||||
}
|
||||
s_copyTgtOfs = next_ofs;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(EEPROM)
|
||||
|
@ -295,8 +290,6 @@ void menuModelSelect(event_t event)
|
|||
uint8_t sz = menuSize(menuTabModel, DIM(menuTabModel));
|
||||
#if defined(NAVIGATION_X7)
|
||||
drawScreenIndex(MENU_MODEL_SELECT, sz, 0);
|
||||
#elif defined(ROTARY_ENCODER_NAVIGATION)
|
||||
drawScreenIndex(MENU_MODEL_SELECT, sz, (sub == g_eeGeneral.currModel) ? ((IS_ROTARY_ENCODER_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0);
|
||||
#else
|
||||
drawScreenIndex(MENU_MODEL_SELECT, sz, (sub == g_eeGeneral.currModel) ? INVERS : 0);
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
#include "opentx.h"
|
||||
#include "mixer_scheduler.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "switches.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
|
@ -44,18 +47,16 @@
|
|||
|
||||
uint8_t g_moduleIdx;
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
uint8_t getSwitchWarningsCount()
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (int i=0; i<NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES; ++i) {
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_NAME,
|
||||
|
@ -329,7 +330,7 @@ inline uint8_t TIMER_ROW(uint8_t timer, uint8_t value)
|
|||
return HIDDEN_ROW;
|
||||
}
|
||||
|
||||
#define POT_WARN_ROWS PREFLIGHT_ROW(((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0))
|
||||
#define POT_WARN_ROWS PREFLIGHT_ROW(((g_model.potsWarnMode) ? adcGetMaxInputs(ADC_INPUT_POT) : (uint8_t)0))
|
||||
|
||||
#define TIMER_ROWS(x) \
|
||||
1, TIMER_ROW(x,0), \
|
||||
|
@ -504,14 +505,9 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
|
|||
#define EXTERNAL_MODULE_ROWS
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define WARN_ROWS \
|
||||
#define WARN_ROWS \
|
||||
SW_WARN_ROWS, /* Switch warning */ \
|
||||
POT_WARN_ROWS, /* Pot warning */
|
||||
#else
|
||||
#define WARN_ROWS \
|
||||
PREFLIGHT_ROW((NUM_SWITCHES - 1), /* Switch warning */
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
inline uint8_t USB_JOYSTICK_EXTROW()
|
||||
|
@ -585,7 +581,7 @@ void menuModelSetup(event_t event)
|
|||
PREFLIGHT_ROW(0), // Custom position for throttle warning value
|
||||
WARN_ROWS
|
||||
|
||||
NUM_STICKS + NUM_POTS + NUM_SLIDERS - 1, // Center beeps
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_POT + 1) - 1)), // Center beeps
|
||||
|
||||
0, // ADC Jitter filter
|
||||
|
||||
|
@ -795,7 +791,8 @@ void menuModelSetup(event_t event)
|
|||
{
|
||||
int index = k - ITEM_MODEL_SETUP_SW1;
|
||||
int config = FSWITCH_CONFIG(index);
|
||||
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH + NUM_REGULAR_SWITCHES - MIXSRC_Rud + index + 1, menuHorizontalPosition < 0 ? attr : 0);
|
||||
lcdDrawSizedText(INDENT_WIDTH, y, STR_CHAR_SWITCH, 2, menuHorizontalPosition < 0 ? attr : 0);
|
||||
drawStringWithIndex(lcdNextPos, y, STR_FUNC_SW, index, menuHorizontalPosition < 0 ? attr : 0);
|
||||
if (ZEXIST(g_model.switchNames[index]) || (attr && s_editMode > 0 && menuHorizontalPosition == 0))
|
||||
editName(35, y, g_model.switchNames[index], LEN_SWITCH_NAME, event, menuHorizontalPosition == 0 ? attr : 0, 0, old_editMode);
|
||||
else
|
||||
|
@ -822,7 +819,7 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
}
|
||||
else if (attr && menuHorizontalPosition == 3) { // Non visible checkbox
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -891,7 +888,7 @@ void menuModelSetup(event_t event)
|
|||
if (attr)
|
||||
CHECK_INCDEC_MODELVAR_ZERO_CHECK(
|
||||
event, g_model.thrTraceSrc,
|
||||
NUM_POTS + NUM_SLIDERS + MAX_OUTPUT_CHANNELS,
|
||||
adcGetMaxInputs(ADC_INPUT_POT) + MAX_OUTPUT_CHANNELS,
|
||||
isThrottleSourceAvailable);
|
||||
|
||||
uint8_t idx = throttleSource2Source(g_model.thrTraceSrc);
|
||||
|
@ -907,7 +904,7 @@ void menuModelSetup(event_t event)
|
|||
case ITEM_MODEL_SETUP_THROTTLE_TRIM_SWITCH:
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_TTRIM_SW);
|
||||
if (attr)
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTrimSw, NUM_TRIMS - 1);
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTrimSw, keysGetMaxTrims() - 1);
|
||||
drawSource(MODEL_SETUP_2ND_COLUMN+20, y, g_model.getThrottleStickTrimSource(), attr);
|
||||
break;
|
||||
|
||||
|
@ -939,7 +936,7 @@ void menuModelSetup(event_t event)
|
|||
|
||||
case ITEM_MODEL_SETUP_SWITCHES_WARNING2:
|
||||
if (i==0) {
|
||||
if (CURSOR_MOVED_LEFT(event))
|
||||
if (IS_PREVIOUS_EVENT(event))
|
||||
menuVerticalOffset--;
|
||||
else
|
||||
menuVerticalOffset++;
|
||||
|
@ -948,13 +945,12 @@ void menuModelSetup(event_t event)
|
|||
|
||||
case ITEM_MODEL_SETUP_SWITCHES_WARNING1:
|
||||
{
|
||||
#define FIRSTSW_STR (&STR_VSRCRAW[MIXSRC_FIRST_SWITCH-MIXSRC_FIRST_STICK+1])
|
||||
uint8_t switchWarningsCount = getSwitchWarningsCount();
|
||||
//uint8_t length = STR_VSRCRAW[0];
|
||||
horzpos_t l_posHorz = menuHorizontalPosition;
|
||||
|
||||
if (i>=NUM_BODY_LINES-2 && getSwitchWarningsCount() > MAX_SWITCH_PER_LINE*(NUM_BODY_LINES-i)) {
|
||||
if (CURSOR_MOVED_LEFT(event))
|
||||
if (IS_PREVIOUS_EVENT(event))
|
||||
menuVerticalOffset--;
|
||||
else
|
||||
menuVerticalOffset++;
|
||||
|
@ -987,7 +983,7 @@ void menuModelSetup(event_t event)
|
|||
getMovedSwitch();
|
||||
// Mask switches enabled for warnings
|
||||
swarnstate_t sw_mask = 0;
|
||||
for(uint8_t i=0; i<NUM_SWITCHES; i++) {
|
||||
for(uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i))
|
||||
if (g_model.switchWarningState & (0x07 << (3 * i)))
|
||||
sw_mask |= (0x07 << (3 * i));
|
||||
|
@ -1003,7 +999,7 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
|
||||
int current = 0;
|
||||
for (int i = 0; i < NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES; i++) {
|
||||
for (int i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
div_t qr = div(current, MAX_SWITCH_PER_LINE);
|
||||
if (!READ_ONLY() && event == EVT_KEY_BREAK(KEY_ENTER) && attr &&
|
||||
|
@ -1019,9 +1015,10 @@ void menuModelSetup(event_t event)
|
|||
s_editMode = 0;
|
||||
#endif
|
||||
}
|
||||
lcdDrawSizedText(
|
||||
|
||||
lcdDrawChar(
|
||||
MODEL_SETUP_2ND_COLUMN + qr.rem * ((2 * FW) + 1),
|
||||
y + FH * qr.quot, FIRSTSW_STR[i] + sizeof(STR_CHAR_SWITCH), 1,
|
||||
y + FH * qr.quot, switchGetLetter(i),
|
||||
attr && (menuHorizontalPosition == current) ? INVERS : 0);
|
||||
lcdDrawText(lcdNextPos, y + FH * qr.quot,
|
||||
getSwitchWarnSymbol(states & 0x03));
|
||||
|
@ -1066,30 +1063,38 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
if (g_model.potsWarnMode) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN+28;
|
||||
for (int i=0; i<NUM_POTS+NUM_SLIDERS; ++i) {
|
||||
if (i<NUM_XPOTS && !IS_POT_SLIDER_AVAILABLE(POT1+i)) {
|
||||
if (attr && (menuHorizontalPosition==i+1)) REPEAT_LAST_CURSOR_MOVE();
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
for (int i = 0; i < max_pots; ++i) {
|
||||
|
||||
if (!IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
// skip non configured pot
|
||||
if (attr && (menuHorizontalPosition==i+1)) repeatLastCursorMove(event);
|
||||
}
|
||||
else {
|
||||
LcdFlags flags = ((menuHorizontalPosition==i+1) && attr) ? BLINK : 0;
|
||||
if ((!attr || menuHorizontalPosition >= 0) && (g_model.potsWarnEnabled & (1 << i))) {
|
||||
if ((!attr || menuHorizontalPosition >= 0) &&
|
||||
(g_model.potsWarnEnabled & (1 << i))) {
|
||||
flags |= INVERS;
|
||||
}
|
||||
|
||||
// skip "---" (+1) and source symbol (+2)
|
||||
const char* source = STR_VSRCRAW[NUM_STICKS + 1 + i] + 2;
|
||||
lcdDrawSizedText(x, y, source, UINT8_MAX, flags);
|
||||
lcdDrawText(x, y, getPotLabel(i), flags);
|
||||
x = lcdNextPos+3;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER:
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER: {
|
||||
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
|
||||
for (uint8_t i = 0; i < NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
uint8_t input_max = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_POT);
|
||||
for (uint8_t i = 0; i < input_max; i++) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN + i*FW;
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK | INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) );
|
||||
LcdFlags flags = 0;
|
||||
if ((menuHorizontalPosition == i) && attr)
|
||||
flags = BLINK | INVERS;
|
||||
else if (ANALOG_CENTER_BEEP(x) || (attr && CURSOR_ON_LINE()))
|
||||
flags = INVERS;
|
||||
lcdDrawText(x, y, getAnalogShortLabel(i), flags);
|
||||
}
|
||||
if (attr) {
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
|
@ -1100,7 +1105,7 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USE_JITTER_FILTER:
|
||||
g_model.jitterFilter = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_JITTER_FILTER, STR_ADCFILTERVALUES, g_model.jitterFilter, 0, 2, attr, event);
|
||||
|
@ -1970,7 +1975,7 @@ void menuModelSetup(event_t event)
|
|||
if (isModuleTypeR9MLiteNonPro(module.type)) { // R9M lite FCC has only one power value, so displayed for info only
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_LITE_FCC_POWER_VALUES, 0, LEFT);
|
||||
if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -153,7 +153,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
#if defined(PCBTARANIS)
|
||||
#if defined(PCBXLITE)
|
||||
// ENT LONG on xlite brings up switch type menu, so this menu is activated with SHIFT + ENT LONG
|
||||
if (menuHorizontalPosition==0 && event==EVT_KEY_LONG(KEY_ENTER) && IS_SHIFT_PRESSED() && !READ_ONLY()) {
|
||||
if (menuHorizontalPosition==0 && event==EVT_KEY_LONG(KEY_ENTER) && keysGetState(KEY_SHIFT) && !READ_ONLY()) {
|
||||
#else
|
||||
if (menuHorizontalPosition<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
|
||||
#endif
|
||||
|
@ -203,7 +203,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
|
||||
case 1:
|
||||
if (CFN_SWITCH(cfn)) {
|
||||
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr);
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_2ND_COLUMN, y, funcGetLabel(func), attr);
|
||||
if (active) {
|
||||
CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
|
||||
if (checkIncDec_Ret) CFN_RESET(cfn);
|
||||
|
@ -212,7 +212,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
else {
|
||||
j = 4; // skip other fields
|
||||
if (sub==k && menuHorizontalPosition > 0) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -227,31 +227,31 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
else
|
||||
#endif
|
||||
if (func == FUNC_TRAINER) {
|
||||
maxParam = NUM_STICKS + 1;
|
||||
maxParam = MAX_STICKS + 1;
|
||||
uint8_t param = CFN_CH_INDEX(cfn);
|
||||
if (param == 0)
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_STICKS, attr);
|
||||
else if (param == NUM_STICKS + 1)
|
||||
else if (param == MAX_STICKS + 1)
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_CHANS, attr);
|
||||
else
|
||||
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_Rud + param - 1, attr);
|
||||
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_FIRST_STICK + param - 1, attr);
|
||||
}
|
||||
#if defined(GVARS)
|
||||
else if (func == FUNC_ADJUST_GVAR) {
|
||||
maxParam = MAX_GVARS-1;
|
||||
maxParam = MAX_GVARS - 1;
|
||||
drawStringWithIndex(lcdNextPos + 2, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr);
|
||||
if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags);
|
||||
break;
|
||||
}
|
||||
#endif // GVARS
|
||||
else if (func == FUNC_SET_TIMER) {
|
||||
maxParam = MAX_TIMERS-1;
|
||||
maxParam = MAX_TIMERS - 1;
|
||||
lcdDrawTextAtIndex(lcdNextPos, y, STR_VFSWRESET, CFN_TIMER_INDEX(cfn), attr);
|
||||
if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags);
|
||||
break;
|
||||
}
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam);
|
||||
break;
|
||||
|
@ -406,7 +406,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
}
|
||||
#endif // GVARS
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
#if defined(NAVIGATION_X7)
|
||||
if (active || event==EVT_KEY_LONG(KEY_ENTER)) {
|
||||
|
@ -456,7 +456,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
}
|
||||
}
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -21,175 +21,7 @@
|
|||
|
||||
#include "opentx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define XPOT_DELTA 10
|
||||
#define XPOT_DELAY 10 /* cycles */
|
||||
|
||||
void menuCommonCalib(event_t event)
|
||||
{
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high values for sticks, pots and sliders
|
||||
int16_t vt = anaIn(i);
|
||||
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
|
||||
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
|
||||
if (i >= POT1 && i <= POT_LAST) {
|
||||
if (IS_POT_WITHOUT_DETENT(i)) {
|
||||
reusableBuffer.calib.midVals[i] = (reusableBuffer.calib.hiVals[i] + reusableBuffer.calib.loVals[i]) / 2;
|
||||
}
|
||||
#if defined(PCBTARANIS)
|
||||
uint8_t idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i) && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
// use raw analog value for multipos calibraton, anaIn() already has multipos decoded value
|
||||
vt = getAnalogValue(i) >> 1;
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 ||
|
||||
vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA ||
|
||||
vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastPosition = vt;
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastCount = 1;
|
||||
}
|
||||
else {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255)
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastCount++;
|
||||
}
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == XPOT_DELAY) {
|
||||
int16_t position = reusableBuffer.calib.xpotsCalib[idx].lastPosition;
|
||||
bool found = false;
|
||||
for (int j=0; j<count; j++) {
|
||||
int16_t step = reusableBuffer.calib.xpotsCalib[idx].steps[j];
|
||||
if (position >= step-XPOT_DELTA && position <= step+XPOT_DELTA) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (count < XPOTS_MULTIPOS_COUNT) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].steps[count] = position;
|
||||
}
|
||||
reusableBuffer.calib.xpotsCalib[idx].stepsCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
menuCalibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
|
||||
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
reusableBuffer.calib.state = CALIB_START;
|
||||
break;
|
||||
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
reusableBuffer.calib.state++;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (reusableBuffer.calib.state) {
|
||||
case CALIB_START:
|
||||
// START CALIBRATION
|
||||
if (!READ_ONLY()) {
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUTOSTART);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIB_SET_MIDPOINT:
|
||||
// SET MIDPOINT
|
||||
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
reusableBuffer.calib.loVals[i] = 15000;
|
||||
reusableBuffer.calib.hiVals[i] = -15000;
|
||||
#if defined(PCBTARANIS)
|
||||
#if defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FIRST_ANALOG_ADC_FS) )
|
||||
{
|
||||
reusableBuffer.calib.midVals[i] = anaIn(i);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
|
||||
}
|
||||
if (i<NUM_XPOTS) {
|
||||
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
|
||||
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
|
||||
}
|
||||
#else
|
||||
reusableBuffer.calib.midVals[i] = anaIn(i);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIB_MOVE_STICKS:
|
||||
// MOVE STICKS/POTS
|
||||
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
|
||||
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
|
||||
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
|
||||
g_eeGeneral.calib[i].spanNeg = v - v/STICK_TOLERANCE;
|
||||
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
|
||||
g_eeGeneral.calib[i].spanPos = v - v/STICK_TOLERANCE;
|
||||
}
|
||||
}
|
||||
#if defined(PCBTARANIS)
|
||||
for (uint8_t i=POT1; i<=POT_LAST; i++) {
|
||||
int idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
if (count > 1 && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
for (int j=0; j<count; j++) {
|
||||
for (int k=j+1; k<count; k++) {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].steps[k] < reusableBuffer.calib.xpotsCalib[idx].steps[j]) {
|
||||
SWAP(reusableBuffer.calib.xpotsCalib[idx].steps[j], reusableBuffer.calib.xpotsCalib[idx].steps[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
|
||||
calib->count = count - 1;
|
||||
for (int j=0; j<calib->count; j++) {
|
||||
calib->steps[j] = (reusableBuffer.calib.xpotsCalib[idx].steps[j+1] + reusableBuffer.calib.xpotsCalib[idx].steps[j]) >> 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CALIB_STORE:
|
||||
#if defined(RADIO_BOXER)
|
||||
for (uint8_t i=POT1; i<=POT_LAST; i++) {
|
||||
int idx = i - POT1;
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (count < XPOTS_MULTIPOS_COUNT)
|
||||
{
|
||||
// load 6-pos calib with factory data if 6-pos was not manually calibrated
|
||||
constexpr int16_t factoryValues[]= {0x5,0xd,0x16,0x1f,0x28};
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[POT3];
|
||||
calib->count = 5;
|
||||
for (int j=0; j<calib->count ; j++) {
|
||||
calib->steps[j] = factoryValues[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
g_eeGeneral.chkSum = evalChkSum();
|
||||
storageDirty(EE_GENERAL);
|
||||
reusableBuffer.calib.state = CALIB_FINISHED;
|
||||
break;
|
||||
|
||||
default:
|
||||
reusableBuffer.calib.state = CALIB_START;
|
||||
break;
|
||||
}
|
||||
|
||||
doMainScreenGraphics();
|
||||
}
|
||||
#include "gui/common/stdlcd/calibration.h"
|
||||
|
||||
void menuRadioCalibration(event_t event)
|
||||
{
|
||||
|
|
|
@ -20,18 +20,14 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "../../hal/adc_driver.h"
|
||||
|
||||
#if defined(FLYSKY_GIMBAL)
|
||||
#include "flysky_gimbal_driver.h"
|
||||
#endif
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define HOLDANAVALUEFRAMES 4 /* 4* 50ms = 200 ms update rate */
|
||||
|
||||
void menuRadioDiagAnalogs(event_t event)
|
||||
{
|
||||
static int8_t entryCount = 0;
|
||||
static int16_t lastShownAnalogValue[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
|
||||
static uint16_t lastShownAnalogValue[MAX_ANALOG_INPUTS];
|
||||
|
||||
enum ANAVIEWS{
|
||||
ANAVIEW_FIRST,
|
||||
|
@ -50,12 +46,9 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
#endif
|
||||
|
||||
switch (event) {
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
#if defined(KEYS_GPIO_REG_PAGEDN)
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
case EVT_KEY_BREAK(KEY_PAGEDN):
|
||||
#elif defined(NAVIGATION_X7)
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
#endif
|
||||
{
|
||||
if (viewpage == ANAVIEW_LAST)
|
||||
viewpage = ANAVIEW_FIRST;
|
||||
|
@ -65,12 +58,9 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
break;
|
||||
}
|
||||
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
#if defined(KEYS_GPIO_REG_PAGEUP)
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
case EVT_KEY_BREAK(KEY_PAGEUP):
|
||||
#elif defined(NAVIGATION_X7)
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
#endif
|
||||
{
|
||||
if (viewpage == ANAVIEW_FIRST)
|
||||
viewpage = ANAVIEW_LAST;
|
||||
|
@ -94,10 +84,10 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1;
|
||||
|
||||
lcdDrawTextAlignedLeft(y, STICKS_PWM_ENABLED() ? STR_PWM_STICKS_POTS_SLIDERS
|
||||
: STR_STICKS_POTS_SLIDERS);
|
||||
lcdDrawTextAlignedLeft(y, STR_STICKS_POTS_SLIDERS);
|
||||
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
for (uint8_t i = 0; i < adcGetMaxInputs(ADC_INPUT_ALL); i++) {
|
||||
// TODO: if available
|
||||
uint8_t x;
|
||||
if (i & 1) {
|
||||
x = LCD_W / 2 + INDENT_WIDTH;
|
||||
|
@ -110,16 +100,8 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
switch (viewpage) {
|
||||
case (ANAVIEW_RAWLOWFPS):
|
||||
if (entryCount == 0) {
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && i < FIRST_ANALOG_ADC_FS)
|
||||
{
|
||||
lastShownAnalogValue[i] = hall_raw_values[i];
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
lastShownAnalogValue[i] = getAnalogValue(i); // Update value
|
||||
}
|
||||
}
|
||||
lcdDrawNumber(x+3*FW-1, y, lastShownAnalogValue[i],
|
||||
LEADING0|LEFT, 4);
|
||||
break;
|
||||
|
@ -129,7 +111,7 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
break;
|
||||
}
|
||||
lcdDrawNumber(x+10*FW-1, y,
|
||||
(int16_t)calibratedAnalogs[CONVERT_MODE(i)]*25/256,
|
||||
(int16_t)calibratedAnalogs[i]*25/256,
|
||||
RIGHT);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,18 +20,56 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/key_driver.h"
|
||||
#include "switches.h"
|
||||
|
||||
void displayKeyState(uint8_t x, uint8_t y, uint8_t key)
|
||||
{
|
||||
uint8_t t = keys[key].state();
|
||||
uint8_t t = keysGetState(key);
|
||||
lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
|
||||
}
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
void displaySwitchState(uint8_t x, uint8_t y, uint8_t sw)
|
||||
void displayTrimState(uint8_t x, uint8_t y, uint8_t trim)
|
||||
{
|
||||
swsrc_t t = switchState(sw);
|
||||
lcdDrawChar(x, y, (t ? '1' : '0'), t ? INVERS : 0);
|
||||
uint8_t t = keysGetTrimState(trim);
|
||||
lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
|
||||
}
|
||||
|
||||
static EnumKeys get_ith_key(uint8_t i)
|
||||
{
|
||||
auto supported_keys = keysGetSupported();
|
||||
for (uint8_t k = 0; k < MAX_KEYS; k++) {
|
||||
if (supported_keys & (1 << k)) {
|
||||
if (i-- == 0) return (EnumKeys)k;
|
||||
}
|
||||
}
|
||||
|
||||
// should not get here,
|
||||
// we assume: i < keysGetMaxKeys()
|
||||
return (EnumKeys)0;
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
void menuRadioDiagFS(event_t event)
|
||||
{
|
||||
constexpr coord_t FS_1ST_COLUMN = 40;
|
||||
constexpr coord_t FS_2ND_COLUMN = 70;
|
||||
constexpr coord_t FS_3RD_COLUMN = 100;
|
||||
SIMPLE_SUBMENU(STR_MENU_FSWITCH, 1);
|
||||
lcdDrawText(FS_1ST_COLUMN, MENU_HEADER_HEIGHT + 1, "Phys");
|
||||
lcdDrawText(FS_2ND_COLUMN, MENU_HEADER_HEIGHT + 1, "Log");
|
||||
lcdDrawText(FS_3RD_COLUMN, MENU_HEADER_HEIGHT + 1, "Led");
|
||||
|
||||
for(uint8_t i=0; i < NUM_FUNCTIONS_SWITCHES; i++) {
|
||||
coord_t y = 2*FH + i*FH;
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_CHAR_SWITCH, 0);
|
||||
lcdDrawText(lcdNextPos, y, switchGetName(i+switchGetMaxSwitches()), 0);
|
||||
lcdDrawNumber(FS_1ST_COLUMN + 2, y, getFSPhysicalState(i));
|
||||
lcdDrawNumber(FS_2ND_COLUMN + 5, y, getFSLogicalState(i));
|
||||
lcdDrawNumber(FS_3RD_COLUMN + 5, y, getFSLedState(i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -41,62 +79,50 @@ void menuRadioDiagKeys(event_t event)
|
|||
|
||||
lcdDrawText(14*FW, MENU_HEADER_HEIGHT + 1, STR_VTRIM);
|
||||
|
||||
for (uint8_t i=0; i<10; i++) {
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
coord_t y;
|
||||
|
||||
if (i < NUM_TRIMS_KEYS) {
|
||||
y = MENU_HEADER_HEIGHT + 1 + FH + FH*(i/2);
|
||||
if (i&1) lcdDraw1bitBitmap(14*FW, y, sticks, i/2, 0);
|
||||
displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
|
||||
if (i < keysGetMaxTrims() * 2) {
|
||||
y = MENU_HEADER_HEIGHT + 1 + FH + FH * (i / 2);
|
||||
if (i & 1) lcdDraw1bitBitmap(14 * FW, y, sticks, i / 2, 0);
|
||||
displayTrimState(i & 1 ? 20 * FW : 18 * FW, y, i);
|
||||
}
|
||||
|
||||
if (i <= KEY_MAX) {
|
||||
if (i == 7) { // T8 8th key???
|
||||
if (i < keysGetMaxKeys()) {
|
||||
auto k = get_ith_key(i);
|
||||
if (i >= 7) { // max 7 lines on display
|
||||
y = MENU_HEADER_HEIGHT + 1 + FH * 6;
|
||||
lcdDrawTextAtIndex(8, y, STR_VKEYS, i, 0);
|
||||
lcdDrawText(8, y, keysGetLabel(k), 0);
|
||||
displayKeyState(lcdNextPos + 10, y, i);
|
||||
}
|
||||
else {
|
||||
y = MENU_HEADER_HEIGHT + 1 + FH * i;
|
||||
lcdDrawTextAtIndex(0, y, STR_VKEYS, i, 0);
|
||||
lcdDrawText(0, y, keysGetLabel(k), 0);
|
||||
displayKeyState(5 * FW + 2, y, i);
|
||||
}
|
||||
}
|
||||
|
||||
#if (NUM_SWITCHES > 6)
|
||||
if (i < NUM_SWITCHES) {
|
||||
if (i < switchGetMaxSwitches()) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
y = (i > 4) ? FH*(i-4)+1 : MENU_HEADER_HEIGHT + FH*i + 1;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
|
||||
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
|
||||
drawSwitch(i > 4 ? 11*FW-5: 8*FW-9, y, sw, 0, false);
|
||||
y = (i > 4) ? FH * (i - 4) + 1 : MENU_HEADER_HEIGHT + FH * i + 1;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw =
|
||||
((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(i > 4 ? 11 * FW - 5 : 8 * FW - 9, y, sw, 0, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (i < NUM_SWITCHES) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
y = (NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES > 6 ? 0 : MENU_HEADER_HEIGHT) + FH*i;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
|
||||
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
|
||||
drawSwitch(8*FW+4, y, sw, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES) && defined(DEBUG)
|
||||
lcdDrawText(LCD_W / 2 , LCD_H - 2 * FH, "Phys");
|
||||
lcdDrawText(LCD_W / 2 , LCD_H - 1 * FH, "Log");
|
||||
|
||||
for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) {
|
||||
lcdDrawNumber(LCD_W / 2 + 20 + (i + 1) * FW , LCD_H - 2 * FH, getFSPhysicalState(i));
|
||||
lcdDrawNumber(LCD_W / 2 + 20 + (i + 1) * FW , LCD_H - 1 * FH, getFSLogicalState(i));
|
||||
}
|
||||
#if defined(AUTOSWITCH)
|
||||
lcdDrawText(13*FW+FWNUM, LCD_H - FH + 1,"Last");
|
||||
swsrc_t swtch = getMovedSwitch();
|
||||
if (swtch)
|
||||
drawSwitch(17*FW+FWNUM+2, LCD_H - FH + 1, swtch, 0);
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
coord_t y = LCD_H - FH + 1;
|
||||
lcdDrawText(8*FW-9, y, STR_ROTARY_ENCODER);
|
||||
lcdDrawNumber(12*FW+FWNUM+2, y, rotencValue / ROTARY_ENCODER_GRANULARITY, RIGHT);
|
||||
lcdDrawNumber(12*FW+FWNUM+2, y, rotaryEncoderGetValue(), RIGHT);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "opentx.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
const unsigned char sticks[] = {
|
||||
#include "sticks.lbm"
|
||||
|
@ -48,6 +50,12 @@ const unsigned char sticks[] = {
|
|||
#define CASE_BATTGRAPH(x)
|
||||
#endif
|
||||
|
||||
#if !defined(SURFACE_RTADIO)
|
||||
#define CASE_TX_MODE(x) x,
|
||||
#else
|
||||
#define CASE_TX_MODE(x)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CASE_RTCLOCK(ITEM_RADIO_SETUP_DATE)
|
||||
CASE_RTCLOCK(ITEM_RADIO_SETUP_TIME)
|
||||
|
@ -104,8 +112,10 @@ enum {
|
|||
CASE_JACK_DETECT(ITEM_RADIO_SETUP_JACK_MODE)
|
||||
ITEM_RADIO_SETUP_RX_CHANNEL_ORD,
|
||||
CASE_ROTARY_ENCODER(ITEM_RADIO_SETUP_ROTARY_ENC_MODE)
|
||||
#if !defined(SURFACE_RADIO)
|
||||
ITEM_RADIO_SETUP_STICK_MODE_LABELS,
|
||||
ITEM_RADIO_SETUP_STICK_MODE,
|
||||
#endif
|
||||
ITEM_VIEW_OPTIONS_LABEL,
|
||||
ITEM_VIEW_OPTIONS_RADIO_TAB,
|
||||
ITEM_VIEW_OPTIONS_GF,
|
||||
|
@ -121,12 +131,6 @@ enum {
|
|||
ITEM_RADIO_SETUP_MAX
|
||||
};
|
||||
|
||||
#if defined(FRSKY_STICKS) && !defined(PCBTARANIS)
|
||||
#define COL_TX_MODE 0
|
||||
#else
|
||||
#define COL_TX_MODE LABEL(TX_MODE)
|
||||
#endif
|
||||
|
||||
uint8_t viewOptCheckBox(coord_t y, const char* title, uint8_t value, uint8_t attr, event_t event)
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH, y, title);
|
||||
|
@ -139,9 +143,11 @@ void menuRadioSetup(event_t event)
|
|||
struct gtm t;
|
||||
gettime(&t);
|
||||
|
||||
if ((menuVerticalPosition==ITEM_RADIO_SETUP_DATE+HEADER_LINE || menuVerticalPosition==ITEM_RADIO_SETUP_TIME+HEADER_LINE) &&
|
||||
(s_editMode>0) &&
|
||||
(event==EVT_KEY_FIRST(KEY_ENTER) || event==EVT_KEY_FIRST(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event))) {
|
||||
if ((menuVerticalPosition == ITEM_RADIO_SETUP_DATE + HEADER_LINE ||
|
||||
menuVerticalPosition == ITEM_RADIO_SETUP_TIME + HEADER_LINE) &&
|
||||
(s_editMode > 0) &&
|
||||
(event == EVT_KEY_FIRST(KEY_ENTER) || event == EVT_KEY_LONG(KEY_ENTER) ||
|
||||
event == EVT_KEY_FIRST(KEY_EXIT))) {
|
||||
// set the date and time into RTC chip
|
||||
rtcSetTime(&t);
|
||||
}
|
||||
|
@ -198,7 +204,9 @@ void menuRadioSetup(event_t event)
|
|||
0, // USB mode
|
||||
CASE_JACK_DETECT(0) // Jack mode
|
||||
CASE_ROTARY_ENCODER(0)
|
||||
0, COL_TX_MODE, 0,
|
||||
0,
|
||||
CASE_TX_MODE(LABEL(TX_MODE))
|
||||
CASE_TX_MODE(0)
|
||||
LABEL(ViewOptions), LABEL(RadioMenuTabs), 0, 0, LABEL(ModelMenuTabs), CASE_HELI(0) CASE_FLIGHT_MODES(0) 0, 0, 0, CASE_LUA_MODEL_SCRIPTS(0) 0,
|
||||
1/*to force edit mode*/});
|
||||
|
||||
|
@ -661,31 +669,47 @@ void menuRadioSetup(event_t event)
|
|||
|
||||
case ITEM_RADIO_SETUP_RX_CHANNEL_ORD:
|
||||
lcdDrawTextAlignedLeft(y, STR_DEF_CHAN_ORD); // RAET->AETR
|
||||
for (uint8_t i=1; i<=4; i++) {
|
||||
putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, channelOrder(i), attr);
|
||||
{
|
||||
for (uint8_t i = 0; i < adcGetMaxInputs(ADC_INPUT_MAIN); i++) {
|
||||
putsChnLetter(RADIO_SETUP_2ND_COLUMN + i*FW, y, inputMappingChannelOrder(i), attr);
|
||||
}
|
||||
if (attr) {
|
||||
auto max_order = inputMappingGetMaxChannelOrder() - 1;
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, max_order);
|
||||
}
|
||||
}
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23);
|
||||
break;
|
||||
|
||||
#if !defined(SURFACE_RADIO)
|
||||
case ITEM_RADIO_SETUP_STICK_MODE_LABELS:
|
||||
lcdDrawTextAlignedLeft(y, STR_MODE);
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
lcdDraw1bitBitmap(5*FW+i*(4*FW+2), y, sticks, i, 0);
|
||||
#if defined(FRSKY_STICKS) && !defined(PCBTARANIS)
|
||||
if (g_eeGeneral.stickReverse & (1<<i)) {
|
||||
lcdDrawFilledRect(5*FW+i*(4*FW+2), y, 3*FW, FH-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if defined(FRSKY_STICKS) && !defined(PCBTARANIS)
|
||||
if (attr) {
|
||||
s_editMode = 0;
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickReverse, 0, 15);
|
||||
lcdDrawRect(5*FW-1, y-1, 16*FW+2, 9);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ITEM_RADIO_SETUP_STICK_MODE:
|
||||
lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr);
|
||||
{
|
||||
auto controls = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto mode = reusableBuffer.generalSettings.stickMode;
|
||||
for (uint8_t i = 0; i < controls; i++) {
|
||||
source_t src = MIXSRC_FIRST_STICK + inputMappingConvertMode(mode, i);
|
||||
drawSource((5 * FW - 3) + i * (4 * FW + 2), y, src, 0);
|
||||
}
|
||||
}
|
||||
if (attr && s_editMode > 0) {
|
||||
CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3);
|
||||
} else if (reusableBuffer.generalSettings.stickMode !=
|
||||
g_eeGeneral.stickMode) {
|
||||
mixerTaskStop();
|
||||
g_eeGeneral.stickMode = reusableBuffer.generalSettings.stickMode;
|
||||
checkThrottleStick();
|
||||
mixerTaskStart();
|
||||
waitKeysReleased();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
case ITEM_RADIO_SETUP_ROTARY_ENC_MODE:
|
||||
lcdDrawTextAlignedLeft(y, STR_ROTARY_ENC_MODE);
|
||||
|
@ -705,23 +729,6 @@ void menuRadioSetup(event_t event)
|
|||
break;
|
||||
#endif
|
||||
|
||||
case ITEM_RADIO_SETUP_STICK_MODE:
|
||||
lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr);
|
||||
for (uint8_t i=0; i<NUM_STICKS; i++) {
|
||||
drawSource((5*FW-3)+i*(4*FW+2), y, MIXSRC_Rud + *(modn12x3 + 4*reusableBuffer.generalSettings.stickMode + i), 0);
|
||||
}
|
||||
if (attr && s_editMode>0) {
|
||||
CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3);
|
||||
}
|
||||
else if (reusableBuffer.generalSettings.stickMode != g_eeGeneral.stickMode) {
|
||||
mixerTaskStop();
|
||||
g_eeGeneral.stickMode = reusableBuffer.generalSettings.stickMode;
|
||||
checkThrottleStick();
|
||||
mixerTaskStart();
|
||||
waitKeysReleased();
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_VIEW_OPTIONS_LABEL:
|
||||
lcdDrawTextAlignedLeft(y, STR_ENABLED_FEATURES);
|
||||
break;
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
#include "switches.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#define BIGSIZE DBLSIZE
|
||||
#if defined (PCBTARANIS)
|
||||
|
@ -76,38 +81,58 @@ void drawExternalAntennaAndRSSI()
|
|||
|
||||
void drawPotsBars()
|
||||
{
|
||||
// Optimization by Mike Blandford
|
||||
for (uint8_t x = LCD_W / 2 - (NUM_POTS + NUM_SLIDERS - 1) * 5 / 2 - 1, i = NUM_STICKS; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; x += 5, i++) {
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t configured_pots = 0;
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
if (IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
uint8_t len = ((calibratedAnalogs[i] + RESX) * BAR_HEIGHT / (RESX * 2)) + 1l; // calculate once per loop
|
||||
V_BAR(x, LCD_H - 8, len);
|
||||
configured_pots ++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t lines = configured_pots > 3 ? 2 : 1;
|
||||
uint8_t cols = configured_pots > 4 ? 3 : configured_pots % 2 ? 3 : 2;
|
||||
coord_t xstart = LCD_W / 2 - (cols % 2 ? 5 : 3);
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
if (IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
coord_t x = xstart + (i % cols) * 5;
|
||||
coord_t y = i >= cols ? (LCD_H - 8 - BAR_HEIGHT / 2) : (LCD_H - 8);
|
||||
auto v = calibratedAnalogs[offset + i] + RESX;
|
||||
uint8_t len = (v * BAR_HEIGHT / (RESX * 2 * lines)) + 1l;
|
||||
V_BAR(x, y, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void doMainScreenGraphics()
|
||||
{
|
||||
int16_t calibStickVert = calibratedAnalogs[CONVERT_MODE(1)];
|
||||
if (g_model.throttleReversed && CONVERT_MODE(1) == THR_STICK)
|
||||
#if defined(SURFACE_RADIO)
|
||||
drawWheel(LBOX_CENTERX, calibratedAnalogs[ADC_MAIN_ST]);
|
||||
drawThrottle(RBOX_CENTERX, calibratedAnalogs[ADC_MAIN_TH]);
|
||||
#else
|
||||
int16_t calibStickVert = calibratedAnalogs[ADC_MAIN_LV];
|
||||
if (g_model.throttleReversed && inputMappingConvertMode(ADC_MAIN_LV) == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
drawStick(LBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(0)], calibStickVert);
|
||||
drawStick(LBOX_CENTERX, calibratedAnalogs[ADC_MAIN_LH], calibStickVert);
|
||||
|
||||
calibStickVert = calibratedAnalogs[CONVERT_MODE(2)];
|
||||
if (g_model.throttleReversed && CONVERT_MODE(2) == THR_STICK)
|
||||
calibStickVert = calibratedAnalogs[ADC_MAIN_RV];
|
||||
if (g_model.throttleReversed && inputMappingConvertMode(ADC_MAIN_RV) == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
drawStick(RBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(3)], calibStickVert);
|
||||
#if defined(HARDWARE_POT1)
|
||||
drawPotsBars();
|
||||
drawStick(RBOX_CENTERX, calibratedAnalogs[ADC_MAIN_RH], calibStickVert);
|
||||
#endif
|
||||
|
||||
drawPotsBars();
|
||||
}
|
||||
|
||||
void displayTrims(uint8_t phase)
|
||||
{
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
static coord_t x[4] = {TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X};
|
||||
static uint8_t vert[4] = {0, 1, 1, 0};
|
||||
for (uint8_t i = 0; i < keysGetMaxTrims(); i++) {
|
||||
static coord_t x[] = {TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X, TRIM_LH_X, TRIM_LV_X, TRIM_RH_X, TRIM_RV_X};
|
||||
static uint8_t vert[] = {0, 1, 1, 0, 0, 1, 0, 1};
|
||||
coord_t xm, ym;
|
||||
uint8_t stickIndex = CONVERT_MODE(i);
|
||||
uint8_t stickIndex = inputMappingConvertMode(i);
|
||||
xm = x[stickIndex];
|
||||
uint8_t att = ROUND;
|
||||
int16_t val = getTrimValue(phase, i);
|
||||
|
@ -132,7 +157,9 @@ void displayTrims(uint8_t phase)
|
|||
|
||||
if (vert[i]) {
|
||||
ym = 31;
|
||||
if (i < 4)
|
||||
lcdDrawSolidVerticalLine(xm, ym - TRIM_LEN, TRIM_LEN * 2 + 1);
|
||||
if (keysGetMaxTrims() <= 4) {
|
||||
if (i != 2 || !g_model.thrTrim) {
|
||||
lcdDrawSolidVerticalLine(xm - 1, ym - 1, 3);
|
||||
lcdDrawSolidVerticalLine(xm + 1, ym - 1, 3);
|
||||
|
@ -149,14 +176,33 @@ void displayTrims(uint8_t phase)
|
|||
lcdDrawSolidHorizontalLine(xm - 1, ym, 3);
|
||||
}
|
||||
if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) {
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1 << i)))) {
|
||||
lcdDrawNumber(dir > 0 ? 12 : 40, xm - 2, -abs(dir), TINSIZE | VERTICAL);
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS ||
|
||||
(trimsDisplayTimer > 0 && (trimsDisplayMask & (1 << i)))) {
|
||||
lcdDrawNumber(dir > 0 ? 12 : 40, xm - 2, -abs(dir),
|
||||
TINSIZE | VERTICAL);
|
||||
}
|
||||
}
|
||||
lcdDrawSquare(xm - 3, ym - 3, 7, att);
|
||||
}
|
||||
else {
|
||||
ym -= val;
|
||||
if ((i > 4 && xm < LCD_W / 2) || (i < 4 && xm > LCD_W / 2) ) {
|
||||
lcdDrawSolidVerticalLine(xm - 1, ym, 1);
|
||||
lcdDrawSolidVerticalLine(xm - 2, ym - 1, 3);
|
||||
lcdDrawSolidVerticalLine(xm - 3, ym - 2, 5);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidVerticalLine(xm + 1, ym, 1);
|
||||
lcdDrawSolidVerticalLine(xm + 2, ym - 1, 3);
|
||||
lcdDrawSolidVerticalLine(xm + 3, ym - 2, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ym = 60;
|
||||
if (i < 4)
|
||||
lcdDrawSolidHorizontalLine(xm - TRIM_LEN, ym, TRIM_LEN * 2 + 1);
|
||||
if (keysGetMaxTrims() <= 4) {
|
||||
lcdDrawSolidHorizontalLine(xm - 1, ym - 1, 3);
|
||||
lcdDrawSolidHorizontalLine(xm - 1, ym + 1, 3);
|
||||
xm += val;
|
||||
|
@ -171,13 +217,32 @@ void displayTrims(uint8_t phase)
|
|||
lcdDrawSolidVerticalLine(xm, ym - 1, 3);
|
||||
}
|
||||
if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) {
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1 << i)))) {
|
||||
lcdDrawNumber((stickIndex == 0 ? (dir > 0 ? TRIM_LH_POS : TRIM_LH_NEG) : (dir > 0 ? TRIM_RH_POS : TRIM_RH_NEG)), ym - 2, -abs(dir), TINSIZE);
|
||||
}
|
||||
if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS ||
|
||||
(trimsDisplayTimer > 0 && (trimsDisplayMask & (1 << i)))) {
|
||||
lcdDrawNumber(
|
||||
(stickIndex == 0 ? (dir > 0 ? TRIM_LH_POS : TRIM_LH_NEG)
|
||||
: (dir > 0 ? TRIM_RH_POS : TRIM_RH_NEG)),
|
||||
ym - 2, -abs(dir), TINSIZE);
|
||||
}
|
||||
}
|
||||
lcdDrawSquare(xm - 3, ym - 3, 7, att);
|
||||
}
|
||||
else {
|
||||
xm += val;
|
||||
if (i > 3) {
|
||||
lcdDrawSolidHorizontalLine(xm, ym + 1, 1);
|
||||
lcdDrawSolidHorizontalLine(xm - 1, ym + 2, 3);
|
||||
lcdDrawSolidHorizontalLine(xm - 2, ym + 3, 5);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidHorizontalLine(xm, ym - 1, 1);
|
||||
lcdDrawSolidHorizontalLine(xm - 1, ym - 2, 3);
|
||||
lcdDrawSolidHorizontalLine(xm - 2, ym - 3, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void displayBattVoltage()
|
||||
|
@ -491,64 +556,46 @@ void menuMainView(event_t event)
|
|||
doMainScreenGraphics();
|
||||
|
||||
// Switches
|
||||
#if defined(PCBX9LITES)
|
||||
static const uint8_t x[NUM_SWITCHES-2] = {2*FW-2, 2*FW-2, 17*FW+1, 2*FW-2, 17*FW+1};
|
||||
static const uint8_t y[NUM_SWITCHES-2] = {4*FH+1, 5*FH+1, 5*FH+1, 6*FH+1, 6*FH+1};
|
||||
for (int i=0; i<NUM_SWITCHES - 2; ++i) {
|
||||
// -> 2 columns: one for each side
|
||||
// -> 4 slots on each side (3 normal / 1 small)
|
||||
uint8_t switches = switchGetMaxSwitches();
|
||||
uint8_t configured_switches = 0;
|
||||
|
||||
for (uint8_t i = 0; i < switches; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(x[i], y[i], sw, 0, false);
|
||||
configured_switches ++;
|
||||
}
|
||||
}
|
||||
drawSmallSwitch(29, 5*FH+1, 4, SW_SF);
|
||||
drawSmallSwitch(16*FW+1, 5*FH+1, 4, SW_SG);
|
||||
#elif defined(PCBX9LITE)
|
||||
static const uint8_t x[NUM_SWITCHES] = {2 * FW - 2, 2 * FW - 2, 16 * FW + 1, 2 * FW - 2, 16 * FW + 1};
|
||||
static const uint8_t y[NUM_SWITCHES] = {4 * FH + 1, 5 * FH + 1, 5 * FH + 1, 6 * FH + 1, 6 * FH + 1};
|
||||
for (int i = 0; i < NUM_SWITCHES; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(x[i], y[i], sw, 0, false);
|
||||
}
|
||||
}
|
||||
#elif defined(PCBXLITES)
|
||||
static const uint8_t x[NUM_SWITCHES] = {2*FW-2, 16*FW+1, 2*FW-2, 16*FW+1, 2*FW-2, 16*FW+1};
|
||||
static const uint8_t y[NUM_SWITCHES] = {4*FH+1, 4*FH+1, 6*FH+1, 6*FH+1, 5*FH+1, 5*FH+1};
|
||||
for (int i=0; i<NUM_SWITCHES; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(x[i], y[i], sw, 0, false);
|
||||
}
|
||||
}
|
||||
#elif defined(PCBTARANIS)
|
||||
uint8_t switches = min(NUM_SWITCHES- NUM_FUNCTIONS_SWITCHES, 6);
|
||||
|
||||
if (configured_switches < 9) {
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
uint8_t x = 2 * FW - 2, y = 4 * FH + i * FH + 1;
|
||||
if (i >= switches / 2) {
|
||||
x = 16 * FW + 1;
|
||||
y -= (switches / 2) * FH;
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.row >= 3) {
|
||||
drawSmallSwitch(switch_display.col == 0 ? 28 : 16 * FW + 1,
|
||||
5 * FH + 1, 4, i);
|
||||
}
|
||||
else {
|
||||
coord_t x = switch_display.col == 0 ? 2 * FW - 2 : 16 * FW + 7;
|
||||
coord_t y = 33 + switch_display.row * FH;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
getvalue_t sw =
|
||||
((val < 0) ? 3 * i + 1
|
||||
: ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(x, y, sw, 0, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// The ID0 3-POS switch is merged with the TRN switch
|
||||
for (uint8_t i = SWSRC_THR; i <= SWSRC_TRN; i++) {
|
||||
int8_t sw = (i == SWSRC_TRN ? (switchState(SW_ID0) ? SWSRC_ID0 : (switchState(SW_ID1) ? SWSRC_ID1 : SWSRC_ID2)) : i);
|
||||
uint8_t x = 2 * FW - 2, y = i * FH + 1;
|
||||
if (i >= SWSRC_AIL) {
|
||||
x = 17 * FW - 1;
|
||||
y -= 3 * FH;
|
||||
}
|
||||
drawSwitch(x, y, sw, getSwitch(i) ? INVERS : 0, false);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
coord_t x = (switch_display.col == 0 ? 8 : 96) + switch_display.row * 5;
|
||||
drawSmallSwitch(x, 5 * FH + 1, 4, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Logical Switches
|
||||
|
@ -556,7 +603,7 @@ void menuMainView(event_t event)
|
|||
uint8_t y = LCD_H - 20;
|
||||
for (uint8_t line = 0; line < 2; line++) {
|
||||
for (uint8_t column = 0; column < MAX_LOGICAL_SWITCHES / 2; column++) {
|
||||
int8_t len = getSwitch(SWSRC_SW1 + index) ? 10 : 1;
|
||||
int8_t len = getSwitch(SWSRC_FIRST_LOGICAL_SWITCH + index) ? 10 : 1;
|
||||
uint8_t x = (16 + 3 * column);
|
||||
lcdDrawSolidVerticalLine(x - 1, y - len, len);
|
||||
lcdDrawSolidVerticalLine(x, y - len, len);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "opentx.h"
|
||||
#include "tasks.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
#include "bluetooth_driver.h"
|
||||
#endif
|
||||
|
@ -60,9 +62,6 @@ void menuStatisticsView(event_t event)
|
|||
#endif
|
||||
break;
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
case EVT_KEY_LONG(KEY_MENU): // historical
|
||||
#endif
|
||||
case EVT_KEY_LONG(KEY_ENTER):
|
||||
g_eeGeneral.globalTimer = 0;
|
||||
storageDirty(EE_GENERAL);
|
||||
|
|
|
@ -21,6 +21,34 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
// For surface radio
|
||||
void drawWheel(coord_t centrex, int16_t tval)
|
||||
{
|
||||
constexpr coord_t BOX_CENTERY = (LCD_H - 9 - BOX_WIDTH / 2);
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidHorizontalLine(centrex - MARKER_WIDTH /2 , BOX_CENTERY, MARKER_WIDTH);
|
||||
coord_t x1 = centrex - MARKER_WIDTH - tval / 300;
|
||||
coord_t x2 = centrex - MARKER_WIDTH + tval / 300;
|
||||
lcdDrawLine( x1, BOX_CENTERY+BOX_WIDTH / MARKER_WIDTH, x2, BOX_CENTERY-BOX_WIDTH / MARKER_WIDTH, SOLID, FORCE);
|
||||
lcdDrawLine( x1 + BOX_WIDTH/2, BOX_CENTERY+BOX_WIDTH / MARKER_WIDTH,
|
||||
x2 + BOX_WIDTH / 2, BOX_CENTERY-BOX_WIDTH / MARKER_WIDTH, SOLID, FORCE);
|
||||
#undef BOX_CENTERY
|
||||
#undef MARKER_WIDTH
|
||||
}
|
||||
|
||||
// For surface radio
|
||||
void drawThrottle(coord_t centrex, int16_t wval)
|
||||
{
|
||||
constexpr coord_t BOX_CENTERY = (LCD_H - 9 - BOX_WIDTH / 2);
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidHorizontalLine(centrex - MARKER_WIDTH, BOX_CENTERY, 2 * MARKER_WIDTH + 1);
|
||||
coord_t tsize = wval / 150;
|
||||
lcdDrawLine( centrex - tsize, BOX_CENTERY, centrex, BOX_CENTERY + tsize, SOLID, FORCE);
|
||||
lcdDrawLine( centrex + tsize, BOX_CENTERY, centrex, BOX_CENTERY + tsize, SOLID, FORCE);
|
||||
}
|
||||
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
|
||||
{
|
||||
#define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "lcd.h"
|
||||
#include "menus.h"
|
||||
#include "popups.h"
|
||||
|
||||
#include "navigation/navigation.h"
|
||||
#include "common/stdlcd/draw_functions.h"
|
||||
|
||||
#define HEADER_LINE 0
|
||||
|
@ -76,153 +78,45 @@ void showAlertBox(const char * title, const char * text, const char * action, ui
|
|||
|
||||
void doMainScreenGraphics();
|
||||
|
||||
extern int8_t checkIncDec_Ret; // global helper vars
|
||||
|
||||
#define EDIT_SELECT_FIELD 0
|
||||
#define EDIT_MODIFY_FIELD 1
|
||||
#define EDIT_MODIFY_STRING 2
|
||||
extern int8_t s_editMode; // global editmode
|
||||
|
||||
// checkIncDec flags
|
||||
// we leave room for EE_MODEL and EE_GENERAL
|
||||
#define NO_INCDEC_MARKS 0x04
|
||||
#define INCDEC_SWITCH 0x08
|
||||
#define INCDEC_SOURCE 0x10
|
||||
#define INCDEC_REP10 0x40
|
||||
#define NO_DBLKEYS 0x80
|
||||
|
||||
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = nullptr
|
||||
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
|
||||
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
|
||||
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
|
||||
|
||||
struct CheckIncDecStops
|
||||
{
|
||||
const int count;
|
||||
const int stops[];
|
||||
int min() const
|
||||
{
|
||||
return stops[0];
|
||||
}
|
||||
int max() const
|
||||
{
|
||||
return stops[count-1];
|
||||
}
|
||||
bool contains(int value) const
|
||||
{
|
||||
for (int i=0; i<count; ++i) {
|
||||
int stop = stops[i];
|
||||
if (value == stop)
|
||||
return true;
|
||||
else if (value < stop)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
extern const CheckIncDecStops &stops100;
|
||||
extern const CheckIncDecStops &stops1000;
|
||||
extern const CheckIncDecStops &stopsSwitch;
|
||||
|
||||
#define INIT_STOPS(var, ...) \
|
||||
const int _ ## var[] = { __VA_ARGS__ }; \
|
||||
const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
|
||||
#define CATEGORY_END(val) \
|
||||
(val), (val+1)
|
||||
|
||||
int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=nullptr, const CheckIncDecStops &stops=stops100);
|
||||
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
|
||||
#define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
|
||||
#define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR(event, var, min, max) \
|
||||
var = checkIncDecModel(event, var, min, max)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
|
||||
var = checkIncDecModelZero(event, var, max)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
|
||||
var = checkIncDec(event, var, min, max, EE_MODEL, check)
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
|
||||
var = checkIncDec(event, var, 0, max, EE_MODEL, check)
|
||||
|
||||
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
|
||||
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
|
||||
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
|
||||
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
|
||||
|
||||
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
|
||||
var = checkIncDec(event, var, min, max, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
|
||||
|
||||
#define CHECK_INCDEC_GENVAR(event, var, min, max) \
|
||||
var = checkIncDecGen(event, var, min, max)
|
||||
|
||||
#define NAVIGATION_LINE_BY_LINE 0x40
|
||||
#define CURSOR_ON_LINE() (menuHorizontalPosition<0)
|
||||
|
||||
#define CHECK_FLAG_NO_SCREEN_INDEX 1
|
||||
void check(event_t event, uint8_t curr, const MenuHandler *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags=0);
|
||||
void check_simple(event_t event, uint8_t curr, const MenuHandler *menuTab, uint8_t menuTabSize, vertpos_t maxrow);
|
||||
void check_submenu_simple(event_t event, uint8_t maxrow);
|
||||
|
||||
void title(const char * s);
|
||||
|
||||
#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
|
||||
|
||||
#define MENU_CHECK(tab, menu, lines_count) \
|
||||
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count)
|
||||
|
||||
#define MENU_CHECK_FLAGS(tab, menu, flags, lines_count) \
|
||||
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count, flags)
|
||||
|
||||
#define MENU(name, tab, menu, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
MENU_CHECK(tab, menu, lines_count); \
|
||||
title(name)
|
||||
|
||||
#define MENU_FLAGS(name, tab, menu, flags, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
MENU_CHECK_FLAGS(tab, menu, flags, lines_count); \
|
||||
title(name)
|
||||
|
||||
#define SIMPLE_MENU(name, tab, menu, lines_count) \
|
||||
check_simple(event, menu, tab, DIM(tab), lines_count); \
|
||||
title(name)
|
||||
|
||||
#define SUBMENU_NOTITLE(lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, lines_count);
|
||||
|
||||
#define SUBMENU(name, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
|
||||
title(name)
|
||||
|
||||
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
|
||||
check_submenu_simple(event, lines_count)
|
||||
|
||||
#define SIMPLE_SUBMENU(name, lines_count) \
|
||||
SIMPLE_SUBMENU_NOTITLE(lines_count); \
|
||||
title(name)
|
||||
|
||||
typedef int choice_t;
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label, const char* const* values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, IsValueAvailable isValueAvailable = nullptr);
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event);
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable = nullptr);
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event);
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr,
|
||||
event_t event);
|
||||
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags=0);
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event);
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
|
||||
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
#else
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, event)
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event);
|
||||
#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value,
|
||||
LcdFlags flags = 0);
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, uint8_t editflags,
|
||||
event_t event);
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
|
||||
|
||||
#define displayGVar(x, y, v, min, max) \
|
||||
GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
|
||||
#else // GVARS
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, lcdattr, event)
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, event_t event);
|
||||
|
||||
#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
|
||||
|
||||
#endif
|
||||
|
||||
void gvarWeightItem(coord_t x, coord_t y, MixData * md, LcdFlags attr, event_t event);
|
||||
|
@ -239,12 +133,14 @@ void editSingleName(coord_t x, coord_t y, const char *label, char *name,
|
|||
uint8_t old_editMode);
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay);
|
||||
|
||||
#define EDIT_DELAY(y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
|
||||
|
||||
void copySelection(char * dst, const char * src, uint8_t size);
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
|
||||
extern uint8_t s_copyMode;
|
||||
extern int8_t s_copySrcRow;
|
||||
extern int8_t s_copyTgtOfs;
|
||||
|
@ -252,10 +148,10 @@ extern uint8_t s_currIdx;
|
|||
extern uint8_t s_currIdxSubMenu;
|
||||
extern uint16_t s_currSrcRaw;
|
||||
extern uint16_t s_currScale;
|
||||
extern uint8_t s_maxLines;
|
||||
extern uint8_t s_copySrcIdx;
|
||||
extern uint8_t s_copySrcCh;
|
||||
extern int8_t s_currCh;
|
||||
extern uint8_t s_maxLines;
|
||||
|
||||
uint8_t getExposCount();
|
||||
void deleteExpo(uint8_t idx);
|
||||
|
@ -277,18 +173,12 @@ void readModelNotes();
|
|||
|
||||
void menuChannelsView(event_t event);
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
#define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT)
|
||||
#define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT)
|
||||
#else
|
||||
#define CURSOR_MOVED_LEFT(event) (EVT_KEY_MASK(event) == KEY_LEFT)
|
||||
#define CURSOR_MOVED_RIGHT(event) (EVT_KEY_MASK(event) == KEY_RIGHT)
|
||||
#endif
|
||||
void repeatLastCursorMove(event_t event);
|
||||
|
||||
#define REPEAT_LAST_CURSOR_MOVE() { if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) pushEvent(event); else menuHorizontalPosition = 0; }
|
||||
#define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0)
|
||||
#define EDIT_MODE_INIT 0 // TODO enum
|
||||
|
||||
void onSwitchLongEnterPress(const char *result);
|
||||
void onSourceLongEnterPress(const char *result);
|
||||
|
||||
uint8_t switchToMix(uint8_t source);
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
|
||||
#if !defined(BOOT)
|
||||
#include "opentx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "switches.h"
|
||||
#endif
|
||||
|
||||
#if (defined(PCBX9E) || defined(PCBX9DP)) && defined(LCD_DUAL_BUFFER)
|
||||
|
@ -615,18 +618,15 @@ void putsVBat(coord_t x, coord_t y, LcdFlags att)
|
|||
putsVolts(x, y, g_vbat100mV, att);
|
||||
}
|
||||
|
||||
void drawStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
// Skip "---": idx + 1
|
||||
// Skip source symbol: + 2
|
||||
const char* stickName = STR_VSRCRAW[idx + 1] + 2;
|
||||
lcdDrawSizedText(x, y, stickName, UINT8_MAX, att);
|
||||
lcdDrawSizedText(x, y, getMainControlLabel(idx), UINT8_MAX, att);
|
||||
}
|
||||
|
||||
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
|
||||
{
|
||||
if (idx == MIXSRC_NONE) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
|
||||
lcdDrawText(x, y, STR_EMPTY, att);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_INPUT) {
|
||||
lcdDrawChar(x+2, y+1, CHR_INPUT, TINSIZE);
|
||||
|
@ -654,54 +654,55 @@ void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
|
|||
}
|
||||
|
||||
else if (idx <= MIXSRC_LAST_POT) {
|
||||
idx = idx-MIXSRC_Rud;
|
||||
if (g_eeGeneral.anaNames[idx][0]) {
|
||||
if (idx < MIXSRC_FIRST_POT-MIXSRC_Rud )
|
||||
lcdDrawSizedText(x, y, STR_CHAR_STICK, 2, att);
|
||||
else if (idx < MIXSRC_FIRST_SLIDER-MIXSRC_Rud )
|
||||
lcdDrawSizedText(x, y, STR_CHAR_POT, 2, att);
|
||||
else
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SLIDER, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, att);
|
||||
}
|
||||
else
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx+1, att);
|
||||
lcdDrawText(x, y, getSourceString(idx), att);
|
||||
}
|
||||
else if (idx >= MIXSRC_FIRST_SWITCH && idx <= MIXSRC_LAST_SWITCH) {
|
||||
idx = idx - MIXSRC_FIRST_SWITCH;
|
||||
if (g_eeGeneral.switchNames[idx][0]) {
|
||||
lcdDrawSizedText(x, y, STR_CHAR_SWITCH, 2, att);
|
||||
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME, att);
|
||||
lcdDrawText(x, y, getSourceString(idx), att);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1, att);
|
||||
}
|
||||
}
|
||||
else if (idx < MIXSRC_SW1)
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
|
||||
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
|
||||
drawSwitch(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
|
||||
else if (idx < MIXSRC_CH1)
|
||||
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
|
||||
else if (idx <= MIXSRC_LAST_CH) {
|
||||
drawStringWithIndex(x, y, STR_CH, idx-MIXSRC_CH1+1, att);
|
||||
if (ZEXIST(g_model.limitData[idx-MIXSRC_CH1].name) && (att & STREXPANDED)) {
|
||||
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) {
|
||||
idx -= MIXSRC_FIRST_LOGICAL_SWITCH;
|
||||
drawSwitch(x, y, idx + SWSRC_FIRST_LOGICAL_SWITCH, att);
|
||||
} else if (idx <= MIXSRC_LAST_TRAINER) {
|
||||
idx -= MIXSRC_FIRST_TRAINER;
|
||||
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx + 1, att);
|
||||
} else if (idx <= MIXSRC_LAST_CH) {
|
||||
idx -= MIXSRC_FIRST_CH;
|
||||
drawStringWithIndex(x, y, STR_CH, idx + 1, att);
|
||||
if (ZEXIST(g_model.limitData[idx].name) && (att & STREXPANDED)) {
|
||||
lcdDrawChar(lcdLastRightPos, y, ' ', att|SMLSIZE);
|
||||
lcdDrawSizedText(lcdLastRightPos+3, y, g_model.limitData[idx-MIXSRC_CH1].name, LEN_CHANNEL_NAME, att|SMLSIZE);
|
||||
lcdDrawSizedText(lcdLastRightPos+3, y, g_model.limitData[idx].name, LEN_CHANNEL_NAME, att|SMLSIZE);
|
||||
}
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_GVAR) {
|
||||
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
|
||||
idx -= MIXSRC_FIRST_GVAR - 1;
|
||||
drawStringWithIndex(x, y, STR_GV, idx, att);
|
||||
}
|
||||
else if (idx < MIXSRC_FIRST_TIMER) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
|
||||
// Built-in sources: TX Voltage, Time, GPS (+ reserved)
|
||||
const char* src_str;
|
||||
switch(idx) {
|
||||
case MIXSRC_TX_VOLTAGE:
|
||||
src_str = STR_SRC_BATT;
|
||||
break;
|
||||
case MIXSRC_TX_TIME:
|
||||
src_str = STR_SRC_TIME;
|
||||
break;
|
||||
case MIXSRC_TX_GPS:
|
||||
src_str = STR_SRC_BATT;
|
||||
break;
|
||||
default:
|
||||
src_str = "";
|
||||
break;
|
||||
}
|
||||
lcdDrawText(x, y, src_str, att);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_TIMER) {
|
||||
if(ZEXIST(g_model.timers[idx-MIXSRC_FIRST_TIMER].name)) {
|
||||
lcdDrawSizedText(x, y, g_model.timers[idx-MIXSRC_FIRST_TIMER].name, LEN_TIMER_NAME, att);
|
||||
idx -= MIXSRC_FIRST_TIMER;
|
||||
if(g_model.timers[idx].name[0]) {
|
||||
lcdDrawSizedText(x, y, g_model.timers[idx].name, LEN_TIMER_NAME, att);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
|
||||
drawStringWithIndex(x, y, STR_SRC_TIMER, idx, att);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -714,7 +715,7 @@ void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
|
|||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, idx-1, att);
|
||||
lcdDrawText(x, y, getAnalogShortLabel(idx), att);
|
||||
}
|
||||
|
||||
void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
|
||||
|
|
|
@ -123,12 +123,12 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
|
|||
|
||||
void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
|
||||
void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0, bool autoBold = true);
|
||||
void drawStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
|
||||
void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
|
||||
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
|
||||
|
||||
#define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_CH1+idx-1, att)
|
||||
#define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_FIRST_CH+idx-1, att)
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
void runPopupCurvePreset(event_t event)
|
||||
{
|
||||
|
@ -128,9 +129,7 @@ void menuModelCurveOne(event_t event)
|
|||
lcdDrawNumber(INDENT_WIDTH, 6*FH+1, 5+crv.points, LEFT|attr);
|
||||
lcdDrawText(lcdLastRightPos, 6*FH+1, STR_PTS, attr);
|
||||
if (attr) {
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
#endif
|
||||
rotaryEncoderResetAccel();
|
||||
int8_t count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
|
||||
if (checkIncDec_Ret) {
|
||||
int8_t newPoints[MAX_POINTS_PER_CURVE];
|
||||
|
|
|
@ -265,7 +265,7 @@ void menuModelDisplay(event_t event)
|
|||
}
|
||||
}
|
||||
if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -150,11 +150,20 @@ void menuModelExpoOne(event_t event)
|
|||
break;
|
||||
|
||||
case EXPO_FIELD_TRIM:
|
||||
uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
|
||||
int8_t trimSource = -ed->trimSource;
|
||||
lcdDrawTextAlignedLeft(y, STR_TRIM);
|
||||
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && trimSource == 0) ? 0 : trimSource + 1, menuHorizontalPosition==0 ? attr : 0);
|
||||
if (attr) ed->trimSource = -checkIncDecModel(event, trimSource, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_LAST);
|
||||
{
|
||||
const char* trim_str = getTrimSourceLabel(ed->srcRaw, ed->trimSource);
|
||||
LcdFlags flags = RIGHT | (menuHorizontalPosition==0 ? attr : 0);
|
||||
lcdDrawText(EXPO_ONE_2ND_COLUMN, y, trim_str, flags);
|
||||
|
||||
if (attr) {
|
||||
int8_t min = TRIM_ON;
|
||||
if (ed->srcRaw >= MIXSRC_FIRST_STICK && ed->srcRaw <= MIXSRC_LAST_STICK) {
|
||||
min = -TRIM_OFF;
|
||||
}
|
||||
ed->trimSource = -checkIncDecModel(event, -ed->trimSource, min, keysGetMaxTrims());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
y += FH;
|
||||
|
|
|
@ -109,7 +109,7 @@ void menuModelLogicalSwitches(event_t event)
|
|||
LogicalSwitchData * cs = lswAddress(k);
|
||||
|
||||
// CSW name
|
||||
unsigned int sw = SWSRC_SW1+k;
|
||||
unsigned int sw = SWSRC_FIRST_LOGICAL_SWITCH+k;
|
||||
drawSwitch(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && CURSOR_ON_LINE()) ? INVERS : 0));
|
||||
|
||||
// CSW func
|
||||
|
@ -189,7 +189,7 @@ void menuModelLogicalSwitches(event_t event)
|
|||
if (cstate == LS_FAMILY_EDGE) {
|
||||
lcdDrawText(CSW_6TH_COLUMN, y, STR_NA);
|
||||
if (attr && horz == LS_FIELD_DELAY) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
else if (cs->delay > 0) {
|
||||
|
@ -200,7 +200,7 @@ void menuModelLogicalSwitches(event_t event)
|
|||
}
|
||||
|
||||
if (attr && horz == LS_FIELD_V3 && cstate != LS_FAMILY_EDGE) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
|
||||
if (s_editMode>0 && attr) {
|
||||
|
|
|
@ -79,6 +79,27 @@ void onModelSelectMenu(const char * result)
|
|||
}
|
||||
}
|
||||
|
||||
static void moveToFreeModelSlot(bool forward, int8_t& sub, int8_t oldSub)
|
||||
{
|
||||
int8_t next_ofs = s_copyTgtOfs + oldSub - menuVerticalPosition;
|
||||
if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS) next_ofs = 0;
|
||||
|
||||
if (s_copySrcRow < 0 && s_copyMode == COPY_MODE) {
|
||||
s_copySrcRow = oldSub;
|
||||
// find a hole (in the first empty slot above / below)
|
||||
sub = findEmptyModel(s_copySrcRow, forward);
|
||||
if (sub < 0) {
|
||||
// no free room for duplicating the model
|
||||
AUDIO_ERROR();
|
||||
sub = oldSub;
|
||||
s_copyMode = 0;
|
||||
}
|
||||
next_ofs = 0;
|
||||
menuVerticalPosition = sub;
|
||||
}
|
||||
s_copyTgtOfs = next_ofs;
|
||||
}
|
||||
|
||||
void menuModelSelect(event_t event)
|
||||
{
|
||||
if (warningResult) {
|
||||
|
@ -89,10 +110,13 @@ void menuModelSelect(event_t event)
|
|||
event = EVT_ENTRY_UP;
|
||||
}
|
||||
|
||||
event_t _event_ = ((event==EVT_KEY_BREAK(KEY_ENTER) || event==EVT_KEY_LONG(KEY_ENTER)) ? 0 : event);
|
||||
|
||||
if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
|
||||
_event_ -= KEY_EXIT;
|
||||
// Suppress "edit mode": model select has none
|
||||
// Suppress exit in "copy mode": handled in this function
|
||||
event_t _event_ = event;
|
||||
if ((s_copyMode && IS_KEY_EVT(event, KEY_EXIT)) ||
|
||||
event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER) ||
|
||||
event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
_event_ = 0;
|
||||
}
|
||||
|
||||
int8_t oldSub = menuVerticalPosition;
|
||||
|
@ -101,7 +125,7 @@ void menuModelSelect(event_t event)
|
|||
|
||||
if (s_editMode > 0) s_editMode = 0;
|
||||
|
||||
int sub = menuVerticalPosition;
|
||||
int8_t sub = menuVerticalPosition;
|
||||
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
|
@ -208,39 +232,19 @@ void menuModelSelect(event_t event)
|
|||
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
chainMenu(event == EVT_KEY_BREAK(KEY_PAGE) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1].menuFunc);
|
||||
chainMenu(event == EVT_KEY_BREAK(KEY_PAGE)
|
||||
? menuModelSetup
|
||||
: menuTabModel[DIM(menuTabModel) - 1].menuFunc);
|
||||
killEvents(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_REPT(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_REPT(KEY_DOWN):
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
case EVT_ROTARY_LEFT:
|
||||
case EVT_ROTARY_RIGHT:
|
||||
#endif
|
||||
if (s_copyMode) {
|
||||
int8_t next_ofs = s_copyTgtOfs + oldSub - menuVerticalPosition;
|
||||
if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS)
|
||||
next_ofs = 0;
|
||||
|
||||
if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) {
|
||||
s_copySrcRow = oldSub;
|
||||
// find a hole (in the first empty slot above / below)
|
||||
sub = findEmptyModel(s_copySrcRow, event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN));
|
||||
if (sub < 0) {
|
||||
// no free room for duplicating the model
|
||||
AUDIO_ERROR();
|
||||
sub = oldSub;
|
||||
s_copyMode = 0;
|
||||
if (IS_PREVIOUS_EVENT(event)) {
|
||||
moveToFreeModelSlot(false, sub, oldSub);
|
||||
} else if (IS_NEXT_EVENT(event)) {
|
||||
moveToFreeModelSlot(true, sub, oldSub);
|
||||
}
|
||||
next_ofs = 0;
|
||||
menuVerticalPosition = sub;
|
||||
}
|
||||
s_copyTgtOfs = next_ofs;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(EEPROM)
|
||||
|
|
|
@ -19,8 +19,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
#include "opentx.h"
|
||||
#include "mixer_scheduler.h"
|
||||
#include "switches.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
|
@ -35,7 +40,7 @@ uint8_t g_moduleIdx;
|
|||
uint8_t getSwitchWarningsCount()
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (int i=0; i<NUM_SWITCHES; ++i) {
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
++count;
|
||||
}
|
||||
|
@ -396,20 +401,21 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW()
|
|||
#elif TIMERS == 3
|
||||
#define TIMERS_ROWS TIMER_ROWS(0), TIMER_ROWS(1), TIMER_ROWS(2)
|
||||
#endif
|
||||
|
||||
#if defined(PCBX9E)
|
||||
#define SW_WARN_ROWS \
|
||||
PREFLIGHT_ROW(uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1))), \
|
||||
PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW)), \
|
||||
PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW))
|
||||
#define POT_WARN_ROWS \
|
||||
PREFLIGHT_ROW(uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0)), \
|
||||
PREFLIGHT_ROW(uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(MAX_POTS) : 0)), \
|
||||
PREFLIGHT_ROW(uint8_t(g_model.potsWarnMode ? TITLE_ROW : HIDDEN_ROW))
|
||||
#define TOPLCD_ROWS 0,
|
||||
#else
|
||||
#define SW_WARN_ROWS \
|
||||
PREFLIGHT_ROW(uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount()))
|
||||
#define POT_WARN_ROWS \
|
||||
PREFLIGHT_ROW(uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0))
|
||||
PREFLIGHT_ROW(uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(MAX_POTS) : 0))
|
||||
#define TOPLCD_ROWS
|
||||
#endif
|
||||
|
||||
|
@ -537,7 +543,7 @@ void menuModelSetup(event_t event)
|
|||
SW_WARN_ROWS, // Switch warning
|
||||
POT_WARN_ROWS, // Pot warning
|
||||
|
||||
NAVIGATION_LINE_BY_LINE | (NUM_STICKS+NUM_POTS+NUM_SLIDERS-1), // Center beeps
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_POT + 1) - 1)), // Center beeps
|
||||
|
||||
0, // ADC Jitter filter
|
||||
|
||||
|
@ -796,7 +802,7 @@ void menuModelSetup(event_t event)
|
|||
if (attr)
|
||||
CHECK_INCDEC_MODELVAR_ZERO_CHECK(
|
||||
event, g_model.thrTraceSrc,
|
||||
NUM_POTS + NUM_SLIDERS + MAX_OUTPUT_CHANNELS,
|
||||
MAX_POTS + MAX_OUTPUT_CHANNELS,
|
||||
isThrottleSourceAvailable);
|
||||
|
||||
uint8_t idx = throttleSource2Source(g_model.thrTraceSrc);
|
||||
|
@ -811,7 +817,7 @@ void menuModelSetup(event_t event)
|
|||
case ITEM_MODEL_SETUP_THROTTLE_TRIM_SWITCH:
|
||||
lcdDrawTextAlignedLeft(y, STR_TTRIM_SW);
|
||||
if (attr)
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTrimSw, NUM_TRIMS - 1);
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTrimSw, MAX_TRIMS - 1);
|
||||
drawSource(MODEL_SETUP_2ND_COLUMN, y, g_model.getThrottleStickTrimSource(), attr);
|
||||
break;
|
||||
|
||||
|
@ -846,7 +852,7 @@ void menuModelSetup(event_t event)
|
|||
case ITEM_MODEL_SETUP_SWITCHES_WARNING3:
|
||||
case ITEM_MODEL_SETUP_POTS_WARNING2:
|
||||
if (i==0) {
|
||||
if (CURSOR_MOVED_LEFT(event))
|
||||
if (IS_PREVIOUS_EVENT(event))
|
||||
menuVerticalOffset--;
|
||||
else
|
||||
menuVerticalOffset++;
|
||||
|
@ -858,7 +864,7 @@ void menuModelSetup(event_t event)
|
|||
{
|
||||
#if defined(PCBX9E)
|
||||
if (i>=NUM_BODY_LINES-2 && getSwitchWarningsCount() > 8*(NUM_BODY_LINES-i)) {
|
||||
if (CURSOR_MOVED_LEFT(event))
|
||||
if (IS_PREVIOUS_EVENT(event))
|
||||
menuVerticalOffset--;
|
||||
else
|
||||
menuVerticalOffset++;
|
||||
|
@ -881,7 +887,7 @@ void menuModelSetup(event_t event)
|
|||
getMovedSwitch();
|
||||
// Mask switches enabled for warnings
|
||||
swarnstate_t sw_mask = 0;
|
||||
for(uint8_t i=0; i<NUM_SWITCHES; i++) {
|
||||
for(uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i))
|
||||
if (g_model.switchWarningState & (0x07 << (3 * i)))
|
||||
sw_mask |= (0x07 << (3 * i));
|
||||
|
@ -899,7 +905,7 @@ void menuModelSetup(event_t event)
|
|||
LcdFlags line = attr;
|
||||
|
||||
int current = 0;
|
||||
for (int i=0; i<NUM_SWITCHES; i++) {
|
||||
for (int i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
div_t qr = div(current, 8);
|
||||
if (!READ_ONLY() && event == EVT_KEY_BREAK(KEY_ENTER) && line &&
|
||||
|
@ -935,7 +941,7 @@ void menuModelSetup(event_t event)
|
|||
case ITEM_MODEL_SETUP_POTS_WARNING:
|
||||
#if defined(PCBX9E)
|
||||
if (i==NUM_BODY_LINES-1 && g_model.potsWarnMode) {
|
||||
if (CURSOR_MOVED_LEFT(event))
|
||||
if (IS_PREVIOUS_EVENT(event))
|
||||
menuVerticalOffset--;
|
||||
else
|
||||
menuVerticalOffset++;
|
||||
|
@ -971,25 +977,25 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
if (g_model.potsWarnMode) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN+28;
|
||||
for (int i=0; i<NUM_POTS+NUM_SLIDERS; ++i) {
|
||||
if (i<NUM_XPOTS && !IS_POT_SLIDER_AVAILABLE(POT1+i)) {
|
||||
if (attr && (menuHorizontalPosition==i+1)) REPEAT_LAST_CURSOR_MOVE();
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
for (int i = 0; i < max_pots; ++i) {
|
||||
|
||||
if (!IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
// skip non configured pot
|
||||
if (attr && (menuHorizontalPosition==i+1)) repeatLastCursorMove(event);
|
||||
}
|
||||
else {
|
||||
#if defined(PCBX9E)
|
||||
if (i == NUM_XPOTS) {
|
||||
if (max_pots > 5 && i == 3) {
|
||||
y += FH;
|
||||
x = MODEL_SETUP_2ND_COLUMN;
|
||||
}
|
||||
#endif
|
||||
LcdFlags flags = ((menuHorizontalPosition==i+1) && attr) ? BLINK : 0;
|
||||
if ((!attr || menuHorizontalPosition >= 0) && (g_model.potsWarnEnabled & (1 << i))) {
|
||||
if ((!attr || menuHorizontalPosition >= 0) &&
|
||||
(g_model.potsWarnEnabled & (1 << i))) {
|
||||
flags |= INVERS;
|
||||
}
|
||||
|
||||
// skip "---" (+1) and source symbol (+2)
|
||||
const char* source = STR_VSRCRAW[NUM_STICKS + 1 + i] + 2;
|
||||
lcdDrawSizedText(x, y, source, UINT8_MAX, flags);
|
||||
lcdDrawText(x, y, getPotLabel(i), flags);
|
||||
x = lcdNextPos+3;
|
||||
}
|
||||
}
|
||||
|
@ -1003,17 +1009,22 @@ void menuModelSetup(event_t event)
|
|||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER:
|
||||
{
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER: {
|
||||
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN;
|
||||
for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
if (i>=POT1 && i<POT1+NUM_XPOTS && !IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
if (attr && menuHorizontalPosition == i) REPEAT_LAST_CURSOR_MOVE();
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_POT);
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN + i*FW;
|
||||
if ( i >= pot_offset && IS_POT_MULTIPOS(i - pot_offset) ) {
|
||||
if (attr && menuHorizontalPosition == i) repeatLastCursorMove(event);
|
||||
continue;
|
||||
}
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) );
|
||||
x += FW;
|
||||
LcdFlags flags = 0;
|
||||
if ((menuHorizontalPosition == i) && attr)
|
||||
flags = BLINK | INVERS;
|
||||
else if (ANALOG_CENTER_BEEP(x) || (attr && CURSOR_ON_LINE()))
|
||||
flags = INVERS;
|
||||
lcdDrawText(x, y, getAnalogShortLabel(i), flags);
|
||||
}
|
||||
if (attr && CURSOR_ON_CELL) {
|
||||
if (event==EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
|
|
|
@ -195,7 +195,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
|
||||
case ITEM_CUSTOM_FUNCTIONS_FUNCTION:
|
||||
if (CFN_SWITCH(cfn)) {
|
||||
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr);
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_2ND_COLUMN, y, funcGetLabel(func), attr);
|
||||
if (active) {
|
||||
func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
|
||||
if (checkIncDec_Ret) CFN_RESET(cfn);
|
||||
|
@ -204,7 +204,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
else {
|
||||
j = ITEM_CUSTOM_FUNCTIONS_LAST; // skip other fields
|
||||
if (sub==k && menuHorizontalPosition > 0) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -219,14 +219,14 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
else
|
||||
#endif
|
||||
if (func == FUNC_TRAINER) {
|
||||
maxParam = NUM_STICKS + 1;
|
||||
maxParam = MAX_STICKS + 1;
|
||||
uint8_t param = CFN_CH_INDEX(cfn);
|
||||
if (param == 0)
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_STICKS, attr);
|
||||
else if (param == NUM_STICKS + 1)
|
||||
else if (param == MAX_STICKS + 1)
|
||||
lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_CHANS, attr);
|
||||
else
|
||||
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_Rud + param - 1, attr);
|
||||
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_FIRST_STICK + param - 1, attr);
|
||||
}
|
||||
#if defined(GVARS)
|
||||
else if (func == FUNC_ADJUST_GVAR) {
|
||||
|
@ -243,7 +243,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
break;
|
||||
}
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam);
|
||||
break;
|
||||
|
@ -388,7 +388,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
}
|
||||
#endif
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
|
||||
if (active || event==EVT_KEY_LONG(KEY_ENTER)) {
|
||||
|
@ -436,7 +436,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
|||
}
|
||||
}
|
||||
else if (attr) {
|
||||
REPEAT_LAST_CURSOR_MOVE();
|
||||
repeatLastCursorMove(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "opentx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "gui/common/stdlcd/calibration.h"
|
||||
|
||||
#define XPOT_DELTA 10
|
||||
#define XPOT_DELAY 10 /* cycles */
|
||||
|
@ -30,168 +31,28 @@
|
|||
void drawPotsBars()
|
||||
{
|
||||
// Optimization by Mike Blandford
|
||||
for (uint8_t x=LCD_W/2-(NUM_POTS+NUM_SLIDERS)/2*BAR_SPACING+BAR_SPACING/2, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; x+=BAR_SPACING, i++) {
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t x = LCD_W / 2 - max_pots / 2 * BAR_SPACING + BAR_SPACING / 2,
|
||||
i = 0;
|
||||
i < max_pots; x += BAR_SPACING, i++) {
|
||||
if (IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
uint8_t len = ((calibratedAnalogs[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
|
||||
V_BAR(x, LCD_H-8, len);
|
||||
drawStickName(x-2, LCD_H-6, i, TINSIZE);
|
||||
// calculate once per loop
|
||||
auto v = calibratedAnalogs[offset + i] + RESX;
|
||||
uint8_t len = (v * BAR_HEIGHT / (RESX * 2)) + 1l;
|
||||
V_BAR(x, LCD_H - 8, len);
|
||||
lcdDrawText(x - 2, LCD_H - 6, getPotLabel(i), TINSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void menuCommonCalib(event_t event)
|
||||
{
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high vals for sticks and trims
|
||||
int16_t vt = anaIn(i);
|
||||
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
|
||||
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
|
||||
if (i >= POT1 && i <= POT_LAST) {
|
||||
if (IS_POT_WITHOUT_DETENT(i)) {
|
||||
reusableBuffer.calib.midVals[i] = (reusableBuffer.calib.hiVals[i] + reusableBuffer.calib.loVals[i]) / 2;
|
||||
}
|
||||
uint8_t idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i) && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
// use raw analog value for multipos calibraton, anaIn() already has multipos decoded value
|
||||
vt = getAnalogValue(i) >> 1;
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 || vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA || vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastPosition = vt;
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastCount = 1;
|
||||
}
|
||||
else {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255) reusableBuffer.calib.xpotsCalib[idx].lastCount++;
|
||||
}
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == XPOT_DELAY) {
|
||||
int16_t position = reusableBuffer.calib.xpotsCalib[idx].lastPosition;
|
||||
bool found = false;
|
||||
for (int j=0; j<count; j++) {
|
||||
int16_t step = reusableBuffer.calib.xpotsCalib[idx].steps[j];
|
||||
if (position >= step-XPOT_DELTA && position <= step+XPOT_DELTA) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (count < XPOTS_MULTIPOS_COUNT) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].steps[count] = position;
|
||||
}
|
||||
reusableBuffer.calib.xpotsCalib[idx].stepsCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menuCalibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
|
||||
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
reusableBuffer.calib.state = CALIB_START;
|
||||
break;
|
||||
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
reusableBuffer.calib.state++;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (reusableBuffer.calib.state) {
|
||||
case CALIB_START:
|
||||
// START CALIBRATION
|
||||
if (!READ_ONLY()) {
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUTOSTART);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIB_SET_MIDPOINT:
|
||||
// SET MIDPOINT
|
||||
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
reusableBuffer.calib.loVals[i] = 15000;
|
||||
reusableBuffer.calib.hiVals[i] = -15000;
|
||||
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
|
||||
if (i<NUM_XPOTS) {
|
||||
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
|
||||
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIB_MOVE_STICKS:
|
||||
// MOVE STICKS/POTS
|
||||
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
|
||||
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
|
||||
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
|
||||
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
|
||||
g_eeGeneral.calib[i].spanNeg = v - v/STICK_TOLERANCE;
|
||||
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
|
||||
g_eeGeneral.calib[i].spanPos = v - v/STICK_TOLERANCE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIB_STORE:
|
||||
for (uint8_t i=POT1; i<=POT_LAST; i++) {
|
||||
int idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
if (count > 1 && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
for (int j=0; j<count; j++) {
|
||||
for (int k=j+1; k<count; k++) {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].steps[k] < reusableBuffer.calib.xpotsCalib[idx].steps[j]) {
|
||||
SWAP(reusableBuffer.calib.xpotsCalib[idx].steps[j], reusableBuffer.calib.xpotsCalib[idx].steps[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
|
||||
calib->count = count - 1;
|
||||
for (int j=0; j<calib->count; j++) {
|
||||
calib->steps[j] = (reusableBuffer.calib.xpotsCalib[idx].steps[j+1] + reusableBuffer.calib.xpotsCalib[idx].steps[j]) >> 5;
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_eeGeneral.potsConfig &= ~(0x03<<(2*idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
g_eeGeneral.chkSum = evalChkSum();
|
||||
storageDirty(EE_GENERAL);
|
||||
reusableBuffer.calib.state = CALIB_FINISHED;
|
||||
break;
|
||||
|
||||
default:
|
||||
reusableBuffer.calib.state = CALIB_START;
|
||||
break;
|
||||
}
|
||||
|
||||
doMainScreenGraphics();
|
||||
drawPotsBars();
|
||||
|
||||
#if 0
|
||||
for (int i=POT1; i<=POT_LAST; i++) {
|
||||
uint8_t steps = 0;
|
||||
if (reusableBuffer.calib.state == CALIB_MOVE_STICKS) {
|
||||
steps = reusableBuffer.calib.xpotsCalib[i-POT1].stepsCount;
|
||||
}
|
||||
else if (IS_POT_MULTIPOS(i)) {
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
|
||||
steps = calib->count + 1;
|
||||
}
|
||||
if (steps > 0 && steps <= XPOTS_MULTIPOS_COUNT) {
|
||||
lcdDrawNumber(LCD_W/2-2+(i-POT1)*5, LCD_H-6, steps, TINSIZE|RIGHT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void menuRadioCalibration(event_t event)
|
||||
{
|
||||
check_submenu_simple(event, 0);
|
||||
title(STR_MENUCALIBRATION);
|
||||
menuCommonCalib(READ_ONLY() ? 0 : event);
|
||||
drawPotsBars();
|
||||
if (menuEvent) {
|
||||
menuCalibrationState = CALIB_START;
|
||||
}
|
||||
|
@ -207,5 +68,6 @@ void menuFirstCalib(event_t event)
|
|||
lcdDrawText(LCD_W / 2, 0, STR_MENUCALIBRATION, CENTERED);
|
||||
lcdInvertLine(0);
|
||||
menuCommonCalib(event);
|
||||
drawPotsBars();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
void menuRadioDiagAnalogs(event_t event)
|
||||
{
|
||||
static int8_t entryCount = 0;
|
||||
static uint16_t lastShownAnalogValue[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
|
||||
static uint16_t lastShownAnalogValue[MAX_ANALOG_INPUTS];
|
||||
|
||||
enum ANAVIEWS{
|
||||
ANAVIEW_FIRST,
|
||||
|
@ -53,7 +53,7 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
case (ANAVIEW_RAWLOWFPS): SIMPLE_SUBMENU(STR_MENU_RADIO_ANALOGS_RAWLOWFPS, 0); break;
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
|
||||
for (uint8_t i = 0; i < MAX_ANALOG_INPUTS; i++) {
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH;
|
||||
uint8_t x = i&1 ? LCD_W/2 + FW : 0;
|
||||
lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2);
|
||||
|
@ -75,9 +75,9 @@ void menuRadioDiagAnalogs(event_t event)
|
|||
#if defined(JITTER_MEASURE)
|
||||
lcdDrawNumber(x+10*FW-1, y, rawJitter[i].get(), RIGHT);
|
||||
lcdDrawNumber(x+13*FW-1, y, avgJitter[i].get(), RIGHT);
|
||||
lcdDrawNumber(x+17*FW-1, y, (int16_t)calibratedAnalogs[CONVERT_MODE(i)]*25/256, RIGHT);
|
||||
lcdDrawNumber(x+17*FW-1, y, (int16_t)calibratedAnalogs[i]*25/256, RIGHT);
|
||||
#else
|
||||
lcdDrawNumber(x+10*FW-1, y, (int16_t)calibratedAnalogs[CONVERT_MODE(i)]*25/256, RIGHT);
|
||||
lcdDrawNumber(x+10*FW-1, y, (int16_t)calibratedAnalogs[i]*25/256, RIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -21,32 +21,55 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
void displayKeyState(uint8_t x, uint8_t y, uint8_t key)
|
||||
{
|
||||
uint8_t t = keys[key].state();
|
||||
uint8_t t = keysGetState(key);
|
||||
lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
|
||||
}
|
||||
|
||||
void displayTrimState(uint8_t x, uint8_t y, uint8_t trim)
|
||||
{
|
||||
uint8_t t = keysGetTrimState(trim);
|
||||
lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
|
||||
}
|
||||
|
||||
static EnumKeys get_ith_key(uint8_t i)
|
||||
{
|
||||
auto supported_keys = keysGetSupported();
|
||||
for (uint8_t k = 0; k < MAX_KEYS; k++) {
|
||||
if (supported_keys & (1 << k)) {
|
||||
if (i-- == 0) return (EnumKeys)k;
|
||||
}
|
||||
}
|
||||
|
||||
// should not get here,
|
||||
// we assume: i < keysGetMaxKeys()
|
||||
return (EnumKeys)0;
|
||||
}
|
||||
|
||||
void menuRadioDiagKeys(event_t event)
|
||||
{
|
||||
SIMPLE_SUBMENU(STR_MENU_RADIO_SWITCHES, 1);
|
||||
|
||||
lcdDrawText(24*FW, MENU_HEADER_HEIGHT + 1, STR_VTRIM);
|
||||
|
||||
for (uint8_t i = 0; i < NUM_TRIMS_KEYS; i++) {
|
||||
for (uint8_t i = 0; i < keysGetMaxTrims() * 2; i++) {
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + FH + FH * (i / 2);
|
||||
if (i & 1)
|
||||
lcdDraw1bitBitmap(24 * FW, y, sticks, i / 2, 0);
|
||||
displayKeyState(i & 1 ? 30 * FW : 28 * FW, y, TRM_BASE + i);
|
||||
if (i & 1) lcdDraw1bitBitmap(24 * FW, y, sticks, i / 2, 0);
|
||||
displayTrimState(i & 1 ? 30 * FW : 28 * FW, y, i);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i <= KEY_MAX; i++) {
|
||||
for (uint8_t i = 0; i < keysGetMaxKeys(); i++) {
|
||||
auto k = get_ith_key(i);
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + FH * i;
|
||||
lcdDrawTextAtIndex(0, y, STR_VKEYS, (i), 0);
|
||||
lcdDrawText(0, y, keysGetLabel(k), 0);
|
||||
displayKeyState(5 * FW + 2, y, i);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0, cnt = 0; i < NUM_SWITCHES; i++) {
|
||||
for (uint8_t i = 0, cnt = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
div_t qr = div(cnt++, 6);
|
||||
coord_t x = 4 * FH * qr.quot;
|
||||
|
@ -58,8 +81,8 @@ void menuRadioDiagKeys(event_t event)
|
|||
}
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + FH*KEY_COUNT;
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + FH * MAX_KEYS;
|
||||
lcdDrawText(0, y, STR_ROTARY_ENCODER);
|
||||
lcdDrawNumber(5*FW+FWNUM+2, y, rotencValue / ROTARY_ENCODER_GRANULARITY, RIGHT);
|
||||
lcdDrawNumber(5 * FW + FWNUM + 2, y, rotaryEncoderGetValue(), RIGHT);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define LANGUAGE_PACKS_DEFINITION
|
||||
|
||||
#include "opentx.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
const unsigned char sticks[] = {
|
||||
#include "sticks.lbm"
|
||||
|
@ -608,10 +611,15 @@ void menuRadioSetup(event_t event)
|
|||
|
||||
case ITEM_RADIO_SETUP_RX_CHANNEL_ORD:
|
||||
lcdDrawTextAlignedLeft(y, STR_DEF_CHAN_ORD); // RAET->AETR
|
||||
for (uint8_t i=1; i<=4; i++) {
|
||||
putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, channelOrder(i), attr);
|
||||
{
|
||||
for (uint8_t i = 0; i < adcGetMaxInputs(ADC_INPUT_MAIN); i++) {
|
||||
putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, inputMappingChannelOrder(i), attr);
|
||||
}
|
||||
if (attr) {
|
||||
auto max_order = inputMappingGetMaxChannelOrder() - 1;
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, max_order);
|
||||
}
|
||||
}
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23);
|
||||
break;
|
||||
|
||||
case ITEM_RADIO_SETUP_STICK_MODE_LABELS:
|
||||
|
@ -641,20 +649,24 @@ void menuRadioSetup(event_t event)
|
|||
#endif
|
||||
|
||||
case ITEM_RADIO_SETUP_STICK_MODE:
|
||||
lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr);
|
||||
{
|
||||
auto& mode = reusableBuffer.generalSettings.stickMode;
|
||||
lcdDrawChar(2*FW, y, '1' + mode, attr);
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
drawStickName((6+4*i)*FW, y, *(modn12x3 + 4*reusableBuffer.generalSettings.stickMode + i), 0);
|
||||
auto ctrl = inputMappingConvertMode(mode, i);
|
||||
drawMainControlLabel((6+4*i)*FW, y, ctrl, 0);
|
||||
}
|
||||
if (attr && s_editMode>0) {
|
||||
CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3);
|
||||
if (attr && s_editMode > 0) {
|
||||
CHECK_INCDEC_GENVAR(event, mode, 0, 3);
|
||||
}
|
||||
else if (reusableBuffer.generalSettings.stickMode != g_eeGeneral.stickMode) {
|
||||
else if (mode != g_eeGeneral.stickMode) {
|
||||
mixerTaskStop();
|
||||
g_eeGeneral.stickMode = reusableBuffer.generalSettings.stickMode;
|
||||
g_eeGeneral.stickMode = mode;
|
||||
checkThrottleStick();
|
||||
mixerTaskStart();
|
||||
waitKeysReleased();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_VIEW_OPTIONS_LABEL:
|
||||
|
|
|
@ -40,12 +40,10 @@ void menuChannelsView(event_t event)
|
|||
popMenu();
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
case EVT_ROTARY_LEFT:
|
||||
case EVT_ROTARY_RIGHT:
|
||||
#endif
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
reusableBuffer.viewChannels.secondPage = !reusableBuffer.viewChannels.secondPage;
|
||||
break;
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
#include "opentx.h"
|
||||
#include "hal/trainer_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
#include "switches.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#define BIGSIZE MIDSIZE
|
||||
#define LBOX_CENTERX (BOX_WIDTH/2 + 16)
|
||||
|
@ -73,24 +78,24 @@ const unsigned char icons[] = {
|
|||
|
||||
void doMainScreenGraphics()
|
||||
{
|
||||
int16_t calibStickVert = calibratedAnalogs[CONVERT_MODE(1)];
|
||||
if (g_model.throttleReversed && CONVERT_MODE(1) == THR_STICK)
|
||||
int16_t calibStickVert = calibratedAnalogs[ADC_MAIN_LV];
|
||||
if (g_model.throttleReversed && inputMappingConvertMode(ADC_MAIN_LV) == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
drawStick(LBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(0)], calibStickVert);
|
||||
drawStick(LBOX_CENTERX, calibratedAnalogs[ADC_MAIN_LH], calibStickVert);
|
||||
|
||||
calibStickVert = calibratedAnalogs[CONVERT_MODE(2)];
|
||||
if (g_model.throttleReversed && CONVERT_MODE(2) == THR_STICK)
|
||||
calibStickVert = calibratedAnalogs[ADC_MAIN_RV];
|
||||
if (g_model.throttleReversed && inputMappingConvertMode(ADC_MAIN_RV) == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
drawStick(RBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(3)], calibStickVert);
|
||||
drawStick(RBOX_CENTERX, calibratedAnalogs[ADC_MAIN_RH], calibStickVert);
|
||||
}
|
||||
|
||||
void displayTrims(uint8_t phase)
|
||||
{
|
||||
for (unsigned int i=0; i<NUM_STICKS; i++) {
|
||||
coord_t x[4] = { TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X };
|
||||
uint8_t vert[4] = { 0, 1, 1, 0 };
|
||||
for (unsigned int i = 0; i < MAX_STICKS; i++) {
|
||||
coord_t x[] = { TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X };
|
||||
uint8_t vert[] = { 0, 1, 1, 0 };
|
||||
coord_t xm, ym;
|
||||
unsigned int stickIndex = CONVERT_MODE(i);
|
||||
unsigned int stickIndex = inputMappingConvertMode(i);
|
||||
xm = x[stickIndex];
|
||||
|
||||
uint32_t att = ROUND;
|
||||
|
@ -164,26 +169,45 @@ void displayTrims(uint8_t phase)
|
|||
}
|
||||
}
|
||||
|
||||
// Pots & sliders
|
||||
// X9E: only sliders (1 to 4)
|
||||
// Other: POT1, POT2, SLIDERS1 and SLIDER2
|
||||
//
|
||||
static const coord_t _pot_slots[] = {
|
||||
3, LCD_H / 2 + 1, // SLIDER1 (x,y)
|
||||
LCD_W - 5, LCD_H / 2 + 1, // SLIDER2 (x,y)
|
||||
3, 1, // SLIDER3 (x,y)
|
||||
LCD_W - 5, 1, // SLIDER4 (x,y)
|
||||
};
|
||||
|
||||
void drawSliders()
|
||||
{
|
||||
for (uint8_t i = NUM_STICKS; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
uint8_t slot_idx = 0;
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
|
||||
// TODO: move this into board implementation
|
||||
#if defined(PCBX9E)
|
||||
if (i < SLIDER1)
|
||||
continue; // TODO change and display more values
|
||||
coord_t x = ((i==SLIDER1 || i==SLIDER3) ? 3 : LCD_W-5);
|
||||
int8_t y = (i<SLIDER3 ? LCD_H/2+1 : 1);
|
||||
// Only sliders
|
||||
if (!IS_SLIDER(i)) continue;
|
||||
#else
|
||||
if (i == POT3)
|
||||
continue;
|
||||
coord_t x = ((i==POT1 || i==SLIDER1) ? 3 : LCD_W-5);
|
||||
int8_t y = (i>=SLIDER1 ? LCD_H/2+1 : 1);
|
||||
// Skip POT3
|
||||
if (i == 2) continue;
|
||||
#endif
|
||||
lcdDrawSolidVerticalLine(x, y, LCD_H/2-2);
|
||||
lcdDrawSolidVerticalLine(x+1, y, LCD_H/2-2);
|
||||
|
||||
coord_t x = _pot_slots[slot_idx++];
|
||||
coord_t y = _pot_slots[slot_idx++];
|
||||
|
||||
lcdDrawSolidVerticalLine(x, y, LCD_H / 2 - 2);
|
||||
lcdDrawSolidVerticalLine(x + 1, y, LCD_H / 2 - 2);
|
||||
|
||||
// calculate once per loop
|
||||
y += LCD_H / 2 - 4;
|
||||
y -= ((calibratedAnalogs[i]+RESX)*(LCD_H/2-4)/(RESX*2)); // calculate once per loop
|
||||
lcdDrawSolidVerticalLine(x-1, y, 2);
|
||||
lcdDrawSolidVerticalLine(x+2, y, 2);
|
||||
y -= ((calibratedAnalogs[offset + i] + RESX) * (LCD_H / 2 - 4) / (RESX * 2));
|
||||
lcdDrawSolidVerticalLine(x - 1, y, 2);
|
||||
lcdDrawSolidVerticalLine(x + 2, y, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,17 +441,6 @@ void displaySwitch(coord_t x, coord_t y, int width, unsigned int index)
|
|||
}
|
||||
}
|
||||
|
||||
int getSwitchCount()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i=0; i<NUM_SWITCHES; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void menuMainView(event_t event)
|
||||
{
|
||||
static bool secondPage = false;
|
||||
|
@ -435,8 +448,8 @@ void menuMainView(event_t event)
|
|||
switch(event) {
|
||||
case EVT_ENTRY:
|
||||
killEvents(KEY_EXIT);
|
||||
killEvents(KEY_UP);
|
||||
killEvents(KEY_DOWN);
|
||||
killEvents(KEY_PLUS);
|
||||
killEvents(KEY_MINUS);
|
||||
// no break
|
||||
|
||||
case EVT_ENTRY_UP:
|
||||
|
@ -485,8 +498,8 @@ void menuMainView(event_t event)
|
|||
#endif
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
case EVT_ROTARY_LEFT:
|
||||
case EVT_ROTARY_RIGHT:
|
||||
|
@ -514,29 +527,47 @@ void menuMainView(event_t event)
|
|||
lcdDrawBitmap(BITMAP_X, BITMAP_Y, modelBitmap);
|
||||
|
||||
// Switches
|
||||
if (getSwitchCount() > 8) {
|
||||
for (int i=0; i<NUM_SWITCHES; ++i) {
|
||||
div_t qr = div(i, 9);
|
||||
if (g_model.view == VIEW_INPUTS) {
|
||||
div_t qr2 = div(qr.rem, 5);
|
||||
if (i >= 14) qr2.rem += 1;
|
||||
const coord_t x[4] = { 50, 142 };
|
||||
const coord_t y[4] = { 25, 42, 25, 42 };
|
||||
displaySwitch(x[qr.quot]+qr2.rem*4, y[qr2.quot], 3, i);
|
||||
}
|
||||
else {
|
||||
displaySwitch(17+qr.rem*6, 25+qr.quot*17, 5, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int index = 0;
|
||||
for (int i=0; i<NUM_SWITCHES; ++i) {
|
||||
// Regular radio
|
||||
// -> 2 columns: one for each side
|
||||
// -> 8 slots on each side (2 columns of 4)
|
||||
|
||||
uint8_t switches = switchGetMaxSwitches();
|
||||
if (getSwitchCount() > 16) { // beware, there is a desired col/row swap in this special mode
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
|
||||
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
|
||||
drawSwitch((g_model.view == VIEW_INPUTS) ? (index<4 ? 8*FW+1 : 23*FW+2) : (index<4 ? 3*FW+1 : 8*FW-2), (index%4)*FH+3*FH, sw, 0, false);
|
||||
index++;
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (g_model.view == VIEW_INPUTS) {
|
||||
coord_t x = 50 + (switch_display.row % 5) * 4 +
|
||||
(switch_display.col == 0 ? 0 : 93) +
|
||||
(switch_display.row < 5 ? 0 : 2);
|
||||
coord_t y = switch_display.row < 5 ? 25 : 40;
|
||||
displaySwitch(x, y, 3, i);
|
||||
} else {
|
||||
displaySwitch(17 + switch_display.row * 6,
|
||||
25 + switch_display.col * 17, 5, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
coord_t shiftright = switchGetMaxRow(1) < 4 ? 20 : 0;
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (g_model.view == VIEW_INPUTS) {
|
||||
coord_t x = (switch_display.col == 0 ? 50 : 125) +
|
||||
(switch_display.row < 4 ? 0 : 20) +
|
||||
(switch_display.col == 0 ? 0 : shiftright);
|
||||
coord_t y = 25 + (switch_display.row % 4) * FH;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw =
|
||||
((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(x, y, sw, 0, false);
|
||||
}
|
||||
else {
|
||||
displaySwitch(17 + switch_display.row * 6,
|
||||
25 + switch_display.col * 17, 5, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -566,7 +597,7 @@ void menuMainView(event_t event)
|
|||
lcdDrawSolidHorizontalLine(x, y+6, 4);
|
||||
lcdDrawSolidHorizontalLine(x, y+7, 4);
|
||||
}
|
||||
else if (getSwitch(SWSRC_SW1+sw)) {
|
||||
else if (getSwitch(SWSRC_FIRST_LOGICAL_SWITCH+sw)) {
|
||||
lcdDrawFilledRect(x, y, 4, 8);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "opentx.h"
|
||||
#include "tasks.h"
|
||||
|
||||
|
@ -32,12 +33,12 @@ void menuStatisticsView(event_t event)
|
|||
title(STR_MENUSTAT);
|
||||
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
chainMenu(menuStatisticsDebug);
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
killEvents(event);
|
||||
#if defined(DEBUG_TRACE_BUFFER)
|
||||
|
@ -133,13 +134,13 @@ void menuStatisticsDebug(event_t event)
|
|||
maxMixerDuration = 0;
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
disableVBatBridge();
|
||||
chainMenu(menuStatisticsDebug2);
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
killEvents(event);
|
||||
disableVBatBridge();
|
||||
|
@ -214,7 +215,7 @@ void menuStatisticsDebug2(event_t event)
|
|||
title(STR_MENUDEBUG);
|
||||
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
#if defined(DEBUG_TRACE_BUFFER)
|
||||
chainMenu(menuTraceBuffer);
|
||||
|
@ -223,7 +224,7 @@ void menuStatisticsDebug2(event_t event)
|
|||
#endif
|
||||
return;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
killEvents(event);
|
||||
chainMenu(menuStatisticsDebug);
|
||||
|
@ -257,13 +258,13 @@ void menuTraceBuffer(event_t event)
|
|||
killEvents(event);
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
case EVT_KEY_FIRST(KEY_MINUS):
|
||||
case EVT_KEY_LONG(KEY_PAGE):
|
||||
killEvents(event);
|
||||
chainMenu(menuStatisticsDebug2);
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_PLUS):
|
||||
case EVT_KEY_BREAK(KEY_PAGE):
|
||||
chainMenu(menuStatisticsView);
|
||||
return;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#include "LvglWrapper.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
@ -121,15 +122,16 @@ static void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
|||
data->key = 0;
|
||||
|
||||
if (isEvent()) { // event waiting
|
||||
event_t evt = getEvent(false); // get keyEvent for hard keys other than trim switches
|
||||
event_t evt = getEvent();
|
||||
|
||||
if(evt == EVT_KEY_FIRST(KEY_PGUP) || // generate acoustic/haptic feedback if radio settings allow
|
||||
evt == EVT_KEY_FIRST(KEY_PGDN) ||
|
||||
if(evt == EVT_KEY_FIRST(KEY_PAGEUP) ||
|
||||
evt == EVT_KEY_FIRST(KEY_PAGEDN) ||
|
||||
evt == EVT_KEY_FIRST(KEY_ENTER) ||
|
||||
evt == EVT_KEY_FIRST(KEY_MODEL) ||
|
||||
evt == EVT_KEY_FIRST(KEY_EXIT) ||
|
||||
evt == EVT_KEY_FIRST(KEY_TELEM) ||
|
||||
evt == EVT_KEY_FIRST(KEY_RADIO)) {
|
||||
evt == EVT_KEY_FIRST(KEY_TELE) ||
|
||||
evt == EVT_KEY_FIRST(KEY_SYS)) {
|
||||
// generate acoustic/haptic feedback if radio settings allow
|
||||
audioKeyPress();
|
||||
}
|
||||
|
||||
|
@ -244,7 +246,7 @@ static void rotaryDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
|||
static int8_t prevDir = 0;
|
||||
static uint32_t lastDt = 0;
|
||||
|
||||
rotenc_t newPos = ROTARY_ENCODER_NAVIGATION_VALUE;
|
||||
rotenc_t newPos = rotaryEncoderGetRawValue();
|
||||
rotenc_t diff = (newPos - prevPos) / ROTARY_ENCODER_GRANULARITY;
|
||||
prevPos += diff * ROTARY_ENCODER_GRANULARITY;
|
||||
|
||||
|
@ -270,9 +272,6 @@ static void rotaryDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
|||
_rotary_enc_accel = 0;
|
||||
}
|
||||
|
||||
// For Lua getRotEncSpeed() function
|
||||
rotencSpeed = max(_rotary_enc_accel, (int8_t)1);
|
||||
|
||||
prevDir = dir;
|
||||
lastDt = rotencDt;
|
||||
}
|
||||
|
@ -299,7 +298,7 @@ uint32_t makeLvColor32(uint32_t colorFlags)
|
|||
std::string makeRecolor(std::string value, uint32_t colorFlags)
|
||||
{
|
||||
char s[32];
|
||||
snprintf(s, 32, "#%06x %s#", makeLvColor32(colorFlags), value.c_str());
|
||||
snprintf(s, 32, "#%06" PRIx32 " %s#", makeLvColor32(colorFlags), value.c_str());
|
||||
return std::string(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -346,7 +346,8 @@ void CurveEdit::checkEvents()
|
|||
if (!lockSource) {
|
||||
int16_t val = getMovedSource(MIXSRC_FIRST_INPUT);
|
||||
if (val > 0) {
|
||||
if (val > NUM_STICKS + NUM_POTS + NUM_SLIDERS)
|
||||
// TODO: this code seems odd
|
||||
if (val > MAX_STICKS + MAX_POTS)
|
||||
CurveEdit::currentSource = val + 1 - MIXSRC_FIRST_INPUT;
|
||||
else {
|
||||
CurveEdit::currentSource = expoAddress(val - 1)->srcRaw;
|
||||
|
|
|
@ -239,7 +239,7 @@ FailSafePage::FailSafePage(uint8_t moduleIdx) :
|
|||
|
||||
// Channel name
|
||||
auto line = form->newLine(&grid);
|
||||
const char* ch_label = getSourceString(MIXSRC_CH1 + ch);
|
||||
const char* ch_label = getSourceString(MIXSRC_FIRST_CH + ch);
|
||||
new StaticText(line, rect_t{}, ch_label, 0, COLOR_THEME_PRIMARY1);
|
||||
|
||||
// Channel value
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "theme_manager.h"
|
||||
#include "libopenui.h"
|
||||
|
||||
#include "watchdog_driver.h"
|
||||
|
||||
coord_t drawStringWithIndex(BitmapBuffer * dc, coord_t x, coord_t y, const char * str, int idx, LcdFlags flags, const char * prefix, const char * suffix)
|
||||
{
|
||||
char s[64];
|
||||
|
@ -237,11 +239,6 @@ void drawCurveRef(BitmapBuffer * dc, coord_t x, coord_t y, const CurveRef & curv
|
|||
}
|
||||
}
|
||||
|
||||
void drawStickName(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
dc->drawText(x, y, STR_VSRCRAW[idx]+1, att);
|
||||
}
|
||||
|
||||
void drawModelName(BitmapBuffer * dc, coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att)
|
||||
{
|
||||
uint8_t len = sizeof(g_model.header.name);
|
||||
|
|
|
@ -81,7 +81,7 @@ void drawHexNumber(BitmapBuffer * dc, coord_t x, coord_t y, uint32_t val, LcdFla
|
|||
void drawTextLines(BitmapBuffer * dc, coord_t left, coord_t top, coord_t width, coord_t height, const char * str, LcdFlags flags);
|
||||
inline void drawChn(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
drawSource(dc, x, y, MIXSRC_CH1 + idx - 1, flags);
|
||||
drawSource(dc, x, y, MIXSRC_FIRST_CH + idx - 1, flags);
|
||||
}
|
||||
|
||||
// Screen templates
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "opentx.h"
|
||||
#include "libopenui.h"
|
||||
|
||||
#include "watchdog_driver.h"
|
||||
|
||||
static Window* _get_parent()
|
||||
{
|
||||
Window* p = Layer::back();
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include "hw_inputs.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "analogs.h"
|
||||
#include "switches.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
struct HWInputEdit : public RadioTextEdit {
|
||||
|
@ -42,10 +47,13 @@ HWSticks::HWSticks(Window* parent) : FormGroup(parent, rect_t{})
|
|||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_STICKS; i++) {
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
for (int i = 0; i < max_sticks; i++) {
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[i + 1], 0, COLOR_THEME_PRIMARY1);
|
||||
new HWInputEdit(line, g_eeGeneral.anaNames[i], LEN_ANA_NAME);
|
||||
new StaticText(line, rect_t{}, analogGetCanonicalName(ADC_INPUT_MAIN, i),
|
||||
0, COLOR_THEME_PRIMARY1);
|
||||
new HWInputEdit(line, (char*)analogGetCustomLabel(ADC_INPUT_MAIN, i),
|
||||
LEN_ANA_NAME);
|
||||
}
|
||||
|
||||
#if defined(STICK_DEAD_ZONE)
|
||||
|
@ -64,13 +72,17 @@ HWPots::HWPots(Window* parent) : FormGroup(parent, rect_t{})
|
|||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_POTS; i++) {
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
for (int i = 0; i < max_pots; i++) {
|
||||
// TODO: check initialised ADC inputs instead!
|
||||
|
||||
// Display EX3 & EX4 (= last two pots) only when FlySky gimbals are present
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
#endif
|
||||
// TODO: use input disabled mask instead
|
||||
// #if !defined(SIMU) && defined(RADIO_FAMILY_T16)
|
||||
// if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
// #endif
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[i + NUM_STICKS + 1], 0,
|
||||
new StaticText(line, rect_t{}, analogGetCanonicalName(ADC_INPUT_POT, i), 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
|
@ -79,56 +91,21 @@ HWPots::HWPots(Window* parent) : FormGroup(parent, rect_t{})
|
|||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.anaNames[i + NUM_STICKS], LEN_ANA_NAME);
|
||||
new HWInputEdit(box, (char*)analogGetCustomLabel(ADC_INPUT_POT, i), LEN_ANA_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_POTTYPES, POT_NONE, POT_WITHOUT_DETENT,
|
||||
box, rect_t{}, STR_POTTYPES, POT_NONE, POT_SLIDER_WITH_DETENT,
|
||||
[=]() -> int {
|
||||
return bfGet<uint32_t>(g_eeGeneral.potsConfig, 2 * i, 2);
|
||||
return bfGet<potconfig_t>(g_eeGeneral.potsConfig, POT_CFG_BITS * i,
|
||||
POT_CFG_BITS);
|
||||
},
|
||||
[=](int newValue) {
|
||||
g_eeGeneral.potsConfig =
|
||||
bfSet<uint32_t>(g_eeGeneral.potsConfig, newValue, 2 * i, 2);
|
||||
g_eeGeneral.potsConfig = bfSet<potconfig_t>(
|
||||
g_eeGeneral.potsConfig, newValue, POT_CFG_BITS * i, POT_CFG_BITS);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
HWSliders::HWSliders(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
#if (NUM_SLIDERS > 0)
|
||||
for (int i = 0; i < NUM_SLIDERS; i++) {
|
||||
const int idx = i + NUM_STICKS + NUM_POTS;
|
||||
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[idx + 1], 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.anaNames[idx], LEN_ANA_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_SLIDERTYPES, SLIDER_NONE, SLIDER_WITH_DETENT,
|
||||
[=]() -> int {
|
||||
uint8_t mask = (0x01 << i);
|
||||
return (g_eeGeneral.slidersConfig & mask) >> i;
|
||||
},
|
||||
[=](int newValue) {
|
||||
uint8_t mask = (0x01 << i);
|
||||
g_eeGeneral.slidersConfig &= ~mask;
|
||||
g_eeGeneral.slidersConfig |= (newValue << i);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
class SwitchDynamicLabel : public StaticText
|
||||
{
|
||||
public:
|
||||
|
@ -141,7 +118,7 @@ class SwitchDynamicLabel : public StaticText
|
|||
|
||||
std::string label()
|
||||
{
|
||||
std::string str(STR_VSRCRAW[index + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1]);
|
||||
std::string str(switchGetName(index));
|
||||
return str + getSwitchPositionSymbol(lastpos);
|
||||
}
|
||||
|
||||
|
@ -170,22 +147,12 @@ class SwitchDynamicLabel : public StaticText
|
|||
uint8_t lastpos = 0xff;
|
||||
};
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#define SWITCH_TYPE_MAX(sw) \
|
||||
((MIXSRC_SF - MIXSRC_FIRST_SWITCH == sw || \
|
||||
MIXSRC_SH - MIXSRC_FIRST_SWITCH == sw) \
|
||||
? SWITCH_2POS \
|
||||
: SWITCH_3POS)
|
||||
#else
|
||||
#define SWITCH_TYPE_MAX(sw) (SWITCH_3POS)
|
||||
#endif
|
||||
|
||||
HWSwitches::HWSwitches(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_SWITCHES; i++) {
|
||||
for (int i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
auto line = newLine(&grid);
|
||||
new SwitchDynamicLabel(line, i);
|
||||
|
||||
|
@ -195,14 +162,15 @@ HWSwitches::HWSwitches(Window* parent) : FormGroup(parent, rect_t{})
|
|||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.switchNames[i], LEN_SWITCH_NAME);
|
||||
new HWInputEdit(box, (char*)switchGetCustomName(i), LEN_SWITCH_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_SWTYPES, SWITCH_NONE, SWITCH_TYPE_MAX(i),
|
||||
box, rect_t{}, STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
|
||||
[=]() -> int { return SWITCH_CONFIG(i); },
|
||||
[=](int newValue) {
|
||||
swconfig_t mask = (swconfig_t)0x03 << (2 * i);
|
||||
g_eeGeneral.switchConfig = (g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(newValue) & 0x03) << (2 * i));
|
||||
swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(i);
|
||||
g_eeGeneral.switchConfig =
|
||||
(g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(newValue) & SW_CFG_MASK) << (SW_CFG_BITS * i));
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
|
@ -221,5 +189,4 @@ HWInputDialog<T>::HWInputDialog(const char* title) :
|
|||
|
||||
template struct HWInputDialog<HWSticks>;
|
||||
template struct HWInputDialog<HWPots>;
|
||||
template struct HWInputDialog<HWSliders>;
|
||||
template struct HWInputDialog<HWSwitches>;
|
||||
|
|
|
@ -33,9 +33,6 @@ struct HWPots : public FormGroup {
|
|||
HWPots(Window* parent);
|
||||
};
|
||||
|
||||
struct HWSliders : public FormGroup {
|
||||
HWSliders(Window* parent);
|
||||
};
|
||||
|
||||
struct HWSwitches : public FormGroup {
|
||||
HWSwitches(Window* parent);
|
||||
|
|
|
@ -59,11 +59,16 @@ InputEditAdvanced::InputEditAdvanced(uint8_t input_n, uint8_t index) :
|
|||
// Trim
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_TRIM, 0, COLOR_THEME_PRIMARY1);
|
||||
auto c = new Choice(line, rect_t{}, STR_VMIXTRIMS, -TRIM_OFF,
|
||||
-TRIM_LAST, GET_VALUE(-input->trimSource),
|
||||
auto c = new Choice(line, rect_t{}, -TRIM_OFF, -TRIM_LAST,
|
||||
GET_VALUE(-input->trimSource),
|
||||
SET_VALUE(input->trimSource, -newValue));
|
||||
|
||||
uint16_t srcRaw = input->srcRaw;
|
||||
c->setAvailableHandler([=](int value) {
|
||||
return value != TRIM_ON || input->srcRaw <= MIXSRC_Ail;
|
||||
return value != TRIM_ON || srcRaw <= MIXSRC_LAST_STICK;
|
||||
});
|
||||
c->setTextHandler([=](int value) -> std::string {
|
||||
return getTrimSourceLabel(srcRaw, -value);
|
||||
});
|
||||
|
||||
// Flight modes
|
||||
|
|
|
@ -55,9 +55,9 @@ InputMixGroup::InputMixGroup(Window* parent, mixsrc_t idx) :
|
|||
|
||||
lv_obj_t* chText = nullptr;
|
||||
if (idx >= MIXSRC_FIRST_CH && idx <= MIXSRC_LAST_CH
|
||||
&& g_model.limitData[idx - MIXSRC_CH1].name[0] != '\0') {
|
||||
&& g_model.limitData[idx - MIXSRC_FIRST_CH].name[0] != '\0') {
|
||||
chText = lv_label_create(lvobj);
|
||||
lv_label_set_text_fmt(chText, TR_CH "%zu", (size_t)(idx - MIXSRC_CH1 + 1));
|
||||
lv_label_set_text_fmt(chText, TR_CH "%zu", (size_t)(idx - MIXSRC_FIRST_CH + 1));
|
||||
lv_obj_set_style_text_font(chText, getFont(FONT(XS)), 0);
|
||||
#if LCD_H > LCD_W
|
||||
lv_obj_set_style_pad_bottom(chText, -2, 0);
|
||||
|
|
|
@ -32,24 +32,6 @@ class SensorValue : public StaticText
|
|||
{
|
||||
}
|
||||
|
||||
// void paint(BitmapBuffer *dc) override
|
||||
// {
|
||||
// if (isTelemetryValue()) {
|
||||
// uint8_t sensorIndex = (input->srcRaw - MIXSRC_FIRST_TELEM) / 3;
|
||||
// #if defined(SIMU)
|
||||
// if (true) {
|
||||
// #else
|
||||
// TelemetryItem &telemetryItem = telemetryItems[sensorIndex];
|
||||
// if (telemetryItem.isAvailable()) {
|
||||
// #endif
|
||||
// LcdFlags flags = LEFT | COLOR_THEME_PRIMARY1;
|
||||
// drawSensorCustomValue(dc, 3, 2, sensorIndex, lastSensorVal, flags);
|
||||
// } else {
|
||||
// dc->drawText(3, 2, "---", COLOR_THEME_PRIMARY1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
bool isTelemetryValue()
|
||||
{
|
||||
return input->srcRaw >= MIXSRC_FIRST_TELEM &&
|
||||
|
@ -143,7 +125,7 @@ InputSource::InputSource(Window* parent, ExpoData* input) :
|
|||
|
||||
void InputSource::update()
|
||||
{
|
||||
if (input->srcRaw > MIXSRC_Ail && input->trimSource == TRIM_ON) {
|
||||
if (input->srcRaw > MIXSRC_LAST_STICK && input->trimSource == TRIM_ON) {
|
||||
input->trimSource = TRIM_OFF;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
#include "sliders.h"
|
||||
#include "opentx.h"
|
||||
#include "switches.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
enum slider_type {
|
||||
SLIDER_HORIZ,
|
||||
|
@ -43,6 +46,23 @@ static void slider_self_size(lv_event_t* e)
|
|||
}
|
||||
}
|
||||
|
||||
MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect,
|
||||
uint8_t idx) :
|
||||
Window(parent, rect), idx(idx)
|
||||
{
|
||||
}
|
||||
|
||||
void MainViewSlider::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
auto pot_idx = adcGetInputOffset(ADC_INPUT_POT) + idx;
|
||||
int16_t newValue = calibratedAnalogs[pot_idx];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
MainViewHorizontalSlider::MainViewHorizontalSlider(Window* parent,
|
||||
uint8_t idx) :
|
||||
MainViewSlider(parent, rect_t{}, idx)
|
||||
|
@ -86,7 +106,6 @@ MainView6POS::MainView6POS(Window* parent, uint8_t idx) :
|
|||
|
||||
void MainView6POS::paint(BitmapBuffer * dc)
|
||||
{
|
||||
#if NUM_XPOTS > 0 // prevent compiler warning
|
||||
coord_t x = MULTIPOS_W_SPACING/4;
|
||||
for (uint8_t value = 0; value < XPOTS_MULTIPOS_COUNT; value++) {
|
||||
dc->drawNumber(x+TRIM_SQUARE_SIZE/4, 0, value+1, FONT(XS) | COLOR_THEME_SECONDARY1);
|
||||
|
@ -94,23 +113,20 @@ void MainView6POS::paint(BitmapBuffer * dc)
|
|||
}
|
||||
|
||||
// The square
|
||||
value = (potsPos[idx] & 0x0f);
|
||||
x = MULTIPOS_W_SPACING/4+MULTIPOS_W_SPACING*value;
|
||||
value = getXPotPosition(idx);
|
||||
x = MULTIPOS_W_SPACING / 4 + MULTIPOS_W_SPACING * value;
|
||||
drawTrimSquare(dc, x, 0, COLOR_THEME_FOCUS);
|
||||
dc->drawNumber(x+MULTIPOS_W_SPACING/4, -2, value+1, FONT(BOLD) | COLOR_THEME_PRIMARY2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainView6POS::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
#if NUM_XPOTS > 0 // prevent compiler warning
|
||||
int16_t newValue = (potsPos[idx] & 0x0f);
|
||||
int16_t newValue = getXPotPosition(idx);
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MainViewVerticalSlider::MainViewVerticalSlider(Window* parent, uint8_t idx) :
|
||||
|
|
|
@ -39,21 +39,8 @@ constexpr coord_t VERTICAL_SLIDERS_HEIGHT = SLIDER_TICKS_COUNT * 4 + TRIM_SQUARE
|
|||
class MainViewSlider : public Window
|
||||
{
|
||||
public:
|
||||
MainViewSlider(Window * parent, const rect_t & rect, uint8_t idx):
|
||||
Window(parent, rect),
|
||||
idx(idx)
|
||||
{
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
Window::checkEvents();
|
||||
int16_t newValue = calibratedAnalogs[idx];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx);
|
||||
void checkEvents() override;
|
||||
|
||||
protected:
|
||||
uint8_t idx;
|
||||
|
@ -65,7 +52,7 @@ class MainViewHorizontalSlider : public MainViewSlider
|
|||
public:
|
||||
using MainViewSlider::MainViewSlider;
|
||||
MainViewHorizontalSlider(Window* parent, uint8_t idx);
|
||||
void paint(BitmapBuffer * dc) override;
|
||||
void paint(BitmapBuffer* dc) override;
|
||||
};
|
||||
|
||||
class MainView6POS : public MainViewSlider
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "trims.h"
|
||||
#include "sliders.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
|
@ -67,7 +68,7 @@ void MainViewTrim::setRange()
|
|||
void MainViewTrim::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
int8_t stickIndex = CONVERT_MODE(idx);
|
||||
int8_t stickIndex = inputMappingConvertMode(idx);
|
||||
int newValue = getTrimValue(mixerCurrentFlightMode, stickIndex);
|
||||
|
||||
setRange();
|
||||
|
|
|
@ -72,7 +72,7 @@ MixEditWindow::MixEditWindow(int8_t channel, uint8_t index) :
|
|||
|
||||
void MixEditWindow::buildHeader(Window *window)
|
||||
{
|
||||
std::string title2(getSourceString(MIXSRC_CH1 + channel));
|
||||
std::string title2(getSourceString(MIXSRC_FIRST_CH + channel));
|
||||
header.setTitle(STR_MIXES);
|
||||
header.setTitle2(title2);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ MixEditAdvanced::MixEditAdvanced(int8_t channel, uint8_t index) :
|
|||
{
|
||||
std::string title(STR_MIXES);
|
||||
title += "\n";
|
||||
title += getSourceString(MIXSRC_CH1 + channel);
|
||||
title += getSourceString(MIXSRC_FIRST_CH + channel);
|
||||
header.setTitle(title);
|
||||
|
||||
auto form = new FormWindow(&body, rect_t{});
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "opentx.h"
|
||||
#include "libopenui.h"
|
||||
#include "lvgl_widgets/input_mix_line.h"
|
||||
#include "hal/key_driver.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
|
@ -107,7 +108,7 @@ class FlightModeEdit : public Page
|
|||
|
||||
FlexGridLayout trim_grid(trims_col_dsc, line_row_dsc);
|
||||
|
||||
for (int t = 0; t < NUM_TRIMS; t++) {
|
||||
for (int t = 0; t < MAX_TRIMS; t++) {
|
||||
lastTrim[t] = p_fm->trim[t].value;
|
||||
|
||||
if ((t % TRIMS_PER_LINE) == 0) {
|
||||
|
@ -160,7 +161,7 @@ class FlightModeEdit : public Page
|
|||
|
||||
void checkEvents() override
|
||||
{
|
||||
for (int i = 0; i < NUM_TRIMS; i += 1) {
|
||||
for (int i = 0; i < keysGetMaxTrims(); i += 1) {
|
||||
const auto& fm = g_model.flightModeData[index];
|
||||
if (lastTrim[i] != fm.trim[i].value) {
|
||||
lastTrim[i] = fm.trim[i].value;
|
||||
|
@ -171,9 +172,9 @@ class FlightModeEdit : public Page
|
|||
|
||||
protected:
|
||||
uint8_t index;
|
||||
Choice* tr_mode[NUM_TRIMS] = {nullptr};
|
||||
NumberEdit* tr_value[NUM_TRIMS] = {nullptr};
|
||||
int lastTrim[NUM_TRIMS];
|
||||
Choice* tr_mode[MAX_TRIMS] = {nullptr};
|
||||
NumberEdit* tr_value[MAX_TRIMS] = {nullptr};
|
||||
int lastTrim[MAX_TRIMS];
|
||||
|
||||
void showControls(int trim, uint8_t mode)
|
||||
{
|
||||
|
@ -413,7 +414,7 @@ class FlightModeBtn : public Button
|
|||
lv_obj_t* trims_cont = fmStyle.newTrimCont(container);
|
||||
lv_obj_set_user_data(trims_cont, this);
|
||||
|
||||
for (int i = 0; i < NUM_TRIMS; i += 1) {
|
||||
for (int i = 0; i < keysGetMaxTrims(); i += 1) {
|
||||
fmTrimMode[i] = fmStyle.newTrimMode(trims_cont, i);
|
||||
fmTrimValue[i] = fmStyle.newTrimValue(trims_cont, i);
|
||||
}
|
||||
|
@ -446,7 +447,7 @@ class FlightModeBtn : public Button
|
|||
if (!refreshing && init) {
|
||||
refreshing = true;
|
||||
const auto& fm = g_model.flightModeData[index];
|
||||
for (int t = 0; t < NUM_TRIMS; t += 1) {
|
||||
for (int t = 0; t < keysGetMaxTrims(); t += 1) {
|
||||
if (lastTrim[t] != fm.trim[t].value) {
|
||||
lastTrim[t] = fm.trim[t].value;
|
||||
|
||||
|
@ -485,7 +486,7 @@ class FlightModeBtn : public Button
|
|||
lv_label_set_text(fmSwitch, "");
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_TRIMS; i += 1) {
|
||||
for (int i = 0; i < keysGetMaxTrims(); i += 1) {
|
||||
uint8_t mode = fm.trim[i].mode;
|
||||
bool checked = (mode != TRIM_MODE_NONE);
|
||||
bool showValue = (index == 0) || ((mode & 1) || (mode >> 1 == index));
|
||||
|
@ -510,11 +511,11 @@ class FlightModeBtn : public Button
|
|||
lv_obj_t* fmID = nullptr;
|
||||
lv_obj_t* fmName = nullptr;
|
||||
lv_obj_t* fmSwitch = nullptr;
|
||||
lv_obj_t* fmTrimMode[NUM_TRIMS] = {nullptr};
|
||||
lv_obj_t* fmTrimValue[NUM_TRIMS] = {nullptr};
|
||||
lv_obj_t* fmTrimMode[MAX_TRIMS] = {nullptr};
|
||||
lv_obj_t* fmTrimValue[MAX_TRIMS] = {nullptr};
|
||||
lv_obj_t* fmFadeIn = nullptr;
|
||||
lv_obj_t* fmFadeOut = nullptr;
|
||||
int lastTrim[NUM_TRIMS];
|
||||
int lastTrim[MAX_TRIMS];
|
||||
};
|
||||
|
||||
ModelFlightModesPage::ModelFlightModesPage():
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
#include "input_edit.h"
|
||||
#include "input_mix_group.h"
|
||||
#include "input_mix_button.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
@ -90,7 +93,11 @@ void insertExpo(uint8_t idx, uint8_t input)
|
|||
ExpoData * expo = expoAddress(idx);
|
||||
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
|
||||
memclear(expo, sizeof(ExpoData));
|
||||
expo->srcRaw = (input >= 4 ? MIXSRC_Rud + input : MIXSRC_Rud + channelOrder(input + 1) - 1);
|
||||
if (input >= adcGetMaxInputs(ADC_INPUT_MAIN)) {
|
||||
expo->srcRaw = MIXSRC_FIRST_STICK + input;
|
||||
} else {
|
||||
expo->srcRaw = MIXSRC_FIRST_STICK + inputMappingChannelOrder(input);
|
||||
}
|
||||
expo->curve.type = CURVE_REF_EXPO;
|
||||
expo->mode = 3; // pos+neg
|
||||
expo->chn = input;
|
||||
|
|
|
@ -72,7 +72,8 @@ class LogicalSwitchEditPage : public Page
|
|||
void buildHeader(Window* window)
|
||||
{
|
||||
header.setTitle(STR_MENULOGICALSWITCHES);
|
||||
headerSwitchName = header.setTitle2(getSwitchPositionName(SWSRC_SW1 + index));
|
||||
headerSwitchName = header.setTitle2(
|
||||
getSwitchPositionName(SWSRC_FIRST_LOGICAL_SWITCH + index));
|
||||
|
||||
lv_obj_set_style_text_color(headerSwitchName->getLvObj(),
|
||||
makeLvColor(COLOR_THEME_ACTIVE),
|
||||
|
@ -413,7 +414,7 @@ class LogicalSwitchButton : public Button
|
|||
LogicalSwitchData* ls = lswAddress(lsIndex);
|
||||
uint8_t lsFamily = lswFamily(ls->func);
|
||||
|
||||
lv_label_set_text(lsName, getSwitchPositionName(SWSRC_SW1 + lsIndex));
|
||||
lv_label_set_text(lsName, getSwitchPositionName(SWSRC_FIRST_LOGICAL_SWITCH + lsIndex));
|
||||
lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]);
|
||||
|
||||
// CSW params - V1
|
||||
|
@ -528,7 +529,7 @@ void ModelLogicalSwitchesPage::newLS(FormWindow* window, bool pasteLS)
|
|||
for (uint8_t i = 0; i < MAX_LOGICAL_SWITCHES; i++) {
|
||||
LogicalSwitchData* ls = lswAddress(i);
|
||||
if (ls->func == LS_FUNC_NONE) {
|
||||
std::string ch_name(getSwitchPositionName(SWSRC_SW1 + i));
|
||||
std::string ch_name(getSwitchPositionName(SWSRC_FIRST_LOGICAL_SWITCH + i));
|
||||
menu->addLineBuffered(ch_name.c_str(), [=]() {
|
||||
if (pasteLS) {
|
||||
*ls = clipboard.data.csw;
|
||||
|
|
|
@ -30,8 +30,10 @@
|
|||
#include "input_mix_group.h"
|
||||
#include "input_mix_button.h"
|
||||
#include "mixer_edit.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
#define PASTE_BEFORE -2
|
||||
|
@ -75,8 +77,11 @@ void insertMix(uint8_t idx, uint8_t channel)
|
|||
mix->destCh = channel;
|
||||
mix->srcRaw = channel + 1;
|
||||
if (!isSourceAvailable(mix->srcRaw)) {
|
||||
mix->srcRaw = (channel > 3 ? MIXSRC_Rud - 1 + channel
|
||||
: MIXSRC_Rud - 1 + channelOrder(channel));
|
||||
if (channel >= adcGetMaxInputs(ADC_INPUT_MAIN)) {
|
||||
mix->srcRaw = MIXSRC_FIRST_STICK + channel;
|
||||
} else {
|
||||
mix->srcRaw = MIXSRC_FIRST_STICK + inputMappingChannelOrder(channel);
|
||||
}
|
||||
while (!isSourceAvailable(mix->srcRaw)) {
|
||||
mix->srcRaw += 1;
|
||||
}
|
||||
|
@ -320,13 +325,13 @@ InputMixGroup* ModelMixesPage::getGroupByIndex(uint8_t index)
|
|||
if (is_memclear(mix, sizeof(MixData))) return nullptr;
|
||||
|
||||
int ch = mix->destCh;
|
||||
return getGroupBySrc(MIXSRC_CH1 + ch);
|
||||
return getGroupBySrc(MIXSRC_FIRST_CH + ch);
|
||||
}
|
||||
|
||||
InputMixGroup* ModelMixesPage::createGroup(FormWindow* form, mixsrc_t src)
|
||||
{
|
||||
auto group = new InputMixGroup(form, src);
|
||||
if (showMonitors) group->enableMixerMonitor(src - MIXSRC_CH1);
|
||||
if (showMonitors) group->enableMixerMonitor(src - MIXSRC_FIRST_CH);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -338,7 +343,7 @@ InputMixButton* ModelMixesPage::createLineButton(InputMixGroup *group, uint8_t i
|
|||
lines.emplace_back(button);
|
||||
group->addLine(button);
|
||||
|
||||
uint8_t ch = group->getMixSrc() - MIXSRC_CH1;
|
||||
uint8_t ch = group->getMixSrc() - MIXSRC_FIRST_CH;
|
||||
button->setPressHandler([=]() -> uint8_t {
|
||||
Menu *menu = new Menu(form);
|
||||
menu->addLine(STR_EDIT, [=]() {
|
||||
|
@ -394,7 +399,7 @@ void ModelMixesPage::addLineButton(uint8_t index)
|
|||
if (is_memclear(mix, sizeof(MixData))) return;
|
||||
int channel = mix->destCh;
|
||||
|
||||
addLineButton(MIXSRC_CH1 + channel, index);
|
||||
addLineButton(MIXSRC_FIRST_CH + channel, index);
|
||||
}
|
||||
|
||||
void ModelMixesPage::newMix()
|
||||
|
@ -416,7 +421,7 @@ void ModelMixesPage::newMix()
|
|||
skip_mix = (ch == 0 && is_memclear(line, sizeof(MixData)));
|
||||
}
|
||||
} else {
|
||||
std::string ch_name(getSourceString(MIXSRC_CH1 + ch));
|
||||
std::string ch_name(getSourceString(MIXSRC_FIRST_CH + ch));
|
||||
menu->addLineBuffered(ch_name.c_str(), [=]() { insertMix(ch, index); });
|
||||
}
|
||||
}
|
||||
|
@ -447,7 +452,7 @@ void ModelMixesPage::insertMix(uint8_t channel, uint8_t index)
|
|||
_copyMode = 0;
|
||||
|
||||
::insertMix(index, channel);
|
||||
addLineButton(MIXSRC_CH1 + channel, index);
|
||||
addLineButton(MIXSRC_FIRST_CH + channel, index);
|
||||
editMix(channel, index);
|
||||
}
|
||||
|
||||
|
@ -531,7 +536,7 @@ void ModelMixesPage::build(FormWindow * window)
|
|||
if (line->destCh == ch && !skip_mix) {
|
||||
|
||||
// one group for the complete mixer channel
|
||||
auto group = createGroup(form, MIXSRC_CH1 + ch);
|
||||
auto group = createGroup(form, MIXSRC_FIRST_CH + ch);
|
||||
groups.emplace_back(group);
|
||||
while (index < MAX_MIXERS && (line->destCh == ch) && !skip_mix) {
|
||||
// one button per input line
|
||||
|
@ -573,7 +578,7 @@ void ModelMixesPage::enableMonitors(bool enabled)
|
|||
auto h = lv_obj_get_height(form_obj);
|
||||
for(auto* group : groups) {
|
||||
if (enabled) {
|
||||
group->enableMixerMonitor(group->getMixSrc() - MIXSRC_CH1);
|
||||
group->enableMixerMonitor(group->getMixSrc() - MIXSRC_FIRST_CH);
|
||||
} else {
|
||||
group->disableMixerMonitor();
|
||||
}
|
||||
|
|
|
@ -191,10 +191,10 @@ class OutputLineButton : public ListLineButton
|
|||
lv_obj_set_style_pad_top(source, -7, 0);
|
||||
lv_obj_set_style_pad_bottom(source, -7, 0);
|
||||
#endif
|
||||
lv_label_set_text_fmt(source, "%s\n" TR_CH "%u", getSourceString(MIXSRC_CH1 + index), index + 1);
|
||||
lv_label_set_text_fmt(source, "%s\n" TR_CH "%u", getSourceString(MIXSRC_FIRST_CH + index), index + 1);
|
||||
} else {
|
||||
lv_obj_set_style_text_font(source, getFont(FONT(STD)), 0);
|
||||
lv_label_set_text(source, getSourceString(MIXSRC_CH1 + index));
|
||||
lv_label_set_text(source, getSourceString(MIXSRC_FIRST_CH + index));
|
||||
}
|
||||
if (output->revert) {
|
||||
lv_obj_clear_flag(revert, LV_OBJ_FLAG_HIDDEN);
|
||||
|
|
|
@ -667,18 +667,18 @@ ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL)
|
|||
void ModelLabelsWindow::onEvent(event_t event)
|
||||
{
|
||||
#if defined(KEYS_GPIO_REG_PGUP)
|
||||
if (event == EVT_KEY_BREAK(KEY_PGUP) ||
|
||||
event == EVT_KEY_BREAK(KEY_PGDN)) {
|
||||
if (event == EVT_KEY_BREAK(KEY_PAGEUP) ||
|
||||
event == EVT_KEY_BREAK(KEY_PAGEDN)) {
|
||||
#else
|
||||
if (event == EVT_KEY_LONG(KEY_PGDN) ||
|
||||
event == EVT_KEY_BREAK(KEY_PGDN)) {
|
||||
if (event == EVT_KEY_LONG(KEY_PAGEDN) ||
|
||||
event == EVT_KEY_BREAK(KEY_PAGEDN)) {
|
||||
#endif
|
||||
std::set<uint32_t> curSel = lblselector->getSelection();
|
||||
std::set<uint32_t> sellist;
|
||||
int select = 0;
|
||||
int rowcount = lblselector->getRowCount();
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_PGDN)) {
|
||||
if (event == EVT_KEY_BREAK(KEY_PAGEDN)) {
|
||||
if(curSel.size())
|
||||
select = (*curSel.rbegin() + 1) % rowcount;
|
||||
} else {
|
||||
|
|
|
@ -280,7 +280,7 @@ class USBChannelEditWindow : public Page
|
|||
void buildHeader(Window *window)
|
||||
{
|
||||
header.setTitle(STR_USBJOYSTICK_LABEL);
|
||||
header.setTitle2(getSourceString(MIXSRC_CH1 + channel));
|
||||
header.setTitle2(getSourceString(MIXSRC_FIRST_CH + channel));
|
||||
|
||||
statusBar = new USBChannelEditStatusBar(
|
||||
window,
|
||||
|
@ -418,7 +418,7 @@ class USBChannelLineButton : public Button
|
|||
lv_obj_set_grid_cell(m_btns, LV_GRID_ALIGN_START, USBCH_BTN_MODE_COL+1, 1,
|
||||
LV_GRID_ALIGN_CENTER, USBCH_BTN_MODE_ROW, 1);
|
||||
|
||||
lv_label_set_text(m_chn, getSourceString(MIXSRC_CH1 + index));
|
||||
lv_label_set_text(m_chn, getSourceString(MIXSRC_FIRST_CH + index));
|
||||
lv_label_set_text(m_mode, "");
|
||||
lv_label_set_text(m_param, "");
|
||||
lv_label_set_text(m_btn_mode, "");
|
||||
|
|
|
@ -62,7 +62,7 @@ class OutputEditStatusBar : public Window
|
|||
OutputEditWindow::OutputEditWindow(uint8_t channel) :
|
||||
Page(ICON_MODEL_OUTPUTS), channel(channel)
|
||||
{
|
||||
std::string title2(getSourceString(MIXSRC_CH1 + channel));
|
||||
std::string title2(getSourceString(MIXSRC_FIRST_CH + channel));
|
||||
header.setTitle(STR_MENULIMITS);
|
||||
header.setTitle2(title2);
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "libopenui.h"
|
||||
#include "pwr.h"
|
||||
|
||||
#include "watchdog_driver.h"
|
||||
|
||||
static void _run_popup_dialog(const char* title, const char* msg,
|
||||
const char* info = nullptr)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "button_matrix.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "strhelpers.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
|
@ -79,7 +83,7 @@ struct SwitchWarnMatrix : public ButtonMatrix {
|
|||
bool isActive(uint8_t btn_id);
|
||||
void setTextWithColor(uint8_t btn_id);
|
||||
private:
|
||||
uint8_t sw_idx[NUM_SWITCHES];
|
||||
uint8_t sw_idx[MAX_SWITCHES];
|
||||
};
|
||||
|
||||
struct PotWarnMatrix : public ButtonMatrix {
|
||||
|
@ -88,7 +92,7 @@ struct PotWarnMatrix : public ButtonMatrix {
|
|||
bool isActive(uint8_t btn_id);
|
||||
void setTextWithColor(uint8_t btn_id);
|
||||
private:
|
||||
uint8_t pot_idx[NUM_POTS + NUM_SLIDERS];
|
||||
uint8_t pot_idx[MAX_POTS];
|
||||
};
|
||||
|
||||
struct CenterBeepsMatrix : public ButtonMatrix {
|
||||
|
@ -97,7 +101,8 @@ struct CenterBeepsMatrix : public ButtonMatrix {
|
|||
bool isActive(uint8_t btn_id);
|
||||
void setTextWithColor(uint8_t btn_id);
|
||||
private:
|
||||
uint8_t ana_idx[NUM_STICKS + NUM_POTS + NUM_SLIDERS];
|
||||
uint8_t max_analogs;
|
||||
uint8_t ana_idx[MAX_ANALOG_INPUTS];
|
||||
};
|
||||
|
||||
PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
||||
|
@ -145,19 +150,18 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
|||
new SwitchWarnMatrix(line, rect_t{});
|
||||
|
||||
// Pots and sliders warning
|
||||
#if NUM_POTS + NUM_SLIDERS
|
||||
if (adcGetMaxInputs(ADC_INPUT_POT) > 0) {
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_POTWARNINGSTATE, 0, COLOR_THEME_PRIMARY1);
|
||||
auto pots_wm = new Choice(line, rect_t{}, STR_PREFLIGHT_POTSLIDER_CHECK, 0, 2,
|
||||
auto pots_wm = new Choice(line, rect_t{}, {STR_PREFLIGHT_POTSLIDER_CHECK}, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.potsWarnMode));
|
||||
#if (NUM_POTS)
|
||||
|
||||
// Pot warnings
|
||||
line = form->newLine(&grid);
|
||||
line->padTop(0);
|
||||
auto pwm = new PotWarnMatrix(line, rect_t{});
|
||||
make_conditional(pwm, pots_wm);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Center beeps
|
||||
line = form->newLine(&grid);
|
||||
|
@ -170,8 +174,7 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
|||
static std::string switchWarninglabel(swsrc_t index)
|
||||
{
|
||||
auto warn_pos = g_model.switchWarningState >> (3 * index) & 0x07;
|
||||
return TEXT_AT_INDEX(STR_VSRCRAW,
|
||||
(index + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1)) +
|
||||
return std::string(switchGetName(index)) +
|
||||
std::string(getSwitchWarnSymbol(warn_pos));
|
||||
}
|
||||
|
||||
|
@ -187,7 +190,7 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) :
|
|||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < NUM_SWITCHES; i++) {
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
sw_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
|
@ -198,7 +201,7 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) :
|
|||
update();
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint8_t i = 0; i < NUM_SWITCHES; i++) {
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR);
|
||||
setTextWithColor(i);
|
||||
|
@ -225,12 +228,13 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) :
|
|||
|
||||
void SwitchWarnMatrix::setTextWithColor(uint8_t btn_id)
|
||||
{
|
||||
setText(btn_id, makeRecolor(switchWarninglabel(sw_idx[btn_id]), isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str());
|
||||
auto color = isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1;
|
||||
setText(btn_id, makeRecolor(switchWarninglabel(sw_idx[btn_id]), color).c_str());
|
||||
}
|
||||
|
||||
void SwitchWarnMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_SWITCHES) return;
|
||||
if (btn_id >= MAX_SWITCHES) return;
|
||||
auto sw = sw_idx[btn_id];
|
||||
|
||||
swarnstate_t newstate = bfGet(g_model.switchWarningState, 3 * sw, 3);
|
||||
|
@ -249,7 +253,7 @@ void SwitchWarnMatrix::onPress(uint8_t btn_id)
|
|||
|
||||
bool SwitchWarnMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_SWITCHES) return false;
|
||||
if (btn_id >= MAX_SWITCHES) return false;
|
||||
return bfGet(g_model.switchWarningState, 3 * sw_idx[btn_id], 3) != 0;
|
||||
}
|
||||
|
||||
|
@ -258,16 +262,9 @@ PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) :
|
|||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = POT_FIRST; i <= POT_LAST; i++) {
|
||||
if ((IS_POT(i) || IS_POT_MULTIPOS(i)) && IS_POT_AVAILABLE(i)) {
|
||||
pot_idx[btn_cnt] = i - POT_FIRST;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int8_t i = SLIDER_FIRST; i <= SLIDER_LAST; i++) {
|
||||
if (IS_SLIDER(i)) {
|
||||
pot_idx[btn_cnt] = i - POT_FIRST;
|
||||
for (uint8_t i = 0; i <= MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
pot_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
@ -276,15 +273,8 @@ PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) :
|
|||
update();
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint16_t i = POT_FIRST; i <= POT_LAST; i++) {
|
||||
if ((IS_POT(i) || IS_POT_MULTIPOS(i)) && IS_POT_AVAILABLE(i)) {
|
||||
lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR);
|
||||
setTextWithColor(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
for (int8_t i = SLIDER_FIRST; i <= SLIDER_LAST; i++) {
|
||||
if (IS_SLIDER(i)) {
|
||||
for (uint16_t i = 0; i <= MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR);
|
||||
setTextWithColor(btn_id);
|
||||
btn_id++;
|
||||
|
@ -310,12 +300,14 @@ PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) :
|
|||
|
||||
void PotWarnMatrix::setTextWithColor(uint8_t btn_id)
|
||||
{
|
||||
setText(btn_id, makeRecolor(STR_VSRCRAW[pot_idx[btn_id] + POT_FIRST + 1], isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str());
|
||||
auto idx = pot_idx[btn_id];
|
||||
auto color = isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1;
|
||||
setText(btn_id, makeRecolor(getPotLabel(idx), color).c_str());
|
||||
}
|
||||
|
||||
void PotWarnMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_POTS + NUM_SLIDERS) return;
|
||||
if (btn_id >= MAX_POTS) return;
|
||||
auto pot = pot_idx[btn_id];
|
||||
|
||||
g_model.potsWarnEnabled ^= (1 << pot);
|
||||
|
@ -329,7 +321,7 @@ void PotWarnMatrix::onPress(uint8_t btn_id)
|
|||
|
||||
bool PotWarnMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_POTS + NUM_SLIDERS) return false;
|
||||
if (btn_id >= MAX_POTS) return false;
|
||||
return (g_model.potsWarnEnabled & (1 << pot_idx[btn_id])) != 0;
|
||||
}
|
||||
|
||||
|
@ -338,9 +330,15 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) :
|
|||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
max_analogs = max_sticks + max_pots;
|
||||
|
||||
for (uint8_t i = 0; i < max_analogs; i++) {
|
||||
// multipos cannot be centered
|
||||
if (i < NUM_STICKS || (IS_POT_SLIDER_AVAILABLE(i) && !IS_POT_MULTIPOS(i))) {
|
||||
if (i < max_sticks || (IS_POT_SLIDER_AVAILABLE(i - max_sticks) &&
|
||||
!IS_POT_MULTIPOS(i - max_sticks))) {
|
||||
ana_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
|
@ -350,8 +348,9 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) :
|
|||
update();
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
if (i < NUM_STICKS || (IS_POT_SLIDER_AVAILABLE(i) && !IS_POT_MULTIPOS(i))) {
|
||||
for (uint8_t i = 0; i < max_analogs; i++) {
|
||||
if (i < max_sticks || (IS_POT_SLIDER_AVAILABLE(i - max_sticks) &&
|
||||
!IS_POT_MULTIPOS(i - max_sticks))) {
|
||||
lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR);
|
||||
setTextWithColor(btn_id);
|
||||
btn_id++;
|
||||
|
@ -377,15 +376,15 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) :
|
|||
|
||||
void CenterBeepsMatrix::setTextWithColor(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id < NUM_STICKS)
|
||||
setText(btn_id, makeRecolor(STR_RETA123[ana_idx[btn_id]], isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str());
|
||||
else
|
||||
setText(btn_id, makeRecolor(STR_VSRCRAW[ana_idx[btn_id] + 1], isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str());
|
||||
setText(btn_id, makeRecolor(getAnalogShortLabel(ana_idx[btn_id]),
|
||||
isActive(btn_id) ? COLOR_THEME_PRIMARY1
|
||||
: COLOR_THEME_SECONDARY1)
|
||||
.c_str());
|
||||
}
|
||||
|
||||
void CenterBeepsMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_STICKS + NUM_POTS + NUM_SLIDERS) return;
|
||||
if (btn_id >= max_analogs) return;
|
||||
uint8_t i = ana_idx[btn_id];
|
||||
BFBIT_FLIP(g_model.beepANACenter, bfBit<BeepANACenter>(i));
|
||||
setTextWithColor(btn_id);
|
||||
|
@ -394,7 +393,7 @@ void CenterBeepsMatrix::onPress(uint8_t btn_id)
|
|||
|
||||
bool CenterBeepsMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= NUM_STICKS + NUM_POTS + NUM_SLIDERS) return false;
|
||||
if (btn_id >= max_analogs) return false;
|
||||
uint8_t i = ana_idx[btn_id];
|
||||
return bfSingleBitGet<BeepANACenter>(g_model.beepANACenter, i) != 0;
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ class StickCalibrationWindow: public Window {
|
|||
void paint(BitmapBuffer * dc) override
|
||||
{
|
||||
dc->drawBitmap(0, 0, calibStickBackground);
|
||||
int16_t x = calibratedAnalogs[CONVERT_MODE(stickX)];
|
||||
int16_t y = calibratedAnalogs[CONVERT_MODE(stickY)];
|
||||
int16_t x = calibratedAnalogs[stickX];
|
||||
int16_t y = calibratedAnalogs[stickY];
|
||||
dc->drawBitmap(width() / 2 - 9 + (bitmapSize / 2 * x) / RESX,
|
||||
height() / 2 - 9 - (bitmapSize / 2 * y) / RESX,
|
||||
calibStick);
|
||||
|
@ -78,13 +78,15 @@ void RadioCalibrationPage::buildBody(FormWindow * window)
|
|||
// The two sticks
|
||||
|
||||
//TODO: dynamic placing
|
||||
new StickCalibrationWindow(window,
|
||||
{window->width() / 3, window->height() / 2, 0, 0},
|
||||
STICK1, STICK2);
|
||||
new StickCalibrationWindow(
|
||||
window, {window->width() / 3, window->height() / 2, 0, 0}, 0, 1);
|
||||
|
||||
new StickCalibrationWindow(window,
|
||||
{(2 * window->width()) / 3, window->height() / 2, 0, 0},
|
||||
STICK4, STICK3);
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
if (max_sticks > 2) {
|
||||
new StickCalibrationWindow(
|
||||
window, {(2 * window->width()) / 3, window->height() / 2, 0, 0}, 3,
|
||||
2);
|
||||
}
|
||||
|
||||
std::unique_ptr<ViewMainDecoration> deco(new ViewMainDecoration(window));
|
||||
deco->setTrimsVisible(false);
|
||||
|
@ -104,100 +106,15 @@ void RadioCalibrationPage::checkEvents()
|
|||
{
|
||||
Page::checkEvents();
|
||||
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS + NUM_MOUSE_ANALOGS; i++) { // get low and high vals for sticks and trims
|
||||
int16_t vt = i < TX_VOLTAGE ? anaIn(i) : anaIn(i + 1);
|
||||
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
|
||||
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
|
||||
if (i >= POT1 && i <= POT_LAST) {
|
||||
if (IS_POT_WITHOUT_DETENT(i)) {
|
||||
reusableBuffer.calib.midVals[i] = (reusableBuffer.calib.hiVals[i] + reusableBuffer.calib.loVals[i]) / 2;
|
||||
}
|
||||
#if NUM_XPOTS > 0
|
||||
uint8_t idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i) && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
// use raw analog value for multipos calibraton, anaIn() already has multipos decoded value
|
||||
vt = getAnalogValue(i) >> 1;
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 || vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA ||
|
||||
vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastPosition = vt;
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastCount = 1;
|
||||
}
|
||||
else {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].lastCount++;
|
||||
}
|
||||
}
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == XPOT_DELAY) {
|
||||
int16_t position = reusableBuffer.calib.xpotsCalib[idx].lastPosition;
|
||||
bool found = false;
|
||||
for (int j = 0; j < count; j++) {
|
||||
int16_t step = reusableBuffer.calib.xpotsCalib[idx].steps[j];
|
||||
if (position >= step - XPOT_DELTA && position <= step + XPOT_DELTA) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (count < XPOTS_MULTIPOS_COUNT) {
|
||||
reusableBuffer.calib.xpotsCalib[idx].steps[count] = position;
|
||||
}
|
||||
reusableBuffer.calib.xpotsCalib[idx].stepsCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Get min / max values
|
||||
adcCalibMinMax();
|
||||
|
||||
if (menuCalibrationState == CALIB_SET_MIDPOINT) {
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS + NUM_MOUSE_ANALOGS; i++) {
|
||||
reusableBuffer.calib.loVals[i] = 15000;
|
||||
reusableBuffer.calib.hiVals[i] = -15000;
|
||||
reusableBuffer.calib.midVals[i] = i < TX_VOLTAGE ? anaIn(i) : anaIn(i + 1);
|
||||
#if NUM_XPOTS > 0
|
||||
if (i < NUM_XPOTS) {
|
||||
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
|
||||
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
adcCalibSetMidPoint();
|
||||
}
|
||||
else if (menuCalibrationState == CALIB_MOVE_STICKS) {
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS + NUM_MOUSE_ANALOGS; i++) {
|
||||
if (abs(reusableBuffer.calib.loVals[i] - reusableBuffer.calib.hiVals[i]) > 50) {
|
||||
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
|
||||
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
|
||||
g_eeGeneral.calib[i].spanNeg = v - v / STICK_TOLERANCE;
|
||||
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
|
||||
g_eeGeneral.calib[i].spanPos = v - v / STICK_TOLERANCE;
|
||||
}
|
||||
}
|
||||
#if NUM_XPOTS > 0
|
||||
for (int i = POT1; i <= POT_LAST; i++) {
|
||||
int idx = i - POT1;
|
||||
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
if (count > 1 && count <= XPOTS_MULTIPOS_COUNT) {
|
||||
for (int j = 0; j < count; j++) {
|
||||
for (int k = j + 1; k < count; k++) {
|
||||
if (reusableBuffer.calib.xpotsCalib[idx].steps[k] < reusableBuffer.calib.xpotsCalib[idx].steps[j]) {
|
||||
SWAP(reusableBuffer.calib.xpotsCalib[idx].steps[j], reusableBuffer.calib.xpotsCalib[idx].steps[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
|
||||
calib->count = count - 1;
|
||||
for (int j = 0; j < calib->count; j++) {
|
||||
calib->steps[j] = (reusableBuffer.calib.xpotsCalib[idx].steps[j + 1] + reusableBuffer.calib.xpotsCalib[idx].steps[j]) >> 5;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// g_eeGeneral.potsConfig &= ~(0x03<<(2*idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
adcCalibSetMinMax();
|
||||
adcCalibSetXPot();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,8 +152,7 @@ void RadioCalibrationPage::nextStep()
|
|||
|
||||
case CALIB_STORE:
|
||||
text->setText(STR_CALIB_DONE);
|
||||
g_eeGeneral.chkSum = evalChkSum();
|
||||
storageDirty(EE_GENERAL);
|
||||
adcCalibStore();
|
||||
menuCalibrationState = CALIB_FINISHED;
|
||||
|
||||
// initial calibration completed
|
||||
|
|
|
@ -22,16 +22,12 @@
|
|||
#include "opentx.h"
|
||||
#include "radio_diaganas.h"
|
||||
#include "libopenui.h"
|
||||
#include "../../hal/adc_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
// #if defined(IMU_LSM6DS33)
|
||||
// #include "imu_lsm6ds33.h"
|
||||
// #endif
|
||||
|
||||
#if defined(FLYSKY_GIMBAL)
|
||||
#include "flysky_gimbal_driver.h"
|
||||
#endif
|
||||
|
||||
#define STATSDEPTH 8 // ideally a value of power of 2
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
|
@ -74,7 +70,10 @@ class AnaViewWindow: public FormWindow {
|
|||
{
|
||||
char s[10];
|
||||
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
#if LCD_W > LCD_H
|
||||
if ((i & 1) == 0)
|
||||
line = newLine(grid);
|
||||
|
@ -88,7 +87,7 @@ class AnaViewWindow: public FormWindow {
|
|||
new StaticText(line, rect_t{}, s, COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto lbl = new DynamicText(line, rect_t{}, [=]() {
|
||||
return std::to_string((int16_t)calibratedAnalogs[CONVERT_MODE(i)] * 25 / 256);
|
||||
return std::to_string((int16_t)calibratedAnalogs[i] * 25 / 256);
|
||||
}, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_text_align(lbl->getLvObj(), LV_TEXT_ALIGN_RIGHT, 0);
|
||||
|
||||
|
@ -209,14 +208,7 @@ class AnaCalibratedViewWindow: public AnaViewWindow {
|
|||
protected:
|
||||
int16_t column3(int i) override
|
||||
{
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FLYSKY_HALL_CHANNEL_COUNT))
|
||||
return hall_raw_values[i];
|
||||
else
|
||||
return anaIn(i);
|
||||
#else
|
||||
return anaIn(i);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -301,24 +293,11 @@ class AnaFilteredDevViewWindow: public AnaViewWindow {
|
|||
}
|
||||
};
|
||||
|
||||
Stats stats[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
|
||||
Stats stats[MAX_CALIB_ANALOG_INPUTS];
|
||||
|
||||
int16_t column3(int i) override
|
||||
{
|
||||
extern uint32_t s_anaFilt[NUM_ANALOGS];
|
||||
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FLYSKY_HALL_CHANNEL_COUNT))
|
||||
return hall_raw_values[i];
|
||||
else
|
||||
return s_anaFilt[i]/JITTER_ALPHA;
|
||||
#else
|
||||
#if !defined(SIMU)
|
||||
return s_anaFilt[i]/JITTER_ALPHA;
|
||||
#else
|
||||
return anaIn(i);
|
||||
#endif
|
||||
#endif
|
||||
return anaIn_diag(i);
|
||||
}
|
||||
|
||||
const char* column4prefix() override { return "+/- "; }
|
||||
|
@ -333,21 +312,20 @@ class AnaFilteredDevViewWindow: public AnaViewWindow {
|
|||
AnaFilteredDevViewWindow(Window * parent):
|
||||
AnaViewWindow(parent)
|
||||
{
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++)
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++)
|
||||
stats[i].clear();
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FLYSKY_HALL_CHANNEL_COUNT))
|
||||
stats[i].write(hall_raw_values[i]);
|
||||
else
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
stats[i].write(getAnalogValue(i));
|
||||
#else
|
||||
stats[i].write(getAnalogValue(i));
|
||||
#endif
|
||||
}
|
||||
AnaViewWindow::checkEvents();
|
||||
}
|
||||
|
@ -363,14 +341,7 @@ class AnaUnfilteredRawViewWindow: public AnaViewWindow {
|
|||
protected:
|
||||
int16_t column3(int i) override
|
||||
{
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FLYSKY_HALL_CHANNEL_COUNT))
|
||||
return hall_raw_values[i];
|
||||
else
|
||||
return getAnalogValue(i);
|
||||
#else
|
||||
return getAnalogValue(i);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -419,7 +390,7 @@ class AnaMinMaxViewWindow: public AnaViewWindow {
|
|||
}
|
||||
};
|
||||
|
||||
MinMax minmax[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
|
||||
MinMax minmax[MAX_CALIB_ANALOG_INPUTS];
|
||||
|
||||
int16_t column3(int i) override
|
||||
{
|
||||
|
@ -444,7 +415,10 @@ class AnaMinMaxViewWindow: public AnaViewWindow {
|
|||
AnaMinMaxViewWindow(Window * parent):
|
||||
AnaViewWindow(parent)
|
||||
{
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++)
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++)
|
||||
minmax[i].clear();
|
||||
}
|
||||
|
||||
|
@ -459,15 +433,11 @@ class AnaMinMaxViewWindow: public AnaViewWindow {
|
|||
|
||||
void checkEvents() override
|
||||
{
|
||||
for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) {
|
||||
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
|
||||
if (globalData.flyskygimbals && (i < FLYSKY_HALL_CHANNEL_COUNT))
|
||||
minmax[i].write(hall_raw_values[i]);
|
||||
else
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
minmax[i].write(getAnalogValue(i));
|
||||
#else
|
||||
minmax[i].write(getAnalogValue(i));
|
||||
#endif
|
||||
}
|
||||
AnaViewWindow::checkEvents();
|
||||
}
|
||||
|
|
|
@ -23,11 +23,21 @@
|
|||
#include "radio_diagkeys.h"
|
||||
#include "libopenui.h"
|
||||
|
||||
#if defined(KEYS_GPIO_PIN_PGUP)
|
||||
constexpr uint8_t KEY_START = 0;
|
||||
#else
|
||||
constexpr uint8_t KEY_START = 1;
|
||||
#endif
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
static EnumKeys get_ith_key(uint8_t i)
|
||||
{
|
||||
auto supported_keys = keysGetSupported();
|
||||
for (uint8_t k = 0; k < MAX_KEYS; k++) {
|
||||
if (supported_keys & (1 << k)) {
|
||||
if (i-- == 0) return (EnumKeys)k;
|
||||
}
|
||||
}
|
||||
|
||||
// should not get here,
|
||||
// we assume: i < keysGetMaxKeys()
|
||||
return (EnumKeys)0;
|
||||
}
|
||||
|
||||
class RadioKeyDiagsWindow : public Window
|
||||
{
|
||||
|
@ -45,7 +55,7 @@ class RadioKeyDiagsWindow : public Window
|
|||
|
||||
void displayKeyState(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t key)
|
||||
{
|
||||
uint8_t t = keys[key].state();
|
||||
uint8_t t = keysGetState(key);
|
||||
// TODO use drawChar when done
|
||||
char status[2];
|
||||
status[0] = t + '0';
|
||||
|
@ -73,29 +83,31 @@ class RadioKeyDiagsWindow : public Window
|
|||
|
||||
#if !defined(PCBNV14)
|
||||
// KEYS
|
||||
for (uint8_t i = KEY_START; i <= 6; i++) {
|
||||
coord_t y = 1 + FH * (i - KEY_START);
|
||||
dc->drawTextAtIndex(KEY_COLUMN, y, STR_VKEYS, i, COLOR_THEME_PRIMARY1);
|
||||
coord_t y = 1;
|
||||
for (uint8_t i = 0; i < keysGetMaxKeys(); i++) {
|
||||
auto k = get_ith_key(i);
|
||||
y += FH;
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(k), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, i);
|
||||
}
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
coord_t y = FH * (8 - KEY_START);
|
||||
y += FH;
|
||||
dc->drawText(KEY_COLUMN, y, STR_ROTARY_ENCODER, COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(70, y, rotencValue, COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(70, y, rotaryEncoderGetValue(), COLOR_THEME_PRIMARY1);
|
||||
#endif
|
||||
#else // defined(PCBNV14)
|
||||
// KEYS
|
||||
{
|
||||
coord_t y = 1;
|
||||
dc->drawTextAtIndex(KEY_COLUMN, y, STR_VKEYS, KEY_ENTER, COLOR_THEME_PRIMARY1);
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(KEY_ENTER), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, KEY_ENTER);
|
||||
y += FH;
|
||||
dc->drawTextAtIndex(KEY_COLUMN, y, STR_VKEYS, KEY_EXIT, COLOR_THEME_PRIMARY1);
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(KEY_EXIT), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, KEY_EXIT);
|
||||
}
|
||||
#endif
|
||||
// SWITCHES
|
||||
for (uint8_t i = 0; i < NUM_SWITCHES; i++) {
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
coord_t y = 1 + FH * i;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
|
@ -105,18 +117,18 @@ class RadioKeyDiagsWindow : public Window
|
|||
}
|
||||
|
||||
// TRIMS
|
||||
for (uint8_t i = 0; i < NUM_TRIMS_KEYS; i++) {
|
||||
#if NUM_TRIMS_KEYS == 12
|
||||
const uint8_t trimMap[NUM_TRIMS_KEYS] = {6, 7, 4, 5, 2, 3, 0, 1, 8, 9, 10, 11};
|
||||
for (uint8_t i = 0; i < MAX_TRIMS * 2; i++) {
|
||||
#if MAX_TRIMS * 2 == 12
|
||||
const uint8_t trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, 0, 1, 8, 9, 10, 11};
|
||||
#else
|
||||
const uint8_t trimMap[NUM_TRIMS_KEYS] = {6, 7, 4, 5, 2, 3, 0, 1};
|
||||
const uint8_t trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, 0, 1};
|
||||
#endif
|
||||
coord_t y = 1 + FH + FH * (i / 2);
|
||||
if (i & 1) {
|
||||
dc->drawText(TRIM_COLUMN, y, "T", COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(TRIM_COLUMN + 10, y, i / 2 + 1, COLOR_THEME_PRIMARY1);
|
||||
}
|
||||
displayKeyState(dc, i & 1 ? TRIM_PLUS_COLUMN : TRIM_MINUS_COLUMN, y, TRM_BASE + trimMap[i]);
|
||||
// displayKeyState(dc, i & 1 ? TRIM_PLUS_COLUMN : TRIM_MINUS_COLUMN, y, TRM_BASE + trimMap[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@ RadioHardwarePage::RadioHardwarePage():
|
|||
{
|
||||
}
|
||||
|
||||
void RadioHardwarePage::checkEvents()
|
||||
{
|
||||
enableVBatBridge();
|
||||
}
|
||||
|
||||
void RadioHardwarePage::build(FormWindow * window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 0);
|
||||
|
@ -163,16 +168,10 @@ void RadioHardwarePage::build(FormWindow * window)
|
|||
auto btn = makeHWInputButton<HWSticks>(box, STR_STICKS);
|
||||
lv_obj_set_style_min_width(btn->getLvObj(), LV_DPI_DEF, 0);
|
||||
|
||||
// Pots
|
||||
// Pots & Sliders
|
||||
btn = makeHWInputButton<HWPots>(box, STR_POTS);
|
||||
lv_obj_set_style_min_width(btn->getLvObj(), LV_DPI_DEF, 0);
|
||||
|
||||
// Sliders
|
||||
#if (NUM_SLIDERS > 0)
|
||||
btn = makeHWInputButton<HWSliders>(box, STR_SLIDERS);
|
||||
lv_obj_set_style_min_width(btn->getLvObj(), LV_DPI_DEF, 0);
|
||||
#endif
|
||||
|
||||
// Switches
|
||||
btn = makeHWInputButton<HWSwitches>(box, STR_SWITCHES);
|
||||
lv_obj_set_style_min_width(btn->getLvObj(), LV_DPI_DEF, 0);
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
|
||||
#include "tabsgroup.h"
|
||||
|
||||
class RadioHardwarePage: public PageTab {
|
||||
class RadioHardwarePage : public PageTab
|
||||
{
|
||||
void checkEvents() override;
|
||||
|
||||
public:
|
||||
RadioHardwarePage();
|
||||
|
||||
void build(FormWindow * window) override;
|
||||
void build(FormWindow* window) override;
|
||||
};
|
||||
|
||||
#endif //_RADIO_HARDWARE_H_
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#include "radio_setup.h"
|
||||
#include "opentx.h"
|
||||
#include "libopenui.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
|
@ -781,12 +783,16 @@ void RadioSetupPage::build(FormWindow * window)
|
|||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_DEF_CHAN_ORD, 0,
|
||||
COLOR_THEME_PRIMARY1); // RAET->AETR
|
||||
choice = new Choice(line, rect_t{}, 0, 4 * 3 * 2 - 1,
|
||||
|
||||
uint8_t mains = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto max_order = inputMappingGetMaxChannelOrder() - 1;
|
||||
choice = new Choice(line, rect_t{}, 0, max_order,
|
||||
GET_SET_DEFAULT(g_eeGeneral.templateSetup));
|
||||
choice->setTextHandler([](uint8_t value) {
|
||||
|
||||
choice->setTextHandler([=](uint8_t value) {
|
||||
std::string s;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
s += STR_RETA123[channelOrder(value, i + 1) - 1];
|
||||
for (uint8_t i = 0; i < mains; i++) {
|
||||
s += getAnalogShortLabel(inputMappingChannelOrder(value, i));
|
||||
}
|
||||
return s;
|
||||
});
|
||||
|
@ -803,11 +809,11 @@ void RadioSetupPage::build(FormWindow * window)
|
|||
mixerTaskStart();
|
||||
});
|
||||
choice->setTextHandler([](uint8_t value) {
|
||||
auto stick0 = inputMappingConvertMode(value, 0);
|
||||
auto stick1 = inputMappingConvertMode(value, 1);
|
||||
return std::to_string(1 + value) + ": " + STR_LEFT_STICK + " = " +
|
||||
std::string(&getSourceString(MIXSRC_Rud + modn12x3[4 * value])[1]) +
|
||||
"+" +
|
||||
std::string(
|
||||
&getSourceString(MIXSRC_Rud + modn12x3[4 * value + 1])[1]);
|
||||
std::string(getMainControlLabel(stick0)) + "+" +
|
||||
std::string(getMainControlLabel(stick1));
|
||||
});
|
||||
|
||||
// Model quick select
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "radio_trainer.h"
|
||||
#include "opentx.h"
|
||||
#include "libopenui.h"
|
||||
#include "input_mapping.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "strhelpers.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
|
@ -59,13 +63,13 @@ void RadioTrainerPage::build(FormWindow * form)
|
|||
form->padRight(8);
|
||||
#endif
|
||||
|
||||
for (uint8_t i = 0; i < NUM_STICKS; i++) {
|
||||
uint8_t chan = channelOrder(i + 1);
|
||||
TrainerMix* td = &g_eeGeneral.trainer.mix[chan - 1];
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
for (uint8_t i = 0; i < max_sticks; i++) {
|
||||
uint8_t chan = inputMappingChannelOrder(i);
|
||||
TrainerMix* td = &g_eeGeneral.trainer.mix[chan];
|
||||
|
||||
auto line = form->newLine(&grid);
|
||||
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[chan], 0, COLOR_THEME_PRIMARY1);
|
||||
new StaticText(line, rect_t{}, getMainControlLabel(chan), 0, COLOR_THEME_PRIMARY1);
|
||||
|
||||
new Choice(line, rect_t{}, STR_TRNMODE, 0, 2, GET_SET_DEFAULT(td->mode));
|
||||
new Choice(line, rect_t{}, STR_TRNCHN, 0, 3, GET_SET_DEFAULT(td->srcChn));
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "strhelpers.h"
|
||||
#include "draw_functions.h"
|
||||
#include "opentx.h"
|
||||
#include "switches.h"
|
||||
|
||||
class SourceChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "view_main.h"
|
||||
#include "lvgl_widgets/input_mix_line.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "strhelpers.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(functions == g_model.customFn ? EE_MODEL : EE_GENERAL)
|
||||
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(3),
|
||||
|
@ -125,17 +128,16 @@ class SpecialFunctionEditPage : public Page
|
|||
|
||||
case FUNC_TRAINER: {
|
||||
new StaticText(line, rect_t{}, STR_VALUE, 0, COLOR_THEME_PRIMARY1);
|
||||
auto choice =
|
||||
new Choice(line, rect_t{}, 0,
|
||||
NUM_STICKS + 1, GET_SET_DEFAULT(CFN_CH_INDEX(cfn)));
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto choice = new Choice(line, rect_t{}, 0, max_sticks + 1,
|
||||
GET_SET_DEFAULT(CFN_CH_INDEX(cfn)));
|
||||
choice->setTextHandler([=](int32_t value) {
|
||||
if (value == 0)
|
||||
return std::string(STR_STICKS);
|
||||
else if (value == NUM_STICKS + 1)
|
||||
else if (value == MAX_STICKS + 1)
|
||||
return std::string(STR_CHANS);
|
||||
else
|
||||
return TEXT_AT_INDEX(STR_VSRCRAW, value);
|
||||
;
|
||||
|
||||
return std::string(getMainControlLabel(value));
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -398,9 +400,11 @@ class SpecialFunctionEditPage : public Page
|
|||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_FUNC, 0, COLOR_THEME_PRIMARY1);
|
||||
auto functionChoice =
|
||||
new Choice(line, rect_t{}, STR_VFSWFUNC,
|
||||
0, FUNC_MAX - 1,
|
||||
new Choice(line, rect_t{}, 0, FUNC_MAX - 1,
|
||||
GET_DEFAULT(CFN_FUNC(cfn)));
|
||||
functionChoice->setTextHandler([=](int val) {
|
||||
return funcGetLabel(val);
|
||||
});
|
||||
functionChoice->setSetValueHandler([=](int32_t newValue) {
|
||||
CFN_FUNC(cfn) = newValue;
|
||||
CFN_RESET(cfn);
|
||||
|
@ -560,22 +564,22 @@ class SpecialFunctionButton : public Button
|
|||
lv_label_set_text(sfName, s);
|
||||
lv_label_set_text(sfSwitch, getSwitchPositionName(CFN_SWITCH(cfn)));
|
||||
|
||||
strcpy(s, STR_VFSWFUNC[func]);
|
||||
strcpy(s, funcGetLabel(func));
|
||||
strcat(s, " - ");
|
||||
|
||||
switch (func) {
|
||||
case FUNC_OVERRIDE_CHANNEL:
|
||||
sprintf(s+strlen(s), "%s = %s", getSourceString(MIXSRC_CH1 + CFN_CH_INDEX(cfn)), formatNumberAsString(CFN_PARAM(cfn)).c_str());
|
||||
sprintf(s+strlen(s), "%s = %s", getSourceString(MIXSRC_FIRST_CH + CFN_CH_INDEX(cfn)), formatNumberAsString(CFN_PARAM(cfn)).c_str());
|
||||
break;
|
||||
|
||||
case FUNC_TRAINER: {
|
||||
int16_t value = CFN_CH_INDEX(cfn);
|
||||
if (value == 0)
|
||||
strcat(s, STR_STICKS);
|
||||
else if (value == NUM_STICKS + 1)
|
||||
else if (value == MAX_STICKS + 1)
|
||||
strcat(s, STR_CHANS);
|
||||
else
|
||||
strcat(s, STR_VSRCRAW[value]);
|
||||
strcat(s, getMainControlLabel(value - 1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -646,7 +650,7 @@ class SpecialFunctionButton : public Button
|
|||
break;
|
||||
|
||||
default:
|
||||
strcpy(s, STR_VFSWFUNC[func]);
|
||||
strcpy(s, funcGetLabel(func));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue