1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 16:25:16 +03:00

More files moved

This commit is contained in:
bsongis 2015-01-17 22:05:42 +01:00
parent 2eb3779a18
commit 35207ce6f6
65 changed files with 7895 additions and 1944 deletions

View file

@ -74,6 +74,10 @@ namespace Open9xGruvin9x {
#include "radio/src/stamp.cpp"
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/gui/9X/widgets.cpp"
#include "radio/src/gui/9X/navigation.cpp"
#include "radio/src/gui/9X/popups.cpp"
#include "radio/src/gui/9X/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/9X/menu_model_select.cpp"
@ -88,15 +92,15 @@ namespace Open9xGruvin9x {
#include "radio/src/gui/9X/menu_model_telemetry.cpp"
#include "radio/src/gui/9X/menu_model_templates.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/9X/menu_general_setup.cpp"
#include "radio/src/gui/9X/menu_general_trainer.cpp"
#include "radio/src/gui/9X/menu_general_version.cpp"
#include "radio/src/gui/9X/menu_general_diagkeys.cpp"
#include "radio/src/gui/9X/menu_general_diaganas.cpp"
#include "radio/src/gui/9X/menu_general_calib.cpp"
#include "radio/src/gui/9X/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/9X/view_statistics.cpp"
#include "radio/src/gui/9X/view_telemetry.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"

View file

@ -75,6 +75,10 @@ namespace OpenTxM128 {
#include "radio/src/stamp.cpp"
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/gui/9X/widgets.cpp"
#include "radio/src/gui/9X/navigation.cpp"
#include "radio/src/gui/9X/popups.cpp"
#include "radio/src/gui/9X/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/9X/menu_model_select.cpp"
@ -89,15 +93,15 @@ namespace OpenTxM128 {
#include "radio/src/gui/9X/menu_model_telemetry.cpp"
#include "radio/src/gui/9X/menu_model_templates.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/9X/menu_general_setup.cpp"
#include "radio/src/gui/9X/menu_general_trainer.cpp"
#include "radio/src/gui/9X/menu_general_version.cpp"
#include "radio/src/gui/9X/menu_general_diagkeys.cpp"
#include "radio/src/gui/9X/menu_general_diaganas.cpp"
#include "radio/src/gui/9X/menu_general_calib.cpp"
#include "radio/src/gui/9X/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/9X/view_statistics.cpp"
#include "radio/src/gui/9X/view_telemetry.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"

View file

@ -78,6 +78,10 @@ namespace OpenTxM64 {
#include "radio/src/stamp.cpp"
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/gui/9X/widgets.cpp"
#include "radio/src/gui/9X/navigation.cpp"
#include "radio/src/gui/9X/popups.cpp"
#include "radio/src/gui/9X/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/9X/menu_model_select.cpp"
@ -92,15 +96,15 @@ namespace OpenTxM64 {
#include "radio/src/gui/9X/menu_model_telemetry.cpp"
#include "radio/src/gui/9X/menu_model_templates.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/9X/menu_general_setup.cpp"
#include "radio/src/gui/9X/menu_general_trainer.cpp"
#include "radio/src/gui/9X/menu_general_version.cpp"
#include "radio/src/gui/9X/menu_general_diagkeys.cpp"
#include "radio/src/gui/9X/menu_general_diaganas.cpp"
#include "radio/src/gui/9X/menu_general_calib.cpp"
#include "radio/src/gui/9X/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/9X/view_statistics.cpp"
#include "radio/src/gui/9X/view_telemetry.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"

View file

@ -90,6 +90,10 @@ namespace Open9xSky9x {
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/sdcard.cpp"
#include "radio/src/gui/9X/widgets.cpp"
#include "radio/src/gui/9X/navigation.cpp"
#include "radio/src/gui/9X/popups.cpp"
#include "radio/src/gui/9X/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/9X/menu_model_select.cpp"
@ -104,19 +108,19 @@ namespace Open9xSky9x {
#include "radio/src/gui/9X/menu_model_telemetry.cpp"
#include "radio/src/gui/9X/menu_model_templates.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_sdmanager.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_hardware.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/9X/menu_general_setup.cpp"
#include "radio/src/gui/9X/menu_general_sdmanager.cpp"
#include "radio/src/gui/9X/menu_general_trainer.cpp"
#include "radio/src/gui/9X/menu_general_version.cpp"
#include "radio/src/gui/9X/menu_general_diagkeys.cpp"
#include "radio/src/gui/9X/menu_general_diaganas.cpp"
#include "radio/src/gui/9X/menu_general_hardware.cpp"
#include "radio/src/gui/9X/menu_general_calib.cpp"
#include "radio/src/gui/9X/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/9X/view_statistics.cpp"
#include "radio/src/gui/9X/view_telemetry.cpp"
#include "radio/src/gui/view_about.cpp"
#include "radio/src/gui/view_text.cpp"
#include "radio/src/gui/9X/view_text.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/logs.cpp"

View file

@ -95,6 +95,10 @@ inline int geteepromsize() {
#include "radio/src/stamp.cpp"
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/gui/Taranis/widgets.cpp"
#include "radio/src/gui/Taranis/navigation.cpp"
#include "radio/src/gui/Taranis/popups.cpp"
#include "radio/src/gui/Taranis/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/Taranis/menu_model_select.cpp"
@ -110,19 +114,19 @@ inline int geteepromsize() {
#include "radio/src/gui/Taranis/menu_model_limits.cpp"
#include "radio/src/gui/Taranis/menu_model_telemetry.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_sdmanager.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_hardware.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/Taranis/menu_general_setup.cpp"
#include "radio/src/gui/Taranis/menu_general_sdmanager.cpp"
#include "radio/src/gui/Taranis/menu_general_trainer.cpp"
#include "radio/src/gui/Taranis/menu_general_version.cpp"
#include "radio/src/gui/Taranis/menu_general_diagkeys.cpp"
#include "radio/src/gui/Taranis/menu_general_diaganas.cpp"
#include "radio/src/gui/Taranis/menu_general_hardware.cpp"
#include "radio/src/gui/Taranis/menu_general_calib.cpp"
#include "radio/src/gui/Taranis/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/Taranis/view_statistics.cpp"
#include "radio/src/gui/view_channels.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/view_text.cpp"
#include "radio/src/gui/Taranis/view_telemetry.cpp"
#include "radio/src/gui/Taranis/view_text.cpp"
#include "radio/src/gui/view_about.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_taranis.cpp"

View file

@ -97,6 +97,10 @@ inline int geteepromsize() {
#include "radio/src/stamp.cpp"
#include "radio/src/maths.cpp"
#include "radio/src/vario.cpp"
#include "radio/src/gui/Taranis/widgets.cpp"
#include "radio/src/gui/Taranis/navigation.cpp"
#include "radio/src/gui/Taranis/popups.cpp"
#include "radio/src/gui/Taranis/helpers.cpp"
#include "radio/src/gui/menus.cpp"
#include "radio/src/gui/menu_model.cpp"
#include "radio/src/gui/Taranis/menu_model_select.cpp"
@ -112,19 +116,19 @@ inline int geteepromsize() {
#include "radio/src/gui/Taranis/menu_model_limits.cpp"
#include "radio/src/gui/Taranis/menu_model_telemetry.cpp"
#include "radio/src/gui/menu_general.cpp"
#include "radio/src/gui/menu_general_setup.cpp"
#include "radio/src/gui/menu_general_sdmanager.cpp"
#include "radio/src/gui/menu_general_trainer.cpp"
#include "radio/src/gui/menu_general_version.cpp"
#include "radio/src/gui/menu_general_diagkeys.cpp"
#include "radio/src/gui/menu_general_diaganas.cpp"
#include "radio/src/gui/menu_general_hardware.cpp"
#include "radio/src/gui/menu_general_calib.cpp"
#include "radio/src/gui/Taranis/menu_general_setup.cpp"
#include "radio/src/gui/Taranis/menu_general_sdmanager.cpp"
#include "radio/src/gui/Taranis/menu_general_trainer.cpp"
#include "radio/src/gui/Taranis/menu_general_version.cpp"
#include "radio/src/gui/Taranis/menu_general_diagkeys.cpp"
#include "radio/src/gui/Taranis/menu_general_diaganas.cpp"
#include "radio/src/gui/Taranis/menu_general_hardware.cpp"
#include "radio/src/gui/Taranis/menu_general_calib.cpp"
#include "radio/src/gui/Taranis/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/Taranis/view_statistics.cpp"
#include "radio/src/gui/view_channels.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/view_text.cpp"
#include "radio/src/gui/Taranis/view_telemetry.cpp"
#include "radio/src/gui/Taranis/view_text.cpp"
#include "radio/src/gui/view_about.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_taranis.cpp"

View file

@ -396,7 +396,9 @@ QString findMassstoragePath(const QString &filename)
eepromfile.append("/" + filename);
#if !defined __APPLE__
QString fstype = entry->me_type;
if (QFile::exists(eepromfile) && fstype.contains("fat") ) {
// qDebug() << eepromfile;
if (fstype.contains("fat") && QFile::exists(eepromfile)) {
#else
if (QFile::exists(eepromfile)) {
#endif

View file

@ -366,7 +366,7 @@ M2561_VARIANT = +16384
EEPROM_VARIANT = 0
GUIMODELSRC = gui/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
GUIGENERALSRC = gui/menu_general.cpp gui/menu_general_setup.cpp gui/menu_general_trainer.cpp gui/menu_general_version.cpp gui/menu_general_diagkeys.cpp gui/menu_general_diaganas.cpp gui/menu_general_calib.cpp
GUIGENERALSRC = gui/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
@ -391,6 +391,7 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR))
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR)
FLAVOUR = 9xr
@ -461,6 +462,7 @@ ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128))
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR128)
FLAVOUR = 9xr128
@ -527,6 +529,7 @@ ifeq ($(PCB), $(filter $(PCB), 9X2561))
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCB), 9XR2561)
FLAVOUR = 9xr2561
@ -595,11 +598,12 @@ ifeq ($(PCB), GRUVIN9X)
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp haptic.cpp debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(SDCARD), YES)
CPPDEFS += -DRTCLOCK -DSDCARD
CPPSRC += rtc.cpp sdcard.cpp logs.cpp targets/gruvin9x/rtc_driver.cpp
GUIGENERALSRC += gui/menu_general_sdmanager.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp
endif
@ -639,6 +643,7 @@ ifeq ($(PCB), MEGA2560)
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
ifeq ($(PCBREV), ST7565P)
EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
@ -649,7 +654,7 @@ ifeq ($(PCB), MEGA2560)
ifeq ($(SDCARD), YES)
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp
CPPDEFS += -DSDCARD -DRTCLOCK
GUIGENERALSRC += gui/menu_general_sdmanager.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp
CPPSRC += rtc.cpp sdcard.cpp logs.cpp targets/gruvin9x/rtc_driver.cpp
endif
@ -710,7 +715,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
CPPDEFS += -DSPORT_FILE_LOG
endif
INCDIRS += targets/sky9x CoOS/kernel CoOS/portable
GUIGENERALSRC += gui/menu_general_hardware.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
BOARDSRC = main_arm.cpp targets/sky9x/board_sky9x.cpp
EXTRABOARDSRC = targets/sky9x/lcd_driver.cpp
SRC += targets/sky9x/core_cm3.c targets/sky9x/board_lowlevel.c targets/sky9x/crt.c targets/sky9x/vectors_sam3s.c
@ -722,7 +727,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp pulses/dsm2_arm.cpp
CPPSRC += tasks_arm.cpp audio_arm.cpp haptic.cpp gui/view_about.cpp gui/view_text.cpp telemetry/telemetry.cpp
CPPSRC += tasks_arm.cpp audio_arm.cpp haptic.cpp gui/view_about.cpp gui/$(GUIDIRECTORY)/view_text.cpp telemetry/telemetry.cpp
CPPSRC += targets/sky9x/telemetry_driver.cpp targets/sky9x/second_serial_driver.cpp targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp
CPPSRC += loadboot.cpp debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
@ -730,7 +735,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
CPPDEFS += -DSDCARD -DVOICE
INCDIRS += FatFs FatFs/option
CPPSRC += sdcard.cpp logs.cpp
GUIGENERALSRC += gui/menu_general_sdmanager.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/sky9x/diskio.cpp
endif
ifeq ($(BUZZER), YES)
@ -820,7 +825,7 @@ ifeq ($(PCB), TARANIS)
EXTRAINCDIRS += targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/include
EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc
EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc
GUIGENERALSRC += gui/menu_general_hardware.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp
BOARDSRC = main_arm.cpp targets/taranis/board_taranis.cpp
EXTRABOARDSRC += targets/taranis/configure_pins.cpp targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/aspi.c targets/taranis/i2c.c targets/taranis/delays.c
SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c
@ -830,7 +835,7 @@ ifeq ($(PCB), TARANIS)
PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp
CPPSRC += tasks_arm.cpp audio_arm.cpp sbus.cpp telemetry/telemetry.cpp
CPPSRC += targets/taranis/pulses_driver.cpp targets/taranis/keys_driver.cpp targets/taranis/adc_driver.cpp targets/taranis/trainer_driver.cpp targets/taranis/audio_driver.cpp targets/taranis/uart3_driver.cpp targets/taranis/telemetry_driver.cpp
CPPSRC += bmp.cpp gui/view_channels.cpp gui/view_about.cpp gui/view_text.cpp loadboot.cpp debug.cpp
CPPSRC += bmp.cpp gui/view_channels.cpp gui/view_about.cpp gui/$(GUIDIRECTORY)/view_text.cpp loadboot.cpp debug.cpp
SRC += targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Source/Templates/system_stm32f2xx.c
SRC += targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/src/misc.c
SRC += targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_gpio.c
@ -890,7 +895,7 @@ ifeq ($(PCB), TARANIS)
endif
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp
CPPSRC += sdcard.cpp logs.cpp rtc.cpp targets/taranis/rtc_driver.cpp
GUIGENERALSRC += gui/menu_general_sdmanager.cpp
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_sdmanager.cpp gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp
CPPDEFS += -DSDCARD -DVOICE -DRTCLOCK
INCDIRS += FatFs FatFs/option
ifeq ($(DSM2), PPM)
@ -944,7 +949,7 @@ else
TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi")
endif
GUISRC = gui/menus.cpp $(GUIMODELSRC) $(GUIGENERALSRC) gui/$(GUIDIRECTORY)/view_main.cpp gui/view_statistics.cpp
GUISRC = gui/$(GUIDIRECTORY)/helpers.cpp gui/$(GUIDIRECTORY)/navigation.cpp gui/$(GUIDIRECTORY)/popups.cpp gui/$(GUIDIRECTORY)/widgets.cpp gui/menus.cpp $(GUIMODELSRC) $(GUIGENERALSRC) gui/$(GUIDIRECTORY)/view_main.cpp gui/$(GUIDIRECTORY)/view_statistics.cpp
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
@ -1043,6 +1048,7 @@ ifneq ($(FONT), STD)
INCDIRS += fonts/$(FONTDIR)
endif
INCDIRS += gui
INCDIRS += fonts/std
ifeq ($(THR_TRACE), YES)
@ -1126,7 +1132,8 @@ ifeq ($(EXT), $(filter $(EXT), FRSKY FRSKY_SPORT TELEMETREZ))
else
CPPSRC += telemetry/frsky.cpp telemetry/frsky_d.cpp
endif
CPPSRC += gui/view_telemetry.cpp
CPPSRC += gui/$(GUIDIRECTORY)/view_telemetry.cpp
ifeq ($(FRSKY_HUB), YES)
CPPDEFS += -DFRSKY_HUB

View file

@ -1530,7 +1530,8 @@ bool eeConvert()
s_eeDirtyMsk = EE_GENERAL;
eeCheck(true);
#if LCD_W >= 212
#if defined(COLORLCD)
#elif LCD_W >= 212
lcd_rect(60, 6*FH+4, 132, 3);
#else
lcd_rect(10, 6*FH+4, 102, 3);
@ -1538,7 +1539,8 @@ bool eeConvert()
// Models conversion
for (uint8_t id=0; id<MAX_MODELS; id++) {
#if LCD_W >= 212
#if defined(COLORLCD)
#elif LCD_W >= 212
lcd_hline(61, 6*FH+5, 10+id*2, FORCE);
#else
lcd_hline(11, 6*FH+5, 10+(id*3)/2, FORCE);

View file

@ -36,6 +36,11 @@
#include "opentx.h"
#if defined(COLORLCD)
const pm_uchar font_5x7[] PROGMEM = {
#include "fonts/font_stdsize.lbm"
};
#else
const pm_uchar font_5x7[] PROGMEM = {
#if defined (CPUARM)
#include "font_05x07.lbm"
@ -62,6 +67,7 @@ const pm_uchar font_5x7[] PROGMEM = {
#include "font_se_05x07.lbm"
#endif
};
#endif
#if defined(BOLD_FONT) && (!defined(CPUM64) || defined(EXTSTD))
const pm_uchar font_5x7_B[] PROGMEM = {
@ -70,6 +76,11 @@ const pm_uchar font_5x7_B[] PROGMEM = {
#endif
#if !defined(BOOT)
#if defined(COLORLCD)
const pm_uchar font_10x14[] PROGMEM = {
#include "fonts/font_dblsize.lbm"
};
#else
const pm_uchar font_10x14[] PROGMEM = {
#include "font_10x14_compressed.lbm"
#if defined(CPUARM)
@ -95,6 +106,7 @@ const pm_uchar font_10x14[] PROGMEM = {
#endif
};
#endif
#endif
#if defined(CPUARM) && !defined(BOOT)
const pm_uchar font_3x5[] PROGMEM = {
@ -124,6 +136,11 @@ const pm_uchar font_4x6[] PROGMEM = {
#endif
};
#if defined(COLORLCD)
const pm_uchar font_8x10[] PROGMEM = {
#include "fonts/font_midsize.lbm"
};
#else
const pm_uchar font_8x10[] PROGMEM = {
#include "font_08x10.lbm"
#if defined(TRANSLATIONS_DE)
@ -146,6 +163,7 @@ const pm_uchar font_8x10[] PROGMEM = {
#include "font_se_08x10.lbm"
#endif
};
#endif
const pm_uchar font_22x38_num[] PROGMEM = {
#include "font_22x38_num.lbm"

View file

@ -1 +1,4 @@
/*/*.lbm
/font_dblsize.png
/font_midsize.png
/font_stdsize.png

48
radio/src/gui/9X/gui.h Executable file
View file

@ -0,0 +1,48 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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.
*
*/
#define NUM_BODY_LINES LCD_LINES-1
#define MENU_TITLE_HEIGHT FH
#define MENU_NAVIG_HEIGHT 0
void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
#if !defined(CPUM64)
#define DEFAULT_SCROLLBAR_X (LCD_W-1)
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
#endif
#define SET_SCROLLBAR_X(x)

279
radio/src/gui/9X/helpers.cpp Executable file
View file

@ -0,0 +1,279 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 switchToMix(uint8_t source)
{
if (source <= 3)
return MIXSRC_3POS;
else
return MIXSRC_FIRST_SWITCH - 3 + source;
}
#if defined(CPUARM)
bool isSourceAvailable(int source)
{
#if !defined(HELI)
if (source>=MIXSRC_CYC1 && source<=MIXSRC_CYC3)
return false;
#endif
if (source>=MIXSRC_CH1 && source<=MIXSRC_LAST_CH) {
uint8_t destCh = source-MIXSRC_CH1;
for (uint8_t i = 0; i < MAX_MIXERS; i++) {
MixData *md = mixAddress(i);
if (md->srcRaw == 0) return false;
if (md->destCh==destCh) return true;
}
return false;
}
if (source>=MIXSRC_SW1 && source<=MIXSRC_LAST_LOGICAL_SWITCH) {
LogicalSwitchData * cs = lswAddress(source-MIXSRC_SW1);
return (cs->func != LS_FUNC_NONE);
}
#if !defined(GVARS)
if (source>=MIXSRC_GVAR1 && source<=MIXSRC_LAST_GVAR)
return false;
#endif
if (source>=MIXSRC_RESERVE1 && source<=MIXSRC_RESERVE5)
return false;
if (source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) {
div_t qr = div(source-MIXSRC_FIRST_TELEM, 3);
if (qr.rem == 0)
return isTelemetryFieldAvailable(qr.quot);
else
return isTelemetryFieldComparisonAvailable(qr.quot);
}
return true;
}
bool isSourceAvailableInCustomSwitches(int source)
{
bool result = isSourceAvailable(source);
#if defined(FRSKY)
if (result && source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) {
div_t qr = div(source-MIXSRC_FIRST_TELEM, 3);
result = isTelemetryFieldComparisonAvailable(qr.quot);
}
#endif
return result;
}
bool isInputSourceAvailable(int source)
{
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
return true;
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
return true;
if (source>=MIXSRC_TrimRud && source<MIXSRC_SW1)
return true;
if (source>=MIXSRC_FIRST_CH && source<=MIXSRC_LAST_CH)
return true;
if (source>=MIXSRC_FIRST_TRAINER && source<=MIXSRC_LAST_TRAINER)
return true;
if (source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM)
return isTelemetryFieldAvailable(source-MIXSRC_FIRST_TELEM);
return false;
}
enum SwitchContext
{
LogicalSwitchesContext,
ModelCustomFunctionsContext,
GeneralCustomFunctionsContext,
TimersContext,
MixesContext
};
bool isSwitchAvailable(int swtch, SwitchContext context)
{
if (swtch < 0) {
if (swtch == -SWSRC_ON || swtch == -SWSRC_One) {
return false;
}
swtch = -swtch;
}
if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
if (context == GeneralCustomFunctionsContext) {
return false;
}
else if (context != LogicalSwitchesContext) {
LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
return (cs->func != LS_FUNC_NONE);
}
}
if (context != ModelCustomFunctionsContext && context != GeneralCustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
return false;
}
if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) {
if (context == MixesContext || context == GeneralCustomFunctionsContext) {
return false;
}
else {
swtch -= SWSRC_FIRST_FLIGHT_MODE;
if (swtch == 0) {
return true;
}
FlightModeData * fm = flightModeAddress(swtch);
return (fm->swtch != SWSRC_NONE);
}
}
return true;
}
bool isSwitchAvailableInLogicalSwitches(int swtch)
{
return isSwitchAvailable(swtch, LogicalSwitchesContext);
}
bool isSwitchAvailableInCustomFunctions(int swtch)
{
if (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions)
return isSwitchAvailable(swtch, ModelCustomFunctionsContext);
else
return isSwitchAvailable(swtch, GeneralCustomFunctionsContext);
}
bool isSwitchAvailableInMixes(int swtch)
{
return isSwitchAvailable(swtch, MixesContext);
}
bool isSwitchAvailableInTimers(int swtch)
{
if (swtch >= 0) {
if (swtch < TMRMODE_COUNT)
return true;
else
swtch -= TMRMODE_COUNT-1;
}
else {
if (swtch > -TMRMODE_COUNT)
return false;
else
swtch += TMRMODE_COUNT-1;
}
return isSwitchAvailable(swtch, TimersContext);
}
bool isThrottleSourceAvailable(int source)
{
return true;
}
bool isLogicalSwitchFunctionAvailable(int function)
{
return function != LS_FUNC_RANGE;
}
bool isAssignableFunctionAvailable(int function)
{
bool modelFunctions = (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions);
switch (function) {
case FUNC_OVERRIDE_CHANNEL:
#if defined(OVERRIDE_CHANNEL_FUNCTION)
return modelFunctions;
#else
return false;
#endif
case FUNC_ADJUST_GVAR:
#if defined(GVARS)
return modelFunctions;
#else
return false;
#endif
#if !defined(HAPTIC)
case FUNC_HAPTIC:
#endif
case FUNC_PLAY_DIFF:
#if !defined(DANGEROUS_MODULE_FUNCTIONS)
case FUNC_RANGECHECK:
case FUNC_BIND:
case FUNC_MODULE_OFF:
#endif
case FUNC_PLAY_SCRIPT:
case FUNC_RESERVE5:
return false;
default:
return true;
}
}
bool isModuleAvailable(int module)
{
#if defined(PCBSKY9X)
if (module == MODULE_TYPE_NONE)
return false;
#endif
#if !defined(PXX)
if (module == MODULE_TYPE_XJT)
return false;
#endif
return true;
}
bool modelHasNotes()
{
char filename[sizeof(MODELS_PATH)+1+sizeof(g_model.header.name)+sizeof(TEXT_EXT)] = MODELS_PATH "/";
char *buf = strcat_modelname(&filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(buf, TEXT_EXT);
return isFileAvailable(filename);
}
#endif

View file

@ -0,0 +1,142 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 XPOT_DELTA 10
#define XPOT_DELAY 10 /* cycles */
void menuCommonCalib(uint8_t event)
{
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { // get low and high vals for sticks and trims
int16_t vt = anaIn(i);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
if (i >= POT1 && i <= POT_LAST) {
if (IS_POT_WITHOUT_DETENT(i)) {
reusableBuffer.calib.midVals[i] = (reusableBuffer.calib.hiVals[i] + reusableBuffer.calib.loVals[i]) / 2;
}
}
}
calibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
switch (event)
{
case EVT_ENTRY:
reusableBuffer.calib.state = 0;
break;
case EVT_KEY_BREAK(KEY_ENTER):
reusableBuffer.calib.state++;
break;
}
switch (reusableBuffer.calib.state) {
case 0:
// START CALIBRATION
if (!READ_ONLY()) {
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUTOSTART);
}
break;
case 1:
// SET MIDPOINT
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = anaIn(i);
}
break;
case 2:
// MOVE STICKS/POTS
STICK_SCROLL_DISABLE();
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
g_eeGeneral.calib[i].spanNeg = v - v/STICK_TOLERANCE;
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
g_eeGeneral.calib[i].spanPos = v - v/STICK_TOLERANCE;
}
}
break;
case 3:
g_eeGeneral.chkSum = evalChkSum();
eeDirty(EE_GENERAL);
reusableBuffer.calib.state = 4;
break;
default:
reusableBuffer.calib.state = 0;
break;
}
doMainScreenGraphics();
}
void menuGeneralCalib(uint8_t event)
{
check_simple(event, e_Calib, menuTabGeneral, DIM(menuTabGeneral), 0);
if (menuEvent) {
calibrationState = 0;
}
TITLE(STR_MENUCALIBRATION);
menuCommonCalib(READ_ONLY() ? 0 : event);
}
void menuFirstCalib(uint8_t event)
{
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == 4) {
calibrationState = 0;
chainMenu(menuMainView);
}
else {
lcd_putsCenter(0*FH, MENUCALIBRATION);
lcd_invert_line(0);
menuCommonCalib(event);
}
}

View file

@ -0,0 +1,107 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuGeneralDiagAna(uint8_t event)
{
#if defined(PCBSKY9X) && !defined(REVA)
#define ANAS_ITEMS_COUNT 4
#elif defined(PCBSKY9X)
#define ANAS_ITEMS_COUNT 3
#else
#define ANAS_ITEMS_COUNT 2
#endif
SIMPLE_MENU(STR_MENUANA, menuTabGeneral, e_Ana, ANAS_ITEMS_COUNT);
STICK_SCROLL_DISABLE();
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
#if (NUM_STICKS+NUM_POTS) > 9
coord_t y = MENU_TITLE_HEIGHT + 1 + (i/3)*FH;
const uint8_t x_coord[] = {0, 70, 154};
uint8_t x = x_coord[i%3];
lcd_outdezNAtt(x, y, i+1, LEADING0|LEFT, 2);
lcd_putc(x+2*FW-2, y, ':');
#else
coord_t y = MENU_TITLE_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? 64+5 : 0;
putsStrIdx(x, y, PSTR("A"), i+1);
lcd_putc(lcdNextPos, y, ':');
#endif
lcd_outhex4(x+3*FW-1, y, anaIn(i));
lcd_outdez8(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
}
#if !defined(CPUARM)
// Display raw BandGap result (debug)
lcd_puts(64+5, MENU_TITLE_HEIGHT+1+3*FH, STR_BG);
lcd_outdezAtt(64+5+6*FW-3, 1+4*FH, BandGap, 0);
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(MENU_TITLE_HEIGHT+1+4*FH, STR_BATT_CALIB);
static int32_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8;
uint32_t batCalV = (adcBatt + adcBatt*(g_eeGeneral.vBatCalib)/128) * 4191;
batCalV /= 55296;
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_TITLE_HEIGHT+1+4*FH, batCalV, (m_posVert==1 ? INVERS : 0));
#elif defined(PCBGRUVIN9X)
lcd_putsLeft(6*FH-2, STR_BATT_CALIB);
// Gruvin wants 2 decimal places and instant update of volts calib field when button pressed
static uint16_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8; // running average, sourced directly (to avoid unending debate :P)
uint32_t batCalV = ((uint32_t)adcBatt*1390 + (10*(int32_t)adcBatt*g_eeGeneral.vBatCalib)/8) / BandGap;
lcd_outdezNAtt(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, batCalV, PREC2|(m_posVert==1 ? INVERS : 0));
#else
lcd_putsLeft(6*FH-2, STR_BATT_CALIB);
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, g_vbat100mV, (m_posVert==1 ? INVERS : 0));
#endif
if (m_posVert==1) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatCalib, -127, 127);
#if defined(PCBSKY9X) && !defined(REVA)
lcd_putsLeft(6*FH+1, STR_CURRENT_CALIB);
putsValueWithUnit(LEN_CALIB_FIELDS*FW+4*FW, 6*FH+1, getCurrent(), UNIT_MILLIAMPS, (m_posVert==2 ? INVERS : 0)) ;
if (m_posVert==2) CHECK_INCDEC_GENVAR(event, g_eeGeneral.currentCalib, -49, 49);
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(7*FH+1, STR_TEMP_CALIB);
putsValueWithUnit(LEN_CALIB_FIELDS*FW+4*FW, 7*FH+1, getTemperature(), UNIT_TEMPERATURE, (m_posVert==3 ? INVERS : 0)) ;
if (m_posVert==3) CHECK_INCDEC_GENVAR(event, g_eeGeneral.temperatureCalib, -100, 100);
#endif
}

View file

@ -0,0 +1,81 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void displayKeyState(uint8_t x, uint8_t y, EnumKeys key)
{
uint8_t t = switchState(key);
lcd_putcAtt(x, y, t+'0', t ? INVERS : 0);
}
void menuGeneralDiagKeys(uint8_t event)
{
SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, e_Keys, 1);
lcd_puts(14*FW, MENU_TITLE_HEIGHT+2*FH, STR_VTRIM);
for(uint8_t i=0; i<9; i++) {
coord_t y;
if (i<8) {
y = MENU_TITLE_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i));
}
if (i<6) {
y = i*FH+MENU_TITLE_HEIGHT+FH;
lcd_putsiAtt(0, y, STR_VKEYS, (5-i), 0);
displayKeyState(5*FW+2, y, (EnumKeys)(KEY_MENU+(5-i)));
}
if (i != SW_ID0-SW_BASE) {
y = MENU_TITLE_HEIGHT+i*FH-2*FH;
putsSwitches(8*FW, y, i+1, 0); //ohne off,on
displayKeyState(11*FW+2, y, (EnumKeys)(SW_BASE+i));
}
}
#if defined(ROTARY_ENCODERS) || defined(ROTARY_ENCODER_NAVIGATION)
for(uint8_t i=0; i<DIM(g_rotenc); i++) {
coord_t y = MENU_TITLE_HEIGHT /* ??? + 1 ??? */ + i*FH;
lcd_putsiAtt(14*FW, y, STR_VRENCODERS, i, 0);
lcd_outdezNAtt(18*FW, y, g_rotenc[i], LEFT|(switchState((EnumKeys)(BTN_REa+i)) ? INVERS : 0));
}
#endif
}

View file

@ -0,0 +1,110 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
enum menuGeneralHwItems {
ITEM_SETUP_HW_OPTREX_DISPLAY,
ITEM_SETUP_HW_STICKS_GAINS_LABELS,
ITEM_SETUP_HW_STICK_LV_GAIN,
ITEM_SETUP_HW_STICK_LH_GAIN,
ITEM_SETUP_HW_STICK_RV_GAIN,
ITEM_SETUP_HW_STICK_RH_GAIN,
IF_ROTARY_ENCODERS(ITEM_SETUP_HW_ROTARY_ENCODER)
CASE_BLUETOOTH(ITEM_SETUP_HW_BT_BAUDRATE)
ITEM_SETUP_HW_MAX
};
#define GENERAL_HW_PARAM_OFS (2+(15*FW))
void menuGeneralHardware(uint8_t event)
{
MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
uint8_t sub = m_posVert - 1;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
uint8_t attr = (sub == k ? blink : 0);
switch(k) {
case ITEM_SETUP_HW_OPTREX_DISPLAY:
g_eeGeneral.optrexDisplay = selectMenuItem(GENERAL_HW_PARAM_OFS, y, STR_LCD, STR_VLCD, g_eeGeneral.optrexDisplay, 0, 1, attr, event);
break;
case ITEM_SETUP_HW_STICKS_GAINS_LABELS:
lcd_putsLeft(y, PSTR("Sticks"));
break;
case ITEM_SETUP_HW_STICK_LV_GAIN:
case ITEM_SETUP_HW_STICK_LH_GAIN:
case ITEM_SETUP_HW_STICK_RV_GAIN:
case ITEM_SETUP_HW_STICK_RH_GAIN:
{
lcd_putsiAtt(INDENT_WIDTH, y, PSTR("\002LVLHRVRH"), k-ITEM_SETUP_HW_STICK_LV_GAIN, 0);
lcd_puts(INDENT_WIDTH+3*FW, y, PSTR("Gain"));
uint8_t mask = (1<<(k-ITEM_SETUP_HW_STICK_LV_GAIN));
uint8_t val = (g_eeGeneral.sticksGain & mask ? 1 : 0);
lcd_putcAtt(GENERAL_HW_PARAM_OFS, y, val ? '2' : '1', attr);
if (attr) {
CHECK_INCDEC_GENVAR(event, val, 0, 1);
if (checkIncDec_Ret) {
g_eeGeneral.sticksGain ^= mask;
setSticksGain(g_eeGeneral.sticksGain);
}
}
break;
}
#if defined(ROTARY_ENCODERS)
case ITEM_SETUP_HW_ROTARY_ENCODER:
g_eeGeneral.rotarySteps = selectMenuItem(GENERAL_HW_PARAM_OFS, y, PSTR("Rotary Encoder"), PSTR("\0062steps4steps"), g_eeGeneral.rotarySteps, 0, 1, attr, event);
break;
#endif
#if defined(BLUETOOTH)
case ITEM_SETUP_HW_BT_BAUDRATE:
g_eeGeneral.btBaudrate = selectMenuItem(GENERAL_HW_PARAM_OFS, y, STR_BAUDRATE, PSTR("\005115k 9600 19200"), g_eeGeneral.btBaudrate, 0, 2, attr, event);
if (attr && checkIncDec_Ret) {
btInit();
}
break;
#endif
}
}
}

View file

@ -0,0 +1,293 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuGeneralSdManagerInfo(uint8_t event)
{
SIMPLE_SUBMENU(STR_SD_INFO_TITLE, 1);
lcd_putsLeft(2*FH, STR_SD_TYPE);
lcd_puts(10*FW, 2*FH, SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD);
lcd_putsLeft(3*FH, STR_SD_SIZE);
lcd_outdezAtt(10*FW, 3*FH, SD_GET_SIZE_MB(), LEFT);
lcd_putc(lcdLastPos, 3*FH, 'M');
lcd_putsLeft(4*FH, STR_SD_SECTORS);
lcd_outdezAtt(10*FW, 4*FH, SD_GET_BLOCKNR()/1000, LEFT);
lcd_putc(lcdLastPos, 4*FH, 'k');
lcd_putsLeft(5*FH, STR_SD_SPEED);
lcd_outdezAtt(10*FW, 5*FH, SD_GET_SPEED()/1000, LEFT);
lcd_puts(lcdLastPos, 5*FH, "kb/s");
}
inline bool isFilenameGreater(bool isfile, const char * fn, const char * line)
{
return (isfile && !line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) > 0);
}
inline bool isFilenameLower(bool isfile, const char * fn, const char * line)
{
return (!isfile && line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) < 0);
}
void onSdManagerMenu(const char *result)
{
TCHAR lfn[_MAX_LFN+1];
uint8_t index = m_posVert-1-s_pgOfs;
if (result == STR_SD_INFO) {
pushMenu(menuGeneralSdManagerInfo);
}
else if (result == STR_SD_FORMAT) {
POPUP_CONFIRMATION(STR_CONFIRM_FORMAT);
}
else if (result == STR_DELETE_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat_P(lfn, PSTR("/"));
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
f_unlink(lfn);
strncpy(statusLineMsg, reusableBuffer.sdmanager.lines[index], 13);
strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED);
showStatusLine();
if ((uint16_t)m_posVert == reusableBuffer.sdmanager.count) m_posVert--;
reusableBuffer.sdmanager.offset = s_pgOfs-1;
}
#if defined(CPUARM)
/* TODO else if (result == STR_LOAD_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
POPUP_WARNING(eeLoadModelSD(lfn));
} */
else if (result == STR_PLAY_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
audioQueue.stopAll();
audioQueue.playFile(lfn, 0, ID_PLAY_FROM_SD_MANAGER);
}
#endif
}
void menuGeneralSdManager(uint8_t _event)
{
FILINFO fno;
DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#if defined(SDCARD)
if (s_warning_result) {
s_warning_result = 0;
displayPopup(STR_FORMATTING);
closeLogs();
#if defined(PCBSKY9X)
Card_state = SD_ST_DATA;
#endif
#if defined(CPUARM)
audioQueue.stopSD();
#endif
if (f_mkfs(0, 1, 0) == FR_OK) {
f_chdir("/");
reusableBuffer.sdmanager.offset = -1;
}
else {
POPUP_WARNING(STR_SDCARD_ERROR);
}
}
#endif
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, 1+reusableBuffer.sdmanager.count);
if (s_editMode > 0)
s_editMode = 0;
switch(_event) {
case EVT_ENTRY:
f_chdir(ROOT_PATH);
reusableBuffer.sdmanager.offset = 65535;
break;
CASE_EVT_ROTARY_BREAK
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_ENTER):
{
if (m_posVert > 0) {
vertpos_t index = m_posVert-1-s_pgOfs;
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
f_chdir(reusableBuffer.sdmanager.lines[index]);
s_pgOfs = 0;
m_posVert = 1;
reusableBuffer.sdmanager.offset = 65535;
killEvents(_event);
break;
}
}
if (!IS_ROTARY_BREAK(_event) || m_posVert==0)
break;
// no break;
}
case EVT_KEY_LONG(KEY_ENTER):
killEvents(_event);
if (m_posVert == 0) {
MENU_ADD_ITEM(STR_SD_INFO);
MENU_ADD_ITEM(STR_SD_FORMAT);
}
else
{
#if defined(CPUARM)
uint8_t index = m_posVert-1-s_pgOfs;
// TODO duplicated code for finding extension
char * ext = reusableBuffer.sdmanager.lines[index];
int len = strlen(ext) - 4;
ext += len;
/* TODO if (!strcasecmp(ext, MODELS_EXT)) {
s_menu[s_menu_count++] = STR_LOAD_FILE;
}
else */ if (!strcasecmp(ext, SOUNDS_EXT)) {
MENU_ADD_ITEM(STR_PLAY_FILE);
}
#endif
if (!READ_ONLY()) {
MENU_ADD_ITEM(STR_DELETE_FILE);
// MENU_ADD_ITEM(STR_RENAME_FILE); TODO: Implement
// MENU_ADD_ITEM(STR_COPY_FILE); TODO: Implement
}
}
menuHandler = onSdManagerMenu;
break;
}
if (reusableBuffer.sdmanager.offset != s_pgOfs) {
if (s_pgOfs == 0) {
reusableBuffer.sdmanager.offset = 0;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
}
else if (s_pgOfs == reusableBuffer.sdmanager.count-7) {
reusableBuffer.sdmanager.offset = s_pgOfs;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
}
else if (s_pgOfs > reusableBuffer.sdmanager.offset) {
memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
memset(reusableBuffer.sdmanager.lines[6], 0xff, SD_SCREEN_FILE_LENGTH);
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = 1;
}
else {
memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
}
reusableBuffer.sdmanager.count = 0;
FRESULT res = f_opendir(&dir, "."); /* Open the directory */
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
reusableBuffer.sdmanager.count++;
bool isfile = !(fno.fattrib & AM_DIR);
if (s_pgOfs == 0) {
for (uint8_t i=0; i<LCD_LINES-1; i++) {
char *line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) {
if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn);
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break;
}
}
}
else if (reusableBuffer.sdmanager.offset == s_pgOfs) {
for (int8_t i=6; i>=0; i--) {
char *line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) {
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn);
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break;
}
}
}
else if (s_pgOfs > reusableBuffer.sdmanager.offset) {
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) {
memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[6], fn);
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile;
}
}
else {
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) {
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[0], fn);
reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile;
}
}
}
}
}
reusableBuffer.sdmanager.offset = s_pgOfs;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
lcdNextPos = 0;
uint8_t attr = (m_posVert-1-s_pgOfs == i ? BSS|INVERS : BSS);
if (reusableBuffer.sdmanager.lines[i][0]) {
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', attr); }
lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', attr); }
}
}
}

View file

@ -0,0 +1,588 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
const pm_uchar sticks[] PROGMEM = {
#include "../../bitmaps/sticks.lbm"
};
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#define RADIO_SETUP_DATE_COLUMN (FW*15+7)
#if !defined(CPUM64)
#define SLIDER_5POS(y, value, label, event, attr) { \
int8_t tmp = value; \
displaySlider(RADIO_SETUP_2ND_COLUMN, y, 2+tmp, 4, attr); \
value = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, label, NULL, tmp, -2, +2, attr, event); \
}
#elif defined(GRAPHICS)
#define SLIDER_5POS(y, value, label, event, attr) { \
int8_t tmp = value; \
display5posSlider(RADIO_SETUP_2ND_COLUMN, y, tmp, attr); \
value = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, label, NULL, tmp, -2, +2, attr, event); \
}
#else
#define SLIDER_5POS(y, value, label, event, attr) value = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, label, STR_VBEEPLEN, value, -2, +2, attr, event)
#endif
#if defined(SPLASH) && !defined(FSPLASH)
#define CASE_SPLASH_PARAM(x) x,
#else
#define CASE_SPLASH_PARAM(x)
#endif
enum menuGeneralSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME)
CASE_BATTGRAPH(ITEM_SETUP_BATT_RANGE)
ITEM_SETUP_SOUND_LABEL,
CASE_AUDIO(ITEM_SETUP_BEEP_MODE)
CASE_BUZZER(ITEM_SETUP_BUZZER_MODE)
CASE_VOICE(ITEM_SETUP_SPEAKER_VOLUME)
CASE_CPUARM(ITEM_SETUP_BEEP_VOLUME)
ITEM_SETUP_BEEP_LENGTH,
CASE_AUDIO(ITEM_SETUP_SPEAKER_PITCH)
CASE_CPUARM(ITEM_SETUP_WAV_VOLUME)
CASE_CPUARM(ITEM_SETUP_BACKGROUND_VOLUME)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_LABEL)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_VOLUME)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_PITCH)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_RANGE)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_REPEAT)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_LABEL)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_MODE)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_LENGTH)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_STRENGTH)
ITEM_SETUP_CONTRAST,
ITEM_SETUP_ALARMS_LABEL,
ITEM_SETUP_BATTERY_WARNING,
CASE_PCBSKY9X(ITEM_SETUP_CAPACITY_WARNING)
CASE_PCBSKY9X(ITEM_SETUP_TEMPERATURE_WARNING)
ITEM_SETUP_INACTIVITY_ALARM,
ITEM_SETUP_MEMORY_WARNING,
ITEM_SETUP_ALARM_WARNING,
IF_ROTARY_ENCODERS(ITEM_SETUP_RE_NAVIGATION)
ITEM_SETUP_BACKLIGHT_LABEL,
ITEM_SETUP_BACKLIGHT_MODE,
ITEM_SETUP_BACKLIGHT_DELAY,
CASE_CPUARM(ITEM_SETUP_BRIGHTNESS)
CASE_PWM_BACKLIGHT(ITEM_SETUP_BACKLIGHT_BRIGHTNESS_OFF)
CASE_PWM_BACKLIGHT(ITEM_SETUP_BACKLIGHT_BRIGHTNESS_ON)
ITEM_SETUP_FLASH_BEEP,
CASE_SPLASH_PARAM(ITEM_SETUP_DISABLE_SPLASH)
CASE_GPS(ITEM_SETUP_TIMEZONE)
CASE_GPS(ITEM_SETUP_GPSFORMAT)
CASE_PXX(ITEM_SETUP_COUNTRYCODE)
CASE_CPUARM(ITEM_SETUP_LANGUAGE)
CASE_CPUARM(ITEM_SETUP_IMPERIAL)
IF_FAI_CHOICE(ITEM_SETUP_FAI)
CASE_MAVLINK(ITEM_MAVLINK_BAUD)
CASE_CPUARM(ITEM_SETUP_SWITCHES_DELAY)
ITEM_SETUP_RX_CHANNEL_ORD,
ITEM_SETUP_STICK_MODE_LABELS,
ITEM_SETUP_STICK_MODE,
ITEM_SETUP_MAX
};
#if defined(FRSKY_STICKS)
#define COL_TX_MODE 0
#else
#define COL_TX_MODE LABEL(TX_MODE)
#endif
void menuGeneralSetup(uint8_t event)
{
#if defined(RTCLOCK)
struct gtm t;
gettime(&t);
if ((m_posVert==ITEM_SETUP_DATE+1 || m_posVert==ITEM_SETUP_TIME+1) &&
(s_editMode>0) &&
(event==EVT_KEY_FIRST(KEY_ENTER) || event==EVT_KEY_FIRST(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event))) {
// set the date and time into RTC chip
rtcSetTime(&t);
}
#endif
#if defined(FAI_CHOICE)
if (s_warning_result) {
s_warning_result = 0;
g_eeGeneral.fai = true;
eeDirty(EE_GENERAL);
}
#endif
MENU(STR_MENURADIOSETUP, menuTabGeneral, e_Setup, ITEM_SETUP_MAX+1, {0, CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) CASE_VOICE(0) CASE_CPUARM(0) CASE_CPUARM(0) CASE_CPUARM(0) 0, CASE_AUDIO(0) CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_PCBSKY9X(0) CASE_PCBSKY9X(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, CASE_CPUARM(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) CASE_CPUARM(0) CASE_CPUARM(0) IF_FAI_CHOICE(0) CASE_MAVLINK(0) CASE_CPUARM(0) 0, COL_TX_MODE, 1/*to force edit mode*/});
uint8_t sub = m_posVert - 1;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
uint8_t attr = (sub == k ? blink : 0);
switch(k) {
#if defined(RTCLOCK)
case ITEM_SETUP_DATE:
lcd_putsLeft(y, STR_DATE);
lcd_putc(RADIO_SETUP_DATE_COLUMN, y, '-'); lcd_putc(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-');
for (uint8_t j=0; j<3; j++) {
uint8_t rowattr = (m_posHorz==j ? attr : 0);
switch (j) {
case 0:
lcd_outdezAtt(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0);
break;
case 1:
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0);
break;
case 2:
{
int16_t year = 1900 + t.tm_year;
int8_t dlim = (((((year%4==0) && (year%100!=0)) || (year%400==0)) && (t.tm_mon==1)) ? 1 : 0);
static const pm_uint8_t dmon[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
dlim += pgm_read_byte(&dmon[t.tm_mon]);
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0);
break;
}
}
}
if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break;
case ITEM_SETUP_TIME:
lcd_putsLeft(y, STR_TIME);
lcd_putc(RADIO_SETUP_TIME_COLUMN+1, y, ':'); lcd_putc(RADIO_SETUP_TIME_COLUMN+3*FW-2, y, ':');
for (uint8_t j=0; j<3; j++) {
uint8_t rowattr = (m_posHorz==j ? attr : 0);
switch (j) {
case 0:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0);
break;
case 1:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0);
break;
case 2:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0);
break;
}
}
if (attr && checkIncDec_Ret)
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
break;
#endif
#if defined(BATTGRAPH)
case ITEM_SETUP_BATT_RANGE:
lcd_putsLeft(y, STR_BATTERY_RANGE);
putsVolts(RADIO_SETUP_2ND_COLUMN, y, 90+g_eeGeneral.vBatMin, (m_posHorz==0 ? attr : 0)|LEFT|NO_UNIT);
lcd_putc(lcdLastPos, y, '-');
putsVolts(lcdLastPos+FW, y, 120+g_eeGeneral.vBatMax, (m_posHorz>0 ? attr : 0)|LEFT|NO_UNIT);
if (attr && s_editMode>0) {
if (m_posHorz==0)
CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMin, -50, g_eeGeneral.vBatMax+29); // min=4.0V
else
CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMax, g_eeGeneral.vBatMin-29, +40); // max=16.0V
}
break;
#endif
case ITEM_SETUP_SOUND_LABEL:
lcd_putsLeft(y, STR_SOUND_LABEL);
break;
#if defined(AUDIO)
case ITEM_SETUP_BEEP_MODE:
g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event);
#if defined(FRSKY)
if (attr && checkIncDec_Ret) frskySendAlarms();
#endif
break;
#if defined(BUZZER)
case ITEM_SETUP_BUZZER_MODE:
g_eeGeneral.buzzerMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_BUZZER, STR_VBEEPMODE, g_eeGeneral.buzzerMode, -2, 1, attr, event);
#if defined(FRSKY)
if (attr && checkIncDec_Ret) frskySendAlarms();
#endif
break;
#endif
#else
case ITEM_SETUP_BUZZER_MODE:
g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event);
#if defined(FRSKY)
if (attr && checkIncDec_Ret) frskySendAlarms();
#endif
break;
#endif
#if defined(VOICE)
case ITEM_SETUP_SPEAKER_VOLUME:
{
lcd_putsLeft(y, STR_SPEAKER_VOLUME);
uint8_t b = g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF;
displaySlider(RADIO_SETUP_2ND_COLUMN, y, b, VOLUME_LEVEL_MAX, attr);
if (attr) {
CHECK_INCDEC_GENVAR(event, b, 0, VOLUME_LEVEL_MAX);
if (checkIncDec_Ret) {
g_eeGeneral.speakerVolume = (int8_t)b-VOLUME_LEVEL_DEF;
#if !defined(CPUARM)
setVolume(b);
#endif
}
}
break;
}
#endif
#if defined(CPUARM)
case ITEM_SETUP_BEEP_VOLUME:
SLIDER_5POS(y, g_eeGeneral.beepVolume, STR_BEEP_VOLUME, event, attr);
break;
case ITEM_SETUP_WAV_VOLUME:
SLIDER_5POS(y, g_eeGeneral.wavVolume, STR_WAV_VOLUME, event, attr);
break;
case ITEM_SETUP_BACKGROUND_VOLUME:
SLIDER_5POS(y, g_eeGeneral.backgroundVolume, STR_BG_VOLUME, event, attr);
break;
#endif
case ITEM_SETUP_BEEP_LENGTH:
SLIDER_5POS(y, g_eeGeneral.beepLength, STR_BEEP_LENGTH, event, attr);
break;
#if defined(AUDIO)
case ITEM_SETUP_SPEAKER_PITCH:
lcd_putsLeft( y, STR_SPKRPITCH);
#if defined(CPUARM)
lcd_putcAtt(RADIO_SETUP_2ND_COLUMN, y, '+', attr);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN+FW, y, g_eeGeneral.speakerPitch*15, attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
#else
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.speakerPitch, attr|LEFT);
#endif
if (attr) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.speakerPitch, 0, 20);
}
break;
#endif
#if defined(CPUARM) && defined(VARIO)
case ITEM_SETUP_VARIO_LABEL:
lcd_putsLeft(y, STR_VARIO);
break;
case ITEM_SETUP_VARIO_VOLUME:
SLIDER_5POS(y, g_eeGeneral.varioVolume, TR_SPEAKER_VOLUME, event, attr);
break;
case ITEM_SETUP_VARIO_PITCH:
lcd_putsLeft(y, STR_PITCH_AT_ZERO);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioPitch, -40, 40);
break;
case ITEM_SETUP_VARIO_RANGE:
lcd_putsLeft(y, STR_PITCH_AT_MAX);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10)+VARIO_FREQUENCY_RANGE+(g_eeGeneral.varioRange*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRange, -80, 80);
break;
case ITEM_SETUP_VARIO_REPEAT:
lcd_putsLeft(y, STR_REPEAT_AT_ZERO);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_REPEAT_ZERO+(g_eeGeneral.varioRepeat*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, STR_MS, attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRepeat, -30, 50);
break;
#endif
#if defined(HAPTIC)
case ITEM_SETUP_HAPTIC_LABEL:
lcd_putsLeft(y, STR_HAPTIC_LABEL);
break;
case ITEM_SETUP_HAPTIC_MODE:
g_eeGeneral.hapticMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBEEPMODE, g_eeGeneral.hapticMode, -2, 1, attr, event);
break;
case ITEM_SETUP_HAPTIC_LENGTH:
SLIDER_5POS(y, g_eeGeneral.hapticLength, STR_LENGTH, event, attr);
break;
case ITEM_SETUP_HAPTIC_STRENGTH:
SLIDER_5POS(y, g_eeGeneral.hapticStrength, STR_HAPTICSTRENGTH, event, attr);
break;
#endif
case ITEM_SETUP_CONTRAST:
lcd_putsLeft(y, STR_CONTRAST);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.contrast, attr|LEFT);
if (attr) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.contrast, CONTRAST_MIN, CONTRAST_MAX);
lcdSetContrast();
}
break;
case ITEM_SETUP_ALARMS_LABEL:
lcd_putsLeft(y, STR_ALARMS_LABEL);
break;
case ITEM_SETUP_BATTERY_WARNING:
lcd_putsLeft(y, STR_BATTERYWARNING);
putsVolts(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.vBatWarn, attr|LEFT);
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V
break;
case ITEM_SETUP_MEMORY_WARNING:
{
uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event);
break;
}
case ITEM_SETUP_ALARM_WARNING:
{
uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event);
break;
}
#if defined(PCBSKY9X)
case ITEM_SETUP_CAPACITY_WARNING:
lcd_putsLeft(y, STR_CAPAWARNING);
putsValueWithUnit(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.mAhWarn*50, UNIT_MAH, attr|LEFT) ;
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.mAhWarn, 0, 100);
break;
#endif
#if defined(PCBSKY9X)
case ITEM_SETUP_TEMPERATURE_WARNING:
lcd_putsLeft(y, STR_TEMPWARNING);
putsValueWithUnit(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.temperatureWarn, UNIT_TEMPERATURE, attr|LEFT) ;
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.temperatureWarn, 0, 120); // 0 means no alarm
break;
#endif
case ITEM_SETUP_INACTIVITY_ALARM:
lcd_putsLeft( y,STR_INACTIVITYALARM);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.inactivityTimer, attr|LEFT);
lcd_putc(lcdLastPos, y, 'm');
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
break;
#if ROTARY_ENCODERS > 0
case ITEM_SETUP_RE_NAVIGATION:
g_eeGeneral.reNavigation = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_RENAVIG, STR_VRENAVIG, g_eeGeneral.reNavigation, 0, NUM_ROTARY_ENCODERS, attr, event);
if (attr && checkIncDec_Ret) {
g_rotenc[NAVIGATION_RE_IDX()] = 0;
}
break;
#endif
case ITEM_SETUP_BACKLIGHT_LABEL:
lcd_putsLeft(y, STR_BACKLIGHT_LABEL);
break;
case ITEM_SETUP_BACKLIGHT_MODE:
g_eeGeneral.backlightMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBLMODE, g_eeGeneral.backlightMode, e_backlight_mode_off, e_backlight_mode_on, attr, event);
break;
case ITEM_SETUP_FLASH_BEEP:
g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ;
break;
case ITEM_SETUP_BACKLIGHT_DELAY:
lcd_putsLeft(y, STR_BLDELAY);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT);
lcd_putc(lcdLastPos, y, 's');
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5);
break;
#if defined(CPUARM)
case ITEM_SETUP_BRIGHTNESS:
lcd_putsLeft(y, STR_BRIGHTNESS);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 100-g_eeGeneral.backlightBright, attr|LEFT) ;
if (attr) {
uint8_t b = 100 - g_eeGeneral.backlightBright;
CHECK_INCDEC_GENVAR(event, b, 0, 100);
g_eeGeneral.backlightBright = 100 - b;
}
break;
#endif
#if defined(PWM_BACKLIGHT)
case ITEM_SETUP_BACKLIGHT_BRIGHTNESS_OFF:
lcd_putsLeft(y, STR_BLOFFBRIGHTNESS);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.blOffBright, attr|LEFT);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.blOffBright, 0, 15);
break;
case ITEM_SETUP_BACKLIGHT_BRIGHTNESS_ON:
lcd_putsLeft(y, STR_BLONBRIGHTNESS);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 15-g_eeGeneral.blOnBright, attr|LEFT);
if (attr) g_eeGeneral.blOnBright = 15 - checkIncDecGen(event, 15-g_eeGeneral.blOnBright, 0, 15);
break;
#endif
#if defined(SPLASH) && !defined(FSPLASH)
case ITEM_SETUP_DISABLE_SPLASH:
{
uint8_t b = 1-g_eeGeneral.splashMode;
g_eeGeneral.splashMode = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_SPLASHSCREEN, attr, event);
break;
}
#endif
#if defined(FRSKY) && defined(FRSKY_HUB) && defined(GPS)
case ITEM_SETUP_TIMEZONE:
lcd_putsLeft(y, STR_TIMEZONE);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12);
break;
case ITEM_SETUP_GPSFORMAT:
g_eeGeneral.gpsFormat = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_GPSCOORD, STR_GPSFORMAT, g_eeGeneral.gpsFormat, 0, 1, attr, event);
break;
#endif
#if defined(PXX)
case ITEM_SETUP_COUNTRYCODE:
g_eeGeneral.countryCode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_COUNTRYCODE, STR_COUNTRYCODES, g_eeGeneral.countryCode, 0, 2, attr, event);
break;
#endif
#if defined(CPUARM)
case ITEM_SETUP_LANGUAGE:
lcd_putsLeft(y, STR_VOICELANG);
lcd_putsAtt(RADIO_SETUP_2ND_COLUMN, y, currentLanguagePack->name, attr);
if (attr) {
currentLanguagePackIdx = checkIncDec(event, currentLanguagePackIdx, 0, DIM(languagePacks)-2, EE_GENERAL);
if (checkIncDec_Ret) {
currentLanguagePack = languagePacks[currentLanguagePackIdx];
strncpy(g_eeGeneral.ttsLanguage, currentLanguagePack->id, 2);
}
}
break;
case ITEM_SETUP_IMPERIAL:
g_eeGeneral.imperial = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_UNITSSYSTEM, STR_VUNITSSYSTEM, g_eeGeneral.imperial, 0, 1, attr, event);
break;
#endif
#if defined(FAI_CHOICE)
case ITEM_SETUP_FAI:
onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event);
if (attr && checkIncDec_Ret) {
if (g_eeGeneral.fai)
POPUP_WARNING(PSTR("FAI\001mode blocked!"));
else
POPUP_CONFIRMATION(PSTR("FAI mode?"));
}
break;
#endif
#if defined(MAVLINK)
case ITEM_MAVLINK_BAUD:
g_eeGeneral.mavbaud = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MAVLINK_BAUD_LABEL, STR_MAVLINK_BAUDS, g_eeGeneral.mavbaud, 0, 7, attr, event);
break;
#endif
#if defined(CPUARM)
case ITEM_SETUP_SWITCHES_DELAY:
lcd_putsLeft(y, STR_SWITCHES_DELAY);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 10*SWITCHES_DELAY(), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, STR_MS, attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.switchesDelay, -15, +15);
break;
#endif
case ITEM_SETUP_RX_CHANNEL_ORD:
lcd_putsLeft(y, STR_RXCHANNELORD); // RAET->AETR
for (uint8_t i=1; i<=4; i++) {
putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, channel_order(i), attr);
}
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23);
break;
case ITEM_SETUP_STICK_MODE_LABELS:
lcd_putsLeft(y, NO_INDENT(STR_MODE));
for (uint8_t i=0; i<4; i++) {
lcd_img((6+4*i)*FW, y, sticks, i, 0);
#if defined(FRSKY_STICKS)
if (g_eeGeneral.stickReverse & (1<<i)) {
drawFilledRect((6+4*i)*FW, y, 3*FW, FH-1);
}
#endif
}
#if defined(FRSKY_STICKS)
if (attr) {
s_editMode = 0;
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickReverse, 0, 15);
lcd_rect(6*FW-1, y-1, 15*FW+2, 9);
}
#endif
break;
case ITEM_SETUP_STICK_MODE:
lcd_putcAtt(2*FW, y, '1'+g_eeGeneral.stickMode, attr);
for (uint8_t i=0; i<4; i++) {
putsMixerSource((6+4*i)*FW, y, MIXSRC_Rud + pgm_read_byte(modn12x3 + 4*g_eeGeneral.stickMode + i), 0);
}
if (attr && s_editMode>0) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickMode, 0, 3);
}
else if (stickMode != g_eeGeneral.stickMode) {
pausePulses();
stickMode = g_eeGeneral.stickMode;
checkTHR();
resumePulses();
clearKeyEvents();
}
#if defined(ROTARY_ENCODER_NAVIGATION)
MOVE_CURSOR_FROM_HERE();
#endif
break;
}
}
}

View file

@ -0,0 +1,114 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 TRAINER_CALIB_POS 8
void menuGeneralTrainer(uint8_t event)
{
uint8_t y;
bool slave = SLAVE_MODE();
MENU(STR_MENUTRAINER, menuTabGeneral, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
if (slave) {
lcd_puts(7*FW, 4*FH, STR_SLAVE);
}
else {
uint8_t attr;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
lcd_puts(3*FW, MENU_TITLE_HEIGHT+1, STR_MODESRC);
y = MENU_TITLE_HEIGHT + 1 + FH;
for (uint8_t i=1; i<=NUM_STICKS; i++) {
uint8_t chan = channel_order(i);
volatile TrainerMix *td = &g_eeGeneral.trainer.mix[chan-1];
putsMixerSource(0, y, MIXSRC_Rud-1+chan, (m_posVert==i && CURSOR_ON_LINE()) ? INVERS : 0);
for (uint8_t j=0; j<3; j++) {
attr = ((m_posVert==i && m_posHorz==j) ? blink : 0);
switch(j) {
case 0:
lcd_putsiAtt(4*FW, y, STR_TRNMODE, td->mode, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->mode, 0, 2);
break;
case 1:
lcd_outdezAtt(11*FW, y, td->studWeight, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->studWeight, -125, 125);
break;
case 2:
lcd_putsiAtt(12*FW, y, STR_TRNCHN, td->srcChn, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->srcChn, 0, 3);
break;
}
}
y += FH;
}
attr = (m_posVert==5) ? blink : 0;
lcd_putsLeft(MENU_TITLE_HEIGHT+1+5*FH, STR_MULTIPLIER);
lcd_outdezAtt(LEN_MULTIPLIER*FW+3*FW, MENU_TITLE_HEIGHT+1+5*FH, g_eeGeneral.PPM_Multiplier+10, attr|PREC1);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.PPM_Multiplier, -10, 40);
attr = (m_posVert==6) ? INVERS : 0;
if (attr) s_editMode = 0;
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+1+6*FH, STR_CAL, attr);
for (uint8_t i=0; i<4; i++) {
uint8_t x = (i*TRAINER_CALIB_POS+16)*FW/2;
#if defined (PPM_UNIT_PERCENT_PREC1)
lcd_outdezAtt(x, MENU_TITLE_HEIGHT+1+6*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])*2, PREC1);
#else
lcd_outdezAtt(x, MENU_TITLE_HEIGHT+1+6*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])/5, 0);
#endif
}
if (attr) {
if (event==EVT_KEY_LONG(KEY_ENTER)){
memcpy(g_eeGeneral.trainer.calib, g_ppmIns, sizeof(g_eeGeneral.trainer.calib));
eeDirty(EE_GENERAL);
AUDIO_WARNING1();
}
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuGeneralVersion(uint8_t event)
{
SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1);
lcd_putsLeft(MENU_TITLE_HEIGHT+FH, vers_stamp);
#if defined(COPROCESSOR)
if (Coproc_valid == 1) {
lcd_putsLeft(6*FH, PSTR("CoPr:"));
lcd_outdez8(10*FW, 6*FH, Coproc_read);
}
else {
lcd_putsLeft(6*FH, PSTR("CoPr: ---"));
}
#endif
}

View file

@ -155,7 +155,7 @@ void menuModelSetup(uint8_t event)
int8_t editMode = s_editMode;
for (uint8_t i=0; i<NUM_BODY_LINES; ++i) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*HEIGHT_BODY_LINE;
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
#if defined(CPUARM)
for (int j=0; j<=k; j++) {

661
radio/src/gui/9X/navigation.cpp Executable file
View file

@ -0,0 +1,661 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
vertpos_t s_pgOfs;
int8_t s_editMode;
uint8_t s_noHi;
uint8_t calibrationState;
vertpos_t m_posVert;
horzpos_t m_posHorz;
#if defined(NAVIGATION_POT1)
int16_t p1valdiff;
#endif
#if defined(NAVIGATION_POT2)
int8_t p2valdiff;
#endif
#if defined(AUTOSWITCH)
int8_t checkIncDecMovedSwitch(int8_t val)
{
if (s_editMode>0) {
int8_t swtch = getMovedSwitch();
if (swtch) {
if (IS_MOMENTARY(val) && swtch==val)
val = -val;
else
val = swtch;
}
}
return val;
}
#endif
int8_t checkIncDec_Ret;
#if defined(CPUARM)
INIT_STOPS(stops100, 3, -100, 0, 100)
INIT_STOPS(stops1000, 3, -1000, 0, 1000)
INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST)
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops)
{
int16_t newval = val;
#if defined(DBLKEYS)
uint8_t in = KEYS_PRESSED();
if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) {
bool dblkey = true;
if (DBLKEYS_PRESSED_RGT_LFT(in))
newval = -val;
else if (DBLKEYS_PRESSED_RGT_UP(in)) {
newval = (i_max > 100 ? 100 : i_max);
}
else if (DBLKEYS_PRESSED_LFT_DWN(in)) {
newval = (i_min < -100 ? -100 : i_min);
}
else if (DBLKEYS_PRESSED_UP_DWN(in)) {
newval = 0;
}
else {
dblkey = false;
}
if (dblkey) {
killEvents(KEY_UP);
killEvents(KEY_DOWN);
killEvents(KEY_RIGHT);
killEvents(KEY_LEFT);
event = 0;
}
}
#endif
if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) {
newval++;
AUDIO_KEYPAD_UP();
}
else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) {
newval--;
AUDIO_KEYPAD_DOWN();
}
if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) {
s_editMode = 0;
newval = !val;
}
#if defined(NAVIGATION_POT1)
// change values based on P1
newval -= p1valdiff;
p1valdiff = 0;
#endif
#if defined(AUTOSWITCH)
if (i_flags & INCDEC_SWITCH) {
newval = checkIncDecMovedSwitch(newval);
}
#endif
#if defined(AUTOSOURCE)
if (i_flags & INCDEC_SOURCE) {
if (s_editMode>0) {
int8_t source = GET_MOVED_SOURCE(i_min, i_max);
if (source) {
newval = source;
}
#if defined(AUTOSWITCH)
else {
uint8_t swtch = abs(getMovedSwitch());
if (swtch) {
newval = switchToMix(swtch);
}
}
#endif
}
}
#endif
if (newval > i_max || newval < i_min) {
newval = (newval > i_max ? i_max : i_min);
killEvents(event);
AUDIO_WARNING2();
}
if (newval != val) {
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) {
pauseEvents(event); // delay before auto-repeat continues
if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same
AUDIO_KEYPAD_UP();
else
AUDIO_KEYPAD_DOWN();
}
eeDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
#else
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags)
{
int16_t newval = val;
#if defined(DBLKEYS)
uint8_t in = KEYS_PRESSED();
if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) {
bool dblkey = true;
if (DBLKEYS_PRESSED_RGT_LFT(in))
newval = -val;
else if (DBLKEYS_PRESSED_RGT_UP(in)) {
newval = (i_max > 100 ? 100 : i_max);
}
else if (DBLKEYS_PRESSED_LFT_DWN(in)) {
newval = (i_min < -100 ? -100 : i_min);
}
else if (DBLKEYS_PRESSED_UP_DWN(in)) {
newval = 0;
}
else {
dblkey = false;
}
if (dblkey) {
killEvents(KEY_UP);
killEvents(KEY_DOWN);
killEvents(KEY_RIGHT);
killEvents(KEY_LEFT);
event = 0;
}
}
#endif
if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) {
newval++;
AUDIO_KEYPAD_UP();
}
else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) {
newval--;
AUDIO_KEYPAD_DOWN();
}
if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) {
s_editMode = 0;
newval = !val;
}
#if defined(NAVIGATION_POT1)
// change values based on P1
newval -= p1valdiff;
p1valdiff = 0;
#endif
#if defined(AUTOSWITCH)
if (i_flags & INCDEC_SWITCH) {
newval = checkIncDecMovedSwitch(newval);
}
#endif
#if defined(AUTOSOURCE)
if (i_flags & INCDEC_SOURCE) {
if (s_editMode>0) {
int8_t source = GET_MOVED_SOURCE(i_min, i_max);
if (source) {
newval = source;
}
#if defined(AUTOSWITCH)
else {
uint8_t swtch = abs(getMovedSwitch());
if (swtch) {
newval = switchToMix(swtch);
}
}
#endif
}
}
#endif
if (newval > i_max || newval < i_min) {
newval = (newval > i_max ? i_max : i_min);
killEvents(event);
AUDIO_WARNING2();
}
if (newval != val) {
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) {
pauseEvents(event); // delay before auto-repeat continues
if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same
AUDIO_KEYPAD_UP();
else
AUDIO_KEYPAD_DOWN();
}
eeDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
#endif
#if defined(CPUM64)
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
{
return checkIncDec(event, i_val, i_min, i_max, EE_MODEL);
}
int8_t checkIncDecModelZero(uint8_t event, int8_t i_val, int8_t i_max)
{
return checkIncDecModel(event, i_val, 0, i_max);
}
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
{
return checkIncDec(event, i_val, i_min, i_max, EE_GENERAL);
}
#endif
#define SCROLL_TH 64
#define SCROLL_POT1_TH 32
#if defined(CPUARM)
#define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0)
#else
#define CURSOR_NOT_ALLOWED_IN_ROW(row) (MAXCOL(row) == TITLE_ROW)
#endif
#define MAXCOL(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0)
#define INC(val, min, max) if (val<max) {val++;} else {val=min;}
#define DEC(val, min, max) if (val>min) {val--;} else {val=max;}
#if defined(CPUARM)
tmr10ms_t menuEntryTime;
#endif
void check(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow)
{
vertpos_t l_posVert = m_posVert;
horzpos_t l_posHorz = m_posHorz;
uint8_t maxcol = MAXCOL(l_posVert);
#if defined(NAVIGATION_POT1)
// check pot 1 - if changed -> scroll values
static int16_t p1val;
static int16_t p1valprev;
p1valdiff = (p1val-calibratedStick[6]) / SCROLL_POT1_TH;
if (p1valdiff) {
p1valdiff = (p1valprev-calibratedStick[6]) / 2;
p1val = calibratedStick[6];
}
p1valprev = calibratedStick[6];
#endif
#if defined(NAVIGATION_POT2)
// check pot 2 - if changed -> scroll menu
static int16_t p2valprev;
p2valdiff = (p2valprev-calibratedStick[4]) / SCROLL_TH;
if (p2valdiff) p2valprev = calibratedStick[4];
#endif
#if defined(NAVIGATION_POT3)
// check pot 3 if changed -> cursor down/up
static int16_t p3valprev;
int8_t scrollUD = (p3valprev-calibratedStick[5]) / SCROLL_TH;
if (scrollUD) p3valprev = calibratedStick[5];
#else
#define scrollUD 0
#endif
if (p2valdiff || scrollUD || p1valdiff) backlightOn(); // on keypress turn the light on
if (menuTab) {
uint8_t attr = 0;
if (l_posVert==0 && !calibrationState) {
attr = INVERS;
int8_t cc = curr;
if (p2valdiff) {
cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1));
}
switch(event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK:
if (s_editMode < 0 && maxrow > 0) {
s_editMode = 0;
// TODO ? l_posVert = (horTab && horTab[1]==0xff) ? 2 : 1;
l_posHorz = 0;
}
else {
s_editMode = -1;
}
event = 0;
break;
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LEFT:
if (s_editMode >= 0)
break;
#endif
case EVT_KEY_FIRST(KEY_LEFT):
if (curr > 0)
cc = curr - 1;
else
cc = menuTabSize-1;
break;
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_RIGHT:
if (s_editMode >= 0)
break;
#endif
case EVT_KEY_FIRST(KEY_RIGHT):
if (curr < (menuTabSize-1))
cc = curr + 1;
else
cc = 0;
break;
}
if (cc != curr) {
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[cc]));
}
#if defined(ROTARY_ENCODER_NAVIGATION)
if (IS_RE_NAVIGATION_ENABLE() && s_editMode < 0)
attr = INVERS|BLINK;
#endif
}
calibrationState = 0;
displayScreenIndex(curr, menuTabSize, attr);
}
DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);
if (s_editMode<=0) {
if (scrollUD) {
l_posVert = limit((int8_t)0, (int8_t)(l_posVert - scrollUD), (int8_t)maxrow);
l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
}
if (p2valdiff && l_posVert>0) {
l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol);
}
}
switch(event)
{
case EVT_ENTRY:
#if defined(CPUARM)
menuEntryTime = get_tmr10ms();
#endif
l_posVert = POS_VERT_INIT;
l_posHorz = POS_HORZ_INIT(l_posVert);
SET_SCROLLBAR_X(LCD_W-1);
#if defined(ROTARY_ENCODER_NAVIGATION)
if (menuTab) {
s_editMode = EDIT_MODE_INIT;
break;
}
// no break
#else
s_editMode = EDIT_MODE_INIT;
break;
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ENTRY_UP:
s_editMode = 0;
SET_SCROLLBAR_X(LCD_W-1);
break;
case EVT_ROTARY_BREAK:
if (s_editMode > 1) break;
#endif
case EVT_KEY_FIRST(KEY_ENTER):
if (!menuTab || l_posVert>0) {
if (READ_ONLY_UNLOCKED()) {
s_editMode = (s_editMode<=0);
}
}
break;
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LONG:
if (s_editMode > 1) break;
killEvents(event);
if (l_posVert != POS_VERT_INIT) {
l_posVert = POS_VERT_INIT;
s_editMode = EDIT_MODE_INIT;
break;
}
// no break
#endif
case EVT_KEY_LONG(KEY_EXIT):
s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same
popMenu();
break;
case EVT_KEY_BREAK(KEY_EXIT):
#if defined(ROTARY_ENCODER_NAVIGATION)
if (s_editMode == 0)
s_editMode = EDIT_MODE_INIT;
else
#endif
if (s_editMode>0) {
s_editMode = 0;
break;
}
if (l_posVert==0 || !menuTab) {
popMenu(); // beeps itself
}
else {
AUDIO_MENUS();
l_posVert = 0;
l_posHorz = 0;
}
break;
case EVT_KEY_REPT(KEY_RIGHT): //inc
if (l_posHorz==maxcol) break;
// no break
case EVT_KEY_FIRST(KEY_RIGHT)://inc
if (!horTab || s_editMode>0) break;
#if defined(ROTARY_ENCODER_NAVIGATION)
CASE_EVT_ROTARY_MOVE_RIGHT
if (s_editMode != 0) break;
if (l_posHorz < maxcol) {
l_posHorz++;
break;
}
else {
l_posHorz = 0;
if (!IS_ROTARY_MOVE_RIGHT(event))
break;
}
#else
INC(l_posHorz, 0, maxcol);
break;
#endif
case EVT_KEY_REPT(KEY_DOWN): //inc
if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break;
// no break
case EVT_KEY_FIRST(KEY_DOWN): //inc
if (s_editMode>0) break;
do {
INC(l_posVert, POS_VERT_INIT, maxrow);
} while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));
#if defined(ROTARY_ENCODER_NAVIGATION)
s_editMode = 0; // if we go down, we must be in this mode
#endif
l_posHorz = min(l_posHorz, MAXCOL(l_posVert));
break;
case EVT_KEY_REPT(KEY_LEFT): //dec
if (l_posHorz==0) break;
// no break
case EVT_KEY_FIRST(KEY_LEFT)://dec
if (!horTab || s_editMode>0) break;
#if defined(ROTARY_ENCODER_NAVIGATION)
CASE_EVT_ROTARY_MOVE_LEFT
if (s_editMode != 0) break;
if (l_posHorz > 0) {
l_posHorz--;
break;
}
else if (IS_ROTARY_MOVE_LEFT(event) && s_editMode == 0) {
l_posHorz = 0xff;
}
else {
l_posHorz = maxcol;
break;
}
#else
DEC(l_posHorz, 0, maxcol);
break;
#endif
case EVT_KEY_REPT(KEY_UP): //dec
if (!IS_ROTARY_LEFT(event) && l_posVert==0) break;
// no break
case EVT_KEY_FIRST(KEY_UP): //dec
if (s_editMode>0) break;
do {
DEC(l_posVert, POS_VERT_INIT, maxrow);
} while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));
#if defined(ROTARY_ENCODER_NAVIGATION)
s_editMode = 0; // if we go up, we must be in this mode
#endif
l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
break;
}
#if defined(CPUARM)
if (l_posVert<1) {
s_pgOfs=0;
}
else if (menuTab && horTab) {
vertpos_t realPosVert = l_posVert;
vertpos_t realPgOfs = s_pgOfs;
vertpos_t realMaxrow = maxrow;
for (vertpos_t i=1; i<=maxrow; i++) {
if (MAXCOL(i) == HIDDEN_ROW) {
realMaxrow--;
if (i < l_posVert)
realPosVert--;
if (i < s_pgOfs)
realPgOfs--;
}
}
if (realPosVert>(LCD_LINES-1)+realPgOfs) realPgOfs = realPosVert-(LCD_LINES-1);
else if (realPosVert<1+realPgOfs) realPgOfs = realPosVert-1;
s_pgOfs = realPgOfs;
for (vertpos_t i=1; i<=realPgOfs; i++) {
if (MAXCOL(i) == HIDDEN_ROW) {
s_pgOfs++;
}
}
maxrow = realMaxrow;
}
else {
uint8_t max = menuTab ? LCD_LINES-1 : LCD_LINES-2;
if (l_posVert>max+s_pgOfs) s_pgOfs = l_posVert-max;
else if (l_posVert<1+s_pgOfs) s_pgOfs = l_posVert-1;
}
#else
uint8_t max = menuTab ? LCD_LINES-1 : LCD_LINES-2;
if (l_posVert<1) s_pgOfs=0;
else if (l_posVert>max+s_pgOfs) s_pgOfs = l_posVert-max;
else if (l_posVert<1+s_pgOfs) s_pgOfs = l_posVert-1;
#endif
m_posVert = l_posVert;
m_posHorz = l_posHorz;
#if !defined(CPUM64)
// cosmetics on 9x
if (s_pgOfs > 0) {
l_posVert--;
if (l_posVert == s_pgOfs && CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)) {
s_pgOfs = l_posVert-1;
}
}
#endif
}
void check_simple(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, vertpos_t maxrow)
{
check(event, curr, menuTab, menuTabSize, 0, 0, maxrow);
}
void check_submenu_simple(check_event_t event, uint8_t maxrow)
{
check_simple(event, 0, 0, 0, maxrow);
}
void repeatLastCursorMove(uint8_t event)
{
if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) {
putEvent(event);
}
else {
m_posHorz = 0;
}
}

206
radio/src/gui/9X/popups.cpp Executable file
View file

@ -0,0 +1,206 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
const pm_char * s_warning = NULL;
const pm_char * s_warning_info;
uint8_t s_warning_info_len;
uint8_t s_warning_type;
uint8_t s_warning_result = 0;
#if defined(CPUARM)
uint8_t s_warning_info_flags = ZCHAR;
int16_t s_warning_input_value;
int16_t s_warning_input_min;
int16_t s_warning_input_max;
#endif
void displayBox()
{
drawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE);
lcd_rect(10, 16, LCD_W-20, 40);
#if defined(CPUARM)
lcd_putsn(WARNING_LINE_X, WARNING_LINE_Y, s_warning, WARNING_LINE_LEN);
#else
lcd_puts(WARNING_LINE_X, WARNING_LINE_Y, s_warning);
#endif
// could be a place for a s_warning_info
}
void displayPopup(const pm_char * pstr)
{
s_warning = pstr;
displayBox();
s_warning = NULL;
lcdRefresh();
}
void displayWarning(uint8_t event)
{
s_warning_result = false;
displayBox();
if (s_warning_info) {
lcd_putsnAtt(WARNING_LINE_X, WARNING_LINE_Y+FH, s_warning_info, s_warning_info_len, WARNING_INFO_FLAGS);
}
lcd_puts(WARNING_LINE_X, WARNING_LINE_Y+2*FH, s_warning_type == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS);
switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK:
#endif
case EVT_KEY_BREAK(KEY_ENTER):
if (s_warning_type == WARNING_TYPE_ASTERISK)
break;
s_warning_result = true;
// no break
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LONG:
killEvents(event);
#endif
case EVT_KEY_BREAK(KEY_EXIT):
s_warning = NULL;
s_warning_type = WARNING_TYPE_ASTERISK;
break;
#if defined(CPUARM)
default:
if (s_warning_type != WARNING_TYPE_INPUT) break;
s_editMode = EDIT_MODIFY_FIELD;
s_warning_input_value = checkIncDec(event, s_warning_input_value, s_warning_input_min, s_warning_input_max);
s_editMode = EDIT_SELECT_FIELD;
break;
#endif
}
}
#if defined(CPUARM)
void (*popupFunc)(uint8_t event) = NULL;
#endif
#if defined(NAVIGATION_MENUS)
const char *s_menu[MENU_MAX_LINES];
uint8_t s_menu_item = 0;
uint16_t s_menu_count = 0;
uint8_t s_menu_flags = 0;
uint16_t s_menu_offset = 0;
void (*menuHandler)(const char *result);
const char * displayMenu(uint8_t event)
{
const char * result = NULL;
uint8_t display_count = min(s_menu_count, (uint16_t)MENU_MAX_LINES);
uint8_t y = (display_count >= 5 ? MENU_Y - FH - 1 : MENU_Y);
drawFilledRect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE);
lcd_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2);
for (uint8_t i=0; i<display_count; i++) {
lcd_putsAtt(MENU_X+6, i*(FH+1) + y + 2, s_menu[i], s_menu_flags);
if (i == s_menu_item) drawFilledRect(MENU_X+1, i*(FH+1) + y + 1, MENU_W-2, 9);
}
if (s_menu_count > display_count) {
displayScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_LINES * (FH+1), s_menu_offset, s_menu_count, MENU_MAX_LINES);
}
switch(event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
CASE_EVT_ROTARY_LEFT
#endif
case EVT_KEY_FIRST(KEY_MOVE_UP):
case EVT_KEY_REPT(KEY_MOVE_UP):
if (s_menu_item > 0) {
s_menu_item--;
}
#if defined(SDCARD)
else if (s_menu_offset > 0) {
s_menu_offset--;
result = STR_UPDATE_LIST;
}
#endif
else {
s_menu_item = display_count - 1;
#if defined(SDCARD)
if (s_menu_count > MENU_MAX_LINES) {
s_menu_offset = s_menu_count - display_count;
result = STR_UPDATE_LIST;
}
#endif
}
break;
#if defined(ROTARY_ENCODER_NAVIGATION)
CASE_EVT_ROTARY_RIGHT
#endif
case EVT_KEY_FIRST(KEY_MOVE_DOWN):
case EVT_KEY_REPT(KEY_MOVE_DOWN):
if (s_menu_item < display_count - 1 && s_menu_offset + s_menu_item + 1 < s_menu_count) {
s_menu_item++;
}
#if defined(SDCARD)
else if (s_menu_count > s_menu_offset + display_count) {
s_menu_offset++;
result = STR_UPDATE_LIST;
}
#endif
else {
s_menu_item = 0;
#if defined(SDCARD)
if (s_menu_offset) {
s_menu_offset = 0;
result = STR_UPDATE_LIST;
}
#endif
}
break;
CASE_EVT_ROTARY_BREAK
case EVT_KEY_BREAK(KEY_ENTER):
result = s_menu[s_menu_item];
// no break
#if defined(ROTARY_ENCODER_NAVIGATION)
CASE_EVT_ROTARY_LONG
killEvents(event);
#endif
case EVT_KEY_BREAK(KEY_EXIT):
s_menu_count = 0;
s_menu_item = 0;
s_menu_flags = 0;
s_menu_offset = 0;
break;
}
return result;
}
#endif

View file

@ -37,8 +37,6 @@
#include "../../opentx.h"
#define BIGSIZE DBLSIZE
#define BOX_WIDTH 23
#define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
#define LBOX_CENTERX (LCD_W/4 + 10)
#define RBOX_CENTERX (3*LCD_W/4 - 10)
#define MODELNAME_X (2*FW-2)
@ -60,8 +58,6 @@
#define TRIM_RH_X (LCD_W*3/4-2)
#define TRIM_LEN 27
#define MARKER_WIDTH 5
#define BOX_LIMIT (BOX_WIDTH-MARKER_WIDTH)
void drawPotsBars()
{
@ -75,13 +71,6 @@ void drawPotsBars()
}
}
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
{
lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
DO_CROSS(centrex, BOX_CENTERY, 3);
lcd_square(centrex + (xval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
}
void doMainScreenGraphics()
{
int16_t calibStickVert = calibratedStick[CONVERT_MODE(1)];

View file

@ -0,0 +1,224 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuStatisticsView(uint8_t event)
{
TITLE(STR_MENUSTAT);
switch(event)
{
case EVT_KEY_FIRST(KEY_UP):
chainMenu(menuStatisticsDebug);
break;
#if defined(CPUARM)
case EVT_KEY_LONG(KEY_MENU):
g_eeGeneral.globalTimer = 0;
eeDirty(EE_GENERAL);
sessionTimer = 0;
break;
#endif
case EVT_KEY_FIRST(KEY_EXIT):
chainMenu(menuMainView);
break;
}
lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP);
putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0);
putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0);
#if defined(CPUARM)
putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0);
#endif
#if defined(THRTRACE)
coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0);
const coord_t x = 5;
const coord_t y = 60;
lcd_hline(x-3, y, MAXTRACE+3+3);
lcd_vline(x, y-32, 32+3);
for (coord_t i=0; i<MAXTRACE; i+=6) {
lcd_vline(x+i+6, y-1, 3);
}
for (coord_t i=1; i<=MAXTRACE; i++) {
lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]);
traceRd++;
if (traceRd>=MAXTRACE) traceRd = 0;
if (traceRd==s_traceWr) break;
}
#endif
}
#if defined(PCBSKY9X)
#define MENU_DEBUG_COL1_OFS (11*FW-3)
#define MENU_DEBUG_COL2_OFS (17*FW)
#define MENU_DEBUG_Y_CURRENT (1*FH)
#define MENU_DEBUG_Y_MAH (2*FH)
#define MENU_DEBUG_Y_CPU_TEMP (3*FH)
#define MENU_DEBUG_Y_COPROC (4*FH)
#define MENU_DEBUG_Y_MIXMAX (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
#else
#define MENU_DEBUG_COL1_OFS (14*FW)
#endif
void menuStatisticsDebug(uint8_t event)
{
TITLE(STR_MENUDEBUG);
switch(event)
{
#if defined(CPUARM)
case EVT_KEY_LONG(KEY_ENTER):
g_eeGeneral.mAhUsed = 0;
g_eeGeneral.globalTimer = 0;
eeDirty(EE_GENERAL);
#if defined(PCBSKY9X)
Current_used = 0;
#endif
sessionTimer = 0;
killEvents(event);
AUDIO_KEYPAD_UP();
break;
#endif
case EVT_KEY_FIRST(KEY_ENTER):
#if !defined(CPUARM)
g_tmr1Latency_min = 0xff;
g_tmr1Latency_max = 0;
#endif
maxMixerDuration = 0;
AUDIO_KEYPAD_UP();
break;
#if defined(DEBUG_TRACE_BUFFER)
case EVT_KEY_FIRST(KEY_UP):
pushMenu(menuTraceBuffer);
return;
#endif
case EVT_KEY_FIRST(KEY_DOWN):
chainMenu(menuStatisticsView);
break;
case EVT_KEY_FIRST(KEY_EXIT):
chainMenu(menuMainView);
break;
}
#if defined(PCBSKY9X)
if ((ResetReason&RSTC_SR_RSTTYP) == (2<<8)) {
lcd_puts(LCD_W-8*FW, 0*FH, "WATCHDOG");
}
else if (unexpectedShutdown) {
lcd_puts(LCD_W-13*FW, 0*FH, "UNEXP.SHTDOWN");
}
#endif
#if defined(PCBSKY9X) && !defined(REVA)
// current
lcd_putsLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT);
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT);
uint32_t current_scale = 488 + g_eeGeneral.currentCalib;
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>');
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
// consumption
lcd_putsLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH);
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP);
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT);
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>');
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
#endif
#if defined(COPROCESSOR)
lcd_putsLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP);
if (Coproc_read==0) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Co Proc NACK"),INVERS);
}
else if (Coproc_read==0x81) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Inst.TinyApp"),INVERS);
}
else if (Coproc_read<3) {
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Upgr.TinyApp"),INVERS);
}
else {
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT);
putsValueWithUnit(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
}
#endif
#if defined(CPUARM)
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
#endif
#if defined(PCBSKY9X)
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
#endif
#if !defined(CPUARM)
lcd_putsLeft(1*FH, STR_TMR1LATMAXUS);
lcd_outdez8(MENU_DEBUG_COL1_OFS , 1*FH, g_tmr1Latency_max/2 );
lcd_putsLeft(2*FH, STR_TMR1LATMINUS);
lcd_outdez8(MENU_DEBUG_COL1_OFS , 2*FH, g_tmr1Latency_min/2 );
lcd_putsLeft(3*FH, STR_TMR1JITTERUS);
lcd_outdez8(MENU_DEBUG_COL1_OFS , 3*FH, (g_tmr1Latency_max - g_tmr1Latency_min) /2 );
lcd_putsLeft(4*FH, STR_TMIXMAXMS);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 4*FH, DURATION_MS_PREC2(maxMixerDuration), PREC2);
lcd_putsLeft(5*FH, STR_FREESTACKMINB);
lcd_outdezAtt(14*FW, 5*FH, stack_free(), UNSIGN) ;
#endif
lcd_puts(3*FW, 7*FH+1, STR_MENUTORESET);
lcd_status_line();
}

View file

@ -0,0 +1,562 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 STATUS_BAR_Y (7*FH+1)
#define TELEM_2ND_COLUMN (10*FW)
#if defined(FRSKY_HUB) && defined(GAUGES)
bar_threshold_t barsThresholds[THLD_MAX];
#endif
uint8_t s_frsky_view = 0;
#define BAR_LEFT 25
#define BAR_WIDTH 100
void displayRssiLine()
{
if (TELEMETRY_STREAMING()) {
lcd_hline(0, 55, 128, 0); // separator
uint8_t rssi;
#if !defined(CPUARM)
rssi = min((uint8_t)99, frskyData.rssi[1].value);
lcd_putsLeft(STATUS_BAR_Y, STR_TX); lcd_outdezNAtt(4*FW+1, STATUS_BAR_Y, rssi, LEADING0, 2);
lcd_rect(BAR_LEFT+1, 57, 38, 7);
drawFilledRect(BAR_LEFT+1, 58, 4*rssi/11, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID);
#endif
rssi = min((uint8_t)99, TELEMETRY_RSSI());
lcd_puts(104, STATUS_BAR_Y, STR_RX); lcd_outdezNAtt(105+4*FW, STATUS_BAR_Y, rssi, LEADING0, 2);
lcd_rect(65, 57, 38, 7);
uint8_t v = 4*rssi/11;
drawFilledRect(66+36-v, 58, v, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID);
}
else {
lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK);
lcd_status_line();
}
}
#if defined(FRSKY) && defined(FRSKY_HUB) && defined(GPS) && !defined(CPUARM)
void displayGpsTime()
{
uint8_t att = (TELEMETRY_STREAMING() ? LEFT|LEADING0 : LEFT|LEADING0|BLINK);
lcd_outdezNAtt(CENTER_OFS+6*FW+7, STATUS_BAR_Y, frskyData.hub.hour, att, 2);
lcd_putcAtt(CENTER_OFS+8*FW+4, STATUS_BAR_Y, ':', att);
lcd_outdezNAtt(CENTER_OFS+9*FW+2, STATUS_BAR_Y, frskyData.hub.min, att, 2);
lcd_putcAtt(CENTER_OFS+11*FW-1, STATUS_BAR_Y, ':', att);
lcd_outdezNAtt(CENTER_OFS+12*FW-3, STATUS_BAR_Y, frskyData.hub.sec, att, 2);
lcd_status_line();
}
void displayGpsCoord(uint8_t y, char direction, int16_t bp, int16_t ap)
{
if (frskyData.hub.gpsFix >= 0) {
if (!direction) direction = '-';
lcd_outdezAtt(TELEM_2ND_COLUMN, y, bp / 100, LEFT); // ddd before '.'
lcd_putc(lcdLastPos, y, '@');
uint8_t mn = bp % 100; // TODO div_t
if (g_eeGeneral.gpsFormat == 0) {
lcd_putc(lcdLastPos+FWNUM, y, direction);
lcd_outdezNAtt(lcdLastPos+FW+FW+1, y, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_vline(lcdLastPos, y, 2);
uint16_t ss = ap * 6;
lcd_outdezAtt(lcdLastPos+3, y, ss / 1000, LEFT); // ''
lcd_plot(lcdLastPos, y+FH-2, 0); // small decimal point
lcd_outdezAtt(lcdLastPos+2, y, ss % 1000, LEFT); // ''
lcd_vline(lcdLastPos, y, 2);
lcd_vline(lcdLastPos+2, y, 2);
}
else {
lcd_outdezNAtt(lcdLastPos+FW, y, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcdLastPos, y+FH-2, 0); // small decimal point
lcd_outdezNAtt(lcdLastPos+2, y, ap, LEFT|UNSIGN|LEADING0, 4); // after '.'
lcd_putc(lcdLastPos+1, y, direction);
}
}
else {
// no fix
lcd_puts(TELEM_2ND_COLUMN, y, STR_VCSWFUNC+1/*----*/);
}
}
#elif !defined(CPUARM)
#define displayGpsTime()
#define displayGpsCoord(...)
#endif
NOINLINE uint8_t getRssiAlarmValue(uint8_t alarm)
{
return (45 - 3*alarm + g_model.frsky.rssiAlarms[alarm].value);
}
#if !defined(CPUARM)
void displayVoltageScreenLine(uint8_t y, uint8_t index)
{
putsStrIdx(0, y, STR_A, index+1, 0);
if (TELEMETRY_STREAMING()) {
putsTelemetryChannelValue(3*FW+6*FW+4, y-FH, index+TELEM_A1-1, frskyData.analog[index].value, DBLSIZE);
lcd_putc(12*FW-1, y-FH, '<'); putsTelemetryChannelValue(17*FW, y-FH, index+TELEM_A1-1, frskyData.analog[index].min, NO_UNIT);
lcd_putc(12*FW, y, '>'); putsTelemetryChannelValue(17*FW, y, index+TELEM_A1-1, frskyData.analog[index].max, NO_UNIT);
}
}
#endif
uint8_t barCoord(int16_t value, int16_t min, int16_t max)
{
#if defined(CPUARM)
if (value <= min)
return 0;
else if (value >= max)
return BAR_WIDTH-1;
else
return ((int32_t)(BAR_WIDTH-1) * (value - min)) / (max - min);
#else
return limit((uint8_t)0, (uint8_t)(((int32_t)(BAR_WIDTH-1) * (value - min)) / (max - min)), (uint8_t)BAR_WIDTH);
#endif
}
#if !defined(CPUARM)
void displayVoltagesScreen()
{
// Volts / Amps / Watts / mAh
uint8_t analog = 0;
lcd_putsiAtt(0, 2*FH, STR_AMPSRC, g_model.frsky.voltsSource+1, 0);
switch (g_model.frsky.voltsSource) {
case FRSKY_VOLTS_SOURCE_A1:
case FRSKY_VOLTS_SOURCE_A2:
displayVoltageScreenLine(2*FH, g_model.frsky.voltsSource);
analog = 1+g_model.frsky.voltsSource;
break;
#if defined(FRSKY_HUB)
case FRSKY_VOLTS_SOURCE_FAS:
putsTelemetryChannelValue(3*FW+6*FW+4, FH, TELEM_VFAS-1, frskyData.hub.vfas, DBLSIZE);
break;
case FRSKY_VOLTS_SOURCE_CELLS:
putsTelemetryChannelValue(3*FW+6*FW+4, FH, TELEM_CELLS_SUM-1, frskyData.hub.cellsSum, DBLSIZE);
break;
#endif
}
if (g_model.frsky.currentSource) {
lcd_putsiAtt(0, 4*FH, STR_AMPSRC, g_model.frsky.currentSource, 0);
switch(g_model.frsky.currentSource) {
case FRSKY_CURRENT_SOURCE_A1:
case FRSKY_CURRENT_SOURCE_A2:
displayVoltageScreenLine(4*FH, g_model.frsky.currentSource-1);
break;
#if defined(FRSKY_HUB)
case FRSKY_CURRENT_SOURCE_FAS:
putsTelemetryChannelValue(3*FW+6*FW+4, 3*FH, TELEM_CURRENT-1, frskyData.hub.current, DBLSIZE);
break;
#endif
}
putsTelemetryChannelValue(4, 5*FH, TELEM_POWER-1, frskyData.hub.power, LEFT|DBLSIZE);
putsTelemetryChannelValue(3*FW+4+4*FW+6*FW+FW, 5*FH, TELEM_CONSUMPTION-1, frskyData.hub.currentConsumption, DBLSIZE);
}
else {
displayVoltageScreenLine(analog > 0 ? 5*FH : 4*FH, analog ? 2-analog : 0);
if (analog == 0) displayVoltageScreenLine(6*FH, 1);
}
#if defined(FRSKY_HUB)
// Cells voltage
if (frskyData.hub.cellsCount > 0) {
uint8_t y = 1*FH;
for (uint8_t k=0; k<frskyData.hub.cellsCount && k<6; k++) {
#if defined(GAUGES)
uint8_t attr = (barsThresholds[THLD_CELL] && frskyData.hub.cellVolts[k] < barsThresholds[THLD_CELL]) ? BLINK|PREC2 : PREC2;
#else
uint8_t attr = PREC2;
#endif
lcd_outdezNAtt(LCD_W, y, TELEMETRY_CELL_VOLTAGE(k), attr, 4);
y += 1*FH;
}
lcd_vline(LCD_W-3*FW-2, 8, 47);
}
#endif
displayRssiLine();
}
void displayAfterFlightScreen()
{
uint8_t line=1*FH+1;
if (IS_GPS_AVAILABLE()) {
// Latitude
lcd_putsLeft(line, STR_LATITUDE);
displayGpsCoord(line, frskyData.hub.gpsLatitudeNS, frskyData.hub.gpsLatitude_bp, frskyData.hub.gpsLatitude_ap);
// Longitude
line+=1*FH+1;
lcd_putsLeft(line, STR_LONGITUDE);
displayGpsCoord(line, frskyData.hub.gpsLongitudeEW, frskyData.hub.gpsLongitude_bp, frskyData.hub.gpsLongitude_ap);
displayGpsTime();
line+=1*FH+1;
}
// Rssi
lcd_putsLeft(line, STR_MINRSSI);
lcd_puts(TELEM_2ND_COLUMN, line, STR_TX);
lcd_outdezNAtt(TELEM_2ND_COLUMN+3*FW, line, frskyData.rssi[1].min, LEFT|LEADING0, 2);
lcd_puts(TELEM_2ND_COLUMN+6*FW, line, STR_RX);
lcd_outdezNAtt(TELEM_2ND_COLUMN+9*FW, line, frskyData.rssi[0].min, LEFT|LEADING0, 2);
}
#endif
bool displayGaugesTelemetryScreen(FrSkyScreenData & screen)
{
// Custom Screen with gauges
uint8_t barHeight = 5;
for (int8_t i=3; i>=0; i--) {
FrSkyBarData & bar = screen.bars[i];
source_t source = bar.source;
#if defined(CPUARM)
getvalue_t barMin = bar.barMin;
getvalue_t barMax = bar.barMax;
#else
getvalue_t barMin = convertBarTelemValue(source, bar.barMin);
getvalue_t barMax = convertBarTelemValue(source, 255-bar.barMax);
#endif
if (source && barMax > barMin) {
uint8_t y = barHeight+6+i*(barHeight+6);
#if defined(CPUARM)
putsMixerSource(0, y+barHeight-5, source, 0);
#else
lcd_putsiAtt(0, y+barHeight-5, STR_VTELEMCHNS, source, 0);
#endif
lcd_rect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
#if defined(CPUARM)
getvalue_t value = getValue(source);
#else
getvalue_t value = getValue(MIXSRC_FIRST_TELEM+source-1);
#endif
uint8_t thresholdX = 0;
#if !defined(CPUARM)
getvalue_t threshold = 0;
if (source <= TELEM_TIMER_MAX)
threshold = 0;
else if (source <= TELEM_RSSI_RX)
threshold = getRssiAlarmValue(source-TELEM_RSSI_TX);
else if (source <= TELEM_A2)
threshold = g_model.frsky.channels[source-TELEM_A1].alarms_value[0];
#if defined(FRSKY_HUB)
else {
#if defined(GAUGES)
threshold = convertBarTelemValue(source, barsThresholds[source-TELEM_ALT]);
#endif
}
#endif
if (threshold) {
thresholdX = barCoord(threshold, barMin, barMax);
if (thresholdX == 100)
thresholdX = 0;
}
#endif
uint8_t width = barCoord(value, barMin, barMax);
#if defined(CPUARM)
uint8_t barShade = SOLID;
#else
// reversed barshade for T1/T2
uint8_t barShade = ((threshold > value) ? DOTTED : SOLID);
if (source == TELEM_T1 || source == TELEM_T2) {
barShade = -barShade;
}
#endif
drawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade);
for (uint8_t j=24; j<99; j+=25) {
if (j>thresholdX || j>width) {
lcd_vline(j*BAR_WIDTH/100+BAR_LEFT+1, y+1, barHeight);
}
}
if (thresholdX) {
lcd_vlineStip(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED);
lcd_hline(BAR_LEFT+thresholdX, y-2, 3);
}
}
else {
barHeight += 2;
}
}
displayRssiLine();
return barHeight < 13;
}
#if defined(CPUARM)
bool displayNumbersTelemetryScreen(FrSkyScreenData & screen)
{
// Custom Screen with numbers
uint8_t fields_count = 0;
for (uint8_t i=0; i<4; i++) {
for (uint8_t j=0; j<NUM_LINE_ITEMS; j++) {
source_t field = screen.lines[i].sources[j];
if (field > 0) {
fields_count++;
}
if (i==3) {
lcd_vline(63, 8, 48);
if (!TELEMETRY_STREAMING()) {
displayRssiLine();
return fields_count;
}
}
if (field) {
LcdFlags att = (i==3 ? NO_UNIT : DBLSIZE|NO_UNIT);
coord_t pos[] = {0, 65, 130};
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER && i!=3) {
// there is not enough space on LCD for displaying "Tmr1" or "Tmr2" and still see the - sign, we write "T1" or "T2" instead
putsStrIdx(pos[j], 1+FH+2*FH*i, "T", field-MIXSRC_FIRST_TIMER+1, 0);
}
else if (field >= MIXSRC_FIRST_TELEM && isGPSSensor(1+(field-MIXSRC_FIRST_TELEM)/3) && telemetryItems[(field-MIXSRC_FIRST_TELEM)/3].isAvailable()) {
// we don't display GPS name, no space for it
}
else {
putsMixerSource(pos[j], 1+FH+2*FH*i, field, 0);
}
if (field >= MIXSRC_FIRST_TELEM) {
TelemetryItem & telemetryItem = telemetryItems[(field-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index
if (!telemetryItem.isAvailable()) {
continue;
}
else if (telemetryItem.isOld()) {
att |= INVERS|BLINK;
}
}
putsChannel(pos[j+1]-2, (i==3 ? 1+FH+2*FH*i:FH+2*FH*i), field, att);
}
}
}
lcd_status_line();
return fields_count;
}
#else
bool displayNumbersTelemetryScreen(FrSkyScreenData & screen)
{
// Custom Screen with numbers
uint8_t fields_count = 0;
for (uint8_t i=0; i<4; i++) {
for (uint8_t j=0; j<NUM_LINE_ITEMS; j++) {
uint8_t field = screen.lines[i].sources[j];
if (field > 0) {
fields_count++;
}
if (i==3) {
lcd_vline(63, 8, 48);
if (TELEMETRY_STREAMING()) {
#if defined(FRSKY_HUB)
if (field == TELEM_ACC) {
lcd_putsLeft(STATUS_BAR_Y, STR_ACCEL);
lcd_outdezNAtt(4*FW, STATUS_BAR_Y, frskyData.hub.accelX, LEFT|PREC2);
lcd_outdezNAtt(10*FW, STATUS_BAR_Y, frskyData.hub.accelY, LEFT|PREC2);
lcd_outdezNAtt(16*FW, STATUS_BAR_Y, frskyData.hub.accelZ, LEFT|PREC2);
break;
}
#endif
#if defined(FRSKY_HUB) && defined(GPS)
else if (field == TELEM_GPS_TIME) {
displayGpsTime();
break;
}
#endif
}
else {
displayRssiLine();
return fields_count;
}
}
if (field) {
getvalue_t value = getValue(MIXSRC_FIRST_TELEM+field-1);
uint8_t att = (i==3 ? NO_UNIT : DBLSIZE|NO_UNIT);
coord_t pos[] = {0, 65, 130};
putsTelemetryChannelValue(pos[j+1]-2, FH+2*FH*i, field-1, value, att);
if (field >= TELEM_TIMER1 && field <= TELEM_TIMER_MAX && i!=3) {
// there is not enough space on LCD for displaying "Tmr1" or "Tmr2" and still see the - sign, we write "T1" or "T2" instead
field = field-TELEM_TIMER1+TELEM_T1;
}
lcd_putsiAtt(pos[j], 1+FH+2*FH*i, STR_VTELEMCHNS, field, 0);
}
}
}
lcd_status_line();
return fields_count;
}
#endif
#if defined(CPUARM)
bool displayCustomTelemetryScreen(uint8_t index)
{
FrSkyScreenData & screen = g_model.frsky.screens[index];
#if defined(GAUGES)
if (IS_BARS_SCREEN(s_frsky_view)) {
return displayGaugesTelemetryScreen(screen);
}
#endif
displayNumbersTelemetryScreen(screen);
return true;
}
#else
bool displayCustomTelemetryScreen(uint8_t index)
{
FrSkyScreenData & screen = g_model.frsky.screens[index];
#if defined(GAUGES)
if (IS_BARS_SCREEN(s_frsky_view)) {
return displayGaugesTelemetryScreen(screen);
}
#endif
return displayNumbersTelemetryScreen(screen);
}
#endif
bool displayTelemetryScreen()
{
#if defined(CPUARM)
if (TELEMETRY_SCREEN_TYPE(s_frsky_view) == TELEMETRY_SCREEN_TYPE_NONE) {
return false;
}
#endif
lcdDrawTelemetryTopBar();
if (s_frsky_view < MAX_TELEMETRY_SCREENS) {
return displayCustomTelemetryScreen(s_frsky_view);
}
#if !defined(CPUARM)
if (s_frsky_view == TELEMETRY_VOLTAGES_SCREEN) {
displayVoltagesScreen();
}
#endif
#if !defined(CPUARM) && defined(FRSKY_HUB)
else {
displayAfterFlightScreen();
}
#endif
return true;
}
#if defined(CPUARM)
enum NavigationDirection {
none,
up,
down
};
#define decrTelemetryScreen() direction = up
#define incrTelemetryScreen() direction = down
#else
void decrTelemetryScreen()
{
if (s_frsky_view-- == 0)
s_frsky_view = TELEMETRY_VIEW_MAX;
}
void incrTelemetryScreen()
{
if (s_frsky_view++ == TELEMETRY_VIEW_MAX)
s_frsky_view = 0;
}
#endif
void menuTelemetryFrsky(uint8_t event)
{
#if defined(CPUARM)
enum NavigationDirection direction = none;
#endif
switch (event) {
case EVT_KEY_FIRST(KEY_EXIT):
killEvents(event);
chainMenu(menuMainView);
break;
case EVT_KEY_FIRST(KEY_UP):
decrTelemetryScreen();
break;
case EVT_KEY_FIRST(KEY_DOWN):
incrTelemetryScreen();
break;
case EVT_KEY_FIRST(KEY_ENTER):
telemetryReset();
break;
}
#if defined(CPUARM)
for (int i=0; i<=TELEMETRY_SCREEN_TYPE_MAX; i++) {
if (direction == up) {
if (s_frsky_view-- == 0)
s_frsky_view = TELEMETRY_VIEW_MAX;
}
else if (direction == down) {
if (s_frsky_view++ == TELEMETRY_VIEW_MAX)
s_frsky_view = 0;
}
else {
direction = down;
}
if (displayTelemetryScreen()) {
return;
}
}
lcdDrawTelemetryTopBar();
lcd_puts(8*FW, 3*FH, "No Telemetry Screens");
displayRssiLine();
#else
if (!displayTelemetryScreen()) {
putEvent(event == EVT_KEY_FIRST(KEY_UP) ? event : EVT_KEY_FIRST(KEY_DOWN));
}
#endif
}

164
radio/src/gui/9X/view_text.cpp Executable file
View file

@ -0,0 +1,164 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 TEXT_FILENAME_MAXLEN 40
#define TEXT_FILE_MAXSIZE 2048
char s_text_file[TEXT_FILENAME_MAXLEN];
char s_text_screen[LCD_LINES-1][LCD_COLS+1];
void readTextFile(int & lines_count)
{
FIL file;
int result;
char c;
unsigned int sz;
int line_length = 0;
int escape = 0;
char escape_chars[2];
int current_line = 0;
memset(s_text_screen, 0, sizeof(s_text_screen));
result = f_open(&file, s_text_file, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) {
for (int i=0; i<TEXT_FILE_MAXSIZE && f_read(&file, &c, 1, &sz)==FR_OK && sz==1 && (lines_count==0 || current_line-s_pgOfs<LCD_LINES-1); i++) {
if (c == '\n') {
++current_line;
line_length = 0;
escape = 0;
}
else if (c!='\r' && current_line>=s_pgOfs && current_line-s_pgOfs<LCD_LINES-1 && line_length<LCD_COLS) {
if (c=='\\' && escape==0) {
escape = 1;
continue;
}
else if (c!='\\' && escape>0 && escape<3) {
escape_chars[escape-1] = c;
if (escape == 2 && !strncmp(escape_chars, "up", 2)) {
c = '\300';
escape = 0;
}
else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) {
c = '\301';
escape = 0;
}
else {
escape++;
continue;
}
}
else if (c=='~') {
c = 'z'+1;
}
else if (c=='\t') {
c = 0x1D; //tab
}
escape = 0;
s_text_screen[current_line-s_pgOfs][line_length++] = c;
}
}
if (c != '\n') {
current_line += 1;
}
f_close(&file);
}
if (lines_count == 0) {
lines_count = current_line;
}
}
void menuTextView(uint8_t event)
{
static int lines_count;
switch (event) {
case EVT_ENTRY:
s_pgOfs = 0;
lines_count = 0;
readTextFile(lines_count);
break;
case EVT_KEY_FIRST(KEY_UP):
if (s_pgOfs == 0)
break;
else
s_pgOfs--;
// no break;
case EVT_KEY_FIRST(KEY_DOWN):
// if (event == EVT_KEY_BREAK(KEY_DOWN)) {
if (s_pgOfs+LCD_LINES-1 >= lines_count)
break;
else
++s_pgOfs;
// }
readTextFile(lines_count);
break;
case EVT_KEY_BREAK(KEY_EXIT):
popMenu();
break;
}
for (int i=0; i<LCD_LINES-1; i++) {
lcd_putsAtt(0, i*FH+FH+1, s_text_screen[i], FIXEDWIDTH);
}
char *title = s_text_file;
#if defined(SIMU)
if (!strncmp(title, "./", 2)) title += 2;
#else
// TODO?
#endif
lcd_puts(LCD_W/2-strlen(title)*FW/2, 0, title);
lcd_invert_line(0);
if (lines_count > LCD_LINES-1) {
displayScrollbar(LCD_W-1, FH, LCD_H-FH, s_pgOfs, lines_count, LCD_LINES-1);
}
}
void pushMenuTextView(const char *filename)
{
if (strlen(filename) < TEXT_FILENAME_MAXLEN) {
strcpy(s_text_file, filename);
pushMenu(menuTextView);
}
}

263
radio/src/gui/9X/widgets.cpp Executable file
View file

@ -0,0 +1,263 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
{
#define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
#define MARKER_WIDTH 5
lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
lcd_vline(centrex, BOX_CENTERY-1, 3);
lcd_hline(centrex-1, BOX_CENTERY, 3);
lcd_square(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
#undef BOX_CENTERY
#undef MARKER_WIDTH
}
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
{
#if defined(GRAPHICS)
if (value)
lcd_putc(x+1, y, '#');
if (attr)
drawFilledRect(x, y, 7, 7);
else
lcd_square(x, y, 7);
#else
/* ON / OFF version */
lcd_putsiAtt(x, y, STR_OFFON, value, attr ? INVERS:0) ;
#endif
}
void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
{
lcd_outdezAtt(LCD_W, 0, count, attr);
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
lcd_putcAtt(x, 0, '/', attr);
lcd_outdezAtt(x, 0, index+1, attr);
}
#if !defined(CPUM64)
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
{
lcd_vlineStip(x, y, h, DOTTED);
coord_t yofs = (h * offset) / count;
coord_t yhgt = (h * visible) / count;
if (yhgt + yofs > h)
yhgt = h - yofs;
lcd_vlineStip(x, y + yofs, yhgt, SOLID, FORCE);
}
#endif
void title(const pm_char * s)
{
lcd_putsAtt(0, 0, s, INVERS);
}
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)
{
lcd_putsColumnLeft(x, y, label);
if (values) lcd_putsiAtt(x, y, values, value-min, attr);
if (attr) value = checkIncDec(event, value, min, max, (g_menuPos[0] == 0) ? EE_MODEL : EE_GENERAL);
return value;
}
uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event )
{
#if defined(GRAPHICS)
menu_lcd_onoff(x, y, value, attr);
return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event);
#else
return selectMenuItem(x, y, label, STR_OFFON, value, 0, 1, attr, event);
#endif
}
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event)
{
lcd_putsColumnLeft(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
return value;
}
#if !defined(CPUM64)
void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
{
lcd_putc(x+(value*4*FW)/max, y, '$');
lcd_hline(x, y+3, 5*FW-1, FORCE);
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1);
}
#elif defined(GRAPHICS)
void display5posSlider(coord_t x, coord_t y, uint8_t value, uint8_t attr)
{
lcd_putc(x+2*FW+(value*FW), y, '$');
lcd_hline(x, y+3, 5*FW-1, SOLID);
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1);
}
#endif
#if defined(GVARS) && defined(CPUARM)
bool noZero(int val)
{
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)
{
uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode;
if (attr & PREC1)
value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta);
else
value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta);
eeDirty(EE_MODEL);
}
if (GV_IS_GV_VALUE(value, min, max)) {
if (attr & LEFT)
attr -= LEFT; /* because of ZCHAR */
else
x -= 2*FW+FWNUM;
attr &= ~PREC1;
int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta);
if (idx >= 0) ++idx; // transform form idx=0=GV1 to idx=1=GV1 in order to handle double keys invert
if (invers) {
CHECK_INCDEC_MODELVAR_CHECK(event, idx, -MAX_GVARS, MAX_GVARS, noZero);
if (idx == 0) idx = 1; // handle reset to zero, map to GV1
}
if (idx < 0) {
value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta);
idx = -idx;
lcd_putcAtt(x-6, y, '-', attr);
}
else {
value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta);
}
putsStrIdx(x, y, STR_GV, idx, attr);
}
else {
lcd_outdezAtt(x, y, value, attr);
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
}
return value;
}
#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)
{
uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode;
value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta);
eeDirty(EE_MODEL);
}
if (GV_IS_GV_VALUE(value, min, max)) {
if (attr & LEFT)
attr -= LEFT; /* because of ZCHAR */
else
x -= 2*FW+FWNUM;
int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta);
if (invers) {
idx = checkIncDec(event, idx, -MAX_GVARS, MAX_GVARS-1, EE_MODEL|NO_DBLKEYS); // disable double keys
}
if (idx < 0) {
value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta);
idx = -idx;
lcd_putcAtt(x-6, y, '-', attr);
}
else {
value = (int16_t) GV_CALC_VALUE_IDX_POS(idx, delta);
idx++;
}
putsStrIdx(x, y, STR_GV, idx, attr);
}
else {
lcd_outdezAtt(x, y, value, attr);
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL);
}
return value;
}
#else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
{
lcd_outdezAtt(x, y, value, attr);
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
return value;
}
#endif
#if defined(SDCARD)
char statusLineMsg[STATUS_LINE_LENGTH];
tmr10ms_t statusLineTime = 0;
uint8_t statusLineHeight = 0;
void showStatusLine()
{
statusLineTime = get_tmr10ms();
}
#define STATUS_LINE_DELAY (3 * 100) /* 3s */
void drawStatusLine()
{
if (statusLineTime) {
if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
if (statusLineHeight < FH) statusLineHeight++;
}
else if (statusLineHeight) {
statusLineHeight--;
}
else {
statusLineTime = 0;
}
drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
lcd_putsAtt(5, LCD_H+1-statusLineHeight, statusLineMsg, BSS);
drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
}
}
#endif

47
radio/src/gui/Taranis/gui.h Executable file
View file

@ -0,0 +1,47 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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.
*
*/
#define DEFAULT_SCROLLBAR_X (LCD_W-1)
#define NUM_BODY_LINES (LCD_LINES-1)
#define MENU_TITLE_HEIGHT FH
#define MENU_NAVIG_HEIGHT 0
void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
extern coord_t scrollbar_X;
#define SET_SCROLLBAR_X(x) scrollbar_X = (x);

348
radio/src/gui/Taranis/helpers.cpp Executable file
View file

@ -0,0 +1,348 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 switchToMix(uint8_t source)
{
if (source <= 5*3)
return MIXSRC_FIRST_SWITCH + (source-1) / 3;
else if (source <= 17)
return MIXSRC_SF;
else if (source <= 20)
return MIXSRC_SG;
else
return MIXSRC_SH;
}
bool isInputAvailable(int input)
{
for (int i=0; i<MAX_EXPOS; i++) {
ExpoData * expo = expoAddress(i);
if (!EXPO_VALID(expo))
break;
if (expo->chn == input)
return true;
}
return false;
}
bool isSourceAvailable(int source)
{
if (source>=MIXSRC_FIRST_INPUT && source<=MIXSRC_LAST_INPUT) {
return isInputAvailable(source - MIXSRC_FIRST_INPUT);
}
#if defined(LUA_MODEL_SCRIPTS)
if (source>=MIXSRC_FIRST_LUA && source<=MIXSRC_LAST_LUA) {
div_t qr = div(source-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
return (qr.rem<scriptInputsOutputs[qr.quot].outputsCount);
}
#else
if (source>=MIXSRC_FIRST_LUA && source<=MIXSRC_LAST_LUA)
return false;
#endif
if (source>=MIXSRC_FIRST_POT && source<=MIXSRC_LAST_POT) {
return IS_POT_AVAILABLE(POT1+source-MIXSRC_FIRST_POT);
}
#if !defined(HELI)
if (source>=MIXSRC_CYC1 && source<=MIXSRC_CYC3)
return false;
#endif
if (source>=MIXSRC_CH1 && source<=MIXSRC_LAST_CH) {
uint8_t destCh = source-MIXSRC_CH1;
for (uint8_t i = 0; i < MAX_MIXERS; i++) {
MixData *md = mixAddress(i);
if (md->srcRaw == 0) return false;
if (md->destCh==destCh) return true;
}
return false;
}
if (source>=MIXSRC_SI && source<=MIXSRC_SN) {
if (!IS_2x2POS(source-MIXSRC_SI)) {
return false;
}
}
if (source>=MIXSRC_SW1 && source<=MIXSRC_LAST_LOGICAL_SWITCH) {
LogicalSwitchData * cs = lswAddress(source-MIXSRC_SW1);
return (cs->func != LS_FUNC_NONE);
}
#if !defined(GVARS)
if (source>=MIXSRC_GVAR1 && source<=MIXSRC_LAST_GVAR)
return false;
#endif
if (source>=MIXSRC_RESERVE1 && source<=MIXSRC_RESERVE5)
return false;
if (source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) {
div_t qr = div(source-MIXSRC_FIRST_TELEM, 3);
if (qr.rem == 0)
return isTelemetryFieldAvailable(qr.quot);
else
return isTelemetryFieldComparisonAvailable(qr.quot);
}
return true;
}
bool isSourceAvailableInCustomSwitches(int source)
{
bool result = isSourceAvailable(source);
#if defined(FRSKY)
if (result && source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) {
div_t qr = div(source-MIXSRC_FIRST_TELEM, 3);
result = isTelemetryFieldComparisonAvailable(qr.quot);
}
#endif
return result;
}
bool isInputSourceAvailable(int source)
{
#if !defined(REVPLUS)
if (source == MIXSRC_POT3)
return false;
#endif
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
return true;
if (source>=MIXSRC_Rud && source<=MIXSRC_MAX)
return true;
if (source>=MIXSRC_TrimRud && source<MIXSRC_SW1)
return true;
if (source>=MIXSRC_FIRST_CH && source<=MIXSRC_LAST_CH)
return true;
if (source>=MIXSRC_FIRST_TRAINER && source<=MIXSRC_LAST_TRAINER)
return true;
if (source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM)
return isTelemetryFieldAvailable(source-MIXSRC_FIRST_TELEM);
return false;
}
enum SwitchContext
{
LogicalSwitchesContext,
ModelCustomFunctionsContext,
GeneralCustomFunctionsContext,
TimersContext,
MixesContext
};
bool isSwitchAvailable(int swtch, SwitchContext context)
{
uint32_t index = switchInfo(abs(swtch)).quot;
if (swtch < 0) {
if (!IS_3POS(index))
return false;
if (swtch == -SWSRC_ON || swtch == -SWSRC_One) {
return false;
}
swtch = -swtch;
}
#if defined(REV9E)
if (swtch >= SWSRC_SA1 && swtch <= SWSRC_SR1 && (swtch-SWSRC_SA1)%3 == 0) {
return IS_3POS(index);
}
#else
if (swtch == SWSRC_SA1 || swtch == SWSRC_SB1 || swtch == SWSRC_SC1 || swtch == SWSRC_SD1 || swtch == SWSRC_SE1 || swtch == SWSRC_SG1) {
return IS_3POS(index);
}
if (swtch >= SWSRC_SI0 && swtch <= SWSRC_SM2) {
return IS_2x2POS((swtch-SWSRC_SI0)/2);
}
if (swtch >= SWSRC_SN0 && swtch <= SWSRC_SN2) {
return IS_2x2POS(6);
}
#endif
if (swtch >= SWSRC_FIRST_MULTIPOS_SWITCH && swtch <= SWSRC_LAST_MULTIPOS_SWITCH) {
int index = (swtch - SWSRC_FIRST_MULTIPOS_SWITCH) / XPOTS_MULTIPOS_COUNT;
if (IS_POT_MULTIPOS(POT1+index)) {
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[POT1+index];
return (calib->count >= ((swtch - SWSRC_FIRST_MULTIPOS_SWITCH) % XPOTS_MULTIPOS_COUNT));
}
else {
return false;
}
}
if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
if (context == GeneralCustomFunctionsContext) {
return false;
}
else if (context != LogicalSwitchesContext) {
LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
return (cs->func != LS_FUNC_NONE);
}
}
if (context != ModelCustomFunctionsContext && context != GeneralCustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
return false;
}
if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) {
if (context == MixesContext || context == GeneralCustomFunctionsContext) {
return false;
}
else {
swtch -= SWSRC_FIRST_FLIGHT_MODE;
if (swtch == 0) {
return true;
}
FlightModeData * fm = flightModeAddress(swtch);
return (fm->swtch != SWSRC_NONE);
}
}
return true;
}
bool isSwitchAvailableInLogicalSwitches(int swtch)
{
return isSwitchAvailable(swtch, LogicalSwitchesContext);
}
bool isSwitchAvailableInCustomFunctions(int swtch)
{
if (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions)
return isSwitchAvailable(swtch, ModelCustomFunctionsContext);
else
return isSwitchAvailable(swtch, GeneralCustomFunctionsContext);
}
bool isSwitchAvailableInMixes(int swtch)
{
return isSwitchAvailable(swtch, MixesContext);
}
bool isSwitchAvailableInTimers(int swtch)
{
if (swtch >= 0) {
if (swtch < TMRMODE_COUNT)
return true;
else
swtch -= TMRMODE_COUNT-1;
}
else {
if (swtch > -TMRMODE_COUNT)
return false;
else
swtch += TMRMODE_COUNT-1;
}
return isSwitchAvailable(swtch, TimersContext);
}
bool isThrottleSourceAvailable(int source)
{
if (source == THROTTLE_SOURCE_S3 && !IS_POT_AVAILABLE(POT3))
return false;
else
return true;
}
bool isLogicalSwitchFunctionAvailable(int function)
{
return function != LS_FUNC_RANGE;
}
bool isAssignableFunctionAvailable(int function)
{
bool modelFunctions = (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions);
switch (function) {
case FUNC_OVERRIDE_CHANNEL:
#if defined(OVERRIDE_CHANNEL_FUNCTION)
return modelFunctions;
#else
return false;
#endif
case FUNC_ADJUST_GVAR:
#if defined(GVARS)
return modelFunctions;
#else
return false;
#endif
#if !defined(HAPTIC)
case FUNC_HAPTIC:
#endif
case FUNC_PLAY_DIFF:
#if !defined(DANGEROUS_MODULE_FUNCTIONS)
case FUNC_RANGECHECK:
case FUNC_BIND:
case FUNC_MODULE_OFF:
#endif
#if !defined(LUA)
case FUNC_PLAY_SCRIPT:
#endif
case FUNC_RESERVE5:
return false;
default:
return true;
}
}
bool isModuleAvailable(int module)
{
return true;
}
bool modelHasNotes()
{
char filename[sizeof(MODELS_PATH)+1+sizeof(g_model.header.name)+sizeof(TEXT_EXT)] = MODELS_PATH "/";
char *buf = strcat_modelname(&filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(buf, TEXT_EXT);
return isFileAvailable(filename);
}

View file

@ -0,0 +1,212 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 XPOT_DELTA 10
#define XPOT_DELAY 10 /* cycles */
void menuCommonCalib(uint8_t event)
{
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { // get low and high vals for sticks and trims
int16_t vt = anaIn(i);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
if (i >= POT1 && i <= POT_LAST) {
if (IS_POT_WITHOUT_DETENT(i)) {
reusableBuffer.calib.midVals[i] = (reusableBuffer.calib.hiVals[i] + reusableBuffer.calib.loVals[i]) / 2;
}
uint8_t idx = i - POT1;
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
if (IS_POT_MULTIPOS(i) && count <= XPOTS_MULTIPOS_COUNT) {
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 || vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA || vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
reusableBuffer.calib.xpotsCalib[idx].lastPosition = vt;
reusableBuffer.calib.xpotsCalib[idx].lastCount = 1;
}
else {
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255) reusableBuffer.calib.xpotsCalib[idx].lastCount++;
}
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == XPOT_DELAY) {
int16_t position = reusableBuffer.calib.xpotsCalib[idx].lastPosition;
bool found = false;
for (int j=0; j<count; j++) {
int16_t step = reusableBuffer.calib.xpotsCalib[idx].steps[j];
if (position >= step-XPOT_DELTA && position <= step+XPOT_DELTA) {
found = true;
break;
}
}
if (!found) {
if (count < XPOTS_MULTIPOS_COUNT) {
reusableBuffer.calib.xpotsCalib[idx].steps[count] = position;
}
reusableBuffer.calib.xpotsCalib[idx].stepsCount += 1;
}
}
}
}
}
calibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
switch (event)
{
case EVT_ENTRY:
reusableBuffer.calib.state = 0;
break;
case EVT_KEY_BREAK(KEY_ENTER):
reusableBuffer.calib.state++;
break;
}
switch (reusableBuffer.calib.state) {
case 0:
// START CALIBRATION
if (!READ_ONLY()) {
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUTOSTART);
}
break;
case 1:
// SET MIDPOINT
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = anaIn(i);
if (i<NUM_XPOTS) {
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
}
}
break;
case 2:
// MOVE STICKS/POTS
STICK_SCROLL_DISABLE();
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcd_putsLeft(MENU_TITLE_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
g_eeGeneral.calib[i].spanNeg = v - v/STICK_TOLERANCE;
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
g_eeGeneral.calib[i].spanPos = v - v/STICK_TOLERANCE;
}
}
break;
case 3:
for (uint8_t i=POT1; i<=POT_LAST; i++) {
int idx = i - POT1;
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
if (IS_POT_MULTIPOS(i)) {
if (count > 1 && count <= XPOTS_MULTIPOS_COUNT) {
for (int j=0; j<count; j++) {
for (int k=j+1; k<count; k++) {
if (reusableBuffer.calib.xpotsCalib[idx].steps[k] < reusableBuffer.calib.xpotsCalib[idx].steps[j]) {
swap(reusableBuffer.calib.xpotsCalib[idx].steps[j], reusableBuffer.calib.xpotsCalib[idx].steps[k]);
}
}
}
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
calib->count = count - 1;
for (int j=0; j<calib->count; j++) {
calib->steps[j] = (reusableBuffer.calib.xpotsCalib[idx].steps[j+1] + reusableBuffer.calib.xpotsCalib[idx].steps[j]) >> 5;
}
}
else {
g_eeGeneral.potsType &= ~(0x03<<(2*idx));
}
}
}
g_eeGeneral.chkSum = evalChkSum();
eeDirty(EE_GENERAL);
reusableBuffer.calib.state = 4;
break;
default:
reusableBuffer.calib.state = 0;
break;
}
doMainScreenGraphics();
drawPotsBars();
for (int i=POT1; i<=POT_LAST; i++) {
uint8_t steps = 0;
if (reusableBuffer.calib.state == 2) {
steps = reusableBuffer.calib.xpotsCalib[i-POT1].stepsCount;
}
else if (IS_POT_MULTIPOS(i)) {
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[i];
steps = calib->count + 1;
}
if (steps > 0 && steps <= XPOTS_MULTIPOS_COUNT) {
lcd_outdezAtt(LCD_W/2-2+(i-POT1)*5, LCD_H-6, steps, TINSIZE);
}
}
}
void menuGeneralCalib(uint8_t event)
{
check_simple(event, e_Calib, menuTabGeneral, DIM(menuTabGeneral), 0);
if (menuEvent) {
calibrationState = 0;
}
TITLE(STR_MENUCALIBRATION);
menuCommonCalib(READ_ONLY() ? 0 : event);
}
void menuFirstCalib(uint8_t event)
{
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == 4) {
calibrationState = 0;
chainMenu(menuMainView);
}
else {
lcd_putsCenter(0*FH, MENUCALIBRATION);
lcd_invert_line(0);
menuCommonCalib(event);
}
}

View file

@ -0,0 +1,71 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuGeneralDiagAna(uint8_t event)
{
SIMPLE_MENU(STR_MENUANA, menuTabGeneral, e_Ana, 2);
STICK_SCROLL_DISABLE();
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
#if (NUM_STICKS+NUM_POTS) > 9
coord_t y = MENU_TITLE_HEIGHT + 1 + (i/3)*FH;
const uint8_t x_coord[] = {0, 70, 154};
uint8_t x = x_coord[i%3];
lcd_outdezNAtt(x, y, i+1, LEADING0|LEFT, 2);
lcd_putc(x+2*FW-2, y, ':');
#else
coord_t y = MENU_TITLE_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? 64+5 : 0;
putsStrIdx(x, y, PSTR("A"), i+1);
lcd_putc(lcdNextPos, y, ':');
#endif
lcd_outhex4(x+3*FW-1, y, anaIn(i));
lcd_outdez8(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
}
lcd_putsLeft(MENU_TITLE_HEIGHT+1+5*FH, STR_BATT_CALIB);
static int32_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8;
uint32_t batCalV = (adcBatt + (adcBatt*g_eeGeneral.vBatCalib)/128) * BATT_SCALE;
batCalV >>= 11;
batCalV += 2; // because of the diode
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_TITLE_HEIGHT+1+5*FH, batCalV, (m_posVert==1 ? INVERS : 0));
if (m_posVert==1) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatCalib, -127, 127);
}

View file

@ -0,0 +1,66 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void displayKeyState(uint8_t x, uint8_t y, EnumKeys key)
{
uint8_t t = switchState(key);
lcd_putcAtt(x, y, t+'0', t ? INVERS : 0);
}
void menuGeneralDiagKeys(uint8_t event)
{
SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, e_Keys, 1);
lcd_puts(14*FW, MENU_TITLE_HEIGHT+2*FH, STR_VTRIM);
for(uint8_t i=0; i<9; i++) {
coord_t y;
if (i<8) {
y = MENU_TITLE_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i));
}
if (i<6) {
y = i*FH+MENU_TITLE_HEIGHT+FH;
lcd_putsiAtt(0, y, STR_VKEYS, (5-i), 0);
displayKeyState(5*FW+2, y, (EnumKeys)(KEY_MENU+(5-i)));
}
}
}

View file

@ -0,0 +1,220 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
enum menuGeneralHwItems {
ITEM_SETUP_HW_LABEL_STICKS,
ITEM_SETUP_HW_STICK1,
ITEM_SETUP_HW_STICK2,
ITEM_SETUP_HW_STICK3,
ITEM_SETUP_HW_STICK4,
ITEM_SETUP_HW_LABEL_POTS,
ITEM_SETUP_HW_POT1,
ITEM_SETUP_HW_POT2,
CASE_REVPLUS(ITEM_SETUP_HW_POT3)
CASE_REV9E(ITEM_SETUP_HW_POT4)
ITEM_SETUP_HW_LS,
ITEM_SETUP_HW_RS,
CASE_REV9E(ITEM_SETUP_HW_LS2)
CASE_REV9E(ITEM_SETUP_HW_RS2)
ITEM_SETUP_HW_LABEL_SWITCHES,
ITEM_SETUP_HW_SA,
ITEM_SETUP_HW_SB,
ITEM_SETUP_HW_SC,
ITEM_SETUP_HW_SD,
ITEM_SETUP_HW_SE,
ITEM_SETUP_HW_SF,
ITEM_SETUP_HW_SG,
ITEM_SETUP_HW_SH,
ITEM_SETUP_HW_SI,
ITEM_SETUP_HW_SJ,
ITEM_SETUP_HW_SK,
ITEM_SETUP_HW_SL,
ITEM_SETUP_HW_SM,
ITEM_SETUP_HW_SN,
CASE_REV9E(ITEM_SETUP_HW_SO)
CASE_REV9E(ITEM_SETUP_HW_SP)
CASE_REV9E(ITEM_SETUP_HW_SQ)
CASE_REV9E(ITEM_SETUP_HW_SR)
ITEM_SETUP_HW_UART3_MODE,
ITEM_SETUP_HW_MAX
};
#define HW_SETTINGS_COLUMN 15*FW
#if defined(REVPLUS)
#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, 0, 0
#else
#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, 0, 0
#endif
#if defined(REV9E)
#define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1
#else
#define SWITCH_ROWS(x) uint8_t(IS_2x2POS(x) ? 0 : HIDDEN_ROW)
#define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, SWITCH_ROWS(0), SWITCH_ROWS(1), SWITCH_ROWS(2), SWITCH_ROWS(3), SWITCH_ROWS(4), SWITCH_ROWS(6)
#endif
void menuGeneralHardware(uint8_t event)
{
MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, 0});
uint8_t sub = m_posVert - 1;
for (uint8_t i=0; i<LCD_LINES-1; ++i) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i + s_pgOfs;
for (int j=0; j<=k; j++) {
if (mstate_tab[j+1] == HIDDEN_ROW)
k++;
}
uint8_t attr = (sub == k ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
switch (k) {
case ITEM_SETUP_HW_LABEL_STICKS:
lcd_putsLeft(y, "Sticks");
break;
case ITEM_SETUP_HW_STICK1:
case ITEM_SETUP_HW_STICK2:
case ITEM_SETUP_HW_STICK3:
case ITEM_SETUP_HW_STICK4:
case ITEM_SETUP_HW_LS:
case ITEM_SETUP_HW_RS:
#if defined(REV9E)
case ITEM_SETUP_HW_LS2:
case ITEM_SETUP_HW_RS2:
#endif
{
int idx = (k<=ITEM_SETUP_HW_STICK4 ? k-ITEM_SETUP_HW_STICK1 : k-ITEM_SETUP_HW_LS+7);
lcd_putsiAtt(INDENT_WIDTH, y, STR_VSRCRAW, idx+1, 0);
if (ZEXIST(g_eeGeneral.anaNames[idx]) || attr)
editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, event, attr);
else
lcd_putsiAtt(HW_SETTINGS_COLUMN, y, STR_MMMINV, 0, 0);
break;
}
case ITEM_SETUP_HW_LABEL_POTS:
lcd_putsLeft(y, "Pots");
break;
case ITEM_SETUP_HW_POT1:
case ITEM_SETUP_HW_POT2:
#if defined(REVPLUS)
case ITEM_SETUP_HW_POT3:
#endif
#if defined(REV9E)
case ITEM_SETUP_HW_POT4:
#endif
{
int idx = k - ITEM_SETUP_HW_POT1;
uint8_t shift = (2*idx);
uint8_t mask = (0x03 << shift);
lcd_putsiAtt(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+idx+1, m_posHorz < 0 ? attr : 0);
if (ZEXIST(g_eeGeneral.anaNames[NUM_STICKS+idx]) || (attr && m_posHorz == 0))
editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.anaNames[NUM_STICKS+idx], LEN_ANA_NAME, event, attr && m_posHorz == 0);
else
lcd_putsiAtt(HW_SETTINGS_COLUMN, y, STR_MMMINV, 0, 0);
uint8_t potType = (g_eeGeneral.potsType & mask) >> shift;
if (potType == POT_TYPE_NONE && k <= ITEM_SETUP_HW_POT2)
potType = POT_TYPE_DETENT;
potType = selectMenuItem(HW_SETTINGS_COLUMN+5*FW, y, "", STR_POTTYPES, potType, 0, POT_TYPE_MAX, m_posHorz == 1 ? attr : 0, event);
if (potType == POT_TYPE_DETENT && k <= ITEM_SETUP_HW_POT2)
potType = POT_TYPE_NONE;
g_eeGeneral.potsType &= ~mask;
g_eeGeneral.potsType |= (potType << shift);
break;
}
case ITEM_SETUP_HW_LABEL_SWITCHES:
lcd_putsLeft(y, "Switches");
break;
case ITEM_SETUP_HW_SA:
case ITEM_SETUP_HW_SB:
case ITEM_SETUP_HW_SC:
case ITEM_SETUP_HW_SD:
case ITEM_SETUP_HW_SE:
case ITEM_SETUP_HW_SF:
case ITEM_SETUP_HW_SG:
case ITEM_SETUP_HW_SH:
case ITEM_SETUP_HW_SI:
case ITEM_SETUP_HW_SJ:
case ITEM_SETUP_HW_SK:
case ITEM_SETUP_HW_SL:
case ITEM_SETUP_HW_SM:
case ITEM_SETUP_HW_SN:
#if defined(REV9E)
case ITEM_SETUP_HW_SO:
case ITEM_SETUP_HW_SP:
case ITEM_SETUP_HW_SQ:
case ITEM_SETUP_HW_SR:
#endif
{
int index = k-ITEM_SETUP_HW_SA;
char label[] = INDENT "S*";
label[2] = 'A' + index;
int config = SWITCH_CONFIG(index);
lcd_putsAtt(0, y, label, m_posHorz < 0 ? attr : 0);
if (ZEXIST(g_eeGeneral.switchNames[index]) || (attr && m_posHorz == 0))
editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.switchNames[index], LEN_SWITCH_NAME, event, m_posHorz == 0 ? attr : 0);
else
lcd_putsiAtt(HW_SETTINGS_COLUMN, y, STR_MMMINV, 0, 0);
#if defined(REV9E)
config = selectMenuItem(HW_SETTINGS_COLUMN+5*FW, y, "", "\007None\0 DefaultToggle\0""2POS\0 3POS\0", config, SWITCH_NONE, SWITCH_3POS, m_posHorz == 1 ? attr : 0, event);
if (attr && checkIncDec_Ret) {
uint32_t mask = 0x0f << (4*index);
TRACE("avant %x", g_eeGeneral.switchConfig);
g_eeGeneral.switchConfig = (g_eeGeneral.switchConfig & ~mask) | ((uint32_t(config)&0xf) << (4*index));
TRACE("apres %x", g_eeGeneral.switchConfig);
}
#else
if (k <= ITEM_SETUP_HW_SH) {
config = selectMenuItem(HW_SETTINGS_COLUMN+5*FW, y, "", "\007DefaultToggle\0""2POS\0 3POS\0 2x2POS\0", config, SWITCH_NONE, SWITCH_2x2POS, m_posHorz == 1 ? attr : 0, event);
if (attr && checkIncDec_Ret) {
uint32_t mask = 0x0f << (4*index);
g_eeGeneral.switchConfig = (g_eeGeneral.switchConfig & ~mask) | (((uint32_t)(config)&0xf) << (4*index));
}
}
#endif
break;
}
case ITEM_SETUP_HW_UART3_MODE:
g_eeGeneral.uart3Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.uart3Mode, 0, UART_MODE_MAX, attr, event);
if (attr && checkIncDec_Ret) {
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL());
}
break;
}
}
}

View file

@ -0,0 +1,388 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuGeneralSdManagerInfo(uint8_t event)
{
SIMPLE_SUBMENU(STR_SD_INFO_TITLE, 1);
lcd_putsLeft(2*FH, STR_SD_TYPE);
lcd_puts(10*FW, 2*FH, SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD);
lcd_putsLeft(3*FH, STR_SD_SIZE);
lcd_outdezAtt(10*FW, 3*FH, SD_GET_SIZE_MB(), LEFT);
lcd_putc(lcdLastPos, 3*FH, 'M');
lcd_putsLeft(4*FH, STR_SD_SECTORS);
lcd_outdezAtt(10*FW, 4*FH, SD_GET_BLOCKNR()/1000, LEFT);
lcd_putc(lcdLastPos, 4*FH, 'k');
lcd_putsLeft(5*FH, STR_SD_SPEED);
lcd_outdezAtt(10*FW, 5*FH, SD_GET_SPEED()/1000, LEFT);
lcd_puts(lcdLastPos, 5*FH, "kb/s");
}
inline bool isFilenameGreater(bool isfile, const char * fn, const char * line)
{
return (isfile && !line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) > 0);
}
inline bool isFilenameLower(bool isfile, const char * fn, const char * line)
{
return (!isfile && line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) < 0);
}
void flashBootloader(const char * filename)
{
FIL file;
f_open(&file, filename, FA_READ);
uint8_t buffer[1024];
UINT count;
lcd_clear();
lcd_putsLeft(4*FH, STR_WRITING);
lcd_rect(3, 6*FH+4, 204, 7);
lcdRefresh();
static uint8_t unlocked = 0;
if (!unlocked) {
unlocked = 1;
unlockFlash();
}
for (int i=0; i<BOOTLOADER_SIZE; i+=1024) {
watchdogSetTimeout(100/*1s*/);
if (f_read(&file, buffer, 1024, &count) != FR_OK || count != 1024) {
POPUP_WARNING(STR_SDCARD_ERROR);
break;
}
if (i==0 && !isBootloaderStart((uint32_t *)buffer)) {
POPUP_WARNING(STR_INCOMPATIBLE);
break;
}
for (int j=0; j<1024; j+=FLASH_PAGESIZE) {
writeFlash(CONVERT_UINT_PTR(FIRMWARE_ADDRESS+i+j), (uint32_t *)(buffer+j));
lcd_hline(5, 6*FH+6, (200*i)/BOOTLOADER_SIZE, FORCE);
lcd_hline(5, 6*FH+7, (200*i)/BOOTLOADER_SIZE, FORCE);
lcd_hline(5, 6*FH+8, (200*i)/BOOTLOADER_SIZE, FORCE);
lcdRefresh();
SIMU_SLEEP(30/*ms*/);
}
}
if (unlocked) {
lockFlash();
unlocked = 0;
}
f_close(&file);
}
void onSdManagerMenu(const char *result)
{
TCHAR lfn[_MAX_LFN+1];
uint8_t index = m_posVert-1-s_pgOfs;
if (result == STR_SD_INFO) {
pushMenu(menuGeneralSdManagerInfo);
}
else if (result == STR_SD_FORMAT) {
POPUP_CONFIRMATION(STR_CONFIRM_FORMAT);
}
else if (result == STR_DELETE_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat_P(lfn, PSTR("/"));
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
f_unlink(lfn);
strncpy(statusLineMsg, reusableBuffer.sdmanager.lines[index], 13);
strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED);
showStatusLine();
if ((uint16_t)m_posVert == reusableBuffer.sdmanager.count) m_posVert--;
reusableBuffer.sdmanager.offset = s_pgOfs-1;
}
/* TODO else if (result == STR_LOAD_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
POPUP_WARNING(eeLoadModelSD(lfn));
} */
else if (result == STR_PLAY_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
audioQueue.stopAll();
audioQueue.playFile(lfn, 0, ID_PLAY_FROM_SD_MANAGER);
}
else if (result == STR_ASSIGN_BITMAP) {
strAppendFilename(g_model.header.bitmap, reusableBuffer.sdmanager.lines[index], sizeof(g_model.header.bitmap));
LOAD_MODEL_BITMAP();
memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap));
eeDirty(EE_MODEL);
}
else if (result == STR_VIEW_TEXT) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
pushMenuTextView(lfn);
}
else if (result == STR_FLASH_BOOTLOADER) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
flashBootloader(lfn);
}
#if defined(LUA)
else if (result == STR_EXECUTE_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
luaExec(lfn);
}
#endif
}
void menuGeneralSdManager(uint8_t _event)
{
FILINFO fno;
DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
if (s_warning_result) {
s_warning_result = 0;
displayPopup(STR_FORMATTING);
closeLogs();
audioQueue.stopSD();
if (f_mkfs(0, 1, 0) == FR_OK) {
f_chdir("/");
reusableBuffer.sdmanager.offset = -1;
}
else {
POPUP_WARNING(STR_SDCARD_ERROR);
}
}
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, 1+reusableBuffer.sdmanager.count);
if (s_editMode > 0)
s_editMode = 0;
switch(_event) {
case EVT_ENTRY:
f_chdir(ROOT_PATH);
reusableBuffer.sdmanager.offset = 65535;
break;
case EVT_KEY_LONG(KEY_MENU):
if (!READ_ONLY()) {
killEvents(_event);
// MENU_ADD_ITEM(STR_SD_INFO); TODO: Implement
MENU_ADD_ITEM(STR_SD_FORMAT);
menuHandler = onSdManagerMenu;
}
break;
case EVT_KEY_BREAK(KEY_ENTER):
{
if (m_posVert > 0) {
vertpos_t index = m_posVert-1-s_pgOfs;
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
f_chdir(reusableBuffer.sdmanager.lines[index]);
s_pgOfs = 0;
m_posVert = 1;
reusableBuffer.sdmanager.offset = 65535;
killEvents(_event);
break;
}
}
if (!IS_ROTARY_BREAK(_event) || m_posVert==0)
break;
// no break;
}
case EVT_KEY_LONG(KEY_ENTER):
killEvents(_event);
{
uint8_t index = m_posVert-1-s_pgOfs;
// TODO duplicated code for finding extension
char * ext = reusableBuffer.sdmanager.lines[index];
int len = strlen(ext) - 4;
ext += len;
/* TODO if (!strcasecmp(ext, MODELS_EXT)) {
s_menu[s_menu_count++] = STR_LOAD_FILE;
}
else */ if (!strcasecmp(ext, SOUNDS_EXT)) {
MENU_ADD_ITEM(STR_PLAY_FILE);
}
else if (!strcasecmp(ext, BITMAPS_EXT) && !READ_ONLY() && len <= (int)sizeof(g_model.header.bitmap)) {
MENU_ADD_ITEM(STR_ASSIGN_BITMAP);
}
else if (!strcasecmp(ext, TEXT_EXT)) {
MENU_ADD_ITEM(STR_VIEW_TEXT);
}
else if (!strcasecmp(ext, FIRMWARE_EXT) && !READ_ONLY()) {
MENU_ADD_ITEM(STR_FLASH_BOOTLOADER);
}
#if defined(LUA)
else if (!strcasecmp(ext, SCRIPTS_EXT)) {
MENU_ADD_ITEM(STR_EXECUTE_FILE);
}
#endif
if (!READ_ONLY()) {
MENU_ADD_ITEM(STR_DELETE_FILE);
// MENU_ADD_ITEM(STR_RENAME_FILE); TODO: Implement
// MENU_ADD_ITEM(STR_COPY_FILE); TODO: Implement
}
}
menuHandler = onSdManagerMenu;
break;
}
if (reusableBuffer.sdmanager.offset != s_pgOfs) {
if (s_pgOfs == 0) {
reusableBuffer.sdmanager.offset = 0;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
}
else if (s_pgOfs == reusableBuffer.sdmanager.count-7) {
reusableBuffer.sdmanager.offset = s_pgOfs;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
}
else if (s_pgOfs > reusableBuffer.sdmanager.offset) {
memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
memset(reusableBuffer.sdmanager.lines[6], 0xff, SD_SCREEN_FILE_LENGTH);
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = 1;
}
else {
memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], 6*sizeof(reusableBuffer.sdmanager.lines[0]));
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
}
reusableBuffer.sdmanager.count = 0;
FRESULT res = f_opendir(&dir, "."); /* Open the directory */
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
reusableBuffer.sdmanager.count++;
bool isfile = !(fno.fattrib & AM_DIR);
if (s_pgOfs == 0) {
for (uint8_t i=0; i<LCD_LINES-1; i++) {
char *line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) {
if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn);
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break;
}
}
}
else if (reusableBuffer.sdmanager.offset == s_pgOfs) {
for (int8_t i=6; i>=0; i--) {
char *line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) {
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn);
line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break;
}
}
}
else if (s_pgOfs > reusableBuffer.sdmanager.offset) {
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) {
memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[6], fn);
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile;
}
}
else {
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) {
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[0], fn);
reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile;
}
}
}
}
}
reusableBuffer.sdmanager.offset = s_pgOfs;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
lcdNextPos = 0;
uint8_t attr = (m_posVert-1-s_pgOfs == i ? BSS|INVERS : BSS);
if (reusableBuffer.sdmanager.lines[i][0]) {
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', attr); }
lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', attr); }
}
}
static vertpos_t sdBitmapIdx = 0xFFFF;
static uint8_t sdBitmap[MODEL_BITMAP_SIZE];
vertpos_t index = m_posVert-1-s_pgOfs;
if (m_posVert > 0) {
char * ext = reusableBuffer.sdmanager.lines[index];
ext += strlen(ext) - 4;
if (!strcasecmp(ext, BITMAPS_EXT)) {
if (sdBitmapIdx != m_posVert) {
sdBitmapIdx = m_posVert;
uint8_t *dest = sdBitmap;
if (bmpLoad(dest, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) {
memcpy(sdBitmap, logo_taranis, MODEL_BITMAP_SIZE);
}
}
lcd_bmp(22*FW+2, 2*FH+FH/2, sdBitmap);
}
}
}

View file

@ -0,0 +1,518 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
const pm_uchar sticks[] PROGMEM = {
#include "../../bitmaps/sticks.lbm"
};
#define RADIO_SETUP_2ND_COLUMN (LCD_W-10*FW-MENUS_SCROLLBAR_WIDTH)
#define RADIO_SETUP_DATE_COLUMN RADIO_SETUP_2ND_COLUMN + 4*FWNUM
#define RADIO_SETUP_TIME_COLUMN RADIO_SETUP_2ND_COLUMN + 2*FWNUM
#define SLIDER_5POS(y, value, label, event, attr) { \
int8_t tmp = value; \
displaySlider(RADIO_SETUP_2ND_COLUMN, y, 2+tmp, 4, attr); \
value = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, label, NULL, tmp, -2, +2, attr, event); \
}
#if defined(SPLASH) && !defined(FSPLASH)
#define CASE_SPLASH_PARAM(x) x,
#else
#define CASE_SPLASH_PARAM(x)
#endif
enum menuGeneralSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME)
ITEM_SETUP_BATT_RANGE,
ITEM_SETUP_SOUND_LABEL,
ITEM_SETUP_BEEP_MODE,
ITEM_SETUP_SPEAKER_VOLUME,
ITEM_SETUP_BEEP_VOLUME,
ITEM_SETUP_BEEP_LENGTH,
ITEM_SETUP_SPEAKER_PITCH,
ITEM_SETUP_WAV_VOLUME,
ITEM_SETUP_BACKGROUND_VOLUME,
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_LABEL)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_VOLUME)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_PITCH)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_RANGE)
CASE_VARIO_CPUARM(ITEM_SETUP_VARIO_REPEAT)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_LABEL)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_MODE)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_LENGTH)
CASE_HAPTIC(ITEM_SETUP_HAPTIC_STRENGTH)
ITEM_SETUP_CONTRAST,
ITEM_SETUP_ALARMS_LABEL,
ITEM_SETUP_BATTERY_WARNING,
ITEM_SETUP_INACTIVITY_ALARM,
ITEM_SETUP_MEMORY_WARNING,
ITEM_SETUP_ALARM_WARNING,
ITEM_SETUP_BACKLIGHT_LABEL,
ITEM_SETUP_BACKLIGHT_MODE,
ITEM_SETUP_BACKLIGHT_DELAY,
ITEM_SETUP_BRIGHTNESS,
CASE_REVPLUS(ITEM_SETUP_BACKLIGHT_COLOR)
ITEM_SETUP_FLASH_BEEP,
CASE_SPLASH_PARAM(ITEM_SETUP_DISABLE_SPLASH)
CASE_GPS(ITEM_SETUP_TIMEZONE)
CASE_GPS(ITEM_SETUP_GPSFORMAT)
CASE_PXX(ITEM_SETUP_COUNTRYCODE)
ITEM_SETUP_LANGUAGE,
ITEM_SETUP_IMPERIAL,
IF_FAI_CHOICE(ITEM_SETUP_FAI)
CASE_MAVLINK(ITEM_MAVLINK_BAUD)
ITEM_SETUP_SWITCHES_DELAY,
ITEM_SETUP_RX_CHANNEL_ORD,
ITEM_SETUP_STICK_MODE_LABELS,
ITEM_SETUP_STICK_MODE,
ITEM_SETUP_MAX
};
void menuGeneralSetup(uint8_t event)
{
#if defined(RTCLOCK)
struct gtm t;
gettime(&t);
if ((m_posVert==ITEM_SETUP_DATE+1 || m_posVert==ITEM_SETUP_TIME+1) &&
(s_editMode>0) &&
(event==EVT_KEY_FIRST(KEY_ENTER) || event==EVT_KEY_FIRST(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event))) {
// set the date and time into RTC chip
rtcSetTime(&t);
}
#endif
#if defined(FAI_CHOICE)
if (s_warning_result) {
s_warning_result = 0;
g_eeGeneral.fai = true;
eeDirty(EE_GENERAL);
}
#endif
MENU(STR_MENURADIOSETUP, menuTabGeneral, e_Setup, ITEM_SETUP_MAX+1, { 0, 2, 2, 1, LABEL(SOUND), 0, 0, 0, 0, 0, 0, 0, CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, 0, CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) 0, 0, IF_FAI_CHOICE(0) CASE_MAVLINK(0) 0, 0, LABEL(TX_MODE), 0, 1/*to force edit mode*/ });
uint8_t sub = m_posVert - 1;
for (unsigned int i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
uint8_t attr = (sub == k ? blink : 0);
switch(k) {
case ITEM_SETUP_DATE:
lcd_putsLeft(y, STR_DATE);
lcd_putc(RADIO_SETUP_DATE_COLUMN, y, '-'); lcd_putc(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-');
for (uint8_t j=0; j<3; j++) {
uint8_t rowattr = (m_posHorz==j ? attr : 0);
switch (j) {
case 0:
lcd_outdezAtt(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0);
break;
case 1:
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0);
break;
case 2:
{
int16_t year = 1900 + t.tm_year;
int8_t dlim = (((((year%4==0) && (year%100!=0)) || (year%400==0)) && (t.tm_mon==1)) ? 1 : 0);
static const pm_uint8_t dmon[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
dlim += pgm_read_byte(&dmon[t.tm_mon]);
lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0);
break;
}
}
}
if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break;
case ITEM_SETUP_TIME:
lcd_putsLeft(y, STR_TIME);
lcd_putc(RADIO_SETUP_TIME_COLUMN+1, y, ':'); lcd_putc(RADIO_SETUP_TIME_COLUMN+3*FW-2, y, ':');
for (uint8_t j=0; j<3; j++) {
uint8_t rowattr = (m_posHorz==j ? attr : 0);
switch (j) {
case 0:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0);
break;
case 1:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0);
break;
case 2:
lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0);
break;
}
}
if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
if (attr && checkIncDec_Ret)
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
break;
case ITEM_SETUP_BATT_RANGE:
lcd_putsLeft(y, STR_BATTERY_RANGE);
putsVolts(RADIO_SETUP_2ND_COLUMN, y, 90+g_eeGeneral.vBatMin, (m_posHorz==0 ? attr : 0)|LEFT|NO_UNIT);
lcd_putc(lcdLastPos, y, '-');
putsVolts(lcdLastPos+FW, y, 120+g_eeGeneral.vBatMax, (m_posHorz>0 ? attr : 0)|LEFT|NO_UNIT);
if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
if (attr && s_editMode>0) {
if (m_posHorz==0)
CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMin, -50, g_eeGeneral.vBatMax+29); // min=4.0V
else
CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMax, g_eeGeneral.vBatMin-29, +40); // max=16.0V
}
break;
case ITEM_SETUP_SOUND_LABEL:
lcd_putsLeft(y, STR_SOUND_LABEL);
break;
case ITEM_SETUP_BEEP_MODE:
g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event);
#if defined(FRSKY)
if (attr && checkIncDec_Ret) frskySendAlarms();
#endif
break;
case ITEM_SETUP_SPEAKER_VOLUME:
{
lcd_putsLeft(y, STR_SPEAKER_VOLUME);
uint8_t b = g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF;
displaySlider(RADIO_SETUP_2ND_COLUMN, y, b, VOLUME_LEVEL_MAX, attr);
if (attr) {
CHECK_INCDEC_GENVAR(event, b, 0, VOLUME_LEVEL_MAX);
if (checkIncDec_Ret) {
g_eeGeneral.speakerVolume = (int8_t)b-VOLUME_LEVEL_DEF;
}
}
break;
}
case ITEM_SETUP_BEEP_VOLUME:
SLIDER_5POS(y, g_eeGeneral.beepVolume, STR_BEEP_VOLUME, event, attr);
break;
case ITEM_SETUP_WAV_VOLUME:
SLIDER_5POS(y, g_eeGeneral.wavVolume, STR_WAV_VOLUME, event, attr);
break;
case ITEM_SETUP_BACKGROUND_VOLUME:
SLIDER_5POS(y, g_eeGeneral.backgroundVolume, STR_BG_VOLUME, event, attr);
break;
case ITEM_SETUP_BEEP_LENGTH:
SLIDER_5POS(y, g_eeGeneral.beepLength, STR_BEEP_LENGTH, event, attr);
break;
case ITEM_SETUP_SPEAKER_PITCH:
lcd_putsLeft( y, STR_SPKRPITCH);
lcd_putcAtt(RADIO_SETUP_2ND_COLUMN, y, '+', attr);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN+FW, y, g_eeGeneral.speakerPitch*15, attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
if (attr) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.speakerPitch, 0, 20);
}
break;
#if defined(VARIO)
case ITEM_SETUP_VARIO_LABEL:
lcd_putsLeft(y, STR_VARIO);
break;
case ITEM_SETUP_VARIO_VOLUME:
SLIDER_5POS(y, g_eeGeneral.varioVolume, TR_SPEAKER_VOLUME, event, attr);
break;
case ITEM_SETUP_VARIO_PITCH:
lcd_putsLeft(y, STR_PITCH_AT_ZERO);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioPitch, -40, 40);
break;
case ITEM_SETUP_VARIO_RANGE:
lcd_putsLeft(y, STR_PITCH_AT_MAX);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10)+VARIO_FREQUENCY_RANGE+(g_eeGeneral.varioRange*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, "Hz", attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRange, -80, 80);
break;
case ITEM_SETUP_VARIO_REPEAT:
lcd_putsLeft(y, STR_REPEAT_AT_ZERO);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_REPEAT_ZERO+(g_eeGeneral.varioRepeat*10), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, STR_MS, attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRepeat, -30, 50);
break;
#endif
#if defined(HAPTIC)
case ITEM_SETUP_HAPTIC_LABEL:
lcd_putsLeft(y, STR_HAPTIC_LABEL);
break;
case ITEM_SETUP_HAPTIC_MODE:
g_eeGeneral.hapticMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBEEPMODE, g_eeGeneral.hapticMode, -2, 1, attr, event);
break;
case ITEM_SETUP_HAPTIC_LENGTH:
SLIDER_5POS(y, g_eeGeneral.hapticLength, STR_LENGTH, event, attr);
break;
case ITEM_SETUP_HAPTIC_STRENGTH:
SLIDER_5POS(y, g_eeGeneral.hapticStrength, STR_HAPTICSTRENGTH, event, attr);
break;
#endif
case ITEM_SETUP_CONTRAST:
lcd_putsLeft(y, STR_CONTRAST);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.contrast, attr|LEFT);
if (attr) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.contrast, CONTRAST_MIN, CONTRAST_MAX);
lcdSetContrast();
}
break;
case ITEM_SETUP_ALARMS_LABEL:
lcd_putsLeft(y, STR_ALARMS_LABEL);
break;
case ITEM_SETUP_BATTERY_WARNING:
lcd_putsLeft(y, STR_BATTERYWARNING);
putsVolts(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.vBatWarn, attr|LEFT);
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V
break;
case ITEM_SETUP_MEMORY_WARNING:
{
uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event);
break;
}
case ITEM_SETUP_ALARM_WARNING:
{
uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event);
break;
}
#if defined(PCBSKY9X)
case ITEM_SETUP_CAPACITY_WARNING:
lcd_putsLeft(y, STR_CAPAWARNING);
putsValueWithUnit(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.mAhWarn*50, UNIT_MAH, attr|LEFT) ;
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.mAhWarn, 0, 100);
break;
#endif
#if defined(PCBSKY9X)
case ITEM_SETUP_TEMPERATURE_WARNING:
lcd_putsLeft(y, STR_TEMPWARNING);
putsValueWithUnit(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.temperatureWarn, UNIT_TEMPERATURE, attr|LEFT) ;
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.temperatureWarn, 0, 120); // 0 means no alarm
break;
#endif
case ITEM_SETUP_INACTIVITY_ALARM:
lcd_putsLeft( y,STR_INACTIVITYALARM);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.inactivityTimer, attr|LEFT);
lcd_putc(lcdLastPos, y, 'm');
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
break;
case ITEM_SETUP_BACKLIGHT_LABEL:
lcd_putsLeft(y, STR_BACKLIGHT_LABEL);
break;
case ITEM_SETUP_BACKLIGHT_MODE:
g_eeGeneral.backlightMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBLMODE, g_eeGeneral.backlightMode, e_backlight_mode_off, e_backlight_mode_on, attr, event);
break;
case ITEM_SETUP_FLASH_BEEP:
g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ;
break;
case ITEM_SETUP_BACKLIGHT_DELAY:
lcd_putsLeft(y, STR_BLDELAY);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT);
lcd_putc(lcdLastPos, y, 's');
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5);
break;
case ITEM_SETUP_BRIGHTNESS:
lcd_putsLeft(y, STR_BRIGHTNESS);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 100-g_eeGeneral.backlightBright, attr|LEFT) ;
if (attr) {
uint8_t b = 100 - g_eeGeneral.backlightBright;
CHECK_INCDEC_GENVAR(event, b, 0, 100);
g_eeGeneral.backlightBright = 100 - b;
}
break;
#if defined(REVPLUS)
case ITEM_SETUP_BACKLIGHT_COLOR:
lcd_putsLeft(y, STR_BLCOLOR);
displaySlider(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.backlightColor, 20, attr);
if (attr) g_eeGeneral.backlightColor = checkIncDec(event, g_eeGeneral.backlightColor, 0, 20, EE_GENERAL | NO_INCDEC_MARKS);
break;
#endif
#if defined(SPLASH) && !defined(FSPLASH)
case ITEM_SETUP_DISABLE_SPLASH:
{
lcd_putsLeft(y, STR_SPLASHSCREEN);
if (SPLASH_NEEDED()) {
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, SPLASH_TIMEOUT/100, attr|LEFT);
lcd_putc(lcdLastPos, y, 's');
}
else {
lcd_putsiAtt(RADIO_SETUP_2ND_COLUMN, y, STR_MMMINV, 0, attr); // TODO define
}
if (attr) g_eeGeneral.splashMode = -checkIncDecGen(event, -g_eeGeneral.splashMode, -3, 4);
break;
}
#endif
#if defined(FRSKY) && defined(FRSKY_HUB) && defined(GPS)
case ITEM_SETUP_TIMEZONE:
lcd_putsLeft(y, STR_TIMEZONE);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12);
break;
case ITEM_SETUP_GPSFORMAT:
g_eeGeneral.gpsFormat = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_GPSCOORD, STR_GPSFORMAT, g_eeGeneral.gpsFormat, 0, 1, attr, event);
break;
#endif
#if defined(PXX)
case ITEM_SETUP_COUNTRYCODE:
g_eeGeneral.countryCode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_COUNTRYCODE, STR_COUNTRYCODES, g_eeGeneral.countryCode, 0, 2, attr, event);
break;
#endif
case ITEM_SETUP_LANGUAGE:
lcd_putsLeft(y, STR_VOICELANG);
lcd_putsAtt(RADIO_SETUP_2ND_COLUMN, y, currentLanguagePack->name, attr);
if (attr) {
currentLanguagePackIdx = checkIncDec(event, currentLanguagePackIdx, 0, DIM(languagePacks)-2, EE_GENERAL);
if (checkIncDec_Ret) {
currentLanguagePack = languagePacks[currentLanguagePackIdx];
strncpy(g_eeGeneral.ttsLanguage, currentLanguagePack->id, 2);
}
}
break;
case ITEM_SETUP_IMPERIAL:
g_eeGeneral.imperial = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_UNITSSYSTEM, STR_VUNITSSYSTEM, g_eeGeneral.imperial, 0, 1, attr, event);
break;
#if defined(FAI_CHOICE)
case ITEM_SETUP_FAI:
onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event);
if (attr && checkIncDec_Ret) {
if (g_eeGeneral.fai)
POPUP_WARNING(PSTR("FAI\001mode blocked!"));
else
POPUP_CONFIRMATION(PSTR("FAI mode?"));
}
break;
#endif
#if defined(MAVLINK)
case ITEM_MAVLINK_BAUD:
g_eeGeneral.mavbaud = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MAVLINK_BAUD_LABEL, STR_MAVLINK_BAUDS, g_eeGeneral.mavbaud, 0, 7, attr, event);
break;
#endif
case ITEM_SETUP_SWITCHES_DELAY:
lcd_putsLeft(y, STR_SWITCHES_DELAY);
lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 10*SWITCHES_DELAY(), attr|LEFT);
lcd_putsAtt(lcdLastPos, y, STR_MS, attr);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.switchesDelay, -15, +15);
break;
case ITEM_SETUP_RX_CHANNEL_ORD:
lcd_putsLeft(y, STR_RXCHANNELORD); // RAET->AETR
for (uint8_t i=1; i<=4; i++) {
putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, channel_order(i), attr);
}
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23);
break;
case ITEM_SETUP_STICK_MODE_LABELS:
lcd_putsLeft(y, NO_INDENT(STR_MODE));
for (uint8_t i=0; i<4; i++) {
lcd_img((6+4*i)*FW, y, sticks, i, 0);
#if defined(FRSKY_STICKS)
if (g_eeGeneral.stickReverse & (1<<i)) {
drawFilledRect((6+4*i)*FW, y, 3*FW, FH-1);
}
#endif
}
#if defined(FRSKY_STICKS)
if (attr) {
s_editMode = 0;
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickReverse, 0, 15);
lcd_rect(6*FW-1, y-1, 15*FW+2, 9);
}
#endif
break;
case ITEM_SETUP_STICK_MODE:
lcd_putcAtt(2*FW, y, '1'+g_eeGeneral.stickMode, attr);
for (uint8_t i=0; i<4; i++) {
putsMixerSource((6+4*i)*FW, y, MIXSRC_Rud + pgm_read_byte(modn12x3 + 4*g_eeGeneral.stickMode + i), 0);
}
if (attr && s_editMode>0) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickMode, 0, 3);
}
else if (stickMode != g_eeGeneral.stickMode) {
pausePulses();
stickMode = g_eeGeneral.stickMode;
checkTHR();
resumePulses();
clearKeyEvents();
}
break;
}
}
}

View file

@ -0,0 +1,114 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 TRAINER_CALIB_POS 12
void menuGeneralTrainer(uint8_t event)
{
uint8_t y;
bool slave = SLAVE_MODE();
MENU(STR_MENUTRAINER, menuTabGeneral, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
if (slave) {
lcd_puts(7*FW, 4*FH, STR_SLAVE);
}
else {
uint8_t attr;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
lcd_puts(3*FW, MENU_TITLE_HEIGHT+1, STR_MODESRC);
y = MENU_TITLE_HEIGHT + 1 + FH;
for (uint8_t i=1; i<=NUM_STICKS; i++) {
uint8_t chan = channel_order(i);
volatile TrainerMix *td = &g_eeGeneral.trainer.mix[chan-1];
putsMixerSource(0, y, MIXSRC_Rud-1+chan, (m_posVert==i && CURSOR_ON_LINE()) ? INVERS : 0);
for (uint8_t j=0; j<3; j++) {
attr = ((m_posVert==i && m_posHorz==j) ? blink : 0);
switch(j) {
case 0:
lcd_putsiAtt(4*FW, y, STR_TRNMODE, td->mode, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->mode, 0, 2);
break;
case 1:
lcd_outdezAtt(11*FW, y, td->studWeight, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->studWeight, -125, 125);
break;
case 2:
lcd_putsiAtt(12*FW, y, STR_TRNCHN, td->srcChn, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->srcChn, 0, 3);
break;
}
}
y += FH;
}
attr = (m_posVert==5) ? blink : 0;
lcd_putsLeft(MENU_TITLE_HEIGHT+1+5*FH, STR_MULTIPLIER);
lcd_outdezAtt(LEN_MULTIPLIER*FW+3*FW, MENU_TITLE_HEIGHT+1+5*FH, g_eeGeneral.PPM_Multiplier+10, attr|PREC1);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.PPM_Multiplier, -10, 40);
attr = (m_posVert==6) ? INVERS : 0;
if (attr) s_editMode = 0;
lcd_putsAtt(0*FW, MENU_TITLE_HEIGHT+1+6*FH, STR_CAL, attr);
for (uint8_t i=0; i<4; i++) {
uint8_t x = (i*TRAINER_CALIB_POS+16)*FW/2;
#if defined (PPM_UNIT_PERCENT_PREC1)
lcd_outdezAtt(x, MENU_TITLE_HEIGHT+1+6*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])*2, PREC1);
#else
lcd_outdezAtt(x, MENU_TITLE_HEIGHT+1+6*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])/5, 0);
#endif
}
if (attr) {
if (event==EVT_KEY_LONG(KEY_ENTER)){
memcpy(g_eeGeneral.trainer.calib, g_ppmIns, sizeof(g_eeGeneral.trainer.calib));
eeDirty(EE_GENERAL);
AUDIO_WARNING1();
}
}
}
}

View file

@ -0,0 +1,104 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void backupEeprom()
{
char filename[60];
uint8_t buffer[1024];
FIL file;
lcd_clear();
lcd_putsLeft(4*FH, STR_WRITING);
lcd_rect(3, 6*FH+4, 204, 7);
lcdRefresh();
//reset unexpectedShutdown to prevent warning when user restores EEPROM backup
g_eeGeneral.unexpectedShutdown = 0;
eeDirty(EE_GENERAL);
eeCheck(true);
// create the directory if needed...
DIR folder;
FRESULT result = f_opendir(&folder, EEPROMS_PATH);
if (result != FR_OK) {
if (result == FR_NO_PATH)
result = f_mkdir(EEPROMS_PATH);
if (result != FR_OK) {
POPUP_WARNING(SDCARD_ERROR(result));
return;
}
}
// prepare the filename...
char * tmp = strAppend(filename, EEPROMS_PATH "/eeprom");
tmp = strAppendDate(tmp, true);
strAppend(tmp, EEPROM_EXT);
// open the file for writing...
f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS);
for (int i=0; i<EESIZE; i+=1024) {
UINT count;
eeprom_read_block(buffer, i, 1024);
f_write(&file, buffer, 1024, &count);
lcd_hline(5, 6*FH+6, (200*i)/EESIZE, FORCE);
lcd_hline(5, 6*FH+7, (200*i)/EESIZE, FORCE);
lcd_hline(5, 6*FH+8, (200*i)/EESIZE, FORCE);
lcdRefresh();
SIMU_SLEEP(100/*ms*/);
}
f_close(&file);
//set back unexpectedShutdown
g_eeGeneral.unexpectedShutdown = 1;
eeDirty(EE_GENERAL);
eeCheck(true);
}
void menuGeneralVersion(uint8_t event)
{
SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1);
lcd_putsLeft(MENU_TITLE_HEIGHT+FH, vers_stamp);
lcd_putsLeft(MENU_TITLE_HEIGHT+6*FH, STR_EEBACKUP);
if (event == EVT_KEY_LONG(KEY_ENTER)) {
backupEeprom();
}
}

View file

@ -253,7 +253,7 @@ void menuModelSelect(uint8_t event)
TITLE(STR_MENUMODELSEL);
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*HEIGHT_BODY_LINE;
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
lcd_outdezNAtt(3*FW+2, y, k+1, LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2);

View file

@ -157,7 +157,7 @@ void menuModelSetup(uint8_t event)
int8_t editMode = s_editMode;
for (uint8_t i=0; i<NUM_BODY_LINES; ++i) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*HEIGHT_BODY_LINE;
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
uint8_t k = i+s_pgOfs;
for (int j=0; j<=k; j++) {
if (mstate_tab[j+1] == HIDDEN_ROW)

View file

@ -0,0 +1,493 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
vertpos_t s_pgOfs;
vertpos_t m_posVert;
horzpos_t m_posHorz;
int8_t s_editMode;
uint8_t s_noHi;
uint8_t calibrationState;
#if defined(AUTOSWITCH)
int8_t checkIncDecMovedSwitch(int8_t val)
{
if (s_editMode>0) {
int8_t swtch = getMovedSwitch();
if (swtch) {
div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) {
if (info.rem != 0) {
val = (val == swtch ? swtch+2 : swtch);
}
}
else {
val = swtch;
}
}
}
return val;
}
#endif
int8_t checkIncDec_Ret;
INIT_STOPS(stops100, 3, -100, 0, 100)
INIT_STOPS(stops1000, 3, -1000, 0, 1000)
INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST)
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops)
{
int newval = val;
#if defined(DBLKEYS)
unsigned int in = KEYS_PRESSED();
if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) {
bool dblkey = true;
if (DBLKEYS_PRESSED_RGT_LFT(in)) {
if (!isValueAvailable || isValueAvailable(-val))
newval = -val;
}
else if (DBLKEYS_PRESSED_RGT_UP(in)) {
newval = (i_max > stops.max() ? stops.max() : i_max);
while (isValueAvailable && !isValueAvailable(newval) && newval>i_min) {
--newval;
}
}
else if (DBLKEYS_PRESSED_LFT_DWN(in)) {
newval = (i_min < stops.min() ? stops.min() : i_min);
while (isValueAvailable && !isValueAvailable(newval) && newval<i_max) {
++newval;
}
}
else if (DBLKEYS_PRESSED_UP_DWN(in)) {
newval = 0;
}
else {
dblkey = false;
}
if (dblkey) {
killEvents(KEY_UP);
killEvents(KEY_DOWN);
killEvents(KEY_RIGHT);
killEvents(KEY_LEFT);
killEvents(KEY_PAGE);
killEvents(KEY_MENU);
killEvents(KEY_ENTER);
killEvents(KEY_EXIT);
event = 0;
}
}
#endif
if (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))) {
do {
if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) {
newval += min(10, i_max-val);
}
else {
newval++;
}
} while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max);
if (newval > i_max) {
newval = val;
killEvents(event);
AUDIO_WARNING2();
}
else {
AUDIO_KEYPAD_UP();
}
}
else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) {
do {
if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) {
newval -= min(10, val-i_min);
}
else {
newval--;
}
} while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min);
if (newval < i_min) {
newval = val;
killEvents(event);
AUDIO_WARNING2();
}
else {
AUDIO_KEYPAD_DOWN();
}
}
if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) {
s_editMode = 0;
newval = !val;
}
#if defined(AUTOSWITCH)
if (i_flags & INCDEC_SWITCH) {
newval = checkIncDecMovedSwitch(newval);
}
#endif
#if defined(AUTOSOURCE)
if (i_flags & INCDEC_SOURCE) {
if (s_editMode>0) {
int source = GET_MOVED_SOURCE(i_min, i_max);
if (source) {
newval = source;
}
#if defined(AUTOSWITCH)
else {
unsigned int swtch = abs(getMovedSwitch());
if (swtch) {
newval = switchToMix(swtch);
}
}
#endif
}
}
#endif
if (newval > i_max || newval < i_min) {
newval = (newval > i_max ? i_max : i_min);
killEvents(event);
AUDIO_WARNING2();
}
if (newval != val) {
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && stops.contains(newval) && !IS_ROTARY_EVENT(event)) {
bool pause = (newval > val ? !stops.contains(newval+1) : !stops.contains(newval-1));
if (pause) {
pauseEvents(event); // delay before auto-repeat continues
if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same
AUDIO_KEYPAD_UP();
else
AUDIO_KEYPAD_DOWN();
}
}
eeDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
#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(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 INC(val, min, max) if (val<max) {val++;} else {val=min;}
#define DEC(val, min, max) if (val>min) {val--;} else {val=max;}
coord_t scrollbar_X = DEFAULT_SCROLLBAR_X;
void onLongMenuPress(const char *result)
{
if (result == STR_VIEW_CHANNELS) {
pushMenu(menuChannelsView);
}
else if (result == STR_VIEW_NOTES) {
pushModelNotes();
}
}
tmr10ms_t menuEntryTime;
void check(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags)
{
vertpos_t l_posVert = m_posVert;
horzpos_t l_posHorz = m_posHorz;
uint8_t maxcol = MAXCOL(l_posVert);
if (p2valdiff || 0 || p1valdiff) backlightOn(); // on keypress turn the light on
if (menuTab) {
int8_t cc = curr;
switch (event) {
case EVT_KEY_LONG(KEY_MENU):
if (menuTab == menuTabModel) {
killEvents(event);
if (modelHasNotes()) {
MENU_ADD_SD_ITEM(STR_VIEW_CHANNELS);
MENU_ADD_ITEM(STR_VIEW_NOTES);
menuHandler = onLongMenuPress;
}
else {
pushMenu(menuChannelsView);
}
}
break;
case EVT_KEY_LONG(KEY_PAGE):
if (curr > 0)
cc = curr - 1;
else
cc = menuTabSize-1;
killEvents(event);
break;
case EVT_KEY_BREAK(KEY_PAGE):
if (curr < (menuTabSize-1))
cc = curr + 1;
else
cc = 0;
break;
}
if (!calibrationState && cc != curr) {
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[cc]));
}
if (!(flags&CHECK_FLAG_NO_SCREEN_INDEX)) {
displayScreenIndex(curr, menuTabSize, 0);
}
drawFilledRect(0, 0, LCD_W, MENU_TITLE_HEIGHT, SOLID, FILL_WHITE|GREY_DEFAULT);
}
DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);
if (s_editMode<=0) {
if (0) {
l_posVert = limit((int8_t)0, (int8_t)(l_posVert - 0), (int8_t)maxrow);
l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
}
if (p2valdiff && l_posVert>0) {
l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol);
}
}
switch(event)
{
case EVT_ENTRY:
menuEntryTime = get_tmr10ms();
l_posVert = POS_VERT_INIT;
l_posHorz = POS_HORZ_INIT(l_posVert);
SET_SCROLLBAR_X(LCD_W-1);
s_editMode = EDIT_MODE_INIT;
break;
case EVT_ENTRY_UP:
menuEntryTime = get_tmr10ms();
s_editMode = 0;
l_posHorz = POS_HORZ_INIT(l_posVert);
SET_SCROLLBAR_X(LCD_W-1);
break;
case EVT_ROTARY_BREAK:
if (s_editMode > 1) break;
if (m_posHorz < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) {
l_posHorz = 0;
break;
}
if (!menuTab || l_posVert>0) {
if (READ_ONLY_UNLOCKED()) {
s_editMode = (s_editMode<=0);
}
}
break;
case EVT_KEY_LONG(KEY_EXIT):
s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same
popMenu();
break;
case EVT_KEY_BREAK(KEY_EXIT):
if (s_editMode>0) {
s_editMode = 0;
break;
}
if (l_posHorz >= 0 && (COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
l_posHorz = -1;
}
else
{
uint8_t posVertInit = POS_VERT_INIT;
if (s_pgOfs != 0 || l_posVert != posVertInit) {
s_pgOfs = 0;
l_posVert = posVertInit;
l_posHorz = POS_HORZ_INIT(l_posVert);
}
else {
popMenu();
}
}
break;
CASE_EVT_ROTARY_MOVE_RIGHT
if (s_editMode != 0) break;
if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
if (l_posHorz >= 0) {
INC(l_posHorz, 0, maxcol);
break;
}
}
else {
if (l_posHorz < maxcol) {
l_posHorz++;
break;
}
else {
l_posHorz = 0;
if (!IS_ROTARY_MOVE_RIGHT(event))
break;
}
}
do {
INC(l_posVert, POS_VERT_INIT, maxrow);
} while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));
s_editMode = 0; // if we go down, we must be in this mode
l_posHorz = POS_HORZ_INIT(l_posVert);
break;
CASE_EVT_ROTARY_MOVE_LEFT
if (s_editMode != 0) break;
if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
if (l_posHorz >= 0) {
DEC(l_posHorz, 0, maxcol);
break;
}
}
else {
if (l_posHorz > 0) {
l_posHorz--;
break;
}
else if (IS_ROTARY_MOVE_LEFT(event) && s_editMode == 0) {
l_posHorz = 0xff;
}
else {
l_posHorz = maxcol;
break;
}
}
do {
DEC(l_posVert, POS_VERT_INIT, maxrow);
} while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));
s_editMode = 0; // if we go up, we must be in this mode
if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE))
l_posHorz = -1;
else
l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
break;
}
if (l_posVert == 0 || (l_posVert==2 && MAXCOL(vertpos_t(1)) >= HIDDEN_ROW) || (l_posVert==3 && MAXCOL(vertpos_t(1)) >= HIDDEN_ROW && MAXCOL(vertpos_t(2)) >= HIDDEN_ROW)) {
s_pgOfs = 0;
}
else if (horTab) {
uint8_t max = menuTab ? NUM_BODY_LINES : NUM_BODY_LINES-1;
if (maxrow > max) {
while (1) {
vertpos_t firstLine = 0;
for (int numLines=0; firstLine<=maxrow && numLines<s_pgOfs; firstLine++) {
if (horTab[firstLine+1] != HIDDEN_ROW) {
numLines++;
}
}
if (l_posVert <= firstLine) {
s_pgOfs--;
}
else {
vertpos_t lastLine = firstLine;
for (int numLines=0; lastLine<=maxrow && numLines<max; lastLine++) {
if (horTab[lastLine+1] != HIDDEN_ROW) {
numLines++;
}
}
if (l_posVert > lastLine) {
s_pgOfs++;
}
else {
break;
}
}
}
}
}
else {
uint8_t max = menuTab ? NUM_BODY_LINES : NUM_BODY_LINES-1;
if (l_posVert>max+s_pgOfs) {
s_pgOfs = l_posVert-max;
}
else if (l_posVert<1+s_pgOfs) {
s_pgOfs = l_posVert-1;
}
}
if (maxrow > NUM_BODY_LINES && scrollbar_X) {
displayScrollbar(scrollbar_X, MENU_TITLE_HEIGHT, LCD_H-MENU_TITLE_HEIGHT-MENU_NAVIG_HEIGHT, s_pgOfs, menuTab ? maxrow : maxrow+1, NUM_BODY_LINES);
}
m_posVert = l_posVert;
m_posHorz = l_posHorz;
}
void check_simple(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, vertpos_t maxrow)
{
check(event, curr, menuTab, menuTabSize, 0, 0, maxrow);
}
void check_submenu_simple(check_event_t event, uint8_t maxrow)
{
check_simple(event, 0, 0, 0, maxrow);
}
void repeatLastCursorMove(uint8_t event)
{
if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) {
putEvent(event);
}
else {
m_posHorz = 0;
}
}

166
radio/src/gui/Taranis/popups.cpp Executable file
View file

@ -0,0 +1,166 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
const char *s_warning = NULL;
const char *s_warning_info;
uint8_t s_warning_info_len;
uint8_t s_warning_type;
uint8_t s_warning_result = 0;
uint8_t s_warning_info_flags = ZCHAR;
int16_t s_warning_input_value;
int16_t s_warning_input_min;
int16_t s_warning_input_max;
void (*popupFunc)(uint8_t event) = NULL;
const char *s_menu[MENU_MAX_LINES];
uint8_t s_menu_item = 0;
uint16_t s_menu_count = 0;
uint8_t s_menu_flags = 0;
uint16_t s_menu_offset = 0;
void (*menuHandler)(const char *result);
void displayBox()
{
drawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE);
lcd_rect(10, 16, LCD_W-20, 40);
lcd_putsn(WARNING_LINE_X, WARNING_LINE_Y, s_warning, WARNING_LINE_LEN);
// could be a place for a s_warning_info
}
void displayPopup(const pm_char * pstr)
{
s_warning = pstr;
displayBox();
s_warning = NULL;
lcdRefresh();
}
void displayWarning(uint8_t event)
{
s_warning_result = false;
displayBox();
if (s_warning_info) {
lcd_putsnAtt(WARNING_LINE_X, WARNING_LINE_Y+FH, s_warning_info, s_warning_info_len, WARNING_INFO_FLAGS);
}
lcd_puts(WARNING_LINE_X, WARNING_LINE_Y+2*FH, s_warning_type == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS);
switch (event) {
case EVT_KEY_BREAK(KEY_ENTER):
if (s_warning_type == WARNING_TYPE_ASTERISK)
break;
s_warning_result = true;
// no break
case EVT_KEY_BREAK(KEY_EXIT):
s_warning = NULL;
s_warning_type = WARNING_TYPE_ASTERISK;
break;
default:
if (s_warning_type != WARNING_TYPE_INPUT) break;
s_editMode = EDIT_MODIFY_FIELD;
s_warning_input_value = checkIncDec(event, s_warning_input_value, s_warning_input_min, s_warning_input_max);
s_editMode = EDIT_SELECT_FIELD;
break;
}
}
const char * displayMenu(uint8_t event)
{
const char * result = NULL;
uint8_t display_count = min(s_menu_count, (uint16_t)MENU_MAX_LINES);
uint8_t y = (display_count >= 5 ? MENU_Y - FH - 1 : MENU_Y);
drawFilledRect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE);
lcd_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2);
for (uint8_t i=0; i<display_count; i++) {
lcd_putsAtt(MENU_X+6, i*(FH+1) + y + 2, s_menu[i], s_menu_flags);
if (i == s_menu_item) drawFilledRect(MENU_X+1, i*(FH+1) + y + 1, MENU_W-2, 9);
}
if (s_menu_count > display_count) {
displayScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_LINES * (FH+1), s_menu_offset, s_menu_count, MENU_MAX_LINES);
}
switch(event) {
case EVT_KEY_FIRST(KEY_MOVE_UP):
case EVT_KEY_REPT(KEY_MOVE_UP):
if (s_menu_item > 0) {
s_menu_item--;
}
else if (s_menu_offset > 0) {
s_menu_offset--;
result = STR_UPDATE_LIST;
}
else {
s_menu_item = display_count - 1;
if (s_menu_count > MENU_MAX_LINES) {
s_menu_offset = s_menu_count - display_count;
result = STR_UPDATE_LIST;
}
}
break;
case EVT_KEY_FIRST(KEY_MOVE_DOWN):
case EVT_KEY_REPT(KEY_MOVE_DOWN):
if (s_menu_item < display_count - 1 && s_menu_offset + s_menu_item + 1 < s_menu_count) {
s_menu_item++;
}
else if (s_menu_count > s_menu_offset + display_count) {
s_menu_offset++;
result = STR_UPDATE_LIST;
}
else {
s_menu_item = 0;
if (s_menu_offset) {
s_menu_offset = 0;
result = STR_UPDATE_LIST;
}
}
break;
CASE_EVT_ROTARY_BREAK
case EVT_KEY_BREAK(KEY_ENTER):
result = s_menu[s_menu_item];
// no break
case EVT_KEY_BREAK(KEY_EXIT):
s_menu_count = 0;
s_menu_item = 0;
s_menu_flags = 0;
s_menu_offset = 0;
break;
}
return result;
}

View file

@ -37,8 +37,6 @@
#include "../../opentx.h"
#define BIGSIZE MIDSIZE
#define BOX_WIDTH 31
#define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10)
#define LBOX_CENTERX (BOX_WIDTH/2 + 17)
#define RBOX_CENTERX (LCD_W-LBOX_CENTERX)
#define MODELNAME_X (15)
@ -67,7 +65,6 @@
#define TRIM_LEN 27
#define MARKER_WIDTH 5
#define BOX_LIMIT (BOX_WIDTH-MARKER_WIDTH)
const pm_uchar logo_taranis[] PROGMEM = {
#include "../../bitmaps/Taranis/logo.lbm"
@ -104,13 +101,6 @@ void drawPotsBars()
}
}
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
{
lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
DO_CROSS(centrex, BOX_CENTERY, 3);
lcd_square(centrex + (xval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
}
void doMainScreenGraphics()
{
int16_t calibStickVert = calibratedStick[CONVERT_MODE(1)];

View file

@ -0,0 +1,215 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void menuStatisticsView(uint8_t event)
{
TITLE(STR_MENUSTAT);
switch(event)
{
case EVT_KEY_FIRST(KEY_UP):
chainMenu(menuStatisticsDebug);
break;
case EVT_KEY_LONG(KEY_MENU):
g_eeGeneral.globalTimer = 0;
eeDirty(EE_GENERAL);
sessionTimer = 0;
break;
case EVT_KEY_FIRST(KEY_EXIT):
chainMenu(menuMainView);
break;
}
lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP);
putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0);
putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0);
putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0);
#if defined(THRTRACE)
coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0);
const coord_t x = 5;
const coord_t y = 60;
lcd_hline(x-3, y, MAXTRACE+3+3);
lcd_vline(x, y-32, 32+3);
for (coord_t i=0; i<MAXTRACE; i+=6) {
lcd_vline(x+i+6, y-1, 3);
}
for (coord_t i=1; i<=MAXTRACE; i++) {
lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]);
traceRd++;
if (traceRd>=MAXTRACE) traceRd = 0;
if (traceRd==s_traceWr) break;
}
#endif
}
#define MENU_DEBUG_COL1_OFS (11*FW-2)
#define MENU_DEBUG_Y_MIXMAX (2*FH-3)
#define MENU_DEBUG_Y_LUA (3*FH-2)
#define MENU_DEBUG_Y_FREE_RAM (4*FH-1)
#define MENU_DEBUG_Y_STACK (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
void menuStatisticsDebug(uint8_t event)
{
TITLE(STR_MENUDEBUG);
switch(event)
{
case EVT_KEY_LONG(KEY_ENTER):
g_eeGeneral.mAhUsed = 0;
g_eeGeneral.globalTimer = 0;
eeDirty(EE_GENERAL);
sessionTimer = 0;
killEvents(event);
AUDIO_KEYPAD_UP();
break;
case EVT_KEY_FIRST(KEY_ENTER):
#if defined(LUA)
maxLuaInterval = 0;
maxLuaDuration = 0;
#endif
maxMixerDuration = 0;
AUDIO_KEYPAD_UP();
break;
#if defined(DEBUG_TRACE_BUFFER)
case EVT_KEY_FIRST(KEY_UP):
pushMenu(menuTraceBuffer);
return;
#endif
case EVT_KEY_FIRST(KEY_DOWN):
chainMenu(menuStatisticsView);
break;
case EVT_KEY_FIRST(KEY_EXIT):
chainMenu(menuMainView);
break;
}
lcd_putsLeft(MENU_DEBUG_Y_FREE_RAM, "Free Mem");
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_FREE_RAM, getAvailableMemory(), LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_FREE_RAM, "b");
#if defined(LUA)
lcd_putsLeft(MENU_DEBUG_Y_LUA, "Lua scripts");
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_LUA+1, "[Duration]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaDuration, LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_LUA+1, "[Interval]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_LUA, 10*maxLuaInterval, LEFT);
#endif
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS+1, "[Main]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Mix]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
lcd_putsAtt(lcdLastPos+2, MENU_DEBUG_Y_RTOS+1, "[Audio]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
lcd_puts(3*FW, 7*FH+1, STR_MENUTORESET);
lcd_status_line();
}
#if defined(DEBUG_TRACE_BUFFER)
#include "stamp-opentx.h"
void menuTraceBuffer(uint8_t event)
{
switch(event)
{
case EVT_KEY_LONG(KEY_ENTER):
dumpTraceBuffer();
killEvents(event);
break;
}
SIMPLE_SUBMENU("Trace Buffer " VERS_STR, TRACE_BUFFER_LEN);
/* RTC time */
struct gtm t;
gettime(&t);
putsTime(LCD_W+1, 0, t, TIMEBLINK);
uint8_t y = 0;
uint8_t k = 0;
int8_t sub = m_posVert;
lcd_putc(0, FH, '#');
lcd_puts(4*FW, FH, "Time");
lcd_puts(14*FW, FH, "Event");
lcd_puts(20*FW, FH, "Data");
for (uint8_t i=0; i<LCD_LINES-2; i++) {
y = 1 + (i+2)*FH;
k = i+s_pgOfs;
//item
lcd_outdezAtt(0, y, k, LEFT | (sub==k ? INVERS : 0));
const struct TraceElement * te = getTraceElement(k);
if (te) {
//time
putstime_t tme = te->time % SECS_PER_DAY;
putsTimer(4*FW, y, tme, TIMEHOUR|LEFT, TIMEHOUR|LEFT);
//event
lcd_outdezNAtt(14*FW, y, te->event, LEADING0|LEFT, 3);
//data
lcd_putsn (20*FW, y, "0x", 2);
lcd_outhex4(22*FW-2, y, (uint16_t)(te->data >> 16));
lcd_outhex4(25*FW, y, (uint16_t)(te->data & 0xFFFF));
}
}
}
#endif //#if defined(DEBUG_TRACE_BUFFER)

View file

@ -0,0 +1,265 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 STATUS_BAR_Y (7*FH+1)
#define TELEM_2ND_COLUMN (11*FW)
#if defined(FRSKY_HUB) && defined(GAUGES)
bar_threshold_t barsThresholds[THLD_MAX];
#endif
uint8_t s_frsky_view = 0;
#define BAR_LEFT 26
#define BAR_WIDTH 157
void displayRssiLine()
{
if (TELEMETRY_STREAMING()) {
lcd_hline(0, 55, 212, 0); // separator
uint8_t rssi = min((uint8_t)99, TELEMETRY_RSSI());
lcd_putsn(0, STATUS_BAR_Y, STR_RX, 2); lcd_outdezNAtt(4*FW, STATUS_BAR_Y, rssi, LEADING0, 2);
lcd_rect(BAR_LEFT, 57, 78, 7);
drawFilledRect(BAR_LEFT+1, 58, 19*rssi/25, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID);
}
else {
lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK);
lcd_status_line();
}
}
NOINLINE uint8_t getRssiAlarmValue(uint8_t alarm)
{
return (45 - 3*alarm + g_model.frsky.rssiAlarms[alarm].value);
}
uint8_t barCoord(int16_t value, int16_t min, int16_t max)
{
if (value <= min)
return 0;
else if (value >= max)
return BAR_WIDTH-1;
else
return ((int32_t)(BAR_WIDTH-1) * (value - min)) / (max - min);
}
bool displayGaugesTelemetryScreen(FrSkyScreenData & screen)
{
// Custom Screen with gauges
uint8_t barHeight = 5;
for (int8_t i=3; i>=0; i--) {
FrSkyBarData & bar = screen.bars[i];
source_t source = bar.source;
getvalue_t barMin = bar.barMin;
getvalue_t barMax = bar.barMax;
if (source && barMax > barMin) {
uint8_t y = barHeight+6+i*(barHeight+6);
putsMixerSource(0, y+barHeight-5, source, 0);
lcd_rect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
getvalue_t value = getValue(source);
putsChannel(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT);
uint8_t thresholdX = 0;
uint8_t width = barCoord(value, barMin, barMax);
uint8_t barShade = SOLID;
drawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade);
for (uint8_t j=24; j<99; j+=25) {
if (j>thresholdX || j>width) {
lcd_vline(j*BAR_WIDTH/100+BAR_LEFT+1, y+1, barHeight);
}
}
if (thresholdX) {
lcd_vlineStip(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED);
lcd_hline(BAR_LEFT+thresholdX, y-2, 3);
}
}
else {
barHeight += 2;
}
}
displayRssiLine();
return barHeight < 13;
}
bool displayNumbersTelemetryScreen(FrSkyScreenData & screen)
{
// Custom Screen with numbers
uint8_t fields_count = 0;
for (uint8_t i=0; i<4; i++) {
for (uint8_t j=0; j<NUM_LINE_ITEMS; j++) {
source_t field = screen.lines[i].sources[j];
if (field > 0) {
fields_count++;
}
if (i==3) {
lcd_vline(69, 8, 48);
lcd_vline(141, 8, 48);
if (!TELEMETRY_STREAMING()) {
displayRssiLine();
return fields_count;
}
}
if (field) {
LcdFlags att = (i==3 ? NO_UNIT : DBLSIZE|NO_UNIT);
coord_t pos[] = {0, 71, 143, 214};
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER && i!=3) {
// there is not enough space on LCD for displaying "Tmr1" or "Tmr2" and still see the - sign, we write "T1" or "T2" instead
putsStrIdx(pos[j], 1+FH+2*FH*i, "T", field-MIXSRC_FIRST_TIMER+1, 0);
}
else if (field >= MIXSRC_FIRST_TELEM && isGPSSensor(1+(field-MIXSRC_FIRST_TELEM)/3) && telemetryItems[(field-MIXSRC_FIRST_TELEM)/3].isAvailable()) {
// we don't display GPS name, no space for it
}
else {
putsMixerSource(pos[j], 1+FH+2*FH*i, field, 0);
}
if (field >= MIXSRC_FIRST_TELEM) {
TelemetryItem & telemetryItem = telemetryItems[(field-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index
if (!telemetryItem.isAvailable()) {
continue;
}
else if (telemetryItem.isOld()) {
att |= INVERS|BLINK;
}
}
putsChannel(pos[j+1]-2, (i==3 ? 1+FH+2*FH*i:FH+2*FH*i), field, att);
}
}
}
lcd_status_line();
return fields_count;
}
bool displayCustomTelemetryScreen(uint8_t index)
{
FrSkyScreenData & screen = g_model.frsky.screens[index];
#if defined(GAUGES)
if (IS_BARS_SCREEN(s_frsky_view)) {
return displayGaugesTelemetryScreen(screen);
}
#endif
displayNumbersTelemetryScreen(screen);
return true;
}
bool displayTelemetryScreen()
{
#if defined(LUA)
if (TELEMETRY_SCREEN_TYPE(s_frsky_view) == TELEMETRY_SCREEN_TYPE_SCRIPT) {
return true;
}
#endif
if (TELEMETRY_SCREEN_TYPE(s_frsky_view) == TELEMETRY_SCREEN_TYPE_NONE) {
return false;
}
lcdDrawTelemetryTopBar();
if (s_frsky_view < MAX_TELEMETRY_SCREENS) {
return displayCustomTelemetryScreen(s_frsky_view);
}
return true;
}
enum NavigationDirection {
none,
up,
down
};
#define decrTelemetryScreen() direction = up
#define incrTelemetryScreen() direction = down
void menuTelemetryFrsky(uint8_t event)
{
enum NavigationDirection direction = none;
switch (event) {
case EVT_KEY_FIRST(KEY_EXIT):
killEvents(event);
chainMenu(menuMainView);
break;
case EVT_KEY_LONG(KEY_PAGE):
killEvents(event);
// no break;
case EVT_KEY_FIRST(KEY_UP):
decrTelemetryScreen();
break;
case EVT_KEY_BREAK(KEY_PAGE):
case EVT_KEY_FIRST(KEY_DOWN):
incrTelemetryScreen();
break;
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
MENU_ADD_ITEM(STR_RESET_TELEMETRY);
MENU_ADD_ITEM(STR_RESET_FLIGHT);
menuHandler = onMainViewMenu;
break;
}
for (int i=0; i<=TELEMETRY_SCREEN_TYPE_MAX; i++) {
if (direction == up) {
if (s_frsky_view-- == 0)
s_frsky_view = TELEMETRY_VIEW_MAX;
}
else if (direction == down) {
if (s_frsky_view++ == TELEMETRY_VIEW_MAX)
s_frsky_view = 0;
}
else {
direction = down;
}
if (displayTelemetryScreen()) {
return;
}
}
lcdDrawTelemetryTopBar();
lcd_puts(8*FW, 3*FH, "No Telemetry Screens");
displayRssiLine();
}

View file

@ -0,0 +1,164 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 TEXT_FILENAME_MAXLEN 40
#define TEXT_FILE_MAXSIZE 2048
char s_text_file[TEXT_FILENAME_MAXLEN];
char s_text_screen[LCD_LINES-1][LCD_COLS+1];
void readTextFile(int & lines_count)
{
FIL file;
int result;
char c;
unsigned int sz;
int line_length = 0;
int escape = 0;
char escape_chars[2];
int current_line = 0;
memset(s_text_screen, 0, sizeof(s_text_screen));
result = f_open(&file, s_text_file, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) {
for (int i=0; i<TEXT_FILE_MAXSIZE && f_read(&file, &c, 1, &sz)==FR_OK && sz==1 && (lines_count==0 || current_line-s_pgOfs<LCD_LINES-1); i++) {
if (c == '\n') {
++current_line;
line_length = 0;
escape = 0;
}
else if (c!='\r' && current_line>=s_pgOfs && current_line-s_pgOfs<LCD_LINES-1 && line_length<LCD_COLS) {
if (c=='\\' && escape==0) {
escape = 1;
continue;
}
else if (c!='\\' && escape>0 && escape<3) {
escape_chars[escape-1] = c;
if (escape == 2 && !strncmp(escape_chars, "up", 2)) {
c = '\300';
escape = 0;
}
else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) {
c = '\301';
escape = 0;
}
else {
escape++;
continue;
}
}
else if (c=='~') {
c = 'z'+1;
}
else if (c=='\t') {
c = 0x1D; //tab
}
escape = 0;
s_text_screen[current_line-s_pgOfs][line_length++] = c;
}
}
if (c != '\n') {
current_line += 1;
}
f_close(&file);
}
if (lines_count == 0) {
lines_count = current_line;
}
}
void menuTextView(uint8_t event)
{
static int lines_count;
switch (event) {
case EVT_ENTRY:
s_pgOfs = 0;
lines_count = 0;
readTextFile(lines_count);
break;
case EVT_KEY_FIRST(KEY_UP):
if (s_pgOfs == 0)
break;
else
s_pgOfs--;
// no break;
case EVT_KEY_FIRST(KEY_DOWN):
// if (event == EVT_KEY_BREAK(KEY_DOWN)) {
if (s_pgOfs+LCD_LINES-1 >= lines_count)
break;
else
++s_pgOfs;
// }
readTextFile(lines_count);
break;
case EVT_KEY_BREAK(KEY_EXIT):
popMenu();
break;
}
for (int i=0; i<LCD_LINES-1; i++) {
lcd_putsAtt(0, i*FH+FH+1, s_text_screen[i], FIXEDWIDTH);
}
char *title = s_text_file;
#if defined(SIMU)
if (!strncmp(title, "./", 2)) title += 2;
#else
// TODO?
#endif
lcd_puts(LCD_W/2-strlen(title)*FW/2, 0, title);
lcd_invert_line(0);
if (lines_count > LCD_LINES-1) {
displayScrollbar(LCD_W-1, FH, LCD_H-FH, s_pgOfs, lines_count, LCD_LINES-1);
}
}
void pushMenuTextView(const char *filename)
{
if (strlen(filename) < TEXT_FILENAME_MAXLEN) {
strcpy(s_text_file, filename);
pushMenu(menuTextView);
}
}

208
radio/src/gui/Taranis/widgets.cpp Executable file
View file

@ -0,0 +1,208 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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"
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
{
#define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10)
#define MARKER_WIDTH 5
lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
lcd_vline(centrex, BOX_CENTERY-1, 3);
lcd_hline(centrex-1, BOX_CENTERY, 3);
lcd_square(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
#undef BOX_CENTERY
#undef MARKER_WIDTH
}
void displayColumnHeader(const char * const *headers, uint8_t index)
{
lcd_putsAtt(17*FW, 0, headers[index], 0);
}
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
{
if (value)
lcd_putc(x+1, y, '#');
if (attr)
drawFilledRect(x, y, 7, 7);
else
lcd_square(x, y, 7);
}
void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
{
lcd_outdezAtt(LCD_W, 0, count, attr);
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
lcd_putcAtt(x, 0, '/', attr);
lcd_outdezAtt(x, 0, index+1, attr);
}
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
{
lcd_vlineStip(x, y, h, DOTTED);
coord_t yofs = (h * offset) / count;
coord_t yhgt = (h * visible) / count;
if (yhgt + yofs > h)
yhgt = h - yofs;
lcd_vlineStip(x, y + yofs, yhgt, SOLID, FORCE);
}
void title(const pm_char * s)
{
lcd_putsAtt(0, 0, s, INVERS);
}
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)
{
lcd_putsColumnLeft(x, y, label);
if (values) lcd_putsiAtt(x, y, values, value-min, attr);
if (attr) value = checkIncDec(event, value, min, max, (g_menuPos[0] == 0) ? EE_MODEL : EE_GENERAL);
return value;
}
uint8_t onoffMenuItem(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);
return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event);
}
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event)
{
lcd_putsColumnLeft(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
return value;
}
void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
{
lcd_putc(x+(value*4*FW)/max, y, '$');
lcd_hline(x, y+3, 5*FW-1, FORCE);
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1);
}
#if defined(GVARS)
bool noZero(int val)
{
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)
{
uint16_t delta = GV_GET_GV1_VALUE(max);
bool invers = (attr & INVERS);
// TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max);
if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
s_editMode = !s_editMode;
if (attr & PREC1)
value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta);
else
value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta);
eeDirty(EE_MODEL);
}
if (GV_IS_GV_VALUE(value, min, max)) {
if (attr & LEFT)
attr -= LEFT; /* because of ZCHAR */
else
x -= 2*FW+FWNUM;
attr &= ~PREC1;
int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta);
if (idx >= 0) ++idx; // transform form idx=0=GV1 to idx=1=GV1 in order to handle double keys invert
if (invers) {
CHECK_INCDEC_MODELVAR_CHECK(event, idx, -MAX_GVARS, MAX_GVARS, noZero);
if (idx == 0) idx = 1; // handle reset to zero, map to GV1
}
if (idx < 0) {
value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta);
idx = -idx;
lcd_putcAtt(x-6, y, '-', attr);
}
else {
value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta);
}
putsStrIdx(x, y, STR_GV, idx, attr);
}
else {
lcd_outdezAtt(x, y, value, attr);
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
}
return value;
}
#else
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
{
lcd_outdezAtt(x, y, value, attr);
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
return value;
}
#endif
#if defined(SDCARD)
char statusLineMsg[STATUS_LINE_LENGTH];
tmr10ms_t statusLineTime = 0;
uint8_t statusLineHeight = 0;
void showStatusLine()
{
statusLineTime = get_tmr10ms();
}
#define STATUS_LINE_DELAY (3 * 100) /* 3s */
void drawStatusLine()
{
if (statusLineTime) {
if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
if (statusLineHeight < FH) statusLineHeight++;
}
else if (statusLineHeight) {
statusLineHeight--;
}
else {
statusLineTime = 0;
}
drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
lcd_putsAtt(5, LCD_H+1-statusLineHeight, statusLineMsg, BSS);
drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
}
}
#endif

46
radio/src/gui/gui.h Executable file
View file

@ -0,0 +1,46 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _GUI_H_
#define _GUI_H_
#if defined(PCBTARANIS)
#include "Taranis/gui.h"
#else
#include "9X/gui.h"
#endif
#endif // _GUI_H_

View file

@ -36,10 +36,6 @@
#include "../opentx.h"
const pm_uchar sticks[] PROGMEM = {
#include "../bitmaps/sticks.lbm"
};
#if defined(CPUARM)
extern LP_CONST LanguagePack czLanguagePack;
extern LP_CONST LanguagePack enLanguagePack;
@ -70,6 +66,16 @@ const LanguagePack * LP_CONST languagePacks[] = {
};
#endif
void menuGeneralSetup(uint8_t event);
void menuGeneralSdManager(uint8_t event);
void menuGeneralCustomFunctions(uint8_t event);
void menuGeneralTrainer(uint8_t event);
void menuGeneralVersion(uint8_t event);
void menuGeneralDiagKeys(uint8_t event);
void menuGeneralDiagAna(uint8_t event);
void menuGeneralHardware(uint8_t event);
void menuGeneralCalib(uint8_t event);
enum EnumTabDiag {
e_Setup,
CASE_SDCARD(e_Sd)
@ -82,16 +88,6 @@ enum EnumTabDiag {
e_Calib
};
void menuGeneralSetup(uint8_t event);
void menuGeneralSdManager(uint8_t event);
void menuGeneralCustomFunctions(uint8_t event);
void menuGeneralTrainer(uint8_t event);
void menuGeneralVersion(uint8_t event);
void menuGeneralDiagKeys(uint8_t event);
void menuGeneralDiagAna(uint8_t event);
void menuGeneralHardware(uint8_t event);
void menuGeneralCalib(uint8_t event);
const MenuFuncP_PROGMEM menuTabGeneral[] PROGMEM = {
menuGeneralSetup,
CASE_SDCARD(menuGeneralSdManager)

View file

@ -241,9 +241,6 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
}
lcd_putcAtt(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH);
#if defined(PCBHORUS)
lcd_putcAtt(x+editNameCursorPos*FW, y, idx2char(v), FIXEDWIDTH|WHITE);
#endif
}
else {
cur = 0;

File diff suppressed because it is too large Load diff

View file

@ -34,28 +34,11 @@
*
*/
#ifndef menus_h
#define menus_h
#ifndef _MENUS_H_
#define _MENUS_H_
#define NO_HI_LEN 25
void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
inline void displayColumnHeader(const char * const *headers, uint8_t index)
{
lcd_putsAtt(17*FW, 0, headers[index], 0);
}
#if !defined(CPUM64)
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
#endif
#if LCD_W >= 212
extern coord_t scrollbar_X;
#define SET_SCROLLBAR_X(x) scrollbar_X = (x);
#else
#define SET_SCROLLBAR_X(x)
#endif
#if LCD_W >= 212
#if defined(TRANSLATIONS_FR)
#define MENU_COLUMNS 1
@ -414,14 +397,22 @@ extern uint8_t s_warning_info_len;
extern uint8_t s_warning_result;
extern uint8_t s_warning_type;
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
#if LCD_W >= 212
#define MENU_X 30
#define MENU_Y 16
#define WARNING_LINE_LEN 32
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
#else
#define MENU_X 10
#define MENU_Y 16
#define WARNING_LINE_LEN 20
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
#endif
#define MENU_W LCD_W-(2*MENU_X)
void displayBox();
void displayPopup(const pm_char * pstr);
void displayWarning(uint8_t event);
@ -545,4 +536,4 @@ void displayWarning(uint8_t event);
typedef int16_t (*FnFuncP) (int16_t x);
void DrawFunction(FnFuncP fn, uint8_t offset=0);
#endif
#endif // _MENUS_H_

View file

@ -36,7 +36,8 @@
#include "../opentx.h"
#if defined(PCBTARANIS)
#if defined(COLORLCD)
#elif defined(PCBTARANIS)
const pm_uchar about_bmp[] PROGMEM = {
#include "../bitmaps/Taranis/about.lbm"
};
@ -93,7 +94,9 @@ void menuAboutView(uint8_t event)
break;
}
#if defined(PCBTARANIS)
#if defined(COLORLCD)
LcdFlags att = GREY(max(0, 15-greyIndex/2));
#elif defined(PCBTARANIS)
lcd_bmp(0, 0, about_bmp);
lcd_putsAtt(64, 0, STR_ABOUTUS, DBLSIZE);
lcd_hline(ABOUT_X, 18, 120);

View file

@ -59,7 +59,10 @@ void menuChannelsView(uint8_t event)
else
ch = 0;
#if !defined(COLORLCD)
lcd_putsCenter(0*FH, CHANNELS_MONITOR);
#endif
lcd_invert_line(0);
// Column separator

View file

@ -40,6 +40,7 @@
#if defined(PCBTARANIS)
#define LCD_W 212
#define LCD_H 64
#define BOX_WIDTH 31
#define coord_t int
#define scoord_t int
#define CENTER "\015"
@ -49,6 +50,7 @@
#else
#define LCD_W 128
#define LCD_H 64
#define BOX_WIDTH 23
#define coord_t uint8_t
#define scoord_t int8_t
#define CENTER
@ -80,19 +82,23 @@
/* lcd text flags */
#define INVERS 0x02
#ifdef BOLD_FONT
#if defined(BOLD_FONT)
#define BOLD 0x40
#else
#define BOLD 0x00
#endif
/* lcd putc flags */
#define CONDENSED 0x08
#define CONDENSED 0x08 // TODO remove on TARANIS
#define FIXEDWIDTH 0x10
/* lcd puts flags */
/* no 0x80 here because of "GV"1 which is aligned LEFT */
/* no 0x10 here because of "MODEL"01 which uses LEADING0 */
#define BSS 0x20
#if defined(CPUARM)
#define BSS 0x00
#else
#define BSS 0x20
#endif
#define ZCHAR 0x80
/* lcd outdez flags */
@ -205,15 +211,21 @@ void lcd_putsnAtt(coord_t x, coord_t y, const pm_char * s,unsigned char len, Lcd
void lcd_puts(coord_t x, coord_t y, const pm_char * s);
void lcd_putsn(coord_t x, coord_t y, const pm_char * s, unsigned char len);
void lcd_putsLeft(coord_t y, const pm_char * s);
#define lcd_putsCenter(y, s) lcd_puts((LCD_W-sizeof(TR_##s)*FW+FW+1)/2, y, STR_##s)
#if defined(COLORLCD)
void lcd_putsCenter(coord_t y, const pm_char * s, LcdFlags attr=0);
#else
#define lcd_putsCenter(y, s) lcd_puts((LCD_W-sizeof(TR_##s)*FW+FW+1)/2, y, STR_##s)
#endif
#if defined(CPUARM)
void lcd_outhex4(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
void lcd_outhex4(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
#else
void lcd_outhex4(coord_t x, coord_t y, uint16_t val);
void lcd_outhex4(coord_t x, coord_t y, uint16_t val);
#endif
void lcd_outdezAtt(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0);
void lcd_outdezNAtt(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0, uint8_t len=0);
void lcd_outdezAtt(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0);
void lcd_outdez8(coord_t x, coord_t y, int8_t val);
void putsStrIdx(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att=0);
@ -279,11 +291,7 @@ inline void lcd_square(coord_t x, coord_t y, coord_t w, LcdFlags att=0) { lcd_re
void lcdDrawTelemetryTopBar();
#define DO_CROSS(xx,yy,ww) \
lcd_vline(xx,yy-ww/2,ww); \
lcd_hline(xx-ww/2,yy,ww);
#define V_BAR(xx,yy,ll) \
#define V_BAR(xx, yy, ll) \
lcd_vline(xx-1,yy-ll,ll); \
lcd_vline(xx ,yy-ll,ll); \
lcd_vline(xx+1,yy-ll,ll);
@ -328,12 +336,11 @@ void lcdInit();
extern display_t lcd_buf[DISPLAY_BUF_SIZE];
#endif
char * strAppend(char * dest, const char * source);
char * strAppendDate(char * str, bool time=false);
char * strAppendFilename(char * dest, const char * filename, const int size);
char *strAppend(char * dest, const char * source, int len=0);
char *strSetCursor(char *dest, int position);
char *strAppendDate(char * str, bool time=false);
char *strAppendFilename(char * dest, const char * filename, const int size);
#define NUM_BODY_LINES LCD_LINES-1
#define HEIGHT_BODY_LINE FH
#define MENU_TITLE_HEIGHT FH
#define MENU_NAVIG_HEIGHT 0

View file

@ -36,7 +36,6 @@
#include "opentx.h"
#if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER)
display_t displayBuf1[DISPLAY_BUF_SIZE];
display_t displayBuf2[DISPLAY_BUF_SIZE];
@ -250,10 +249,6 @@ void lcd_putsnAtt(coord_t x, coord_t y, const pm_char * s, uint8_t len, LcdFlags
lcd_putcAtt(x, y, c, flags);
x = lcdNextPos;
}
else if (setx) {
x = c;
setx = false;
}
else if (c == 0x1F) { //X-coord prefix
setx = true;
}

View file

@ -116,7 +116,7 @@ void perMain()
if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on
checkBacklight();
#if defined(FRSKY) || defined(MAVLINK) || defined(SIMU)
#if defined(FRSKY) || defined(MAVLINK)
telemetryWakeup();
#endif

View file

@ -38,7 +38,8 @@
#if defined(SPLASH)
const pm_uchar splashdata[] PROGMEM = { 'S','P','S',0,
#if defined(PCBTARANIS)
#if defined(COLORLCD)
#elif defined(PCBTARANIS)
#include "bitmaps/Taranis/splash.lbm"
#else
#include "bitmaps/9X/splash.lbm"
@ -47,7 +48,8 @@ const pm_uchar splashdata[] PROGMEM = { 'S','P','S',0,
const pm_uchar * const splash_lbm = splashdata+4;
#endif
#if defined(PCBTARANIS)
#if defined(COLORLCD)
#elif defined(PCBTARANIS)
const pm_uchar asterisk_lbm[] PROGMEM = {
#include "bitmaps/Taranis/asterisk.lbm"
};
@ -76,8 +78,10 @@ void loadModelBitmap(char *name, uint8_t *bitmap)
}
}
#if !defined(COLORLCD)
// In all error cases, we set the default logo
memcpy(bitmap, logo_taranis, MODEL_BITMAP_SIZE);
#endif
}
#endif
@ -206,7 +210,7 @@ void per10ms()
}
#endif
#if defined(FRSKY) || defined(JETI) || defined(SIMU)
#if defined(FRSKY) || defined(JETI)
if (!IS_DSM2_SERIAL_PROTOCOL(s_current_protocol[0]))
telemetryInterrupt10ms();
#endif
@ -959,7 +963,8 @@ bool readonlyUnlocked()
inline void Splash()
{
lcd_clear();
#if defined(PCBTARANIS)
#if defined(COLORLCD)
#elif defined(PCBTARANIS)
lcd_bmp(0, 0, splash_lbm);
#else
lcd_img(0, 0, splash_lbm, 0, 0);
@ -1185,7 +1190,10 @@ void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SO
{
lcd_clear();
#if LCD_W >= 212
#if defined(COLORLCD)
#define MESSAGE_LCD_OFFSET 60
drawFilledRect(30, 20, 252, 100, SOLID, BLACK);
#elif defined(PCBTARANIS)
lcd_bmp(0, 0, asterisk_lbm);
#define MESSAGE_LCD_OFFSET 60
#else
@ -1193,7 +1201,10 @@ void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SO
#define MESSAGE_LCD_OFFSET 6*FW
#endif
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || defined(TRANSLATIONS_CZ)
#if defined(COLORLCD)
lcd_putsAtt(MESSAGE_LCD_OFFSET, 30, STR_WARNING, WHITE|DBLSIZE);
lcd_putsAtt(MESSAGE_LCD_OFFSET, 46, title, WHITE|DBLSIZE);
#elif defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || defined(TRANSLATIONS_CZ)
lcd_putsAtt(MESSAGE_LCD_OFFSET, 0, STR_WARNING, DBLSIZE);
lcd_putsAtt(MESSAGE_LCD_OFFSET, 2*FH, title, DBLSIZE);
#else
@ -1201,7 +1212,13 @@ void message(const pm_char *title, const pm_char *t, const char *last MESSAGE_SO
lcd_putsAtt(MESSAGE_LCD_OFFSET, 2*FH, STR_WARNING, DBLSIZE);
#endif
#if LCD_W >= 212
#if defined(COLORLCD)
if (t) lcd_putsAtt(MESSAGE_LCD_OFFSET, 80, t, WHITE);
if (last) {
lcd_putsAtt(MESSAGE_LCD_OFFSET, 92, last, WHITE);
AUDIO_ERROR_MESSAGE(sound);
}
#elif LCD_W >= 212
drawFilledRect(MESSAGE_LCD_OFFSET, 0, LCD_W-MESSAGE_LCD_OFFSET, 32);
if (t) lcd_puts(MESSAGE_LCD_OFFSET, 5*FH, t);
if (last) {
@ -2146,10 +2163,13 @@ uint8_t getSticksNavigationEvent()
void checkBattery()
{
static uint8_t counter = 0;
#if !defined(COLORLCD)
// TODO not the right menu I think ...
if (g_menuStack[g_menuStackPtr] == menuGeneralDiagAna) {
g_vbat100mV = 0;
counter = 0;
}
#endif
if (counter-- == 0) {
counter = 10;
int32_t instant_vbat = anaIn(TX_VOLTAGE);

View file

@ -667,7 +667,9 @@ extern uint8_t flightModeTransitionLast;
#define bitfield_channels_t uint16_t
#endif
#if defined(CPUARM) && !defined(SIMU)
#if defined(SIMU)
inline int getAvailableMemory() { return 1000; }
#elif defined(CPUARM) && !defined(SIMU)
extern unsigned char *heap;
extern int _end;
extern int _estack;
@ -1094,7 +1096,14 @@ extern int16_t calcRESXto1000(int16_t x);
extern int8_t calcRESXto100(int16_t x);
#endif
#if defined(COLORLCD)
extern const char vers_stamp[];
extern const char date_stamp[];
extern const char time_stamp[];
extern const char eeprom_stamp[];
#else
extern const char vers_stamp[];
#endif
extern uint8_t g_vbat100mV;
#define g_blinkTmr10ms (*(uint8_t*)&g_tmr10ms)
@ -1336,6 +1345,7 @@ void evalFunctions();
extern volatile rotenc_t g_rotenc[1];
#endif
#include "gui/gui.h"
#include "gui/menus.h"
#if defined(CPUARM)
@ -1557,7 +1567,7 @@ void convertUnit(getvalue_t & val, uint8_t & unit); // TODO check FORCEINLINE on
#if defined(CPUARM)
uint8_t zlen(const char *str, uint8_t size);
bool zexist(const char *str, uint8_t size);
char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx);
char * strcat_zchar(char *dest, const char *name, uint8_t size, const char *defaultName=NULL, uint8_t defaultNameSize=0, uint8_t defaultIdx=0);
#define strcat_modelname(dest, idx) strcat_zchar(dest, modelHeaders[idx].name, LEN_MODEL_NAME, STR_MODEL, PSIZE(TR_MODEL), idx+1)
#define strcat_phasename(dest, idx) strcat_zchar(dest, g_model.flightModeData[idx].name, LEN_FLIGHT_MODE_NAME, STR_FP, PSIZE(TR_FP), idx+1)
#define ZLEN(s) zlen(s, sizeof(s))

View file

@ -43,8 +43,10 @@
#include <time.h>
#include <ctype.h>
#define W2 LCD_W*2
#define H2 LCD_H*2
#define LCD_ZOOM 2
#define W2 LCD_W*LCD_ZOOM
#define H2 LCD_H*LCD_ZOOM
int g_snapshot_idx = 0;
@ -61,6 +63,7 @@ class Open9xSim: public FXMainWindow
void makeSnapshot(const FXDrawable* drawable);
void doEvents();
void refreshDisplay();
void setPixel(int x, int y, FXColor color);
private:
FXImage *bmp;
@ -192,7 +195,7 @@ long Open9xSim::onKeypress(FXObject*,FXSelector,void*v)
{
FXEvent *evt=(FXEvent*)v;
// printf("keypress %x\n", evt->code);
if (evt->code=='s'){
if (evt->code=='s') {
makeSnapshot(bmf);
}
return 0;
@ -332,6 +335,15 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
#define BL_COLOR FXRGB(150,200,152)
#endif
void Open9xSim::setPixel(int x, int y, FXColor color)
{
for (int i=0; i<LCD_ZOOM; ++i) {
for (int j=0; j<LCD_ZOOM; ++j) {
bmp->setPixel(LCD_ZOOM*x+i, LCD_ZOOM*y+j, color);
}
}
}
void Open9xSim::refreshDisplay()
{
if (lcd_refresh) {
@ -351,24 +363,15 @@ void Open9xSim::refreshDisplay()
color = FXRGB(47-(z*47)/15, 123-(z*123)/15, 227-(z*227)/15);
else
color = FXRGB(200-(z*200)/15, 200-(z*200)/15, 200-(z*200)/15);
bmp->setPixel(2*x, 2*y, color);
bmp->setPixel(2*x+1, 2*y, color);
bmp->setPixel(2*x, 2*y+1, color);
bmp->setPixel(2*x+1, 2*y+1, color);
setPixel(x, y, color);
}
#else
if (lcd_buf[x+(y/8)*LCD_W] & (1<<(y%8))) {
bmp->setPixel(2*x, 2*y, onColor);
bmp->setPixel(2*x+1, 2*y, onColor);
bmp->setPixel(2*x, 2*y+1, onColor);
bmp->setPixel(2*x+1, 2*y+1, onColor);
setPixel(x, y, onColor);
}
#endif
else {
bmp->setPixel(2*x, 2*y, offColor);
bmp->setPixel(2*x+1, 2*y, offColor);
bmp->setPixel(2*x, 2*y+1, offColor);
bmp->setPixel(2*x+1, 2*y+1, offColor);
setPixel(x, y, offColor);
}
}
}

View file

@ -46,4 +46,11 @@
#define EEPROM_STR DEFNUMSTR(EEPROM_VER);
#endif
const pm_char vers_stamp[] PROGMEM = "VERS\037\033: " "opentx-" FLAVOUR "-" VERS_STR "\036DATE\037\033: " DATE_STR"\036TIME\037\033: " TIME_STR "\036EEPR\037\033: " EEPROM_STR;
#if defined(COLORLCD)
const pm_char vers_stamp[] PROGMEM = "VERS\037\050: " "opentx-" FLAVOUR "-" VERS_STR;
const pm_char date_stamp[] PROGMEM = "DATE\037\050: " DATE_STR;
const pm_char time_stamp[] PROGMEM = "TIME\037\050: " TIME_STR;
const pm_char eeprom_stamp[] PROGMEM = "EEPR\037\050: " EEPROM_STR;
#else
const pm_char vers_stamp[] PROGMEM = "VERS\037\033: " "opentx-" FLAVOUR "-" VERS_STR "\036DATE\037\033: " DATE_STR"\036TIME\037\033: " TIME_STR "\036EEPR\037\033: " EEPROM_STR;
#endif

View file

@ -116,7 +116,7 @@ uint8_t zlen(const char *str, uint8_t size)
return size;
}
char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx)
char *strcat_zchar(char * dest, const char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx)
{
int8_t len = 0;
@ -151,14 +151,36 @@ char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultN
#endif
#endif
#if defined(CPUARM) || defined(SDCARD)
char * strAppend(char * dest, const char * source)
#if defined(COLORLCD)
char *strAppendDigits(char *dest, int value)
{
while ((*dest++ = *source++))
;
div_t qr = div(value, 10);
*dest++ = '0' + qr.quot;
*dest++ = '0' + qr.rem;
*dest = '\0';
return dest;
}
#endif
#if defined(CPUARM) || defined(SDCARD)
char *strAppend(char *dest, const char *source, int len)
{
while ((*dest++ = *source++)) {
if (--len == 0) {
*dest++ = '\0';
}
}
return dest - 1;
}
char *strSetCursor(char *dest, int position)
{
*dest++ = 0x1F;
*dest++ = position;
*dest = '\0';
return dest;
}
char * strAppendFilename(char * dest, const char * filename, const int size)
{
memset(dest, 0, size);

View file

@ -515,9 +515,15 @@
#endif
// ZERO TERMINATED STRINGS
#define INDENT "\001"
#define LEN_INDENT 1
#define INDENT_WIDTH (FW/2)
#if defined(COLORLCD)
#define INDENT "\007"
#define LEN_INDENT 1
#define INDENT_WIDTH 12
#else
#define INDENT "\001"
#define LEN_INDENT 1
#define INDENT_WIDTH (FW/2)
#endif
#if defined(PCBTARANIS)
#define TR_ENTER "[ENTER]"
@ -649,9 +655,15 @@
#define TR_CAL "Cal"
#define TR_VTRIM "Trim- +"
#define TR_BG "BG:"
#define TR_MENUTOSTART CENTER "\010" TR_ENTER " TO START"
#define TR_SETMIDPOINT TR(CENTER "\004SET STICKS MIDPOINT",CENTER "\004CENTER STICKS/SLIDERS")
#define TR_MOVESTICKSPOTS CENTER "\006MOVE STICKS/POTS"
#if defined(COLORLCD)
#define TR_MENUTOSTART TR_ENTER " TO START"
#define TR_SETMIDPOINT "CENTER STICKS/SLIDERS"
#define TR_MOVESTICKSPOTS "MOVE STICKS/POTS"
#else
#define TR_MENUTOSTART CENTER "\010" TR_ENTER " TO START"
#define TR_SETMIDPOINT TR(CENTER "\004SET STICKS MIDPOINT", CENTER "\004CENTER STICKS/SLIDERS")
#define TR_MOVESTICKSPOTS CENTER "\006MOVE STICKS/POTS"
#endif
#define TR_RXBATT "Rx Batt:"
#define TR_TXnRX "Tx:\0Rx:"
#define OFS_RX 4
@ -694,11 +706,21 @@
#define TR_MENUDIAG TR("SWITCHES","SWITCH TEST")
#define TR_MENUANA TR("ANAS","ANALOG INPUTS")
#define TR_MENUCALIBRATION "CALIBRATION"
#define TR_TRIMS2OFFSETS "\006Trims => Subtrims"
#define TR_MENUMODELSEL TR("MODELSEL","MODEL SELECTION")
#define TR_MENUSETUP TR("SETUP","MODEL SETUP")
#if defined(COLORLCD)
#define TR_TRIMS2OFFSETS "Trims >> Subtrims"
#else
#define TR_TRIMS2OFFSETS "\006Trims => Subtrims"
#endif
#if defined(COLORLCD)
#define TR_MENUMODELSEL "Model Selection"
#define TR_MENUSETUP "Model Setup"
#define TR_MENUFLIGHTPHASES "Flight Modes"
#else
#define TR_MENUMODELSEL TR("MODELSEL", "MODEL SELECTION")
#define TR_MENUSETUP TR("SETUP", "MODEL SETUP")
#define TR_MENUFLIGHTPHASES "FLIGHT MODES"
#endif
#define TR_MENUFLIGHTPHASE "FLIGHT MODE"
#define TR_MENUFLIGHTPHASES "FLIGHT MODES"
#define TR_MENUHELISETUP "HELI SETUP"
#if defined(PCBTARANIS)

View file

@ -3,37 +3,47 @@
import sys
from PyQt4 import Qt, QtGui
from wx import Width
chars = u""" !"#$%&'()*+, ./0123456789:;<=>?°ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} """
chars = u""" !"#$%&'()*+,-./0123456789:;<=>?°ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz~ ≥→←↑↓ △Ⓘ"""
font = sys.argv[1]
size = int(sys.argv[2])
filename = sys.argv[3]
app = QtGui.QApplication(sys.argv)
font = QtGui.QFont(font)
font.setBold(True)
font.setPointSize(size)
metrics = QtGui.QFontMetrics(font)
width = 0
for c in chars:
def getCharWidth():
width = 0
for c in chars:
rect = metrics.boundingRect(c)
if rect.width() > width:
width = rect.width()
return width
image = QtGui.QImage(width*len(chars), size+4, QtGui.QImage.Format_RGB32)
image.fill(0xffffff)
painter = QtGui.QPainter()
painter.begin(image)
painter.setFont(font)
for i, c in enumerate(chars):
width = getCharWidth()
def createFontBitmap(filename, foreground, background):
image = QtGui.QImage(width*len(chars), size+4, QtGui.QImage.Format_RGB32)
image.fill(background)
painter = QtGui.QPainter()
painter.begin(image)
painter.setFont(font)
pen = QtGui.QPen(foreground)
painter.setPen(pen)
for i, c in enumerate(chars):
rect = metrics.boundingRect(c)
if i == 0:
rect.setWidth(4)
elif i == 14:
rect.setLeft(rect.left()+1)
rect.setWidth(1)
painter.drawText(width*i-rect.left(), size+1, c)
for j in range(rect.width(), width):
painter.drawLine(width*i+j, 0, width*i+j, width)
painter.end()
image.save(filename)
painter.drawLine(width*i+j, 0, width*i+j, size+4)
painter.end()
image.save(filename)
if len(sys.argv) == 4:
createFontBitmap(sys.argv[3], QtGui.QColor(0x00, 0x00, 0x00), QtGui.QColor(0xFF, 0xFF, 0xFF))