1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-14 03:49:52 +03:00

[Horus] GUI continued - #3159

[GVars] Refactoring continued - #3185
This commit is contained in:
Bertrand Songis 2016-01-13 23:15:03 +01:00
parent 43b84385d8
commit e8aaa67450
105 changed files with 4033 additions and 3026 deletions

View file

@ -1524,7 +1524,7 @@ bool ModelData::isGVarLinked(int phaseIdx, int gvarIdx)
return flightModeData[phaseIdx].gvars[gvarIdx] > 1024; return flightModeData[phaseIdx].gvars[gvarIdx] > 1024;
} }
int ModelData::getGVarValue(int phaseIdx, int gvarIdx) int ModelData::getGVarFieldValue(int phaseIdx, int gvarIdx)
{ {
int idx = flightModeData[phaseIdx].gvars[gvarIdx]; int idx = flightModeData[phaseIdx].gvars[gvarIdx];
for (int i=0; idx>1024 && i<C9X_MAX_FLIGHT_MODES; i++) { for (int i=0; idx>1024 && i<C9X_MAX_FLIGHT_MODES; i++) {

View file

@ -1077,7 +1077,7 @@ class ModelData {
void setTrimValue(int phaseIdx, int trimIdx, int value); void setTrimValue(int phaseIdx, int trimIdx, int value);
bool isGVarLinked(int phaseIdx, int gvarIdx); bool isGVarLinked(int phaseIdx, int gvarIdx);
int getGVarValue(int phaseIdx, int gvarIdx); int getGVarFieldValue(int phaseIdx, int gvarIdx);
ModelData removeGlobalVars(); ModelData removeGlobalVars();

View file

@ -2113,7 +2113,7 @@ class ArmCustomFunctionField: public TransformedField {
if (fn.swtch.type != SWITCH_TYPE_NONE) { if (fn.swtch.type != SWITCH_TYPE_NONE) {
_func = fn.func; _func = fn.func;
if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic) if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic || (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast))
_active = (version >= 216 ? fn.repeatParam : (fn.repeatParam/5)); _active = (version >= 216 ? fn.repeatParam : (fn.repeatParam/5));
else else
_active = (fn.enabled ? 1 : 0); _active = (fn.enabled ? 1 : 0);
@ -2209,7 +2209,7 @@ class ArmCustomFunctionField: public TransformedField {
{ {
fn.func = (AssignFunc)_func; fn.func = (AssignFunc)_func;
if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic) if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic || (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast))
fn.repeatParam = (version >= 216 ? _active : (_active*5)); fn.repeatParam = (version >= 216 ? _active : (_active*5));
else else
fn.enabled = (_active & 0x01); fn.enabled = (_active & 0x01);

View file

@ -148,7 +148,8 @@ namespace NAMESPACE {
#include "radio/src/gui/horus/menu_model_setup.cpp" #include "radio/src/gui/horus/menu_model_setup.cpp"
#include "radio/src/gui/horus/menu_model_heli.cpp" #include "radio/src/gui/horus/menu_model_heli.cpp"
#include "radio/src/gui/horus/menu_model_flightmodes.cpp" #include "radio/src/gui/horus/menu_model_flightmodes.cpp"
#include "radio/src/gui/horus/menu_model_inputs_mixes.cpp" #include "radio/src/gui/horus/menu_model_inputs.cpp"
#include "radio/src/gui/horus/menu_model_mixes.cpp"
#include "radio/src/gui/horus/menu_model_curves.cpp" #include "radio/src/gui/horus/menu_model_curves.cpp"
#include "radio/src/gui/horus/menu_model_logical_switches.cpp" #include "radio/src/gui/horus/menu_model_logical_switches.cpp"
#include "radio/src/gui/horus/menu_model_custom_functions.cpp" #include "radio/src/gui/horus/menu_model_custom_functions.cpp"
@ -220,7 +221,8 @@ namespace NAMESPACE {
#include "radio/src/gui/taranis/menu_model_setup.cpp" #include "radio/src/gui/taranis/menu_model_setup.cpp"
#include "radio/src/gui/taranis/menu_model_heli.cpp" #include "radio/src/gui/taranis/menu_model_heli.cpp"
#include "radio/src/gui/taranis/menu_model_flightmodes.cpp" #include "radio/src/gui/taranis/menu_model_flightmodes.cpp"
#include "radio/src/gui/taranis/menu_model_inputs_mixes.cpp" #include "radio/src/gui/taranis/menu_model_inputs.cpp"
#include "radio/src/gui/taranis/menu_model_mixes.cpp"
#include "radio/src/gui/taranis/menu_model_curves.cpp" #include "radio/src/gui/taranis/menu_model_curves.cpp"
#include "radio/src/gui/taranis/menu_model_logical_switches.cpp" #include "radio/src/gui/taranis/menu_model_logical_switches.cpp"
#include "radio/src/gui/taranis/menu_model_custom_functions.cpp" #include "radio/src/gui/taranis/menu_model_custom_functions.cpp"

View file

@ -373,8 +373,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
} }
else if (func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) { else if (func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) {
if (modified) cfn.adjustMode = fswtchGVmode[i]->currentIndex(); if (modified) cfn.adjustMode = fswtchGVmode[i]->currentIndex();
widgetsMask |= CUSTOM_FUNCTION_GV_MODE + CUSTOM_FUNCTION_ENABLE; widgetsMask |= CUSTOM_FUNCTION_GV_MODE | (IS_ARM(firmware->getBoard()) ? CUSTOM_FUNCTION_REPEAT : CUSTOM_FUNCTION_ENABLE);
if (cfn.adjustMode==0) { if (cfn.adjustMode==0 || cfn.adjustMode==3) {
if (modified) cfn.param = fswtchParam[i]->value(); if (modified) cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0); fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setSingleStep(1);
@ -677,12 +677,6 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi
case 2: case 2:
populateSourceCB(b, RawSource(value), generalSettings, model, POPULATE_GVARS); populateSourceCB(b, RawSource(value), generalSettings, model, POPULATE_GVARS);
break; break;
case 3:
b->clear();
b->addItem("-1", 0);
b->addItem("+1", 1);
b->setCurrentIndex(value);
break;
} }
} }
else { else {

View file

@ -220,7 +220,7 @@ void FlightModePanel::update()
gvNames[i]->setText(model->gvars_names[i]); gvNames[i]->setText(model->gvars_names[i]);
} }
gvValues[i]->setDisabled(model->isGVarLinked(phaseIdx, i)); gvValues[i]->setDisabled(model->isGVarLinked(phaseIdx, i));
gvValues[i]->setValue(model->getGVarValue(phaseIdx, i)); gvValues[i]->setValue(model->getGVarFieldValue(phaseIdx, i));
if (IS_TARANIS(GetEepromInterface()->getBoard()) && phaseIdx == 0) { if (IS_TARANIS(GetEepromInterface()->getBoard()) && phaseIdx == 0) {
gvPopups[i]->setChecked(model->gvars_popups[i]); gvPopups[i]->setChecked(model->gvars_popups[i]);
} }

View file

@ -71,7 +71,7 @@ for (int i=0; i<NUM_LOGICAL_SWITCH; i++)
#if defined(GVARS) #if defined(GVARS)
for (int fm=0; fm<MAX_FLIGHT_MODES; fm++) { for (int fm=0; fm<MAX_FLIGHT_MODES; fm++) {
for (int gv=0; gv<MAX_GVARS; gv++) { for (int gv=0; gv<MAX_GVARS; gv++) {
outputs.gvars[fm][gv] = GVAR_VALUE(gv, getGVarFlightPhase(fm, gv)); outputs.gvars[fm][gv] = GVAR_VALUE(gv, getGVarFlightMode(fm, gv));
} }
} }
#endif #endif

View file

@ -40,6 +40,12 @@ set(M128_VARIANT 32768)
set(FIRMWARE_DEPENDENCIES firmware_translations) set(FIRMWARE_DEPENDENCIES firmware_translations)
set(9X_GUI_SRC
menu_model_inputs_mixes.cpp
menu_general_diagkeys.cpp
menu_general_diaganas.cpp
)
if(PCB STREQUAL HORUS) if(PCB STREQUAL HORUS)
set(CPU_TYPE STM32F4) set(CPU_TYPE STM32F4)
set(HSE_VALUE 12000000) set(HSE_VALUE 12000000)
@ -60,6 +66,8 @@ if(PCB STREQUAL HORUS)
${GUI_SRC} ${GUI_SRC}
curves.cpp curves.cpp
bitmaps.cpp bitmaps.cpp
menu_model_inputs.cpp
menu_model_mixes.cpp
view_channels.cpp view_channels.cpp
view_about.cpp view_about.cpp
view_text.cpp view_text.cpp
@ -125,7 +133,7 @@ elseif(PCB STREQUAL TARANIS)
add_definitions(-DAUDIO -DVOICE -DRTCLOCK) add_definitions(-DAUDIO -DVOICE -DRTCLOCK)
add_definitions(-DDBLKEYS -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DVARIO) add_definitions(-DDBLKEYS -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DVARIO)
set(SRC ${SRC} bmp.cpp) set(SRC ${SRC} bmp.cpp)
set(GUI_SRC ${GUI_SRC} menu_general_diagkeys.cpp menu_general_diaganas.cpp menu_general_hardware.cpp view_channels.cpp view_telemetry.cpp view_text.cpp view_about.cpp) set(GUI_SRC ${GUI_SRC} menu_model_inputs.cpp menu_model_mixes.cpp menu_general_diagkeys.cpp menu_general_diaganas.cpp menu_general_hardware.cpp view_channels.cpp view_telemetry.cpp view_text.cpp view_about.cpp)
set(TARGET_SRC ${TARGET_SRC} board_taranis.cpp rtc_driver.cpp) set(TARGET_SRC ${TARGET_SRC} board_taranis.cpp rtc_driver.cpp)
set(FIRMWARE_SRC ${FIRMWARE_SRC} loadboot.cpp) set(FIRMWARE_SRC ${FIRMWARE_SRC} loadboot.cpp)
set(FIRMWARE_TARGET_SRC set(FIRMWARE_TARGET_SRC
@ -185,7 +193,7 @@ elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X)
add_definitions(-DAUDIO -DVOICE -DRTCLOCK) add_definitions(-DAUDIO -DVOICE -DRTCLOCK)
add_definitions(-DDBLKEYS -DVARIO) add_definitions(-DDBLKEYS -DVARIO)
add_definitions(-DEEPROM_VARIANT=0) add_definitions(-DEEPROM_VARIANT=0)
set(GUI_SRC ${GUI_SRC} menu_general_diagkeys.cpp menu_general_diaganas.cpp menu_general_hardware.cpp view_telemetry.cpp view_text.cpp view_about.cpp) set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC} menu_general_hardware.cpp view_telemetry.cpp view_text.cpp view_about.cpp)
set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} core_cm3.c board_lowlevel.c crt.c vectors_sam3s.c) set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} core_cm3.c board_lowlevel.c crt.c vectors_sam3s.c)
set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} lcd_driver.cpp set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} lcd_driver.cpp
usb/device/core/USBD_UDP.c usb/device/core/USBDDriver.c usb/device/core/USBD_UDP.c usb/device/core/USBDDriver.c
@ -220,7 +228,7 @@ elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR)
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps) set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM64) add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM64)
set(TARGET_SRC ${TARGET_SRC} board_stock.cpp) set(TARGET_SRC ${TARGET_SRC} board_stock.cpp)
set(GUI_SRC ${GUI_SRC} menu_general_diagkeys.cpp menu_general_diaganas.cpp) set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC})
else() else()
message(FATAL_ERROR "Unknown PCB '${PCB}'") message(FATAL_ERROR "Unknown PCB '${PCB}'")
endif() endif()
@ -577,7 +585,6 @@ set(GUI_SRC
menu_model.cpp menu_model.cpp
menu_model_select.cpp menu_model_select.cpp
menu_model_setup.cpp menu_model_setup.cpp
menu_model_inputs_mixes.cpp
menu_model_limits.cpp menu_model_limits.cpp
menu_model_logical_switches.cpp menu_model_logical_switches.cpp
menu_model_custom_functions.cpp menu_model_custom_functions.cpp

View file

@ -427,7 +427,7 @@ M128_VARIANT = +32768
M2561_VARIANT = +16384 M2561_VARIANT = +16384
EEPROM_VARIANT = 0 EEPROM_VARIANT = 0
GUIMODELSRC = gui/$(GUIDIRECTORY)/menu_model.cpp gui/$(GUIDIRECTORY)/menu_model_select.cpp gui/$(GUIDIRECTORY)/menu_model_setup.cpp gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp gui/$(GUIDIRECTORY)/menu_model_limits.cpp gui/$(GUIDIRECTORY)/menu_model_logical_switches.cpp gui/$(GUIDIRECTORY)/menu_model_custom_functions.cpp gui/$(GUIDIRECTORY)/menu_model_telemetry.cpp GUIMODELSRC = gui/$(GUIDIRECTORY)/menu_model.cpp gui/$(GUIDIRECTORY)/menu_model_select.cpp gui/$(GUIDIRECTORY)/menu_model_setup.cpp gui/$(GUIDIRECTORY)/menu_model_limits.cpp gui/$(GUIDIRECTORY)/menu_model_logical_switches.cpp gui/$(GUIDIRECTORY)/menu_model_custom_functions.cpp gui/$(GUIDIRECTORY)/menu_model_telemetry.cpp
GUIGENERALSRC = gui/$(GUIDIRECTORY)/menu_general.cpp gui/$(GUIDIRECTORY)/menu_general_setup.cpp gui/$(GUIDIRECTORY)/menu_general_trainer.cpp gui/$(GUIDIRECTORY)/menu_general_version.cpp gui/$(GUIDIRECTORY)/menu_general_calib.cpp GUIGENERALSRC = gui/$(GUIDIRECTORY)/menu_general.cpp gui/$(GUIDIRECTORY)/menu_general_setup.cpp gui/$(GUIDIRECTORY)/menu_general_trainer.cpp gui/$(GUIDIRECTORY)/menu_general_version.cpp gui/$(GUIDIRECTORY)/menu_general_calib.cpp
BITMAPS = bitmaps/sticks.lbm BITMAPS = bitmaps/sticks.lbm
@ -455,6 +455,7 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR))
PULSESSRC = pulses/pulses_avr.cpp PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp CPPSRC += debug.cpp
BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR) ifeq ($(PCB), 9XR)
@ -534,6 +535,7 @@ ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128))
PULSESSRC = pulses/pulses_avr.cpp PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp CPPSRC += debug.cpp
BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR128) ifeq ($(PCB), 9XR128)
@ -609,6 +611,7 @@ ifeq ($(PCB), $(filter $(PCB), 9X2561))
PULSESSRC = pulses/pulses_avr.cpp PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp CPPSRC += debug.cpp
BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR2561) ifeq ($(PCB), 9XR2561)
@ -682,6 +685,7 @@ ifeq ($(PCB), GRUVIN9X)
PULSESSRC = pulses/pulses_avr.cpp PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp haptic.cpp debug.cpp CPPSRC += audio_avr.cpp haptic.cpp debug.cpp
BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(SDCARD), YES) ifeq ($(SDCARD), YES)
@ -727,6 +731,7 @@ ifeq ($(PCB), MEGA2560)
PULSESSRC = pulses/pulses_avr.cpp PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp debug.cpp CPPSRC += audio_avr.cpp debug.cpp
BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm BITMAPS += bitmaps/9x/splash.lbm bitmaps/9x/asterisk.lbm bitmaps/9x/about.lbm
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/9x/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/9x/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
@ -838,6 +843,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO AR9X))
CPPDEFS += -DSDCARD -DVOICE CPPDEFS += -DSDCARD -DVOICE
INCDIRS += $(FATFSDIR) $(FATFSDIR)/option INCDIRS += $(FATFSDIR) $(FATFSDIR)/option
CPPSRC += sdcard.cpp logs.cpp CPPSRC += sdcard.cpp logs.cpp
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp
EXTRABOARDSRC += $(FATFSDIR)/ff.c $(FATFSDIR)/fattime.c $(FATFSDIR)/option/ccsbcs.c targets/sky9x/diskio.cpp EXTRABOARDSRC += $(FATFSDIR)/ff.c $(FATFSDIR)/fattime.c $(FATFSDIR)/option/ccsbcs.c targets/sky9x/diskio.cpp
endif endif
@ -1023,6 +1029,7 @@ ifeq ($(PCB), TARANIS)
NEWLIB_NANO_FLAGS = --specs=nano.specs -u _printf_float NEWLIB_NANO_FLAGS = --specs=nano.specs -u _printf_float
CPPDEFS += -DNANO CPPDEFS += -DNANO
endif endif
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs.cpp gui/$(GUIDIRECTORY)/menu_model_mixes.cpp
ifeq ($(GVARS), YES) ifeq ($(GVARS), YES)
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_gvars.cpp GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_gvars.cpp
endif endif
@ -1139,6 +1146,7 @@ ifeq ($(PCB), FLAMENCO)
SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Core/src/usbd_ioreq.c SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Core/src/usbd_ioreq.c
SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Core/src/usbd_req.c SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Core/src/usbd_req.c
EXTRABOARDSRC += targets/flamenco/usbd_usr.cpp EXTRABOARDSRC += targets/flamenco/usbd_usr.cpp
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp
SRC += syscalls.c SRC += syscalls.c
ifeq ($(USB), JOYSTICK) ifeq ($(USB), JOYSTICK)
CPPDEFS += -DUSB_JOYSTICK CPPDEFS += -DUSB_JOYSTICK
@ -1282,6 +1290,7 @@ ifeq ($(PCB), HORUS)
SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
EXTRABOARDSRC += targets/horus/usbd_storage_msd.cpp EXTRABOARDSRC += targets/horus/usbd_storage_msd.cpp
endif endif
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_inputs.cpp gui/$(GUIDIRECTORY)/menu_model_mixes.cpp
ifeq ($(GVARS), YES) ifeq ($(GVARS), YES)
GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_gvars.cpp GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_gvars.cpp
endif endif

View file

@ -6,7 +6,8 @@ add_truetype_font_target(horus dblsize "DejaVu Sans" 32 True)
add_truetype_font_target(horus xxlsize "DejaVu Sans" 48 False) add_truetype_font_target(horus xxlsize "DejaVu Sans" 48 False)
add_custom_target(ttf_horus_fonts DEPENDS ttf_horus_tinsize ttf_horus_smlsize ttf_horus_stdsize ttf_horus_midsize ttf_horus_dblsize ttf_horus_xxlsize) add_custom_target(ttf_horus_fonts DEPENDS ttf_horus_tinsize ttf_horus_smlsize ttf_horus_stdsize ttf_horus_midsize ttf_horus_dblsize ttf_horus_xxlsize)
add_bitmaps_target(horus_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/????[^_]*.png" 480 5/6/5/8) add_bitmaps_target(horus_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/????[^_]*.png" 480 5/6/5)
# add_bitmaps_target(horus_alpha_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/alpha_*.png" 480 5/6/5/8)
add_bitmaps_target(horus_masks ${RADIO_SRC_DIRECTORY}/bitmaps/horus/mask_*.png 480 8bits) add_bitmaps_target(horus_masks ${RADIO_SRC_DIRECTORY}/bitmaps/horus/mask_*.png 480 8bits)
add_bitmaps_target(horus_fonts ${RADIO_SRC_DIRECTORY}/fonts/horus/*.png 480 8bits) add_bitmaps_target(horus_fonts ${RADIO_SRC_DIRECTORY}/fonts/horus/*.png 480 8bits)
add_dependencies(horus_bitmaps horus_masks horus_fonts) add_dependencies(horus_bitmaps horus_masks horus_fonts)

View file

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Before After
Before After

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "opentx.h" #include "opentx.h"
#include <ctype.h> #include <ctype.h>
@ -156,18 +156,6 @@ int cliStackInfo(const char ** argv)
return 0; return 0;
} }
int cliVolume(const char ** argv)
{
int level = 0;
if (toInt(argv, 1, &level) > 0) {
setVolume(level);
}
else {
serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]);
}
return 0;
}
#if defined(PCBFLAMENCO) #if defined(PCBFLAMENCO)
int cliReadBQ24195(const char ** argv) int cliReadBQ24195(const char ** argv)
{ {
@ -229,6 +217,16 @@ int cliSet(const char ** argv)
serialPrint("%s: Invalid arguments \"%s\" \"%s\"", argv[0], argv[1], argv[2]); serialPrint("%s: Invalid arguments \"%s\" \"%s\"", argv[0], argv[1], argv[2]);
} }
} }
else if (!strcmp(argv[1], "volume")) {
int level = 0;
if (toInt(argv, 2, &level) > 0) {
setVolume(level);
}
else {
serialPrint("%s: Invalid argument \"%s\" \"%s\"", argv[0], argv[1], argv[2]);
}
return 0;
}
return 0; return 0;
} }
@ -279,6 +277,9 @@ int cliDisplay(const char ** argv)
gettime(&utm); gettime(&utm);
serialPrint("rtc = %4d-%02d-%02d %02d:%02d:%02d.%02d0", utm.tm_year+1900, utm.tm_mon+1, utm.tm_mday, utm.tm_hour, utm.tm_min, utm.tm_sec, g_ms100); serialPrint("rtc = %4d-%02d-%02d %02d:%02d:%02d.%02d0", utm.tm_year+1900, utm.tm_mon+1, utm.tm_mday, utm.tm_hour, utm.tm_min, utm.tm_sec, g_ms100);
} }
else if (!strcmp(argv[1], "volume")) {
serialPrint("volume = %d", getVolume());
}
#if defined(PCBFLAMENCO) #if defined(PCBFLAMENCO)
else if (!strcmp(argv[1], "bq24195")) { else if (!strcmp(argv[1], "bq24195")) {
{ {
@ -326,7 +327,7 @@ int cliDisplay(const char ** argv)
int cliDebugVars(const char ** argv) int cliDebugVars(const char ** argv)
{ {
#if defined(PCBHORUS) #if defined(PCBHORUS) && !defined(SIMU)
extern unsigned int ioMutexReq, ioMutexRel; extern unsigned int ioMutexReq, ioMutexRel;
extern unsigned int sdReadRetries; extern unsigned int sdReadRetries;
@ -367,7 +368,6 @@ const CliCommand cliCommands[] = {
{ "set", cliSet, "<what> <value>" }, { "set", cliSet, "<what> <value>" },
{ "stackinfo", cliStackInfo, "" }, { "stackinfo", cliStackInfo, "" },
{ "trace", cliTrace, "on | off" }, { "trace", cliTrace, "on | off" },
{ "volume", cliVolume, "<level>" },
#if defined(PCBFLAMENCO) #if defined(PCBFLAMENCO)
{ "read_bq24195", cliReadBQ24195, "<register>" }, { "read_bq24195", cliReadBQ24195, "<register>" },
{ "write_bq24195", cliWriteBQ24195, "<register> <data>" }, { "write_bq24195", cliWriteBQ24195, "<register> <data>" },

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "opentx.h" #include "opentx.h"
#if defined(XCURVES) #if defined(XCURVES)
@ -72,7 +72,7 @@ CurveInfo curveInfo(uint8_t idx)
#if defined(XCURVES) #if defined(XCURVES)
#define CUSTOM_POINT_X(points, count, idx) ((idx)==0 ? -100 : (((idx)==(count)-1) ? 100 : points[(count)+(idx)-1])) #define CUSTOM_POINT_X(points, count, idx) ((idx)==0 ? -100 : (((idx)==(count)-1) ? 100 : points[(count)+(idx)-1]))
s32 compute_tangent(CurveInfo *crv, int8_t *points, int i) s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
{ {
s32 m=0; s32 m=0;
uint8_t num_points = crv->points + 5; uint8_t num_points = crv->points + 5;
@ -238,16 +238,32 @@ int applyCurve(int x, CurveRef & curve)
switch (curve.type) { switch (curve.type) {
case CURVE_REF_DIFF: case CURVE_REF_DIFF:
{ {
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode);
if (curveParam > 0 && x < 0)
x = (x * (1000 - curveParam)) / 1000;
else if (curveParam < 0 && x > 0)
x = (x * (1000 + curveParam)) / 1000;
return x;
#else
int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode)); int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode));
if (curveParam > 0 && x < 0) if (curveParam > 0 && x < 0)
x = (x * (256 - curveParam)) >> 8; x = (x * (256 - curveParam)) >> 8;
else if (curveParam < 0 && x > 0) else if (curveParam < 0 && x > 0)
x = (x * (256 + curveParam)) >> 8; x = (x * (256 + curveParam)) >> 8;
return x; return x;
#endif
} }
case CURVE_REF_EXPO: case CURVE_REF_EXPO:
return expo(x, GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode)); {
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode) / 10;
#else
int curveParam = GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode);
#endif
return expo(x, curveParam);
}
case CURVE_REF_FUNC: case CURVE_REF_FUNC:
switch (curve.value) { switch (curve.value) {

View file

@ -27,7 +27,6 @@ CustomFunctionsContext modelFunctionsContext = { 0 };
CustomFunctionsContext globalFunctionsContext = { 0 }; CustomFunctionsContext globalFunctionsContext = { 0 };
#endif #endif
#if defined(DEBUG) #if defined(DEBUG)
/* /*
* This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES * This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES
@ -204,10 +203,8 @@ PLAY_FUNCTION(playValue, source_t idx)
} }
#else #else
default: default:
{
PLAY_NUMBER(val, 0, 0); PLAY_NUMBER(val, 0, 0);
break; break;
}
#endif #endif
} }
#endif #endif
@ -228,6 +225,27 @@ void playCustomFunctionFile(const CustomFunctionData *sd, uint8_t id)
} }
#endif #endif
#if defined(CPUARM)
bool isRepeatDelayElapsed(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext, uint8_t index)
{
const CustomFunctionData * cfn = &functions[index];
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) {
functionsContext.lastFunctionTime[index] = tmr10ms;
}
if (!functionsContext.lastFunctionTime[index] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-functionsContext.lastFunctionTime[index])>=100*repeatParam)) {
functionsContext.lastFunctionTime[index] = tmr10ms;
return true;
}
else {
return false;
}
}
#else
#define isRepeatDelayElapsed(...) true
#endif
#if defined(CPUARM) #if defined(CPUARM)
#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting #define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting
getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range
@ -361,10 +379,8 @@ void evalFunctions()
#if defined(CPUARM) #if defined(CPUARM)
case FUNC_SET_TIMER: case FUNC_SET_TIMER:
{
timerSet(CFN_TIMER_INDEX(cfn), CFN_PARAM(cfn)); timerSet(CFN_TIMER_INDEX(cfn), CFN_PARAM(cfn));
break; break;
}
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
@ -398,30 +414,36 @@ void evalFunctions()
#if defined(GVARS) #if defined(GVARS)
case FUNC_ADJUST_GVAR: case FUNC_ADJUST_GVAR:
if (CFN_GVAR_MODE(cfn) == 0) { if (isRepeatDelayElapsed(functions, functionsContext, i)) {
SET_GVAR(CFN_GVAR_INDEX(cfn), CFN_PARAM(cfn), mixerCurrentFlightMode); if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_CONSTANT) {
} SET_GVAR(CFN_GVAR_INDEX(cfn), CFN_PARAM(cfn), mixerCurrentFlightMode);
else if (CFN_GVAR_MODE(cfn) == 2) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), mixerCurrentFlightMode), mixerCurrentFlightMode);
}
else if (CFN_GVAR_MODE(cfn) == 3) {
if (!(functionsContext.activeSwitches & switch_mask)) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode);
} }
} else if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_GVAR) {
else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) { SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_PARAM(cfn))), mixerCurrentFlightMode);
trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn);
}
#if defined(ROTARY_ENCODERS)
else if (CFN_PARAM(cfn) >= MIXSRC_REa && CFN_PARAM(cfn) < MIXSRC_TrimRud) {
int8_t scroll = rePreviousValues[CFN_PARAM(cfn)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(cfn)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY);
if (scroll) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + scroll, mixerCurrentFlightMode);
} }
} else if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_INCDEC) {
#if defined(CPUARM)
SET_GVAR(CFN_GVAR_INDEX(cfn), limit(CFN_GVAR_CST_MIN+g_model.gvars[CFN_GVAR_INDEX(cfn)].min, GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + CFN_PARAM(cfn), CFN_GVAR_CST_MAX-g_model.gvars[CFN_GVAR_INDEX(cfn)].max), mixerCurrentFlightMode);
#else
if (!(functionsContext.activeSwitches & switch_mask)) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode);
}
#endif #endif
else { }
SET_GVAR(CFN_GVAR_INDEX(cfn), calcRESXto100(getValue(CFN_PARAM(cfn))), mixerCurrentFlightMode); else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) {
trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn);
}
#if defined(ROTARY_ENCODERS)
else if (CFN_PARAM(cfn) >= MIXSRC_REa && CFN_PARAM(cfn) < MIXSRC_TrimRud) {
int8_t scroll = rePreviousValues[CFN_PARAM(cfn)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(cfn)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY);
if (scroll) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + scroll, mixerCurrentFlightMode);
}
}
#endif
else {
SET_GVAR(CFN_GVAR_INDEX(cfn), calcRESXto100(getValue(CFN_PARAM(cfn))), mixerCurrentFlightMode);
}
} }
break; break;
#endif #endif
@ -447,14 +469,8 @@ void evalFunctions()
case FUNC_HAPTIC: case FUNC_HAPTIC:
#endif #endif
{ {
tmr10ms_t tmr10ms = get_tmr10ms(); if (isRepeatDelayElapsed(functions, functionsContext, i)) {
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) {
functionsContext.lastFunctionTime[i] = tmr10ms;
}
if (!functionsContext.lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=100*repeatParam)) {
if (!IS_PLAYING(PLAY_INDEX)) { if (!IS_PLAYING(PLAY_INDEX)) {
functionsContext.lastFunctionTime[i] = tmr10ms;
if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) { if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn)); AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn));
} }
@ -507,7 +523,7 @@ void evalFunctions()
else { else {
#if defined(GVARS) #if defined(GVARS)
if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK && param > 250) if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK && param > 250)
param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251)); param = GVAR_VALUE(param-251, getGVarFlightMode(mixerCurrentFlightMode, param-251));
#endif #endif
PUSH_CUSTOM_PROMPT(active ? param : param+1, PLAY_INDEX); PUSH_CUSTOM_PROMPT(active ? param : param+1, PLAY_INDEX);
} }

View file

@ -260,7 +260,7 @@ void menuGeneralSetup(uint8_t event)
if (checkIncDec_Ret) { if (checkIncDec_Ret) {
g_eeGeneral.speakerVolume = (int8_t)b-VOLUME_LEVEL_DEF; g_eeGeneral.speakerVolume = (int8_t)b-VOLUME_LEVEL_DEF;
#if !defined(CPUARM) #if !defined(CPUARM)
setVolume(b); setScaledVolume(b);
#endif #endif
} }
} }
@ -367,14 +367,14 @@ void menuGeneralSetup(uint8_t event)
case ITEM_SETUP_MEMORY_WARNING: case ITEM_SETUP_MEMORY_WARNING:
{ {
uint8_t b = 1-g_eeGeneral.disableMemoryWarning; uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event); g_eeGeneral.disableMemoryWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event);
break; break;
} }
case ITEM_SETUP_ALARM_WARNING: case ITEM_SETUP_ALARM_WARNING:
{ {
uint8_t b = 1-g_eeGeneral.disableAlarmWarning; uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event); g_eeGeneral.disableAlarmWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event);
break; break;
} }
@ -395,7 +395,7 @@ void menuGeneralSetup(uint8_t event)
#endif #endif
case ITEM_SETUP_INACTIVITY_ALARM: case ITEM_SETUP_INACTIVITY_ALARM:
lcd_putsLeft( y,STR_INACTIVITYALARM); lcd_putsLeft(y, STR_INACTIVITYALARM);
lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.inactivityTimer, attr|LEFT); lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.inactivityTimer, attr|LEFT);
lcdDrawChar(lcdLastPos, y, 'm'); lcdDrawChar(lcdLastPos, y, 'm');
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
@ -419,7 +419,7 @@ void menuGeneralSetup(uint8_t event)
break; break;
case ITEM_SETUP_FLASH_BEEP: case ITEM_SETUP_FLASH_BEEP:
g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ; g_eeGeneral.alarmsFlash = editCheckBox(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ;
break; break;
case ITEM_SETUP_BACKLIGHT_DELAY: case ITEM_SETUP_BACKLIGHT_DELAY:
@ -459,7 +459,7 @@ void menuGeneralSetup(uint8_t event)
case ITEM_SETUP_DISABLE_SPLASH: case ITEM_SETUP_DISABLE_SPLASH:
{ {
uint8_t b = 1-g_eeGeneral.splashMode; uint8_t b = 1-g_eeGeneral.splashMode;
g_eeGeneral.splashMode = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_SPLASHSCREEN, attr, event); g_eeGeneral.splashMode = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, STR_SPLASHSCREEN, attr, event);
break; break;
} }
#endif #endif
@ -502,7 +502,7 @@ void menuGeneralSetup(uint8_t event)
#if defined(FAI_CHOICE) #if defined(FAI_CHOICE)
case ITEM_SETUP_FAI: case ITEM_SETUP_FAI:
onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event); editCheckBox(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
if (g_eeGeneral.fai) if (g_eeGeneral.fai)
POPUP_WARNING(PSTR("FAI\001mode blocked!")); POPUP_WARNING(PSTR("FAI\001mode blocked!"));

View file

@ -341,7 +341,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
case 4: case 4:
if (HAS_ENABLE_PARAM(func)) { if (HAS_ENABLE_PARAM(func)) {
menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); drawCheckBox(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr);
#if defined(CPUARM) #if defined(CPUARM)
if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
#else #else

View file

@ -172,10 +172,10 @@ void menuModelPhaseOne(uint8_t event)
} }
} }
uint8_t p = getGVarFlightPhase(s_currIdx, idx); uint8_t p = getGVarFlightMode(s_currIdx, idx);
lcdDrawNumber(21*FW, y, GVAR_VALUE(idx, p), posHorz==2 ? attr : 0); lcdDrawNumber(21*FW, y, GVAR_VALUE(idx, p), posHorz==2 ? attr : 0);
if (attr && posHorz==2 && ((editMode>0) || p1valdiff)) { if (attr && posHorz==2 && ((editMode>0) || p1valdiff)) {
GVAR_VALUE(idx, p) = checkIncDec(event, GVAR_VALUE(idx, p), -GVAR_LIMIT, GVAR_LIMIT, EE_MODEL); GVAR_VALUE(idx, p) = checkIncDec(event, GVAR_VALUE(idx, p), -500, 500, EE_MODEL);
} }
break; break;

View file

@ -171,19 +171,6 @@ void copyExpoMix(uint8_t expo, uint8_t idx)
storageDirty(EE_MODEL); storageDirty(EE_MODEL);
} }
void memswap(void *a, void *b, uint8_t size)
{
uint8_t *x = (uint8_t*)a;
uint8_t *y = (uint8_t*)b;
uint8_t temp ;
while (size--) {
temp = *x;
*x++ = *y;
*y++ = temp;
}
}
bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up) bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
{ {
void *x, *y; void *x, *y;
@ -449,8 +436,8 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
void menuModelMixOne(uint8_t event) void menuModelMixOne(uint8_t event)
{ {
TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX); TITLE(STR_MIXER);
MixData *md2 = mixAddress(s_currIdx) ; MixData * md2 = mixAddress(s_currIdx) ;
putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0); putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0);
#if defined(ROTARY_ENCODERS) #if defined(ROTARY_ENCODERS)
@ -530,7 +517,7 @@ void menuModelMixOne(uint8_t event)
if (attr && menuHorizontalPosition==0 && (not_stick || editMode>0)) md2->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL); if (attr && menuHorizontalPosition==0 && (not_stick || editMode>0)) md2->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
if (!not_stick) { if (!not_stick) {
lcdDrawText(COLUMN_X+MIXES_2ND_COLUMN, y, STR_DREX); lcdDrawText(COLUMN_X+MIXES_2ND_COLUMN, y, STR_DREX);
menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN+DREX_CHBOX_OFFSET, y, !md2->noExpo, menuHorizontalPosition==1 ? attr : 0); drawCheckBox(COLUMN_X+MIXES_2ND_COLUMN+DREX_CHBOX_OFFSET, y, !md2->noExpo, menuHorizontalPosition==1 ? attr : 0);
if (attr && menuHorizontalPosition==1 && editMode>0) md2->noExpo = !checkIncDecModel(event, !md2->noExpo, 0, 1); if (attr && menuHorizontalPosition==1 && editMode>0) md2->noExpo = !checkIncDecModel(event, !md2->noExpo, 0, 1);
} }
else if (attr) { else if (attr) {

View file

@ -232,7 +232,7 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_TIMER3_MINUTE_BEEP: case ITEM_MODEL_TIMER3_MINUTE_BEEP:
{ {
TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)]; TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)];
timer->minuteBeep = onoffMenuItem(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); timer->minuteBeep = editCheckBox(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
break; break;
} }
@ -263,10 +263,10 @@ void menuModelSetup(uint8_t event)
{ {
TimerData *timer = &g_model.timers[k>=ITEM_MODEL_TIMER2 ? 1 : 0]; TimerData *timer = &g_model.timers[k>=ITEM_MODEL_TIMER2 ? 1 : 0];
if (k==ITEM_MODEL_TIMER1_MINUTE_BEEP || k==ITEM_MODEL_TIMER2_MINUTE_BEEP) { if (k==ITEM_MODEL_TIMER1_MINUTE_BEEP || k==ITEM_MODEL_TIMER2_MINUTE_BEEP) {
timer->minuteBeep = onoffMenuItem(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); timer->minuteBeep = editCheckBox(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
} }
else if (k==ITEM_MODEL_TIMER1_COUNTDOWN_BEEP || k==ITEM_MODEL_TIMER2_COUNTDOWN_BEEP) { else if (k==ITEM_MODEL_TIMER1_COUNTDOWN_BEEP || k==ITEM_MODEL_TIMER2_COUNTDOWN_BEEP) {
timer->countdownBeep = onoffMenuItem(timer->countdownBeep, MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event); timer->countdownBeep = editCheckBox(timer->countdownBeep, MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event);
} }
else { else {
putsStrIdx(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1); putsStrIdx(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1);
@ -369,7 +369,7 @@ void menuModelSetup(uint8_t event)
#endif #endif
case ITEM_MODEL_THROTTLE_WARNING: case ITEM_MODEL_THROTTLE_WARNING:
g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event); g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event);
break; break;
case ITEM_MODEL_SWITCHES_WARNING: case ITEM_MODEL_SWITCHES_WARNING:
@ -465,7 +465,7 @@ void menuModelSetup(uint8_t event)
#if defined(CPUARM) #if defined(CPUARM)
case ITEM_MODEL_USE_GLOBAL_FUNCTIONS: case ITEM_MODEL_USE_GLOBAL_FUNCTIONS:
lcd_putsLeft(y, STR_USE_GLOBAL_FUNCS); lcd_putsLeft(y, STR_USE_GLOBAL_FUNCS);
menu_lcd_onoff(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr); drawCheckBox(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr);
if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1); if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1);
break; break;
#endif #endif

View file

@ -50,7 +50,7 @@ extern uint8_t noHighlightCounter;
#define NO_HIGHLIGHT() (noHighlightCounter > 0) #define NO_HIGHLIGHT() (noHighlightCounter > 0)
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr); void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
typedef void (* MenuHandlerFunc)(uint8_t event); typedef void (* MenuHandlerFunc)(uint8_t event);
@ -385,26 +385,26 @@ void title(const pm_char * s);
#endif #endif
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event); select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event);
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event); uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event);
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event); int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event);
#define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = onoffMenuItem(value, x, y, label, attr, event) #define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
#if defined(CPUARM) && defined(GVARS) #if defined(CPUARM) && defined(GVARS)
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(x, y, v, min, max, lcdattr, editflags, event) #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
#else #else
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(x, y, v, min, max, lcdattr, event) #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event)
#endif #endif
#if defined(GVARS) #if defined(GVARS)
#if defined(CPUARM) #if defined(CPUARM)
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event); int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event);
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); // @@@ open.20.fsguruh int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); // @@@ open.20.fsguruh
#endif #endif
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event);
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) #define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
#endif #endif

View file

@ -397,8 +397,8 @@ void menuMainView(uint8_t event)
case EVT_KEY_FIRST(KEY_EXIT): case EVT_KEY_FIRST(KEY_EXIT):
#if defined(GVARS) && !defined(PCBSTD) #if defined(GVARS) && !defined(PCBSTD)
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer = 0; gvarDisplayTimer = 0;
} }
#endif #endif
if (view == VIEW_TIMER2) { if (view == VIEW_TIMER2) {
@ -555,13 +555,14 @@ void menuMainView(uint8_t event)
} }
#if defined(GVARS) && !defined(PCBSTD) #if defined(GVARS) && !defined(PCBSTD)
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer--; gvarDisplayTimer--;
warningText = STR_GLOBAL_VAR; warningText = STR_GLOBAL_VAR;
displayBox(); displayBox();
lcdDrawSizedText(16, 5*FH, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); lcdDrawSizedText(16, 5*FH, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, ZCHAR);
lcdDrawText(16+7*FW, 5*FH, PSTR("[\010]"), BOLD); lcdDrawText(16+7*FW, 5*FH, PSTR("[\010]"), BOLD);
lcdDrawNumber(16+7*FW+4*FW+FW/2, 5*FH, GVAR_VALUE(s_gvar_last, getGVarFlightPhase(mixerCurrentFlightMode, s_gvar_last)), BOLD);
lcdDrawNumber(16+7*FW+4*FW+FW/2, 5*FH, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), BOLD);
warningText = NULL; warningText = NULL;
} }
#endif #endif

View file

@ -499,7 +499,7 @@ void menuTelemetryMavlinkSetup(uint8_t event) {
if (attr) CHECK_INCDEC_MODELVAR(event, g_model.mavlink.rc_rssi_scale, 0, 15); if (attr) CHECK_INCDEC_MODELVAR(event, g_model.mavlink.rc_rssi_scale, 0, 15);
break; break;
case ITEM_MAVLINK_PC_RSSI_EN: case ITEM_MAVLINK_PC_RSSI_EN:
g_model.mavlink.pc_rssi_en = onoffMenuItem(g_model.mavlink.pc_rssi_en, g_model.mavlink.pc_rssi_en = editCheckBox(g_model.mavlink.pc_rssi_en,
RADIO_SETUP_2ND_COLUMN, RADIO_SETUP_2ND_COLUMN,
y, y,
STR_MAVLINK_PC_RSSI_EN_LABEL, STR_MAVLINK_PC_RSSI_EN_LABEL,

View file

@ -32,7 +32,7 @@ void drawStick(coord_t centrex, int16_t xval, int16_t yval)
#undef MARKER_WIDTH #undef MARKER_WIDTH
} }
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr) void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
{ {
#if defined(GRAPHICS) #if defined(GRAPHICS)
if (value) if (value)
@ -80,10 +80,10 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, c
return value; return value;
} }
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event ) uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event )
{ {
#if defined(GRAPHICS) #if defined(GRAPHICS)
menu_lcd_onoff(x, y, value, attr); drawCheckBox(x, y, value, attr);
return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event); return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event);
#else #else
return selectMenuItem(x, y, label, STR_OFFON, value, 0, 1, attr, event); return selectMenuItem(x, y, label, STR_OFFON, value, 0, 1, attr, event);
@ -120,12 +120,12 @@ bool noZero(int val)
return val != 0; return val != 0;
} }
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event)
{ {
uint16_t delta = GV_GET_GV1_VALUE(max); uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS); bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode; s_editMode = !s_editMode;
@ -167,12 +167,12 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
return value; return value;
} }
#elif defined(GVARS) #elif defined(GVARS)
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
{ {
uint16_t delta = GV_GET_GV1_VALUE(max); uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS); bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode; s_editMode = !s_editMode;
@ -207,7 +207,7 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
return value; return value;
} }
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
{ {
lcdDrawNumber(x, y, value, attr); lcdDrawNumber(x, y, value, attr);
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);

View file

@ -259,3 +259,7 @@ const uint8_t LBM_SHUTDOWN[] __DMA = {
const uint8_t LBM_SLEEP[] __DMA = { const uint8_t LBM_SLEEP[] __DMA = {
#include "sleep.lbm" #include "sleep.lbm"
}; };
const uint8_t LBM_BIGRSCALE[] __DMA = {
#include "mask_bigrscale.lbm"
};

View file

@ -78,6 +78,13 @@ void drawSubmenuTemplate(const char * name, uint16_t scrollbar_X);
void drawStick(coord_t centrex, int16_t xval, int16_t yval); void drawStick(coord_t centrex, int16_t xval, int16_t yval);
void drawSticks(); void drawSticks();
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value, uint8_t attr);
FlightModesType editFlightModes(coord_t x, coord_t y, evt_t event, FlightModesType value, uint8_t attr);
#else
#define displayFlightModes(...)
#endif
// Curve functions // Curve functions
coord_t getCurveYCoord(FnFuncP fn, int x, int width); coord_t getCurveYCoord(FnFuncP fn, int x, int width);
void drawFunction(FnFuncP fn, int offset); void drawFunction(FnFuncP fn, int offset);
@ -127,3 +134,4 @@ extern const uint8_t LBM_CURVE_POINT_CENTER[];
extern const uint8_t LBM_CURVE_COORD_SHADOW[]; extern const uint8_t LBM_CURVE_COORD_SHADOW[];
extern const uint8_t LBM_SHUTDOWN[]; extern const uint8_t LBM_SHUTDOWN[];
extern const uint8_t LBM_SLEEP[]; extern const uint8_t LBM_SLEEP[];
extern const uint8_t LBM_BIGRSCALE[];

View file

@ -547,57 +547,80 @@ void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
} }
} }
void putsSwitches(coord_t x, coord_t y, int8_t idx, LcdFlags att) char * getStringAtIndex(char * dest, const char * s, int idx)
{
uint8_t len = s[0];
strncpy(dest, s+1+len*idx, len);
dest[len] = '\0';
return dest;
}
char * getStringWithIndex(char * dest, const char * s, int idx)
{
// TODO reimplement without the sprintf
sprintf(dest, "%s%d", s, abs(idx));
return dest;
}
char * getSwitchString(char * dest, swsrc_t idx)
{ {
if (idx == SWSRC_NONE) { if (idx == SWSRC_NONE) {
return lcdDrawTextAtIndex(x, y, STR_VSWITCHES, 0, att); return getStringAtIndex(dest, STR_VSWITCHES, 0);
} }
else if (idx == SWSRC_OFF) { else if (idx == SWSRC_OFF) {
return lcdDrawTextAtIndex(x, y, STR_OFFON, 0, att); return getStringAtIndex(dest, STR_OFFON, 0);
} }
char s[8]; char * s = dest;
int pos = 0;
if (idx < 0) { if (idx < 0) {
s[pos++] = '!'; *s++ = '!';
idx = -idx; idx = -idx;
} }
if (idx <= SWSRC_LAST_SWITCH) { if (idx <= SWSRC_LAST_SWITCH) {
div_t swinfo = switchInfo(idx); div_t swinfo = switchInfo(idx);
if (ZEXIST(g_eeGeneral.switchNames[swinfo.quot])) { if (ZEXIST(g_eeGeneral.switchNames[swinfo.quot])) {
pos = zchar2str(&s[pos], g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME); zchar2str(s, g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME);
// TODO tous zchar2str
} }
else { else {
s[pos++] = 'S'; *s++ = 'S';
s[pos++] = 'A'+swinfo.quot; *s++ = 'A'+swinfo.quot;
} }
s[pos++] = "\300-\301"[swinfo.rem]; *s++ = "\300-\301"[swinfo.rem];
s[pos] = '\0'; *s = '\0';
lcdDrawText(x, y, s, att);
} }
/*else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) { else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) {
div_t swinfo = div(idx - SWSRC_FIRST_MULTIPOS_SWITCH, XPOTS_MULTIPOS_COUNT); div_t swinfo = div(idx - SWSRC_FIRST_MULTIPOS_SWITCH, XPOTS_MULTIPOS_COUNT);
putsStrIdx(x, y, "S", swinfo.quot*10+swinfo.rem+11, att); getStringWithIndex(s, "S", swinfo.quot*10+swinfo.rem+11);
}*/ }
else if (idx <= SWSRC_LAST_TRIM) { else if (idx <= SWSRC_LAST_TRIM) {
lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx-SWSRC_FIRST_TRIM+1, att); getStringAtIndex(s, STR_VSWITCHES, idx-SWSRC_FIRST_TRIM+1);
} }
else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) { else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) {
putsStrIdx(x, y, "L", idx-SWSRC_FIRST_LOGICAL_SWITCH+1, att); getStringWithIndex(s, "L", idx-SWSRC_FIRST_LOGICAL_SWITCH+1);
} }
else if (idx <= SWSRC_ONE) { else if (idx <= SWSRC_ONE) {
lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx-SWSRC_ON+1+(2*NUM_STICKS), att); getStringAtIndex(s, STR_VSWITCHES, idx-SWSRC_ON+1+(2*NUM_STICKS));
} }
else if (idx <= SWSRC_LAST_FLIGHT_MODE) { else if (idx <= SWSRC_LAST_FLIGHT_MODE) {
putsStrIdx(x, y, STR_FP, idx-SWSRC_FIRST_FLIGHT_MODE, att); getStringWithIndex(s, STR_FP, idx-SWSRC_FIRST_FLIGHT_MODE);
} }
else if (idx == SWSRC_TELEMETRY_STREAMING) { else if (idx == SWSRC_TELEMETRY_STREAMING) {
lcdDrawText(x, y, "Tele", att); strcpy(s, "Tele");
} }
else { else {
lcdDrawSizedText(x, y, g_model.telemetrySensors[idx-SWSRC_FIRST_SENSOR].label, TELEM_LABEL_LEN, ZCHAR|att); zchar2str(s, g_model.telemetrySensors[idx-SWSRC_FIRST_SENSOR].label, TELEM_LABEL_LEN);
} }
return dest;
}
void putsSwitches(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags)
{
char s[8];
getSwitchString(s, idx);
lcdDrawText(x, y, s, flags);
} }
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att) void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att)

View file

@ -182,7 +182,7 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags=0, uint8_t
void putsStrIdx(coord_t x, coord_t y, const pm_char *str, int idx, LcdFlags att=0, const char *prefix=""); void putsStrIdx(coord_t x, coord_t y, const pm_char *str, int idx, LcdFlags att=0, const char *prefix="");
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void putsSwitches(coord_t x, coord_t y, int8_t swtch, LcdFlags att=0); void putsSwitches(coord_t x, coord_t y, swsrc_t swtch, LcdFlags flags=0);
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att=0); void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att=0);

View file

@ -195,8 +195,8 @@ bool menuCommonCalib(evt_t event)
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i]; StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
steps = calib->count + 1; steps = calib->count + 1;
} }
if (steps > 0 && steps <= XPOTS_MULTIPOS_COUNT) { if (calibrationState != 0 && steps > 0 && steps <= XPOTS_MULTIPOS_COUNT) {
lcdDrawNumber(LCD_W/2-(POT_BAR_INTERVAL*NUM_POTS/2)+(POT_BAR_INTERVAL*(i-POT1)), POT_BAR_BOTTOM+15, steps, TEXT_COLOR|TINSIZE, 0, "[", "]"); lcdDrawNumber(LCD_W/2+3-(POT_BAR_INTERVAL*NUM_POTS/2)+(POT_BAR_INTERVAL*(i-POT1)), POT_BAR_BOTTOM+15, steps, TEXT_COLOR|TINSIZE, 0, "[", "]");
} }
} }

View file

@ -338,7 +338,7 @@ bool menuGeneralSetup(evt_t event)
{ {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MEMORYWARNING); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MEMORYWARNING);
uint8_t b = 1-g_eeGeneral.disableMemoryWarning; uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, attr, event); g_eeGeneral.disableMemoryWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, attr, event);
break; break;
} }
#endif #endif
@ -347,7 +347,7 @@ bool menuGeneralSetup(evt_t event)
{ {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALARMWARNING); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALARMWARNING);
uint8_t b = 1-g_eeGeneral.disableAlarmWarning; uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, attr, event); g_eeGeneral.disableAlarmWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, attr, event);
break; break;
} }
@ -385,7 +385,7 @@ bool menuGeneralSetup(evt_t event)
case ITEM_SETUP_FLASH_BEEP: case ITEM_SETUP_FLASH_BEEP:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALARM); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALARM);
g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, attr, event ) ; g_eeGeneral.alarmsFlash = editCheckBox(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, attr, event ) ;
break; break;
case ITEM_SETUP_BACKLIGHT_DELAY: case ITEM_SETUP_BACKLIGHT_DELAY:
@ -462,7 +462,7 @@ bool menuGeneralSetup(evt_t event)
#if 0 #if 0
case ITEM_SETUP_FAI: case ITEM_SETUP_FAI:
lcdDrawText(MENUS_MARGIN_LEFT, y, PSTR("FAI Mode")); lcdDrawText(MENUS_MARGIN_LEFT, y, PSTR("FAI Mode"));
g_eeGeneral.fai = onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, attr, event); g_eeGeneral.fai = editCheckBox(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
if (g_eeGeneral.fai) if (g_eeGeneral.fai)
POPUP_WARNING(PSTR("FAI\001mode blocked!")); POPUP_WARNING(PSTR("FAI\001mode blocked!"));

View file

@ -34,6 +34,8 @@ uint8_t editDelay(const coord_t x, const coord_t y, const evt_t event, const uin
uint8_t s_copyMode = 0; uint8_t s_copyMode = 0;
int8_t s_copySrcRow; int8_t s_copySrcRow;
int8_t s_copyTgtOfs; int8_t s_copyTgtOfs;
uint8_t s_copySrcIdx;
uint8_t s_copySrcCh;
uint8_t editNameCursorPos = 0; uint8_t editNameCursorPos = 0;

View file

@ -135,7 +135,7 @@ enum MenuModelCurveOneItems {
bool menuModelCurveOne(evt_t event) bool menuModelCurveOne(evt_t event)
{ {
static uint8_t pointsOfs = 0; static uint8_t pointsOfs = 0;
CurveInfo & crv = g_model.curves[s_curveChan]; CurveData & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan); int8_t * points = curveAddress(s_curveChan);
SUBMENU(STR_MENUCURVE, crv.type==CURVE_TYPE_CUSTOM ? 6 : 5, 0, { 0, 0, 0, 0, uint8_t(5+crv.points-1), uint8_t(5+crv.points-1) }); SUBMENU(STR_MENUCURVE, crv.type==CURVE_TYPE_CUSTOM ? 6 : 5, 0, { 0, 0, 0, 0, uint8_t(5+crv.points-1), uint8_t(5+crv.points-1) });
@ -144,7 +144,7 @@ bool menuModelCurveOne(evt_t event)
// Curve name // Curve name
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP, STR_NAME); lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP, STR_NAME);
editName(MODEL_CURVE_ONE_2ND_COLUMN, MENU_CONTENT_TOP, g_model.curveNames[s_curveChan], sizeof(g_model.curveNames[s_curveChan]), event, menuVerticalPosition==ITEM_CURVE_NAME); editName(MODEL_CURVE_ONE_2ND_COLUMN, MENU_CONTENT_TOP, crv.name, sizeof(crv.name), event, menuVerticalPosition==ITEM_CURVE_NAME);
// Curve type // Curve type
LcdFlags attr = (menuVerticalPosition==ITEM_CURVE_TYPE ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0); LcdFlags attr = (menuVerticalPosition==ITEM_CURVE_TYPE ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0);
@ -328,6 +328,9 @@ void editCurveRef(coord_t x, coord_t y, CurveRef & curve, evt_t event, uint8_t a
} }
} }
#define CURVES_NAME_POS 60
#define CURVES_POINTS_POS 120
bool menuModelCurvesAll(evt_t event) bool menuModelCurvesAll(evt_t event)
{ {
SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, MAX_CURVES, DEFAULT_SCROLLBAR_X); SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, MAX_CURVES, DEFAULT_SCROLLBAR_X);
@ -349,9 +352,9 @@ bool menuModelCurvesAll(evt_t event)
LcdFlags attr = (sub == k ? INVERS : 0); LcdFlags attr = (sub == k ? INVERS : 0);
{ {
putsStrIdx(MENUS_MARGIN_LEFT, y, STR_CV, k+1, attr); putsStrIdx(MENUS_MARGIN_LEFT, y, STR_CV, k+1, attr);
editName(50, y, g_model.curveNames[k], sizeof(g_model.curveNames[k]), 0, 0); CurveData & crv = g_model.curves[k];
CurveInfo & crv = g_model.curves[k]; editName(CURVES_NAME_POS, y, crv.name, sizeof(crv.name), 0, 0);
lcdDrawNumber(120, y, 5+crv.points, LEFT, 0, NULL, STR_PTS); lcdDrawNumber(CURVES_POINTS_POS, y, 5+crv.points, LEFT, 0, NULL, STR_PTS);
} }
} }

View file

@ -53,7 +53,7 @@ bool menuModelCustomScriptOne(evt_t event)
// putsStrIdx(lcdLastPos+FW, 0, "LUA", s_currIdx+1, 0); // putsStrIdx(lcdLastPos+FW, 0, "LUA", s_currIdx+1, 0);
SUBMENU(STR_MENUCUSTOMSCRIPT, 3+scriptInputsOutputs[s_currIdx].inputsCount, 0, { 0, 0, LABEL(inputs), 0/*repeated*/ }); SUBMENU(STR_MENUCUSTOMSCRIPTS, 3+scriptInputsOutputs[s_currIdx].inputsCount, 0, { 0, 0, LABEL(inputs), 0/*repeated*/ });
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;

View file

@ -21,6 +21,36 @@
#include <stdio.h> #include <stdio.h>
#include "../../opentx.h" #include "../../opentx.h"
void displayFlightModes(coord_t x, coord_t y, FlightModesType value, uint8_t attr)
{
for (int i=0; i<MAX_FLIGHT_MODES; i++) {
LcdFlags flags = ((menuHorizontalPosition==i && attr) ? INVERS : 0);
flags |= ((value & (1<<i))) ? TEXT_DISABLE_COLOR : TEXT_COLOR;
if (attr && menuHorizontalPosition < 0) flags |= INVERS;
char s[] = " ";
s[0] = '0' + i;
lcdDrawText(x, y, s, flags);
x += 12;
}
}
FlightModesType editFlightModes(coord_t x, coord_t y, evt_t event, FlightModesType value, uint8_t attr)
{
int posHorz = menuHorizontalPosition;
displayFlightModes(x, y, value, attr);
if (attr) {
if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
enum FlightModesItems { enum FlightModesItems {
ITEM_FLIGHT_MODES_NAME, ITEM_FLIGHT_MODES_NAME,
ITEM_FLIGHT_MODES_SWITCH, ITEM_FLIGHT_MODES_SWITCH,

View file

@ -0,0 +1,572 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
#include "../../opentx.h"
#define EXPO_ONE_2ND_COLUMN 110
int expoFn(int x)
{
ExpoData * ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
applyExpos(anas, e_perout_mode_inactive_flight_mode, ed->srcRaw, x);
return anas[ed->chn];
}
int getExposLinesCount()
{
int lastch = -1;
uint8_t count = MAX_INPUTS;
for (int i=0; i<MAX_EXPOS; i++) {
bool valid = EXPO_VALID(expoAddress(i));
if (!valid)
break;
int ch = expoAddress(i)->chn;
if (ch == lastch) {
count++;
}
else {
lastch = ch;
}
}
return count;
}
uint8_t getExposCount()
{
uint8_t count = 0;
uint8_t ch ;
for (int i=MAX_EXPOS-1 ; i>=0; i--) {
ch = EXPO_VALID(expoAddress(i));
if (ch != 0) {
count++;
}
}
return count;
}
bool reachExposLimit()
{
if (getExposCount() >= MAX_EXPOS) {
POPUP_WARNING(STR_NOFREEEXPO);
return true;
}
return false;
}
void deleteExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
int input = expo->chn;
memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData));
if (!isInputAvailable(input)) {
memclear(&g_model.inputNames[input], LEN_INPUT_NAME);
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
// TODO avoid this global s_currCh on ARM boards ...
int8_t s_currCh;
void insertExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(expo, sizeof(ExpoData));
expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
expo->curve.type = CURVE_REF_EXPO;
expo->mode = 3; // pos+neg
expo->chn = s_currCh - 1;
expo->weight = 100;
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
bool swapExpos(uint8_t & idx, uint8_t up)
{
ExpoData * x, * y;
int8_t tgt_idx = (up ? idx-1 : idx+1);
x = expoAddress(idx);
if (tgt_idx < 0) {
if (x->chn == 0)
return false;
x->chn--;
return true;
}
if (tgt_idx == MAX_EXPOS) {
if (x->chn == NUM_INPUTS-1)
return false;
x->chn++;
return true;
}
y = expoAddress(tgt_idx);
if (x->chn != y->chn || !EXPO_VALID(y)) {
if (up) {
if (x->chn>0) x->chn--;
else return false;
}
else {
if (x->chn<NUM_INPUTS-1) x->chn++;
else return false;
}
return true;
}
pauseMixerCalculations();
memswap(x, y, sizeof(ExpoData));
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum ExposFields {
EXPO_FIELD_INPUT_NAME,
EXPO_FIELD_NAME,
EXPO_FIELD_SOURCE,
EXPO_FIELD_WEIGHT,
EXPO_FIELD_OFFSET,
CASE_CURVES(EXPO_FIELD_CURVE)
CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES)
EXPO_FIELD_SWITCH,
EXPO_FIELD_SIDE,
EXPO_FIELD_TRIM,
EXPO_FIELD_MAX
};
#define CURVE_ROWS 1
bool menuModelExpoOne(evt_t event)
{
ExpoData * ed = expoAddress(s_currIdx);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, 0, { 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)1 : (uint8_t)0), 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
int sub = menuVerticalPosition;
coord_t y = MENU_CONTENT_TOP;
drawFunction(expoFn, CURVE_CENTER_X, CURVE_CENTER_Y, CURVE_SIDE_WIDTH);
drawCurveHorizontalScale();
drawCurveVerticalScale(CURVE_CENTER_X-CURVE_SIDE_WIDTH-15);
{
char textx[5];
char texty[5];
int x = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
sprintf(textx, "%d", calcRESXto100(x));
// TODO putsTelemetryChannelValue(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x);
if (ed->scale > 0) x = (x * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
}
else {
sprintf(textx, "%d", calcRESXto100(x));
}
x = limit(-1024, x, 1024);
int y = limit<int>(-1024, expoFn(x), 1024);
sprintf(texty, "%d", calcRESXto100(y));
x = divRoundClosest(x*CURVE_SIDE_WIDTH, RESX);
y = CURVE_CENTER_Y + getCurveYCoord(expoFn, x, CURVE_SIDE_WIDTH);
lcdDrawSolidFilledRect(CURVE_CENTER_X+x, CURVE_CENTER_Y-CURVE_SIDE_WIDTH, 2, 2*CURVE_SIDE_WIDTH+2, CURVE_CURSOR_COLOR);
lcdDrawSolidFilledRect(CURVE_CENTER_X-CURVE_SIDE_WIDTH-2, y-1, 2*CURVE_SIDE_WIDTH+2, 2, CURVE_CURSOR_COLOR);
lcdDrawBitmapPattern(CURVE_CENTER_X+x-4, y-4, LBM_CURVE_POINT, CURVE_CURSOR_COLOR);
lcdDrawBitmapPattern(CURVE_CENTER_X+x-4, y-4, LBM_CURVE_POINT_CENTER, TEXT_BGCOLOR);
int left = limit(CURVE_CENTER_X-CURVE_SIDE_WIDTH, CURVE_CENTER_X-CURVE_COORD_WIDTH/2+x, CURVE_CENTER_X+CURVE_SIDE_WIDTH-CURVE_COORD_WIDTH+2);
drawCurveCoord(left, CURVE_CENTER_Y+CURVE_SIDE_WIDTH+2, textx);
int top = limit(CURVE_CENTER_Y-CURVE_SIDE_WIDTH-1, -CURVE_COORD_HEIGHT/2+y, CURVE_CENTER_Y+CURVE_SIDE_WIDTH-CURVE_COORD_HEIGHT+1);
drawCurveCoord(CURVE_CENTER_X-CURVE_SIDE_WIDTH-37, top, texty);
}
for (int i=0; i<NUM_BODY_LINES+1; i++) {
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (i) {
case EXPO_FIELD_INPUT_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_INPUTNAME);
editName(EXPO_ONE_2ND_COLUMN, y, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr);
break;
case EXPO_FIELD_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXPONAME);
editName(EXPO_ONE_2ND_COLUMN, y, ed->name, sizeof(ed->name), event, attr);
break;
case EXPO_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|(menuHorizontalPosition==0?attr:0));
if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN+60, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0));
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
}
else if (attr) {
menuHorizontalPosition = 0;
}
break;
case EXPO_FIELD_WEIGHT:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WEIGHT);
ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event);
break;
case EXPO_FIELD_OFFSET:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_OFFSET));
ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event);
break;
#if defined(CURVES)
case EXPO_FIELD_CURVE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURVE);
editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case EXPO_FIELD_FLIGHT_MODES:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FLMODE);
ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
break;
#endif
case EXPO_FIELD_SWITCH:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SWITCH);
ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event);
break;
case EXPO_FIELD_SIDE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SIDE);
ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_VSIDE, 4-ed->mode, 1, 3, attr, event);
break;
case EXPO_FIELD_TRIM:
uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
int8_t carryTrim = -ed->carryTrim;
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRIM);
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, menuHorizontalPosition==0 ? attr : 0);
if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
break;
}
y += FH;
}
return true;
}
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define EXPO_LINE_WEIGHT_POS 92
#define EXPO_LINE_SRC_POS 115
#define EXPO_LINE_CURVE_POS 162
#define EXPO_LINE_SWITCH_POS 210
#define EXPO_LINE_SIDE_POS 250
#define EXPO_LINE_FM_POS 270
#define EXPO_LINE_NAME_POS 384
#define EXPO_LINE_SELECT_POS 50
#define EXPO_LINE_SELECT_WIDTH (LCD_W-EXPO_LINE_SELECT_POS-15)
void lineExpoSurround(coord_t y, LcdFlags flags=CURVE_AXIS_COLOR)
{
lcdDrawRect(EXPO_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, EXPO_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
}
void onExposMenu(const char * result)
{
uint8_t chn = expoAddress(s_currIdx)->chn + 1;
if (result == STR_EDIT) {
pushMenu(menuModelExpoOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachExposLimit()) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteExpo(s_currIdx);
}
}
void displayExpoInfos(coord_t y, ExpoData *ed)
{
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve);
if (ed->swtch) {
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch);
}
if (ed->mode != 3) {
lcdDrawText(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? "\176" : "\177");
}
}
void displayExpoLine(coord_t y, ExpoData *ed)
{
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw);
displayExpoInfos(y, ed);
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes, 0);
if (ed->name[0]) {
lcdDrawSizedText(EXPO_LINE_NAME_POS, y+2, ed->name, sizeof(ed->name), ZCHAR|SMLSIZE);
}
}
bool menuModelExposAll(evt_t event)
{
int sub = menuVerticalPosition;
if (s_editMode > 0) {
s_editMode = 0;
}
uint8_t chn = expoAddress(s_currIdx)->chn + 1;
int linesCount = getExposLinesCount();
SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, linesCount, DEFAULT_SCROLLBAR_X);
switch (event) {
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteExpo(s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteExpo(s_currIdx);
}
else {
do {
swapExpos(s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(menuModelExpoOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachExposLimit()) break;
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onExposMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachExposLimit()) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = ((event==EVT_ROTARY_LEFT || key==KEY_UP) ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachExposLimit()) break;
copyExpo(s_currIdx);
if (event==EVT_ROTARY_RIGHT || key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteExpo(s_currIdx);
if (event==EVT_ROTARY_LEFT || key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapExpos(s_currIdx, event==EVT_ROTARY_LEFT || key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
char str[6];
sprintf(str, "%d/%d", getExposCount(), MAX_EXPOS);
lcdDrawText(MENU_TITLE_NEXT_POS, MENU_TITLE_TOP+2, str, HEADER_COLOR);
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=NUM_INPUTS; ch++) {
ExpoData * ed;
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
if ((i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed))) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch);
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineExpoSurround(y);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
LcdFlags attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0);
displayExpoLine(y, ed);
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lineExpoSurround(y);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lineExpoSurround(y, ALARM_COLOR);
}
}
}
cur++; y+=FH; mixCnt++; i++; ed++;
} while (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed));
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineExpoSurround(y);
cur++; y+=FH;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch, attr);
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lineExpoSurround(y);
}
}
cur++; y+=FH;
}
}
if (sub >= linesCount-1) menuVerticalPosition = linesCount-1;
return true;
}

View file

@ -1,936 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
#include "../../opentx.h"
#define EXPO_ONE_2ND_COLUMN 110
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value, uint8_t attr)
{
for (int i=0; i<MAX_FLIGHT_MODES; i++) {
LcdFlags flags = ((menuHorizontalPosition==i && attr) ? INVERS : 0);
flags |= ((value & (1<<i))) ? TEXT_DISABLE_COLOR : TEXT_COLOR;
if (attr && menuHorizontalPosition < 0) flags |= INVERS;
char s[] = " ";
s[0] = '0' + i;
lcdDrawText(x, y, s, flags);
x += 12;
}
}
FlightModesType editFlightModes(coord_t x, coord_t y, evt_t event, FlightModesType value, uint8_t attr)
{
int posHorz = menuHorizontalPosition;
displayFlightModes(x, y, value, attr);
if (attr) {
if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
#else
#define displayFlightModes(...)
#endif
int expoFn(int x)
{
ExpoData *ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
applyExpos(anas, e_perout_mode_inactive_flight_mode, ed->srcRaw, x);
return anas[ed->chn];
}
int getLinesCount(uint8_t expo)
{
int lastch = -1;
uint8_t count = (expo ? MAX_INPUTS : NUM_CHNOUT);
for (int i=0; i<(expo ? MAX_EXPOS : MAX_MIXERS); i++) {
bool valid = (expo ? EXPO_VALID(expoAddress(i)) : mixAddress(i)->srcRaw);
if (!valid)
break;
int ch = (expo ? expoAddress(i)->chn : mixAddress(i)->destCh);
if (ch == lastch) {
count++;
}
else {
lastch = ch;
}
}
return count;
}
uint8_t getExpoMixCount(uint8_t expo)
{
uint8_t count = 0;
uint8_t ch ;
for(int8_t i=(expo ? MAX_EXPOS-1 : MAX_MIXERS-1); i>=0; i--) {
ch = (expo ? EXPO_VALID(expoAddress(i)) : mixAddress(i)->srcRaw);
if (ch != 0) {
count++;
}
}
return count;
}
bool reachExpoMixCountLimit(uint8_t expo)
{
// check mixers count limit
if (getExpoMixCount(expo) >= (expo ? MAX_EXPOS : MAX_MIXERS)) {
POPUP_WARNING(expo ? STR_NOFREEEXPO : STR_NOFREEMIXER);
return true;
}
return false;
}
void deleteExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
int input = expo->chn;
memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData));
if (!isInputAvailable(input)) {
memclear(&g_model.inputNames[input], LEN_INPUT_NAME);
}
}
else {
MixData *mix = mixAddress(idx);
memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData));
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
// TODO avoid this global s_currCh on ARM boards ...
int8_t s_currCh;
void insertExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(expo, sizeof(ExpoData));
expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
expo->curve.type = CURVE_REF_EXPO;
expo->mode = 3; // pos&neg
expo->chn = s_currCh - 1;
expo->weight = 100;
}
else {
MixData *mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(mix, sizeof(MixData));
mix->destCh = s_currCh-1;
mix->srcRaw = s_currCh;
if (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
while (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw += 1;
}
}
mix->weight = 100;
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
}
else {
MixData *mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void memswap(void *a, void *b, uint8_t size)
{
uint8_t *x = (uint8_t*)a;
uint8_t *y = (uint8_t*)b;
uint8_t temp ;
while (size--) {
temp = *x;
*x++ = *y;
*y++ = temp;
}
}
bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
{
void *x, *y;
uint8_t size;
int8_t tgt_idx = (up ? idx-1 : idx+1);
if (expo) {
x = (ExpoData *)expoAddress(idx);
if (tgt_idx < 0) {
if (((ExpoData *)x)->chn == 0)
return false;
((ExpoData *)x)->chn--;
return true;
}
if (tgt_idx == MAX_EXPOS) {
if (((ExpoData *)x)->chn == NUM_INPUTS-1)
return false;
((ExpoData *)x)->chn++;
return true;
}
y = (ExpoData *)expoAddress(tgt_idx);
if(((ExpoData *)x)->chn != ((ExpoData *)y)->chn || !EXPO_VALID((ExpoData *)y)) {
if (up) {
if (((ExpoData *)x)->chn>0) ((ExpoData *)x)->chn--;
else return false;
}
else {
if (((ExpoData *)x)->chn<NUM_INPUTS-1) ((ExpoData *)x)->chn++;
else return false;
}
return true;
}
size = sizeof(ExpoData);
}
else {
x = (MixData *)mixAddress(idx);
if (tgt_idx < 0) {
if (((MixData *)x)->destCh == 0)
return false;
((MixData *)x)->destCh--;
return true;
}
if (tgt_idx == MAX_MIXERS) {
if (((MixData *)x)->destCh == NUM_CHNOUT-1)
return false;
((MixData *)x)->destCh++;
return true;
}
y = (MixData *)mixAddress(tgt_idx);
uint8_t destCh = ((MixData *)x)->destCh;
if(!((MixData *)y)->srcRaw || destCh != ((MixData *)y)->destCh) {
if (up) {
if (destCh>0) ((MixData *)x)->destCh--;
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) ((MixData *)x)->destCh++;
else return false;
}
return true;
}
size = sizeof(MixData);
}
pauseMixerCalculations();
memswap(x, y, size);
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum ExposFields {
EXPO_FIELD_INPUT_NAME,
EXPO_FIELD_NAME,
EXPO_FIELD_SOURCE,
EXPO_FIELD_WEIGHT,
EXPO_FIELD_OFFSET,
CASE_CURVES(EXPO_FIELD_CURVE)
CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES)
EXPO_FIELD_SWITCH,
EXPO_FIELD_SIDE,
EXPO_FIELD_TRIM,
EXPO_FIELD_MAX
};
#define CURVE_ROWS 1
bool menuModelExpoOne(evt_t event)
{
ExpoData *ed = expoAddress(s_currIdx);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, 0, { 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)1 : (uint8_t)0), 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
int sub = menuVerticalPosition;
coord_t y = MENU_CONTENT_TOP;
drawFunction(expoFn, CURVE_CENTER_X, CURVE_CENTER_Y, CURVE_SIDE_WIDTH);
drawCurveHorizontalScale();
drawCurveVerticalScale(CURVE_CENTER_X-CURVE_SIDE_WIDTH-15);
{
char textx[5];
char texty[5];
int x = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
sprintf(textx, "%d", calcRESXto100(x));
// TODO putsTelemetryChannelValue(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x);
if (ed->scale > 0) x = (x * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
}
else {
sprintf(textx, "%d", calcRESXto100(x));
}
x = limit(-1024, x, 1024);
int y = limit<int>(-1024, expoFn(x), 1024);
sprintf(texty, "%d", calcRESXto100(y));
x = divRoundClosest(x*CURVE_SIDE_WIDTH, RESX);
y = CURVE_CENTER_Y + getCurveYCoord(expoFn, x, CURVE_SIDE_WIDTH);
lcdDrawSolidFilledRect(CURVE_CENTER_X+x, CURVE_CENTER_Y-CURVE_SIDE_WIDTH, 2, 2*CURVE_SIDE_WIDTH+2, CURVE_CURSOR_COLOR);
lcdDrawSolidFilledRect(CURVE_CENTER_X-CURVE_SIDE_WIDTH-2, y-1, 2*CURVE_SIDE_WIDTH+2, 2, CURVE_CURSOR_COLOR);
lcdDrawBitmapPattern(CURVE_CENTER_X+x-4, y-4, LBM_CURVE_POINT, CURVE_CURSOR_COLOR);
lcdDrawBitmapPattern(CURVE_CENTER_X+x-4, y-4, LBM_CURVE_POINT_CENTER, TEXT_BGCOLOR);
int left = limit(CURVE_CENTER_X-CURVE_SIDE_WIDTH, CURVE_CENTER_X-CURVE_COORD_WIDTH/2+x, CURVE_CENTER_X+CURVE_SIDE_WIDTH-CURVE_COORD_WIDTH+2);
drawCurveCoord(left, CURVE_CENTER_Y+CURVE_SIDE_WIDTH+2, textx);
int top = limit(CURVE_CENTER_Y-CURVE_SIDE_WIDTH-1, -CURVE_COORD_HEIGHT/2+y, CURVE_CENTER_Y+CURVE_SIDE_WIDTH-CURVE_COORD_HEIGHT+1);
drawCurveCoord(CURVE_CENTER_X-CURVE_SIDE_WIDTH-37, top, texty);
}
for (int i=0; i<NUM_BODY_LINES+1; i++) {
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (i) {
case EXPO_FIELD_INPUT_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_INPUTNAME);
editName(EXPO_ONE_2ND_COLUMN, y, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr);
break;
case EXPO_FIELD_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXPONAME);
editName(EXPO_ONE_2ND_COLUMN, y, ed->name, sizeof(ed->name), event, attr);
break;
case EXPO_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|(menuHorizontalPosition==0?attr:0));
if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN+60, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0));
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
}
else if (attr) {
menuHorizontalPosition = 0;
}
break;
case EXPO_FIELD_WEIGHT:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WEIGHT);
ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event);
break;
case EXPO_FIELD_OFFSET:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_OFFSET));
ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event);
break;
#if defined(CURVES)
case EXPO_FIELD_CURVE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURVE);
editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case EXPO_FIELD_FLIGHT_MODES:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FLMODE);
ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
break;
#endif
case EXPO_FIELD_SWITCH:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SWITCH);
ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event);
break;
case EXPO_FIELD_SIDE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SIDE);
ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_VSIDE, 4-ed->mode, 1, 3, attr, event);
break;
case EXPO_FIELD_TRIM:
uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
int8_t carryTrim = -ed->carryTrim;
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRIM);
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, menuHorizontalPosition==0 ? attr : 0);
if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
break;
}
y += FH;
}
return true;
}
enum MixFields {
MIX_FIELD_NAME,
MIX_FIELD_SOURCE,
MIX_FIELD_WEIGHT,
MIX_FIELD_OFFSET,
MIX_FIELD_TRIM,
CASE_CURVES(MIX_FIELD_CURVE)
CASE_FLIGHT_MODES(MIX_FIELD_FLIGHT_PHASE)
MIX_FIELD_SWITCH,
// MIX_FIELD_WARNING,
MIX_FIELD_MLTPX,
MIX_FIELD_DELAY_UP,
MIX_FIELD_DELAY_DOWN,
MIX_FIELD_SLOW_UP,
MIX_FIELD_SLOW_DOWN,
MIX_FIELD_COUNT
};
void gvarWeightItem(coord_t x, coord_t y, MixData *md, uint8_t attr, evt_t event)
{
u_int8int16_t weight;
MD_WEIGHT_TO_UNION(md, weight);
weight.word = GVAR_MENU_ITEM(x, y, weight.word, GV_RANGELARGE_WEIGHT_NEG, GV_RANGELARGE_WEIGHT, attr, 0, event);
MD_UNION_TO_WEIGHT(weight, md);
}
#if 0
#define GAUGE_WIDTH 33
#define GAUGE_HEIGHT 6
void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
{
int offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
int weight = abs(GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode));
int barMin = offset - weight;
int barMax = offset + weight;
if (y > 15) {
lcdDrawNumber(x-((barMin >= 0) ? 2 : 3), y-6, barMin, TINSIZE|LEFT);
lcdDrawNumber(x+GAUGE_WIDTH+1, y-6, barMax, TINSIZE);
}
if (barMin < -101)
barMin = -101;
if (barMax > 101)
barMax = 101;
lcdDrawHorizontalLine(x-2, y, GAUGE_WIDTH+2, DOTTED);
lcdDrawHorizontalLine(x-2, y+GAUGE_HEIGHT, GAUGE_WIDTH+2, DOTTED);
lcdDrawSolidVerticalLine(x-2, y+1, GAUGE_HEIGHT-1);
lcdDrawSolidVerticalLine(x+GAUGE_WIDTH-1, y+1, GAUGE_HEIGHT-1);
if (barMin <= barMax) {
int8_t right = (barMax * GAUGE_WIDTH) / 200;
int8_t left = ((barMin * GAUGE_WIDTH) / 200)-1;
lcdDrawSolidFilledRect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3);
}
lcdDrawSolidVerticalLine(x+GAUGE_WIDTH/2-1, y, GAUGE_HEIGHT+1);
if (barMin == -101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+i, y+4-i);
lcdDrawPoint(x+3+i, y+4-i);
}
}
if (barMax == 101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+GAUGE_WIDTH-8+i, y+4-i);
lcdDrawPoint(x+GAUGE_WIDTH-5+i, y+4-i);
}
}
}
#undef GAUGE_WIDTH
#undef GAUGE_HEIGHT
#endif
bool menuModelMixOne(evt_t event)
{
MixData *md2 = mixAddress(s_currIdx) ;
SUBMENU(s_currCh ? STR_INSERTMIX : STR_EDITMIX, MIX_FIELD_COUNT, 0, { 0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/ });
putsChn(MENU_TITLE_NEXT_POS, MENU_TITLE_TOP+1, md2->destCh+1, TEXT_COLOR);
// The separation line between 2 columns
lcdDrawSolidVerticalLine(MENU_COLUMN2_X-20, DEFAULT_SCROLLBAR_Y, DEFAULT_SCROLLBAR_H+5, TEXT_COLOR);
int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode;
for (int k=0; k<2*NUM_BODY_LINES; k++) {
coord_t y;
if (k >= NUM_BODY_LINES) {
y = MENU_CONTENT_TOP + (k-NUM_BODY_LINES)*FH + 2;
}
else {
y = MENU_CONTENT_TOP + k*FH + 2;
}
int8_t i = k;
LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case MIX_FIELD_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MIXNAME);
editName(MIXES_2ND_COLUMN, y, md2->name, sizeof(md2->name), event, attr);
break;
case MIX_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break;
case MIX_FIELD_WEIGHT:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WEIGHT);
gvarWeightItem(MIXES_2ND_COLUMN, y, md2, attr|LEFT, event);
break;
case MIX_FIELD_OFFSET:
{
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_OFFSET));
u_int8int16_t offset;
MD_OFFSET_TO_UNION(md2, offset);
offset.word = GVAR_MENU_ITEM(MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event);
MD_UNION_TO_OFFSET(offset, md2);
#if 0
drawOffsetBar(x+MIXES_2ND_COLUMN+22, y, md2);
#endif
break;
}
case MIX_FIELD_TRIM:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRIM);
drawCheckBox(MIXES_2ND_COLUMN, y, !md2->carryTrim, attr);
if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1);
break;
#if defined(CURVES)
case MIX_FIELD_CURVE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURVE);
editCurveRef(MIXES_2ND_COLUMN, y, md2->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_PHASE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FLMODE);
md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break;
#endif
case MIX_FIELD_SWITCH:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SWITCH);
md2->swtch = switchMenuItem(MIXES_2ND_COLUMN, y, md2->swtch, attr, event);
break;
case MIX_FIELD_MLTPX:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTPX);
md2->mltpx = selectMenuItem(MIXES_2ND_COLUMN, y, STR_VMLTPX, md2->mltpx, 0, 2, attr, event);
break;
case MIX_FIELD_DELAY_UP:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_DELAYUP);
md2->delayUp = editDelay(MENU_COLUMN2_X, y, event, attr, md2->delayUp);
break;
case MIX_FIELD_DELAY_DOWN:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_DELAYDOWN);
md2->delayDown = editDelay(MENU_COLUMN2_X, y, event, attr, md2->delayDown);
break;
case MIX_FIELD_SLOW_UP:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_SLOWUP);
md2->speedUp = editDelay(MENU_COLUMN2_X, y, event, attr, md2->speedUp);
break;
case MIX_FIELD_SLOW_DOWN:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_SLOWDOWN);
md2->speedDown = editDelay(MENU_COLUMN2_X, y, event, attr, md2->speedDown);
break;
}
}
return true;
}
static uint8_t s_copySrcIdx;
static uint8_t s_copySrcCh;
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define EXPO_LINE_WEIGHT_POS 92
#define EXPO_LINE_SRC_POS 115
#define EXPO_LINE_CURVE_POS 162
#define EXPO_LINE_SWITCH_POS 210
#define EXPO_LINE_SIDE_POS 250
#define EXPO_LINE_FM_POS 270
#define EXPO_LINE_NAME_POS 380
#define EXPO_LINE_SELECT_POS 50
#define EXPO_LINE_SELECT_WIDTH (LCD_W-EXPO_LINE_SELECT_POS-5)
#define MIX_LINE_WEIGHT_POS 92
#define MIX_LINE_SRC_POS 115
#define MIX_LINE_CURVE_POS 162
#define MIX_LINE_SWITCH_POS 210
#define MIX_LINE_DELAY_POS 255
#define MIX_LINE_FM_POS 270
#define MIX_LINE_NAME_POS 380
#define MIX_LINE_SELECT_POS 50
#define MIX_LINE_SELECT_WIDTH (LCD_W-EXPO_LINE_SELECT_POS-5)
void lineSurround(bool expo, coord_t y, LcdFlags flags=CURVE_AXIS_COLOR)
{
lcdDrawRect(expo ? EXPO_LINE_SELECT_POS : MIX_LINE_SELECT_POS, y-INVERT_VERT_MARGIN, expo ? EXPO_LINE_SELECT_WIDTH : MIX_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, (s_copyMode == COPY_MODE ? SOLID : DOTTED), flags);
}
void onExpoMixMenu(const char *result)
{
bool expo = (menuHandlers[menuLevel] == menuModelExposAll);
uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1);
if (result == STR_EDIT) {
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachExpoMixCountLimit(expo)) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteExpoMix(expo, s_currIdx);
}
}
void displayHeaderChannelName(uint8_t ch)
{
uint8_t len = zlen(g_model.limitData[ch-1].name, sizeof(g_model.limitData[ch-1].name));
if (len) {
lcdDrawSizedText(COLUMN_HEADER_X, MENU_FOOTER_TOP, g_model.limitData[ch-1].name, len, HEADER_COLOR|ZCHAR);
}
}
void displayMixInfos(coord_t y, MixData *md)
{
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve);
if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch);
}
}
void displayMixLine(coord_t y, MixData *md)
{
if (md->name[0])
lcdDrawSizedText(EXPO_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR);
displayMixInfos(y, md);
displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes, 0);
}
void displayExpoInfos(coord_t y, ExpoData *ed)
{
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve);
if (ed->swtch) {
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch);
}
if (ed->mode != 3) {
lcdDrawText(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? "\176" : "\177");
}
}
void displayExpoLine(coord_t y, ExpoData *ed)
{
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw);
displayExpoInfos(y, ed);
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes, 0);
if (ed->name[0]) {
lcdDrawSizedText(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR);
}
}
bool menuModelExpoMix(uint8_t expo, evt_t event)
{
int sub = menuVerticalPosition;
if (s_editMode > 0)
s_editMode = 0;
uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1);
int linesCount = getLinesCount(expo);
SIMPLE_MENU(expo ? STR_MENUINPUTS : STR_MIXER, menuTabModel, expo ? e_InputsAll : e_MixAll, linesCount, DEFAULT_SCROLLBAR_X);
switch (event)
{
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteExpoMix(expo, s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteExpoMix(expo, s_currIdx);
}
else {
do {
swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachExpoMixCountLimit(expo)) break;
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onExpoMixMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachExpoMixCountLimit(expo)) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = ((event==EVT_ROTARY_LEFT || key==KEY_UP) ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachExpoMixCountLimit(expo)) break;
copyExpoMix(expo, s_currIdx);
if (event==EVT_ROTARY_RIGHT || key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteExpoMix(expo, s_currIdx);
if (event==EVT_ROTARY_LEFT || key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapExpoMix(expo, s_currIdx, event==EVT_ROTARY_LEFT || key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
char str[6];
sprintf(str, "%d/%d", getExpoMixCount(expo), expo ? MAX_EXPOS : MAX_MIXERS);
lcdDrawText(MENU_TITLE_NEXT_POS, MENU_TITLE_TOP+2, str, HEADER_COLOR);
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) {
void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer;
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
if (expo) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch);
}
else {
putsChn(MENUS_MARGIN_LEFT, y, ch, 0); // show CHx
}
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineSurround(expo, y);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
LcdFlags attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
if (expo) {
GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0);
displayExpoLine(y, ed);
}
else {
if (attr) {
displayHeaderChannelName(ch);
}
if (mixCnt > 0) lcdDrawTextAtIndex(6, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event);
displayMixLine(y, md);
char cs[] = " ";
if (md->speedDown || md->speedUp)
cs[0] = 'S';
if (md->delayUp || md->delayDown)
cs[0] = (cs[0] =='S' ? '*' : 'D');
lcdDrawText(MIX_LINE_DELAY_POS, y, cs);
}
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lineSurround(expo, y);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lineSurround(expo, y, ALARM_COLOR);
}
}
}
cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++;
} while (expo ? (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch));
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineSurround(expo, y);
cur++; y+=FH;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
if (expo) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch, attr);
}
else {
putsChn(MENUS_MARGIN_LEFT, y, ch, attr); // show CHx
if (attr) {
displayHeaderChannelName(ch);
}
}
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lineSurround(expo, y);
}
}
cur++; y+=FH;
}
}
if (sub >= linesCount-1) menuVerticalPosition = linesCount-1;
return true;
}
bool menuModelExposAll(evt_t event)
{
return menuModelExpoMix(1, event);
}
bool menuModelMixAll(evt_t event)
{
return menuModelExpoMix(0, event);
}

View file

@ -0,0 +1,571 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include <stdio.h>
int getMixesLinesCount()
{
int lastch = -1;
uint8_t count = NUM_CHNOUT;
for (int i=0; i<MAX_MIXERS; i++) {
bool valid = mixAddress(i)->srcRaw;
if (!valid)
break;
int ch = mixAddress(i)->destCh;
if (ch == lastch) {
count++;
}
else {
lastch = ch;
}
}
return count;
}
uint8_t getMixesCount()
{
uint8_t count = 0;
uint8_t ch ;
for (int i=MAX_MIXERS-1; i>=0; i--) {
ch = mixAddress(i)->srcRaw;
if (ch != 0) {
count++;
}
}
return count;
}
bool reachMixesLimit()
{
if (getMixesCount() >= MAX_MIXERS) {
POPUP_WARNING(STR_NOFREEMIXER);
return true;
}
return false;
}
void deleteMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void insertMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(mix, sizeof(MixData));
mix->destCh = s_currCh-1;
mix->srcRaw = s_currCh;
if (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
while (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw += 1;
}
}
mix->weight = 100;
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
bool swapMixes(uint8_t & idx, uint8_t up)
{
MixData * x, * y;
int8_t tgt_idx = (up ? idx-1 : idx+1);
x = mixAddress(idx);
if (tgt_idx < 0) {
if (x->destCh == 0)
return false;
x->destCh--;
return true;
}
if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1)
return false;
x->destCh++;
return true;
}
y = mixAddress(tgt_idx);
uint8_t destCh = x->destCh;
if(!y->srcRaw || destCh != y->destCh) {
if (up) {
if (destCh>0) x->destCh--;
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) x->destCh++;
else return false;
}
return true;
}
pauseMixerCalculations();
memswap(x, y, sizeof(MixData));
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum MixFields {
MIX_FIELD_NAME,
MIX_FIELD_SOURCE,
MIX_FIELD_WEIGHT,
MIX_FIELD_OFFSET,
MIX_FIELD_TRIM,
CASE_CURVES(MIX_FIELD_CURVE)
CASE_FLIGHT_MODES(MIX_FIELD_FLIGHT_PHASE)
MIX_FIELD_SWITCH,
// MIX_FIELD_WARNING,
MIX_FIELD_MLTPX,
MIX_FIELD_DELAY_UP,
MIX_FIELD_DELAY_DOWN,
MIX_FIELD_SLOW_UP,
MIX_FIELD_SLOW_DOWN,
MIX_FIELD_COUNT
};
void gvarWeightItem(coord_t x, coord_t y, MixData *md, uint8_t attr, evt_t event)
{
u_int8int16_t weight;
MD_WEIGHT_TO_UNION(md, weight);
weight.word = GVAR_MENU_ITEM(x, y, weight.word, GV_RANGELARGE_WEIGHT_NEG, GV_RANGELARGE_WEIGHT, attr, 0, event);
MD_UNION_TO_WEIGHT(weight, md);
}
bool menuModelMixOne(evt_t event)
{
MixData *md2 = mixAddress(s_currIdx) ;
SUBMENU(STR_MIXER, MIX_FIELD_COUNT, 0, { 0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/ });
putsChn(MENU_TITLE_NEXT_POS, MENU_TITLE_TOP+1, md2->destCh+1, TEXT_COLOR);
// The separation line between 2 columns
lcdDrawSolidVerticalLine(MENU_COLUMN2_X-20, DEFAULT_SCROLLBAR_Y, DEFAULT_SCROLLBAR_H+5, TEXT_COLOR);
int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode;
for (int k=0; k<2*NUM_BODY_LINES; k++) {
coord_t y;
if (k >= NUM_BODY_LINES) {
y = MENU_CONTENT_TOP + (k-NUM_BODY_LINES)*FH + 2;
}
else {
y = MENU_CONTENT_TOP + k*FH + 2;
}
int8_t i = k;
LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case MIX_FIELD_NAME:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MIXNAME);
editName(MIXES_2ND_COLUMN, y, md2->name, sizeof(md2->name), event, attr);
break;
case MIX_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break;
case MIX_FIELD_WEIGHT:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WEIGHT);
gvarWeightItem(MIXES_2ND_COLUMN, y, md2, attr|LEFT, event);
break;
case MIX_FIELD_OFFSET:
{
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_OFFSET));
u_int8int16_t offset;
MD_OFFSET_TO_UNION(md2, offset);
offset.word = GVAR_MENU_ITEM(MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event);
MD_UNION_TO_OFFSET(offset, md2);
#if 0
drawOffsetBar(x+MIXES_2ND_COLUMN+22, y, md2);
#endif
break;
}
case MIX_FIELD_TRIM:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRIM);
drawCheckBox(MIXES_2ND_COLUMN, y, !md2->carryTrim, attr);
if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1);
break;
#if defined(CURVES)
case MIX_FIELD_CURVE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURVE);
editCurveRef(MIXES_2ND_COLUMN, y, md2->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_PHASE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FLMODE);
md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break;
#endif
case MIX_FIELD_SWITCH:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SWITCH);
md2->swtch = switchMenuItem(MIXES_2ND_COLUMN, y, md2->swtch, attr, event);
break;
case MIX_FIELD_MLTPX:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTPX);
md2->mltpx = selectMenuItem(MIXES_2ND_COLUMN, y, STR_VMLTPX, md2->mltpx, 0, 2, attr, event);
break;
case MIX_FIELD_DELAY_UP:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_DELAYUP);
md2->delayUp = editDelay(MENU_COLUMN2_X, y, event, attr, md2->delayUp);
break;
case MIX_FIELD_DELAY_DOWN:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_DELAYDOWN);
md2->delayDown = editDelay(MENU_COLUMN2_X, y, event, attr, md2->delayDown);
break;
case MIX_FIELD_SLOW_UP:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_SLOWUP);
md2->speedUp = editDelay(MENU_COLUMN2_X, y, event, attr, md2->speedUp);
break;
case MIX_FIELD_SLOW_DOWN:
lcdDrawText(MENU_COLUMN2_X+MENUS_MARGIN_LEFT, y, STR_SLOWDOWN);
md2->speedDown = editDelay(MENU_COLUMN2_X, y, event, attr, md2->speedDown);
break;
}
}
return true;
}
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define MIX_LINE_WEIGHT_POS 92
#define MIX_LINE_SRC_POS 115
#define MIX_LINE_CURVE_POS 162
#define MIX_LINE_SWITCH_POS 210
#define MIX_LINE_DELAY_POS 255
#define MIX_LINE_FM_POS 270
#define MIX_LINE_NAME_POS 384
#define MIX_LINE_SELECT_POS 50
#define MIX_LINE_SELECT_POS 50
#define MIX_LINE_SELECT_WIDTH (LCD_W-MIX_LINE_SELECT_POS-15)
void lineMixSurround(coord_t y, LcdFlags flags=CURVE_AXIS_COLOR)
{
lcdDrawRect(MIX_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, MIX_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
}
void onMixesMenu(const char * result)
{
uint8_t chn = mixAddress(s_currIdx)->destCh + 1;
if (result == STR_EDIT) {
pushMenu(menuModelMixOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachMixesLimit()) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteMix(s_currIdx);
}
}
void displayHeaderChannelName(uint8_t ch)
{
uint8_t len = zlen(g_model.limitData[ch-1].name, sizeof(g_model.limitData[ch-1].name));
if (len) {
lcdDrawSizedText(COLUMN_HEADER_X, MENU_FOOTER_TOP, g_model.limitData[ch-1].name, len, HEADER_COLOR|ZCHAR);
}
}
void displayMixInfos(coord_t y, MixData *md)
{
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve);
if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch);
}
}
void displayMixLine(coord_t y, MixData *md)
{
if (md->name[0]) {
lcdDrawSizedText(MIX_LINE_NAME_POS, y+2, md->name, sizeof(md->name), ZCHAR | SMLSIZE);
}
displayMixInfos(y, md);
displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes, 0);
}
bool menuModelMixAll(evt_t event)
{
int sub = menuVerticalPosition;
if (s_editMode > 0) {
s_editMode = 0;
}
uint8_t chn = mixAddress(s_currIdx)->destCh + 1;
int linesCount = getMixesLinesCount();
SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, linesCount, DEFAULT_SCROLLBAR_X);
switch (event) {
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteMix(s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteMix(s_currIdx);
}
else {
do {
swapMixes(s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(menuModelMixOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachMixesLimit()) break;
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onMixesMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachMixesLimit()) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = ((event==EVT_ROTARY_LEFT || key==KEY_UP) ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachMixesLimit()) break;
copyMix(s_currIdx);
if (event==EVT_ROTARY_RIGHT || key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteMix(s_currIdx);
if (event==EVT_ROTARY_LEFT || key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapMixes(s_currIdx, event==EVT_ROTARY_LEFT || key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
char str[6];
sprintf(str, "%d/%d", getMixesCount(), MAX_MIXERS);
lcdDrawText(MENU_TITLE_NEXT_POS, MENU_TITLE_TOP+2, str, HEADER_COLOR);
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) {
MixData * md;
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsChn(MENUS_MARGIN_LEFT, y, ch, 0); // show CHx
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineMixSurround(y);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
LcdFlags attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
if (attr) {
displayHeaderChannelName(ch);
}
if (mixCnt > 0) lcdDrawTextAtIndex(6, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event);
displayMixLine(y, md);
char cs[] = " ";
if (md->speedDown || md->speedUp)
cs[0] = 'S';
if (md->delayUp || md->delayDown)
cs[0] = (cs[0] =='S' ? '*' : 'D');
lcdDrawText(MIX_LINE_DELAY_POS, y, cs);
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lineMixSurround(y);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lineMixSurround(y, ALARM_COLOR);
}
}
}
cur++; y+=FH; mixCnt++; i++; md++;
} while (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch);
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lineMixSurround(y);
cur++; y+=FH;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsChn(MENUS_MARGIN_LEFT, y, ch, attr); // show CHx
if (attr) {
displayHeaderChannelName(ch);
}
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lineMixSurround(y);
}
}
cur++; y+=FH;
}
}
if (sub >= linesCount-1) menuVerticalPosition = linesCount-1;
return true;
}

View file

@ -50,7 +50,7 @@ enum menuModelSetupItems {
ITEM_MODEL_DISPLAY_TRIMS, ITEM_MODEL_DISPLAY_TRIMS,
ITEM_MODEL_TRIM_INC, ITEM_MODEL_TRIM_INC,
ITEM_MODEL_THROTTLE_LABEL, ITEM_MODEL_THROTTLE_LABEL,
// ITEM_MODEL_THROTTLE_REVERSED, ITEM_MODEL_THROTTLE_REVERSED,
ITEM_MODEL_THROTTLE_TRACE, ITEM_MODEL_THROTTLE_TRACE,
ITEM_MODEL_THROTTLE_TRIM, ITEM_MODEL_THROTTLE_TRIM,
ITEM_MODEL_PREFLIGHT_LABEL, ITEM_MODEL_PREFLIGHT_LABEL,
@ -60,6 +60,11 @@ enum menuModelSetupItems {
ITEM_MODEL_POT_WARNING, ITEM_MODEL_POT_WARNING,
ITEM_MODEL_BEEP_CENTER, ITEM_MODEL_BEEP_CENTER,
ITEM_MODEL_USE_GLOBAL_FUNCTIONS, ITEM_MODEL_USE_GLOBAL_FUNCTIONS,
ITEM_MODEL_INTERNAL_MODULE_LABEL,
ITEM_MODEL_INTERNAL_MODULE_MODE,
ITEM_MODEL_INTERNAL_MODULE_CHANNELS,
ITEM_MODEL_INTERNAL_MODULE_BIND,
ITEM_MODEL_INTERNAL_MODULE_FAILSAFE,
ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_MODE, ITEM_MODEL_EXTERNAL_MODULE_MODE,
ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_EXTERNAL_MODULE_CHANNELS,
@ -134,7 +139,7 @@ void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, evt_t event)
} }
} }
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : EXTERNAL_MODULE) #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
int getSwitchWarningsCount() int getSwitchWarningsCount()
{ {
@ -147,29 +152,48 @@ int getSwitchWarningsCount()
return count; return count;
} }
#define INTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(INTERNAL_MODULE) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols
#define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? HIDDEN_ROW : (uint8_t)(x))
#define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW)
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE)) ? (uint8_t)0 : (uint8_t)1)
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS()))
#define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
#define TIMER_ROWS NAVIGATION_LINE_BY_LINE|1, 0, CASE_PERSISTENT_TIMERS(0) 0, 0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS
#elif TIMERS == 2
#define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS
#elif TIMERS == 3
#define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS, TIMER_ROWS
#endif
#define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1))
#define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
bool menuModelSetup(evt_t event) bool menuModelSetup(evt_t event)
{ {
horzpos_t l_posHorz = menuHorizontalPosition; horzpos_t l_posHorz = menuHorizontalPosition;
#define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS() : TRAINER_CHANNELS_ROWS())
#define FAILSAFE_ROWS(x) ((g_model.moduleData[x].rfProtocol==RF_PROTO_X16 || g_model.moduleData[x].rfProtocol==RF_PROTO_LR12) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
#define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
#define TIMER_ROWS NAVIGATION_LINE_BY_LINE|1, 0, CASE_PERSISTENT_TIMERS(0) 0, 0
#if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS
#elif TIMERS == 2
#define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS
#elif TIMERS == 3
#define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS, TIMER_ROWS
#endif
bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0); bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0);
MENU(STR_MENUSETUP, menuTabModel, e_ModelSetup, ITEM_MODEL_SETUP_MAX, DEFAULT_SCROLLBAR_X, { 0, 0, TIMERS_ROWS, 0, 1, 0, 0, LABEL(Throttle), 0, 0, LABEL(PreflightCheck), 0, 0, uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2) }); MENU(STR_MENUSETUP, menuTabModel, e_ModelSetup, ITEM_MODEL_SETUP_MAX, DEFAULT_SCROLLBAR_X,
{ 0, 0, TIMERS_ROWS, 0, 1, 0, 0,
LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS,
IF_INTERNAL_MODULE_ON(IS_MODULE_XJT(INTERNAL_MODULE) ? (HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1) : (IS_MODULE_PPM(INTERNAL_MODULE) ? (uint8_t)1 : HIDDEN_ROW)),
IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW),
LABEL(ExternalModule),
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0,
EXTERNAL_MODULE_CHANNELS_ROWS,
(IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)),
LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2) });
#if (defined(DSM2) || defined(PXX)) #if (defined(DSM2) || defined(PXX))
if (menuEvent) { if (menuEvent) {
@ -227,7 +251,7 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_TIMER1_MINUTE_BEEP: case ITEM_MODEL_TIMER1_MINUTE_BEEP:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP);
g_model.timers[0].minuteBeep = onoffMenuItem(g_model.timers[0].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.timers[0].minuteBeep = editCheckBox(g_model.timers[0].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP:
@ -252,7 +276,7 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_TIMER2_MINUTE_BEEP: case ITEM_MODEL_TIMER2_MINUTE_BEEP:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP);
g_model.timers[1].minuteBeep = onoffMenuItem(g_model.timers[1].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.timers[1].minuteBeep = editCheckBox(g_model.timers[1].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP:
@ -278,7 +302,7 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_TIMER3_MINUTE_BEEP: case ITEM_MODEL_TIMER3_MINUTE_BEEP:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MINUTEBEEP);
g_model.timers[2].minuteBeep = onoffMenuItem(g_model.timers[2].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.timers[2].minuteBeep = editCheckBox(g_model.timers[2].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP:
@ -294,12 +318,12 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_EXTENDED_LIMITS: case ITEM_MODEL_EXTENDED_LIMITS:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ELIMITS); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ELIMITS);
g_model.extendedLimits = onoffMenuItem(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.extendedLimits = editCheckBox(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_EXTENDED_TRIMS: case ITEM_MODEL_EXTENDED_TRIMS:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ETRIMS); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ETRIMS);
g_model.extendedTrims = onoffMenuItem(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, menuHorizontalPosition<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0); g_model.extendedTrims = editCheckBox(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, menuHorizontalPosition<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0);
lcdDrawText(MODEL_SETUP_2ND_COLUMN+18, y, STR_RESET_BTN, menuHorizontalPosition>0 && !NO_HIGHLIGHT() ? attr : 0); lcdDrawText(MODEL_SETUP_2ND_COLUMN+18, y, STR_RESET_BTN, menuHorizontalPosition>0 && !NO_HIGHLIGHT() ? attr : 0);
if (attr && menuHorizontalPosition>0) { if (attr && menuHorizontalPosition>0) {
s_editMode = 0; s_editMode = 0;
@ -328,11 +352,10 @@ bool menuModelSetup(evt_t event)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_THROTTLE_LABEL); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_THROTTLE_LABEL);
break; break;
#if 0
case ITEM_MODEL_THROTTLE_REVERSED: case ITEM_MODEL_THROTTLE_REVERSED:
ON_OFF_MENU_ITEM(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ; lcdDrawText(MENUS_MARGIN_LEFT, y, STR_THROTTLEREVERSE);
g_model.throttleReversed = editCheckBox(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
#endif
case ITEM_MODEL_THROTTLE_TRACE: case ITEM_MODEL_THROTTLE_TRACE:
{ {
@ -349,7 +372,7 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_THROTTLE_TRIM: case ITEM_MODEL_THROTTLE_TRIM:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRIM); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRIM);
g_model.thrTrim = onoffMenuItem(g_model.thrTrim, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.thrTrim = editCheckBox(g_model.thrTrim, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_PREFLIGHT_LABEL: case ITEM_MODEL_PREFLIGHT_LABEL:
@ -358,12 +381,12 @@ bool menuModelSetup(evt_t event)
case ITEM_MODEL_CHECKLIST_DISPLAY: case ITEM_MODEL_CHECKLIST_DISPLAY:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CHECKLIST); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CHECKLIST);
g_model.displayChecklist = onoffMenuItem(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.displayChecklist = editCheckBox(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_THROTTLE_WARNING: case ITEM_MODEL_THROTTLE_WARNING:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_THROTTLEWARNING); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_THROTTLEWARNING);
g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, attr, event); g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, attr, event);
break; break;
case ITEM_MODEL_SWITCHES_WARNING: case ITEM_MODEL_SWITCHES_WARNING:
@ -379,7 +402,7 @@ bool menuModelSetup(evt_t event)
} }
if (attr && menuHorizontalPosition < 0) { if (attr && menuHorizontalPosition < 0) {
lcdDrawSolidFilledRect(MODEL_SETUP_2ND_COLUMN-INVERT_HORZ_MARGIN, y-INVERT_VERT_MARGIN, NUM_SWITCHES*18+INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR); lcdDrawSolidFilledRect(MODEL_SETUP_2ND_COLUMN-INVERT_HORZ_MARGIN, y-INVERT_VERT_MARGIN+1, (NUM_SWITCHES-1)*25+INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR);
} }
unsigned int newStates = 0; unsigned int newStates = 0;
@ -395,16 +418,12 @@ bool menuModelSetup(evt_t event)
color |= INVERS; color |= INVERS;
} }
char s[3]; char s[3];
s[0] = 'A' + i + (i >= 3 ? 1 : 0 /* skip SD which is a POT*/); s[0] = 'A' + i;
int max; int max;
if (state == 0) { if (state == 0) {
s[1] = 'x'; s[1] = 'x';
max = 2; max = 2;
} }
else if (i == 2) {
s[1] = '0' + state;
max = 6;
}
else if (IS_3POS(i)) { else if (IS_3POS(i)) {
s[1] = "\300-\301"[state-1]; s[1] = "\300-\301"[state-1];
max = 3; max = 3;
@ -414,7 +433,7 @@ bool menuModelSetup(evt_t event)
max = 2; max = 2;
} }
s[2] = '\0'; s[2] = '\0';
lcdDrawText(MODEL_SETUP_2ND_COLUMN+i*18, y, s, color|(menuHorizontalPosition==current ? attr : 0)); lcdDrawText(MODEL_SETUP_2ND_COLUMN+i*25, y, s, color|(menuHorizontalPosition==current ? attr : 0));
if (attr && menuHorizontalPosition==current) CHECK_INCDEC_MODELVAR_ZERO(event, state, max); if (attr && menuHorizontalPosition==current) CHECK_INCDEC_MODELVAR_ZERO(event, state, max);
newStates |= (state << (3*i)); newStates |= (state << (3*i));
++current; ++current;
@ -488,11 +507,28 @@ bool menuModelSetup(evt_t event)
break; break;
case ITEM_MODEL_USE_GLOBAL_FUNCTIONS: case ITEM_MODEL_USE_GLOBAL_FUNCTIONS:
lcdDrawText(MENUS_MARGIN_LEFT, y, "Use Global Funcs"); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_USE_GLOBAL_FUNCS);
drawCheckBox(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr); drawCheckBox(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr);
if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1); if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1);
break; break;
case ITEM_MODEL_INTERNAL_MODULE_LABEL:
lcdDrawText(MENUS_MARGIN_LEFT, y, TR_INTERNALRF);
break;
case ITEM_MODEL_INTERNAL_MODULE_MODE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[0].rfProtocol, attr);
if (attr) {
g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, RF_PROTO_OFF, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[0].type = MODULE_TYPE_XJT;
g_model.moduleData[0].channelsStart = 0;
g_model.moduleData[0].channelsCount = 0;
}
}
break;
case ITEM_MODEL_TRAINER_MODE: case ITEM_MODEL_TRAINER_MODE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODE);
g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, TRAINER_MODE_MASTER, TRAINER_MODE_SLAVE, attr, event); g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, TRAINER_MODE_MASTER, TRAINER_MODE_SLAVE, attr, event);
@ -539,6 +575,7 @@ bool menuModelSetup(evt_t event)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRAINER); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TRAINER);
break; break;
case ITEM_MODEL_INTERNAL_MODULE_CHANNELS:
case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS: case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS:
case ITEM_MODEL_TRAINER_CHANNELS: case ITEM_MODEL_TRAINER_CHANNELS:
{ {
@ -567,6 +604,7 @@ bool menuModelSetup(evt_t event)
break; break;
} }
case ITEM_MODEL_INTERNAL_MODULE_BIND:
case ITEM_MODEL_EXTERNAL_MODULE_BIND: case ITEM_MODEL_EXTERNAL_MODULE_BIND:
case ITEM_MODEL_TRAINER_SETTINGS: case ITEM_MODEL_TRAINER_SETTINGS:
{ {
@ -624,6 +662,7 @@ bool menuModelSetup(evt_t event)
break; break;
} }
case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE:
case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE: case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE:
{ {
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);

View file

@ -207,19 +207,19 @@ bool menuModelSensor(evt_t event)
// lcdDrawNumber(MENUS_MARGIN_LEFT+getTextWidth(TR_MENUSENSOR)+5, MENU_FOOTER_TOP, s_currIdx+1, HEADER_COLOR|LEFT); // lcdDrawNumber(MENUS_MARGIN_LEFT+getTextWidth(TR_MENUSENSOR)+5, MENU_FOOTER_TOP, s_currIdx+1, HEADER_COLOR|LEFT);
// putsTelemetryChannelValue(SENSOR_2ND_COLUMN, MENU_FOOTER_TOP, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), HEADER_COLOR|LEFT); // putsTelemetryChannelValue(SENSOR_2ND_COLUMN, MENU_FOOTER_TOP, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), HEADER_COLOR|LEFT);
int sub = menuVerticalPosition;
for (unsigned int i=0; i<NUM_BODY_LINES+1; i++) { for (unsigned int i=0; i<NUM_BODY_LINES+1; i++) {
coord_t y = MENU_CONTENT_TOP + i*FH; coord_t y = MENU_CONTENT_TOP + i*FH;
int k = i + menuVerticalOffset; int k = i + menuVerticalOffset;
for (int j=0; j<=k; j++) { for (int j=0; j<k; j++) {
if (mstate_tab[j] == HIDDEN_ROW) { if (mstate_tab[j+1] == HIDDEN_ROW) {
k++; if (++k >= (int)DIM(mstate_tab)) {
return true;
}
} }
} }
LcdFlags attr = (sub==k ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); LcdFlags attr = (menuVerticalPosition==k ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (k) { switch (k) {
@ -409,27 +409,27 @@ bool menuModelSensor(evt_t event)
case SENSOR_FIELD_AUTOOFFSET: case SENSOR_FIELD_AUTOOFFSET:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_AUTOOFFSET); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_AUTOOFFSET);
sensor->autoOffset = onoffMenuItem(sensor->autoOffset, SENSOR_2ND_COLUMN, y, attr, event); sensor->autoOffset = editCheckBox(sensor->autoOffset, SENSOR_2ND_COLUMN, y, attr, event);
break; break;
case SENSOR_FIELD_ONLYPOSITIVE: case SENSOR_FIELD_ONLYPOSITIVE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ONLYPOSITIVE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ONLYPOSITIVE);
sensor->onlyPositive = onoffMenuItem(sensor->onlyPositive, SENSOR_2ND_COLUMN, y, attr, event); sensor->onlyPositive = editCheckBox(sensor->onlyPositive, SENSOR_2ND_COLUMN, y, attr, event);
break; break;
case SENSOR_FIELD_FILTER: case SENSOR_FIELD_FILTER:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FILTER); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FILTER);
sensor->filter = onoffMenuItem(sensor->filter, SENSOR_2ND_COLUMN, y, attr, event); sensor->filter = editCheckBox(sensor->filter, SENSOR_2ND_COLUMN, y, attr, event);
break; break;
case SENSOR_FIELD_PERSISTENT: case SENSOR_FIELD_PERSISTENT:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_PERSISTENT)); lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_PERSISTENT));
sensor->persistent = onoffMenuItem(sensor->persistent, SENSOR_2ND_COLUMN, y, attr, event); sensor->persistent = editCheckBox(sensor->persistent, SENSOR_2ND_COLUMN, y, attr, event);
break; break;
case SENSOR_FIELD_LOGS: case SENSOR_FIELD_LOGS:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_LOGS); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_LOGS);
sensor->logs = onoffMenuItem(sensor->logs, SENSOR_2ND_COLUMN, y, attr, event); sensor->logs = editCheckBox(sensor->logs, SENSOR_2ND_COLUMN, y, attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
closeLogs(); closeLogs();
} }
@ -478,8 +478,7 @@ void onSensorMenu(const char *result)
#if defined(LUA) #if defined(LUA)
void onTelemetryScriptFileSelectionMenu(const char *result) void onTelemetryScriptFileSelectionMenu(const char *result)
{ {
int sub = menuVerticalPosition; int screenIndex = TELEMETRY_CURRENT_SCREEN(menuVerticalPosition);
int screenIndex = TELEMETRY_CURRENT_SCREEN(sub);
if (result == STR_UPDATE_LIST) { if (result == STR_UPDATE_LIST) {
if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) { if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) {
@ -506,8 +505,6 @@ bool menuModelTelemetry(evt_t event)
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX, DEFAULT_SCROLLBAR_X, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS LABEL(TopBar), 0, 0, TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), TELEMETRY_SCREEN_ROWS(2), TELEMETRY_SCREEN_ROWS(3) }); MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX, DEFAULT_SCROLLBAR_X, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS LABEL(TopBar), 0, 0, TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), TELEMETRY_SCREEN_ROWS(2), TELEMETRY_SCREEN_ROWS(3) });
int sub = menuVerticalPosition;
for (int i=0; i<NUM_BODY_LINES; i++) { for (int i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_CONTENT_TOP + i*FH; coord_t y = MENU_CONTENT_TOP + i*FH;
int k = i + menuVerticalOffset; int k = i + menuVerticalOffset;
@ -517,7 +514,7 @@ bool menuModelTelemetry(evt_t event)
} }
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (sub == k ? blink : 0); LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_SENSORS) { if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_SENSORS) {
int index = k-ITEM_TELEMETRY_SENSOR1; int index = k-ITEM_TELEMETRY_SENSOR1;
@ -604,7 +601,7 @@ bool menuModelTelemetry(evt_t event)
case ITEM_TELEMETRY_IGNORE_SENSOR_INSTANCE: case ITEM_TELEMETRY_IGNORE_SENSOR_INSTANCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_IGNORE_INSTANCE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_IGNORE_INSTANCE);
onoffMenuItem(g_model.ignoreSensorIds, TELEM_COL2, y, attr, event); editCheckBox(g_model.ignoreSensorIds, TELEM_COL2, y, attr, event);
break; break;
case ITEM_TELEMETRY_RSSI_LABEL: case ITEM_TELEMETRY_RSSI_LABEL:

View file

@ -123,7 +123,7 @@ const MenuHandlerFunc menuTabModel[] = {
CASE_TEMPLATES(menuModelTemplates) CASE_TEMPLATES(menuModelTemplates)
}; };
enum EnumTabDiag { enum EnumTabRadio {
e_Setup, e_Setup,
e_Sd, e_Sd,
e_GeneralCustomFunctions, e_GeneralCustomFunctions,
@ -221,7 +221,7 @@ extern const CheckIncDecStops &stopsSwitch;
(val), (val+1) (val), (val+1)
int checkIncDec(evt_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100); int checkIncDec(evt_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100);
int8_t checkIncDecMovedSwitch(int8_t val); swsrc_t checkIncDecMovedSwitch(swsrc_t val);
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL) #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 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 checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
@ -245,7 +245,7 @@ int8_t checkIncDecMovedSwitch(int8_t val);
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available) CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \ #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event, var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable) var = checkIncDec(event, var, min, max, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
#define CHECK_INCDEC_GENVAR(event, var, min, max) \ #define CHECK_INCDEC_GENVAR(event, var, min, max) \
var = checkIncDecGen(event, var, min, max) var = checkIncDecGen(event, var, min, max)
@ -297,20 +297,20 @@ void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
typedef int select_menu_value_t; typedef int select_menu_value_t;
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char * values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, evt_t event); select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char * values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, evt_t event);
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event); uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event);
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, evt_t event); int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, evt_t event);
#if defined(GVARS) #if defined(GVARS)
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(x, y, v, min, max, lcdattr, editflags, event) #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
#else #else
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(x, y, v, min, max, lcdattr, event) #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, event)
#endif #endif
#if defined(GVARS) #if defined(GVARS)
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, evt_t event); int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, evt_t event);
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, evt_t event); int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, evt_t event);
#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v) #define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
#endif #endif
@ -335,10 +335,20 @@ extern uint8_t warningType;
#define COPY_MODE 1 #define COPY_MODE 1
#define MOVE_MODE 2 #define MOVE_MODE 2
extern uint8_t s_copyMode; extern uint8_t s_copyMode;
extern int8_t s_copySrcRow; extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs; extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx; extern uint8_t s_currIdx;
extern int8_t s_currCh;
extern uint8_t s_copySrcIdx;
extern uint8_t s_copySrcCh;
uint8_t getExposCount();
void deleteExpo(uint8_t idx);
void insertExpo(uint8_t idx);
uint8_t getMixesCount();
void deleteMix(uint8_t idx);
void insertMix(uint8_t idx);
#define MENU_X 80 #define MENU_X 80
#define MENU_W LCD_W-(2*MENU_X) #define MENU_W LCD_W-(2*MENU_X)
@ -362,32 +372,36 @@ extern int16_t warningInputValueMin;
extern int16_t warningInputValueMax; extern int16_t warningInputValueMax;
extern uint8_t warningInfoFlags; extern uint8_t warningInfoFlags;
#define DISPLAY_WARNING (*popupFunc) #define DISPLAY_WARNING (*popupFunc)
#define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = displayWarning) #define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = displayWarning)
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = displayWarning) #define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = displayWarning)
#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max) #define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max)
#define WARNING_INFO_FLAGS warningInfoFlags #define WARNING_INFO_FLAGS warningInfoFlags
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags) #define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
#define NAVIGATION_MENUS #define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) popupMenuItems[popupMenuNoItems++] = s #define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0)
#define POPUP_MENU_MAX_LINES 6 #define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 6 #define MENU_MAX_DISPLAY_LINES 6
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s) #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define POPUP_MENU_ITEMS_FROM_BSS() #define POPUP_MENU_ITEMS_FROM_BSS()
extern const char *popupMenuItems[POPUP_MENU_MAX_LINES]; extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems; extern uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset; extern uint16_t popupMenuOffset;
enum {
MENU_OFFSET_INTERNAL,
MENU_OFFSET_EXTERNAL
};
extern uint8_t popupMenuOffsetType;
const char * displayPopupMenu(evt_t event); const char * displayPopupMenu(evt_t event);
extern void (*popupMenuHandler)(const char *result); extern void (*popupMenuHandler)(const char * result);
#define TEXT_FILENAME_MAXLEN 40 #define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN]; extern char s_text_file[TEXT_FILENAME_MAXLEN];
void pushMenuTextView(const char *filename); void pushMenuTextView(const char * filename);
void pushModelNotes(); void pushModelNotes();
#define LABEL(...) (uint8_t)-1 #define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT || EVT_KEY_MASK(event) == KEY_LEFT) #define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT || EVT_KEY_MASK(event) == KEY_RIGHT) #define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT || EVT_KEY_MASK(event) == KEY_RIGHT)

View file

@ -26,17 +26,18 @@ horzpos_t menuHorizontalPosition;
int8_t s_editMode; int8_t s_editMode;
uint8_t noHighlightCounter; uint8_t noHighlightCounter;
uint8_t calibrationState; // TODO rename this variable uint8_t calibrationState; // TODO rename this variable
int checkIncDecSelection = 0;
#if defined(AUTOSWITCH) #if defined(AUTOSWITCH)
int8_t checkIncDecMovedSwitch(int8_t val) swsrc_t checkIncDecMovedSwitch(swsrc_t val)
{ {
if (s_editMode>0) { if (s_editMode>0) {
int8_t swtch = getMovedSwitch(); swsrc_t swtch = getMovedSwitch();
if (swtch) { if (swtch) {
div_t info = switchInfo(swtch); div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) { if (IS_TOGGLE(info.quot)) {
if (info.rem != 0) { if (info.rem != 0) {
val = (val == swtch ? swtch+2 : swtch); val = (val == swtch ? swtch-2 : swtch);
} }
} }
else { else {
@ -54,6 +55,57 @@ INIT_STOPS(stops100, 3, -100, 0, 100)
INIT_STOPS(stops1000, 3, -1000, 0, 1000) INIT_STOPS(stops1000, 3, -1000, 0, 1000)
INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST) INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST)
void onSourceLongEnterPress(const char * result)
{
if (result == STR_MENU_INPUTS)
checkIncDecSelection = getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable)+1;
#if defined(LUA_MODEL_SCRIPTS)
else if (result == STR_MENU_LUA)
checkIncDecSelection = getFirstAvailable(MIXSRC_FIRST_LUA, MIXSRC_LAST_LUA, isSourceAvailable);
#endif
else if (result == STR_MENU_STICKS)
checkIncDecSelection = MIXSRC_FIRST_STICK;
else if (result == STR_MENU_POTS)
checkIncDecSelection = MIXSRC_FIRST_POT;
else if (result == STR_MENU_MAX)
checkIncDecSelection = MIXSRC_MAX;
else if (result == STR_MENU_HELI)
checkIncDecSelection = MIXSRC_FIRST_HELI;
else if (result == STR_MENU_TRIMS)
checkIncDecSelection = MIXSRC_FIRST_TRIM;
else if (result == STR_MENU_SWITCHES)
checkIncDecSelection = MIXSRC_FIRST_SWITCH;
else if (result == STR_MENU_TRAINER)
checkIncDecSelection = MIXSRC_FIRST_TRAINER;
else if (result == STR_MENU_CHANNELS)
checkIncDecSelection = getFirstAvailable(MIXSRC_FIRST_CH, MIXSRC_LAST_CH, isSourceAvailable);
else if (result == STR_MENU_GVARS)
checkIncDecSelection = MIXSRC_FIRST_GVAR;
else if (result == STR_MENU_TELEMETRY) {
for (int i = 0; i < MAX_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) {
checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i;
break;
}
}
}
}
void onSwitchLongEnterPress(const char *result)
{
if (result == STR_MENU_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_SWITCH;
else if (result == STR_MENU_TRIMS)
checkIncDecSelection = SWSRC_FIRST_TRIM;
else if (result == STR_MENU_LOGICAL_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, NUM_LOGICAL_SWITCH, isLogicalSwitchAvailable);
else if (result == STR_MENU_OTHER)
checkIncDecSelection = SWSRC_ON;
else if (result == STR_MENU_INVERT)
checkIncDecSelection = SWSRC_INVERT;
}
int checkIncDec(evt_t event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops) int checkIncDec(evt_t event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops)
{ {
int newval = val; int newval = val;
@ -192,6 +244,85 @@ int checkIncDec(evt_t event, int val, int i_min, int i_max, unsigned int i_flags
else { else {
checkIncDec_Ret = 0; checkIncDec_Ret = 0;
} }
if (i_flags & INCDEC_SOURCE) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
checkIncDecSelection = MIXSRC_NONE;
TRACE("count items avant = %d", popupMenuNoItems);
if (i_min <= MIXSRC_FIRST_INPUT && i_max >= MIXSRC_FIRST_INPUT) {
if (getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable) != MIXSRC_NONE) {
POPUP_MENU_ADD_ITEM(STR_MENU_INPUTS);
}
}
#if defined(LUA_MODEL_SCRIPTS)
if (i_min <= MIXSRC_FIRST_LUA && i_max >= MIXSRC_FIRST_LUA) {
if (getFirstAvailable(MIXSRC_FIRST_LUA, MIXSRC_LAST_LUA, isSourceAvailable) != MIXSRC_NONE) {
POPUP_MENU_ADD_ITEM(STR_MENU_LUA);
}
}
#endif
if (i_min <= MIXSRC_FIRST_STICK && i_max >= MIXSRC_FIRST_STICK) POPUP_MENU_ADD_ITEM(STR_MENU_STICKS);
if (i_min <= MIXSRC_FIRST_POT && i_max >= MIXSRC_FIRST_POT) POPUP_MENU_ADD_ITEM(STR_MENU_POTS);
if (i_min <= MIXSRC_MAX && i_max >= MIXSRC_MAX) POPUP_MENU_ADD_ITEM(STR_MENU_MAX);
#if defined(HELI)
if (i_min <= MIXSRC_FIRST_HELI && i_max >= MIXSRC_FIRST_HELI) POPUP_MENU_ADD_ITEM(STR_MENU_HELI);
#endif
if (i_min <= MIXSRC_FIRST_TRIM && i_max >= MIXSRC_FIRST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= MIXSRC_FIRST_SWITCH && i_max >= MIXSRC_FIRST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= MIXSRC_FIRST_TRAINER && i_max >= MIXSRC_FIRST_TRAINER) POPUP_MENU_ADD_ITEM(STR_MENU_TRAINER);
if (i_min <= MIXSRC_FIRST_CH && i_max >= MIXSRC_FIRST_CH) POPUP_MENU_ADD_ITEM(STR_MENU_CHANNELS);
if (i_min <= MIXSRC_FIRST_GVAR && i_max >= MIXSRC_FIRST_GVAR && isValueAvailable(MIXSRC_FIRST_GVAR)) {
POPUP_MENU_ADD_ITEM(STR_MENU_GVARS);
}
if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) {
for (int i = 0; i < MAX_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) {
POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY);
break;
}
}
}
popupMenuHandler = onSourceLongEnterPress;
TRACE("count items apres = %d", popupMenuNoItems);
}
if (checkIncDecSelection != 0) {
newval = checkIncDecSelection;
if (checkIncDecSelection != MIXSRC_MAX)
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
}
}
else if (i_flags & INCDEC_SWITCH) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
checkIncDecSelection = SWSRC_NONE;
if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) {
if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) {
POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES);
break;
}
}
}
if (isValueAvailable && isValueAvailable(SWSRC_ON)) POPUP_MENU_ADD_ITEM(STR_MENU_OTHER);
if (isValueAvailable && isValueAvailable(-newval)) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT);
popupMenuHandler = onSwitchLongEnterPress;
s_editMode = EDIT_MODIFY_FIELD;
}
if (checkIncDecSelection != 0) {
newval = (checkIncDecSelection == SWSRC_INVERT ? -newval : checkIncDecSelection);
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
}
}
return newval; return newval;
} }
@ -319,8 +450,7 @@ bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, u
menuPageCount = menuTabSize; menuPageCount = menuTabSize;
} }
switch(event) switch(event) {
{
case EVT_ENTRY: case EVT_ENTRY:
menuVerticalPosition = (menuTab ? -1 : MENU_FIRST_LINE_EDIT); menuVerticalPosition = (menuTab ? -1 : MENU_FIRST_LINE_EDIT);
menuHorizontalPosition = POS_HORZ_INIT(0); menuHorizontalPosition = POS_HORZ_INIT(0);
@ -353,6 +483,10 @@ bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, u
break; break;
} }
if (s_copyMode > 0) {
break;
}
if (menuHorizontalPosition >= 0 && (COLATTR(menuVerticalPosition) & NAVIGATION_LINE_BY_LINE)) { if (menuHorizontalPosition >= 0 && (COLATTR(menuVerticalPosition) & NAVIGATION_LINE_BY_LINE)) {
menuHorizontalPosition = -1; menuHorizontalPosition = -1;
} }

View file

@ -29,12 +29,13 @@ uint8_t warningInfoFlags = ZCHAR;
int16_t warningInputValue; int16_t warningInputValue;
int16_t warningInputValueMin; int16_t warningInputValueMin;
int16_t warningInputValueMax; int16_t warningInputValueMax;
void (*popupFunc)(evt_t event) = NULL; void (*popupFunc)(evt_t event) = NULL;
const char *popupMenuItems[POPUP_MENU_MAX_LINES]; const char *popupMenuItems[POPUP_MENU_MAX_LINES];
uint8_t s_menu_item = 0; uint8_t s_menu_item = 0;
uint16_t popupMenuNoItems = 0; uint16_t popupMenuNoItems = 0;
uint16_t popupMenuOffset = 0; uint16_t popupMenuOffset = 0;
void (*popupMenuHandler)(const char *result); uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL;
void (*popupMenuHandler)(const char * result);
void displayAlertBox() void displayAlertBox()
{ {
@ -61,7 +62,7 @@ void displayMessageBox()
// lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_MESSAGE); // lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_MESSAGE);
} }
void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SOUND_ARG) void drawMessageBox(const char * title, const char * t, const char * last, uint8_t sound)
{ {
displayAlertBox(); displayAlertBox();
@ -78,7 +79,11 @@ void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SO
lcdDrawText(WARNING_LINE_X, WARNING_INFOLINE_Y+16, last); lcdDrawText(WARNING_LINE_X, WARNING_INFOLINE_Y+16, last);
AUDIO_ERROR_MESSAGE(sound); AUDIO_ERROR_MESSAGE(sound);
} }
}
void message(const pm_char * title, const pm_char * t, const char * last, uint8_t sound)
{
drawMessageBox(title, t, last, sound);
lcdRefresh(); lcdRefresh();
lcdSetContrast(); lcdSetContrast();
clearKeyEvents(); clearKeyEvents();
@ -125,7 +130,8 @@ void displayWarning(evt_t event)
const char * displayPopupMenu(evt_t event) const char * displayPopupMenu(evt_t event)
{ {
const char * result = NULL; const char * result = NULL;
uint8_t display_count = min(popupMenuNoItems, (uint16_t)POPUP_MENU_MAX_LINES);
uint8_t display_count = min<unsigned int>(popupMenuNoItems, MENU_MAX_DISPLAY_LINES);
switch (event) { switch (event) {
case EVT_ROTARY_LEFT: case EVT_ROTARY_LEFT:
@ -139,9 +145,9 @@ const char * displayPopupMenu(evt_t event)
result = STR_UPDATE_LIST; result = STR_UPDATE_LIST;
} }
else { else {
s_menu_item = display_count - 1; s_menu_item = min<uint8_t>(display_count, MENU_MAX_DISPLAY_LINES) - 1;
if (popupMenuNoItems > POPUP_MENU_MAX_LINES) { if (popupMenuNoItems > MENU_MAX_DISPLAY_LINES) {
popupMenuOffset = popupMenuNoItems - display_count; popupMenuOffset = popupMenuNoItems - MENU_MAX_DISPLAY_LINES;
result = STR_UPDATE_LIST; result = STR_UPDATE_LIST;
} }
} }
@ -166,7 +172,7 @@ const char * displayPopupMenu(evt_t event)
} }
break; break;
case EVT_KEY_BREAK(KEY_ENTER): case EVT_KEY_BREAK(KEY_ENTER):
result = popupMenuItems[s_menu_item]; result = popupMenuItems[s_menu_item + (popupMenuOffsetType == MENU_OFFSET_INTERNAL ? popupMenuOffset : 0)];
// no break // no break
case EVT_KEY_BREAK(KEY_EXIT): case EVT_KEY_BREAK(KEY_EXIT):
popupMenuNoItems = 0; popupMenuNoItems = 0;
@ -183,10 +189,10 @@ const char * displayPopupMenu(evt_t event)
for (uint8_t i=0; i<display_count; i++) { for (uint8_t i=0; i<display_count; i++) {
if (i == s_menu_item) { if (i == s_menu_item) {
lcdDrawSolidFilledRect(MENU_X+1, i*(FH+1) + y + 1, MENU_W-2, FH+1, TEXT_INVERTED_BGCOLOR); lcdDrawSolidFilledRect(MENU_X+1, i*(FH+1) + y + 1, MENU_W-2, FH+1, TEXT_INVERTED_BGCOLOR);
lcdDrawText(MENU_X+6, i*(FH+1) + y + 4, popupMenuItems[i], TEXT_INVERTED_COLOR); lcdDrawText(MENU_X+6, i*(FH+1) + y + 4, popupMenuItems[i+(popupMenuOffsetType == MENU_OFFSET_INTERNAL ? popupMenuOffset : 0)], TEXT_INVERTED_COLOR);
} }
else { else {
lcdDrawText(MENU_X+6, i*(FH+1) + y + 4, popupMenuItems[i], 0); lcdDrawText(MENU_X+6, i*(FH+1) + y + 4, popupMenuItems[i+(popupMenuOffsetType == MENU_OFFSET_INTERNAL ? popupMenuOffset : 0)], 0);
} }
} }

View file

@ -321,8 +321,8 @@ bool menuMainView(evt_t event)
case EVT_KEY_FIRST(KEY_EXIT): case EVT_KEY_FIRST(KEY_EXIT):
#if defined(GVARS) #if defined(GVARS)
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer = 0; gvarDisplayTimer = 0;
} }
#endif #endif
AUDIO_KEYPAD_UP(); AUDIO_KEYPAD_UP();
@ -388,12 +388,12 @@ bool menuMainView(evt_t event)
} }
#if 0 #if 0
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer--; gvarDisplayTimer--;
displayMessageBox(); displayMessageBox();
putsStrIdx(WARNING_LINE_X, WARNING_LINE_Y, STR_GV, s_gvar_last+1, DBLSIZE|YELLOW); putsStrIdx(WARNING_LINE_X, WARNING_LINE_Y, STR_GV, gvarLastChanged+1, DBLSIZE|YELLOW);
lcdDrawSizedText(WARNING_LINE_X+45, WARNING_LINE_Y, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, DBLSIZE|YELLOW|ZCHAR); lcdDrawSizedText(WARNING_LINE_X+45, WARNING_LINE_Y, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, DBLSIZE|YELLOW|ZCHAR);
lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, GVAR_VALUE(s_gvar_last, getGVarFlightPhase(mixerCurrentFlightMode, s_gvar_last)), DBLSIZE|LEFT); lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), DBLSIZE|LEFT);
} }
#endif #endif

View file

@ -238,7 +238,7 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char * values,
return value; return value;
} }
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event ) uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event )
{ {
drawCheckBox(x, y, value, attr); drawCheckBox(x, y, value, attr);
return selectMenuItem(x, y, NULL, value, 0, 1, attr, event); return selectMenuItem(x, y, NULL, value, 0, 1, attr, event);
@ -269,12 +269,12 @@ bool noZero(int val)
return val != 0; return val != 0;
} }
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, evt_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, evt_t event)
{ {
uint16_t delta = GV_GET_GV1_VALUE(max); uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS); bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode; s_editMode = !s_editMode;
@ -316,7 +316,7 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
return value; return value;
} }
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, evt_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, evt_t event)
{ {
if (attr & INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); if (attr & INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
lcdDrawNumber(x, y, value, attr, 0, NULL, "%"); lcdDrawNumber(x, y, value, attr, 0, NULL, "%");
@ -324,8 +324,8 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
} }
#endif #endif
#define SLEEP_BITMAP_WIDTH 60 #define SLEEP_BITMAP_WIDTH 110
#define SLEEP_BITMAP_HEIGHT 60 #define SLEEP_BITMAP_HEIGHT 110
void drawSleepBitmap() void drawSleepBitmap()
{ {
lcdClear(); lcdClear();
@ -333,11 +333,12 @@ void drawSleepBitmap()
lcdRefresh(); lcdRefresh();
} }
#define SHUTDOWN_BITMAP_WIDTH 60 #define SHUTDOWN_BITMAP_WIDTH 110
#define SHUTDOWN_BITMAP_HEIGHT 60 #define SHUTDOWN_BITMAP_HEIGHT 110
void drawShutdownBitmap(uint8_t index) void drawShutdownBitmap(uint8_t index)
{ {
lcdClear(); // lcdClear();
lcdDrawBitmap((LCD_W-SHUTDOWN_BITMAP_WIDTH)/2, (LCD_H-SHUTDOWN_BITMAP_HEIGHT)/2, LBM_SHUTDOWN, index*SHUTDOWN_BITMAP_WIDTH, SHUTDOWN_BITMAP_WIDTH); lcdDrawBitmap((LCD_W-SHUTDOWN_BITMAP_WIDTH)/2, (LCD_H-SHUTDOWN_BITMAP_HEIGHT)/2, LBM_SHUTDOWN, index*SHUTDOWN_BITMAP_WIDTH, SHUTDOWN_BITMAP_WIDTH);
lcdDrawBitmapPatternPie((LCD_W-150)/2, (LCD_H-150)/2, LBM_BIGRSCALE, TEXT_COLOR, 0, 360/4*index);
lcdRefresh(); lcdRefresh();
} }

View file

@ -70,3 +70,10 @@ extern coord_t scrollbar_X;
extern const pm_uchar sticks[] PROGMEM; extern const pm_uchar sticks[] PROGMEM;
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr);
#else
#define displayFlightModes(...)
#endif

View file

@ -404,22 +404,21 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t le
xn = x; xn = x;
} }
else if (smlsize) { else if (smlsize) {
x -= 2; x -= 1;
lcdDrawPoint(x+1, y+5); lcdDrawPoint(x-1, y+5);
if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE)) { if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE)) {
lcdDrawSolidVerticalLine(x+1, y, 7); lcdDrawSolidVerticalLine(x-1, y, 7);
} }
} }
else if (tinsize) { else if (tinsize) {
x--; x -= 2;
lcdDrawPoint(x-1, y+4); lcdDrawPoint(x, y+4);
if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE)) { if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE)) {
lcdDrawSolidVerticalLine(x-1, y-1, 7); lcdDrawSolidVerticalLine(x, y-1, 7);
} }
x--;
} }
else { else {
x -= 2; x -= (flags & BOLD) ? 3 : 2;
lcdDrawChar(x, y, '.', f); lcdDrawChar(x, y, '.', f);
} }
} }
@ -952,10 +951,9 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, int32_t va
} }
else { else {
LcdFlags flags = att; LcdFlags flags = att;
if (telemetrySensor.prec==2) if (telemetrySensor.prec > 0) {
flags |= PREC2; flags |= (telemetrySensor.prec==1 ? PREC1 : PREC2);
else if (telemetrySensor.prec==1) }
flags |= PREC1;
putsValueWithUnit(x, y, value, telemetrySensor.unit == UNIT_CELLS ? UNIT_VOLTS : telemetrySensor.unit, flags); putsValueWithUnit(x, y, value, telemetrySensor.unit == UNIT_CELLS ? UNIT_VOLTS : telemetrySensor.unit, flags);
} }
} }

View file

@ -46,7 +46,7 @@
/* lcd text flags */ /* lcd text flags */
#define INVERS 0x02 #define INVERS 0x02
#if defined(BOLD_FONT) #if defined(BOLD_FONT)
#define BOLD 0x40 #define BOLD 0x04
#else #else
#define BOLD 0x00 #define BOLD 0x00
#endif #endif
@ -71,7 +71,7 @@
#define FORCE 0x02 #define FORCE 0x02
#define ERASE 0x04 #define ERASE 0x04
#define ROUND 0x08 #define ROUND 0x08
#define FILL_WHITE 0x10 #define FILL_WHITE 0x10
/* telemetry flags */ /* telemetry flags */
#define NO_UNIT 0x40 #define NO_UNIT 0x40

View file

@ -198,7 +198,7 @@ void menuGeneralHardware(uint8_t event)
#if defined(REV9E) #if defined(REV9E)
case ITEM_SETUP_HW_BLUETOOTH: case ITEM_SETUP_HW_BLUETOOTH:
lcd_putsLeft(y, "Bluetooth"); lcd_putsLeft(y, "Bluetooth");
menu_lcd_onoff(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 0); drawCheckBox(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 0);
if (attr && menuHorizontalPosition == 0) { if (attr && menuHorizontalPosition == 0) {
g_eeGeneral.bluetoothEnable = checkIncDecGen(event, g_eeGeneral.bluetoothEnable, 0, 1); g_eeGeneral.bluetoothEnable = checkIncDecGen(event, g_eeGeneral.bluetoothEnable, 0, 1);
} }

View file

@ -310,14 +310,14 @@ void menuGeneralSetup(uint8_t event)
case ITEM_SETUP_MEMORY_WARNING: case ITEM_SETUP_MEMORY_WARNING:
{ {
uint8_t b = 1-g_eeGeneral.disableMemoryWarning; uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event); g_eeGeneral.disableMemoryWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event);
break; break;
} }
case ITEM_SETUP_ALARM_WARNING: case ITEM_SETUP_ALARM_WARNING:
{ {
uint8_t b = 1-g_eeGeneral.disableAlarmWarning; uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event); g_eeGeneral.disableAlarmWarning = 1 - editCheckBox(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event);
break; break;
} }
@ -337,7 +337,7 @@ void menuGeneralSetup(uint8_t event)
break; break;
case ITEM_SETUP_FLASH_BEEP: case ITEM_SETUP_FLASH_BEEP:
g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ; g_eeGeneral.alarmsFlash = editCheckBox(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ;
break; break;
case ITEM_SETUP_BACKLIGHT_DELAY: case ITEM_SETUP_BACKLIGHT_DELAY:
@ -393,7 +393,7 @@ void menuGeneralSetup(uint8_t event)
break; break;
case ITEM_SETUP_ADJUST_RTC: case ITEM_SETUP_ADJUST_RTC:
g_eeGeneral.adjustRTC = onoffMenuItem(g_eeGeneral.adjustRTC, RADIO_SETUP_2ND_COLUMN, y, STR_ADJUST_RTC, attr, event); g_eeGeneral.adjustRTC = editCheckBox(g_eeGeneral.adjustRTC, RADIO_SETUP_2ND_COLUMN, y, STR_ADJUST_RTC, attr, event);
break; break;
case ITEM_SETUP_GPSFORMAT: case ITEM_SETUP_GPSFORMAT:
@ -425,7 +425,7 @@ void menuGeneralSetup(uint8_t event)
#if defined(FAI_CHOICE) #if defined(FAI_CHOICE)
case ITEM_SETUP_FAI: case ITEM_SETUP_FAI:
onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event); editCheckBox(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
if (g_eeGeneral.fai) if (g_eeGeneral.fai)
POPUP_WARNING(PSTR("FAI\001mode blocked!")); POPUP_WARNING(PSTR("FAI\001mode blocked!"));

View file

@ -43,6 +43,9 @@ uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, cons
uint8_t s_copyMode = 0; uint8_t s_copyMode = 0;
int8_t s_copySrcRow; int8_t s_copySrcRow;
int8_t s_copyTgtOfs; int8_t s_copyTgtOfs;
uint8_t s_maxLines = 8;
uint8_t s_copySrcIdx;
uint8_t s_copySrcCh;
uint8_t editNameCursorPos = 0; uint8_t editNameCursorPos = 0;

View file

@ -125,17 +125,17 @@ void onCurveOneMenu(const char *result)
void menuModelCurveOne(uint8_t event) void menuModelCurveOne(uint8_t event)
{ {
static uint8_t pointsOfs = 0; static uint8_t pointsOfs = 0;
CurveInfo & crv = g_model.curves[s_curveChan]; CurveData & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan); int8_t * points = curveAddress(s_curveChan);
lcdDrawText(9*FW, 0, TR_PT "\003X\006Y"); lcdDrawText(11*FW+FW/2, 0, TR_PT "\002X\006Y");
putsStrIdx(PSIZE(TR_MENUCURVES)*FW+FW, 0, "CV", s_curveChan+1);
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SIMPLE_SUBMENU(STR_MENUCURVE, 4 + 5+crv.points + (crv.type==CURVE_TYPE_CUSTOM ? 5+crv.points-2 : 0)); SIMPLE_SUBMENU(STR_MENUCURVES, 4 + 5+crv.points + (crv.type==CURVE_TYPE_CUSTOM ? 5+crv.points-2 : 0));
lcdDrawNumber(PSIZE(TR_MENUCURVE)*FW+1, 0, s_curveChan+1, INVERS|LEFT);
lcd_putsLeft(FH+1, STR_NAME); lcd_putsLeft(FH+1, STR_NAME);
editName(INDENT_WIDTH, 2*FH+1, g_model.curveNames[s_curveChan], sizeof(g_model.curveNames[s_curveChan]), event, menuVerticalPosition==0); editName(INDENT_WIDTH, 2*FH+1, crv.name, sizeof(crv.name), event, menuVerticalPosition==0);
uint8_t attr = (menuVerticalPosition==1 ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0); uint8_t attr = (menuVerticalPosition==1 ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0);
lcd_putsLeft(3*FH+1, STR_TYPE); lcd_putsLeft(3*FH+1, STR_TYPE);
@ -177,7 +177,7 @@ void menuModelCurveOne(uint8_t event)
} }
lcd_putsLeft(7*FH+1, STR_SMOOTH); lcd_putsLeft(7*FH+1, STR_SMOOTH);
menu_lcd_onoff(7*FW, 7*FH+1, crv.smooth, menuVerticalPosition==3 ? INVERS : 0); drawCheckBox(7 * FW, 7 * FH + 1, crv.smooth, menuVerticalPosition == 3 ? INVERS : 0);
if (menuVerticalPosition==3) crv.smooth = checkIncDecModel(event, crv.smooth, 0, 1); if (menuVerticalPosition==3) crv.smooth = checkIncDecModel(event, crv.smooth, 0, 1);
switch(event) { switch(event) {
@ -219,9 +219,9 @@ void menuModelCurveOne(uint8_t event)
if (i>=pointsOfs && i<pointsOfs+7) { if (i>=pointsOfs && i<pointsOfs+7) {
int8_t x = -100 + 200*i/(5+crv.points-1); int8_t x = -100 + 200*i/(5+crv.points-1);
if (crv.type==CURVE_TYPE_CUSTOM && i>0 && i<5+crv.points-1) x = points[5+crv.points+i-1]; if (crv.type==CURVE_TYPE_CUSTOM && i>0 && i<5+crv.points-1) x = points[5+crv.points+i-1];
lcdDrawNumber(6+8*FW, posY, i+1, LEFT); lcdDrawNumber(6+10*FW+FW/2, posY, i+1, LEFT);
lcdDrawNumber(3+12*FW, posY, x, LEFT|(selectionMode==1?attr:0)); lcdDrawNumber(3+14*FW, posY, x, LEFT|(selectionMode==1?attr:0));
lcdDrawNumber(3+16*FW, posY, points[i], LEFT|(selectionMode==2?attr:0)); lcdDrawNumber(3+18*FW, posY, points[i], LEFT|(selectionMode==2?attr:0));
posY += FH; posY += FH;
} }
@ -253,10 +253,10 @@ void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t
switch (curve.type) { switch (curve.type) {
case CURVE_REF_DIFF: case CURVE_REF_DIFF:
case CURVE_REF_EXPO: case CURVE_REF_EXPO:
curve.value = GVAR_MENU_ITEM(x+5*FW, y, curve.value, -100, 100, menuHorizontalPosition==1 ? LEFT|attr : LEFT, 0, event); curve.value = GVAR_MENU_ITEM(x+5*FW+2, y, curve.value, -100, 100, menuHorizontalPosition==1 ? LEFT|attr : LEFT, 0, event);
break; break;
case CURVE_REF_FUNC: case CURVE_REF_FUNC:
lcdDrawTextAtIndex(x+5*FW, y, STR_VCURVEFUNC, curve.value, menuHorizontalPosition==1 ? attr : 0); lcdDrawTextAtIndex(x+5*FW+2, y, STR_VCURVEFUNC, curve.value, menuHorizontalPosition==1 ? attr : 0);
if (attr && menuHorizontalPosition==1) CHECK_INCDEC_MODELVAR_ZERO(event, curve.value, CURVE_BASE-1); if (attr && menuHorizontalPosition==1) CHECK_INCDEC_MODELVAR_ZERO(event, curve.value, CURVE_BASE-1);
break; break;
case CURVE_REF_CUSTOM: case CURVE_REF_CUSTOM:
@ -295,8 +295,8 @@ void menuModelCurvesAll(uint8_t event)
LcdFlags attr = (sub == k ? INVERS : 0); LcdFlags attr = (sub == k ? INVERS : 0);
{ {
putsStrIdx(0, y, STR_CV, k+1, attr); putsStrIdx(0, y, STR_CV, k+1, attr);
editName(4*FW, y, g_model.curveNames[k], sizeof(g_model.curveNames[k]), 0, 0); CurveData & crv = g_model.curves[k];
CurveInfo & crv = g_model.curves[k]; editName(4*FW, y, crv.name, sizeof(crv.name), 0, 0);
lcdDrawNumber(11*FW, y, 5+crv.points, LEFT); lcdDrawNumber(11*FW, y, 5+crv.points, LEFT);
lcdDrawText(lcdLastPos, y, STR_PTS, 0); lcdDrawText(lcdLastPos, y, STR_PTS, 0);
} }

View file

@ -26,7 +26,7 @@
#define MODEL_CUSTOM_FUNC_4TH_COLUMN (33*FW-3) #define MODEL_CUSTOM_FUNC_4TH_COLUMN (33*FW-3)
#define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (34*FW-3) #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (34*FW-3)
void onCustomFunctionsFileSelectionMenu(const char *result) void onCustomFunctionsFileSelectionMenu(const char * result)
{ {
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
CustomFunctionData * cfn; CustomFunctionData * cfn;
@ -66,7 +66,7 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
} }
} }
void onCustomFunctionsMenu(const char *result) void onCustomFunctionsMenu(const char * result)
{ {
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
CustomFunctionData * cfn; CustomFunctionData * cfn;
@ -125,7 +125,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result)
storageDirty(EE_MODEL); storageDirty(EE_MODEL);
} }
else if (result == STR_INCDEC) { else if (result == STR_INCDEC) {
CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_INC; CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_INCDEC;
CFN_PARAM(cfn) = 0; CFN_PARAM(cfn) = 0;
storageDirty(EE_MODEL); storageDirty(EE_MODEL);
} }
@ -134,6 +134,16 @@ void onAdjustGvarSourceLongEnterPress(const char * result)
} }
} }
enum CustomFunctionsItems {
ITEM_CUSTOM_FUNCTIONS_SWITCH,
ITEM_CUSTOM_FUNCTIONS_FUNCTION,
ITEM_CUSTOM_FUNCTIONS_PARAM1,
ITEM_CUSTOM_FUNCTIONS_PARAM2,
ITEM_CUSTOM_FUNCTIONS_REPEAT,
ITEM_CUSTOM_FUNCTIONS_COUNT,
ITEM_CUSTOM_FUNCTIONS_LAST = ITEM_CUSTOM_FUNCTIONS_COUNT-1
};
void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext) void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext)
{ {
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
@ -170,7 +180,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && s_editMode>0); uint8_t active = (attr && s_editMode>0);
switch (j) { switch (j) {
case 0: case ITEM_CUSTOM_FUNCTIONS_SWITCH:
putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) { if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) {
@ -178,7 +188,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
} }
break; break;
case 1: case ITEM_CUSTOM_FUNCTIONS_FUNCTION:
if (CFN_SWITCH(cfn)) { if (CFN_SWITCH(cfn)) {
lcdDrawTextAtIndex(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr); lcdDrawTextAtIndex(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr);
if (active) { if (active) {
@ -187,14 +197,14 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
} }
} }
else { else {
j = 4; // skip other fields j = ITEM_CUSTOM_FUNCTIONS_LAST; // skip other fields
if (sub==k && menuHorizontalPosition > 0) { if (sub==k && menuHorizontalPosition > 0) {
REPEAT_LAST_CURSOR_MOVE(); REPEAT_LAST_CURSOR_MOVE();
} }
} }
break; break;
case 2: case ITEM_CUSTOM_FUNCTIONS_PARAM1:
{ {
int8_t maxParam = NUM_CHNOUT-1; int8_t maxParam = NUM_CHNOUT-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION) #if defined(OVERRIDE_CHANNEL_FUNCTION)
@ -204,7 +214,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
else else
#endif #endif
if (func == FUNC_TRAINER) { if (func == FUNC_TRAINER) {
maxParam = 4; maxParam = NUM_STICKS;
putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
} }
#if defined(GVARS) #if defined(GVARS)
@ -228,7 +238,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
break; break;
} }
case 3: case ITEM_CUSTOM_FUNCTIONS_PARAM2:
{ {
INCDEC_DECLARE_VARS(eeFlags); INCDEC_DECLARE_VARS(eeFlags);
int16_t val_displayed = CFN_PARAM(cfn); int16_t val_displayed = CFN_PARAM(cfn);
@ -335,7 +345,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
switch (CFN_GVAR_MODE(cfn)) { switch (CFN_GVAR_MODE(cfn)) {
case FUNC_ADJUST_GVAR_CONSTANT: case FUNC_ADJUST_GVAR_CONSTANT:
val_displayed = (int16_t)CFN_PARAM(cfn); val_displayed = (int16_t)CFN_PARAM(cfn);
val_min = -CFN_GVAR_CST_MAX; val_max = +CFN_GVAR_CST_MAX; val_min = CFN_GVAR_CST_MIN; val_max = CFN_GVAR_CST_MAX;
lcdDrawNumber(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); lcdDrawNumber(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
break; break;
case FUNC_ADJUST_GVAR_SOURCE: case FUNC_ADJUST_GVAR_SOURCE:
@ -351,17 +361,12 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed+1, attr); putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed+1, attr);
break; break;
default: // FUNC_ADJUST_GVAR_INC default: // FUNC_ADJUST_GVAR_INC
#if 0 // TODO 2.2.X
val_min = -100; val_max = +100; val_min = -100; val_max = +100;
if (val_displayed < 0) if (val_displayed < 0)
lcdDrawText(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, "-=", attr); lcdDrawText(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, "-= ", attr);
else else
lcdDrawText(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, "+=", attr); lcdDrawText(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, "+= ", attr);
lcdDrawNumber(lcdNextPos, y, abs(val_displayed), attr|LEFT); drawGVarValue(lcdNextPos, y, CFN_GVAR_INDEX(cfn), abs(val_displayed), attr|LEFT);
#endif
val_max = 1;
lcdDrawTextAtIndex(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, PSTR("\003-=1+=1"), val_displayed, attr);
break;
} }
} }
#endif #endif
@ -379,7 +384,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
POPUP_MENU_ADD_ITEM(STR_MIXSOURCE); POPUP_MENU_ADD_ITEM(STR_MIXSOURCE);
if (CFN_GVAR_MODE(cfn) != FUNC_ADJUST_GVAR_GVAR) if (CFN_GVAR_MODE(cfn) != FUNC_ADJUST_GVAR_GVAR)
POPUP_MENU_ADD_ITEM(STR_GLOBALVAR); POPUP_MENU_ADD_ITEM(STR_GLOBALVAR);
if (CFN_GVAR_MODE(cfn) != FUNC_ADJUST_GVAR_INC) if (CFN_GVAR_MODE(cfn) != FUNC_ADJUST_GVAR_INCDEC)
POPUP_MENU_ADD_ITEM(STR_INCDEC); POPUP_MENU_ADD_ITEM(STR_INCDEC);
popupMenuHandler = onAdjustGvarSourceLongEnterPress; popupMenuHandler = onAdjustGvarSourceLongEnterPress;
s_editMode = EDIT_MODIFY_FIELD; s_editMode = EDIT_MODIFY_FIELD;
@ -388,9 +393,9 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu
break; break;
} }
case 4: case ITEM_CUSTOM_FUNCTIONS_REPEAT:
if (HAS_ENABLE_PARAM(func)) { if (HAS_ENABLE_PARAM(func)) {
menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); drawCheckBox(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr);
if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
} }
else if (HAS_REPEAT_PARAM(func)) { else if (HAS_REPEAT_PARAM(func)) {

View file

@ -49,13 +49,12 @@ enum menuModelCustomScriptItems {
void menuModelCustomScriptOne(uint8_t event) void menuModelCustomScriptOne(uint8_t event)
{ {
TITLE(STR_MENUCUSTOMSCRIPT); ScriptData & sd = g_model.scriptsData[s_currIdx];
ScriptData &sd = g_model.scriptsData[s_currIdx]; putsStrIdx(PSIZE(TR_MENUCUSTOMSCRIPTS)*FW+FW, 0, "LUA", s_currIdx+1, 0);
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
putsStrIdx(lcdLastPos+FW, 0, "LUA", s_currIdx+1, 0); SUBMENU(STR_MENUCUSTOMSCRIPTS, 3+scriptInputsOutputs[s_currIdx].inputsCount, { 0, 0, LABEL(inputs), 0/*repeated*/ });
SUBMENU_NOTITLE(3+scriptInputsOutputs[s_currIdx].inputsCount, { 0, 0, LABEL(inputs), 0/*repeated*/ });
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;

View file

@ -30,6 +30,36 @@ void displayFlightModes(coord_t x, coord_t y, FlightModesType value)
} }
} }
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
lcd_putsColumnLeft(x, y, STR_FLMODE);
int posHorz = menuHorizontalPosition;
for (int p=0; p<MAX_FLIGHT_MODES; p++) {
LcdFlags flags = 0;
if (attr) {
flags |= INVERS;
if (posHorz==p) flags |= BLINK;
}
if (value & (1<<p))
lcdDrawChar(x, y, ' ', flags|FIXEDWIDTH);
else
lcdDrawChar(x, y, '0'+p, flags);
x += FW;
}
if (attr) {
if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
enum FlightModesItems { enum FlightModesItems {
ITEM_FLIGHT_MODES_NAME, ITEM_FLIGHT_MODES_NAME,
ITEM_FLIGHT_MODES_SWITCH, ITEM_FLIGHT_MODES_SWITCH,

View file

@ -20,17 +20,107 @@
#include "../../opentx.h" #include "../../opentx.h"
void editGVarValue(coord_t x, coord_t y, uint8_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags)
{
FlightModeData * fm = &g_model.flightModeData[flightMode];
gvar_t & v = fm->gvars[gvar];
int16_t vmin, vmax;
if (v > GVAR_MAX) {
uint8_t fm = v - GVAR_MAX - 1;
if (fm >= flightMode) fm++;
putsFlightMode(x, y, fm + 1, flags&(~LEFT));
vmin = GVAR_MAX + 1;
vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1;
}
else {
drawGVarValue(x, y, gvar, v, flags);
vmin = GVAR_MIN + g_model.gvars[gvar].min;
vmax = GVAR_MAX - g_model.gvars[gvar].max;
}
if (flags & INVERS) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
v = (v > GVAR_MAX ? 0 : GVAR_MAX+1);
storageDirty(EE_MODEL);
}
else if (s_editMode > 0) {
v = checkIncDec(event, v, vmin, vmax, EE_MODEL);
}
}
}
enum GVarFields {
GVAR_FIELD_NAME,
GVAR_FIELD_UNIT,
GVAR_FIELD_PREC,
GVAR_FIELD_MIN,
GVAR_FIELD_MAX,
GVAR_FIELD_POPUP,
GVAR_FIELD_FM0,
GVAR_FIELD_LAST=GVAR_FIELD_FM0+MAX_FLIGHT_MODES
};
#define GVAR_2ND_COLUMN (12*FW)
void menuModelGVarOne(uint8_t event)
{
GVarData * gvar = &g_model.gvars[s_currIdx];
putsStrIdx(PSIZE(TR_GVARS)*FW+FW, 0, STR_GV, s_currIdx+1, 0);
drawGVarValue(32*FW, 0, s_currIdx, getGVarValue(s_currIdx, getFlightMode()));
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SIMPLE_SUBMENU(STR_GVARS, GVAR_FIELD_LAST);
for (int i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i * FH;
int k = i + menuVerticalOffset;
LcdFlags attr = (menuVerticalPosition == k ? (s_editMode > 0 ? BLINK | INVERS : INVERS) : 0);
switch (k) {
case GVAR_FIELD_NAME:
editSingleName(GVAR_2ND_COLUMN, y, STR_NAME, gvar->name, LEN_GVAR_NAME, event, attr);
break;
case GVAR_FIELD_UNIT:
gvar->unit = selectMenuItem(GVAR_2ND_COLUMN, y, STR_UNIT, "\001-%", gvar->unit, 0, 1, attr, event);
break;
case GVAR_FIELD_PREC:
gvar->prec = selectMenuItem(GVAR_2ND_COLUMN, y, STR_PRECISION, STR_VPREC, gvar->prec, 0, 1, attr, event);
break;
case GVAR_FIELD_MIN:
lcdDrawText(0, y, STR_MIN);
drawGVarValue(GVAR_2ND_COLUMN, y, s_currIdx, GVAR_MIN+gvar->min, LEFT|attr);
if (attr) gvar->min = checkIncDec(event, GVAR_MIN+gvar->min, GVAR_MIN, GVAR_MAX-gvar->max, EE_MODEL) - GVAR_MIN;
break;
case GVAR_FIELD_MAX:
lcdDrawText(0, y, STR_MAX);
drawGVarValue(GVAR_2ND_COLUMN, y, s_currIdx, GVAR_MAX-gvar->max, LEFT|attr);
if (attr) gvar->max = GVAR_MAX - checkIncDec(event, GVAR_MAX-gvar->max, GVAR_MIN+gvar->min, GVAR_MAX, EE_MODEL);
break;
case GVAR_FIELD_POPUP:
ON_OFF_MENU_ITEM(gvar->popup, GVAR_2ND_COLUMN, y, STR_POPUP, attr, event);
break;
default:
putsStrIdx(0, y, STR_FP, k-GVAR_FIELD_FM0);
editGVarValue(GVAR_2ND_COLUMN, y, event, s_currIdx, k-GVAR_FIELD_FM0, LEFT|attr);
break;
}
}
}
void onGVARSMenu(const char *result) void onGVARSMenu(const char *result)
{ {
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
if (result == STR_ENABLE_POPUP) { if (result == STR_EDIT) {
g_model.gvars[sub].popup = true; s_currIdx = sub;
storageDirty(EE_MODEL); pushMenu(menuModelGVarOne);
}
else if (result == STR_DISABLE_POPUP) {
g_model.gvars[sub].popup = false;
storageDirty(EE_MODEL);
} }
else if (result == STR_CLEAR) { else if (result == STR_CLEAR) {
for (int i=0; i<MAX_FLIGHT_MODES; i++) { for (int i=0; i<MAX_FLIGHT_MODES; i++) {
@ -40,16 +130,17 @@ void onGVARSMenu(const char *result)
} }
} }
#define GVARS_FM_COLUMN(p) (12*FW + FWNUM + (p)*(2+3*FWNUM) - 3) #define GVARS_COLUMNS (NAVIGATION_LINE_BY_LINE|(MAX_FLIGHT_MODES-1))
#define GVARS_FM_COLUMN(p) (7*FW + 9 + (p)*20)
void menuModelGVars(uint8_t event) void menuModelGVars(uint8_t event)
{ {
tmr10ms_t tmr10ms = get_tmr10ms(); tmr10ms_t tmr10ms = get_tmr10ms();
const char * menuTitle; const char * menuTitle;
bool first2seconds = (tmr10ms - menuEntryTime > 200); /*2 seconds*/ bool after2seconds = (tmr10ms - menuEntryTime > 200); /*2 seconds*/
if (first2seconds) { if (after2seconds) {
menuTitle = STR_GLOBAL_V; menuTitle = STR_GVARS;
for (int i=0; i<MAX_GVARS; i++) { for (int i=0; i<MAX_GVARS; i++) {
putsStrIdx(GVARS_FM_COLUMN(i)-16, 1, STR_FP, i, SMLSIZE|(getFlightMode()==i ? INVERS : 0)); putsStrIdx(GVARS_FM_COLUMN(i)-16, 1, STR_FP, i, SMLSIZE|(getFlightMode()==i ? INVERS : 0));
} }
@ -58,66 +149,39 @@ void menuModelGVars(uint8_t event)
menuTitle = STR_MENUGLOBALVARS; menuTitle = STR_MENUGLOBALVARS;
} }
MENU_FLAGS(menuTitle, menuTabModel, e_GVars, first2seconds ? CHECK_FLAG_NO_SCREEN_INDEX : 0, MAX_GVARS, { NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES, NAVIGATION_LINE_BY_LINE|MAX_FLIGHT_MODES }); MENU_FLAGS(menuTitle, menuTabModel, e_GVars, after2seconds ? CHECK_FLAG_NO_SCREEN_INDEX : 0, MAX_GVARS, { GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS, GVARS_COLUMNS });
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
for (int l=0; l<LCD_LINES-1; l++) { for (int l=0; l<NUM_BODY_LINES; l++) {
int i = l+menuVerticalOffset; int i = l + menuVerticalOffset;
coord_t y = MENU_HEADER_HEIGHT + 1 + l*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + l*FH;
if (g_model.gvars[i].popup) lcdDrawChar(3*FW, y, '!'); drawGVarName(0, y, i, (sub==i && menuHorizontalPosition<0) ? INVERS : 0);
putsStrIdx(0, y, STR_GV, i+1, (sub==i && menuHorizontalPosition<0) ? INVERS : 0);
for (int j=0; j<1+MAX_FLIGHT_MODES; j++) { for (int j=0; j<MAX_FLIGHT_MODES; j++) {
LcdFlags attr = ((sub==i && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); FlightModeData * fm = &g_model.flightModeData[j];
coord_t x = GVARS_FM_COLUMN(j-1); gvar_t v = fm->gvars[i];
switch(j) LcdFlags attr = ((sub == i && menuHorizontalPosition == j) ? (s_editMode > 0 ? BLINK | INVERS : INVERS) : 0);
{ coord_t x = GVARS_FM_COLUMN(j);
case 0: if (v > GVAR_MAX) {
editName(4*FW-3, y, g_model.gvars[i].name, LEN_GVAR_NAME, event, attr); x -= 16;
break; attr |= SMLSIZE;
default:
{
FlightModeData *fm = &g_model.flightModeData[j-1];
int16_t & v = fm->gvars[i];
int16_t vmin, vmax;
if (v > GVAR_MAX) {
uint8_t p = v - GVAR_MAX - 1;
if (p >= j-1) p++;
putsFlightMode(x-15, y, p+1, attr|SMLSIZE);
vmin = GVAR_MAX+1; vmax = GVAR_MAX+MAX_FLIGHT_MODES-1;
}
else {
if (abs(v) >= 100)
lcdDrawNumber(x, y+1, v, attr | TINSIZE);
else
lcdDrawNumber(x, y, v, attr);
vmin = -GVAR_MAX; vmax = GVAR_MAX;
}
if (attr) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
v = (v > GVAR_MAX ? 0 : GVAR_MAX+1);
storageDirty(EE_MODEL);
}
else if (s_editMode>0) {
v = checkIncDec(event, v, vmin, vmax, EE_MODEL);
}
}
break;
}
} }
else if (g_model.gvars[i].prec > 0 || abs(v) >= 100) {
attr |= TINSIZE | NO_UNIT;
}
else {
attr |= SMLSIZE | NO_UNIT;
}
editGVarValue(x, y, event, i, j, attr);
} }
} }
if (menuHorizontalPosition < 0 && event==EVT_KEY_LONG(KEY_ENTER)) { if (menuHorizontalPosition<0 && event==EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event); killEvents(event);
if (g_model.gvars[sub].popup) POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_DISABLE_POPUP);
else
POPUP_MENU_ADD_ITEM(STR_ENABLE_POPUP);
POPUP_MENU_ADD_ITEM(STR_CLEAR); POPUP_MENU_ADD_ITEM(STR_CLEAR);
popupMenuHandler = onGVARSMenu; popupMenuHandler = onGVARSMenu;
} }

View file

@ -32,7 +32,7 @@ enum menuModelHeliItems {
ITEM_HELI_MAX ITEM_HELI_MAX
}; };
#define MODEL_HELI_2ND_COLUMN (LCD_W-17*FW-MENUS_SCROLLBAR_WIDTH) #define MODEL_HELI_2ND_COLUMN (LCD_W-17*FW-MENUS_SCROLLBAR_WIDTH)
void menuModelHeli(uint8_t event) void menuModelHeli(uint8_t event)
{ {
@ -42,7 +42,7 @@ void menuModelHeli(uint8_t event)
for (unsigned int i=0; i<NUM_BODY_LINES; i++) { for (unsigned int i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
int k = i+menuVerticalOffset; int k = i + menuVerticalOffset;
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (sub == k ? blink : 0); LcdFlags attr = (sub == k ? blink : 0);
@ -92,7 +92,6 @@ void menuModelHeli(uint8_t event)
lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveWeight, LEFT|attr); lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveWeight, LEFT|attr);
if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.collectiveWeight, -100, 100); if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.collectiveWeight, -100, 100);
break; break;
} }
} }
} }

View file

@ -0,0 +1,574 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90)
#define EXPO_ONE_FM_WIDTH (9*FW)
int16_t expoFn(int16_t x)
{
ExpoData * ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
applyExpos(anas, e_perout_mode_inactive_flight_mode, ed->srcRaw, x);
return anas[ed->chn];
}
void drawFunction(FnFuncP fn, uint8_t offset)
{
lcdDrawVerticalLine(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee);
coord_t prev_yv = (coord_t)-1;
for (int xv=-WCHART; xv<=WCHART; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX);
if (prev_yv != (coord_t)-1) {
if (abs((int8_t)yv-prev_yv) <= 1) {
lcdDrawPoint(X0+xv-offset-1, prev_yv, FORCE);
}
else {
uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv);
}
}
prev_yv = yv;
}
}
uint8_t getExposCount()
{
uint8_t count = 0;
uint8_t ch ;
for (int i=MAX_EXPOS-1 ; i>=0; i--) {
ch = EXPO_VALID(expoAddress(i));
if (ch != 0) {
count++;
}
}
return count;
}
bool reachExposLimit()
{
if (getExposCount() >= MAX_EXPOS) {
POPUP_WARNING(STR_NOFREEEXPO);
return true;
}
return false;
}
void deleteExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
int input = expo->chn;
memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData));
if (!isInputAvailable(input)) {
memclear(&g_model.inputNames[input], LEN_INPUT_NAME);
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
// TODO avoid this global s_currCh on ARM boards ...
int8_t s_currCh;
void insertExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(expo, sizeof(ExpoData));
expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
expo->curve.type = CURVE_REF_EXPO;
expo->mode = 3; // pos+neg
expo->chn = s_currCh - 1;
expo->weight = 100;
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyExpo(uint8_t idx)
{
pauseMixerCalculations();
ExpoData * expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
bool swapExpos(uint8_t & idx, uint8_t up)
{
ExpoData * x, * y;
int8_t tgt_idx = (up ? idx-1 : idx+1);
x = expoAddress(idx);
if (tgt_idx < 0) {
if (x->chn == 0)
return false;
x->chn--;
return true;
}
if (tgt_idx == MAX_EXPOS) {
if (x->chn == NUM_INPUTS-1)
return false;
x->chn++;
return true;
}
y = expoAddress(tgt_idx);
if (x->chn != y->chn || !EXPO_VALID(y)) {
if (up) {
if (x->chn>0) x->chn--;
else return false;
}
else {
if (x->chn<NUM_INPUTS-1) x->chn++;
else return false;
}
return true;
}
pauseMixerCalculations();
memswap(x, y, sizeof(ExpoData));
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum ExposFields {
EXPO_FIELD_INPUT_NAME,
EXPO_FIELD_NAME,
EXPO_FIELD_SOURCE,
EXPO_FIELD_SCALE,
EXPO_FIELD_WEIGHT,
EXPO_FIELD_OFFSET,
CASE_CURVES(EXPO_FIELD_CURVE)
CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES)
EXPO_FIELD_SWITCH,
EXPO_FIELD_SIDE,
EXPO_FIELD_TRIM,
EXPO_FIELD_MAX
};
#define CURVE_ROWS 1
void menuModelExpoOne(uint8_t event)
{
if (event == EVT_KEY_LONG(KEY_MENU)) {
pushMenu(menuChannelsView);
killEvents(event);
}
ExpoData * ed = expoAddress(s_currIdx);
putsMixerSource(PSIZE(TR_MENUINPUTS)*FW+FW, 0, MIXSRC_FIRST_INPUT+ed->chn, 0);
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW);
int8_t sub = menuVerticalPosition;
coord_t y = MENU_HEADER_HEIGHT + 1;
for (unsigned int k=0; k<NUM_BODY_LINES; k++) {
int i = k + menuVerticalOffset;
for (int j=0; j<=i; ++j) {
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
++i;
}
}
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case EXPO_FIELD_INPUT_NAME:
editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr);
break;
case EXPO_FIELD_NAME:
editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr);
break;
case EXPO_FIELD_SOURCE:
lcd_putsLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr);
if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
break;
case EXPO_FIELD_SCALE:
lcd_putsLeft(y, STR_SCALE);
putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr);
if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
break;
case EXPO_FIELD_WEIGHT:
lcd_putsLeft(y, STR_WEIGHT);
ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event);
break;
case EXPO_FIELD_OFFSET:
lcd_putsLeft(y, NO_INDENT(STR_OFFSET));
ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event);
break;
#if defined(CURVES)
case EXPO_FIELD_CURVE:
lcd_putsLeft(y, STR_CURVE);
editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case EXPO_FIELD_FLIGHT_MODES:
ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
break;
#endif
case EXPO_FIELD_SWITCH:
ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event);
break;
case EXPO_FIELD_SIDE:
ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event);
break;
case EXPO_FIELD_TRIM:
uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
int8_t carryTrim = -ed->carryTrim;
lcd_putsLeft(y, STR_TRIM);
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, menuHorizontalPosition==0 ? attr : 0);
if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
break;
}
y += FH;
}
drawFunction(expoFn);
int x512 = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannelValue(LCD_W-8, 6*FH, (ed->srcRaw - MIXSRC_FIRST_TELEM) / 3, x512, 0);
if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
}
else {
lcdDrawNumber(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1);
}
x512 = limit(-1024, x512, 1024);
int y512 = expoFn(x512);
y512 = limit(-1024, y512, 1024);
lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1);
x512 = X0+x512/(RESX/WCHART);
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
lcdDrawSolidVerticalLine(x512, y512-3, 3*2+1);
lcdDrawSolidHorizontalLine(x512-3, y512, 3*2+1);
}
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define EXPO_LINE_WEIGHT_POS 8*FW+8
#define EXPO_LINE_SRC_POS 9*FW+3
#define EXPO_LINE_CURVE_POS 12*FW+11
#define EXPO_LINE_TRIM_POS 19*FW-4
#define EXPO_LINE_SWITCH_POS 20*FW-1
#define EXPO_LINE_SIDE_POS 25*FW
#define EXPO_LINE_FM_POS 12*FW+11
#define EXPO_LINE_SELECT_POS 5*FW+2
#define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH
void onExposMenu(const char * result)
{
uint8_t chn = expoAddress(s_currIdx)->chn + 1;
if (result == STR_EDIT) {
pushMenu(menuModelExpoOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachExposLimit()) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteExpo(s_currIdx);
}
}
void displayExpoInfos(coord_t y, ExpoData *ed)
{
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0);
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
}
void displayExpoLine(coord_t y, ExpoData *ed)
{
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0);
if (ed->carryTrim != TRIM_ON) {
lcdDrawChar(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]);
}
if (!ed->flightModes || ((ed->curve.value || ed->swtch) && ((get_tmr10ms() / 200) & 1)))
displayExpoInfos(y, ed);
else
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes);
if (ed->name[0]) {
lcdDrawSizedText(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR);
}
}
void menuModelExposAll(uint8_t event)
{
uint8_t sub = menuVerticalPosition;
if (s_editMode > 0) {
s_editMode = 0;
}
uint8_t chn = expoAddress(s_currIdx)->chn + 1;
switch (event) {
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteExpo(s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteExpo(s_currIdx);
}
else {
do {
swapExpos(s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(menuModelExpoOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachExposLimit()) break;
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onExposMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachExposLimit()) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertExpo(s_currIdx);
pushMenu(menuModelExpoOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = (key==KEY_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachExposLimit()) break;
copyExpo(s_currIdx);
if (key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteExpo(s_currIdx);
if (key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapExpos(s_currIdx, key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
lcdDrawNumber(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, getExposCount());
lcdDrawText(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, STR_MAX(MAX_EXPOS));
// Value
uint8_t index = expoAddress(s_currIdx)->chn;
if (!s_currCh) {
lcdDrawNumber(127, 2, calcRESXto1000(anas[index]), PREC1|TINSIZE);
}
SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, s_maxLines);
// Gauge
if (!s_currCh) {
drawGauge(127, 1, 58, 6, anas[index], 1024);
}
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=NUM_INPUTS; ch++) {
ExpoData * ed;
coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH;
if (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(0, y, ch, 0);
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(18, y-1, LCD_W-18, 9, DOTTED);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0);
displayExpoLine(y, ed);
if (ed->mode!=3) {
lcdDrawChar(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127);
}
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lcdDrawRect(EXPO_LINE_SELECT_POS, y-1, LCD_W-EXPO_LINE_SELECT_POS, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lcdDrawFilledRect(EXPO_LINE_SELECT_POS+1, y, LCD_W-EXPO_LINE_SELECT_POS-2, 7);
}
}
}
cur++; y+=FH; mixCnt++; i++; ed++;
} while (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed));
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(EXPO_LINE_SELECT_POS, y-1, LCD_W-EXPO_LINE_SELECT_POS, 9, DOTTED);
cur++;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(0, y, ch, attr);
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lcdDrawRect(EXPO_LINE_SELECT_POS, y-1, LCD_W-EXPO_LINE_SELECT_POS, 9, DOTTED);
}
}
cur++;
}
}
s_maxLines = cur;
if (sub >= s_maxLines-1) menuVerticalPosition = s_maxLines-1;
}

View file

@ -1,964 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90)
#define EXPO_ONE_FM_WIDTH (9*FW)
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
lcd_putsColumnLeft(x, y, STR_FLMODE);
int posHorz = menuHorizontalPosition;
for (int p=0; p<MAX_FLIGHT_MODES; p++) {
LcdFlags flags = 0;
if (attr) {
flags |= INVERS;
if (posHorz==p) flags |= BLINK;
}
if (value & (1<<p))
lcdDrawChar(x, y, ' ', flags|FIXEDWIDTH);
else
lcdDrawChar(x, y, '0'+p, flags);
x += FW;
}
if (attr) {
if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
#else
#define displayFlightModes(...)
#endif
int16_t expoFn(int16_t x)
{
ExpoData *ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
applyExpos(anas, e_perout_mode_inactive_flight_mode, ed->srcRaw, x);
return anas[ed->chn];
}
void drawFunction(FnFuncP fn, uint8_t offset)
{
lcdDrawVerticalLine(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee);
coord_t prev_yv = (coord_t)-1;
for (int xv=-WCHART; xv<=WCHART; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX);
if (prev_yv != (coord_t)-1) {
if (abs((int8_t)yv-prev_yv) <= 1) {
lcdDrawPoint(X0+xv-offset-1, prev_yv, FORCE);
}
else {
uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv);
}
}
prev_yv = yv;
}
}
uint8_t getExpoMixCount(uint8_t expo)
{
uint8_t count = 0;
uint8_t ch ;
for (int i=(expo ? MAX_EXPOS-1 : MAX_MIXERS-1); i>=0; i--) {
ch = (expo ? EXPO_VALID(expoAddress(i)) : mixAddress(i)->srcRaw);
if (ch != 0) {
count++;
}
}
return count;
}
bool reachExpoMixCountLimit(uint8_t expo)
{
// check mixers count limit
if (getExpoMixCount(expo) >= (expo ? MAX_EXPOS : MAX_MIXERS)) {
POPUP_WARNING(expo ? STR_NOFREEEXPO : STR_NOFREEMIXER);
return true;
}
return false;
}
void deleteExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
int input = expo->chn;
memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData));
if (!isInputAvailable(input)) {
memclear(&g_model.inputNames[input], LEN_INPUT_NAME);
}
}
else {
MixData *mix = mixAddress(idx);
memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData));
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
// TODO avoid this global s_currCh on ARM boards ...
int8_t s_currCh;
void insertExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
memclear(expo, sizeof(ExpoData));
expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
expo->curve.type = CURVE_REF_EXPO;
expo->mode = 3; // pos&neg
expo->chn = s_currCh - 1;
expo->weight = 100;
}
else {
MixData *mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(mix, sizeof(MixData));
mix->destCh = s_currCh-1;
mix->srcRaw = s_currCh;
if (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
while (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw += 1;
}
}
mix->weight = 100;
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyExpoMix(uint8_t expo, uint8_t idx)
{
pauseMixerCalculations();
if (expo) {
ExpoData *expo = expoAddress(idx);
memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData));
}
else {
MixData *mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
}
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void memswap(void *a, void *b, uint8_t size)
{
uint8_t *x = (uint8_t*)a;
uint8_t *y = (uint8_t*)b;
uint8_t temp ;
while (size--) {
temp = *x;
*x++ = *y;
*y++ = temp;
}
}
bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
{
void *x, *y;
uint8_t size;
int8_t tgt_idx = (up ? idx-1 : idx+1);
if (expo) {
x = (ExpoData *)expoAddress(idx);
if (tgt_idx < 0) {
if (((ExpoData *)x)->chn == 0)
return false;
((ExpoData *)x)->chn--;
return true;
}
if (tgt_idx == MAX_EXPOS) {
if (((ExpoData *)x)->chn == NUM_INPUTS-1)
return false;
((ExpoData *)x)->chn++;
return true;
}
y = (ExpoData *)expoAddress(tgt_idx);
if(((ExpoData *)x)->chn != ((ExpoData *)y)->chn || !EXPO_VALID((ExpoData *)y)) {
if (up) {
if (((ExpoData *)x)->chn>0) ((ExpoData *)x)->chn--;
else return false;
}
else {
if (((ExpoData *)x)->chn<NUM_INPUTS-1) ((ExpoData *)x)->chn++;
else return false;
}
return true;
}
size = sizeof(ExpoData);
}
else {
x = (MixData *)mixAddress(idx);
if (tgt_idx < 0) {
if (((MixData *)x)->destCh == 0)
return false;
((MixData *)x)->destCh--;
return true;
}
if (tgt_idx == MAX_MIXERS) {
if (((MixData *)x)->destCh == NUM_CHNOUT-1)
return false;
((MixData *)x)->destCh++;
return true;
}
y = (MixData *)mixAddress(tgt_idx);
uint8_t destCh = ((MixData *)x)->destCh;
if(!((MixData *)y)->srcRaw || destCh != ((MixData *)y)->destCh) {
if (up) {
if (destCh>0) ((MixData *)x)->destCh--;
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) ((MixData *)x)->destCh++;
else return false;
}
return true;
}
size = sizeof(MixData);
}
pauseMixerCalculations();
memswap(x, y, size);
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum ExposFields {
EXPO_FIELD_INPUT_NAME,
EXPO_FIELD_NAME,
EXPO_FIELD_SOURCE,
EXPO_FIELD_SCALE,
EXPO_FIELD_WEIGHT,
EXPO_FIELD_OFFSET,
CASE_CURVES(EXPO_FIELD_CURVE)
CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES)
EXPO_FIELD_SWITCH,
EXPO_FIELD_SIDE,
EXPO_FIELD_TRIM,
EXPO_FIELD_MAX
};
#define CURVE_ROWS 1
void menuModelExpoOne(uint8_t event)
{
if (event == EVT_KEY_LONG(KEY_MENU)) {
pushMenu(menuChannelsView);
killEvents(event);
}
ExpoData *ed = expoAddress(s_currIdx);
putsMixerSource(7*FW+FW/2, 0, MIXSRC_FIRST_INPUT+ed->chn, 0);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW);
int8_t sub = menuVerticalPosition;
coord_t y = MENU_HEADER_HEIGHT + 1;
for (unsigned int k=0; k<NUM_BODY_LINES; k++) {
int i = k + menuVerticalOffset;
for (int j=0; j<=i; ++j) {
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
++i;
}
}
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i)
{
case EXPO_FIELD_INPUT_NAME:
editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr);
break;
case EXPO_FIELD_NAME:
editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr);
break;
case EXPO_FIELD_SOURCE:
lcd_putsLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr);
if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
break;
case EXPO_FIELD_SCALE:
lcd_putsLeft(y, STR_SCALE);
putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr);
if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
break;
case EXPO_FIELD_WEIGHT:
lcd_putsLeft(y, STR_WEIGHT);
ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event);
break;
case EXPO_FIELD_OFFSET:
lcd_putsLeft(y, NO_INDENT(STR_OFFSET));
ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event);
break;
#if defined(CURVES)
case EXPO_FIELD_CURVE:
lcd_putsLeft(y, STR_CURVE);
editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case EXPO_FIELD_FLIGHT_MODES:
ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
break;
#endif
case EXPO_FIELD_SWITCH:
ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event);
break;
case EXPO_FIELD_SIDE:
ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event);
break;
case EXPO_FIELD_TRIM:
uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
int8_t carryTrim = -ed->carryTrim;
lcd_putsLeft(y, STR_TRIM);
lcdDrawTextAtIndex(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, menuHorizontalPosition==0 ? attr : 0);
if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
break;
}
y += FH;
}
drawFunction(expoFn);
int x512 = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannelValue(LCD_W-8, 6*FH, (ed->srcRaw - MIXSRC_FIRST_TELEM) / 3, x512, 0);
if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
}
else {
lcdDrawNumber(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1);
}
x512 = limit(-1024, x512, 1024);
int y512 = expoFn(x512);
y512 = limit(-1024, y512, 1024);
lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1);
x512 = X0+x512/(RESX/WCHART);
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
lcdDrawSolidVerticalLine(x512, y512-3, 3*2+1);
lcdDrawSolidHorizontalLine(x512-3, y512, 3*2+1);
}
enum MixFields {
MIX_FIELD_NAME,
MIX_FIELD_SOURCE,
MIX_FIELD_WEIGHT,
MIX_FIELD_OFFSET,
MIX_FIELD_TRIM,
CASE_CURVES(MIX_FIELD_CURVE)
CASE_FLIGHT_MODES(MIX_FIELD_FLIGHT_PHASE)
MIX_FIELD_SWITCH,
MIX_FIELD_WARNING,
MIX_FIELD_MLTPX,
MIX_FIELD_DELAY_UP,
MIX_FIELD_DELAY_DOWN,
MIX_FIELD_SLOW_UP,
MIX_FIELD_SLOW_DOWN,
MIX_FIELD_COUNT
};
void gvarWeightItem(coord_t x, coord_t y, MixData *md, uint8_t attr, uint8_t event)
{
u_int8int16_t weight;
MD_WEIGHT_TO_UNION(md, weight);
weight.word = GVAR_MENU_ITEM(x, y, weight.word, GV_RANGELARGE_WEIGHT_NEG, GV_RANGELARGE_WEIGHT, attr, 0, event);
MD_UNION_TO_WEIGHT(weight, md);
}
#define GAUGE_WIDTH 33
#define GAUGE_HEIGHT 6
void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
{
int offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
int weight = abs(GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode));
int barMin = offset - weight;
int barMax = offset + weight;
if (y > 15) {
lcdDrawNumber(x-((barMin >= 0) ? 2 : 3), y-6, barMin, TINSIZE|LEFT);
lcdDrawNumber(x+GAUGE_WIDTH+1, y-6, barMax, TINSIZE);
}
if (barMin < -101)
barMin = -101;
if (barMax > 101)
barMax = 101;
lcdDrawHorizontalLine(x-2, y, GAUGE_WIDTH+2, DOTTED);
lcdDrawHorizontalLine(x-2, y+GAUGE_HEIGHT, GAUGE_WIDTH+2, DOTTED);
lcdDrawSolidVerticalLine(x-2, y+1, GAUGE_HEIGHT-1);
lcdDrawSolidVerticalLine(x+GAUGE_WIDTH-1, y+1, GAUGE_HEIGHT-1);
if (barMin <= barMax) {
int8_t right = (barMax * GAUGE_WIDTH) / 200;
int8_t left = ((barMin * GAUGE_WIDTH) / 200)-1;
lcdDrawFilledRect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3);
}
lcdDrawSolidVerticalLine(x+GAUGE_WIDTH/2-1, y, GAUGE_HEIGHT+1);
if (barMin == -101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+i, y+4-i);
lcdDrawPoint(x+3+i, y+4-i);
}
}
if (barMax == 101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+GAUGE_WIDTH-8+i, y+4-i);
lcdDrawPoint(x+GAUGE_WIDTH-5+i, y+4-i);
}
}
}
#undef GAUGE_WIDTH
#undef GAUGE_HEIGHT
void menuModelMixOne(uint8_t event)
{
if (event == EVT_KEY_LONG(KEY_MENU)) {
pushMenu(menuChannelsView);
killEvents(event);
}
TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX);
MixData *md2 = mixAddress(s_currIdx) ;
putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0);
SUBMENU_NOTITLE(MIX_FIELD_COUNT, {0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/});
#if MENU_COLUMNS > 1
lcdDrawSolidVerticalLine(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1);
SET_SCROLLBAR_X(0);
#endif
int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode;
for (int k=0; k<MENU_COLUMNS*(LCD_LINES-1); k++) {
coord_t y;
coord_t COLUMN_X;
if (k >= LCD_LINES-1) {
y = 1 + (k-LCD_LINES+2)*FH;
COLUMN_X = MENU_COLUMN2_X;
}
else {
y = 1 + (k+1)*FH;
COLUMN_X = 0;
}
int8_t i = k;
#if MENU_COLUMNS < 2
i = i + menuVerticalOffset;
#endif
LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case MIX_FIELD_NAME:
editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr);
break;
case MIX_FIELD_SOURCE:
lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_SOURCE));
putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break;
case MIX_FIELD_WEIGHT:
lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT);
gvarWeightItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2, attr|LEFT, event);
break;
case MIX_FIELD_OFFSET:
{
lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET));
u_int8int16_t offset;
MD_OFFSET_TO_UNION(md2, offset);
offset.word = GVAR_MENU_ITEM(COLUMN_X+MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event);
MD_UNION_TO_OFFSET(offset, md2);
drawOffsetBar(COLUMN_X+MIXES_2ND_COLUMN+22, y, md2);
break;
}
case MIX_FIELD_TRIM:
lcd_putsColumnLeft(COLUMN_X, y, STR_TRIM);
menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN, y, !md2->carryTrim, attr);
if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1);
break;
#if defined(CURVES)
case MIX_FIELD_CURVE:
{
lcd_putsColumnLeft(COLUMN_X, y, STR_CURVE);
editCurveRef(COLUMN_X+MIXES_2ND_COLUMN, y, md2->curve, event, attr);
break;
}
#endif
#if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_PHASE:
md2->flightModes = editFlightModes(COLUMN_X+MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break;
#endif
case MIX_FIELD_SWITCH:
md2->swtch = switchMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->swtch, attr, event);
break;
case MIX_FIELD_WARNING:
lcd_putsColumnLeft(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXWARNING);
if (md2->mixWarn)
lcdDrawNumber(COLUMN_X+MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT);
else
lcdDrawText(COLUMN_X+MIXES_2ND_COLUMN, y, STR_OFF, attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3);
break;
case MIX_FIELD_MLTPX:
md2->mltpx = selectMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MULTPX, STR_VMLTPX, md2->mltpx, 0, 2, attr, event);
break;
case MIX_FIELD_DELAY_UP:
md2->delayUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYUP, md2->delayUp);
break;
case MIX_FIELD_DELAY_DOWN:
md2->delayDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYDOWN, md2->delayDown);
break;
case MIX_FIELD_SLOW_UP:
md2->speedUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWUP, md2->speedUp);
break;
case MIX_FIELD_SLOW_DOWN:
md2->speedDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWDOWN, md2->speedDown);
break;
}
}
}
static uint8_t s_maxLines = 8;
static uint8_t s_copySrcIdx;
static uint8_t s_copySrcCh;
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define EXPO_LINE_WEIGHT_POS 8*FW+8
#define EXPO_LINE_SRC_POS 9*FW+3
#define EXPO_LINE_CURVE_POS 12*FW+11
#define EXPO_LINE_TRIM_POS 19*FW-4
#define EXPO_LINE_SWITCH_POS 20*FW-1
#define EXPO_LINE_SIDE_POS 25*FW
#define EXPO_LINE_FM_POS 12*FW+11
#define EXPO_LINE_SELECT_POS 5*FW+2
#define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH
#define MIX_LINE_WEIGHT_POS 6*FW+8
#define MIX_LINE_SRC_POS 7*FW+3
#define MIX_LINE_CURVE_POS 13*FW+3
#define MIX_LINE_SWITCH_POS 19*FW+1
#define MIX_LINE_FM_POS 13*FW+3
#define MIX_LINE_DELAY_POS 24*FW+3
void onExpoMixMenu(const char *result)
{
bool expo = (menuHandlers[menuLevel] == menuModelExposAll);
uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1);
if (result == STR_EDIT) {
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachExpoMixCountLimit(expo)) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteExpoMix(expo, s_currIdx);
}
}
void displayHeaderChannelName(uint8_t ch)
{
uint8_t len = zlen(g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name));
if (len) {
lcdDrawSizedText(80, 1, g_model.limitData[ch].name, len, ZCHAR|SMLSIZE);
}
}
void displayMixInfos(coord_t y, MixData *md)
{
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0);
if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch);
}
}
void displayMixLine(coord_t y, MixData *md)
{
if (md->name[0])
lcdDrawSizedText(EXPO_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR);
if (!md->flightModes || ((md->curve.value || md->swtch) && ((get_tmr10ms() / 200) & 1)))
displayMixInfos(y, md);
else
displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes);
}
void displayExpoInfos(coord_t y, ExpoData *ed)
{
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0);
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
}
void displayExpoLine(coord_t y, ExpoData *ed)
{
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0);
if (ed->carryTrim != TRIM_ON) {
lcdDrawChar(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]);
}
if (!ed->flightModes || ((ed->curve.value || ed->swtch) && ((get_tmr10ms() / 200) & 1)))
displayExpoInfos(y, ed);
else
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes);
if (ed->name[0]) {
lcdDrawSizedText(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR);
}
}
void menuModelExpoMix(uint8_t expo, uint8_t event)
{
uint8_t sub = menuVerticalPosition;
if (s_editMode > 0)
s_editMode = 0;
uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1);
switch (event)
{
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteExpoMix(expo, s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteExpoMix(expo, s_currIdx);
}
else {
do {
swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachExpoMixCountLimit(expo)) break;
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onExpoMixMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachExpoMixCountLimit(expo)) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertExpoMix(expo, s_currIdx);
pushMenu(expo ? menuModelExpoOne : menuModelMixOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = (key==KEY_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachExpoMixCountLimit(expo)) break;
copyExpoMix(expo, s_currIdx);
if (key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteExpoMix(expo, s_currIdx);
if (key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapExpoMix(expo, s_currIdx, key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
if (expo) {
lcdDrawNumber(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, getExpoMixCount(true));
lcdDrawText(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, STR_MAX(MAX_EXPOS));
// Value
uint8_t index = expoAddress(s_currIdx)->chn;
if (!s_currCh) {
lcdDrawNumber(127, 2, calcRESXto1000(anas[index]), PREC1|TINSIZE);
}
SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, s_maxLines);
// Gauge
if (!s_currCh) {
drawGauge(127, 1, 58, 6, anas[index], 1024);
}
}
else {
lcdDrawNumber(FW*sizeof(TR_MIXER)+FW+FW/2, 0, getExpoMixCount(false));
lcdDrawText(FW*sizeof(TR_MIXER)+FW+FW/2, 0, STR_MAX(MAX_MIXERS));
// Value
uint8_t index = mixAddress(s_currIdx)->destCh;
if (!s_currCh) {
displayHeaderChannelName(index);
lcdDrawNumber(127, 2, calcRESXto1000(ex_chans[index]), PREC1|TINSIZE);
}
SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, s_maxLines);
// Gauge
if (!s_currCh) {
drawGauge(127, 1, 58, 6, ex_chans[index], 1024);
}
}
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) {
void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer;
coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH;
if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
if (expo) {
putsMixerSource(0, y, ch, 0);
}
else {
putsChn(0, y, ch, 0); // show CHx
}
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(expo ? 18 : 22, y-1, expo ? LCD_W-18 : LCD_W-22, 9, DOTTED);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
if (expo) {
GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0);
displayExpoLine(y, ed);
if (ed->mode!=3) {
lcdDrawChar(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127);
}
}
else {
if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), 0);
displayMixLine(y, md);
char cs = ' ';
if (md->speedDown || md->speedUp)
cs = 'S';
if (md->delayUp || md->delayDown)
cs = (cs =='S' ? '*' : 'D');
lcdDrawChar(MIX_LINE_DELAY_POS, y, cs);
}
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lcdDrawRect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, s_copyMode == COPY_MODE ? SOLID : DOTTED);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lcdDrawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7);
}
}
}
cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++;
} while (expo ? (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch));
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? LCD_W-EXPO_LINE_SELECT_POS : LCD_W-22, 9, DOTTED);
cur++; y+=FH;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
if (expo) {
putsMixerSource(0, y, ch, attr);
}
else {
putsChn(0, y, ch, attr); // show CHx
}
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lcdDrawRect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED);
}
}
cur++; y+=FH;
}
}
s_maxLines = cur;
if (sub >= s_maxLines-1) menuVerticalPosition = s_maxLines-1;
}
void menuModelExposAll(uint8_t event)
{
return menuModelExpoMix(1, event);
}
void menuModelMixAll(uint8_t event)
{
return menuModelExpoMix(0, event);
}

View file

@ -0,0 +1,604 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "../../opentx.h"
uint8_t getMixesCount()
{
uint8_t count = 0;
uint8_t ch ;
for (int i=MAX_MIXERS-1; i>=0; i--) {
ch = mixAddress(i)->srcRaw;
if (ch != 0) {
count++;
}
}
return count;
}
bool reachMixesLimit()
{
if (getMixesCount() >= MAX_MIXERS) {
POPUP_WARNING(STR_NOFREEMIXER);
return true;
}
return false;
}
void deleteMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void insertMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
memclear(mix, sizeof(MixData));
mix->destCh = s_currCh-1;
mix->srcRaw = s_currCh;
if (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh));
while (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw += 1;
}
}
mix->weight = 100;
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
void copyMix(uint8_t idx)
{
pauseMixerCalculations();
MixData * mix = mixAddress(idx);
memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
bool swapMixes(uint8_t & idx, uint8_t up)
{
MixData * x, * y;
int8_t tgt_idx = (up ? idx-1 : idx+1);
x = mixAddress(idx);
if (tgt_idx < 0) {
if (x->destCh == 0)
return false;
x->destCh--;
return true;
}
if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1)
return false;
x->destCh++;
return true;
}
y = mixAddress(tgt_idx);
uint8_t destCh = x->destCh;
if(!y->srcRaw || destCh != y->destCh) {
if (up) {
if (destCh>0) x->destCh--;
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) x->destCh++;
else return false;
}
return true;
}
pauseMixerCalculations();
memswap(x, y, sizeof(MixData));
resumeMixerCalculations();
idx = tgt_idx;
return true;
}
enum MixFields {
MIX_FIELD_NAME,
MIX_FIELD_SOURCE,
MIX_FIELD_WEIGHT,
MIX_FIELD_OFFSET,
MIX_FIELD_TRIM,
CASE_CURVES(MIX_FIELD_CURVE)
CASE_FLIGHT_MODES(MIX_FIELD_FLIGHT_MODE)
MIX_FIELD_SWITCH,
MIX_FIELD_WARNING,
MIX_FIELD_MLTPX,
MIX_FIELD_DELAY_UP,
MIX_FIELD_DELAY_DOWN,
MIX_FIELD_SLOW_UP,
MIX_FIELD_SLOW_DOWN,
MIX_FIELD_COUNT
};
void gvarWeightItem(coord_t x, coord_t y, MixData *md, uint8_t attr, uint8_t event)
{
u_int8int16_t weight;
MD_WEIGHT_TO_UNION(md, weight);
weight.word = GVAR_MENU_ITEM(x, y, weight.word, GV_RANGELARGE_WEIGHT_NEG, GV_RANGELARGE_WEIGHT, attr, 0, event);
MD_UNION_TO_WEIGHT(weight, md);
}
void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
{
const int gaugeWidth = 33;
const int gaugeHeight = 6;
int offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
int weight = abs(GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode));
int barMin = offset - weight;
int barMax = offset + weight;
if (y > 15) {
lcdDrawNumber(x-((barMin >= 0) ? 2 : 3), y-6, barMin, TINSIZE|LEFT);
lcdDrawNumber(x+gaugeWidth+1, y-6, barMax, TINSIZE);
}
if (barMin < -101)
barMin = -101;
if (barMax > 101)
barMax = 101;
lcdDrawHorizontalLine(x-2, y, gaugeWidth+2, DOTTED);
lcdDrawHorizontalLine(x-2, y+gaugeHeight, gaugeWidth+2, DOTTED);
lcdDrawSolidVerticalLine(x-2, y+1, gaugeHeight-1);
lcdDrawSolidVerticalLine(x+gaugeWidth-1, y+1, gaugeHeight-1);
if (barMin <= barMax) {
int8_t right = (barMax * gaugeWidth) / 200;
int8_t left = ((barMin * gaugeWidth) / 200)-1;
lcdDrawFilledRect(x+gaugeWidth/2+left, y+2, right-left, gaugeHeight-3);
}
lcdDrawSolidVerticalLine(x+gaugeWidth/2-1, y, gaugeHeight+1);
if (barMin == -101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+i, y+4-i);
lcdDrawPoint(x+3+i, y+4-i);
}
}
if (barMax == 101) {
for (uint8_t i=0; i<3; ++i) {
lcdDrawPoint(x+gaugeWidth-8+i, y+4-i);
lcdDrawPoint(x+gaugeWidth-5+i, y+4-i);
}
}
}
void menuModelMixOne(uint8_t event)
{
if (event == EVT_KEY_LONG(KEY_MENU)) {
pushMenu(menuChannelsView);
killEvents(event);
}
MixData * md2 = mixAddress(s_currIdx) ;
putsChn(PSIZE(TR_MIXER)*FW+FW, 0, md2->destCh+1,0);
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SUBMENU(STR_MIXER, MIX_FIELD_COUNT, {0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/});
#if MENU_COLUMNS > 1
SET_SCROLLBAR_X(0);
#endif
int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode;
for (int k=0; k<MENU_COLUMNS*(LCD_LINES-1); k++) {
coord_t y;
if (k >= LCD_LINES-1)
y = 1 + (k-LCD_LINES+2)*FH;
else
y = 1 + (k+1)*FH;
int8_t i = k;
#if MENU_COLUMNS < 2
i = i + menuVerticalOffset;
#endif
LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case MIX_FIELD_NAME:
editSingleName(MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr);
break;
case MIX_FIELD_SOURCE:
lcd_putsLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break;
case MIX_FIELD_WEIGHT:
lcd_putsLeft(y, STR_WEIGHT);
gvarWeightItem(MIXES_2ND_COLUMN, y, md2, attr|LEFT, event);
break;
case MIX_FIELD_OFFSET:
{
lcd_putsLeft(y, NO_INDENT(STR_OFFSET));
u_int8int16_t offset;
MD_OFFSET_TO_UNION(md2, offset);
offset.word = GVAR_MENU_ITEM(MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event);
MD_UNION_TO_OFFSET(offset, md2);
drawOffsetBar(MIXES_2ND_COLUMN+22, y, md2);
break;
}
case MIX_FIELD_TRIM:
lcd_putsLeft(y, STR_TRIM);
drawCheckBox(MIXES_2ND_COLUMN, y, !md2->carryTrim, attr);
if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1);
break;
#if defined(CURVES)
case MIX_FIELD_CURVE:
lcd_putsLeft(y, STR_CURVE);
editCurveRef(MIXES_2ND_COLUMN, y, md2->curve, event, attr);
break;
#endif
#if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_MODE:
md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break;
#endif
case MIX_FIELD_SWITCH:
md2->swtch = switchMenuItem(MENU_COLUMN2_X+MIXES_2ND_COLUMN, y, md2->swtch, attr, event);
break;
case MIX_FIELD_WARNING:
lcd_putsColumnLeft(MENU_COLUMN2_X+MIXES_2ND_COLUMN, y, STR_MIXWARNING);
if (md2->mixWarn)
lcdDrawNumber(MENU_COLUMN2_X+MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT);
else
lcdDrawText(MENU_COLUMN2_X+MIXES_2ND_COLUMN, y, STR_OFF, attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3);
break;
case MIX_FIELD_MLTPX:
md2->mltpx = selectMenuItem(MENU_COLUMN2_X+MIXES_2ND_COLUMN, y, STR_MULTPX, STR_VMLTPX, md2->mltpx, 0, 2, attr, event);
break;
case MIX_FIELD_DELAY_UP:
md2->delayUp = EDIT_DELAY(MENU_COLUMN2_X, y, event, attr, STR_DELAYUP, md2->delayUp);
break;
case MIX_FIELD_DELAY_DOWN:
md2->delayDown = EDIT_DELAY(MENU_COLUMN2_X, y, event, attr, STR_DELAYDOWN, md2->delayDown);
break;
case MIX_FIELD_SLOW_UP:
md2->speedUp = EDIT_DELAY(MENU_COLUMN2_X, y, event, attr, STR_SLOWUP, md2->speedUp);
break;
case MIX_FIELD_SLOW_DOWN:
md2->speedDown = EDIT_DELAY(MENU_COLUMN2_X, y, event, attr, STR_SLOWDOWN, md2->speedDown);
break;
}
}
}
#define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x)
#define MIX_LINE_WEIGHT_POS 6*FW+10
#define MIX_LINE_SRC_POS 7*FW+5
#define MIX_LINE_CURVE_POS 13*FW+3
#define MIX_LINE_SWITCH_POS 19*FW+1
#define MIX_LINE_FM_POS 13*FW+3
#define MIX_LINE_DELAY_POS 24*FW+3
#define MIX_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH
void onMixesMenu(const char * result)
{
uint8_t chn = mixAddress(s_currIdx)->destCh + 1;
if (result == STR_EDIT) {
pushMenu(menuModelMixOne);
}
else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) {
if (!reachMixesLimit()) {
s_currCh = chn;
if (result == STR_INSERT_AFTER) { s_currIdx++; menuVerticalPosition++; }
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
}
}
else if (result == STR_COPY || result == STR_MOVE) {
s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = menuVerticalPosition;
}
else if (result == STR_DELETE) {
deleteMix(s_currIdx);
}
}
void displayHeaderChannelName(uint8_t ch)
{
uint8_t len = zlen(g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name));
if (len) {
lcdDrawSizedText(80, 1, g_model.limitData[ch].name, len, ZCHAR|SMLSIZE);
}
}
void displayMixInfos(coord_t y, MixData *md)
{
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0);
if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch);
}
}
void displayMixLine(coord_t y, MixData *md)
{
if (md->name[0])
lcdDrawSizedText(MIX_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR);
if (!md->flightModes || ((md->curve.value || md->swtch) && ((get_tmr10ms() / 200) & 1)))
displayMixInfos(y, md);
else
displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes);
}
void menuModelMixAll(uint8_t event)
{
uint8_t sub = menuVerticalPosition;
if (s_editMode > 0) {
s_editMode = 0;
}
uint8_t chn = mixAddress(s_currIdx)->destCh + 1;
switch (event) {
case EVT_ENTRY:
case EVT_ENTRY_UP:
s_copyMode = 0;
s_copyTgtOfs = 0;
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0) {
deleteMix(s_currIdx);
killEvents(event);
event = 0;
}
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
if (s_copyTgtOfs) {
// cancel the current copy / move operation
if (s_copyMode == COPY_MODE) {
deleteMix(s_currIdx);
}
else {
do {
swapMixes(s_currIdx, s_copyTgtOfs > 0);
s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1);
} while (s_copyTgtOfs != 0);
storageDirty(EE_MODEL);
}
menuVerticalPosition = s_copySrcRow;
s_copyTgtOfs = 0;
}
s_copyMode = 0;
event = 0;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
s_copySrcIdx = s_currIdx;
s_copySrcCh = chn;
s_copySrcRow = sub;
break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
if (s_copyTgtOfs) {
s_copyMode = 0;
s_copyTgtOfs = 0;
}
else {
if (READ_ONLY()) {
if (!s_currCh) {
pushMenu(menuModelMixOne);
}
}
else {
if (s_copyMode) s_currCh = 0;
if (s_currCh) {
if (reachMixesLimit()) break;
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
s_copyMode = 0;
}
else {
event = 0;
s_copyMode = 0;
POPUP_MENU_ADD_ITEM(STR_EDIT);
POPUP_MENU_ADD_ITEM(STR_INSERT_BEFORE);
POPUP_MENU_ADD_ITEM(STR_INSERT_AFTER);
POPUP_MENU_ADD_ITEM(STR_COPY);
POPUP_MENU_ADD_ITEM(STR_MOVE);
POPUP_MENU_ADD_ITEM(STR_DELETE);
popupMenuHandler = onMixesMenu;
}
}
}
break;
case EVT_KEY_LONG(KEY_LEFT):
case EVT_KEY_LONG(KEY_RIGHT):
if (s_copyMode && !s_copyTgtOfs) {
if (reachMixesLimit()) break;
s_currCh = chn;
if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; menuVerticalPosition++; }
insertMix(s_currIdx);
pushMenu(menuModelMixOne);
s_copyMode = 0;
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 (s_copyMode) {
uint8_t key = (event & 0x1f);
uint8_t next_ofs = (key==KEY_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1);
if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) {
// insert a mix on the same channel (just above / just below)
if (reachMixesLimit()) break;
copyMix(s_currIdx);
if (key==KEY_DOWN) s_currIdx++;
else if (sub-menuVerticalOffset >= 6) menuVerticalOffset++;
}
else if (next_ofs==0 && s_copyMode==COPY_MODE) {
// delete the mix
deleteMix(s_currIdx);
if (key==KEY_UP) s_currIdx--;
}
else {
// only swap the mix with its neighbor
if (!swapMixes(s_currIdx, key==KEY_UP)) break;
storageDirty(EE_MODEL);
}
s_copyTgtOfs = next_ofs;
}
break;
}
lcdDrawNumber(FW*sizeof(TR_MIXER)+FW+FW/2, 0, getMixesCount());
lcdDrawText(FW*sizeof(TR_MIXER)+FW+FW/2, 0, STR_MAX(MAX_MIXERS));
// Value
uint8_t index = mixAddress(s_currIdx)->destCh;
if (!s_currCh) {
displayHeaderChannelName(index);
lcdDrawNumber(127, 2, calcRESXto1000(ex_chans[index]), PREC1|TINSIZE);
}
SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, s_maxLines);
// Gauge
if (!s_currCh) {
drawGauge(127, 1, 58, 6, ex_chans[index], 1024);
}
sub = menuVerticalPosition;
s_currCh = 0;
int cur = 0;
int i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) {
MixData * md;
coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH;
if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsChn(0, y, ch, 0); // show CHx
}
uint8_t mixCnt = 0;
do {
if (s_copyMode) {
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(22, y-1, LCD_W-22, 9, DOTTED);
cur++; y+=FH;
}
if (s_currIdx == i) {
sub = menuVerticalPosition = cur;
s_currCh = ch;
}
}
else if (sub == cur) {
s_currIdx = i;
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS);
if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), 0);
displayMixLine(y, md);
char cs = ' ';
if (md->speedDown || md->speedUp)
cs = 'S';
if (md->delayUp || md->delayDown)
cs = (cs =='S' ? '*' : 'D');
lcdDrawChar(MIX_LINE_DELAY_POS, y, cs);
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */
lcdDrawRect(22, y-1, LCD_W-22, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED);
}
if (cur == sub) {
/* invert the raw when it's the current one */
lcdDrawFilledRect(23, y, LCD_W-24, 7);
}
}
}
cur++; y+=FH; mixCnt++; i++; md++;
} while (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch);
if (s_copyMode == MOVE_MODE && cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
lcdDrawRect(22, y-1, LCD_W-22, 9, DOTTED);
cur++;
}
}
else {
uint8_t attr = 0;
if (sub == cur) {
s_currIdx = i;
s_currCh = ch;
if (!s_copyMode) {
attr = INVERS;
}
}
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsChn(0, y, ch, attr); // show CHx
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lcdDrawRect(22, y-1, LCD_W-22, 9, DOTTED);
}
}
cur++;
}
}
s_maxLines = cur;
if (sub >= s_maxLines-1) menuVerticalPosition = s_maxLines-1;
}

View file

@ -162,7 +162,6 @@ void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event)
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
#if defined(PCBTARANIS)
int getSwitchWarningsCount() int getSwitchWarningsCount()
{ {
int count = 0; int count = 0;
@ -173,7 +172,6 @@ int getSwitchWarningsCount()
} }
return count; return count;
} }
#endif
#if !defined(TARANIS_INTERNAL_PPM) #if !defined(TARANIS_INTERNAL_PPM)
#define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols)
@ -195,7 +193,7 @@ int getSwitchWarningsCount()
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS())) #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS()))
#define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW) #define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
#define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 #define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 #define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#if TIMERS == 1 #if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS #define TIMERS_ROWS TIMER_ROWS
#elif TIMERS == 2 #elif TIMERS == 2
@ -218,8 +216,9 @@ void menuModelSetup(uint8_t event)
horzpos_t l_posHorz = menuHorizontalPosition; horzpos_t l_posHorz = menuHorizontalPosition;
bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0); bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0);
#if defined(TARANIS_INTERNAL_PPM) #if defined(TARANIS_INTERNAL_PPM)
MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0,
NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule), LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS, INTERNAL_MODULE_CHANNELS_ROWS,
@ -300,7 +299,7 @@ void menuModelSetup(uint8_t event)
break; break;
case ITEM_MODEL_TIMER1_MINUTE_BEEP: case ITEM_MODEL_TIMER1_MINUTE_BEEP:
g_model.timers[0].minuteBeep = onoffMenuItem(g_model.timers[0].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); g_model.timers[0].minuteBeep = editCheckBox(g_model.timers[0].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
break; break;
case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP:
@ -321,7 +320,7 @@ void menuModelSetup(uint8_t event)
break; break;
case ITEM_MODEL_TIMER2_MINUTE_BEEP: case ITEM_MODEL_TIMER2_MINUTE_BEEP:
g_model.timers[1].minuteBeep = onoffMenuItem(g_model.timers[1].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); g_model.timers[1].minuteBeep = editCheckBox(g_model.timers[1].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
break; break;
case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP:
@ -343,7 +342,7 @@ void menuModelSetup(uint8_t event)
break; break;
case ITEM_MODEL_TIMER3_MINUTE_BEEP: case ITEM_MODEL_TIMER3_MINUTE_BEEP:
g_model.timers[2].minuteBeep = onoffMenuItem(g_model.timers[2].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); g_model.timers[2].minuteBeep = editCheckBox(g_model.timers[2].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
break; break;
case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP: case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP:
@ -427,7 +426,7 @@ void menuModelSetup(uint8_t event)
break; break;
case ITEM_MODEL_THROTTLE_WARNING: case ITEM_MODEL_THROTTLE_WARNING:
g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event); g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event);
break; break;
#if defined(REV9E) #if defined(REV9E)
@ -602,13 +601,14 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_USE_GLOBAL_FUNCTIONS: case ITEM_MODEL_USE_GLOBAL_FUNCTIONS:
lcd_putsLeft(y, STR_USE_GLOBAL_FUNCS); lcd_putsLeft(y, STR_USE_GLOBAL_FUNCS);
menu_lcd_onoff(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr); drawCheckBox(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr);
if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1); if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1);
break; break;
case ITEM_MODEL_INTERNAL_MODULE_LABEL: case ITEM_MODEL_INTERNAL_MODULE_LABEL:
lcd_putsLeft(y, TR_INTERNALRF); lcd_putsLeft(y, TR_INTERNALRF);
break; break;
#if defined(TARANIS_INTERNAL_PPM) #if defined(TARANIS_INTERNAL_PPM)
case ITEM_MODEL_INTERNAL_MODULE_MODE: case ITEM_MODEL_INTERNAL_MODULE_MODE:
lcd_putsLeft(y, STR_MODE); lcd_putsLeft(y, STR_MODE);

View file

@ -204,10 +204,11 @@ void menuModelSensor(uint8_t event)
{ {
TelemetrySensor * sensor = &g_model.telemetrySensors[s_currIdx]; TelemetrySensor * sensor = &g_model.telemetrySensors[s_currIdx];
SUBMENU(STR_MENUSENSOR, SENSOR_FIELD_MAX, { 0, 0, sensor->type == TELEM_TYPE_CALCULATED ? (uint8_t)0 : (uint8_t)1, SENSOR_UNIT_ROWS, SENSOR_PREC_ROWS, SENSOR_PARAM1_ROWS, SENSOR_PARAM2_ROWS, SENSOR_PARAM3_ROWS, SENSOR_PARAM4_ROWS, SENSOR_AUTOOFFSET_ROWS, SENSOR_ONLYPOS_ROWS, SENSOR_FILTER_ROWS, SENSOR_PERSISTENT_ROWS, 0 }); putsStrIdx(PSIZE(TR_MENUSENSOR)*FW+FW, 0, STR_SENSOR, s_currIdx+1);
lcdDrawNumber(PSIZE(TR_MENUSENSOR)*FW+1, 0, s_currIdx+1, INVERS|LEFT); putsTelemetryChannelValue(32*FW, 0, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx));
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
putsTelemetryChannelValue(SENSOR_2ND_COLUMN, 0, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), LEFT); SUBMENU(STR_MENUSENSOR, SENSOR_FIELD_MAX, { 0, 0, sensor->type == TELEM_TYPE_CALCULATED ? (uint8_t)0 : (uint8_t)1, SENSOR_UNIT_ROWS, SENSOR_PREC_ROWS, SENSOR_PARAM1_ROWS, SENSOR_PARAM2_ROWS, SENSOR_PARAM3_ROWS, SENSOR_PARAM4_ROWS, SENSOR_AUTOOFFSET_ROWS, SENSOR_ONLYPOS_ROWS, SENSOR_FILTER_ROWS, SENSOR_PERSISTENT_ROWS, 0 });
for (int i=0; i<NUM_BODY_LINES; i++) { for (int i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;

View file

@ -47,7 +47,7 @@ extern uint8_t noHighlightCounter;
#define NO_HIGHLIGHT() (noHighlightCounter > 0) #define NO_HIGHLIGHT() (noHighlightCounter > 0)
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr); void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
typedef void (*MenuHandlerFunc)(uint8_t event); typedef void (*MenuHandlerFunc)(uint8_t event);
@ -109,7 +109,7 @@ void menuAboutView(uint8_t event);
void menuTraceBuffer(uint8_t event); void menuTraceBuffer(uint8_t event);
#endif #endif
enum EnumTabDiag { enum EnumTabRadio {
e_Setup, e_Setup,
e_Sd, e_Sd,
e_GeneralCustomFunctions, e_GeneralCustomFunctions,
@ -263,7 +263,7 @@ swsrc_t checkIncDecMovedSwitch(swsrc_t val);
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available) CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \ #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable) var = checkIncDec(event, var, min, max, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
#define CHECK_INCDEC_GENVAR(event, var, min, max) \ #define CHECK_INCDEC_GENVAR(event, var, min, max) \
var = checkIncDecGen(event, var, min, max) var = checkIncDecGen(event, var, min, max)
@ -295,6 +295,9 @@ void title(const pm_char * s);
MENU_TAB(__VA_ARGS__); \ MENU_TAB(__VA_ARGS__); \
MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count) MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count)
#define SIMPLE_MENU_FLAGS(title, tab, menu, flags, lines_count, ...) \
check(title, event, menu, tab, DIM(tab), NULL, 0, lines_count, flags)
#define SIMPLE_MENU(title, tab, menu, lines_count) \ #define SIMPLE_MENU(title, tab, menu, lines_count) \
check_simple(title, event, menu, tab, DIM(tab), lines_count) check_simple(title, event, menu, tab, DIM(tab), lines_count)
@ -316,22 +319,20 @@ void title(const pm_char * s);
typedef int select_menu_value_t; typedef int select_menu_value_t;
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event); select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event);
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event); uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event);
swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8_t event); swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8_t event);
#define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = onoffMenuItem(value, x, y, label, attr, event) #define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
#if defined(GVARS) #if defined(GVARS)
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(x, y, v, min, max, lcdattr, editflags, event) void drawGVarName(coord_t x, coord_t y, int8_t index, LcdFlags flags=0);
#else void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags=0);
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) gvarMenuItem(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, uint8_t editflags, uint8_t event);
#endif #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
#if defined(GVARS)
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event);
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); #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, uint8_t event);
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) #define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
#endif #endif
@ -368,6 +369,18 @@ extern uint8_t s_copyMode;
extern int8_t s_copySrcRow; extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs; extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx; extern uint8_t s_currIdx;
extern uint8_t s_maxLines;
extern uint8_t s_copySrcIdx;
extern uint8_t s_copySrcCh;
extern int8_t s_currCh;
uint8_t getExposCount();
void deleteExpo(uint8_t idx);
void insertExpo(uint8_t idx);
uint8_t getMixesCount();
void deleteMix(uint8_t idx);
void insertMix(uint8_t idx);
#define MENU_X 30 #define MENU_X 30
#define MENU_Y 16 #define MENU_Y 16
@ -400,7 +413,7 @@ extern uint8_t warningInfoFlags;
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s) #define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s)
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define POPUP_MENU_ITEMS_FROM_BSS() #define POPUP_MENU_ITEMS_FROM_BSS()
extern const char *popupMenuItems[POPUP_MENU_MAX_LINES]; extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems; extern uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset; extern uint16_t popupMenuOffset;
enum { enum {

View file

@ -328,11 +328,11 @@ int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int
} }
#define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0)
#define MAXCOL_RAW(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #define MAXCOL_RAW(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0)
#define MAXCOL(row) (MAXCOL_RAW(row) >= HIDDEN_ROW ? MAXCOL_RAW(row) : (const uint8_t)(MAXCOL_RAW(row) & (~NAVIGATION_LINE_BY_LINE))) #define MAXCOL(row) (MAXCOL_RAW(row) >= HIDDEN_ROW ? MAXCOL_RAW(row) : (const uint8_t)(MAXCOL_RAW(row) & (~NAVIGATION_LINE_BY_LINE)))
#define COLATTR(row) (MAXCOL_RAW(row) == (uint8_t)-1 ? (const uint8_t)0 : (const uint8_t)(MAXCOL_RAW(row) & NAVIGATION_LINE_BY_LINE)) #define COLATTR(row) (MAXCOL_RAW(row) == (uint8_t)-1 ? (const uint8_t)0 : (const uint8_t)(MAXCOL_RAW(row) & NAVIGATION_LINE_BY_LINE))
#define INC(val, min, max) if (val<max) {val++;} else {val=min;} #define INC(val, min, max) if (val<max) {val++;} else {val=min;}
#define DEC(val, min, max) if (val>min) {val--;} else {val=max;} #define DEC(val, min, max) if (val>min) {val--;} else {val=max;}
coord_t scrollbar_X = DEFAULT_SCROLLBAR_X; coord_t scrollbar_X = DEFAULT_SCROLLBAR_X;

View file

@ -35,9 +35,9 @@ uint8_t s_menu_item = 0;
uint16_t popupMenuNoItems = 0; uint16_t popupMenuNoItems = 0;
uint16_t popupMenuOffset = 0; uint16_t popupMenuOffset = 0;
uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL; uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL;
void (*popupMenuHandler)(const char *result); void (*popupMenuHandler)(const char * result);
void displayBox(const char *title) void displayBox(const char * title)
{ {
lcdDrawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE); lcdDrawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE);
lcdDrawRect(10, 16, LCD_W-20, 40); lcdDrawRect(10, 16, LCD_W-20, 40);
@ -45,7 +45,7 @@ void displayBox(const char *title)
// could be a place for a warningInfoText // could be a place for a warningInfoText
} }
void displayPopup(const char *title) void displayPopup(const char * title)
{ {
displayBox(title); displayBox(title);
lcdRefresh(); lcdRefresh();
@ -55,7 +55,7 @@ const pm_uchar asterisk_lbm[] PROGMEM = {
#include "asterisk.lbm" #include "asterisk.lbm"
}; };
void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SOUND_ARG) void drawMessageBox(const pm_char * title, const pm_char * t, const char * last, uint8_t sound)
{ {
lcdClear(); lcdClear();
lcdDrawBitmap(0, 0, asterisk_lbm); lcdDrawBitmap(0, 0, asterisk_lbm);
@ -78,7 +78,11 @@ void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SO
} }
#undef MESSAGE_LCD_OFFSET #undef MESSAGE_LCD_OFFSET
}
void message(const pm_char * title, const pm_char * t, const char * last, uint8_t sound)
{
drawMessageBox(title, t, last, sound);
lcdRefresh(); lcdRefresh();
lcdSetContrast(); lcdSetContrast();
clearKeyEvents(); clearKeyEvents();
@ -129,7 +133,7 @@ const char * displayPopupMenu(uint8_t event)
drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuNoItems, display_count); drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuNoItems, display_count);
} }
switch(event) { switch (event) {
case EVT_KEY_FIRST(KEY_UP): case EVT_KEY_FIRST(KEY_UP):
case EVT_KEY_REPT(KEY_UP): case EVT_KEY_REPT(KEY_UP):
if (s_menu_item > 0) { if (s_menu_item > 0) {

View file

@ -489,8 +489,8 @@ void menuMainView(uint8_t event)
case EVT_KEY_FIRST(KEY_EXIT): case EVT_KEY_FIRST(KEY_EXIT):
#if defined(GVARS) #if defined(GVARS)
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer = 0; gvarDisplayTimer = 0;
} }
#endif #endif
AUDIO_KEYPAD_UP(); AUDIO_KEYPAD_UP();
@ -553,7 +553,7 @@ void menuMainView(uint8_t event)
else { else {
// Logical Switches // Logical Switches
lcdDrawText(TRIM_RH_X - TRIM_LEN/2 + 5, 6*FH-1, "LS 1-32"); lcdDrawText(TRIM_RH_X - TRIM_LEN/2 + 5, 6*FH-1, "LS 1-32");
for (int sw=0; sw<NUM_LOGICAL_SWITCH; ++sw) { for (int sw=0; sw<32; ++sw) {
div_t qr = div(sw, 10); div_t qr = div(sw, 10);
uint8_t y = 13 + 11 * qr.quot; uint8_t y = 13 + 11 * qr.quot;
uint8_t x = TRIM_RH_X - TRIM_LEN + qr.rem*5 + (qr.rem >= 5 ? 3 : 0); uint8_t x = TRIM_RH_X - TRIM_LEN + qr.rem*5 + (qr.rem >= 5 ? 3 : 0);
@ -572,14 +572,15 @@ void menuMainView(uint8_t event)
} }
#if defined(GVARS) #if defined(GVARS)
if (s_gvar_timer > 0) { if (gvarDisplayTimer > 0) {
s_gvar_timer--; gvarDisplayTimer--;
lcdDrawFilledRect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE); lcdDrawFilledRect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE);
lcdDrawRect(BITMAP_X, BITMAP_Y, 64, 32); lcdDrawRect(BITMAP_X, BITMAP_Y, 64, 32);
putsStrIdx(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, s_gvar_last+1); putsStrIdx(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, gvarLastChanged+1);
lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, ZCHAR);
lcdDrawText(BITMAP_X+FW, BITMAP_Y+2*FH+3, PSTR("[\010]"), BOLD); lcdDrawText(BITMAP_X+FW, BITMAP_Y+2*FH+3, PSTR("["), BOLD);
lcdDrawNumber(BITMAP_X+5*FW+FW/2, BITMAP_Y+2*FH+3, GVAR_VALUE(s_gvar_last, getGVarFlightPhase(mixerCurrentFlightMode, s_gvar_last)), BOLD); drawGVarValue(BITMAP_X+2*FW, BITMAP_Y+2*FH+3, gvarLastChanged, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), LEFT|BOLD);
lcdDrawText(lcdLastPos, BITMAP_Y+2*FH+3, PSTR("]"), BOLD);
} }
#endif #endif
} }

View file

@ -63,7 +63,7 @@ void drawColumnHeader(const char * const *headers, uint8_t index)
lcdDrawText(17*FW, 0, headers[index], 0); lcdDrawText(17*FW, 0, headers[index], 0);
} }
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr) void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
{ {
if (value) if (value)
lcdDrawChar(x+1, y, '#'); lcdDrawChar(x+1, y, '#');
@ -133,9 +133,9 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, c
return value; return value;
} }
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event ) uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event )
{ {
menu_lcd_onoff(x, y, value, attr); drawCheckBox(x, y, value, attr);
return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event); return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event);
} }
@ -160,12 +160,29 @@ bool noZero(int val)
return val != 0; return val != 0;
} }
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event) void drawGVarName(coord_t x, coord_t y, int8_t index, LcdFlags flags)
{
if (ZEXIST(g_model.gvars[index].name))
lcdDrawSizedText(x, y, g_model.gvars[index].name, LEN_GVAR_NAME, ZCHAR|flags);
else
putsStrIdx(x, y, STR_GV, index+1, flags);
}
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags)
{
uint8_t prec = g_model.gvars[gvar].prec;
if (prec > 0) {
flags |= (prec == 1 ? PREC1 : PREC2);
}
putsValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
}
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event)
{ {
uint16_t delta = GV_GET_GV1_VALUE(max); uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS); bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode; s_editMode = !s_editMode;
@ -198,7 +215,8 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
else { else {
value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta); value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta);
} }
putsStrIdx(x, y, STR_GV, idx, attr);
drawGVarName(x, y, idx-1, attr);
} }
else { else {
lcdDrawNumber(x, y, value, attr); lcdDrawNumber(x, y, value, attr);
@ -207,7 +225,7 @@ int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t m
return value; return value;
} }
#else #else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
{ {
lcdDrawNumber(x, y, value, attr); lcdDrawNumber(x, y, value, attr);
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);

View file

@ -11,6 +11,6 @@ macro(add_lua_export_target target)
add_custom_target(lua_export_${target} DEPENDS lua_exports_${target}.inc) add_custom_target(lua_export_${target} DEPENDS lua_exports_${target}.inc)
endmacro(add_lua_export_target) endmacro(add_lua_export_target)
add_lua_export_target(taranis -DCPUARM -DPCBTARANIS -DLUA -DVIRTUALINPUTS) add_lua_export_target(taranis -DPCBTARANIS -DLUA -DVIRTUALINPUTS)
add_lua_export_target(taranis_x9e -DCPUARM -DPCBTARANIS -DREVPLUS -DREV9E -DLUA -DVIRTUALINPUTS) add_lua_export_target(taranis_x9e -DPCBTARANIS -DREVPLUS -DREV9E -DLUA -DVIRTUALINPUTS)
add_lua_export_target(horus -DCPUARM -DPCBHORUS -DLUA -DVIRTUALINPUTS) add_lua_export_target(horus -DPCBHORUS -DLUA -DVIRTUALINPUTS)

View file

@ -384,10 +384,10 @@ static int luaModelInsertInput(lua_State *L)
unsigned int first = getFirstInput(chn); unsigned int first = getFirstInput(chn);
unsigned int count = getInputsCountFromFirst(chn, first); unsigned int count = getInputsCountFromFirst(chn, first);
if (chn<MAX_INPUTS && getExpoMixCount(1)<MAX_EXPOS && idx<=count) { if (chn<MAX_INPUTS && getExposCount()<MAX_EXPOS && idx<=count) {
idx = first + idx; idx = first + idx;
s_currCh = chn + 1; s_currCh = chn + 1;
insertExpoMix(1, idx); insertExpo(idx);
ExpoData * expo = expoAddress(idx); ExpoData * expo = expoAddress(idx);
luaL_checktype(L, -1, LUA_TTABLE); luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
@ -435,7 +435,7 @@ static int luaModelDeleteInput(lua_State *L)
unsigned int count = getInputsCountFromFirst(chn, first); unsigned int count = getInputsCountFromFirst(chn, first);
if (idx < count) { if (idx < count) {
deleteExpoMix(1, first+idx); deleteExpo(first+idx);
} }
return 0; return 0;
@ -595,10 +595,10 @@ static int luaModelInsertMix(lua_State *L)
unsigned int first = getFirstMix(chn); unsigned int first = getFirstMix(chn);
unsigned int count = getMixesCountFromFirst(chn, first); unsigned int count = getMixesCountFromFirst(chn, first);
if (chn<NUM_CHNOUT && getExpoMixCount(0)<MAX_MIXERS && idx<=count) { if (chn<NUM_CHNOUT && getMixesCount()<MAX_MIXERS && idx<=count) {
idx += first; idx += first;
s_currCh = chn+1; s_currCh = chn+1;
insertExpoMix(0, idx); insertMix(idx);
MixData *mix = mixAddress(idx); MixData *mix = mixAddress(idx);
luaL_checktype(L, -1, LUA_TTABLE); luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
@ -676,7 +676,7 @@ static int luaModelDeleteMix(lua_State *L)
unsigned int count = getMixesCountFromFirst(chn, first); unsigned int count = getMixesCountFromFirst(chn, first);
if (idx < count) { if (idx < count) {
deleteExpoMix(0, first+idx); deleteMix(first+idx);
} }
return 0; return 0;
@ -814,33 +814,33 @@ static int luaModelGetCurve(lua_State *L)
{ {
unsigned int idx = luaL_checkunsigned(L, 1); unsigned int idx = luaL_checkunsigned(L, 1);
if (idx < MAX_CURVES) { if (idx < MAX_CURVES) {
CurveInfo & curveInfo = g_model.curves[idx]; CurveData & curveData = g_model.curves[idx];
lua_newtable(L); lua_newtable(L);
lua_pushtablezstring(L, "name", g_model.curveNames[idx]); lua_pushtablezstring(L, "name", curveData.name);
lua_pushtableinteger(L, "type", curveInfo.type); lua_pushtableinteger(L, "type", curveData.type);
lua_pushtableboolean(L, "smooth", curveInfo.smooth); lua_pushtableboolean(L, "smooth", curveData.smooth);
lua_pushtableinteger(L, "points", curveInfo.points+5); lua_pushtableinteger(L, "points", curveData.points + 5);
lua_pushstring(L, "y"); lua_pushstring(L, "y");
lua_newtable(L); lua_newtable(L);
int8_t * point = curveAddress(idx); int8_t * point = curveAddress(idx);
for (int i=0; i<curveInfo.points+5; i++) { for (int i=0; i < curveData.points + 5; i++) {
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_pushinteger(L, *point++); lua_pushinteger(L, *point++);
lua_settable(L, -3); lua_settable(L, -3);
} }
lua_settable(L, -3); lua_settable(L, -3);
if (curveInfo.type == CURVE_TYPE_CUSTOM) { if (curveData.type == CURVE_TYPE_CUSTOM) {
lua_pushstring(L, "x"); lua_pushstring(L, "x");
lua_newtable(L); lua_newtable(L);
lua_pushinteger(L, 0); lua_pushinteger(L, 0);
lua_pushinteger(L, 0); lua_pushinteger(L, 0);
lua_settable(L, -3); lua_settable(L, -3);
for (int i=0; i<curveInfo.points+3; i++) { for (int i=0; i < curveData.points + 3; i++) {
lua_pushinteger(L, i+1); lua_pushinteger(L, i+1);
lua_pushinteger(L, *point++); lua_pushinteger(L, *point++);
lua_settable(L, -3); lua_settable(L, -3);
} }
lua_pushinteger(L, curveInfo.points+4); lua_pushinteger(L, curveData.points + 4);
lua_pushinteger(L, 100); lua_pushinteger(L, 100);
lua_settable(L, -3); lua_settable(L, -3);
lua_settable(L, -3); lua_settable(L, -3);

View file

@ -69,7 +69,7 @@ void checkSpeakerVolume()
{ {
if (currentSpeakerVolume != requiredSpeakerVolume) { if (currentSpeakerVolume != requiredSpeakerVolume) {
currentSpeakerVolume = requiredSpeakerVolume; currentSpeakerVolume = requiredSpeakerVolume;
setVolume(currentSpeakerVolume); setScaledVolume(currentSpeakerVolume);
} }
} }

View file

@ -106,14 +106,19 @@ void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS)
#endif #endif
//========== WEIGHT =============== //========== WEIGHT ===============
#if defined(CPUARM)
int32_t weight = GET_GVAR_PREC1(ed->weight, MIN_EXPO_WEIGHT, 100, mixerCurrentFlightMode);
v = ((int32_t)v * weight) / 1000;
#else
int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, mixerCurrentFlightMode); int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, mixerCurrentFlightMode);
weight = calc100to256(weight); weight = calc100to256(weight);
v = ((int32_t)v * weight) >> 8; v = ((int32_t)v * weight) >> 8;
#endif
#if defined(VIRTUALINPUTS) #if defined(VIRTUALINPUTS)
//========== OFFSET =============== //========== OFFSET ===============
int16_t offset = GET_GVAR(ed->offset, -100, 100, mixerCurrentFlightMode); int32_t offset = GET_GVAR_PREC1(ed->offset, -100, 100, mixerCurrentFlightMode);
if (offset) v += calc100toRESX(offset); if (offset) v += calc100toRESX(offset) / 10;
//========== TRIMS ================ //========== TRIMS ================
if (ed->carryTrim < TRIM_ON) if (ed->carryTrim < TRIM_ON)
@ -293,7 +298,8 @@ getvalue_t getValue(mixsrc_t i)
else if (i<=MIXSRC_LAST_CH) return ex_chans[i-MIXSRC_CH1]; else if (i<=MIXSRC_LAST_CH) return ex_chans[i-MIXSRC_CH1];
#if defined(GVARS) #if defined(GVARS)
else if (i<=MIXSRC_LAST_GVAR) return GVAR_VALUE(i-MIXSRC_GVAR1, getGVarFlightPhase(mixerCurrentFlightMode, i-MIXSRC_GVAR1)); else if (i<=MIXSRC_LAST_GVAR) return GVAR_VALUE(i-MIXSRC_GVAR1,
getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_GVAR1));
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
@ -787,10 +793,14 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
} }
} }
#if defined(CPUARM)
int32_t weight = GET_GVAR_PREC1(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
weight = calc100to256_16Bits(weight);
#else
// saves 12 bytes code if done here and not together with weight; unknown reason // saves 12 bytes code if done here and not together with weight; unknown reason
int16_t weight = GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); int16_t weight = GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
weight = calc100to256_16Bits(weight); weight = calc100to256_16Bits(weight);
#endif
//========== SPEED =============== //========== SPEED ===============
// now its on input side, but without weight compensation. More like other remote controls // now its on input side, but without weight compensation. More like other remote controls
// lower weight causes slower movement // lower weight causes slower movement
@ -844,12 +854,20 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
#endif #endif
//========== WEIGHT =============== //========== WEIGHT ===============
int32_t dv = (int32_t) v * weight; int32_t dv = (int32_t)v * weight;
#if defined(CPUARM)
dv /= 10;
#endif
//========== OFFSET / AFTER =============== //========== OFFSET / AFTER ===============
if (apply_offset_and_curve) { if (apply_offset_and_curve) {
#if defined(CPUARM)
int32_t offset = GET_GVAR_PREC1(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
if (offset) dv += int32_t(calc100toRESX_16Bits(offset) / 10) << 8;
#else
int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);
if (offset) dv += int32_t(calc100toRESX_16Bits(offset)) << 8; if (offset) dv += int32_t(calc100toRESX_16Bits(offset)) << 8;
#endif
} }
//========== DIFFERENTIAL ========= //========== DIFFERENTIAL =========

View file

@ -203,22 +203,6 @@ enum CurveType {
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
}; };
#if defined(XCURVES)
PACK(typedef struct {
uint8_t type:3;
uint8_t smooth:1;
uint8_t spare:4;
int8_t points;
}) CurveInfo;
#else
struct CurveInfo {
int8_t * crv;
uint8_t points;
bool custom;
};
extern CurveInfo curveInfo(uint8_t idx);
#endif
#if defined(PCBHORUS) #if defined(PCBHORUS)
#define LEN_MODEL_NAME 15 #define LEN_MODEL_NAME 15
#define LEN_TIMER_NAME 8 #define LEN_TIMER_NAME 8
@ -227,9 +211,9 @@ extern CurveInfo curveInfo(uint8_t idx);
#define LEN_EXPOMIX_NAME 6 #define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define NUM_POINTS 512
#define CURVDATA CurveInfo
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
#define LEN_MODEL_NAME 12 #define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8 #define LEN_TIMER_NAME 8
@ -237,9 +221,9 @@ extern CurveInfo curveInfo(uint8_t idx);
#define LEN_EXPOMIX_NAME 6 #define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define NUM_POINTS 512
#define CURVDATA CurveInfo
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#define LEN_MODEL_NAME 12 #define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8 #define LEN_TIMER_NAME 8
@ -248,9 +232,9 @@ extern CurveInfo curveInfo(uint8_t idx);
#define LEN_EXPOMIX_NAME 8 #define LEN_EXPOMIX_NAME 8
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define NUM_POINTS 512
#define CURVDATA CurveInfo
#elif defined(CPUARM) #elif defined(CPUARM)
#define LEN_MODEL_NAME 10 #define LEN_MODEL_NAME 10
#define LEN_TIMER_NAME 3 #define LEN_TIMER_NAME 3
@ -258,13 +242,11 @@ extern CurveInfo curveInfo(uint8_t idx);
#define LEN_EXPOMIX_NAME 6 #define LEN_EXPOMIX_NAME 6
#define MAX_CURVES 16 #define MAX_CURVES 16
#define NUM_POINTS 512 #define NUM_POINTS 512
#define CURVDATA int16_t
#else #else
#define LEN_MODEL_NAME 10 #define LEN_MODEL_NAME 10
#define LEN_FLIGHT_MODE_NAME 6 #define LEN_FLIGHT_MODE_NAME 6
#define MAX_CURVES 8 #define MAX_CURVES 8
#define NUM_POINTS (112-MAX_CURVES) #define NUM_POINTS (112-MAX_CURVES)
#define CURVDATA int8_t
#endif #endif
#if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS) #if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS)
@ -273,6 +255,20 @@ extern CurveInfo curveInfo(uint8_t idx);
#define NUM_MODULES 1 #define NUM_MODULES 1
#endif #endif
#if defined(XCURVES)
PACK(typedef struct {
uint8_t type:3;
uint8_t smooth:1;
uint8_t spare:4;
int8_t points;
char name[LEN_CURVE_NAME];
}) CurveData;
#elif defined(CPUARM)
typedef int16_t CurveData;
#else
typedef int8_t CurveData;
#endif
typedef int16_t gvar_t; typedef int16_t gvar_t;
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
@ -282,14 +278,18 @@ typedef int16_t gvar_t;
#endif #endif
#if !defined(PCBSTD) #if !defined(PCBSTD)
#define LEN_GVAR_NAME 6 #define LEN_GVAR_NAME 3
#define GVAR_MAX 1024 #define GVAR_MAX 1024
#define GVAR_LIMIT 500 #define GVAR_MIN -GVAR_MAX
PACK(typedef struct { PACK(typedef struct {
char name[LEN_GVAR_NAME]; char name[LEN_GVAR_NAME];
uint8_t popup:1; uint32_t min:12;
uint8_t spare:7; uint32_t max:12;
}) global_gvar_t; uint32_t popup:1;
uint32_t prec:1;
uint32_t unit:2;
uint32_t spare:4;
}) GVarData;
#endif #endif
#define RESERVE_RANGE_FOR_GVARS 10 #define RESERVE_RANGE_FOR_GVARS 10
@ -310,9 +310,9 @@ typedef int16_t gvar_t;
#else #else
#define MAX_GVARS 5 #define MAX_GVARS 5
#endif #endif
#define MODEL_GVARS_DATA global_gvar_t gvars[MAX_GVARS]; #define MODEL_GVARS_DATA GVarData gvars[MAX_GVARS];
#define PHASE_GVARS_DATA gvar_t gvars[MAX_GVARS] #define PHASE_GVARS_DATA gvar_t gvars[MAX_GVARS]
#define GVAR_VALUE(x, p) g_model.flightModeData[p].gvars[x] #define GVAR_VALUE(gv, fm) g_model.flightModeData[fm].gvars[gv]
#endif #endif
PACK(typedef struct { PACK(typedef struct {
@ -391,7 +391,10 @@ enum BeeperMode {
int8_t backgroundVolume; int8_t backgroundVolume;
#endif #endif
#if defined(PCBTARANIS) || defined(PCBHORUS) #if defined(PCBHORUS) || defined(PCBFLAMENCO)
#define swconfig_t uint16_t
#define swarnstate_t uint32_t
#elif defined(PCBTARANIS)
#if defined(REV9E) #if defined(REV9E)
#define swconfig_t uint64_t #define swconfig_t uint64_t
#define swarnstate_t uint64_t #define swarnstate_t uint64_t
@ -527,7 +530,7 @@ enum PotsWarnMode {
TRAINER_MODE_SLAVE TRAINER_MODE_SLAVE
}; };
#define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME]; #define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME];
#define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS];
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
enum ModuleIndex { enum ModuleIndex {
EXTERNAL_MODULE, EXTERNAL_MODULE,
@ -538,7 +541,7 @@ enum PotsWarnMode {
TRAINER_MODE_SLAVE TRAINER_MODE_SLAVE
}; };
#define MODELDATA_BITMAP uint8_t bitmap; #define MODELDATA_BITMAP uint8_t bitmap;
#define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS];
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
enum ModuleIndex { enum ModuleIndex {
INTERNAL_MODULE, INTERNAL_MODULE,
@ -554,7 +557,7 @@ enum PotsWarnMode {
}; };
#define IS_TRAINER_EXTERNAL_MODULE() (g_model.trainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || g_model.trainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) #define IS_TRAINER_EXTERNAL_MODULE() (g_model.trainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || g_model.trainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE)
#define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME]; #define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME];
#define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS];
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
enum ModuleIndex { enum ModuleIndex {
EXTERNAL_MODULE, EXTERNAL_MODULE,
@ -646,39 +649,34 @@ enum Functions {
FUNC_MAX FUNC_MAX
}; };
#if defined(OVERRIDE_CHANNEL_FUNCTION)
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE)
#else
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL)
#endif
#if defined(VOICE) #if defined(VOICE)
#define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE) #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
#else #else
#define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND) #define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND)
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
#define IS_PLAY_BOTH_FUNC(func) (0) #define IS_PLAY_BOTH_FUNC(func) (0)
#define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME) #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME)
#else #else
#define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH) #define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH)
#define IS_VOLUME_FUNC(func) (0) #define IS_VOLUME_FUNC(func) (0)
#endif #endif
#if defined(GVARS) #if defined(GVARS)
#define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR) #define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR)
#else #else
#define IS_ADJUST_GV_FUNC(func) (0) #define IS_ADJUST_GV_FUNC(func) (0)
#endif #endif
#if defined(HAPTIC) #if defined(HAPTIC)
#define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC) #define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC)
#else #else
#define IS_HAPTIC_FUNC(func) (0) #define IS_HAPTIC_FUNC(func) (0)
#endif #endif
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func)) #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && !IS_ADJUST_GV_FUNC(func))
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func) || IS_ADJUST_GV_FUNC(func))
enum ResetFunctionParam { enum ResetFunctionParam {
FUNC_RESET_TIMER1, FUNC_RESET_TIMER1,
@ -708,16 +706,16 @@ enum AdjustGvarFunctionParam {
FUNC_ADJUST_GVAR_CONSTANT, FUNC_ADJUST_GVAR_CONSTANT,
FUNC_ADJUST_GVAR_SOURCE, FUNC_ADJUST_GVAR_SOURCE,
FUNC_ADJUST_GVAR_GVAR, FUNC_ADJUST_GVAR_GVAR,
FUNC_ADJUST_GVAR_INC, FUNC_ADJUST_GVAR_INCDEC,
}; };
#if defined(CPUARM) #if defined(CPUARM)
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
#define LEN_CFN_NAME 8 #define LEN_CFN_NAME 8
#define CFN_SPARE_TYPE int32_t #define CFN_SPARE_TYPE int32_t
#else #else
#define LEN_CFN_NAME 6 #define LEN_CFN_NAME 6
#define CFN_SPARE_TYPE int16_t #define CFN_SPARE_TYPE int16_t
#endif #endif
PACK(typedef struct { PACK(typedef struct {
int16_t swtch:9; int16_t swtch:9;
@ -731,7 +729,7 @@ PACK(typedef struct {
int16_t val; int16_t val;
uint8_t mode; uint8_t mode;
uint8_t param; uint8_t param;
CFN_SPARE_TYPE spare2; CFN_SPARE_TYPE spare;
}) all; }) all;
PACK(struct { PACK(struct {
@ -741,20 +739,21 @@ PACK(typedef struct {
}); });
uint8_t active; uint8_t active;
}) CustomFunctionData; }) CustomFunctionData;
#define CFN_EMPTY(p) (!(p)->swtch) #define CFN_EMPTY(p) (!(p)->swtch)
#define CFN_SWITCH(p) ((p)->swtch) #define CFN_SWITCH(p) ((p)->swtch)
#define CFN_FUNC(p) ((p)->func) #define CFN_FUNC(p) ((p)->func)
#define CFN_ACTIVE(p) ((p)->active) #define CFN_ACTIVE(p) ((p)->active)
#define CFN_CH_INDEX(p) ((p)->all.param) #define CFN_CH_INDEX(p) ((p)->all.param)
#define CFN_GVAR_INDEX(p) ((p)->all.param) #define CFN_GVAR_INDEX(p) ((p)->all.param)
#define CFN_TIMER_INDEX(p) ((p)->all.param) #define CFN_TIMER_INDEX(p) ((p)->all.param)
#define CFN_PLAY_REPEAT(p) ((p)->active) #define CFN_PLAY_REPEAT(p) ((p)->active)
#define CFN_PLAY_REPEAT_MUL 1 #define CFN_PLAY_REPEAT_MUL 1
#define CFN_PLAY_REPEAT_NOSTART 0xFF #define CFN_PLAY_REPEAT_NOSTART 0xFF
#define CFN_GVAR_MODE(p) ((p)->all.mode) #define CFN_GVAR_MODE(p) ((p)->all.mode)
#define CFN_PARAM(p) ((p)->all.val) #define CFN_PARAM(p) ((p)->all.val)
#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0) #define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0)
#define CFN_GVAR_CST_MAX GVAR_LIMIT #define CFN_GVAR_CST_MIN -GVAR_MAX
#define CFN_GVAR_CST_MAX GVAR_MAX
#elif defined(CPUM2560) #elif defined(CPUM2560)
PACK(typedef struct { PACK(typedef struct {
int8_t swtch; int8_t swtch;
@ -976,9 +975,9 @@ PACK(typedef struct {
#define LIMIT_EXT_PERCENT 150 #define LIMIT_EXT_PERCENT 150
#define LIMIT_EXT_MAX (LIMIT_EXT_PERCENT*10) #define LIMIT_EXT_MAX (LIMIT_EXT_PERCENT*10)
#define PPM_CENTER_MAX 500 #define PPM_CENTER_MAX 500
#define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode)*10 : lim->max+1000) #define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->max+1000)
#define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode)*10 : lim->min-1000) #define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->min-1000)
#define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR(lim->offset, -1000, 1000, mixerCurrentFlightMode)*10 : lim->offset) #define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR_PREC1(lim->offset, -1000, 1000, mixerCurrentFlightMode) : lim->offset)
#define LIMIT_MAX_RESX(lim) calc1000toRESX(LIMIT_MAX(lim)) #define LIMIT_MAX_RESX(lim) calc1000toRESX(LIMIT_MAX(lim))
#define LIMIT_MIN_RESX(lim) calc1000toRESX(LIMIT_MIN(lim)) #define LIMIT_MIN_RESX(lim) calc1000toRESX(LIMIT_MIN(lim))
#define LIMIT_OFS_RESX(lim) calc1000toRESX(LIMIT_OFS(lim)) #define LIMIT_OFS_RESX(lim) calc1000toRESX(LIMIT_OFS(lim))
@ -2312,7 +2311,7 @@ PACK(typedef struct {
LimitData limitData[NUM_CHNOUT]; LimitData limitData[NUM_CHNOUT];
ExpoData expoData[MAX_EXPOS]; ExpoData expoData[MAX_EXPOS];
CURVDATA curves[MAX_CURVES]; CurveData curves[MAX_CURVES];
int8_t points[NUM_POINTS]; int8_t points[NUM_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH]; LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
@ -2325,7 +2324,9 @@ PACK(typedef struct {
uint8_t thrTraceSrc; uint8_t thrTraceSrc;
swarnstate_t switchWarningState; swarnstate_t switchWarningState;
#if !defined(COLORLCD)
swarnenable_t switchWarningEnable; swarnenable_t switchWarningEnable;
#endif
MODEL_GVARS_DATA MODEL_GVARS_DATA

View file

@ -233,6 +233,19 @@ void memclear(void *ptr, uint8_t size)
} }
#endif #endif
void memswap(void * a, void * b, uint8_t size)
{
uint8_t * x = (uint8_t *)a;
uint8_t * y = (uint8_t *)b;
uint8_t temp ;
while (size--) {
temp = *x;
*x++ = *y;
*y++ = temp;
}
}
void generalDefault() void generalDefault()
{ {
memclear(&g_eeGeneral, sizeof(g_eeGeneral)); memclear(&g_eeGeneral, sizeof(g_eeGeneral));
@ -655,13 +668,13 @@ void incRotaryEncoder(uint8_t idx, int8_t inc)
GVAR_VALUE(idx, phase) = value; \ GVAR_VALUE(idx, phase) = value; \
storageDirty(EE_MODEL); \ storageDirty(EE_MODEL); \
if (g_model.gvars[idx].popup) { \ if (g_model.gvars[idx].popup) { \
s_gvar_last = idx; \ gvarLastChanged = idx; \
s_gvar_timer = GVAR_DISPLAY_TIME; \ gvarDisplayTimer = GVAR_DISPLAY_TIME; \
} }
#endif #endif
#if defined(PCBSTD) #if defined(PCBSTD)
int16_t getGVarValue(int16_t x, int16_t min, int16_t max) int16_t getGVarFieldValue(int16_t x, int16_t min, int16_t max)
{ {
if (GV_IS_GV_VALUE(x, min, max)) { if (GV_IS_GV_VALUE(x, min, max)) {
int8_t idx = GV_INDEX_CALCULATION(x, max); int8_t idx = GV_INDEX_CALCULATION(x, max);
@ -685,44 +698,75 @@ void setGVarValue(uint8_t idx, int8_t value)
} }
} }
#else #else
uint8_t s_gvar_timer = 0; uint8_t gvarDisplayTimer = 0;
uint8_t s_gvar_last = 0; uint8_t gvarLastChanged = 0;
uint8_t getGVarFlightPhase(uint8_t phase, uint8_t idx) uint8_t getGVarFlightMode(uint8_t fm, uint8_t gv) // TODO change params order to be consistent!
{ {
for (uint8_t i=0; i<MAX_FLIGHT_MODES; i++) { for (uint8_t i=0; i<MAX_FLIGHT_MODES; i++) {
if (phase == 0) return 0; if (fm == 0) return 0;
int16_t val = GVAR_VALUE(idx, phase); // TODO phase at the end everywhere to be consistent! int16_t val = GVAR_VALUE(gv, fm);
if (val <= GVAR_MAX) return phase; if (val <= GVAR_MAX) return fm;
uint8_t result = val-GVAR_MAX-1; uint8_t result = val-GVAR_MAX-1;
if (result >= phase) result++; if (result >= fm) result++;
phase = result; fm = result;
} }
return 0; return 0;
} }
int16_t getGVarValue(int16_t x, int16_t min, int16_t max, int8_t phase) int16_t getGVarValue(int8_t gv, int8_t fm)
{ {
if (GV_IS_GV_VALUE(x, min, max)) { int8_t mul = 1;
int8_t idx = GV_INDEX_CALCULATION(x, max); if (gv < 0) {
int8_t mul = 1; gv = -1-gv;
mul = -1;
if (idx < 0) {
idx = -1-idx;
mul = -1;
}
x = GVAR_VALUE(idx, getGVarFlightPhase(phase, idx)) * mul;
} }
return limit(min, x, max); return GVAR_VALUE(gv, getGVarFlightMode(fm, gv)) * mul;
} }
void setGVarValue(uint8_t idx, int16_t value, int8_t phase) int32_t getGVarValuePrec1(int8_t gv, int8_t fm)
{ {
phase = getGVarFlightPhase(phase, idx); int8_t mul;
if (GVAR_VALUE(idx, phase) != value) { uint8_t prec = g_model.gvars[gv].prec;
SET_GVAR_VALUE(idx, phase, value); if (prec == 0)
mul = 10;
else
mul = 1;
if (gv < 0) {
gv = -1-gv;
mul = -mul;
} }
return GVAR_VALUE(gv, getGVarFlightMode(fm, gv)) * mul;
}
void setGVarValue(uint8_t gv, int16_t value, int8_t fm)
{
fm = getGVarFlightMode(fm, gv);
if (GVAR_VALUE(gv, fm) != value) {
SET_GVAR_VALUE(gv, fm, value);
}
}
int16_t getGVarFieldValue(int16_t val, int16_t min, int16_t max, int8_t fm)
{
if (GV_IS_GV_VALUE(val, min, max)) {
int8_t gv = GV_INDEX_CALCULATION(val, max);
val = getGVarValue(gv, fm);
}
return limit(min, val, max);
}
int32_t getGVarFieldValuePrec1(int16_t val, int16_t min, int16_t max, int8_t fm)
{
if (GV_IS_GV_VALUE(val, min, max)) {
int8_t gv = GV_INDEX_CALCULATION(val, max);
val = getGVarValuePrec1(gv, fm);
}
else {
val *= 10;
}
return limit<int>(min*10, val, max*10);
} }
#endif #endif
@ -1320,7 +1364,7 @@ uint8_t checkTrim(uint8_t event)
#if defined(PCBSTD) #if defined(PCBSTD)
phase = 0; phase = 0;
#else #else
phase = getGVarFlightPhase(mixerCurrentFlightMode, trimGvar[idx]); phase = getGVarFlightMode(mixerCurrentFlightMode, trimGvar[idx]);
#endif #endif
before = GVAR_VALUE(trimGvar[idx], phase); before = GVAR_VALUE(trimGvar[idx], phase);
thro = false; thro = false;
@ -2408,7 +2452,7 @@ void opentxInit(OPENTX_INIT_ARGS)
#endif #endif
#if defined(VOICE) #if defined(VOICE)
setVolume(g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF); setScaledVolume(g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF);
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)

View file

@ -281,8 +281,6 @@
#include "targets/9x/board_stock.h" #include "targets/9x/board_stock.h"
#endif #endif
#include "debug.h"
#if defined(SIMU) #if defined(SIMU)
#include "targets/simu/simpgmspace.h" #include "targets/simu/simpgmspace.h"
#elif defined(CPUARM) #elif defined(CPUARM)
@ -319,6 +317,8 @@
#include <avr/wdt.h> #include <avr/wdt.h>
#endif #endif
#include "debug.h"
#if defined(PCBFLAMENCO) #if defined(PCBFLAMENCO)
#define NUM_SWITCHES 5 #define NUM_SWITCHES 5
#elif defined(PCBTARANIS) || defined(PCBHORUS) #elif defined(PCBTARANIS) || defined(PCBHORUS)
@ -350,6 +350,8 @@
#define memclear(p, s) memset(p, 0, s) #define memclear(p, s) memset(p, 0, s)
#endif #endif
void memswap(void * a, void * b, uint8_t size);
#if defined(PCBHORUS) #if defined(PCBHORUS)
#define IS_POT_AVAILABLE(x) (true) #define IS_POT_AVAILABLE(x) (true)
#define IS_POT_MULTIPOS(x) ((x)==POT2) #define IS_POT_MULTIPOS(x) ((x)==POT2)
@ -457,7 +459,7 @@
#define MAX_TRAINER_CHANNELS() (8) #define MAX_TRAINER_CHANNELS() (8)
#endif #endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS) || defined(PCBHORUS)
#if defined(TARANIS_INTERNAL_PPM) #if defined(TARANIS_INTERNAL_PPM)
#define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type==MODULE_TYPE_PPM)|| (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM)) #define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type==MODULE_TYPE_PPM)|| (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM))
#define IS_MODULE_XJT(idx) (((idx==INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type==MODULE_TYPE_XJT)|| (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT)) && (g_model.moduleData[idx].rfProtocol != RF_PROTO_OFF)) #define IS_MODULE_XJT(idx) (((idx==INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type==MODULE_TYPE_XJT)|| (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT)) && (g_model.moduleData[idx].rfProtocol != RF_PROTO_OFF))
@ -664,8 +666,12 @@ uint16_t evalChkSum();
#define ALERT(title, msg, sound) alert(title, msg) #define ALERT(title, msg, sound) alert(title, msg)
#endif #endif
extern void message(const pm_char *title, const pm_char *s, const char *last MESSAGE_SOUND_ARG); // TODO these functions in gui directories
extern void alert(const pm_char * t, const pm_char * s MESSAGE_SOUND_ARG); #if defined(COLORLCD) || defined(PCBTARANIS)
void drawMessageBox(const pm_char * title, const pm_char * t, const char * last, uint8_t sound);
#endif
void message(const pm_char * title, const pm_char * s, const char * last MESSAGE_SOUND_ARG);
void alert(const pm_char * t, const pm_char * s MESSAGE_SOUND_ARG);
enum PerOutMode { enum PerOutMode {
e_perout_mode_normal = 0, e_perout_mode_normal = 0,
@ -812,22 +818,27 @@ int getTrimValue(uint8_t phase, uint8_t idx);
#if defined(GVARS) #if defined(GVARS)
#if defined(PCBSTD) #if defined(PCBSTD)
int16_t getGVarValue(int16_t x, int16_t min, int16_t max); int16_t getGVarFieldValue(int16_t x, int16_t min, int16_t max);
void setGVarValue(uint8_t x, int8_t value); void setGVarValue(uint8_t x, int8_t value);
#define GET_GVAR(x, min, max, p) getGVarValue(x, min, max) #define GET_GVAR(x, min, max, fm) getGVarFieldValue(x, min, max)
#define SET_GVAR(idx, val, p) setGVarValue(idx, val) #define SET_GVAR(idx, val, fm) setGVarValue(idx, val)
#else #else
uint8_t getGVarFlightPhase(uint8_t phase, uint8_t idx); uint8_t getGVarFlightMode(uint8_t fm, uint8_t gv);
int16_t getGVarValue(int16_t x, int16_t min, int16_t max, int8_t phase); int16_t getGVarFieldValue(int16_t x, int16_t min, int16_t max, int8_t fm);
void setGVarValue(uint8_t x, int16_t value, int8_t phase); int32_t getGVarFieldValuePrec1(int16_t x, int16_t min, int16_t max, int8_t fm);
#define GET_GVAR(x, min, max, p) getGVarValue(x, min, max, p) int16_t getGVarValue(int8_t gv, int8_t fm);
#define SET_GVAR(idx, val, p) setGVarValue(idx, val, p) int32_t getGVarValuePrec1(int8_t gv, int8_t fm);
void setGVarValue(uint8_t x, int16_t value, int8_t fm);
#define GET_GVAR(x, min, max, fm) getGVarFieldValue(x, min, max, fm)
#define SET_GVAR(idx, val, fm) setGVarValue(idx, val, fm)
#define GVAR_DISPLAY_TIME 100 /*1 second*/; #define GVAR_DISPLAY_TIME 100 /*1 second*/;
extern uint8_t s_gvar_timer; #define GET_GVAR_PREC1(x, min, max, fm) getGVarFieldValuePrec1(x, min, max, fm)
extern uint8_t s_gvar_last; extern uint8_t gvarDisplayTimer;
extern uint8_t gvarLastChanged;
#endif #endif
#else #else
#define GET_GVAR(x, ...) (x) #define GET_GVAR(x, ...) (x)
#define GET_GVAR_PREC1(x, ...) (x*10)
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
@ -1161,6 +1172,17 @@ LimitData *limitAddress(uint8_t idx);
int8_t *curveAddress(uint8_t idx); int8_t *curveAddress(uint8_t idx);
LogicalSwitchData *lswAddress(uint8_t idx); LogicalSwitchData *lswAddress(uint8_t idx);
#if defined(XCURVES)
typedef CurveData CurveInfo;
#else
struct CurveInfo {
int8_t * crv;
uint8_t points:7;
uint8_t custom:1;
};
extern CurveInfo curveInfo(uint8_t idx);
#endif
// static variables used in evalFlightModeMixes - moved here so they don't interfere with the stack // static variables used in evalFlightModeMixes - moved here so they don't interfere with the stack
// It's also easier to initialize them here. // It's also easier to initialize them here.
#if defined(VIRTUALINPUTS) #if defined(VIRTUALINPUTS)
@ -1175,10 +1197,6 @@ extern BeepANACenter bpanaCenter;
extern uint8_t s_mixer_first_run_done; extern uint8_t s_mixer_first_run_done;
extern int8_t s_currCh;
uint8_t getExpoMixCount(uint8_t expo);
void deleteExpoMix(uint8_t expo, uint8_t idx);
void insertExpoMix(uint8_t expo, uint8_t idx);
void applyDefaultTemplate(); void applyDefaultTemplate();
void incSubtrim(uint8_t idx, int16_t inc); void incSubtrim(uint8_t idx, int16_t inc);

View file

@ -316,7 +316,7 @@ void Open9xSim::updateKeysAndSwitches(bool start)
SWITCH_KEY(P, 15, 3); SWITCH_KEY(P, 15, 3);
SWITCH_KEY(Q, 16, 3); SWITCH_KEY(Q, 16, 3);
SWITCH_KEY(R, 17, 3); SWITCH_KEY(R, 17, 3);
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS) || defined(PCBHORUS)
SWITCH_KEY(A, 0, 3); SWITCH_KEY(A, 0, 3);
SWITCH_KEY(B, 1, 3); SWITCH_KEY(B, 1, 3);
SWITCH_KEY(C, 2, 3); SWITCH_KEY(C, 2, 3);
@ -360,11 +360,11 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
#if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBHORUS) #if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBHORUS)
static bool rotencAction = false; static bool rotencAction = false;
if (getApp()->getKeyState(KEY_G)) { if (getApp()->getKeyState(KEY_X)) {
if (!rotencAction) ROTENC_VALUE += ROTARY_ENCODER_GRANULARITY; if (!rotencAction) ROTENC_VALUE += ROTARY_ENCODER_GRANULARITY;
rotencAction = true; rotencAction = true;
} }
else if (getApp()->getKeyState(KEY_D)) { else if (getApp()->getKeyState(KEY_W)) {
if (!rotencAction) ROTENC_VALUE -= ROTARY_ENCODER_GRANULARITY; if (!rotencAction) ROTENC_VALUE -= ROTARY_ENCODER_GRANULARITY;
rotencAction = true; rotencAction = true;
} }
@ -392,7 +392,7 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
SWITCH_KEY(P, 15, 3); SWITCH_KEY(P, 15, 3);
SWITCH_KEY(Q, 16, 3); SWITCH_KEY(Q, 16, 3);
SWITCH_KEY(R, 17, 3); SWITCH_KEY(R, 17, 3);
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS) || defined(PCBHORUS)
SWITCH_KEY(A, 0, 3); SWITCH_KEY(A, 0, 3);
SWITCH_KEY(B, 1, 3); SWITCH_KEY(B, 1, 3);
SWITCH_KEY(C, 2, 3); SWITCH_KEY(C, 2, 3);
@ -545,7 +545,7 @@ uint16_t anaIn(uint8_t chan)
return th9xSim->sliders[chan]->getValue(); return th9xSim->sliders[chan]->getValue();
else if (chan<NUM_STICKS+NUM_POTS) else if (chan<NUM_STICKS+NUM_POTS)
return th9xSim->knobs[chan-NUM_STICKS]->getValue(); return th9xSim->knobs[chan-NUM_STICKS]->getValue();
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) #if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
else if (chan == TX_VOLTAGE) else if (chan == TX_VOLTAGE)
return 1000; return 1000;
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "opentx.h" #include "opentx.h"
enum Mix216Sources { enum Mix216Sources {
@ -636,6 +636,21 @@ PACK(typedef struct {
uint8_t rxBattAlarms[2]; uint8_t rxBattAlarms[2];
#endif #endif
#if defined(PCBTARANIS)
#define MODELDATA_EXTRA_217 \
uint8_t spare:3; \
uint8_t trainerMode:3; \
uint8_t potsWarnMode:2; \
ModuleData moduleData[NUM_MODULES+1]; \
char curveNames[MAX_CURVES][6]; \
ScriptData scriptsData[MAX_SCRIPTS]; \
char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; \
uint8_t potsWarnEnabled; \
int8_t potsWarnPosition[NUM_POTS];
#else
#define MODELDATA_EXTRA_217 MODELDATA_EXTRA
#endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
PACK(typedef struct { PACK(typedef struct {
char name[LEN_MODEL_NAME]; char name[LEN_MODEL_NAME];
@ -670,7 +685,7 @@ PACK(typedef struct {
LimitData_v216 limitData[NUM_CHNOUT]; LimitData_v216 limitData[NUM_CHNOUT];
ExpoData_v216 expoData[MAX_EXPOS]; ExpoData_v216 expoData[MAX_EXPOS];
CURVDATA curves[MAX_CURVES]; CurveData curves[MAX_CURVES];
int8_t points[NUM_POINTS]; int8_t points[NUM_POINTS];
LogicalSwitchData_v216 logicalSw[32]; LogicalSwitchData_v216 logicalSw[32];
@ -683,7 +698,7 @@ PACK(typedef struct {
uint16_t switchWarningState; uint16_t switchWarningState;
uint8_t switchWarningEnable; uint8_t switchWarningEnable;
global_gvar_t gvars[MAX_GVARS]; GVarData gvars[MAX_GVARS];
FrSkyData_v216 frsky; FrSkyData_v216 frsky;
@ -710,7 +725,7 @@ PACK(typedef struct {
LimitData limitData[NUM_CHNOUT]; LimitData limitData[NUM_CHNOUT];
ExpoData_v217 expoData[MAX_EXPOS]; ExpoData_v217 expoData[MAX_EXPOS];
CURVDATA curves[MAX_CURVES]; CurveData curves[MAX_CURVES];
int8_t points[NUM_POINTS]; int8_t points[NUM_POINTS];
LogicalSwitchData_v217 logicalSw[32]; LogicalSwitchData_v217 logicalSw[32];
@ -727,7 +742,7 @@ PACK(typedef struct {
TELEMETRY_DATA TELEMETRY_DATA
MODELDATA_EXTRA MODELDATA_EXTRA_217
TelemetrySensor telemetrySensors[MAX_SENSORS]; TelemetrySensor telemetrySensors[MAX_SENSORS];
@ -1291,6 +1306,16 @@ void ConvertModel_217_to_218(ModelData & model)
newModel.expoData[i].mode = oldModel.expoData[i].mode; newModel.expoData[i].mode = oldModel.expoData[i].mode;
memcpy(newModel.expoData[i].name, oldModel.expoData[i].name, sizeof(newModel.expoData[i].name)); memcpy(newModel.expoData[i].name, oldModel.expoData[i].name, sizeof(newModel.expoData[i].name));
} }
for (int i=0; i<MAX_CURVES; i++) {
#if defined(XCURVES)
newModel.curves[i].type = oldModel.curves[i].type;
newModel.curves[i].smooth = oldModel.curves[i].smooth;
newModel.curves[i].points = oldModel.curves[i].points;
memcpy(newModel.curves[i].name, oldModel.curveNames[i], sizeof(newModel.curves[i].name));
#else
newModel.curves[i] = oldModel.curves[i];
#endif
}
memcpy(newModel.curves, oldModel.curves, sizeof(newModel.curves)); memcpy(newModel.curves, oldModel.curves, sizeof(newModel.curves));
memcpy(newModel.points, oldModel.points, sizeof(newModel.points)); memcpy(newModel.points, oldModel.points, sizeof(newModel.points));
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
@ -1330,7 +1355,6 @@ void ConvertModel_217_to_218(ModelData & model)
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
newModel.trainerMode = oldModel.trainerMode; newModel.trainerMode = oldModel.trainerMode;
memcpy(newModel.scriptsData, oldModel.scriptsData, sizeof(newModel.scriptsData)); memcpy(newModel.scriptsData, oldModel.scriptsData, sizeof(newModel.scriptsData));
memcpy(newModel.curveNames, oldModel.curveNames, sizeof(newModel.curveNames));
memcpy(newModel.inputNames, oldModel.inputNames, sizeof(newModel.inputNames)); memcpy(newModel.inputNames, oldModel.inputNames, sizeof(newModel.inputNames));
#endif #endif
newModel.potsWarnMode = oldModel.potsWarnMode; newModel.potsWarnMode = oldModel.potsWarnMode;

View file

@ -60,7 +60,7 @@ int8_t char2idx(char c)
return 0; return 0;
} }
void str2zchar(char *dest, const char *src, int size) void str2zchar(char * dest, const char *src, int size)
{ {
memset(dest, 0, size); memset(dest, 0, size);
for (int c=0; c<size && src[c]; c++) { for (int c=0; c<size && src[c]; c++) {
@ -68,7 +68,7 @@ void str2zchar(char *dest, const char *src, int size)
} }
} }
int zchar2str(char *dest, const char *src, int size) int zchar2str(char * dest, const char *src, int size)
{ {
for (int c=0; c<size; c++) { for (int c=0; c<size; c++) {
dest[c] = idx2char(src[c]); dest[c] = idx2char(src[c]);

View file

@ -22,6 +22,18 @@
#define CS_LAST_VALUE_INIT -32768 #define CS_LAST_VALUE_INIT -32768
#if defined(PCBFLAMENCO)
#define SWITCH_WARNING_LIST_INTERVAL 20
#elif defined(PCBHORUS)
#define SWITCH_WARNING_LIST_X WARNING_LINE_X
#define SWITCH_WARNING_LIST_Y WARNING_LINE_Y+3*FH
#define SWITCH_WARNING_LIST_INTERVAL 35
#elif defined(PCBTARANIS)
#define SWITCH_WARNING_LIST_X 60
#define SWITCH_WARNING_LIST_Y 4*FH+3
#else
#endif
#if defined(CPUARM) #if defined(CPUARM)
enum LogicalSwitchContextState { enum LogicalSwitchContextState {
@ -759,7 +771,15 @@ void checkSwitches()
getMovedSwitch(); getMovedSwitch();
bool warn = false; bool warn = false;
#if defined(PCBFLAMENCO) #if defined(COLORLCD)
for (int i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
unsigned int state = ((g_model.switchWarningState >> (3*i)) & 0x07);
if (state && state-1 != ((switches_states >> (i*2)) & 0x03)) {
warn = true;
}
}
}
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
for (int i=0; i<NUM_SWITCHES; i++) { for (int i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) { if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) {
@ -807,30 +827,29 @@ void checkSwitches()
// first - display warning // first - display warning
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS) #if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
#if defined(COLORLCD)
if ((last_bad_switches != switches_states) || (last_bad_pots != bad_pots)) { if ((last_bad_switches != switches_states) || (last_bad_pots != bad_pots)) {
int x = WARNING_LINE_X, y = WARNING_INFOLINE_Y-5; drawMessageBox(STR_SWITCHWARN, NULL, STR_PRESSANYKEYTOSKIP, ((last_bad_switches == 0xff) || (last_bad_pots == 0xff)) ? AU_SWITCH_ALERT : AU_NONE);
#elif defined(PCBTARANIS) int x = SWITCH_WARNING_LIST_X, y = SWITCH_WARNING_LIST_Y;
if ((last_bad_switches != switches_states) || (last_bad_pots != bad_pots)) {
MESSAGE(STR_SWITCHWARN, NULL, STR_PRESSANYKEYTOSKIP, ((last_bad_switches == 0xff) || (last_bad_pots == 0xff)) ? AU_SWITCH_ALERT : AU_NONE);
int x = 60, y = 4*FH+3;
#endif
int numWarnings = 0; int numWarnings = 0;
for (int i=0; i<NUM_SWITCHES; ++i) { for (int i=0; i<NUM_SWITCHES; ++i) {
if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) {
swarnstate_t mask = ((swarnstate_t)0x03 << (i*2));
#if defined(COLORLCD) #if defined(COLORLCD)
LcdFlags attr = ((states & mask) == (switches_states & mask)) ? TEXT_COLOR : ALARM_COLOR; if (SWITCH_WARNING_ALLOWED(i)) {
if (attr) { unsigned int state = ((g_model.switchWarningState >> (3*i)) & 0x07);
if (state && state-1 != ((switches_states >> (i*2)) & 0x03)) {
if (++numWarnings < 6) { if (++numWarnings < 6) {
putsSwitches(x, y, SWSRC_FIRST_SWITCH+i*3, attr); // LcdFlags attr = ((states & mask) == (switches_states & mask)) ? TEXT_COLOR : ALARM_COLOR;
x += 20; LcdFlags attr = ALARM_COLOR;
putsSwitches(x, y, SWSRC_FIRST_SWITCH+i*3+state-1, attr);
x += SWITCH_WARNING_LIST_INTERVAL;
} }
else if (numWarnings == 6) { else if (numWarnings == 6) {
lcdDrawText(x, y, "...", ALARM_COLOR); lcdDrawText(x, y, "...", ALARM_COLOR);
} }
} }
}
#else #else
if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) {
swarnstate_t mask = ((swarnstate_t)0x03 << (i*2));
LcdFlags attr = ((states & mask) == (switches_states & mask)) ? 0 : INVERS; LcdFlags attr = ((states & mask) == (switches_states & mask)) ? 0 : INVERS;
if (attr) { if (attr) {
if (++numWarnings < 7) { if (++numWarnings < 7) {
@ -843,9 +862,10 @@ void checkSwitches()
lcdDrawText(x, y, "...", 0); lcdDrawText(x, y, "...", 0);
} }
} }
#endif
} }
#endif
} }
if (g_model.potsWarnMode) { if (g_model.potsWarnMode) {
if (y == 4*FH+3) { if (y == 4*FH+3) {
y = 6*FH-2; y = 6*FH-2;
@ -901,7 +921,11 @@ void checkSwitches()
x += 3*FW+FW/2; x += 3*FW+FW/2;
} }
#endif #endif
lcdRefresh(); lcdRefresh();
lcdSetContrast();
clearKeyEvents();
last_bad_switches = switches_states; last_bad_switches = switches_states;
} }

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
// Bits in VoiceLatch // Bits in VoiceLatch
#define VOICE_CLOCK_BIT 0x01 #define VOICE_CLOCK_BIT 0x01
#define VOICE_DATA_BIT 0x02 #define VOICE_DATA_BIT 0x02
@ -68,7 +68,7 @@ extern struct t_voice Voice ;
#define VOLUME_LEVEL_MAX 7 #define VOLUME_LEVEL_MAX 7
#define VOLUME_LEVEL_DEF 7 #define VOLUME_LEVEL_DEF 7
#define setVolume(v) pushPrompt((v) | 0xFFF0) #define setScaledVolume(v) pushPrompt((v) | 0xFFF0)
inline bool isPlaying() inline bool isPlaying()
{ {

View file

@ -40,4 +40,4 @@ extern bool isPlaying();
#define VOLUME_LEVEL_MAX 7 #define VOLUME_LEVEL_MAX 7
#define VOLUME_LEVEL_DEF 7 #define VOLUME_LEVEL_DEF 7
#define setVolume(v) #define setScaledVolume(v)

View file

@ -130,9 +130,16 @@ void boardInit()
pwrInit(); pwrInit();
ledInit(); ledInit();
i2cInit();
if (getVolume() < 0)
ledRed();
else
ledBlue();
delaysInit(); delaysInit();
ledRed(); // ledRed();
if (0) { if (0) {
// pinCheck(SERIAL_GPIO, SERIAL_GPIO_PIN_TX, SERIAL_RCC_AHB1Periph_GPIO); // pinCheck(SERIAL_GPIO, SERIAL_GPIO_PIN_TX, SERIAL_RCC_AHB1Periph_GPIO);
@ -143,7 +150,7 @@ void boardInit()
serial2Init(0, 0); // default serial mode (None if DEBUG not defined) serial2Init(0, 0); // default serial mode (None if DEBUG not defined)
ledBlue(); // ledBlue();
__enable_irq(); __enable_irq();

View file

@ -1,25 +1,25 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifndef _BOARD_HORUS_H_ #ifndef _BOARD_HORUS_H_
#define _BOARD_HORUS_H_ #define _BOARD_HORUS_H_
#include "stddef.h" #include "stddef.h"
@ -286,7 +286,9 @@ void i2cInit(void);
#define VOLUME_LEVEL_MAX 23 #define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12 #define VOLUME_LEVEL_DEF 12
extern const int8_t volumeScale[]; extern const int8_t volumeScale[];
void setScaledVolume(uint8_t volume);
void setVolume(uint8_t volume); void setVolume(uint8_t volume);
int32_t getVolume(void);
// Telemetry driver // Telemetry driver
void telemetryPortInit(uint32_t baudrate); void telemetryPortInit(uint32_t baudrate);
@ -314,4 +316,4 @@ void usbJoystickUpdate(void);
void checkTrainerSettings(void); void checkTrainerSettings(void);
#endif // _BOARD_HORUS_H_ #endif // _BOARD_HORUS_H_

View file

@ -1,37 +1,28 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "../horus/board_horus.h" #include "board_horus.h"
void i2cInit(void) void i2cInit(void)
{ {
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SCL, I2C_GPIO_AF); I2C_DeInit(I2C);
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SDA, I2C_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_GPIO_PIN_SCL | I2C_GPIO_PIN_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
I2C_InitTypeDef I2C_InitStructure; I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
@ -42,6 +33,17 @@ void i2cInit(void)
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C, &I2C_InitStructure); I2C_Init(I2C, &I2C_InitStructure);
I2C_Cmd(I2C, ENABLE); I2C_Cmd(I2C, ENABLE);
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SCL, I2C_GPIO_AF);
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SDA, I2C_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_GPIO_PIN_SCL | I2C_GPIO_PIN_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
} }
#define I2C_TIMEOUT_MAX 1000 #define I2C_TIMEOUT_MAX 1000
@ -63,34 +65,34 @@ bool I2C_WaitEventCleared(uint32_t event)
return true; return true;
} }
uint8_t i2cReadRegister(uint8_t address, uint8_t index) int16_t i2cReadRegister(uint8_t address, uint8_t index)
{ {
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return 0; return -1;
I2C_GenerateSTART(I2C, ENABLE); I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return 0; return -2;
I2C_Send7bitAddress(I2C, address, I2C_Direction_Transmitter); I2C_Send7bitAddress(I2C, address, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return 0; return -3;
I2C_SendData(I2C, index); I2C_SendData(I2C, index);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return 0; return -4;
I2C_GenerateSTART(I2C, ENABLE); I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return 0; return -5;
I2C_Send7bitAddress(I2C, address, I2C_Direction_Receiver); I2C_Send7bitAddress(I2C, address, I2C_Direction_Receiver);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
return 0; return -6;
I2C_AcknowledgeConfig(I2C, DISABLE); I2C_AcknowledgeConfig(I2C, DISABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
return 0; return -7;
uint8_t result = I2C_ReceiveData(I2C); uint8_t result = I2C_ReceiveData(I2C);
@ -123,11 +125,21 @@ void i2cWriteRegister(uint8_t address, uint8_t index, uint8_t data)
I2C_GenerateSTOP(I2C, ENABLE); I2C_GenerateSTOP(I2C, ENABLE);
} }
void setVolume(uint8_t volume) void setScaledVolume(uint8_t volume)
{ {
if (volume > VOLUME_LEVEL_MAX) { if (volume > VOLUME_LEVEL_MAX) {
volume = VOLUME_LEVEL_MAX; volume = VOLUME_LEVEL_MAX;
} }
i2cWriteRegister(I2C_ADDRESS_VOLUME, 0, volumeScale[volume]); setVolume(volumeScale[volume]);
}
void setVolume(uint8_t volume)
{
i2cWriteRegister(I2C_ADDRESS_VOLUME, 0, volume);
}
int32_t getVolume()
{
return i2cReadRegister(I2C_ADDRESS_VOLUME, 0);
} }

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "../../opentx.h" #include "../../opentx.h"
extern Fifo<32> sbusFifo; extern Fifo<32> sbusFifo;
@ -29,9 +29,9 @@ void init_trainer_ppm()
{ {
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses; trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
configure_pins( TRAINER_GPIO_PIN_OUT, PIN_PERIPHERAL | PIN_PORTB | PIN_PER_2 | PIN_OS25 | PIN_PUSHPULL ) ; configure_pins( TRAINER_GPIO_PIN_OUT, PIN_PERIPHERAL | PIN_PORTB | PIN_PER_2 | PIN_OS25 | PIN_PUSHPULL ) ;
configure_pins( TRAINER_GPIO_PIN_IN, PIN_PORTB | PIN_INPUT ) ; configure_pins( TRAINER_GPIO_PIN_IN, PIN_PORTC | PIN_INPUT ) ;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ;
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN ; TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN ;
@ -76,7 +76,7 @@ void init_trainer_capture()
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = TRAINER_GPIO_PIN_IN; GPIO_InitStructure.GPIO_Pin = TRAINER_GPIO_PIN_IN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

View file

@ -198,7 +198,7 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
// SWITCH_3_CASE(3, SWITCHES_GPIO_REG_D_L, SWITCHES_GPIO_REG_D_H, SWITCHES_GPIO_PIN_D_L, SWITCHES_GPIO_PIN_D_H) // SWITCH_3_CASE(3, SWITCHES_GPIO_REG_D_L, SWITCHES_GPIO_REG_D_H, SWITCHES_GPIO_PIN_D_L, SWITCHES_GPIO_PIN_D_H)
// SWITCH_CASE(4, SWITCHES_GPIO_REG_E, SWITCHES_GPIO_PIN_E) // SWITCH_CASE(4, SWITCHES_GPIO_REG_E, SWITCHES_GPIO_PIN_E)
// SWITCH_3_CASE(5, SWITCHES_GPIO_REG_F_H, SWITCHES_GPIO_REG_F_L, SWITCHES_GPIO_PIN_F_H, SWITCHES_GPIO_PIN_F_L) // SWITCH_3_CASE(5, SWITCHES_GPIO_REG_F_H, SWITCHES_GPIO_REG_F_L, SWITCHES_GPIO_PIN_F_H, SWITCHES_GPIO_PIN_F_L)
#elif defined(PCBTARANIS) && defined(REV9E) #elif defined(PCBTARANIS) || defined(PCBHORUS)
SWITCH_3_CASE(0, SWITCHES_GPIO_REG_A_L, SWITCHES_GPIO_REG_A_H, SWITCHES_GPIO_PIN_A_L, SWITCHES_GPIO_PIN_A_H) SWITCH_3_CASE(0, SWITCHES_GPIO_REG_A_L, SWITCHES_GPIO_REG_A_H, SWITCHES_GPIO_PIN_A_L, SWITCHES_GPIO_PIN_A_H)
SWITCH_3_CASE(1, SWITCHES_GPIO_REG_B_L, SWITCHES_GPIO_REG_B_H, SWITCHES_GPIO_PIN_B_L, SWITCHES_GPIO_PIN_B_H) SWITCH_3_CASE(1, SWITCHES_GPIO_REG_B_L, SWITCHES_GPIO_REG_B_H, SWITCHES_GPIO_PIN_B_L, SWITCHES_GPIO_PIN_B_H)
SWITCH_3_CASE(2, SWITCHES_GPIO_REG_C_L, SWITCHES_GPIO_REG_C_H, SWITCHES_GPIO_PIN_C_L, SWITCHES_GPIO_PIN_C_H) SWITCH_3_CASE(2, SWITCHES_GPIO_REG_C_L, SWITCHES_GPIO_REG_C_H, SWITCHES_GPIO_PIN_C_L, SWITCHES_GPIO_PIN_C_H)
@ -207,6 +207,7 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
SWITCH_CASE(5, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F) SWITCH_CASE(5, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F)
SWITCH_3_CASE(6, SWITCHES_GPIO_REG_G_L, SWITCHES_GPIO_REG_G_H, SWITCHES_GPIO_PIN_G_L, SWITCHES_GPIO_PIN_G_H) SWITCH_3_CASE(6, SWITCHES_GPIO_REG_G_L, SWITCHES_GPIO_REG_G_H, SWITCHES_GPIO_PIN_G_L, SWITCHES_GPIO_PIN_G_H)
SWITCH_CASE(7, SWITCHES_GPIO_REG_H, SWITCHES_GPIO_PIN_H) SWITCH_CASE(7, SWITCHES_GPIO_REG_H, SWITCHES_GPIO_PIN_H)
#if defined(REV9E)
SWITCH_3_CASE(8, SWITCHES_GPIO_REG_I_L, SWITCHES_GPIO_REG_I_H, SWITCHES_GPIO_PIN_I_L, SWITCHES_GPIO_PIN_I_H) SWITCH_3_CASE(8, SWITCHES_GPIO_REG_I_L, SWITCHES_GPIO_REG_I_H, SWITCHES_GPIO_PIN_I_L, SWITCHES_GPIO_PIN_I_H)
SWITCH_3_CASE(9, SWITCHES_GPIO_REG_J_L, SWITCHES_GPIO_REG_J_H, SWITCHES_GPIO_PIN_J_L, SWITCHES_GPIO_PIN_J_H) SWITCH_3_CASE(9, SWITCHES_GPIO_REG_J_L, SWITCHES_GPIO_REG_J_H, SWITCHES_GPIO_PIN_J_L, SWITCHES_GPIO_PIN_J_H)
SWITCH_3_CASE(10, SWITCHES_GPIO_REG_K_L, SWITCHES_GPIO_REG_K_H, SWITCHES_GPIO_PIN_K_L, SWITCHES_GPIO_PIN_K_H) SWITCH_3_CASE(10, SWITCHES_GPIO_REG_K_L, SWITCHES_GPIO_REG_K_H, SWITCHES_GPIO_PIN_K_L, SWITCHES_GPIO_PIN_K_H)
@ -217,15 +218,7 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
SWITCH_3_CASE(15, SWITCHES_GPIO_REG_P_L, SWITCHES_GPIO_REG_P_H, SWITCHES_GPIO_PIN_P_L, SWITCHES_GPIO_PIN_P_H) SWITCH_3_CASE(15, SWITCHES_GPIO_REG_P_L, SWITCHES_GPIO_REG_P_H, SWITCHES_GPIO_PIN_P_L, SWITCHES_GPIO_PIN_P_H)
SWITCH_3_CASE(16, SWITCHES_GPIO_REG_Q_L, SWITCHES_GPIO_REG_Q_H, SWITCHES_GPIO_PIN_Q_L, SWITCHES_GPIO_PIN_Q_H) SWITCH_3_CASE(16, SWITCHES_GPIO_REG_Q_L, SWITCHES_GPIO_REG_Q_H, SWITCHES_GPIO_PIN_Q_L, SWITCHES_GPIO_PIN_Q_H)
SWITCH_3_CASE(17, SWITCHES_GPIO_REG_R_L, SWITCHES_GPIO_REG_R_H, SWITCHES_GPIO_PIN_R_L, SWITCHES_GPIO_PIN_R_H) SWITCH_3_CASE(17, SWITCHES_GPIO_REG_R_L, SWITCHES_GPIO_REG_R_H, SWITCHES_GPIO_PIN_R_L, SWITCHES_GPIO_PIN_R_H)
#elif defined(PCBTARANIS) || defined(PCBHORUS) #endif
SWITCH_3_CASE(0, SWITCHES_GPIO_REG_A_L, SWITCHES_GPIO_REG_A_H, SWITCHES_GPIO_PIN_A_L, SWITCHES_GPIO_PIN_A_H)
SWITCH_3_CASE(1, SWITCHES_GPIO_REG_B_L, SWITCHES_GPIO_REG_B_H, SWITCHES_GPIO_PIN_B_L, SWITCHES_GPIO_PIN_B_H)
SWITCH_3_CASE(2, SWITCHES_GPIO_REG_C_L, SWITCHES_GPIO_REG_C_H, SWITCHES_GPIO_PIN_C_L, SWITCHES_GPIO_PIN_C_H)
SWITCH_3_CASE(3, SWITCHES_GPIO_REG_D_L, SWITCHES_GPIO_REG_D_H, SWITCHES_GPIO_PIN_D_L, SWITCHES_GPIO_PIN_D_H)
SWITCH_3_CASE(4, SWITCHES_GPIO_REG_E_H, SWITCHES_GPIO_REG_E_L, SWITCHES_GPIO_PIN_E_H, SWITCHES_GPIO_PIN_E_L)
SWITCH_CASE(5, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F)
SWITCH_3_CASE(6, SWITCHES_GPIO_REG_G_L, SWITCHES_GPIO_REG_G_H, SWITCHES_GPIO_PIN_G_L, SWITCHES_GPIO_PIN_G_H)
SWITCH_CASE(7, SWITCHES_GPIO_REG_H, SWITCHES_GPIO_PIN_H)
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
SWITCH_CASE(0, PIOC->PIO_PDSR, 1<<20) SWITCH_CASE(0, PIOC->PIO_PDSR, 1<<20)
SWITCH_CASE(1, PIOA->PIO_PDSR, 1<<15) SWITCH_CASE(1, PIOA->PIO_PDSR, 1<<15)
@ -467,6 +460,10 @@ bool dacQueue(AudioBuffer *buffer)
} }
void setVolume(uint8_t volume) void setVolume(uint8_t volume)
{
}
void setScaledVolume(uint8_t volume)
{ {
simuAudio.currentVolume = min<int>((volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)] * simuAudio.volumeGain) / 10, 127); simuAudio.currentVolume = min<int>((volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)] * simuAudio.volumeGain) / 10, 127);
// TRACE("setVolume(): in: %u, out: %u", volume, simuAudio.currentVolume); // TRACE("setVolume(): in: %u, out: %u", volume, simuAudio.currentVolume);
@ -574,7 +571,7 @@ void StartAudioThread(int volumeGain)
simuAudio.leftoverLen = 0; simuAudio.leftoverLen = 0;
simuAudio.threadRunning = true; simuAudio.threadRunning = true;
simuAudio.volumeGain = volumeGain; simuAudio.volumeGain = volumeGain;
setVolume(VOLUME_LEVEL_DEF); setScaledVolume(VOLUME_LEVEL_DEF);
pthread_attr_t attr; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_init(&attr);
@ -1342,3 +1339,9 @@ void i2cWriteTW8823(unsigned char, unsigned char) { }
uint8_t i2cReadBQ24195(uint8_t) { return 0; } uint8_t i2cReadBQ24195(uint8_t) { return 0; }
void i2cWriteBQ24195(uint8_t, uint8_t) { } void i2cWriteBQ24195(uint8_t, uint8_t) { }
#endif #endif
void serialPrintf(const char * format, ...) { }
void serialCrlf() { }
void serialPutc(char c) { }
uint16_t stackSize() { return 0; }
int32_t getVolume() { return 0; }

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "../../opentx.h" #include "../../opentx.h"
const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = const int8_t volumeScale[VOLUME_LEVEL_MAX+1] =
@ -161,7 +161,7 @@ void audioEnd()
PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC
} }
void setVolume(uint8_t volume) void setScaledVolume(uint8_t volume)
{ {
#if !defined(NO_HARDWARE_VOLUME) #if !defined(NO_HARDWARE_VOLUME)
volumeRequired = volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)]; volumeRequired = volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)];
@ -171,6 +171,5 @@ void setVolume(uint8_t volume)
#endif #endif
} }
#endif // #if !defined(SIMU) #endif // #if !defined(SIMU)

View file

@ -20,27 +20,27 @@
#ifndef _AUDIO_DRIVER_H_ #ifndef _AUDIO_DRIVER_H_
#define _AUDIO_DRIVER_H_ #define _AUDIO_DRIVER_H_
void audioInit( void ) ; void audioInit( void ) ;
void audioEnd( void ) ; void audioEnd( void ) ;
void setSampleRate( uint32_t frequency ) ; void setSampleRate( uint32_t frequency ) ;
inline void dacStart() inline void dacStart()
{ {
PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC
DACC->DACC_IER = DACC_IER_ENDTX ; DACC->DACC_IER = DACC_IER_ENDTX ;
} }
inline void dacStop() inline void dacStop()
{ {
DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt
} }
#define VOLUME_LEVEL_MAX 23 #define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12 #define VOLUME_LEVEL_DEF 12
extern const int8_t volumeScale[]; extern const int8_t volumeScale[];
void setVolume(uint8_t volume); void setScaledVolume(uint8_t volume);
#endif // _AUDIO_DRIVER_H_ #endif // _AUDIO_DRIVER_H_

View file

@ -1,25 +1,25 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifndef _BOARD_TARANIS_H_ #ifndef _BOARD_TARANIS_H_
#define _BOARD_TARANIS_H_ #define _BOARD_TARANIS_H_
#include "stddef.h" #include "stddef.h"
@ -328,7 +328,9 @@ void setSampleRate(uint32_t frequency);
extern const int8_t volumeScale[]; extern const int8_t volumeScale[];
#define VOLUME_LEVEL_MAX 23 #define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12 #define VOLUME_LEVEL_DEF 12
void setScaledVolume(uint8_t volume);
void setVolume(uint8_t volume); void setVolume(uint8_t volume);
int32_t getVolume(void);
// Haptic driver // Haptic driver
void hapticInit(void); void hapticInit(void);
@ -384,4 +386,4 @@ void usbJoystickUpdate(void);
extern uint8_t currentTrainerMode; extern uint8_t currentTrainerMode;
void checkTrainerSettings(void); void checkTrainerSettings(void);
#endif // _BOARD_TARANIS_H_ #endif // _BOARD_TARANIS_H_

View file

@ -1,25 +1,25 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifndef _HAL_H_ #ifndef _HAL_H_
#define _HAL_H_ #define _HAL_H_
// Keys // Keys
#define KEYS_GPIO_REG_MENU GPIOD->IDR #define KEYS_GPIO_REG_MENU GPIOD->IDR
@ -148,10 +148,10 @@
#define SWITCHES_GPIO_REG_E_L GPIOE->IDR #define SWITCHES_GPIO_REG_E_L GPIOE->IDR
#define SWITCHES_GPIO_PIN_E_L GPIO_Pin_13 // PE.13 #define SWITCHES_GPIO_PIN_E_L GPIO_Pin_13 // PE.13
#else #else
#define SWITCHES_GPIO_REG_E_L GPIOB->IDR
#define SWITCHES_GPIO_PIN_E_L GPIO_Pin_3 // PB.03
#define SWITCHES_GPIO_REG_E_H GPIOB->IDR #define SWITCHES_GPIO_REG_E_H GPIOB->IDR
#define SWITCHES_GPIO_PIN_E_H GPIO_Pin_4 // PB.04 #define SWITCHES_GPIO_PIN_E_H GPIO_Pin_3 // PB.03
#define SWITCHES_GPIO_REG_E_L GPIOB->IDR
#define SWITCHES_GPIO_PIN_E_L GPIO_Pin_4 // PB.04
#endif #endif
#if defined(REV9E) #if defined(REV9E)
@ -587,4 +587,4 @@
#define TIMER_2MHz_APB1Periph RCC_APB1Periph_TIM7 #define TIMER_2MHz_APB1Periph RCC_APB1Periph_TIM7
#define TIMER_2MHz_TIMER TIM7 #define TIMER_2MHz_TIMER TIM7
#endif // _HAL_H_ #endif // _HAL_H_

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "board_taranis.h" #include "board_taranis.h"
void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite); void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite);
@ -243,12 +243,17 @@ void eepromWaitEepromStandbyState(void)
} }
#if !defined(BOOT) #if !defined(BOOT)
void setVolume(uint8_t volume) void setScaledVolume(uint8_t volume)
{ {
if (volume > VOLUME_LEVEL_MAX) { if (volume > VOLUME_LEVEL_MAX) {
volume = VOLUME_LEVEL_MAX; volume = VOLUME_LEVEL_MAX;
} }
setVolume(volumeScale[volume]);
}
void setVolume(uint8_t volume)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return; return;
@ -263,29 +268,15 @@ void setVolume(uint8_t volume)
I2C_SendData(I2C, 0); I2C_SendData(I2C, 0);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return; return;
I2C_SendData(I2C, volumeScale[volume]); I2C_SendData(I2C, volume);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return; return;
I2C_GenerateSTOP(I2C, ENABLE); I2C_GenerateSTOP(I2C, ENABLE);
} }
#endif
#if 0 int32_t getVolume()
uint8_t I2C_read_volume()
{ {
uint8_t volume ; return 0; // TODO
I2C_START();
I2C_SEND_DATA(I2C_ADDRESS_VOLUME|EE_CMD_WRITE);
I2C_WAIT_ACK();
I2C_SEND_DATA(0);
I2C_WAIT_ACK();
I2C_START();
I2C_SEND_DATA(I2C_ADDRESS_VOLUME|EE_CMD_READ);
I2C_WAIT_ACK();
volume = I2C_READ();
I2C_NO_ACK();
I2C_STOP();
return volume ;
} }
#endif #endif

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "../../opentx.h" #include "../../opentx.h"
uint32_t readKeys() uint32_t readKeys()
@ -175,7 +175,6 @@ void readKeysAndTrims()
case SW_S ## x ## 2: \ case SW_S ## x ## 2: \
xxx = (~SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H) && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \ xxx = (~SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H) && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
break break
#define ADD_3POS_INVERTED_CASE(x, i) ADD_3POS_CASE(x, i)
#else #else
#define ADD_2POS_CASE(x) \ #define ADD_2POS_CASE(x) \
case SW_S ## x ## 0: \ case SW_S ## x ## 0: \
@ -200,22 +199,6 @@ void readKeysAndTrims()
xxx = xxx && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \ xxx = xxx && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
} \ } \
break break
#define ADD_3POS_INVERTED_CASE(x, i) \
case SW_S ## x ## 0: \
xxx = (~SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H); \
if (IS_3POS(i)) { \
xxx = xxx && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
} \
break; \
case SW_S ## x ## 1: \
xxx = (SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H) && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
break; \
case SW_S ## x ## 2: \
xxx = (SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H); \
if (IS_3POS(i)) { \
xxx = xxx && (~SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
} \
break
#endif #endif
#if !defined(BOOT) #if !defined(BOOT)
@ -230,7 +213,7 @@ bool switchState(EnumKeys enuk)
ADD_3POS_CASE(B, 1); ADD_3POS_CASE(B, 1);
ADD_3POS_CASE(C, 2); ADD_3POS_CASE(C, 2);
ADD_3POS_CASE(D, 3); ADD_3POS_CASE(D, 3);
ADD_3POS_INVERTED_CASE(E, 4); ADD_3POS_CASE(E, 4);
ADD_2POS_CASE(F); ADD_2POS_CASE(F);
ADD_3POS_CASE(G, 6); ADD_3POS_CASE(G, 6);
ADD_2POS_CASE(H); ADD_2POS_CASE(H);

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "../../pwr.h" #include "../../pwr.h"
#include "board_taranis.h" #include "board_taranis.h"

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include "opentx.h" #include "opentx.h"
#define ISTR(x) LEN_##x TR_##x #define ISTR(x) LEN_##x TR_##x
@ -172,8 +172,6 @@ const pm_char STR_BUZZER[] PROGMEM = TR_BUZZER;
#endif #endif
const pm_char STR_NOFREEEXPO[] PROGMEM = TR_NOFREEEXPO; const pm_char STR_NOFREEEXPO[] PROGMEM = TR_NOFREEEXPO;
const pm_char STR_NOFREEMIXER[] PROGMEM = TR_NOFREEMIXER; const pm_char STR_NOFREEMIXER[] PROGMEM = TR_NOFREEMIXER;
const pm_char STR_INSERTMIX[] PROGMEM = TR_INSERTMIX;
const pm_char STR_EDITMIX[] PROGMEM = TR_EDITMIX;
const pm_char STR_SOURCE[] PROGMEM = TR_SOURCE; const pm_char STR_SOURCE[] PROGMEM = TR_SOURCE;
const pm_char STR_WEIGHT[] PROGMEM = TR_WEIGHT; const pm_char STR_WEIGHT[] PROGMEM = TR_WEIGHT;
const pm_char STR_EXPO[] PROGMEM = TR_EXPO; const pm_char STR_EXPO[] PROGMEM = TR_EXPO;
@ -337,7 +335,6 @@ const pm_char STR_MENUCUSTOMFUNC[] PROGMEM = TR_MENUCUSTOMFUNC;
#if defined(LUA) #if defined(LUA)
const pm_char STR_MENUCUSTOMSCRIPTS[] PROGMEM = TR_MENUCUSTOMSCRIPTS; const pm_char STR_MENUCUSTOMSCRIPTS[] PROGMEM = TR_MENUCUSTOMSCRIPTS;
const pm_char STR_MENUCUSTOMSCRIPT[] PROGMEM = TR_MENUCUSTOMSCRIPT;
#endif #endif
#if defined(FRSKY) #if defined(FRSKY)
@ -365,6 +362,7 @@ const pm_char STR_COUNTRYCODE[] PROGMEM = TR_COUNTRYCODE;
const pm_char STR_FAILSAFE[] PROGMEM = TR_FAILSAFE; const pm_char STR_FAILSAFE[] PROGMEM = TR_FAILSAFE;
const pm_char STR_FAILSAFESET[] PROGMEM = TR_FAILSAFESET; const pm_char STR_FAILSAFESET[] PROGMEM = TR_FAILSAFESET;
const pm_char STR_MENUSENSOR[] PROGMEM = TR_MENUSENSOR; const pm_char STR_MENUSENSOR[] PROGMEM = TR_MENUSENSOR;
const pm_char STR_SENSOR[] PROGMEM = TR_SENSOR;
#endif #endif
const pm_char STR_INVERT_THR[] PROGMEM = TR_INVERT_THR; const pm_char STR_INVERT_THR[] PROGMEM = TR_INVERT_THR;
@ -408,11 +406,11 @@ const pm_char STR_PERSISTENT_MAH[] PROGMEM = TR_PERSISTENT_MAH;
#if defined(NAVIGATION_MENUS) #if defined(NAVIGATION_MENUS)
const pm_char STR_SELECT_MODEL[] PROGMEM = TR_SELECT_MODEL; const pm_char STR_SELECT_MODEL[] PROGMEM = TR_SELECT_MODEL;
const pm_char STR_CREATE_CATEGORY[] PROGMEM = TR_CREATE_CATEGORY; const pm_char STR_CREATE_CATEGORY[] PROGMEM = TR_CREATE_CATEGORY;
const pm_char STR_RENAME_CATEGORY[] PROGMEM = TR_RENAME_CATEGORY; const pm_char STR_RENAME_CATEGORY[] PROGMEM = TR_RENAME_CATEGORY;
const pm_char STR_DELETE_CATEGORY[] PROGMEM = TR_DELETE_CATEGORY; const pm_char STR_DELETE_CATEGORY[] PROGMEM = TR_DELETE_CATEGORY;
const pm_char STR_CREATE_MODEL[] PROGMEM = TR_CREATE_MODEL; const pm_char STR_CREATE_MODEL[] PROGMEM = TR_CREATE_MODEL;
const pm_char STR_DUPLICATE_MODEL[] PROGMEM = TR_DUPLICATE_MODEL; const pm_char STR_DUPLICATE_MODEL[] PROGMEM = TR_DUPLICATE_MODEL;
const pm_char STR_COPY_MODEL[] PROGMEM = TR_COPY_MODEL; const pm_char STR_COPY_MODEL[] PROGMEM = TR_COPY_MODEL;
const pm_char STR_MOVE_MODEL[] PROGMEM = TR_MOVE_MODEL; const pm_char STR_MOVE_MODEL[] PROGMEM = TR_MOVE_MODEL;
const pm_char STR_DELETE_MODEL[] PROGMEM = TR_DELETE_MODEL; const pm_char STR_DELETE_MODEL[] PROGMEM = TR_DELETE_MODEL;
@ -477,10 +475,10 @@ const pm_char STR_NO_SOUNDS_ON_SD[] PROGMEM = TR_NO_SOUNDS_ON_SD;
const pm_char STR_NO_MODELS_ON_SD[] PROGMEM = TR_NO_MODELS_ON_SD; const pm_char STR_NO_MODELS_ON_SD[] PROGMEM = TR_NO_MODELS_ON_SD;
const pm_char STR_NO_BITMAPS_ON_SD[] PROGMEM = TR_NO_BITMAPS_ON_SD; const pm_char STR_NO_BITMAPS_ON_SD[] PROGMEM = TR_NO_BITMAPS_ON_SD;
const pm_char STR_NO_SCRIPTS_ON_SD[] PROGMEM = TR_NO_SCRIPTS_ON_SD; const pm_char STR_NO_SCRIPTS_ON_SD[] PROGMEM = TR_NO_SCRIPTS_ON_SD;
const pm_char STR_SCRIPT_SYNTAX_ERROR[] PROGMEM = TR_SCRIPT_SYNTAX_ERROR; const pm_char STR_SCRIPT_SYNTAX_ERROR[] PROGMEM = TR_SCRIPT_SYNTAX_ERROR;
const pm_char STR_SCRIPT_PANIC[] PROGMEM = TR_SCRIPT_PANIC; const pm_char STR_SCRIPT_PANIC[] PROGMEM = TR_SCRIPT_PANIC;
const pm_char STR_SCRIPT_KILLED[] PROGMEM = TR_SCRIPT_KILLED; const pm_char STR_SCRIPT_KILLED[] PROGMEM = TR_SCRIPT_KILLED;
const pm_char STR_SCRIPT_ERROR[] PROGMEM = TR_SCRIPT_ERROR; const pm_char STR_SCRIPT_ERROR[] PROGMEM = TR_SCRIPT_ERROR;
const pm_char STR_PLAY_FILE[] PROGMEM = TR_PLAY_FILE; const pm_char STR_PLAY_FILE[] PROGMEM = TR_PLAY_FILE;
const pm_char STR_ASSIGN_BITMAP[] PROGMEM = TR_ASSIGN_BITMAP; const pm_char STR_ASSIGN_BITMAP[] PROGMEM = TR_ASSIGN_BITMAP;
const pm_char STR_EXECUTE_FILE[] PROGMEM = TR_EXECUTE_FILE; const pm_char STR_EXECUTE_FILE[] PROGMEM = TR_EXECUTE_FILE;
@ -503,7 +501,7 @@ const pm_char STR_SD_SECTORS[] PROGMEM = TR_SD_SECTORS;
const pm_char STR_SD_SIZE[] PROGMEM = TR_SD_SIZE; const pm_char STR_SD_SIZE[] PROGMEM = TR_SD_SIZE;
const pm_char STR_TYPE[] PROGMEM = TR_TYPE; const pm_char STR_TYPE[] PROGMEM = TR_TYPE;
const pm_char STR_GLOBAL_VARS[] PROGMEM = TR_GLOBAL_VARS; const pm_char STR_GLOBAL_VARS[] PROGMEM = TR_GLOBAL_VARS;
const pm_char STR_GLOBAL_V[] PROGMEM = TR_GLOBAL_V; const pm_char STR_GVARS[] PROGMEM = TR_GVARS;
const pm_char STR_GLOBAL_VAR[] PROGMEM = TR_GLOBAL_VAR; const pm_char STR_GLOBAL_VAR[] PROGMEM = TR_GLOBAL_VAR;
const pm_char STR_OWN[] PROGMEM = TR_OWN; const pm_char STR_OWN[] PROGMEM = TR_OWN;
const pm_char STR_ROTARY_ENCODER[] PROGMEM = TR_ROTARY_ENCODER; const pm_char STR_ROTARY_ENCODER[] PROGMEM = TR_ROTARY_ENCODER;
@ -545,7 +543,7 @@ const pm_char STR_BLCOLOR[] PROGMEM = TR_BLCOLOR;
const pm_char STR_PREFLIGHT[] PROGMEM = TR_PREFLIGHT; const pm_char STR_PREFLIGHT[] PROGMEM = TR_PREFLIGHT;
const pm_char STR_CHECKLIST[] PROGMEM = TR_CHECKLIST; const pm_char STR_CHECKLIST[] PROGMEM = TR_CHECKLIST;
const pm_char STR_VIEW_NOTES[] PROGMEM = TR_VIEW_NOTES; const pm_char STR_VIEW_NOTES[] PROGMEM = TR_VIEW_NOTES;
const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT; const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT;
const pm_char STR_RESET_SUBMENU[] PROGMEM = TR_RESET_SUBMENU; const pm_char STR_RESET_SUBMENU[] PROGMEM = TR_RESET_SUBMENU;
const pm_char STR_LOWALARM[] PROGMEM = TR_LOWALARM; const pm_char STR_LOWALARM[] PROGMEM = TR_LOWALARM;
const pm_char STR_CRITICALALARM[] PROGMEM = TR_CRITICALALARM; const pm_char STR_CRITICALALARM[] PROGMEM = TR_CRITICALALARM;
@ -572,10 +570,10 @@ const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT;
const pm_char STR_TELEMETRYFULL[] PROGMEM = TR_TELEMETRYFULL; const pm_char STR_TELEMETRYFULL[] PROGMEM = TR_TELEMETRYFULL;
const pm_char STR_INVERTED_SERIAL[] PROGMEM = TR_INVERTED_SERIAL; const pm_char STR_INVERTED_SERIAL[] PROGMEM = TR_INVERTED_SERIAL;
const pm_char STR_IGNORE_INSTANCE[] PROGMEM = TR_IGNORE_INSTANCE; const pm_char STR_IGNORE_INSTANCE[] PROGMEM = TR_IGNORE_INSTANCE;
const pm_char STR_DISCOVER_SENSORS[] PROGMEM = TR_DISCOVER_SENSORS; const pm_char STR_DISCOVER_SENSORS[] PROGMEM = TR_DISCOVER_SENSORS;
const pm_char STR_STOP_DISCOVER_SENSORS[] PROGMEM = TR_STOP_DISCOVER_SENSORS; const pm_char STR_STOP_DISCOVER_SENSORS[] PROGMEM = TR_STOP_DISCOVER_SENSORS;
const pm_char STR_DELETE_ALL_SENSORS[] PROGMEM = TR_DELETE_ALL_SENSORS; const pm_char STR_DELETE_ALL_SENSORS[] PROGMEM = TR_DELETE_ALL_SENSORS;
const pm_char STR_CONFIRMDELETE[] PROGMEM = TR_CONFIRMDELETE; const pm_char STR_CONFIRMDELETE[] PROGMEM = TR_CONFIRMDELETE;
#endif #endif
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS) #if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
@ -584,6 +582,9 @@ const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT;
const pm_char STR_MODULE[] PROGMEM = TR_MODULE; const pm_char STR_MODULE[] PROGMEM = TR_MODULE;
const pm_char STR_ENABLE_POPUP[] PROGMEM = TR_ENABLE_POPUP; const pm_char STR_ENABLE_POPUP[] PROGMEM = TR_ENABLE_POPUP;
const pm_char STR_DISABLE_POPUP[] PROGMEM = TR_DISABLE_POPUP; const pm_char STR_DISABLE_POPUP[] PROGMEM = TR_DISABLE_POPUP;
const pm_char STR_POPUP[] PROGMEM = TR_POPUP;
const pm_char STR_MIN[] PROGMEM = TR_MIN;
const pm_char STR_MAX[] PROGMEM = TR_MAX;
const pm_char STR_CURVE_PRESET[] PROGMEM = TR_CURVE_PRESET; const pm_char STR_CURVE_PRESET[] PROGMEM = TR_CURVE_PRESET;
const pm_char STR_PRESET[] PROGMEM = TR_PRESET; const pm_char STR_PRESET[] PROGMEM = TR_PRESET;
const pm_char STR_MIRROR[] PROGMEM = TR_MIRROR; const pm_char STR_MIRROR[] PROGMEM = TR_MIRROR;
@ -595,10 +596,10 @@ const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT;
const pm_char STR_SMOOTH[] PROGMEM = TR_SMOOTH; const pm_char STR_SMOOTH[] PROGMEM = TR_SMOOTH;
const pm_char STR_COPY_STICKS_TO_OFS[] PROGMEM = TR_COPY_STICKS_TO_OFS; const pm_char STR_COPY_STICKS_TO_OFS[] PROGMEM = TR_COPY_STICKS_TO_OFS;
const pm_char STR_COPY_TRIMS_TO_OFS[] PROGMEM = TR_COPY_TRIMS_TO_OFS; const pm_char STR_COPY_TRIMS_TO_OFS[] PROGMEM = TR_COPY_TRIMS_TO_OFS;
const pm_char STR_INCDEC[] PROGMEM = TR_INCDEC; const pm_char STR_INCDEC[] PROGMEM = TR_INCDEC;
const pm_char STR_GLOBALVAR[] PROGMEM = TR_GLOBALVAR; const pm_char STR_GLOBALVAR[] PROGMEM = TR_GLOBALVAR;
const pm_char STR_MIXSOURCE[] PROGMEM = TR_MIXSOURCE; const pm_char STR_MIXSOURCE[] PROGMEM = TR_MIXSOURCE;
const pm_char STR_CONSTANT[] PROGMEM = TR_CONSTANT; const pm_char STR_CONSTANT[] PROGMEM = TR_CONSTANT;
const pm_char STR_TOP_BAR[] PROGMEM = TR_TOP_BAR; const pm_char STR_TOP_BAR[] PROGMEM = TR_TOP_BAR;
const pm_char STR_ALTITUDE[] PROGMEM = TR_ALTITUDE; const pm_char STR_ALTITUDE[] PROGMEM = TR_ALTITUDE;
const pm_char STR_SCALE[] PROGMEM = TR_SCALE; const pm_char STR_SCALE[] PROGMEM = TR_SCALE;

View file

@ -1,25 +1,25 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifndef _TRANSLATIONS_H_ #ifndef _TRANSLATIONS_H_
#define _TRANSLATIONS_H_ #define _TRANSLATIONS_H_
#if defined(TRANSLATIONS_FR) #if defined(TRANSLATIONS_FR)
#include "translations/fr.h" #include "translations/fr.h"
@ -370,8 +370,6 @@ extern const pm_char STR_BUZZER[];
#endif #endif
extern const pm_char STR_NOFREEEXPO[]; extern const pm_char STR_NOFREEEXPO[];
extern const pm_char STR_NOFREEMIXER[]; extern const pm_char STR_NOFREEMIXER[];
extern const pm_char STR_INSERTMIX[];
extern const pm_char STR_EDITMIX[];
extern const pm_char STR_SOURCE[]; extern const pm_char STR_SOURCE[];
extern const pm_char STR_WEIGHT[]; extern const pm_char STR_WEIGHT[];
extern const pm_char STR_EXPO[]; extern const pm_char STR_EXPO[];
@ -509,7 +507,6 @@ extern const pm_char STR_MENULOGICALSWITCH[];
extern const pm_char STR_MENULOGICALSWITCHES[]; extern const pm_char STR_MENULOGICALSWITCHES[];
extern const pm_char STR_MENUCUSTOMFUNC[]; extern const pm_char STR_MENUCUSTOMFUNC[];
extern const pm_char STR_MENUCUSTOMSCRIPTS[]; extern const pm_char STR_MENUCUSTOMSCRIPTS[];
extern const pm_char STR_MENUCUSTOMSCRIPT[];
extern const pm_char STR_MENUTELEMETRY[]; extern const pm_char STR_MENUTELEMETRY[];
extern const pm_char STR_MENUTEMPLATES[]; extern const pm_char STR_MENUTEMPLATES[];
extern const pm_char STR_MENUSTAT[]; extern const pm_char STR_MENUSTAT[];
@ -535,6 +532,7 @@ extern const pm_char STR_EXTERNALRF[];
extern const pm_char STR_FAILSAFE[]; extern const pm_char STR_FAILSAFE[];
extern const pm_char STR_FAILSAFESET[]; extern const pm_char STR_FAILSAFESET[];
extern const pm_char STR_MENUSENSOR[]; extern const pm_char STR_MENUSENSOR[];
extern const pm_char STR_SENSOR[];
extern const pm_char STR_COUNTRYCODE[]; extern const pm_char STR_COUNTRYCODE[];
#endif #endif
@ -679,7 +677,7 @@ extern const pm_char STR_SD_SECTORS[];
extern const pm_char STR_SD_SIZE[]; extern const pm_char STR_SD_SIZE[];
extern const pm_char STR_TYPE[]; extern const pm_char STR_TYPE[];
extern const pm_char STR_GLOBAL_VARS[]; extern const pm_char STR_GLOBAL_VARS[];
extern const pm_char STR_GLOBAL_V[]; extern const pm_char STR_GVARS[];
extern const pm_char STR_GLOBAL_VAR[]; extern const pm_char STR_GLOBAL_VAR[];
extern const pm_char STR_OWN[]; extern const pm_char STR_OWN[];
extern const pm_char STR_ROTARY_ENCODER[]; extern const pm_char STR_ROTARY_ENCODER[];
@ -829,6 +827,9 @@ extern const pm_char STR_BLCOLOR[];
extern const pm_char STR_MODULE[]; extern const pm_char STR_MODULE[];
extern const pm_char STR_ENABLE_POPUP[]; extern const pm_char STR_ENABLE_POPUP[];
extern const pm_char STR_DISABLE_POPUP[]; extern const pm_char STR_DISABLE_POPUP[];
extern const pm_char STR_POPUP[];
extern const pm_char STR_MIN[];
extern const pm_char STR_MAX[];
extern const pm_char STR_CURVE_PRESET[]; extern const pm_char STR_CURVE_PRESET[];
extern const pm_char STR_PRESET[]; extern const pm_char STR_PRESET[];
extern const pm_char STR_MIRROR[]; extern const pm_char STR_MIRROR[];
@ -958,4 +959,4 @@ extern const pm_char STR_BLCOLOR[];
#define CHR_HOUR TR_CHR_HOUR #define CHR_HOUR TR_CHR_HOUR
#define CHR_INPUT TR_CHR_INPUT #define CHR_INPUT TR_CHR_INPUT
#endif // _TRANSLATIONS_H_ #endif // _TRANSLATIONS_H_

View file

@ -627,8 +627,6 @@
#define TR_MODE INDENT"Mód" #define TR_MODE INDENT"Mód"
#define TR_NOFREEEXPO "Není volné expo!" #define TR_NOFREEEXPO "Není volné expo!"
#define TR_NOFREEMIXER "Není volný mix!" #define TR_NOFREEMIXER "Není volný mix!"
#define TR_INSERTMIX "VLOžIT MIX "
#define TR_EDITMIX "UPRAVIT MIX "
#define TR_SOURCE INDENT"Zdroj" #define TR_SOURCE INDENT"Zdroj"
#define TR_WEIGHT "Váha" #define TR_WEIGHT "Váha"
#define TR_EXPO "Expo" #define TR_EXPO "Expo"
@ -777,7 +775,6 @@
#define TR_MENULOGICALSWITCHES "LOGICKÉ SPÍNAčE" #define TR_MENULOGICALSWITCHES "LOGICKÉ SPÍNAčE"
#define TR_MENUCUSTOMFUNC "SPECIÁLNÍ FUNKCE" #define TR_MENUCUSTOMFUNC "SPECIÁLNÍ FUNKCE"
#define TR_MENUCUSTOMSCRIPTS "SKRIPTY LUA" #define TR_MENUCUSTOMSCRIPTS "SKRIPTY LUA"
#define TR_MENUCUSTOMSCRIPT "SKRIPT"
#define TR_MENUTELEMETRY "TELEMETRIE" #define TR_MENUTELEMETRY "TELEMETRIE"
#define TR_MENUTEMPLATES "ŠABLONY" #define TR_MENUTEMPLATES "ŠABLONY"
#define TR_MENUSTAT "STATISTIKA" #define TR_MENUSTAT "STATISTIKA"
@ -876,7 +873,7 @@
#define TR_SD_SIZE "Velikost:" #define TR_SD_SIZE "Velikost:"
#define TR_TYPE INDENT TR_SD_TYPE #define TR_TYPE INDENT TR_SD_TYPE
#define TR_GLOBAL_VARS "Globální proměnné" #define TR_GLOBAL_VARS "Globální proměnné"
#define TR_GLOBAL_V "GLOB.PROM." #define TR_GVARS "GLOB.PROM."
#define TR_GLOBAL_VAR "Globální proměnná" #define TR_GLOBAL_VAR "Globální proměnná"
#define TR_MENUGLOBALVARS "GLOBÁLNÍ PROMěNNÉ" #define TR_MENUGLOBALVARS "GLOBÁLNÍ PROMěNNÉ"
#define TR_OWN " \043 " #define TR_OWN " \043 "
@ -896,6 +893,7 @@
#define TR_FAILSAFE "Mód Failsafe" #define TR_FAILSAFE "Mód Failsafe"
#define TR_FAILSAFESET "NASTAVENÍ FAILSAFE" #define TR_FAILSAFESET "NASTAVENÍ FAILSAFE"
#define TR_MENUSENSOR "SENZOR" #define TR_MENUSENSOR "SENZOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Kód regionu" #define TR_COUNTRYCODE "Kód regionu"
#define TR_VOICELANG "Jazyk hlasu" #define TR_VOICELANG "Jazyk hlasu"
#define TR_UNITSSYSTEM "Jednotky" #define TR_UNITSSYSTEM "Jednotky"
@ -939,6 +937,9 @@
#define TR_CRITICALALARM INDENT "Kritický Alarm" #define TR_CRITICALALARM INDENT "Kritický Alarm"
#define TR_ENABLE_POPUP "Povolit vyskakovací okno" #define TR_ENABLE_POPUP "Povolit vyskakovací okno"
#define TR_DISABLE_POPUP "Zakázat vyskakovací okno" #define TR_DISABLE_POPUP "Zakázat vyskakovací okno"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Šablona" #define TR_CURVE_PRESET "Šablona"
#define TR_PRESET "Šablona" #define TR_PRESET "Šablona"
#define TR_MIRROR "Zrcadlit" #define TR_MIRROR "Zrcadlit"

View file

@ -631,8 +631,6 @@
#define TR_MODE INDENT "Modus" #define TR_MODE INDENT "Modus"
#define TR_NOFREEEXPO "Expos voll!" #define TR_NOFREEEXPO "Expos voll!"
#define TR_NOFREEMIXER "Mischer voll!" #define TR_NOFREEMIXER "Mischer voll!"
#define TR_INSERTMIX "MISCHER Hinz."
#define TR_EDITMIX "MISCHER Edit"
#define TR_SOURCE INDENT "Quelle" #define TR_SOURCE INDENT "Quelle"
#define TR_WEIGHT "Gewicht" #define TR_WEIGHT "Gewicht"
#define TR_EXPO TR("Expo", "Exponential") #define TR_EXPO TR("Expo", "Exponential")
@ -781,7 +779,6 @@
#define TR_MENULOGICALSWITCHES "LOGIKSCHALTER" #define TR_MENULOGICALSWITCHES "LOGIKSCHALTER"
#define TR_MENUCUSTOMFUNC TR("SPEZ.-FUNKTIONEN", "SPEZIAL-FUNKTIONEN") #define TR_MENUCUSTOMFUNC TR("SPEZ.-FUNKTIONEN", "SPEZIAL-FUNKTIONEN")
#define TR_MENUCUSTOMSCRIPTS "LUA-SCRIPTE" #define TR_MENUCUSTOMSCRIPTS "LUA-SCRIPTE"
#define TR_MENUCUSTOMSCRIPT "LUA-SCRIPT"
#define TR_MENUTELEMETRY "TELEMETRIE" #define TR_MENUTELEMETRY "TELEMETRIE"
#define TR_MENUTEMPLATES "VORLAGEN" #define TR_MENUTEMPLATES "VORLAGEN"
#define TR_MENUSTAT "STAT" #define TR_MENUSTAT "STAT"
@ -809,11 +806,11 @@
#define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spannungsquelle") //9XR-Pro #define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spannungsquelle") //9XR-Pro
#define TR_CURRENT TR(INDENT "Strom", INDENT "Stromquelle") #define TR_CURRENT TR(INDENT "Strom", INDENT "Stromquelle")
#define TR_SELECT_MODEL "Modell Wählen" #define TR_SELECT_MODEL "Modell Wählen"
#define TR_CREATE_CATEGORY "Create Category" #define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category" #define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category" #define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Neues Modell" #define TR_CREATE_MODEL "Neues Modell"
#define TR_DUPLICATE_MODEL "Duplicate Model" #define TR_DUPLICATE_MODEL "Duplicate Model"
#define TR_COPY_MODEL "Kopiere Modell" #define TR_COPY_MODEL "Kopiere Modell"
#define TR_MOVE_MODEL "Verschiebe Modell" #define TR_MOVE_MODEL "Verschiebe Modell"
#define TR_BACKUP_MODEL "Modell auf SD-Karte" //9XR-Pro #define TR_BACKUP_MODEL "Modell auf SD-Karte" //9XR-Pro
@ -880,7 +877,7 @@
#define TR_SD_SIZE "Größe:" #define TR_SD_SIZE "Größe:"
#define TR_TYPE INDENT "Type" #define TR_TYPE INDENT "Type"
#define TR_GLOBAL_VARS "Globale Variablen" #define TR_GLOBAL_VARS "Globale Variablen"
#define TR_GLOBAL_V "GLOBALE V." #define TR_GVARS "GLOBALE V."
#define TR_GLOBAL_VAR "Globale Variable" #define TR_GLOBAL_VAR "Globale Variable"
#define TR_MENUGLOBALVARS "GLOBALE VARIABLEN" #define TR_MENUGLOBALVARS "GLOBALE VARIABLEN"
#define TR_OWN "Eigen" #define TR_OWN "Eigen"
@ -900,6 +897,7 @@
#define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Mode") #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Mode")
#define TR_FAILSAFESET "Failsafe setzen" #define TR_FAILSAFESET "Failsafe setzen"
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Landescode" #define TR_COUNTRYCODE "Landescode"
#define TR_VOICELANG "Sprach-Ansage" #define TR_VOICELANG "Sprach-Ansage"
#define TR_UNITSSYSTEM "Einheiten" #define TR_UNITSSYSTEM "Einheiten"
@ -943,6 +941,9 @@
#define TR_CRITICALALARM INDENT "Kritisch-Alarm" #define TR_CRITICALALARM INDENT "Kritisch-Alarm"
#define TR_ENABLE_POPUP "Freigabe Popup-Fenster" #define TR_ENABLE_POPUP "Freigabe Popup-Fenster"
#define TR_DISABLE_POPUP "Sperren Popup-Fenster" #define TR_DISABLE_POPUP "Sperren Popup-Fenster"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Gerade 0 11 22 33 45" #define TR_CURVE_PRESET "Gerade 0 11 22 33 45"
#define TR_PRESET "Preset" #define TR_PRESET "Preset"
#define TR_MIRROR "Spiegeln" #define TR_MIRROR "Spiegeln"
@ -1071,7 +1072,7 @@
#define TR_SCALE "Skalierer" #define TR_SCALE "Skalierer"
#define TR_VIEW_CHANNELS "Zeige Kanäle" #define TR_VIEW_CHANNELS "Zeige Kanäle"
#define TR_VIEW_NOTES "Zeige Notizen" #define TR_VIEW_NOTES "Zeige Notizen"
#define TR_MODEL_SELECT "Model Select" #define TR_MODEL_SELECT "Model Select"
#define TR_MODS_FORBIDDEN "Veränderungen verboten!" #define TR_MODS_FORBIDDEN "Veränderungen verboten!"
#define TR_UNLOCKED "Entsperrt" #define TR_UNLOCKED "Entsperrt"
#define TR_ID "ID" #define TR_ID "ID"
@ -1090,7 +1091,7 @@
#define TR_ONLYPOSITIVE "Nur Positiv" #define TR_ONLYPOSITIVE "Nur Positiv"
#define TR_FILTER "Filter aktiv" #define TR_FILTER "Filter aktiv"
#define TR_TELEMETRYFULL "Telemetriezeilen voll!" #define TR_TELEMETRYFULL "Telemetriezeilen voll!"
#define TR_INVERTED_SERIAL INDENT "Invert." #define TR_INVERTED_SERIAL INDENT "Invert."
#define TR_IGNORE_INSTANCE TR(INDENT "Keine ID", INDENT "Keine Multisen-ID") //unklar #define TR_IGNORE_INSTANCE TR(INDENT "Keine ID", INDENT "Keine Multisen-ID") //unklar
#define TR_DISCOVER_SENSORS INDENT "Start Sensorsuche" #define TR_DISCOVER_SENSORS INDENT "Start Sensorsuche"
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop Sensorsuche" #define TR_STOP_DISCOVER_SENSORS INDENT "Stop Sensorsuche"
@ -1121,7 +1122,7 @@
#define ZSTR_A4 "A4" #define ZSTR_A4 "A4"
#define ZSTR_BATT "RxBt" #define ZSTR_BATT "RxBt"
#define ZSTR_ALT "Alt" #define ZSTR_ALT "Alt"
#define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP1 "Tmp1"
#define ZSTR_TEMP2 "Tmp2" #define ZSTR_TEMP2 "Tmp2"
#define ZSTR_RPM "RPM" #define ZSTR_RPM "RPM"
#define ZSTR_FUEL "Fuel" #define ZSTR_FUEL "Fuel"

View file

@ -129,7 +129,9 @@
#define LEN_RETA123 "\001" #define LEN_RETA123 "\001"
#if defined(PCBFLAMENCO) #if defined(PCBHORUS)
#define TR_RETA123 "RETA12345LR"
#elif defined(PCBFLAMENCO)
#define TR_RETA123 "RETA123LR" #define TR_RETA123 "RETA123LR"
#elif defined(PCBTARANIS) && defined(REV9E) #elif defined(PCBTARANIS) && defined(REV9E)
#define TR_RETA123 "RETA1234LRLR" #define TR_RETA123 "RETA1234LRLR"
@ -650,8 +652,6 @@
#define TR_MODE INDENT "Mode" #define TR_MODE INDENT "Mode"
#define TR_NOFREEEXPO "No free expo!" #define TR_NOFREEEXPO "No free expo!"
#define TR_NOFREEMIXER "No free mixer!" #define TR_NOFREEMIXER "No free mixer!"
#define TR_INSERTMIX "INSERT MIX "
#define TR_EDITMIX "EDIT MIX "
#define TR_SOURCE INDENT "Source" #define TR_SOURCE INDENT "Source"
#define TR_WEIGHT "Weight" #define TR_WEIGHT "Weight"
#define TR_EXPO TR("Expo", "Exponential") #define TR_EXPO TR("Expo", "Exponential")
@ -804,7 +804,6 @@
#define TR_MENULOGICALSWITCHES "LOGICAL SWITCHES" #define TR_MENULOGICALSWITCHES "LOGICAL SWITCHES"
#define TR_MENUCUSTOMFUNC "SPECIAL FUNCTIONS" #define TR_MENUCUSTOMFUNC "SPECIAL FUNCTIONS"
#define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS" #define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS"
#define TR_MENUCUSTOMSCRIPT "CUSTOM SCRIPT"
#define TR_MENUTELEMETRY "TELEMETRY" #define TR_MENUTELEMETRY "TELEMETRY"
#define TR_MENUTEMPLATES "TEMPLATES" #define TR_MENUTEMPLATES "TEMPLATES"
#define TR_MENUSTAT "STATS" #define TR_MENUSTAT "STATS"
@ -904,7 +903,7 @@
#define TR_SD_SIZE "Size:" #define TR_SD_SIZE "Size:"
#define TR_TYPE INDENT "Type" #define TR_TYPE INDENT "Type"
#define TR_GLOBAL_VARS "Global Variables" #define TR_GLOBAL_VARS "Global Variables"
#define TR_GLOBAL_V "GLOBAL V." #define TR_GVARS "GVARS"
#define TR_GLOBAL_VAR "Global Variable" #define TR_GLOBAL_VAR "Global Variable"
#define TR_MENUGLOBALVARS "GLOBAL VARIABLES" #define TR_MENUGLOBALVARS "GLOBAL VARIABLES"
#define TR_OWN "Own" #define TR_OWN "Own"
@ -923,7 +922,8 @@
#define TR_EXTERNALRF "External RF" #define TR_EXTERNALRF "External RF"
#define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe mode") #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe mode")
#define TR_FAILSAFESET "FAILSAFE SETTINGS" #define TR_FAILSAFESET "FAILSAFE SETTINGS"
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSORS"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Country Code" #define TR_COUNTRYCODE "Country Code"
#define TR_VOICELANG "Voice Language" #define TR_VOICELANG "Voice Language"
#define TR_UNITSSYSTEM "Units" #define TR_UNITSSYSTEM "Units"
@ -967,6 +967,9 @@
#define TR_CRITICALALARM INDENT "Critical Alarm" #define TR_CRITICALALARM INDENT "Critical Alarm"
#define TR_ENABLE_POPUP "Enable Popup" #define TR_ENABLE_POPUP "Enable Popup"
#define TR_DISABLE_POPUP "Disable Popup" #define TR_DISABLE_POPUP "Disable Popup"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Preset..." #define TR_CURVE_PRESET "Preset..."
#define TR_PRESET "Preset" #define TR_PRESET "Preset"
#define TR_MIRROR "Mirror" #define TR_MIRROR "Mirror"

View file

@ -592,8 +592,6 @@
#define TR_MODE INDENT"Modo" #define TR_MODE INDENT"Modo"
#define TR_NOFREEEXPO "No expo libre!" #define TR_NOFREEEXPO "No expo libre!"
#define TR_NOFREEMIXER "No mezcla lib!" #define TR_NOFREEMIXER "No mezcla lib!"
#define TR_INSERTMIX "INSERTAR MIX"
#define TR_EDITMIX "EDITAR MIX "
#define TR_SOURCE INDENT"Fuente" #define TR_SOURCE INDENT"Fuente"
#define TR_WEIGHT "Cantidad" #define TR_WEIGHT "Cantidad"
#define TR_EXPO TR("Expo","Exponencial") #define TR_EXPO TR("Expo","Exponencial")
@ -735,7 +733,6 @@
#define TR_MENULOGICALSWITCHES "AJTE.INTERUPTS." #define TR_MENULOGICALSWITCHES "AJTE.INTERUPTS."
#define TR_MENUCUSTOMFUNC "AJTE. FUNCIONES" #define TR_MENUCUSTOMFUNC "AJTE. FUNCIONES"
#define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS" #define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS"
#define TR_MENUCUSTOMSCRIPT "CUSTOM SCRIPT"
#define TR_MENUTELEMETRY "TELEMETRIA" #define TR_MENUTELEMETRY "TELEMETRIA"
#define TR_MENUTEMPLATES "PLANTILLAS" #define TR_MENUTEMPLATES "PLANTILLAS"
#define TR_MENUSTAT "STATS" #define TR_MENUSTAT "STATS"
@ -830,7 +827,7 @@
#define TR_SD_SIZE "Tamaño:" #define TR_SD_SIZE "Tamaño:"
#define TR_TYPE INDENT "Tipo" #define TR_TYPE INDENT "Tipo"
#define TR_GLOBAL_VARS "Global Variables" #define TR_GLOBAL_VARS "Global Variables"
#define TR_GLOBAL_V "GLOBAL V." #define TR_GVARS "GLOBAL V."
#define TR_GLOBAL_VAR "Global Variable" #define TR_GLOBAL_VAR "Global Variable"
#define TR_MENUGLOBALVARS "GLOBAL VARIABLES" #define TR_MENUGLOBALVARS "GLOBAL VARIABLES"
#define TR_OWN "Propio" #define TR_OWN "Propio"
@ -850,6 +847,7 @@
#define TR_FAILSAFE INDENT"Modo sgdad." #define TR_FAILSAFE INDENT"Modo sgdad."
#define TR_FAILSAFESET "AJUSTES SGDAD." #define TR_FAILSAFESET "AJUSTES SGDAD."
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Codigo Pais" #define TR_COUNTRYCODE "Codigo Pais"
#define TR_VOICELANG "Idioma voces" #define TR_VOICELANG "Idioma voces"
#define TR_UNITSSYSTEM "Unidades" #define TR_UNITSSYSTEM "Unidades"
@ -893,6 +891,9 @@
#define TR_CRITICALALARM INDENT "Alarma Critica" #define TR_CRITICALALARM INDENT "Alarma Critica"
#define TR_ENABLE_POPUP "Enable Popup" #define TR_ENABLE_POPUP "Enable Popup"
#define TR_DISABLE_POPUP "Disable Popup" #define TR_DISABLE_POPUP "Disable Popup"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Preset..." #define TR_CURVE_PRESET "Preset..."
#define TR_PRESET "Preset" #define TR_PRESET "Preset"
#define TR_MIRROR "Mirror" #define TR_MIRROR "Mirror"

View file

@ -592,8 +592,6 @@
#define TR_MODE INDENT"Mode" #define TR_MODE INDENT"Mode"
#define TR_NOFREEEXPO "No free expo!" #define TR_NOFREEEXPO "No free expo!"
#define TR_NOFREEMIXER "No free mixer!" #define TR_NOFREEMIXER "No free mixer!"
#define TR_INSERTMIX "INSERT MIX "
#define TR_EDITMIX "EDIT MIX "
#define TR_SOURCE INDENT"Source" #define TR_SOURCE INDENT"Source"
#define TR_WEIGHT "Weight" #define TR_WEIGHT "Weight"
#define TR_EXPO TR("Expo","Exponential") #define TR_EXPO TR("Expo","Exponential")
@ -735,7 +733,6 @@
#define TR_MENULOGICALSWITCHES "CUSTOM SWITCHES" #define TR_MENULOGICALSWITCHES "CUSTOM SWITCHES"
#define TR_MENUCUSTOMFUNC "CUSTOM FUNCTIONS" #define TR_MENUCUSTOMFUNC "CUSTOM FUNCTIONS"
#define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS" #define TR_MENUCUSTOMSCRIPTS "CUSTOM SCRIPTS"
#define TR_MENUCUSTOMSCRIPT "CUSTOM SCRIPT"
#define TR_MENUTELEMETRY "TELEMETRY" #define TR_MENUTELEMETRY "TELEMETRY"
#define TR_MENUTEMPLATES "TEMPLATES" #define TR_MENUTEMPLATES "TEMPLATES"
#define TR_MENUSTAT "STATS" #define TR_MENUSTAT "STATS"
@ -830,7 +827,7 @@
#define TR_SD_SIZE "Size:" #define TR_SD_SIZE "Size:"
#define TR_TYPE INDENT "Type" #define TR_TYPE INDENT "Type"
#define TR_GLOBAL_VARS "Global Variables" #define TR_GLOBAL_VARS "Global Variables"
#define TR_GLOBAL_V "GLOBAL V." #define TR_GVARS "GLOBAL V."
#define TR_GLOBAL_VAR "Global Variable" #define TR_GLOBAL_VAR "Global Variable"
#define TR_MENUGLOBALVARS "GLOBAL VARIABLES" #define TR_MENUGLOBALVARS "GLOBAL VARIABLES"
#define TR_OWN "Own" #define TR_OWN "Own"
@ -850,6 +847,7 @@
#define TR_FAILSAFE INDENT "Failsafe mode" #define TR_FAILSAFE INDENT "Failsafe mode"
#define TR_FAILSAFESET "FAILSAFE SETTINGS" #define TR_FAILSAFESET "FAILSAFE SETTINGS"
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Country Code" #define TR_COUNTRYCODE "Country Code"
#define TR_VOICELANG "Voice Language" #define TR_VOICELANG "Voice Language"
#define TR_UNITSSYSTEM "Units" #define TR_UNITSSYSTEM "Units"
@ -893,6 +891,9 @@
#define TR_CRITICALALARM INDENT "Critical Alarm" #define TR_CRITICALALARM INDENT "Critical Alarm"
#define TR_ENABLE_POPUP "Enable Popup" #define TR_ENABLE_POPUP "Enable Popup"
#define TR_DISABLE_POPUP "Disable Popup" #define TR_DISABLE_POPUP "Disable Popup"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Preset..." #define TR_CURVE_PRESET "Preset..."
#define TR_PRESET "Preset" #define TR_PRESET "Preset"
#define TR_MIRROR "Mirror" #define TR_MIRROR "Mirror"

View file

@ -626,8 +626,6 @@
#define TR_MODE INDENT "Mode" #define TR_MODE INDENT "Mode"
#define TR_NOFREEEXPO "Max expos atteint!" #define TR_NOFREEEXPO "Max expos atteint!"
#define TR_NOFREEMIXER "Max mixages atteint!" #define TR_NOFREEMIXER "Max mixages atteint!"
#define TR_INSERTMIX "INSERER MIXAGE"
#define TR_EDITMIX "EDITER MIXAGE"
#define TR_SOURCE INDENT "Source" #define TR_SOURCE INDENT "Source"
#define TR_WEIGHT "Ratio" #define TR_WEIGHT "Ratio"
#define TR_EXPO TR("Expo", "Exponentiel") #define TR_EXPO TR("Expo", "Exponentiel")
@ -772,7 +770,6 @@
#define TR_MENULOGICALSWITCHES TR("INTERS LOG.", "INTERS LOGIQUES") #define TR_MENULOGICALSWITCHES TR("INTERS LOG.", "INTERS LOGIQUES")
#define TR_MENUCUSTOMFUNC TR("FONCTIONS SPEC.", "FONCTIONS SPECIALES") #define TR_MENUCUSTOMFUNC TR("FONCTIONS SPEC.", "FONCTIONS SPECIALES")
#define TR_MENUCUSTOMSCRIPTS "SCRIPTS PERSOS" #define TR_MENUCUSTOMSCRIPTS "SCRIPTS PERSOS"
#define TR_MENUCUSTOMSCRIPT "SCRIPT PERSO"
#define TR_MENUTELEMETRY "TELEMESURE" #define TR_MENUTELEMETRY "TELEMESURE"
#define TR_MENUTEMPLATES "GABARITS" #define TR_MENUTEMPLATES "GABARITS"
#define TR_MENUSTAT TR("STATS", "STATISTIQUES") #define TR_MENUSTAT TR("STATS", "STATISTIQUES")
@ -867,7 +864,7 @@
#define TR_SD_SIZE "Taille:" #define TR_SD_SIZE "Taille:"
#define TR_TYPE INDENT "Type" #define TR_TYPE INDENT "Type"
#define TR_GLOBAL_VARS "Variables Globales" #define TR_GLOBAL_VARS "Variables Globales"
#define TR_GLOBAL_V "V. GLOBALES" #define TR_GVARS "V. GLOBALES"
#define TR_GLOBAL_VAR "Variable globale" #define TR_GLOBAL_VAR "Variable globale"
#define TR_MENUGLOBALVARS "VARIABLES GLOBALES" #define TR_MENUGLOBALVARS "VARIABLES GLOBALES"
#define TR_OWN "Pers" #define TR_OWN "Pers"
@ -887,6 +884,7 @@
#define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Type failsafe") #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Type failsafe")
#define TR_FAILSAFESET "REGLAGES FAILSAFE" #define TR_FAILSAFESET "REGLAGES FAILSAFE"
#define TR_MENUSENSOR "CAPTEUR" #define TR_MENUSENSOR "CAPTEUR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE TR("Zone géo.","Zone géographique") #define TR_COUNTRYCODE TR("Zone géo.","Zone géographique")
#define TR_VOICELANG TR("Langue voix", "Langue annonces vocales") #define TR_VOICELANG TR("Langue voix", "Langue annonces vocales")
#define TR_UNITSSYSTEM "Unités" #define TR_UNITSSYSTEM "Unités"
@ -930,6 +928,9 @@
#define TR_CRITICALALARM INDENT "Alarme critique" #define TR_CRITICALALARM INDENT "Alarme critique"
#define TR_ENABLE_POPUP "Activer Popup" #define TR_ENABLE_POPUP "Activer Popup"
#define TR_DISABLE_POPUP "Désactiver Popup" #define TR_DISABLE_POPUP "Désactiver Popup"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Courbe standard..." #define TR_CURVE_PRESET "Courbe standard..."
#define TR_PRESET "Pente" #define TR_PRESET "Pente"
#define TR_MIRROR "Miroir" #define TR_MIRROR "Miroir"

View file

@ -629,8 +629,6 @@
#define TR_MODE INDENT"Modo" #define TR_MODE INDENT"Modo"
#define TR_NOFREEEXPO "Expo pieni!" #define TR_NOFREEEXPO "Expo pieni!"
#define TR_NOFREEMIXER "Mixer pieni!" #define TR_NOFREEMIXER "Mixer pieni!"
#define TR_INSERTMIX "INSER. MIX"
#define TR_EDITMIX "MOD. MIX"
#define TR_SOURCE INDENT"Sorg." #define TR_SOURCE INDENT"Sorg."
#define TR_WEIGHT "Peso" #define TR_WEIGHT "Peso"
#define TR_EXPO "Espo" #define TR_EXPO "Espo"
@ -779,7 +777,6 @@
#define TR_MENULOGICALSWITCHES TR("INTER. LOGICI","INTERRUTTORI LOGICI") #define TR_MENULOGICALSWITCHES TR("INTER. LOGICI","INTERRUTTORI LOGICI")
#define TR_MENUCUSTOMFUNC TR("FUNZ. SPECIALI","FUNZIONI SPECIALI") #define TR_MENUCUSTOMFUNC TR("FUNZ. SPECIALI","FUNZIONI SPECIALI")
#define TR_MENUCUSTOMSCRIPTS "SCRIPTS UTENTE" #define TR_MENUCUSTOMSCRIPTS "SCRIPTS UTENTE"
#define TR_MENUCUSTOMSCRIPT "SCRIPT UTENTE"
#define TR_MENUTELEMETRY "TELEMETRIA" #define TR_MENUTELEMETRY "TELEMETRIA"
#define TR_MENUTEMPLATES "ESEMPI GUIDA" #define TR_MENUTEMPLATES "ESEMPI GUIDA"
#define TR_MENUSTAT "STATO" #define TR_MENUSTAT "STATO"
@ -807,11 +804,11 @@
#define TR_VOLTAGE TR(INDENT "Voltagg.",INDENT "Voltaggio") #define TR_VOLTAGE TR(INDENT "Voltagg.",INDENT "Voltaggio")
#define TR_CURRENT TR(INDENT "Corrente",INDENT "Corrente") #define TR_CURRENT TR(INDENT "Corrente",INDENT "Corrente")
#define TR_SELECT_MODEL "Scegli Memo." #define TR_SELECT_MODEL "Scegli Memo."
#define TR_CREATE_CATEGORY "Create Category" #define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category" #define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category" #define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Crea Modello" #define TR_CREATE_MODEL "Crea Modello"
#define TR_DUPLICATE_MODEL "Duplicate Model" #define TR_DUPLICATE_MODEL "Duplicate Model"
#define TR_COPY_MODEL "Copia Modello" #define TR_COPY_MODEL "Copia Modello"
#define TR_MOVE_MODEL "Sposta Modello" #define TR_MOVE_MODEL "Sposta Modello"
#define TR_BACKUP_MODEL "Salva Modello" #define TR_BACKUP_MODEL "Salva Modello"
@ -878,7 +875,7 @@
#define TR_SD_SIZE "Dimens:" #define TR_SD_SIZE "Dimens:"
#define TR_TYPE INDENT "Tipo" #define TR_TYPE INDENT "Tipo"
#define TR_GLOBAL_VARS "Variabili Globali" #define TR_GLOBAL_VARS "Variabili Globali"
#define TR_GLOBAL_V "V.GLOBALI" #define TR_GVARS "V.GLOBALI"
#define TR_GLOBAL_VAR "Variabile globale" #define TR_GLOBAL_VAR "Variabile globale"
#define TR_MENUGLOBALVARS "VARIABILI GLOBALI" #define TR_MENUGLOBALVARS "VARIABILI GLOBALI"
#define TR_OWN "Fase" #define TR_OWN "Fase"
@ -898,6 +895,7 @@
#define TR_FAILSAFE "Modo failsafe" #define TR_FAILSAFE "Modo failsafe"
#define TR_FAILSAFESET TR("FAILSAFE","IMPOSTAZIONI FAILSAFE") #define TR_FAILSAFESET TR("FAILSAFE","IMPOSTAZIONI FAILSAFE")
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE TR("Codice Paese","Standard 2.4Ghz") #define TR_COUNTRYCODE TR("Codice Paese","Standard 2.4Ghz")
#define TR_VOICELANG "Lingua Voce" #define TR_VOICELANG "Lingua Voce"
#define TR_UNITSSYSTEM "Unità" #define TR_UNITSSYSTEM "Unità"
@ -941,6 +939,9 @@
#define TR_CRITICALALARM INDENT "Allarme Critico" #define TR_CRITICALALARM INDENT "Allarme Critico"
#define TR_ENABLE_POPUP "Abilita Popup" #define TR_ENABLE_POPUP "Abilita Popup"
#define TR_DISABLE_POPUP "Disabilita Popup" #define TR_DISABLE_POPUP "Disabilita Popup"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Preimpostate..." #define TR_CURVE_PRESET "Preimpostate..."
#define TR_PRESET "Preimpostate" #define TR_PRESET "Preimpostate"
#define TR_MIRROR "Mirror" #define TR_MIRROR "Mirror"
@ -1069,7 +1070,7 @@
#define TR_SCALE "Scala" #define TR_SCALE "Scala"
#define TR_VIEW_CHANNELS "Vedi Canali" #define TR_VIEW_CHANNELS "Vedi Canali"
#define TR_VIEW_NOTES "Vedi Note" #define TR_VIEW_NOTES "Vedi Note"
#define TR_MODEL_SELECT "Model Select" #define TR_MODEL_SELECT "Model Select"
#define TR_MODS_FORBIDDEN "Modifica proibita!" #define TR_MODS_FORBIDDEN "Modifica proibita!"
#define TR_UNLOCKED "Sbloccato" #define TR_UNLOCKED "Sbloccato"
#define TR_ID "ID" #define TR_ID "ID"

View file

@ -641,8 +641,6 @@
#define TR_MODE INDENT "Mode" #define TR_MODE INDENT "Mode"
#define TR_NOFREEEXPO "Geen vrije expo!" #define TR_NOFREEEXPO "Geen vrije expo!"
#define TR_NOFREEMIXER "Geen vrije mixer!" #define TR_NOFREEMIXER "Geen vrije mixer!"
#define TR_INSERTMIX "INSERT MIX "
#define TR_EDITMIX "EDIT MIX "
#define TR_SOURCE INDENT "Source" #define TR_SOURCE INDENT "Source"
#define TR_WEIGHT "Weight" #define TR_WEIGHT "Weight"
#define TR_EXPO TR("Expo", "Exponentieel") #define TR_EXPO TR("Expo", "Exponentieel")
@ -798,7 +796,6 @@
#define TR_MENULOGICALSWITCHES "LOGISCHE SCHAKELAARS" #define TR_MENULOGICALSWITCHES "LOGISCHE SCHAKELAARS"
#define TR_MENUCUSTOMFUNC TR("SPEC.-FUNKTIES", "SPECIALE-FUNKTIES") #define TR_MENUCUSTOMFUNC TR("SPEC.-FUNKTIES", "SPECIALE-FUNKTIES")
#define TR_MENUCUSTOMSCRIPTS "LUA-SCRIPTS" #define TR_MENUCUSTOMSCRIPTS "LUA-SCRIPTS"
#define TR_MENUCUSTOMSCRIPT "LUA-SCRIPT"
#define TR_MENUTELEMETRY "TELEMETRIE" #define TR_MENUTELEMETRY "TELEMETRIE"
#define TR_MENUTEMPLATES "SJABLONEN" #define TR_MENUTEMPLATES "SJABLONEN"
#define TR_MENUSTAT "STAT" #define TR_MENUSTAT "STAT"
@ -897,7 +894,7 @@
#define TR_SD_SIZE "Grootte:" #define TR_SD_SIZE "Grootte:"
#define TR_TYPE INDENT "Type" #define TR_TYPE INDENT "Type"
#define TR_GLOBAL_VARS "Globale Variabelen" #define TR_GLOBAL_VARS "Globale Variabelen"
#define TR_GLOBAL_V "GLOBALE V." #define TR_GVARS "GLOBALE V."
#define TR_GLOBAL_VAR "Globale Variabele" #define TR_GLOBAL_VAR "Globale Variabele"
#define TR_MENUGLOBALVARS "GLOBALE VARIABELEN" #define TR_MENUGLOBALVARS "GLOBALE VARIABELEN"
#define TR_OWN "Eigen" #define TR_OWN "Eigen"
@ -917,6 +914,7 @@
#define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Modus") #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Modus")
#define TR_FAILSAFESET "Failsafe instellen" #define TR_FAILSAFESET "Failsafe instellen"
#define TR_MENUSENSOR "SENSOR" #define TR_MENUSENSOR "SENSOR"
#define TR_SENSOR "SENSOR"
#define TR_COUNTRYCODE "Landcode" #define TR_COUNTRYCODE "Landcode"
#define TR_VOICELANG "Taal" #define TR_VOICELANG "Taal"
#define TR_UNITSSYSTEM "Eenheden" #define TR_UNITSSYSTEM "Eenheden"
@ -960,6 +958,9 @@
#define TR_CRITICALALARM INDENT "Kritiek Alarm" #define TR_CRITICALALARM INDENT "Kritiek Alarm"
#define TR_ENABLE_POPUP "Inschakelen Popups" #define TR_ENABLE_POPUP "Inschakelen Popups"
#define TR_DISABLE_POPUP "Uitschakelen Popups" #define TR_DISABLE_POPUP "Uitschakelen Popups"
#define TR_POPUP "Popup"
#define TR_MIN "Min"
#define TR_MAX "Max"
#define TR_CURVE_PRESET "Preset..." #define TR_CURVE_PRESET "Preset..."
#define TR_PRESET "Preset" #define TR_PRESET "Preset"
#define TR_MIRROR "Spiegelen" #define TR_MIRROR "Spiegelen"

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