1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-17 13:25:15 +03:00

Bsongis/gui refactoring for x7 d (#3701)

* [X7D] New board added
* Cosmetics
This commit is contained in:
Bertrand Songis 2016-08-18 11:49:16 +02:00 committed by GitHub
parent 282b856309
commit d3ae3c035d
233 changed files with 7472 additions and 4560 deletions

View file

@ -154,23 +154,6 @@ enum FailsafeModes {
#define BC_BIT_REA (0x80) #define BC_BIT_REA (0x80)
#define BC_BIT_REB (0x100) #define BC_BIT_REB (0x100)
// TODO remove this enum!
enum EnumKeys {
KEY_MENU,
KEY_EXIT,
#if defined(PCBTARANIS)
KEY_ENTER,
KEY_PAGE,
KEY_PLUS,
KEY_MINUS,
#else
KEY_DOWN,
KEY_UP,
KEY_RIGHT,
KEY_LEFT,
#endif
};
#define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
#define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*" #define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*"

View file

@ -25,6 +25,7 @@
#undef max #undef max
#define NUM_POTS 3 #define NUM_POTS 3
#define NUM_SLIDERS 0
#define SWSRC_SW1 DSW_SW1 #define SWSRC_SW1 DSW_SW1
#include <exception> #include <exception>

View file

@ -32,6 +32,7 @@
#define REVB #define REVB
#define NUM_POTS 3 #define NUM_POTS 3
#define NUM_SLIDERS 0
#define SWSRC_SW1 DSW_SW1 #define SWSRC_SW1 DSW_SW1
#undef min #undef min

View file

@ -26,7 +26,7 @@
#define MAX_CUSTOM_FUNCTIONS(board, version) (IS_ARM(board) ? (version >= 216 ? 64 : 32) : (IS_DBLEEPROM(board, version) ? 24 : 16)) #define MAX_CUSTOM_FUNCTIONS(board, version) (IS_ARM(board) ? (version >= 216 ? 64 : 32) : (IS_DBLEEPROM(board, version) ? 24 : 16))
#define MAX_CURVES(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 216) ? 32 : 16) : 8) #define MAX_CURVES(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 216) ? 32 : 16) : 8)
#define MAX_GVARS(board, version) ((IS_ARM(board) && version >= 216) ? 9 : 5) #define MAX_GVARS(board, version) ((IS_ARM(board) && version >= 216) ? 9 : 5)
#define MAX_SENSORS(board, version) (32) #define MAX_TELEMETRY_SENSORS(board, version) (32)
#define NUM_PPM_INPUTS(board, version) ((IS_ARM(board) && version >= 216) ? 16 : 8) #define NUM_PPM_INPUTS(board, version) ((IS_ARM(board) && version >= 216) ? 16 : 8)
#define ROTENC_COUNT(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 218) ? 0 : 1) : (IS_2560(board) ? 2 : 0)) #define ROTENC_COUNT(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 218) ? 0 : 1) : (IS_2560(board) ? 2 : 0))
@ -3271,7 +3271,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne
} }
if (IS_ARM(board) && version >= 217) { if (IS_ARM(board) && version >= 217) {
for (int i=0; i<MAX_SENSORS(board, version); ++i) { for (int i=0; i<MAX_TELEMETRY_SENSORS(board, version); ++i) {
internalField.Append(new SensorField(modelData.sensorData[i], board, version)); internalField.Append(new SensorField(modelData.sensorData[i], board, version));
} }
} }

View file

@ -25,6 +25,7 @@
#undef max #undef max
#define NUM_POTS 3 #define NUM_POTS 3
#define NUM_SLIDERS 0
#define NUM_CSW 12 #define NUM_CSW 12
#define SWSRC_SW1 10 #define SWSRC_SW1 10

View file

@ -16,8 +16,8 @@
#include <stdint.h> #include <stdint.h>
#if !defined(NUM_LOGICAL_SWITCH) && defined(NUM_CSW) #if !defined(MAX_LOGICAL_SWITCHES) && defined(NUM_CSW)
#define NUM_LOGICAL_SWITCH NUM_CSW #define MAX_LOGICAL_SWITCHES NUM_CSW
#endif #endif
#ifdef INIT_IMPORT #ifdef INIT_IMPORT
@ -31,7 +31,7 @@ telemetryStreaming = 20;
#undef SETVALUES_IMPORT #undef SETVALUES_IMPORT
for (int i=0; i<NUM_STICKS; i++) for (int i=0; i<NUM_STICKS; i++)
g_anas[i] = inputs.sticks[i]; g_anas[i] = inputs.sticks[i];
for (int i=0; i<NUM_POTS; i++) for (int i=0; i<NUM_POTS+NUM_SLIDERS; i++)
g_anas[NUM_STICKS+i] = inputs.pots[i]; g_anas[NUM_STICKS+i] = inputs.pots[i];
for (int i=0; i<C9X_NUM_SWITCHES; i++) for (int i=0; i<C9X_NUM_SWITCHES; i++)
simuSetSwitch(i, inputs.switches[i]); simuSetSwitch(i, inputs.switches[i]);
@ -60,7 +60,7 @@ if (inputs.rotenc) simuSetKey(KEY_ENTER, true);
memset(outputs.chans, 0, sizeof(outputs.chans)); memset(outputs.chans, 0, sizeof(outputs.chans));
for (unsigned int i=0; i<DIM(g_chans512); i++) for (unsigned int i=0; i<DIM(g_chans512); i++)
outputs.chans[i] = g_chans512[i]; outputs.chans[i] = g_chans512[i];
for (int i=0; i<NUM_LOGICAL_SWITCH; i++) for (int i=0; i<MAX_LOGICAL_SWITCHES; i++)
#if defined(BOLD_FONT) #if defined(BOLD_FONT)
outputs.vsw[i] = getSwitch(SWSRC_SW1+i); outputs.vsw[i] = getSwitch(SWSRC_SW1+i);
#else #else

View file

@ -18,10 +18,11 @@ option(FAI "Competition mode (no telemetry)" OFF)
option(AUTOSOURCE "Automatic source detection in menus" ON) option(AUTOSOURCE "Automatic source detection in menus" ON)
option(AUTOSWITCH "Automatic switch detection in menus" ON) option(AUTOSWITCH "Automatic switch detection in menus" ON)
option(JITTER_MEASURE "Enable ADC jitter measurement" OFF) option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
option(WATCHDOG_DISABLED "Disable hardware Watchdog on Horus" OFF) # TODO remove it when it's OK option(WATCHDOG_DISABLED "Disable hardware Watchdog" OFF)
option(SIMU_AUDIO "Enable simulator audio" OFF) option(SIMU_AUDIO "Enable simulator audio" OFF)
option(SIMU_DISKIO "Enable disk IO simulation in simulator. Simulator will use FatFs module and simulated IO layer that uses \"./sdcard.image\" file as image of SD card. This file must contain whole SD card from first to last sector" OFF) option(SIMU_DISKIO "Enable disk IO simulation in simulator. Simulator will use FatFs module and simulated IO layer that uses \"./sdcard.image\" file as image of SD card. This file must contain whole SD card from first to last sector" OFF)
option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF) option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF)
option(TEMPLATES "Model templates menu" OFF)
enable_language(ASM) enable_language(ASM)
set(OPT s) set(OPT s)
@ -40,7 +41,6 @@ configure_file(stamp.h.in stamp.h @ONLY)
add_subdirectory(translations) add_subdirectory(translations)
add_subdirectory(bitmaps) add_subdirectory(bitmaps)
add_subdirectory(fonts) add_subdirectory(fonts)
add_subdirectory(lua)
set(EEPROM_VARIANT 0) set(EEPROM_VARIANT 0)
set(GVARS_VARIANT 1) set(GVARS_VARIANT 1)
@ -52,12 +52,6 @@ set(M128_VARIANT 32768)
set(FIRMWARE_DEPENDENCIES firmware_translations) set(FIRMWARE_DEPENDENCIES firmware_translations)
set(9X_GUI_SRC
model_inputs_mixes.cpp
radio_diagkeys.cpp
radio_diaganas.cpp
)
set(FATFS_SRC set(FATFS_SRC
${FATFS_DIR}/ff.c ${FATFS_DIR}/ff.c
${FATFS_DIR}/fattime.c ${FATFS_DIR}/fattime.c
@ -83,7 +77,11 @@ elseif(PCB STREQUAL 9X2561)
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps) set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561) add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561)
set(TARGET_SRC ${TARGET_SRC} board.cpp) set(TARGET_SRC ${TARGET_SRC} board.cpp)
set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC}) set(GUI_SRC
${GUI_SRC}
model_inputs_mixes.cpp
radio_diagkeys.cpp
radio_diaganas.cpp)
if(SP22) if(SP22)
add_definitions(-DSP22) add_definitions(-DSP22)
endif() endif()
@ -99,8 +97,6 @@ else()
message(FATAL_ERROR "Unknown PCB '${PCB}'") message(FATAL_ERROR "Unknown PCB '${PCB}'")
endif() endif()
include_directories(gui gui/${GUI_DIR})
if(NOT PCB STREQUAL 9XR AND NOT PCB STREQUAL 9XRPRO) if(NOT PCB STREQUAL 9XR AND NOT PCB STREQUAL 9XRPRO)
option(DBLKEYS "Double Keys" ON) option(DBLKEYS "Double Keys" ON)
if(DBLKEYS) if(DBLKEYS)
@ -157,47 +153,14 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR})
set(GUI_SRC add_subdirectory(lua)
${GUI_SRC} include(gui/CMakeLists.txt)
lcd.cpp
splash.cpp
fonts.cpp
navigation.cpp
popups.cpp
widgets.cpp
menus.cpp
)
set(GUI_SRC
${GUI_SRC}
menu_model.cpp
model_select.cpp
model_setup.cpp
model_outputs.cpp
model_logical_switches.cpp
model_special_functions.cpp
model_telemetry.cpp
menu_radio.cpp
radio_setup.cpp
radio_trainer.cpp
radio_version.cpp
radio_calibration.cpp
view_main.cpp
view_statistics.cpp
)
if(RAMBACKUP) if(RAMBACKUP)
add_definitions(-DRAMBACKUP) add_definitions(-DRAMBACKUP)
set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp) set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp)
endif() endif()
if(VIRTUAL_INPUTS)
add_definitions(-DVIRTUALINPUTS)
set(TEMPLATES OFF)
else()
option(TEMPLATES "Model Templates Menu" ON)
endif()
if(TEMPLATES) if(TEMPLATES)
add_definitions(-DTEMPLATES) add_definitions(-DTEMPLATES)
set(SRC ${SRC} templates.cpp) set(SRC ${SRC} templates.cpp)
@ -224,7 +187,6 @@ endif()
if(HELI) if(HELI)
add_definitions(-DHELI) add_definitions(-DHELI)
set(GUI_SRC ${GUI_SRC} model_heli.cpp)
endif() endif()
if(FLIGHT_MODES) if(FLIGHT_MODES)
@ -234,7 +196,6 @@ endif()
if(CURVES) if(CURVES)
add_definitions(-DCURVES) add_definitions(-DCURVES)
set(GUI_SRC ${GUI_SRC} model_curves.cpp)
endif() endif()
if(GVARS) if(GVARS)
@ -318,13 +279,19 @@ set(SRC
functions.cpp functions.cpp
strhelpers.cpp strhelpers.cpp
switches.cpp switches.cpp
curves.cpp
mixer.cpp mixer.cpp
stamp.cpp stamp.cpp
timers.cpp timers.cpp
trainer_input.cpp trainer_input.cpp
) )
if(CURVES)
set(SRC
${SRC}
curves.cpp
)
endif()
if(GUI) if(GUI)
add_definitions(-DGUI) add_definitions(-DGUI)
set(SRC set(SRC
@ -402,7 +369,7 @@ endif()
set(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CPP_FLAGS} -g") set(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CPP_FLAGS} -g")
set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections") set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections")
if(PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E) if(PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X7D)
add_subdirectory(targets/${TARGET_DIR}/bootloader) add_subdirectory(targets/${TARGET_DIR}/bootloader)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/${TARGET_DIR}/bootloader) include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/${TARGET_DIR}/bootloader)
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader) set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader)

View file

@ -388,7 +388,7 @@ void referenceModelAudioFiles()
} }
// Logical Switches Audio Files <switchname>-[on|off].wav // Logical Switches Audio Files <switchname>-[on|off].wav
for (int i=0; i<NUM_LOGICAL_SWITCH && !found; i++) { for (int i=0; i<MAX_LOGICAL_SWITCHES && !found; i++) {
for (int event=0; event<2; event++) { for (int event=0; event<2; event++) {
getLogicalSwitchAudioFile(path, i, event); getLogicalSwitchAudioFile(path, i, event);
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn); // TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn);

View file

@ -500,18 +500,18 @@ int cliDisplay(const char ** argv)
uint8_t len = STR_VKEYS[0]; uint8_t len = STR_VKEYS[0];
strncpy(name, STR_VKEYS+1+len*i, len); strncpy(name, STR_VKEYS+1+len*i, len);
name[len] = '\0'; name[len] = '\0';
serialPrint("[%s] = %s", name, switchState(EnumKeys(i)) ? "on" : "off"); serialPrint("[%s] = %s", name, keyState(i) ? "on" : "off");
} }
#if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBX9E) || defined(PCBHORUS) || defined(PCBFLAMENCO) #if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBX9E) || defined(PCBHORUS) || defined(PCBFLAMENCO)
serialPrint("[Enc.] = %d", rotencValue / 2); serialPrint("[Enc.] = %d", rotencValue / 2);
#endif #endif
for (int i=TRM_BASE; i<=TRM_LAST; i++) { for (int i=TRM_BASE; i<=TRM_LAST; i++) {
serialPrint("[Trim%d] = %s", i-TRM_BASE, switchState(EnumKeys(i)) ? "on" : "off"); serialPrint("[Trim%d] = %s", i-TRM_BASE, keyState(i) ? "on" : "off");
} }
for (int i=MIXSRC_FIRST_SWITCH; i<=MIXSRC_LAST_SWITCH; i++) { for (int i=MIXSRC_FIRST_SWITCH; i<=MIXSRC_LAST_SWITCH; i++) {
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH; mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
if (SWITCH_EXISTS(sw)) { if (SWITCH_EXISTS(sw)) {
serialPrint("[S%c] = %s", 'A'+sw, (switchState((EnumKeys)(SW_BASE+(3*sw))) ? "down" : (switchState((EnumKeys)(SW_BASE+(3*sw)+1)) ? "mid" : "up"))); serialPrint("[S%c] = %s", 'A'+sw, (switchState(3*sw) ? "down" : (switchState(3*sw+1) ? "mid" : "up")));
} }
} }
} }
@ -521,7 +521,7 @@ int cliDisplay(const char ** argv)
} }
} }
else if (!strcmp(argv[1], "outputs")) { else if (!strcmp(argv[1], "outputs")) {
for (int i=0; i<NUM_CHNOUT; i++) { for (int i=0; i<MAX_OUTPUT_CHANNELS; i++) {
serialPrint("outputs[%d] = %04d", i, (int)channelOutputs[i]); serialPrint("outputs[%d] = %04d", i, (int)channelOutputs[i]);
} }
} }
@ -533,7 +533,7 @@ int cliDisplay(const char ** argv)
else if (!strcmp(argv[1], "volume")) { else if (!strcmp(argv[1], "volume")) {
serialPrint("volume = %d", getVolume()); serialPrint("volume = %d", getVolume());
} }
#if defined(CPUSTM32) #if defined(STM32)
else if (!strcmp(argv[1], "uid")) { else if (!strcmp(argv[1], "uid")) {
char str[LEN_CPU_UID+1]; char str[LEN_CPU_UID+1];
getCPUUniqueID(str); getCPUUniqueID(str);

View file

@ -20,8 +20,10 @@
#include "opentx.h" #include "opentx.h"
#if defined(XCURVES) uint8_t s_curveChan;
int8_t *curveEnd[MAX_CURVES];
#if defined(CPUARM)
int8_t * curveEnd[MAX_CURVES];
void loadCurves() void loadCurves()
{ {
int8_t * tmp = g_model.points; int8_t * tmp = g_model.points;
@ -42,12 +44,43 @@ void loadCurves()
curveEnd[i] = tmp; curveEnd[i] = tmp;
} }
} }
int8_t *curveAddress(uint8_t idx)
int8_t * curveAddress(uint8_t idx)
{ {
return idx==0 ? g_model.points : curveEnd[idx-1]; return idx==0 ? g_model.points : curveEnd[idx-1];
} }
bool moveCurve(uint8_t index, int8_t shift) // TODO bool?
{
if (curveEnd[MAX_CURVES-1] + shift > g_model.points + sizeof(g_model.points)) {
AUDIO_WARNING2();
return false;
}
int8_t * nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+curveEnd[MAX_CURVES-1]-curveEnd[index]);
if (shift < 0) memclear(&g_model.points[MAX_CURVE_POINTS-1] + shift, -shift);
while (index<MAX_CURVES) {
curveEnd[index++] += shift;
}
storageDirty(EE_MODEL);
return true;
}
int8_t getCurveX(int noPoints, int point)
{
return -100 + div_and_round((point*2000) / (noPoints-1), 10);
}
void resetCustomCurveX(int8_t * points, int noPoints)
{
for (int i=0; i<noPoints-2; i++) {
points[noPoints+i] = getCurveX(noPoints, i+1);
}
}
#else #else
int8_t *curveAddress(uint8_t idx) int8_t * curveAddress(uint8_t idx)
{ {
return &g_model.points[idx==0 ? 0 : 5*idx+g_model.curves[idx-1]]; return &g_model.points[idx==0 ? 0 : 5*idx+g_model.curves[idx-1]];
} }
@ -68,13 +101,41 @@ CurveInfo curveInfo(uint8_t idx)
} }
return result; return result;
} }
bool moveCurve(uint8_t index, int8_t shift, int8_t custom) // TODO move?
{
if (g_model.curves[MAX_CURVES-1] + shift > MAX_CURVE_POINTS-5*MAX_CURVES) {
AUDIO_WARNING2();
return false;
}
int8_t * crv = curveAddress(index);
if (shift < 0) {
for (uint8_t i=0; i<custom; i++)
crv[i] = crv[2*i];
}
int8_t * nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+g_model.curves[MAX_CURVES-1]-g_model.curves[index]);
if (shift < 0) memclear(&g_model.points[MAX_CURVE_POINTS-1] + shift, -shift);
while (index<MAX_CURVES) {
g_model.curves[index++] += shift;
}
for (uint8_t i=0; i<custom-2; i++) {
crv[custom + i] = -100 + ((200 * (i + 1) + custom / 2) / (custom - 1));
}
storageDirty(EE_MODEL);
return true;
}
#endif #endif
#if defined(XCURVES) #if defined(CPUARM)
#define CUSTOM_POINT_X(points, count, idx) ((idx)==0 ? -100 : (((idx)==(count)-1) ? 100 : points[(count)+(idx)-1])) #define CUSTOM_POINT_X(points, count, idx) ((idx)==0 ? -100 : (((idx)==(count)-1) ? 100 : points[(count)+(idx)-1]))
s32 compute_tangent(CurveInfo * crv, int8_t * points, int i) int32_t compute_tangent(CurveInfo * crv, int8_t * points, int i)
{ {
s32 m=0; int32_t m=0;
uint8_t num_points = crv->points + 5; uint8_t num_points = crv->points + 5;
#define MMULT 1024 #define MMULT 1024
if (i == 0) { if (i == 0) {
@ -86,7 +147,7 @@ s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
if (x1 > x0) m = (MMULT * (points[1] - points[0])) / (x1 - x0); if (x1 > x0) m = (MMULT * (points[1] - points[0])) / (x1 - x0);
} }
else { else {
s32 delta = (2 * 100) / (num_points - 1); int32_t delta = (2 * 100) / (num_points - 1);
m = (MMULT * (points[1] - points[0])) / delta; m = (MMULT * (points[1] - points[0])) / delta;
} }
} }
@ -99,7 +160,7 @@ s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
if (x1 > x0) m = (MMULT * (points[num_points-1] - points[num_points-2])) / (x1 - x0); if (x1 > x0) m = (MMULT * (points[num_points-1] - points[num_points-2])) / (x1 - x0);
} }
else { else {
s32 delta = (2 * 100) / (num_points - 1); int32_t delta = (2 * 100) / (num_points - 1);
m = (MMULT * (points[num_points-1] - points[num_points-2])) / delta; m = (MMULT * (points[num_points-1] - points[num_points-2])) / delta;
} }
} }
@ -107,7 +168,7 @@ s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
//apply monotone rules from //apply monotone rules from
//http://en.wikipedia.org/wiki/Monotone_cubic_interpolation //http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
//1) compute slopes of secant lines //1) compute slopes of secant lines
s32 d0=0, d1=0; int32_t d0=0, d1=0;
if (crv->type == CURVE_TYPE_CUSTOM) { if (crv->type == CURVE_TYPE_CUSTOM) {
int8_t x0 = CUSTOM_POINT_X(points, num_points, i-1); int8_t x0 = CUSTOM_POINT_X(points, num_points, i-1);
int8_t x1 = CUSTOM_POINT_X(points, num_points, i); int8_t x1 = CUSTOM_POINT_X(points, num_points, i);
@ -116,7 +177,7 @@ s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
if (x2 > x1) d1 = (MMULT * (points[i+1] - points[i])) / (x2 - x1); if (x2 > x1) d1 = (MMULT * (points[i+1] - points[i])) / (x2 - x1);
} }
else { else {
s32 delta = (2 * 100) / (num_points - 1); int32_t delta = (2 * 100) / (num_points - 1);
d0 = (MMULT * (points[i] - points[i-1])) / (delta); d0 = (MMULT * (points[i] - points[i-1])) / (delta);
d1 = (MMULT * (points[i+1] - points[i])) / (delta); d1 = (MMULT * (points[i+1] - points[i])) / (delta);
} }
@ -154,7 +215,7 @@ int16_t hermite_spline(int16_t x, uint8_t idx)
x = RESX; x = RESX;
for (int i=0; i<count-1; i++) { for (int i=0; i<count-1; i++) {
s32 p0x, p3x; int32_t p0x, p3x;
if (custom) { if (custom) {
p0x = (i>0 ? calc100toRESX(points[count+i-1]) : -RESX); p0x = (i>0 ? calc100toRESX(points[count+i-1]) : -RESX);
p3x = (i<count-2 ? calc100toRESX(points[count+i]) : RESX); p3x = (i<count-2 ? calc100toRESX(points[count+i]) : RESX);
@ -165,19 +226,19 @@ int16_t hermite_spline(int16_t x, uint8_t idx)
} }
if (x >= p0x && x <= p3x) { if (x >= p0x && x <= p3x) {
s32 p0y = calc100toRESX(points[i]); int32_t p0y = calc100toRESX(points[i]);
s32 p3y = calc100toRESX(points[i+1]); int32_t p3y = calc100toRESX(points[i+1]);
s32 m0 = compute_tangent(&crv, points, i); int32_t m0 = compute_tangent(&crv, points, i);
s32 m3 = compute_tangent(&crv, points, i+1); int32_t m3 = compute_tangent(&crv, points, i+1);
s32 y; int32_t y;
s32 h = p3x - p0x; int32_t h = p3x - p0x;
s32 t = (h > 0 ? (MMULT * (x - p0x)) / h : 0); int32_t t = (h > 0 ? (MMULT * (x - p0x)) / h : 0);
s32 t2 = t * t / MMULT; int32_t t2 = t * t / MMULT;
s32 t3 = t2 * t / MMULT; int32_t t3 = t2 * t / MMULT;
s32 h00 = 2*t3 - 3*t2 + MMULT; int32_t h00 = 2*t3 - 3*t2 + MMULT;
s32 h10 = t3 - 2*t2 + t; int32_t h10 = t3 - 2*t2 + t;
s32 h01 = -2*t3 + 3*t2; int32_t h01 = -2*t3 + 3*t2;
s32 h11 = t3 - t2; int32_t h11 = t3 - t2;
y = p0y * h00 + h * (m0 * h10 / MMULT) + p3y * h01 + h * (m3 * h11 / MMULT); y = p0y * h00 + h * (m0 * h10 / MMULT) + p3y * h01 + h * (m3 * h11 / MMULT);
y /= MMULT; y /= MMULT;
return y; return y;
@ -189,14 +250,14 @@ int16_t hermite_spline(int16_t x, uint8_t idx)
int intpol(int x, uint8_t idx) // -100, -75, -50, -25, 0 ,25 ,50, 75, 100 int intpol(int x, uint8_t idx) // -100, -75, -50, -25, 0 ,25 ,50, 75, 100
{ {
#if defined(XCURVES) #if defined(CPUARM)
CurveInfo &crv = g_model.curves[idx]; CurveInfo & crv = g_model.curves[idx];
int8_t *points = curveAddress(idx); int8_t * points = curveAddress(idx);
uint8_t count = crv.points+5; uint8_t count = crv.points+5;
bool custom = (crv.type == CURVE_TYPE_CUSTOM); bool custom = (crv.type == CURVE_TYPE_CUSTOM);
#else #else
CurveInfo crv = curveInfo(idx); CurveInfo crv = curveInfo(idx);
int8_t *points = crv.crv; int8_t * points = crv.crv;
uint8_t count = crv.points; uint8_t count = crv.points;
bool custom = crv.custom; bool custom = crv.custom;
#endif #endif
@ -232,36 +293,23 @@ int intpol(int x, uint8_t idx) // -100, -75, -50, -25, 0 ,25 ,50, 75, 100
return erg / 25; // 100*D5/RESX; return erg / 25; // 100*D5/RESX;
} }
#if defined(CURVES) && defined(XCURVES) #if defined(CPUARM)
int applyCurve(int x, CurveRef & curve) int applyCurve(int x, CurveRef & curve)
{ {
switch (curve.type) { switch (curve.type) {
case CURVE_REF_DIFF: case CURVE_REF_DIFF:
{ {
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode); int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode);
if (curveParam > 0 && x < 0) if (curveParam > 0 && x < 0)
x = (x * (1000 - curveParam)) / 1000; x = (x * (1000 - curveParam)) / 1000;
else if (curveParam < 0 && x > 0) else if (curveParam < 0 && x > 0)
x = (x * (1000 + curveParam)) / 1000; x = (x * (1000 + curveParam)) / 1000;
return x; return x;
#else
int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode));
if (curveParam > 0 && x < 0)
x = (x * (256 - curveParam)) >> 8;
else if (curveParam < 0 && x > 0)
x = (x * (256 + curveParam)) >> 8;
return x;
#endif
} }
case CURVE_REF_EXPO: case CURVE_REF_EXPO:
{ {
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode) / 10; int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode) / 10;
#else
int curveParam = GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode);
#endif
return expo(x, curveParam); return expo(x, curveParam);
} }
@ -306,13 +354,13 @@ int applyCustomCurve(int x, uint8_t idx)
if (idx >= MAX_CURVES) if (idx >= MAX_CURVES)
return 0; return 0;
CurveInfo &crv = g_model.curves[idx]; CurveInfo & crv = g_model.curves[idx];
if (crv.smooth) if (crv.smooth)
return hermite_spline(x, idx); return hermite_spline(x, idx);
else else
return intpol(x, idx); return intpol(x, idx);
} }
#elif defined(CURVES) #else
int applyCurve(int x, int8_t idx) int applyCurve(int x, int8_t idx)
{ {
/* already tried to have only one return at the end */ /* already tried to have only one return at the end */
@ -435,3 +483,32 @@ int expo(int x, int k)
} }
return neg? -y : y; return neg? -y : y;
} }
point_t getPoint(uint8_t i)
{
point_t result = {0, 0};
#if defined(CPUARM)
CurveInfo & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan);
bool custom = (crv.type == CURVE_TYPE_CUSTOM);
uint8_t count = 5+crv.points;
#else
CurveInfo crv = curveInfo(s_curveChan);
int8_t * points = crv.crv;
bool custom = crv.custom;
uint8_t count = crv.points;
#endif
if (i < count) {
result.x = CURVE_CENTER_X-1-CURVE_SIDE_WIDTH + i*CURVE_SIDE_WIDTH*2/(count-1);
result.y = CURVE_CENTER_Y - (points[i]) * (CURVE_SIDE_WIDTH-1) / 100;
if (custom && i>0 && i<count-1) {
result.x = CURVE_CENTER_X - 1 - CURVE_SIDE_WIDTH + (100 + (100 + points[count + i - 1]) * (2 * CURVE_SIDE_WIDTH)) / 200;
}
}
return result;
}
int applyCurrentCurve(int x)
{
return applyCustomCurve(x, s_curveChan);
}

View file

@ -21,6 +21,10 @@
#ifndef _DATACONSTANTS_H_ #ifndef _DATACONSTANTS_H_
#define _DATACONSTANTS_H_ #define _DATACONSTANTS_H_
#include "board.h"
#define NUM_STICKS 4
#if defined(EXPORT) #if defined(EXPORT)
#define LUA_EXPORT(...) LEXP(__VA_ARGS__) #define LUA_EXPORT(...) LEXP(__VA_ARGS__)
#define LUA_EXPORT_MULTIPLE(...) LEXP_MULTIPLE(__VA_ARGS__) #define LUA_EXPORT_MULTIPLE(...) LEXP_MULTIPLE(__VA_ARGS__)
@ -31,104 +35,87 @@
#define LUA_EXPORT_EXTRA(...) #define LUA_EXPORT_EXTRA(...)
#endif #endif
#define NUM_STICKS 4
#if defined(PCBHORUS) #if defined(PCBHORUS)
#define MAX_MODELS 60 #define MAX_MODELS 60
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9 #define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64 #define MAX_MIXERS 64
#define MAX_EXPOS 64 #define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 64 // number of custom switches #define MAX_LOGICAL_SWITCHES 64
#define NUM_CFN 64 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 9 #define MAX_SCRIPTS 9
#define MAX_INPUTS 32 #define MAX_INPUTS 32
#define NUM_TRAINER 16 #define MAX_TRAINER_CHANNELS 16
#define NUM_POTS 7 #define MAX_TELEMETRY_SENSORS 32
#define NUM_XPOTS 3
#define MAX_SENSORS 32
#define MAX_CUSTOM_SCREENS 5 #define MAX_CUSTOM_SCREENS 5
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
#define MAX_MODELS 60 #define MAX_MODELS 60
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9 #define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64 #define MAX_MIXERS 64
#define MAX_EXPOS 64 #define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 32 // number of custom switches #define MAX_LOGICAL_SWITCHES 32
#define NUM_CFN 64 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 7 #define MAX_SCRIPTS 7
#define MAX_INPUTS 32 #define MAX_INPUTS 32
#define NUM_TRAINER 16 #define MAX_TRAINER_CHANNELS 16
#define NUM_POTS 4 #define NUM_POTS 4 // TODO board.h
#define NUM_XPOTS 0 #define NUM_SLIDERS 0 // TODO board.h
#define MAX_SENSORS 32 #define NUM_XPOTS 0 // TODO board.h
#define MAX_TELEMETRY_SENSORS 32
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#define MAX_MODELS 60 #define MAX_MODELS 60
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9 #define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64 #define MAX_MIXERS 64
#define MAX_EXPOS 64 #define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 64 // number of logical switches #define MAX_LOGICAL_SWITCHES 64
#define NUM_CFN 64 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 7 #define MAX_SCRIPTS 7
#define MAX_INPUTS 32 #define MAX_INPUTS 32
#define NUM_TRAINER 16 #define MAX_TRAINER_CHANNELS 16
#if defined(PCBX9E) #define MAX_TELEMETRY_SENSORS 32
#define NUM_POTS 8
#define NUM_XPOTS 4
#else
#define NUM_POTS 5
#define NUM_XPOTS 3
#endif
#define MAX_SENSORS 32
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
#define MAX_MODELS 60 #define MAX_MODELS 60
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9 #define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64 #define MAX_MIXERS 64
#define MAX_EXPOS 32 #define MAX_EXPOS 32
#define NUM_LOGICAL_SWITCH 64 // number of custom switches #define MAX_LOGICAL_SWITCHES 64
#define NUM_CFN 64 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define NUM_TRAINER 16 #define MAX_INPUTS 32
#define NUM_POTS 3 #define MAX_TRAINER_CHANNELS 16
#define NUM_XPOTS 0 #define MAX_TELEMETRY_SENSORS 32
#define MAX_SENSORS 32
#elif defined(CPUM2560) || defined(CPUM2561) #elif defined(CPUM2560) || defined(CPUM2561)
#define MAX_MODELS 30 #define MAX_MODELS 30
#define NUM_CHNOUT 16 // number of real output channels CH1-CH16 #define MAX_OUTPUT_CHANNELS 16 // number of real output channels CH1-CH16
#define MAX_FLIGHT_MODES 6 #define MAX_FLIGHT_MODES 6
#define MAX_MIXERS 32 #define MAX_MIXERS 32
#define MAX_EXPOS 16 #define MAX_EXPOS 16
#define NUM_LOGICAL_SWITCH 12 // number of custom switches #define MAX_LOGICAL_SWITCHES 12
#define NUM_CFN 24 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 24 // number of functions assigned to switches
#define NUM_TRAINER 8 #define MAX_TRAINER_CHANNELS 8
#define NUM_POTS 3 #define MAX_TELEMETRY_SENSORS 0
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#elif defined(CPUM128) #elif defined(CPUM128)
#define MAX_MODELS 30 #define MAX_MODELS 30
#define NUM_CHNOUT 16 // number of real output channels CH1-CH16 #define MAX_OUTPUT_CHANNELS 16 // number of real output channels CH1-CH16
#define MAX_FLIGHT_MODES 5 #define MAX_FLIGHT_MODES 5
#define MAX_MIXERS 32 #define MAX_MIXERS 32
#define MAX_EXPOS 14 #define MAX_EXPOS 14
#define NUM_LOGICAL_SWITCH 12 // number of custom switches #define MAX_LOGICAL_SWITCHES 12
#define NUM_CFN 24 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 24 // number of functions assigned to switches
#define NUM_TRAINER 8 #define MAX_TRAINER_CHANNELS 8
#define NUM_POTS 3 #define MAX_TELEMETRY_SENSORS 0
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#else #else
#define MAX_MODELS 16 #define MAX_MODELS 16
#define NUM_CHNOUT 16 // number of real output channels CH1-CH16 #define MAX_OUTPUT_CHANNELS 16 // number of real output channels CH1-CH16
#define MAX_FLIGHT_MODES 5 #define MAX_FLIGHT_MODES 5
#define MAX_MIXERS 32 #define MAX_MIXERS 32
#define MAX_EXPOS 14 #define MAX_EXPOS 14
#define NUM_LOGICAL_SWITCH 12 // number of custom switches #define MAX_LOGICAL_SWITCHES 12
#define NUM_CFN 16 // number of functions assigned to switches #define MAX_SPECIAL_FUNCTIONS 16 // number of functions assigned to switches
#define NUM_TRAINER 8 #define MAX_TRAINER_CHANNELS 8
#define NUM_POTS 3 #define MAX_TELEMETRY_SENSORS 0
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
@ -146,8 +133,13 @@ enum CurveType {
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
}; };
#define MIN_POINTS 3 #if defined(CPUARM)
#define MAX_POINTS 17 #define MIN_POINTS_PER_CURVE 3
#else
#define MIN_POINTS_PER_CURVE 3
#endif
#define MAX_POINTS_PER_CURVE 17
#if defined(PCBHORUS) #if defined(PCBHORUS)
#define LEN_MODEL_NAME 15 #define LEN_MODEL_NAME 15
@ -158,9 +150,9 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3 #define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 6 #define LEN_FUNCTION_NAME 6
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define MAX_CURVE_POINTS 512
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
#define LEN_MODEL_NAME 12 #define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8 #define LEN_TIMER_NAME 8
@ -169,9 +161,20 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3 #define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8 #define LEN_FUNCTION_NAME 8
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define MAX_CURVE_POINTS 512
#elif defined(PCBSKY9X) || defined(PCBX7D)
#define LEN_MODEL_NAME 10
#define LEN_TIMER_NAME 3
#define LEN_FLIGHT_MODE_NAME 6
#define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 3
#define LEN_CURVE_NAME 3
#define LEN_FUNCTION_NAME 6
#define MAX_CURVES 16
#define MAX_CURVE_POINTS 512
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#define LEN_MODEL_NAME 12 #define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8 #define LEN_TIMER_NAME 8
@ -181,22 +184,14 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6 #define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4 #define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3 #define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8 #define LEN_FUNCTION_NAME 8
#define MAX_CURVES 32 #define MAX_CURVES 32
#define NUM_POINTS 512 #define MAX_CURVE_POINTS 512
#elif defined(CPUARM)
#define LEN_MODEL_NAME 10
#define LEN_TIMER_NAME 3
#define LEN_FLIGHT_MODE_NAME 6
#define LEN_EXPOMIX_NAME 6
#define LEN_CFN_NAME 6
#define MAX_CURVES 16
#define NUM_POINTS 512
#else #else
#define LEN_MODEL_NAME 10 #define LEN_MODEL_NAME 10
#define LEN_FLIGHT_MODE_NAME 6 #define LEN_FLIGHT_MODE_NAME 6
#define MAX_CURVES 8 #define MAX_CURVES 8
#define NUM_POINTS (112-MAX_CURVES) #define MAX_CURVE_POINTS (112-MAX_CURVES)
#endif #endif
#if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS) #if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS)
@ -206,13 +201,7 @@ enum CurveType {
#endif #endif
#if defined(PCBFLAMENCO) #if defined(PCBFLAMENCO)
#define NUM_SWITCHES 5 #define NUM_SWITCHES 5 // TODO in board.h
#elif defined(PCBX9E)
#define NUM_SWITCHES 18 // yes, it's a lot!
#elif defined(PCBTARANIS) || defined(PCBHORUS)
#define NUM_SWITCHES 8
#else
#define NUM_SWITCHES 7
#endif #endif
#define XPOTS_MULTIPOS_COUNT 6 #define XPOTS_MULTIPOS_COUNT 6
@ -250,7 +239,7 @@ enum MainViews {
VIEW_TELEM4, VIEW_TELEM4,
VIEW_COUNT VIEW_COUNT
}; };
#elif defined(PCBTARANIS) #elif LCD_W >= 212
enum MainViews { enum MainViews {
VIEW_TIMERS, VIEW_TIMERS,
VIEW_INPUTS, VIEW_INPUTS,
@ -325,10 +314,7 @@ enum UartModes {
#define LEN_ANA_NAME 3 #define LEN_ANA_NAME 3
#define LEN_MODEL_FILENAME 16 #define LEN_MODEL_FILENAME 16
#define LEN_BLUETOOTH_NAME 10 #define LEN_BLUETOOTH_NAME 10
#elif defined(PCBFLAMENCO) #elif defined(CPUARM)
#define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3
#elif defined(PCBTARANIS)
#define LEN_SWITCH_NAME 3 #define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3 #define LEN_ANA_NAME 3
#define LEN_BLUETOOTH_NAME 10 #define LEN_BLUETOOTH_NAME 10
@ -487,7 +473,7 @@ enum TelemetryUnit {
}; };
#endif #endif
#if defined(PCBTARANIS) #if LCD_W >= 212
#define NUM_LINE_ITEMS 3 #define NUM_LINE_ITEMS 3
#else #else
#define NUM_LINE_ITEMS 2 #define NUM_LINE_ITEMS 2
@ -699,7 +685,7 @@ enum SwitchSources {
SWSRC_SWA, SWSRC_SWA,
SWSRC_SWB, SWSRC_SWB,
SWSRC_SWC, SWSRC_SWC,
SWSRC_LAST_LOGICAL_SWITCH = SWSRC_FIRST_LOGICAL_SWITCH+NUM_LOGICAL_SWITCH-1, SWSRC_LAST_LOGICAL_SWITCH = SWSRC_FIRST_LOGICAL_SWITCH+MAX_LOGICAL_SWITCHES-1,
SWSRC_ON, SWSRC_ON,
SWSRC_ONE, SWSRC_ONE,
@ -710,7 +696,7 @@ enum SwitchSources {
SWSRC_TELEMETRY_STREAMING, SWSRC_TELEMETRY_STREAMING,
SWSRC_FIRST_SENSOR, SWSRC_FIRST_SENSOR,
SWSRC_LAST_SENSOR = SWSRC_FIRST_SENSOR+MAX_SENSORS-1, SWSRC_LAST_SENSOR = SWSRC_FIRST_SENSOR+MAX_TELEMETRY_SENSORS-1,
#endif #endif
SWSRC_COUNT, SWSRC_COUNT,
@ -739,10 +725,12 @@ enum SwitchSources {
enum MixSources { enum MixSources {
MIXSRC_NONE, MIXSRC_NONE,
#if defined(VIRTUALINPUTS) #if defined(VIRTUAL_INPUTS)
MIXSRC_FIRST_INPUT, LUA_EXPORT_MULTIPLE("input", "Input [I%d]", MAX_INPUTS) MIXSRC_FIRST_INPUT, LUA_EXPORT_MULTIPLE("input", "Input [I%d]", MAX_INPUTS)
MIXSRC_LAST_INPUT = MIXSRC_FIRST_INPUT+MAX_INPUTS-1, MIXSRC_LAST_INPUT = MIXSRC_FIRST_INPUT+MAX_INPUTS-1,
#endif
#if defined(LUA_INPUTS)
MIXSRC_FIRST_LUA, MIXSRC_FIRST_LUA,
MIXSRC_LAST_LUA = MIXSRC_FIRST_LUA+(MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)-1, MIXSRC_LAST_LUA = MIXSRC_FIRST_LUA+(MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)-1,
#endif #endif
@ -877,18 +865,18 @@ enum MixSources {
MIXSRC_LAST_SWITCH = MIXSRC_TRN, MIXSRC_LAST_SWITCH = MIXSRC_TRN,
#endif #endif
MIXSRC_FIRST_LOGICAL_SWITCH, MIXSRC_FIRST_LOGICAL_SWITCH,
MIXSRC_SW1 = MIXSRC_FIRST_LOGICAL_SWITCH, LUA_EXPORT_MULTIPLE("ls", "Logical switch L%d", NUM_LOGICAL_SWITCH) MIXSRC_SW1 = MIXSRC_FIRST_LOGICAL_SWITCH, LUA_EXPORT_MULTIPLE("ls", "Logical switch L%d", MAX_LOGICAL_SWITCHES)
MIXSRC_SW9 = MIXSRC_SW1 + 8, MIXSRC_SW9 = MIXSRC_SW1 + 8,
MIXSRC_SWA, MIXSRC_SWA,
MIXSRC_SWB, MIXSRC_SWB,
MIXSRC_SWC, MIXSRC_SWC,
MIXSRC_LAST_LOGICAL_SWITCH = MIXSRC_FIRST_LOGICAL_SWITCH+NUM_LOGICAL_SWITCH-1, MIXSRC_LAST_LOGICAL_SWITCH = MIXSRC_FIRST_LOGICAL_SWITCH+MAX_LOGICAL_SWITCHES-1,
MIXSRC_FIRST_TRAINER, LUA_EXPORT_MULTIPLE("trn", "Trainer input %d", NUM_TRAINER) MIXSRC_FIRST_TRAINER, LUA_EXPORT_MULTIPLE("trn", "Trainer input %d", MAX_TRAINER_CHANNELS)
MIXSRC_LAST_TRAINER = MIXSRC_FIRST_TRAINER+NUM_TRAINER-1, MIXSRC_LAST_TRAINER = MIXSRC_FIRST_TRAINER+MAX_TRAINER_CHANNELS-1,
MIXSRC_FIRST_CH, MIXSRC_FIRST_CH,
MIXSRC_CH1 = MIXSRC_FIRST_CH, LUA_EXPORT_MULTIPLE("ch", "Channel CH%d", NUM_CHNOUT) MIXSRC_CH1 = MIXSRC_FIRST_CH, LUA_EXPORT_MULTIPLE("ch", "Channel CH%d", MAX_OUTPUT_CHANNELS)
MIXSRC_CH2, MIXSRC_CH2,
MIXSRC_CH3, MIXSRC_CH3,
MIXSRC_CH4, MIXSRC_CH4,
@ -904,7 +892,7 @@ enum MixSources {
MIXSRC_CH14, MIXSRC_CH14,
MIXSRC_CH15, MIXSRC_CH15,
MIXSRC_CH16, MIXSRC_CH16,
MIXSRC_LAST_CH = MIXSRC_CH1+NUM_CHNOUT-1, MIXSRC_LAST_CH = MIXSRC_CH1+MAX_OUTPUT_CHANNELS-1,
MIXSRC_FIRST_GVAR, MIXSRC_FIRST_GVAR,
MIXSRC_GVAR1 = MIXSRC_FIRST_GVAR, LUA_EXPORT_MULTIPLE("gvar", "Global variable %d", MAX_GVARS) MIXSRC_GVAR1 = MIXSRC_FIRST_GVAR, LUA_EXPORT_MULTIPLE("gvar", "Global variable %d", MAX_GVARS)
@ -927,7 +915,7 @@ enum MixSources {
MIXSRC_FIRST_TELEM, MIXSRC_FIRST_TELEM,
#if defined(CPUARM) #if defined(CPUARM)
MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+3*MAX_SENSORS-1 MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+3*MAX_TELEMETRY_SENSORS-1
#else #else
MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+NUM_TELEMETRY-1 MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+NUM_TELEMETRY-1
#endif #endif
@ -1029,7 +1017,7 @@ enum ResetFunctionParam {
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
FUNC_RESET_PARAM_FIRST_TELEM, FUNC_RESET_PARAM_FIRST_TELEM,
FUNC_RESET_PARAM_LAST_TELEM = FUNC_RESET_PARAM_FIRST_TELEM + MAX_SENSORS, FUNC_RESET_PARAM_LAST_TELEM = FUNC_RESET_PARAM_FIRST_TELEM + MAX_TELEMETRY_SENSORS,
#endif #endif
FUNC_RESET_PARAMS_COUNT, FUNC_RESET_PARAMS_COUNT,
FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1, FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1,

View file

@ -76,7 +76,7 @@ typedef uint8_t source_t;
* Mixer structure * Mixer structure
*/ */
#if defined(VIRTUALINPUTS) #if defined(CPUARM)
PACK(struct CurveRef { PACK(struct CurveRef {
uint8_t type; uint8_t type;
int8_t value; int8_t value;
@ -100,29 +100,9 @@ PACK(struct MixData {
uint8_t speedDown; uint8_t speedDown;
NOBACKUP(char name[LEN_EXPOMIX_NAME]); NOBACKUP(char name[LEN_EXPOMIX_NAME]);
}); });
#elif defined(CPUARM)
PACK(struct MixData {
uint8_t destCh:5;
uint8_t mixWarn:3; // mixer warning
uint16_t flightModes:9;
uint16_t curveMode:1;
uint16_t noExpo:1;
int16_t carryTrim:3;
uint16_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
int16_t weight;
int8_t swtch;
int8_t curveParam;
uint8_t delayUp;
uint8_t delayDown;
uint8_t speedUp;
uint8_t speedDown;
uint8_t srcRaw;
int16_t offset;
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
});
#elif defined(CPUM2560) || defined(CPUM2561) #elif defined(CPUM2560) || defined(CPUM2561)
PACK(struct MixData { PACK(struct MixData {
uint8_t destCh:4; // 0, 1..NUM_CHNOUT uint8_t destCh:4; // 0, 1..MAX_OUTPUT_CHANNELS
uint8_t curveMode:1; // O=curve, 1=differential uint8_t curveMode:1; // O=curve, 1=differential
uint8_t noExpo:1; uint8_t noExpo:1;
uint8_t weightMode:1; uint8_t weightMode:1;
@ -144,7 +124,7 @@ PACK(struct MixData {
}); });
#else #else
PACK(struct MixData { PACK(struct MixData {
uint8_t destCh:4; // 0, 1..NUM_CHNOUT uint8_t destCh:4; // 0, 1..MAX_OUTPUT_CHANNELS
uint8_t curveMode:1; // O=curve, 1=differential uint8_t curveMode:1; // O=curve, 1=differential
uint8_t noExpo:1; uint8_t noExpo:1;
uint8_t weightMode:1; uint8_t weightMode:1;
@ -169,7 +149,7 @@ PACK(struct MixData {
* Expo/Input structure * Expo/Input structure
*/ */
#if defined(VIRTUALINPUTS) #if defined(CPUARM)
PACK(struct ExpoData { PACK(struct ExpoData {
uint16_t mode:2; uint16_t mode:2;
uint16_t scale:14; uint16_t scale:14;
@ -184,17 +164,6 @@ PACK(struct ExpoData {
int8_t offset; int8_t offset;
CurveRef curve; CurveRef curve;
}); });
#elif defined(CPUARM)
PACK(struct ExpoData {
uint16_t mode:2; // 0=end, 1=pos, 2=neg, 3=both
uint16_t chn:3;
uint16_t curveMode:2;
uint16_t flightModes:9;
int8_t swtch;
int8_t weight;
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
int8_t curveParam;
});
#elif defined(CPUM2560) || defined(CPUM2561) #elif defined(CPUM2560) || defined(CPUM2561)
PACK(struct ExpoData { PACK(struct ExpoData {
uint8_t mode:2; // 0=end, 1=pos, 2=neg, 3=both uint8_t mode:2; // 0=end, 1=pos, 2=neg, 3=both
@ -222,7 +191,7 @@ PACK(struct ExpoData {
* Limit structure * Limit structure
*/ */
#if defined(VIRTUALINPUTS) #if defined(CPUARM)
PACK(struct LimitData { PACK(struct LimitData {
int32_t min:11; int32_t min:11;
int32_t max:11; int32_t max:11;
@ -287,7 +256,7 @@ PACK(struct CustomFunctionData {
uint16_t func:7; uint16_t func:7;
PACK(union { PACK(union {
NOBACKUP(PACK(struct { NOBACKUP(PACK(struct {
char name[LEN_CFN_NAME]; char name[LEN_FUNCTION_NAME];
}) play); }) play);
PACK(struct { PACK(struct {
@ -341,14 +310,14 @@ PACK(struct CustomFunctionData {
* FlightMode structure * FlightMode structure
*/ */
#if defined(VIRTUALINPUTS) #if defined(CPUARM)
PACK(struct trim_t { PACK(struct trim_t {
int16_t value:11; int16_t value:11;
uint16_t mode:5; uint16_t mode:5;
}); });
#else #else
typedef int16_t trim_t; typedef int16_t trim_t;
#endif #endif
typedef int16_t gvar_t; typedef int16_t gvar_t;
@ -394,15 +363,13 @@ PACK(struct FlightModeData {
* Curve structure * Curve structure
*/ */
#if defined(XCURVES) #if defined(CPUARM)
PACK(struct CurveData { PACK(struct CurveData {
uint8_t type:1; uint8_t type:1;
uint8_t smooth:1; uint8_t smooth:1;
int8_t points:6; // TODO conversion int8_t points:6; // TODO conversion
NOBACKUP(char name[LEN_CURVE_NAME]); NOBACKUP(char name[LEN_CURVE_NAME]);
}); });
#elif defined(CPUARM)
typedef int16_t CurveData;
#else #else
typedef int8_t CurveData; typedef int8_t CurveData;
#endif #endif
@ -463,7 +430,7 @@ PACK(struct TimerData {
* Swash Ring structure * Swash Ring structure
*/ */
#if defined(VIRTUALINPUTS) #if defined(VIRTUAL_INPUTS)
PACK(struct SwashRingData { PACK(struct SwashRingData {
uint8_t type; uint8_t type;
uint8_t value; uint8_t value;
@ -685,7 +652,7 @@ PACK(struct ModuleData {
uint8_t failsafeMode:4; //only 3 bits used uint8_t failsafeMode:4; //only 3 bits used
uint8_t subType:3; uint8_t subType:3;
uint8_t invertedSerial:1; // telemetry serial inverted from standard uint8_t invertedSerial:1; // telemetry serial inverted from standard
int16_t failsafeChannels[NUM_CHNOUT]; int16_t failsafeChannels[MAX_OUTPUT_CHANNELS];
union { union {
struct { struct {
int8_t delay:6; int8_t delay:6;
@ -786,13 +753,13 @@ PACK(struct CustomScreenData {
#endif #endif
#if defined(PCBHORUS) #if defined(PCBHORUS)
#define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS]); #define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]);
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
#define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS];
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS];
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
#define MODELDATA_EXTRA uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; uint8_t rxBattAlarms[2]; #define MODELDATA_EXTRA uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; uint8_t rxBattAlarms[2];
#else #else
#define MODELDATA_EXTRA #define MODELDATA_EXTRA
#endif #endif
@ -817,14 +784,14 @@ PACK(struct ModelData {
AVR_FIELD(int8_t ppmDelay) AVR_FIELD(int8_t ppmDelay)
BeepANACenter beepANACenter; BeepANACenter beepANACenter;
MixData mixData[MAX_MIXERS]; MixData mixData[MAX_MIXERS];
LimitData limitData[NUM_CHNOUT]; LimitData limitData[MAX_OUTPUT_CHANNELS];
ExpoData expoData[MAX_EXPOS]; ExpoData expoData[MAX_EXPOS];
CurveData curves[MAX_CURVES]; CurveData curves[MAX_CURVES];
int8_t points[NUM_POINTS]; int8_t points[MAX_CURVE_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH]; LogicalSwitchData logicalSw[MAX_LOGICAL_SWITCHES];
CustomFunctionData customFn[NUM_CFN]; CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
SwashRingData swashR; SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES]; FlightModeData flightModeData[MAX_FLIGHT_MODES];
@ -840,7 +807,7 @@ PACK(struct ModelData {
MODELDATA_EXTRA MODELDATA_EXTRA
ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors[MAX_SENSORS])) ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS]))
TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer) TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer)
@ -903,7 +870,7 @@ PACK(struct TrainerData {
NOBACKUP(int8_t varioPitch); \ NOBACKUP(int8_t varioPitch); \
NOBACKUP(int8_t varioRange); \ NOBACKUP(int8_t varioRange); \
NOBACKUP(int8_t varioRepeat); \ NOBACKUP(int8_t varioRepeat); \
CustomFunctionData customFn[NUM_CFN]; CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
#endif #endif
#if defined(PCBHORUS) #if defined(PCBHORUS)
@ -914,7 +881,7 @@ PACK(struct TrainerData {
uint32_t switchConfig; \ uint32_t switchConfig; \
uint8_t potsConfig; /* two bits per pot */ \ uint8_t potsConfig; /* two bits per pot */ \
NOBACKUP(char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]); \ NOBACKUP(char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]); \
NOBACKUP(char anaNames[NUM_STICKS+NUM_POTS][LEN_ANA_NAME]); \ NOBACKUP(char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]); \
NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \ NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
NOBACKUP(uint8_t bluetoothEnable:1); \ NOBACKUP(uint8_t bluetoothEnable:1); \
NOBACKUP(uint8_t blOffBright:7); \ NOBACKUP(uint8_t blOffBright:7); \
@ -927,7 +894,7 @@ PACK(struct TrainerData {
uint32_t switchConfig; \ uint32_t switchConfig; \
uint8_t potsType; /*two bits for every pot*/\ uint8_t potsType; /*two bits for every pot*/\
char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \ char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
char anaNames[NUM_STICKS+NUM_POTS][LEN_ANA_NAME]; char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME];
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#if defined(PCBX9E) #if defined(PCBX9E)
#define BLUETOOTH_FIELDS \ #define BLUETOOTH_FIELDS \
@ -945,7 +912,7 @@ PACK(struct TrainerData {
swarnstate_t switchUnlockStates; \ swarnstate_t switchUnlockStates; \
swconfig_t switchConfig; \ swconfig_t switchConfig; \
char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \ char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
char anaNames[NUM_STICKS+NUM_POTS][LEN_ANA_NAME]; \ char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; \
BLUETOOTH_FIELDS BLUETOOTH_FIELDS
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
#define EXTRA_GENERAL_FIELDS \ #define EXTRA_GENERAL_FIELDS \
@ -957,7 +924,9 @@ PACK(struct TrainerData {
int8_t temperatureCalib; \ int8_t temperatureCalib; \
uint8_t optrexDisplay; \ uint8_t optrexDisplay; \
uint8_t sticksGain; \ uint8_t sticksGain; \
uint8_t rotarySteps; uint8_t rotarySteps; \
char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME];
#elif defined(CPUARM) #elif defined(CPUARM)
#define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM #define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM
#elif defined(PXX) #elif defined(PXX)
@ -978,7 +947,7 @@ PACK(struct TrainerData {
PACK(struct RadioData { PACK(struct RadioData {
NOBACKUP(uint8_t version); NOBACKUP(uint8_t version);
NOBACKUP(uint16_t variant); NOBACKUP(uint16_t variant);
CalibData calib[NUM_STICKS+NUM_POTS+NUM_MOUSE_ANALOGS]; CalibData calib[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS];
NOBACKUP(uint16_t chkSum); NOBACKUP(uint16_t chkSum);
N_HORUS_FIELD(int8_t currModel); N_HORUS_FIELD(int8_t currModel);
N_HORUS_FIELD(uint8_t contrast); N_HORUS_FIELD(uint8_t contrast);
@ -1053,16 +1022,18 @@ static inline void check_struct()
#define CHKSIZE(x, y) check_size<struct x, y>() #define CHKSIZE(x, y) check_size<struct x, y>()
#define CHKTYPE(x, y) check_size<x, y>() #define CHKTYPE(x, y) check_size<x, y>()
#if defined(VIRTUALINPUTS) #if defined(CPUARM)
CHKSIZE(CurveRef, 2); CHKSIZE(CurveRef, 2);
#endif #endif
/* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */ /* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */
/* Sky9x does not have virtualinputs */ /* Sky9x does not have virtualinputs */
/* LEN_CFN_NAME is the difference in CustomFunctionData */ /* LEN_FUNCTION_NAME is the difference in CustomFunctionData */
#if defined(PCBTARANIS) #if defined(PCBX7D)
// TODO
#elif defined(PCBTARANIS)
CHKSIZE(MixData, 22); CHKSIZE(MixData, 22);
CHKSIZE(ExpoData, 19); CHKSIZE(ExpoData, 19);
CHKSIZE(LimitData, 13); CHKSIZE(LimitData, 13);
@ -1081,6 +1052,9 @@ static inline void check_struct()
#if defined(PCBX9E) #if defined(PCBX9E)
CHKSIZE(RadioData, 952); CHKSIZE(RadioData, 952);
CHKSIZE(ModelData, 6520); CHKSIZE(ModelData, 6520);
#elif defined(PCBX7D)
CHKSIZE(RadioData, 839);
CHKSIZE(ModelData, 6504);
#else #else
CHKSIZE(RadioData, 872); CHKSIZE(RadioData, 872);
CHKSIZE(ModelData, 6507); CHKSIZE(ModelData, 6507);
@ -1105,19 +1079,19 @@ static inline void check_struct()
#elif defined(PCBSKY9X) #elif defined(PCBSKY9X)
CHKSIZE(MixData, 20); CHKSIZE(MixData, 20);
CHKSIZE(ExpoData, 11); CHKSIZE(ExpoData, 17);
CHKSIZE(LimitData, 5); CHKSIZE(LimitData, 13);
CHKSIZE(CustomFunctionData, 9); CHKSIZE(CustomFunctionData, 9);
CHKSIZE(FlightModeData, 38); CHKSIZE(FlightModeData, 38);
CHKSIZE(TimerData, 11); CHKSIZE(TimerData, 11);
CHKSIZE(SwashRingData, 3); CHKSIZE(SwashRingData, 8);
CHKSIZE(FrSkyBarData, 5); CHKSIZE(FrSkyBarData, 5);
CHKSIZE(FrSkyLineData, 2); CHKSIZE(FrSkyLineData, 2);
CHKSIZE(FrSkyTelemetryData, 90); CHKSIZE(FrSkyTelemetryData, 90);
CHKSIZE(ModelHeader, 12); CHKSIZE(ModelHeader, 12);
CHKTYPE(CurveData, 2); CHKTYPE(CurveData, 4);
CHKSIZE(RadioData, 685); CHKSIZE(RadioData, 727);
CHKSIZE(ModelData, 4671); CHKSIZE(ModelData, 5252);
#else #else
// Common for all variants // Common for all variants
CHKSIZE(LimitData, 5); CHKSIZE(LimitData, 5);

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -262,7 +262,7 @@ void evalFunctions()
MASK_CFN_TYPE newActiveSwitches = 0; MASK_CFN_TYPE newActiveSwitches = 0;
#if defined(CPUARM) #if defined(CPUARM)
uint8_t playFirstIndex = (functions == g_model.customFn ? 1 : 1+NUM_CFN); uint8_t playFirstIndex = (functions == g_model.customFn ? 1 : 1+MAX_SPECIAL_FUNCTIONS);
#define PLAY_INDEX (i+playFirstIndex) #define PLAY_INDEX (i+playFirstIndex)
#else #else
#define PLAY_INDEX (i+1) #define PLAY_INDEX (i+1)
@ -273,7 +273,7 @@ void evalFunctions()
#endif #endif
#if defined(OVERRIDE_CHANNEL_FUNCTION) #if defined(OVERRIDE_CHANNEL_FUNCTION)
for (uint8_t i=0; i<NUM_CHNOUT; i++) { for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++) {
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED; safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
} }
#endif #endif
@ -284,7 +284,7 @@ void evalFunctions()
} }
#endif #endif
for (uint8_t i=0; i<NUM_CFN; i++) { for (uint8_t i=0; i<MAX_SPECIAL_FUNCTIONS; i++) {
const CustomFunctionData * cfn = &functions[i]; const CustomFunctionData * cfn = &functions[i];
int8_t swtch = CFN_SWITCH(cfn); int8_t swtch = CFN_SWITCH(cfn);
if (swtch) { if (swtch) {
@ -358,7 +358,7 @@ void evalFunctions()
#if defined(CPUARM) #if defined(CPUARM)
if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) { if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) {
uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM; uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM;
if (item < MAX_SENSORS) { if (item < MAX_TELEMETRY_SENSORS) {
telemetryItems[item].clear(); telemetryItems[item].clear();
} }
} }
@ -376,7 +376,7 @@ void evalFunctions()
{ {
unsigned int moduleIndex = CFN_PARAM(cfn); unsigned int moduleIndex = CFN_PARAM(cfn);
if (moduleIndex < NUM_MODULES) { if (moduleIndex < NUM_MODULES) {
for (int ch=0; ch<NUM_CHNOUT; ch++) { for (int ch=0; ch<MAX_OUTPUT_CHANNELS; ch++) {
if (ch < g_model.moduleData[moduleIndex].channelsStart || ch >= NUM_CHANNELS(moduleIndex) + g_model.moduleData[moduleIndex].channelsStart) { if (ch < g_model.moduleData[moduleIndex].channelsStart || ch >= NUM_CHANNELS(moduleIndex) + g_model.moduleData[moduleIndex].channelsStart) {
g_model.moduleData[moduleIndex].failsafeChannels[ch] = 0; g_model.moduleData[moduleIndex].failsafeChannels[ch] = 0;
} }

View file

@ -22,25 +22,401 @@
#define _GUI_H_ #define _GUI_H_
#include "gui_common.h" #include "gui_common.h"
#include "lcd.h"
#include "menus.h" #include "menus.h"
#include "popups.h"
extern const pm_uchar sticks[] PROGMEM; #define MENUS_SCROLLBAR_WIDTH 0
#if defined(PCBX7D)
#define HEADER_LINE 0
#define HEADER_LINE_COLUMNS
#else
#define HEADER_LINE 1
#define HEADER_LINE_COLUMNS 0,
#endif
#define MENU_COLUMNS 1
#define COLUMN_X 0
#define drawFieldLabel(x, y, str) lcdDrawTextAlignedLeft(y, str)
#define NUM_BODY_LINES (LCD_LINES-1) #define NUM_BODY_LINES (LCD_LINES-1)
#define MENU_HEADER_HEIGHT FH #define MENU_HEADER_HEIGHT FH
#define MENU_INIT_VPOS 0 #define MENU_INIT_VPOS 0
#define DEFAULT_SCROLLBAR_X (LCD_W-1)
#define WCHART (LCD_H/2) #define CURVE_SIDE_WIDTH (LCD_H/2)
#define X0 (LCD_W-WCHART-2) #define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
#define Y0 (LCD_H/2) #define CURVE_CENTER_Y (LCD_H/2)
#define MIXES_2ND_COLUMN (12*FW) #define MIXES_2ND_COLUMN (12*FW)
// Temporary no highlight
extern uint8_t noHighlightCounter;
#define NO_HIGHLIGHT() (noHighlightCounter > 0)
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
#if !defined(CPUM64)
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
#elif defined(GRAPHICS)
void display5posSlider(coord_t x, coord_t y, uint8_t value, uint8_t attr);
#define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
#else
#define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
#endif
#if defined(NAVIGATION_POT1)
extern int16_t p1valdiff;
#else
#define p1valdiff 0
#endif
#if defined(NAVIGATION_POT2)
extern int8_t p2valdiff;
#else
#define p2valdiff 0
#endif
extern int8_t checkIncDec_Ret; // global helper vars
#define EDIT_SELECT_MENU -1
#define EDIT_SELECT_FIELD 0
#define EDIT_MODIFY_FIELD 1
#define EDIT_MODIFY_STRING 2
extern int8_t s_editMode; // global editmode
// checkIncDec flags
#define EE_GENERAL 0x01
#define EE_MODEL 0x02
#define NO_INCDEC_MARKS 0x04
#define INCDEC_SWITCH 0x08
#define INCDEC_SOURCE 0x10
#define INCDEC_REP10 0x40
#define NO_DBLKEYS 0x80
#if defined(CPUARM)
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
#elif defined(CPUM64)
#define INCDEC_DECLARE_VARS(f)
#define INCDEC_SET_FLAG(f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL)
#else
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f)
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
#endif
// mawrow special values
#define TITLE_ROW ((uint8_t)-1)
#define HIDDEN_ROW ((uint8_t)-2)
#if defined(CPUARM)
struct CheckIncDecStops {
const int count;
const int stops[];
int min() const
{
return stops[0];
}
int max() const
{
return stops[count-1];
}
bool contains(int value) const
{
for (int i=0; i<count; ++i) {
int stop = stops[i];
if (value == stop)
return true;
else if (value < stop)
return false;
}
return false;
}
};
extern const CheckIncDecStops &stops100;
extern const CheckIncDecStops &stops1000;
extern const CheckIncDecStops &stopsSwitch;
#define INIT_STOPS(var, ...) \
const int _ ## var[] = { __VA_ARGS__ }; \
const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
#define CATEGORY_END(val) \
(val), (val+1)
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100);
#else
int16_t checkIncDec(uint8_t event, int16_t i_pval, int16_t i_min, int16_t i_max, uint8_t i_flags=0);
#endif
int8_t checkIncDecMovedSwitch(int8_t val);
#if defined(CPUM64)
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
int8_t checkIncDecModelZero(uint8_t event, int8_t i_val, int8_t i_max);
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
#else
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
#define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
#define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
#endif
#define CHECK_INCDEC_MODELVAR(event, var, min, max) \
var = checkIncDecModel(event,var,min,max)
#define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
var = checkIncDecModelZero(event,var,max)
#if defined(CPUARM)
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
var = checkIncDec(event, var, min, max, EE_MODEL, check)
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
var = checkIncDec(event, var, 0, max, EE_MODEL, check)
#else
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
var = checkIncDec(event, var, min, max, EE_MODEL)
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
CHECK_INCDEC_MODELVAR_ZERO(event, var, max)
#endif
#if defined(CPUARM)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#elif defined(AUTOSWITCH)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#else
#define AUTOSWITCH_ENTER_LONG() (0)
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#endif
#if defined(CPUARM)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
#elif defined(AUTOSOURCE)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS)
#else
#define CHECK_INCDEC_MODELSOURCE CHECK_INCDEC_MODELVAR
#endif
#define CHECK_INCDEC_GENVAR(event, var, min, max) \
var = checkIncDecGen(event, var, min, max)
#define CURSOR_ON_LINE() (0)
void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow);
void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t maxrow);
void check_submenu_simple(event_t event, uint8_t maxrow);
void title(const pm_char * s);
#define TITLE(str) title(str)
#if defined(CPUARM)
#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
#else
#define MENU_TAB(...) static const pm_uint8_t mstate_tab[] PROGMEM = __VA_ARGS__
#endif
#if defined(PCBX7D)
#define MENU_CHECK(tab, menu, lines_count) \
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count)
#else
#define MENU_CHECK(tab, menu, lines_count) \
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-1)
#endif
#define MENU(title, tab, menu, lines_count, ...) \
MENU_TAB(__VA_ARGS__); \
MENU_CHECK(tab, menu, lines_count); \
TITLE(title)
#if defined(PCBX7D)
#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
check_simple(event, menu, tab, DIM(tab), lines_count);
#define SUBMENU_NOTITLE(lines_count, ...) { \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
}
#define SUBMENU(title, lines_count, ...) \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
TITLE(title)
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
check_submenu_simple(event, lines_count);
#else
#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
check_simple(event, menu, tab, DIM(tab), (lines_count)-1);
#define SUBMENU_NOTITLE(lines_count, ...) { \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
}
#define SUBMENU(title, lines_count, ...) \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
TITLE(title)
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
check_submenu_simple(event, (lines_count)-1);
#endif
#define SIMPLE_MENU(title, tab, menu, lines_count) \
SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \
TITLE(title)
#define SIMPLE_SUBMENU(title, lines_count) \
SIMPLE_SUBMENU_NOTITLE(lines_count); \
TITLE(title)
#if defined(CPUARM)
typedef int select_menu_value_t;
#else
typedef int8_t select_menu_value_t;
#endif
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event);
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event);
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event);
#define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
#if defined(CPUARM) && defined(GVARS)
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
#else
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event)
#endif
#if defined(GVARS)
#if defined(CPUARM)
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event);
#else
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); // @@@ open.20.fsguruh
#endif
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
#else
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event);
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
#endif
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active);
#if defined(CPUM64)
#define editSingleName(x, y, label, name, size, event, active) editName(x, y, name, size, event, active)
#else
void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint8_t size, uint8_t event, uint8_t active);
#endif
uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, const pm_char * str, uint8_t delay);
#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
#define WARNING_TYPE_ASTERISK 0
#define WARNING_TYPE_CONFIRM 1
#define WARNING_TYPE_INPUT 2
extern const pm_char * warningText;
extern const pm_char * warningInfoText;
extern uint8_t warningInfoLength;
extern uint8_t warningResult;
extern uint8_t warningType;
#define COPY_MODE 1
#define MOVE_MODE 2
extern uint8_t s_copyMode;
extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx;
extern uint8_t s_curveChan;
extern uint8_t s_copySrcIdx;
extern uint8_t s_copySrcCh;
extern int8_t s_currCh;
extern uint8_t s_maxLines;
#if defined(SDCARD)
#define STATUS_LINE_LENGTH 32
extern char statusLineMsg[STATUS_LINE_LENGTH];
void showStatusLine();
void drawStatusLine();
#else
#define drawStatusLine()
#endif
#if defined(CPUARM)
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(uint8_t event);
void pushMenuTextView(const char *filename);
void pushModelNotes();
#endif
#define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)
#if defined(ROTARY_ENCODER_NAVIGATION)
#define IS_ROTARY_LEFT(evt) (evt == EVT_ROTARY_LEFT)
#define IS_ROTARY_RIGHT(evt) (evt == EVT_ROTARY_RIGHT)
#define IS_ROTARY_BREAK(evt) (evt == EVT_ROTARY_BREAK)
#define IS_ROTARY_LONG(evt) (evt == EVT_ROTARY_LONG)
#define IS_ROTARY_EVENT(evt) (EVT_KEY_MASK(evt) >= 0x0e)
#define CASE_EVT_ROTARY_BREAK case EVT_ROTARY_BREAK:
#define CASE_EVT_ROTARY_LONG case EVT_ROTARY_LONG:
#define CASE_EVT_ROTARY_LEFT case EVT_ROTARY_LEFT:
#define CASE_EVT_ROTARY_RIGHT case EVT_ROTARY_RIGHT:
void repeatLastCursorMove(uint8_t event);
#define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) putEvent(event); else repeatLastCursorMove(event); }
#define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE()
#else
#define IS_ROTARY_LEFT(evt) (0)
#define IS_ROTARY_RIGHT(evt) (0)
#define IS_ROTARY_BREAK(evt) (0)
#define IS_ROTARY_LONG(evt) (0)
#define IS_ROTARY_EVENT(evt) (0)
#define CASE_EVT_ROTARY_BREAK
#define CASE_EVT_ROTARY_LONG
#define CASE_EVT_ROTARY_LEFT
#define CASE_EVT_ROTARY_RIGHT
void repeatLastCursorMove(uint8_t event);
#define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event)
#define MOVE_CURSOR_FROM_HERE() REPEAT_LAST_CURSOR_MOVE()
#endif
#define POS_HORZ_INIT(posVert) 0
#define EDIT_MODE_INIT -1
typedef int (*FnFuncP) (int x);
void drawFunction(FnFuncP fn, uint8_t offset=0);
uint8_t switchToMix(uint8_t source);
void deleteExpoMix(uint8_t expo, uint8_t idx);
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
extern const pm_uchar sticks[] PROGMEM;
void drawSplash(); void drawSplash();
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr); void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
void drawStick(coord_t centrex, int16_t xval, int16_t yval); void drawStick(coord_t centrex, int16_t xval, int16_t yval);
void drawPotsBars();
void doMainScreenGraphics();
inline void drawProgressBar(const char * label) inline void drawProgressBar(const char * label)
{ {
// TODO // TODO
@ -59,7 +435,7 @@ void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uin
#endif #endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
void drawAlertBox(const char * title, const char * text, const char * action); void drawAlertBox(const pm_char * title, const pm_char * text, const char * action);
#endif #endif
#if defined(VOICE) #if defined(VOICE)
@ -81,4 +457,16 @@ void showAlertBox(const pm_char * title, const pm_char * text, const char * acti
#endif #endif
#define IS_OTHER_VIEW_DISPLAYED() false #define IS_OTHER_VIEW_DISPLAYED() false
#if defined(CPUARM)
void drawCurveRef(coord_t x, coord_t y, CurveRef & curve, LcdFlags flags);
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, LcdFlags flags);
#endif
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr);
#else
#define displayFlightModes(...)
#endif
#endif // _GUI_H_ #endif // _GUI_H_

View file

@ -116,6 +116,103 @@ void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width,
} }
} }
#if defined(CPUARM) && !defined(BOOT)
struct PatternData
{
uint8_t width;
uint8_t height;
const uint8_t * data;
};
uint8_t getPatternWidth(const PatternData * pattern)
{
uint8_t result = 0;
uint8_t lines = (pattern->height+7)/8;
const uint8_t * data = pattern->data;
for (int8_t i=0; i<pattern->width; i++) {
for (uint8_t j=0; j<lines; j++) {
if (data[j] != 0xff) {
result += 1;
break;
}
}
data += lines;
}
return result;
}
void getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
{
uint32_t fontsize = FONTSIZE(flags);
unsigned char c_remapped = 0;
if (fontsize == DBLSIZE || (flags&BOLD)) {
// To save space only some DBLSIZE and BOLD chars are available
// c has to be remapped. All non existing chars mapped to 0 (space)
if (c>=',' && c<=':')
c_remapped = c - ',' + 1;
else if (c>='A' && c<='Z')
c_remapped = c - 'A' + 16;
else if (c>='a' && c<='z')
c_remapped = c - 'a' + 42;
else if (c=='_')
c_remapped = 4;
else if (c!=' ')
flags &= ~BOLD;
}
if (fontsize == DBLSIZE) {
pattern->width = 10;
pattern->height = 16;
if (c >= 0xC0) {
pattern->data = &font_10x14_extra[((uint16_t)(c-0xC0))*20];
}
else {
if (c >= 128)
c_remapped = c - 60;
pattern->data = &font_10x14[((uint16_t)c_remapped)*20];
}
}
else if (fontsize == XXLSIZE) {
pattern->width = 22;
pattern->height = 38;
pattern->data = &font_22x38_num[((uint16_t)c-'0'+5)*110];
}
else if (fontsize == MIDSIZE) {
pattern->width = 8;
pattern->height = 12;
pattern->data = &font_8x10[((uint16_t)c-0x20)*16];
}
else if (fontsize == SMLSIZE) {
pattern->width = 5;
pattern->height = 6;
pattern->data = (c < 0xc0 ? &font_4x6[(c-0x20)*5] : &font_4x6_extra[(c-0xc0)*5]);
}
else if (fontsize == TINSIZE) {
pattern->width = 3;
pattern->height = 5;
pattern->data = &font_3x5[((uint16_t)c-0x20)*3];
}
else if (flags & BOLD) {
pattern->width = 5;
pattern->height = 7;
pattern->data = &font_5x7_B[c_remapped*5];
}
else {
pattern->width = 5;
pattern->height = 7;
pattern->data = (c < 0xC0) ? &font_5x7[(c-0x20)*5] : &font_5x7_extra[(c-0xC0)*5];
}
}
uint8_t getCharWidth(char c, LcdFlags flags)
{
PatternData pattern;
getCharPattern(&pattern, c, flags);
return getPatternWidth(&pattern);
}
#endif
void lcdDrawChar(coord_t x, coord_t y, const unsigned char c, LcdFlags flags) void lcdDrawChar(coord_t x, coord_t y, const unsigned char c, LcdFlags flags)
{ {
const pm_uchar * q; const pm_uchar * q;
@ -192,13 +289,39 @@ void lcdDrawChar(coord_t x, coord_t y, const unsigned char c)
lcdDrawChar(x, y, c, 0); lcdDrawChar(x, y, c, 0);
} }
#if defined(CPUARM) && !defined(BOOT)
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
{
uint8_t width = 0;
while (len--) {
unsigned char c = (flags & ZCHAR) ? idx2char(*s) : *s;
if (!c) {
break;
}
width += getCharWidth(c, flags) + 1;
s++;
}
return width;
}
#endif
void lcdDrawSizedText(coord_t x, coord_t y, const pm_char * s, uint8_t len, LcdFlags flags) void lcdDrawSizedText(coord_t x, coord_t y, const pm_char * s, uint8_t len, LcdFlags flags)
{ {
const coord_t orig_x = x; const coord_t orig_x = x;
#if defined(CPUARM) #if defined(CPUARM)
const uint8_t orig_len = len; const uint8_t orig_len = len;
uint32_t fontsize = FONTSIZE(flags); uint32_t fontsize = FONTSIZE(flags);
#endif #endif
#if defined(CPUARM) && !defined(BOOT)
uint8_t width = 0;
if (flags & RIGHT) {
width = getTextWidth(s, len, flags);
x -= width;
}
#endif
bool setx = false; bool setx = false;
while (len--) { while (len--) {
unsigned char c; unsigned char c;
@ -259,9 +382,14 @@ void lcdDrawSizedText(coord_t x, coord_t y, const pm_char * s, uint8_t len, LcdF
} }
lcdLastPos = x; lcdLastPos = x;
lcdNextPos = x; lcdNextPos = x;
#if defined(CPUARM) #if defined(CPUARM) && !defined(BOOT)
if (fontsize == MIDSIZE) if (fontsize == MIDSIZE) {
lcdLastPos += 1; lcdLastPos += 1;
}
if (flags & RIGHT) {
lcdLastPos -= width;
lcdNextPos -= width;
}
#endif #endif
} }
@ -334,6 +462,7 @@ void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags flags, uint8_t l
uint8_t fw = FWNUM; uint8_t fw = FWNUM;
int8_t mode = MODE(flags); int8_t mode = MODE(flags);
flags &= ~LEADING0; flags &= ~LEADING0;
#if defined(CPUARM) #if defined(CPUARM)
uint32_t fontsize = FONTSIZE(flags); uint32_t fontsize = FONTSIZE(flags);
bool dblsize = (fontsize == DBLSIZE); bool dblsize = (fontsize == DBLSIZE);
@ -386,16 +515,17 @@ void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags flags, uint8_t l
fw -= 1; fw -= 1;
} }
else { else {
if (flags & LEFT) { if (IS_LEFT_ALIGNED(flags)) {
if (mode > 0) if (mode > 0) {
x += 2; x += 2;
} }
}
#if defined(BOLD_FONT) && !defined(CPUM64) || defined(TELEMETRY_NONE) #if defined(BOLD_FONT) && !defined(CPUM64) || defined(TELEMETRY_NONE)
if (flags & BOLD) fw += 1; if (flags & BOLD) fw += 1;
#endif #endif
} }
if (flags & LEFT) { if (IS_LEFT_ALIGNED(flags)) {
x += len * fw; x += len * fw;
if (neg) { if (neg) {
x += ((xxlsize|dblsize|midsize) ? 7 : FWNUM); x += ((xxlsize|dblsize|midsize) ? 7 : FWNUM);
@ -568,30 +698,31 @@ void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat,
#endif #endif
} }
void lcdDrawTelemetryTopBar() void drawTelemetryTopBar()
{ {
putsModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0); putsModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0);
uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0); uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0);
putsVBat(14*FW,0,att); putsVBat(14*FW,0,att);
if (g_model.timers[0].mode) { if (g_model.timers[0].mode) {
att = (timersStates[0].val<0 ? BLINK : 0); att = (timersStates[0].val<0 ? BLINK : 0);
putsTimer(17*FW+5*FWNUM+1, 0, timersStates[0].val, att, att); drawTimer(17*FW+5*FWNUM+1, 0, timersStates[0].val, att, att);
} }
lcdInvertLine(0); lcdInvertLine(0);
} }
#if defined(CPUARM) && defined(RTCLOCK) #if defined(CPUARM) && defined(RTCLOCK)
void putsRtcTime(coord_t x, coord_t y, LcdFlags att) void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
{ {
putsTimer(x, y, getValue(MIXSRC_TX_TIME), att, att); drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att);
} }
#endif #endif
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2) void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2)
{ {
div_t qr; div_t qr;
if (!(att & LEFT)) { if (IS_RIGHT_ALIGNED(att)) {
att -= RIGHT;
if (att & DBLSIZE) if (att & DBLSIZE)
x -= 5*(2*FWNUM)-4; x -= 5*(2*FWNUM)-4;
else if (att & MIDSIZE) else if (att & MIDSIZE)
@ -622,12 +753,12 @@ void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2
att &= ~DBLSIZE; att &= ~DBLSIZE;
#endif #endif
#if defined(CPUARM) && defined(RTCLOCK) #if defined(CPUARM) && defined(RTCLOCK)
if (att&TIMEBLINK) if (att & TIMEBLINK)
lcdDrawChar(lcdLastPos, y, separator, BLINK); lcdDrawChar(lcdLastPos, y, separator, BLINK);
else else
#endif #endif
lcdDrawChar(lcdLastPos, y, separator, att&att2); lcdDrawChar(lcdLastPos, y, separator, att&att2);
lcdDrawNumber(lcdNextPos, y, qr.rem, att2|LEADING0|LEFT, 2); lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0|LEFT) & (~RIGHT), 2);
} }
// TODO to be optimized with putsValueWithUnit // TODO to be optimized with putsValueWithUnit
@ -642,20 +773,97 @@ void putsVBat(coord_t x, coord_t y, LcdFlags att)
putsVolts(x, y, g_vbat100mV, att); putsVolts(x, y, g_vbat100mV, att);
} }
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att) #if defined(CPUARM)
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
{ {
lcdDrawText(x, y, str, att & ~LEADING0); if (idx == MIXSRC_NONE) {
lcdDrawNumber(lcdNextPos, y, idx, att|LEFT, 2); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
}
else if (idx <= MIXSRC_LAST_INPUT) {
lcdDrawChar(x+2, y+1, CHR_INPUT, TINSIZE);
lcdDrawFilledRect(x, y, 7, 7);
if (ZEXIST(g_model.inputNames[idx-MIXSRC_FIRST_INPUT]))
lcdDrawSizedText(x+8, y, g_model.inputNames[idx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME, ZCHAR|att);
else
lcdDrawNumber(x+8, y, idx, att|LEADING0|LEFT, 2);
}
#if defined(LUA_INPUTS)
else if (idx <= MIXSRC_LAST_LUA) {
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
#if defined(LUA_MODEL_SCRIPTS)
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
lcdDrawChar(x+2, y+1, '1'+qr.quot, TINSIZE);
lcdDrawFilledRect(x, y, 7, 7);
lcdDrawSizedText(x+8, y, scriptInputsOutputs[qr.quot].outputs[qr.rem].name, att & STREXPANDED ? 9 : 4, att);
}
else
#endif
{
drawStringWithIndex(x, y, "LUA", qr.quot+1, att);
lcdDrawChar(lcdLastPos, y, 'a'+qr.rem, att);
}
}
#endif
else if (idx < MIXSRC_LAST_POT) {
idx = idx - MIXSRC_Rud;
if (ZEXIST(g_eeGeneral.anaNames[idx])) {
if (idx < MIXSRC_FIRST_POT-MIXSRC_Rud )
lcdDrawChar(x, y, '\307', att); // stick symbol
else if (idx <= MIXSRC_LAST_POT-MIXSRC_Rud )
lcdDrawChar(x, y, '\310', att); // pot symbol
else
lcdDrawChar(x, y, '\311', att); // slider symbol
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, ZCHAR|att);
}
else {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + 1, att);
}
}
else if (idx >= MIXSRC_FIRST_SWITCH && idx <= MIXSRC_LAST_SWITCH) {
idx = idx-MIXSRC_FIRST_SWITCH;
if (ZEXIST(g_eeGeneral.switchNames[idx])) {
lcdDrawChar(x, y, '\312', att); //switch symbol
lcdDrawSizedText(lcdNextPos, y, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME, ZCHAR|att);
}
else {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1, att);
}
}
else if (idx < MIXSRC_SW1)
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
drawSwitch(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
else if (idx < MIXSRC_CH1)
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
else if (idx <= MIXSRC_LAST_CH) {
drawStringWithIndex(x, y, STR_CH, idx-MIXSRC_CH1+1, att);
if (ZEXIST(g_model.limitData[idx-MIXSRC_CH1].name) && (att & STREXPANDED)) {
lcdDrawChar(lcdLastPos, y, ' ', att|SMLSIZE);
lcdDrawSizedText(lcdLastPos+3, y, g_model.limitData[idx-MIXSRC_CH1].name, LEN_CHANNEL_NAME, ZCHAR|att|SMLSIZE);
}
}
else if (idx <= MIXSRC_LAST_GVAR) {
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
}
else if (idx < MIXSRC_FIRST_TELEM) {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
}
else {
idx -= MIXSRC_FIRST_TELEM;
div_t qr = div(idx, 3);
lcdDrawSizedText(x, y, g_model.telemetrySensors[qr.quot].label, TELEM_LABEL_LEN, ZCHAR|att);
if (qr.rem) lcdDrawChar(lcdLastPos, y, qr.rem==2 ? '+' : '-', att);
}
} }
#else
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att) void drawSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
{ {
if (idx < MIXSRC_THR) if (idx < MIXSRC_THR)
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx, att); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx, att);
else if (idx < MIXSRC_SW1) else if (idx < MIXSRC_SW1)
putsSwitches(x, y, idx-MIXSRC_THR+1+3*(1), att); drawSwitch(x, y, idx-MIXSRC_THR+1+3*(1), att);
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
putsSwitches(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att); drawSwitch(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
else if (idx < MIXSRC_CH1) else if (idx < MIXSRC_CH1)
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att); drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
else if (idx <= MIXSRC_LAST_CH) { else if (idx <= MIXSRC_LAST_CH) {
@ -666,7 +874,7 @@ void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att); drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
#endif #endif
else if (idx < MIXSRC_FIRST_TELEM) { else if (idx < MIXSRC_FIRST_TELEM) {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-(MIXSRC_SW1-MIXSRC_THR)-NUM_LOGICAL_SWITCH-NUM_TRAINER-NUM_CHNOUT-MAX_GVARS, att); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-(MIXSRC_SW1-MIXSRC_THR)-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
} }
#if defined(CPUARM) #if defined(CPUARM)
else { else {
@ -680,6 +888,7 @@ void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
lcdDrawTextAtIndex(x, y, STR_VTELEMCHNS, idx-MIXSRC_FIRST_TELEM+1, att); lcdDrawTextAtIndex(x, y, STR_VTELEMCHNS, idx-MIXSRC_FIRST_TELEM+1, att);
#endif #endif
} }
#endif
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att) void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
{ {
@ -698,7 +907,15 @@ void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
} }
} }
void putsSwitches(coord_t x, coord_t y, int8_t idx, LcdFlags att) #if defined(CPUARM)
void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags)
{
char s[8];
getSwitchString(s, idx);
lcdDrawText(x, y, s, flags);
}
#else
void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags att)
{ {
if (idx == SWSRC_OFF) if (idx == SWSRC_OFF)
return lcdDrawTextAtIndex(x, y, STR_OFFON, 0, att); return lcdDrawTextAtIndex(x, y, STR_OFFON, 0, att);
@ -713,17 +930,6 @@ void putsSwitches(coord_t x, coord_t y, int8_t idx, LcdFlags att)
#endif #endif
return lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx, att); return lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx, att);
} }
#if defined(FLIGHT_MODES)
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att)
{
if (idx==0) { lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, att); return; }
if (idx < 0) { lcdDrawChar(x-2, y, '!', att); idx = -idx; }
if (att & CONDENSED)
lcdDrawNumber(x+FW*1, y, idx-1, (att & ~CONDENSED), 1);
else
drawStringWithIndex(x, y, STR_FP, idx-1, att);
}
#endif #endif
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att) void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att)
@ -738,7 +944,7 @@ void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att)
drawStringWithIndex(x, y, STR_CV, idx-CURVE_BASE+1, att); drawStringWithIndex(x, y, STR_CV, idx-CURVE_BASE+1, att);
} }
void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att) void drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
{ {
if (mode >= 0) { if (mode >= 0) {
if (mode < TMRMODE_COUNT) if (mode < TMRMODE_COUNT)
@ -746,22 +952,52 @@ void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
else else
mode -= (TMRMODE_COUNT-1); mode -= (TMRMODE_COUNT-1);
} }
putsSwitches(x, y, mode, att); drawSwitch(x, y, mode, att);
} }
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att) #if defined(CPUARM)
void drawTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags att)
{ {
trim_t v = getRawTrimValue(phase, idx); trim_t v = getRawTrimValue(fm, idx);
uint8_t mode = v.mode;
uint8_t p = mode >> 1;
char s[] = "--";
if (mode != TRIM_MODE_NONE) {
if (mode % 2 == 0)
s[0] = ':';
else
s[0] = '+';
s[1] = '0'+p;
}
lcdDrawText(x, y, s, att);
}
void drawShortTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags att)
{
trim_t v = getRawTrimValue(fm, idx);
uint8_t mode = v.mode;
uint8_t p = v.mode >> 1;
if (mode == TRIM_MODE_NONE) {
putsChnLetter(x, y, idx+1, att);
}
else {
lcdDrawChar(x, y, '0'+p, att);
}
}
#else
void drawTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags att)
{
trim_t v = getRawTrimValue(fm, idx);
if (v > TRIM_EXTENDED_MAX) { if (v > TRIM_EXTENDED_MAX) {
uint8_t p = v - TRIM_EXTENDED_MAX - 1; uint8_t p = v - TRIM_EXTENDED_MAX - 1;
if (p >= phase) p++; if (p >= fm) p++;
lcdDrawChar(x, y, '0'+p, att); lcdDrawChar(x, y, '0'+p, att);
} }
else { else {
putsChnLetter(x, y, idx+1, att); putsChnLetter(x, y, idx+1, att);
} }
} }
#endif
#if ROTARY_ENCODERS > 0 #if ROTARY_ENCODERS > 0
void putsRotaryEncoderMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att) void putsRotaryEncoderMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att)
@ -870,7 +1106,7 @@ void displayGpsCoords(coord_t x, coord_t y, TelemetryItem & telemetryItem, LcdFl
void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t value, LcdFlags att) void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t value, LcdFlags att)
{ {
if (channel >= MAX_SENSORS) return; if (channel >= MAX_TELEMETRY_SENSORS) return;
TelemetryItem & telemetryItem = telemetryItems[channel]; TelemetryItem & telemetryItem = telemetryItems[channel];
TelemetrySensor & telemetrySensor = g_model.telemetrySensors[channel]; TelemetrySensor & telemetrySensor = g_model.telemetrySensors[channel];
if (telemetrySensor.unit == UNIT_DATETIME) { if (telemetrySensor.unit == UNIT_DATETIME) {
@ -896,7 +1132,7 @@ void putsChannelValue(coord_t x, coord_t y, source_t channel, lcdint_t value, Lc
putsTelemetryChannelValue(x, y, channel, value, att); putsTelemetryChannelValue(x, y, channel, value, att);
} }
else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) { else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) {
putsTimer(x, y, value, att, att); drawTimer(x, y, value, att, att);
} }
else if (channel == MIXSRC_TX_VOLTAGE) { else if (channel == MIXSRC_TX_VOLTAGE) {
lcdDrawNumber(x, y, value, att|PREC1); lcdDrawNumber(x, y, value, att|PREC1);
@ -941,10 +1177,8 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t v
switch (channel) { switch (channel) {
#if defined(CPUARM) && defined(RTCLOCK) #if defined(CPUARM) && defined(RTCLOCK)
case TELEM_TX_TIME-1: case TELEM_TX_TIME-1:
{ drawRtcTime(x, y, att);
putsRtcTime(x, y, att);
break; break;
}
#endif #endif
case TELEM_TIMER1-1: case TELEM_TIMER1-1:
case TELEM_TIMER2-1: case TELEM_TIMER2-1:
@ -952,7 +1186,7 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t v
case TELEM_TIMER3-1: case TELEM_TIMER3-1:
#endif #endif
att &= ~NO_UNIT; att &= ~NO_UNIT;
putsTimer(x, y, val, att, att); drawTimer(x, y, val, att, att);
break; break;
#if defined(TELEMETRY_FRSKY) #if defined(TELEMETRY_FRSKY)
case TELEM_MIN_A1-1: case TELEM_MIN_A1-1:
@ -1080,7 +1314,7 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t v
case TELEM_TIMER1-1: case TELEM_TIMER1-1:
case TELEM_TIMER2-1: case TELEM_TIMER2-1:
att &= ~NO_UNIT; att &= ~NO_UNIT;
putsTimer(x, y, val, att, att); drawTimer(x, y, val, att, att);
break; break;
case TELEM_TX_VOLTAGE-1: case TELEM_TX_VOLTAGE-1:
@ -1251,44 +1485,6 @@ void lcdDrawChar(coord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
} }
#endif #endif
void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
if (p<DISPLAY_END)
lcdMaskPoint(p, BITMASK(y%8), att);
}
void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att)
{
if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; }
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t msk = BITMASK(y%8);
while (w--) {
if(pat&1) {
lcdMaskPoint(p, msk, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
p++;
}
}
#if defined(CPUM64) #if defined(CPUM64)
void lcdDrawVerticalLine(coord_t x, int8_t y, int8_t h, uint8_t pat) void lcdDrawVerticalLine(coord_t x, int8_t y, int8_t h, uint8_t pat)
{ {
@ -1323,6 +1519,84 @@ void lcdDrawVerticalLine(coord_t x, int8_t y, int8_t h, uint8_t pat)
} }
#else #else
// allows the att parameter... // allows the att parameter...
#endif
#define LCD_IMG_FUNCTION(NAME, TYPE, READ_BYTE) \
void NAME(coord_t x, coord_t y, TYPE img, uint8_t idx, LcdFlags att) \
{ \
TYPE q = img; \
uint8_t w = READ_BYTE(q++); \
uint8_t hb = (READ_BYTE(q++)+7)/8; \
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false); \
q += idx*w*hb; \
for (uint8_t yb = 0; yb < hb; yb++) { \
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ]; \
for (coord_t i=0; i<w; i++){ \
uint8_t b = READ_BYTE(q); \
q++; \
ASSERT_IN_DISPLAY(p); \
*p++ = inv ? ~b : b; \
} \
} \
}
#if defined(PCBMEGA2560) && !defined(SIMU)
LCD_IMG_FUNCTION(lcd_imgfar, uint_farptr_t, pgm_read_byte_far)
#endif
LCD_IMG_FUNCTION(lcd_img, const pm_uchar *, pgm_read_byte)
#endif
void lcdMaskPoint(uint8_t * p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att)
{
uint8_t * p = &displayBuf[ y / 8 * LCD_W + x ];
if (p < DISPLAY_END) {
lcdMaskPoint(p, BITMASK(y % 8), att);
}
}
void lcdInvertLine(int8_t y)
{
uint8_t *p = &displayBuf[y * LCD_W];
for (coord_t x=0; x<LCD_W; x++) {
ASSERT_IN_DISPLAY(p);
*p++ ^= 0xff;
}
}
void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att)
{
if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; }
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t msk = BITMASK(y%8);
while (w--) {
if(pat&1) {
lcdMaskPoint(p, msk, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
p++;
}
}
void lcdDrawVerticalLine(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlags att) void lcdDrawVerticalLine(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlags att)
{ {
if (x >= LCD_W) return; if (x >= LCD_W) return;
@ -1360,40 +1634,17 @@ void lcdDrawVerticalLine(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlag
lcdMaskPoint(p, (BITMASK(h)-1) & pat, att); lcdMaskPoint(p, (BITMASK(h)-1) & pat, att);
} }
} }
#endif
void lcdInvertLine(int8_t y) #if defined(PWR_PRESS_BUTTON)
void drawShutdownAnimation(uint32_t index)
{ {
uint8_t *p = &displayBuf[y * LCD_W]; lcdClear();
for (coord_t x=0; x<LCD_W; x++) { int quarter = index / (PWR_PRESS_SHUTDOWN / 5);
ASSERT_IN_DISPLAY(p); for (int i=1; i<=4; i++) {
*p++ ^= 0xff; if (quarter >= i) {
lcdDrawFilledRect(LCD_W / 2 - 28 + 10 * i, LCD_H / 2 - 3, 6, 6, SOLID, 0);
} }
}
lcdRefresh();
} }
#define LCD_IMG_FUNCTION(NAME, TYPE, READ_BYTE) \
void NAME(coord_t x, coord_t y, TYPE img, uint8_t idx, LcdFlags att) \
{ \
TYPE q = img; \
uint8_t w = READ_BYTE(q++); \
uint8_t hb = (READ_BYTE(q++)+7)/8; \
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false); \
q += idx*w*hb; \
for (uint8_t yb = 0; yb < hb; yb++) { \
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ]; \
for (coord_t i=0; i<w; i++){ \
uint8_t b = READ_BYTE(q); \
q++; \
ASSERT_IN_DISPLAY(p); \
*p++ = inv ? ~b : b; \
} \
} \
}
#if defined(PCBMEGA2560) && !defined(SIMU)
LCD_IMG_FUNCTION(lcd_imgfar, uint_farptr_t, pgm_read_byte_far)
#endif
LCD_IMG_FUNCTION(lcd_img, const pm_uchar *, pgm_read_byte)
#endif #endif

View file

@ -23,8 +23,6 @@
#include <inttypes.h> #include <inttypes.h>
#define LCD_W 128
#define LCD_H 64
#define BOX_WIDTH 23 #define BOX_WIDTH 23
#define coord_t uint8_t #define coord_t uint8_t
#define scoord_t int8_t #define scoord_t int8_t
@ -34,11 +32,11 @@
#define CONTRAST_MAX 45 #define CONTRAST_MAX 45
#if defined(CPUARM) #if defined(CPUARM)
#define lcdint_t int32_t typedef int32_t lcdint_t;
#define lcduint_t uint32_t typedef uint32_t lcduint_t;
#else #else
#define lcdint_t int16_t typedef int16_t lcdint_t;
#define lcduint_t uint16_t typedef uint16_t lcduint_t;
#endif #endif
#define FW 6 #define FW 6
@ -78,8 +76,16 @@
#define PREC1 0x20 #define PREC1 0x20
#define PREC2 0x30 #define PREC2 0x30
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4) #define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
#if defined(CPUARM)
#define LEFT 0x00 /* fake */
#define RIGHT 0x04 /* align right */
#define IS_LEFT_ALIGNED(att) !((att) & RIGHT)
#else
#define LEFT 0x80 /* align left */ #define LEFT 0x80 /* align left */
#define RIGHT 0x00 /* fake */ #define RIGHT 0x00 /* fake */
#define IS_LEFT_ALIGNED(att) ((att) & LEFT)
#endif
#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att))
/* line, rect, square flags */ /* line, rect, square flags */
#define FORCE 0x02 #define FORCE 0x02
@ -116,9 +122,9 @@
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
#define LcdFlags uint32_t typedef uint32_t LcdFlags;
#else #else
#define LcdFlags uint8_t typedef uint8_t LcdFlags;
#endif #endif
#define display_t uint8_t #define display_t uint8_t
@ -126,8 +132,6 @@
extern display_t displayBuf[DISPLAY_BUFFER_SIZE]; extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#define lcdRefreshWait()
extern coord_t lcdLastPos; extern coord_t lcdLastPos;
extern coord_t lcdNextPos; extern coord_t lcdNextPos;
@ -170,19 +174,27 @@ void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags mode, uint8_t le
void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0); void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0);
void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val); void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val);
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att=0); void drawStringWithIndex(coord_t x, coord_t y, const pm_char * str, uint8_t idx, LcdFlags att=0);
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); void putsModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att);
void putsSwitches(coord_t x, coord_t y, int8_t swtch, LcdFlags att=0); #if !defined(BOOT) // TODO not here ...
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0);
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att=0);
#endif
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0); void drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0);
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
void drawTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
#if defined(CPUARM)
void drawShortTrimMode(coord_t x, coord_t y, uint8_t mode, uint8_t idx, LcdFlags att);
#else
#define drawShortTrimMode drawTrimMode
#endif
#if defined(ROTARY_ENCODERS) #if defined(ROTARY_ENCODERS)
void putsRotaryEncoderMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att); void putsRotaryEncoderMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
#endif #endif
#define putsChn(x, y, idx, att) putsMixerSource(x, y, MIXSRC_CH1+idx-1, att) #define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_CH1+idx-1, att)
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att); void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
@ -202,8 +214,8 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, lcdint_t v
#define FlightModesType uint8_t #define FlightModesType uint8_t
#endif #endif
void putsRtcTime(coord_t x, coord_t y, LcdFlags att); void drawRtcTime(coord_t x, coord_t y, LcdFlags att);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2); void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
#define SOLID 0xff #define SOLID 0xff
#define DOTTED 0x55 #define DOTTED 0x55
@ -230,7 +242,7 @@ void lcdInvertLine(int8_t line);
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1) #define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0) { lcdDrawRect(x, y, w, w, SOLID, att); } inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0) { lcdDrawRect(x, y, w, w, SOLID, att); }
void lcdDrawTelemetryTopBar(); void drawTelemetryTopBar();
#define V_BAR(xx, yy, ll) \ #define V_BAR(xx, yy, ll) \
lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \ lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \
@ -241,33 +253,26 @@ void lcdDrawTelemetryTopBar();
void lcd_imgfar(coord_t x, coord_t y, const uint_farptr_t img, uint8_t idx, LcdFlags att); // progmem "far" void lcd_imgfar(coord_t x, coord_t y, const uint_farptr_t img, uint8_t idx, LcdFlags att); // progmem "far"
#endif #endif
void lcdClear(void);
void lcd_img(coord_t x, coord_t y, const pm_uchar * img, uint8_t idx, LcdFlags att=0); void lcd_img(coord_t x, coord_t y, const pm_uchar * img, uint8_t idx, LcdFlags att=0);
void lcdSetRefVolt(unsigned char val);
void lcdClear();
void lcdSetContrast();
void lcdInit();
#define lcdOff()
void lcdRefresh();
#if defined(LCD_KS108)
void lcdRefreshSide();
#endif
#if defined(LCD_ST7920)
uint8_t lcdRefresh_ST7920(uint8_t full);
#define IS_LCD_REFRESH_ALLOWED() (0==lcdstate)
#else
#define IS_LCD_REFRESH_ALLOWED() (1)
#endif
#if defined(BOOT) #if defined(BOOT)
#define BLINK_ON_PHASE (0) #define BLINK_ON_PHASE (0)
#else #else
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
#endif #endif
inline display_t getPixel(uint8_t x, uint8_t y)
{
if (x>=LCD_W || y>=LCD_H) {
return 0;
}
display_t * p = &displayBuf[y / 2 * LCD_W + x];
return (y & 1) ? (*p >> 4) : (*p & 0x0F);
}
const char * writeScreenshot(); const char * writeScreenshot();
void drawShutdownAnimation(uint32_t index);
#endif // _LCD_H_ #endif // _LCD_H_

View file

@ -35,14 +35,107 @@ uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, cons
uint8_t s_copyMode = 0; uint8_t s_copyMode = 0;
int8_t s_copySrcRow; int8_t s_copySrcRow;
int8_t s_copyTgtOfs; int8_t s_copyTgtOfs;
uint8_t s_maxLines = 8;
uint8_t s_copySrcIdx;
uint8_t s_copySrcCh;
#if defined(CPUM64) #if defined(CPUM64)
#define editNameCursorPos menuHorizontalPosition #define editNameCursorPos menuHorizontalPosition
#else #else
static uint8_t editNameCursorPos = 0; uint8_t editNameCursorPos = 0;
#endif #endif
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active) #if defined(PCBX7D)
void editName(coord_t x, coord_t y, char * name, uint8_t size, uint8_t event, uint8_t active/* TODO, uint8_t attr*/)
{
LcdFlags attr = ZCHAR; // TODO in args
uint8_t mode = 0;
if (active) {
if (s_editMode <= 0)
mode = INVERS + FIXEDWIDTH;
else
mode = FIXEDWIDTH;
}
lcdDrawSizedText(x, y, name, size, attr | mode);
coord_t backupNextPos = lcdNextPos;
if (active) {
uint8_t cur = editNameCursorPos;
if (s_editMode > 0) {
int8_t c = name[cur];
int8_t v = c;
if (event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_DOWN) || event==EVT_KEY_REPT(KEY_UP)) {
if (attr == ZCHAR) {
v = checkIncDec(event, abs(v), 0, ZCHAR_MAX, 0);
if (c <= 0) v = -v;
}
else {
v = checkIncDec(event, abs(v), '0', 'z', 0);
}
}
switch (event) {
case EVT_ROTARY_BREAK:
if (s_editMode == EDIT_MODIFY_FIELD) {
s_editMode = EDIT_MODIFY_STRING;
cur = 0;
}
else if (cur<size-1)
cur++;
else
s_editMode = 0;
break;
case EVT_ROTARY_LONG:
if (attr & ZCHAR) {
if (v == 0) {
s_editMode = 0;
killEvents(event);
}
else if (v>=-26 && v<=26) {
v = -v; // toggle case
}
}
else {
if (v == ' ') {
s_editMode = 0;
killEvents(event);
break;
}
else if (v>='A' && v<='Z') {
v = 'a'+v-'A'; // toggle case
}
else if (v>='a' && v<='z') {
v = 'A'+v-'a'; // toggle case
}
}
break;
}
if (c != v) {
name[cur] = v;
storageDirty(menuVerticalPositions[0] == 0 ? EE_MODEL : EE_GENERAL);
}
if (attr == ZCHAR) {
lcdDrawChar(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH);
}
else {
lcdDrawChar(x+editNameCursorPos*FW, y, v, ERASEBG|INVERS|FIXEDWIDTH);
}
}
else {
cur = 0;
}
editNameCursorPos = cur;
lcdNextPos = backupNextPos;
}
}
#else
void editName(coord_t x, coord_t y, char * name, uint8_t size, uint8_t event, uint8_t active)
{ {
#if defined(CPUM64) #if defined(CPUM64)
// in order to save flash // in order to save flash
@ -94,7 +187,7 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LONG: case EVT_ROTARY_LONG:
if (v==0) { if (v == 0) {
s_editMode = 0; s_editMode = 0;
killEvents(event); killEvents(event);
break; break;
@ -125,9 +218,10 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
editNameCursorPos = cur; editNameCursorPos = cur;
} }
} }
#endif
#if !defined(CPUM64) #if !defined(CPUM64)
void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint8_t size, uint8_t event, uint8_t active) void editSingleName(coord_t x, coord_t y, const pm_char * label, char * name, uint8_t size, uint8_t event, uint8_t active)
{ {
lcdDrawTextAlignedLeft(y, label); lcdDrawTextAlignedLeft(y, label);
editName(x, y, name, size, event, active); editName(x, y, name, size, event, active);

View file

@ -23,7 +23,7 @@
#if defined(CPUARM) #if defined(CPUARM)
void menuRadioSpecialFunctions(uint8_t event) void menuRadioSpecialFunctions(uint8_t event)
{ {
MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|4/*repeated*/ });
return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext); return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext);
} }
#endif #endif

View file

@ -23,64 +23,53 @@
#include "keys.h" #include "keys.h"
#define MENUS_SCROLLBAR_WIDTH 0 #if defined(PCBX7D)
#define MENU_COLUMNS 1 typedef int8_t horzpos_t;
#define COLUMN_X 0 #define NAVIGATION_LINE_BY_LINE 0x40
#define drawFieldLabel(x, y, str) lcdDrawTextAlignedLeft(y, str) #define IS_LINE_SELECTED(sub, k) ((sub)==(k) && menuHorizontalPosition < 0)
// Menus related stuff ...
#if defined(SDCARD)
typedef uint16_t vertpos_t;
#else #else
typedef uint8_t vertpos_t; typedef uint8_t horzpos_t;
#define NAVIGATION_LINE_BY_LINE 0
#define IS_LINE_SELECTED(sub, k) (false)
#endif #endif
#define horzpos_t uint8_t #if defined(SDCARD)
typedef uint16_t vertpos_t;
#else
typedef uint8_t vertpos_t;
#endif
typedef void (*MenuHandlerFunc)(uint8_t event);
#if defined(CPUARM) #if defined(CPUARM)
extern tmr10ms_t menuEntryTime; extern tmr10ms_t menuEntryTime;
#endif #endif
extern vertpos_t menuVerticalPosition; extern vertpos_t menuVerticalPosition;
extern horzpos_t menuHorizontalPosition; extern horzpos_t menuHorizontalPosition;
extern vertpos_t menuVerticalOffset; extern vertpos_t menuVerticalOffset;
extern uint8_t calibrationState; extern uint8_t menuCalibrationState;
// Temporary no highlight
extern uint8_t noHighlightCounter;
#define NO_HIGHLIGHT() (noHighlightCounter > 0)
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
typedef void (* MenuHandlerFunc)(uint8_t event);
extern MenuHandlerFunc menuHandlers[5]; extern MenuHandlerFunc menuHandlers[5];
extern uint8_t menuVerticalPositions[4]; extern uint8_t menuVerticalPositions[4];
extern uint8_t menuLevel; extern uint8_t menuLevel;
extern uint8_t menuEvent; extern uint8_t menuEvent;
/// goto given Menu, but substitute current menu in menuStack
void chainMenu(MenuHandlerFunc newMenu); void chainMenu(MenuHandlerFunc newMenu);
/// goto given Menu, store current menu in menuStack
void pushMenu(MenuHandlerFunc newMenu); void pushMenu(MenuHandlerFunc newMenu);
/// return to last menu in menustack
void popMenu(); void popMenu();
///deliver address of last menu which was popped from
inline MenuHandlerFunc lastPopMenu() inline MenuHandlerFunc lastPopMenu()
{ {
return menuHandlers[menuLevel+1]; return menuHandlers[menuLevel+1];
} }
void drawPotsBars();
void doMainScreenGraphics();
void menuFirstCalib(uint8_t event);
void onMainViewMenu(const char * result); void onMainViewMenu(const char * result);
void menuFirstCalib(uint8_t event);
void menuMainView(uint8_t event); void menuMainView(uint8_t event);
void menuViewTelemetryFrsky(uint8_t event); void menuViewTelemetryFrsky(uint8_t event);
void menuViewTelemetryMavlink(uint8_t event); void menuViewTelemetryMavlink(uint8_t event);
void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
enum MenuRadioIndexes enum MenuRadioIndexes
@ -90,9 +79,9 @@ enum MenuRadioIndexes
CASE_CPUARM(MENU_RADIO_SPECIAL_FUNCTIONS) CASE_CPUARM(MENU_RADIO_SPECIAL_FUNCTIONS)
MENU_RADIO_TRAINER, MENU_RADIO_TRAINER,
MENU_RADIO_VERSION, MENU_RADIO_VERSION,
MENU_RADIO_DIAG_KEYS, MENU_RADIO_SWITCHES_TEST,
MENU_RADIO_DIAG_ANALOGS, MENU_RADIO_ANALOGS_TEST,
CASE_CPUARM(MENU_RADIO_HARDWARE) CASE_PCBSKY9X(MENU_RADIO_HARDWARE)
MENU_RADIO_CALIBRATION, MENU_RADIO_CALIBRATION,
MENU_RADIO_PAGES_COUNT MENU_RADIO_PAGES_COUNT
}; };
@ -115,11 +104,11 @@ static const MenuHandlerFunc menuTabGeneral[] PROGMEM = {
menuRadioVersion, menuRadioVersion,
menuRadioDiagKeys, menuRadioDiagKeys,
menuRadioDiagAnalogs, menuRadioDiagAnalogs,
CASE_CPUARM(menuRadioHardware) CASE_PCBSKY9X(menuRadioHardware)
menuRadioCalibration menuRadioCalibration
}; };
enum EnumTabModel { enum MenuModelIndexes {
MENU_MODEL_SELECT, MENU_MODEL_SELECT,
MENU_MODEL_SETUP, MENU_MODEL_SETUP,
CASE_HELI(MENU_MODEL_HELI) CASE_HELI(MENU_MODEL_HELI)
@ -132,6 +121,7 @@ enum EnumTabModel {
MENU_MODEL_SPECIAL_FUNCTIONS, MENU_MODEL_SPECIAL_FUNCTIONS,
CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY) CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY)
CASE_MAVLINK(MENU_MODEL_TELEMETRY_MAVLINK) CASE_MAVLINK(MENU_MODEL_TELEMETRY_MAVLINK)
CASE_CPUARM(MENU_MODEL_DISPLAY)
CASE_TEMPLATES(MENU_MODEL_TEMPLATES) CASE_TEMPLATES(MENU_MODEL_TEMPLATES)
MENU_MODEL_PAGES_COUNT MENU_MODEL_PAGES_COUNT
}; };
@ -150,6 +140,7 @@ void menuModelLogicalSwitches(uint8_t event);
void menuModelSpecialFunctions(uint8_t event); void menuModelSpecialFunctions(uint8_t event);
void menuModelTelemetryFrsky(uint8_t event); void menuModelTelemetryFrsky(uint8_t event);
void menuModelTelemetryMavlink(uint8_t event); void menuModelTelemetryMavlink(uint8_t event);
void menuModelDisplay(uint8_t event);
void menuModelTemplates(uint8_t event); void menuModelTemplates(uint8_t event);
void menuModelExpoOne(uint8_t event); void menuModelExpoOne(uint8_t event);
@ -166,404 +157,16 @@ static const MenuHandlerFunc menuTabModel[] PROGMEM = {
menuModelSpecialFunctions, menuModelSpecialFunctions,
CASE_FRSKY(menuModelTelemetryFrsky) CASE_FRSKY(menuModelTelemetryFrsky)
CASE_MAVLINK(menuModelTelemetryMavlink) CASE_MAVLINK(menuModelTelemetryMavlink)
CASE_CPUARM(menuModelDisplay)
CASE_TEMPLATES(menuModelTemplates) CASE_TEMPLATES(menuModelTemplates)
}; };
void menuStatisticsView(uint8_t event); void menuStatisticsView(uint8_t event);
void menuStatisticsDebug(uint8_t event); void menuStatisticsDebug(uint8_t event);
void menuAboutView(uint8_t event); void menuAboutView(uint8_t event);
#if defined(DEBUG_TRACE_BUFFER) #if defined(DEBUG_TRACE_BUFFER)
void menuTraceBuffer(uint8_t event); void menuTraceBuffer(uint8_t event);
#endif #endif
#if !defined(CPUM64)
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
#elif defined(GRAPHICS)
void display5posSlider(coord_t x, coord_t y, uint8_t value, uint8_t attr);
#define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
#else
#define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
#endif
#if defined(NAVIGATION_POT1)
extern int16_t p1valdiff;
#else
#define p1valdiff 0
#endif
#if defined(NAVIGATION_POT2)
extern int8_t p2valdiff;
#else
#define p2valdiff 0
#endif
extern int8_t checkIncDec_Ret; // global helper vars
#define EDIT_SELECT_MENU -1
#define EDIT_SELECT_FIELD 0
#define EDIT_MODIFY_FIELD 1
#define EDIT_MODIFY_STRING 2
extern int8_t s_editMode; // global editmode
// checkIncDec flags
#define EE_GENERAL 0x01
#define EE_MODEL 0x02
#define NO_INCDEC_MARKS 0x04
#define INCDEC_SWITCH 0x08
#define INCDEC_SOURCE 0x10
#define INCDEC_REP10 0x40
#define NO_DBLKEYS 0x80
#if defined(CPUARM)
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
#elif defined(CPUM64)
#define INCDEC_DECLARE_VARS(f)
#define INCDEC_SET_FLAG(f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL)
#else
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f)
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
#endif
// mawrow special values
#define TITLE_ROW ((uint8_t)-1)
#define HIDDEN_ROW ((uint8_t)-2)
#if defined(CPUARM)
struct CheckIncDecStops {
const int count;
const int stops[];
int min() const
{
return stops[0];
}
int max() const
{
return stops[count-1];
}
bool contains(int value) const
{
for (int i=0; i<count; ++i) {
int stop = stops[i];
if (value == stop)
return true;
else if (value < stop)
return false;
}
return false;
}
};
extern const CheckIncDecStops &stops100;
extern const CheckIncDecStops &stops1000;
extern const CheckIncDecStops &stopsSwitch;
#define INIT_STOPS(var, ...) \
const int _ ## var[] = { __VA_ARGS__ }; \
const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
#define CATEGORY_END(val) \
(val), (val+1)
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100);
#else
int16_t checkIncDec(uint8_t event, int16_t i_pval, int16_t i_min, int16_t i_max, uint8_t i_flags=0);
#endif
int8_t checkIncDecMovedSwitch(int8_t val);
#if defined(CPUM64)
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
int8_t checkIncDecModelZero(uint8_t event, int8_t i_val, int8_t i_max);
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
#else
#define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
#define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
#define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
#endif
#define CHECK_INCDEC_MODELVAR(event, var, min, max) \
var = checkIncDecModel(event,var,min,max)
#define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
var = checkIncDecModelZero(event,var,max)
#if defined(CPUARM)
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
var = checkIncDec(event, var, min, max, EE_MODEL, check)
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
var = checkIncDec(event, var, 0, max, EE_MODEL, check)
#else
#define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
var = checkIncDec(event, var, min, max, EE_MODEL)
#define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
CHECK_INCDEC_MODELVAR_ZERO(event, var, max)
#endif
#if defined(CPUARM)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#elif defined(AUTOSWITCH)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#else
#define AUTOSWITCH_ENTER_LONG() (0)
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#endif
#if defined(CPUARM)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
#elif defined(AUTOSOURCE)
#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS)
#else
#define CHECK_INCDEC_MODELSOURCE CHECK_INCDEC_MODELVAR
#endif
#define CHECK_INCDEC_GENVAR(event, var, min, max) \
var = checkIncDecGen(event, var, min, max)
#define NAVIGATION_LINE_BY_LINE 0
#define CURSOR_ON_LINE() (0)
void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow);
void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t maxrow);
void check_submenu_simple(event_t event, uint8_t maxrow);
void title(const pm_char * s);
#define TITLE(str) title(str)
#if defined(CPUARM)
#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
#else
#define MENU_TAB(...) static const pm_uint8_t mstate_tab[] PROGMEM = __VA_ARGS__
#endif
#define MENU_CHECK(tab, menu, lines_count) \
check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-1)
#define MENU(title, tab, menu, lines_count, ...) \
MENU_TAB(__VA_ARGS__); \
MENU_CHECK(tab, menu, lines_count); \
TITLE(title)
#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
check_simple(event, menu, tab, DIM(tab), (lines_count)-1);
#define SIMPLE_MENU(title, tab, menu, lines_count) \
SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \
TITLE(title)
#define SUBMENU_NOTITLE(lines_count, ...) { \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
}
#define SUBMENU(title, lines_count, ...) \
MENU_TAB(__VA_ARGS__); \
check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
TITLE(title)
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
check_submenu_simple(event, (lines_count)-1);
#define SIMPLE_SUBMENU(title, lines_count) \
SIMPLE_SUBMENU_NOTITLE(lines_count); \
TITLE(title)
#if defined(CPUARM)
typedef int select_menu_value_t;
#else
typedef int8_t select_menu_value_t;
#endif
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event);
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event);
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event);
#define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
#if defined(CPUARM) && defined(GVARS)
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
#else
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event)
#endif
#if defined(GVARS)
#if defined(CPUARM)
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event);
#else
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); // @@@ open.20.fsguruh
#endif
#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
#else
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event);
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
#endif
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active);
#if defined(CPUM64)
#define editSingleName(x, y, label, name, size, event, active) editName(x, y, name, size, event, active)
#else
void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint8_t size, uint8_t event, uint8_t active);
#endif
uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, const pm_char * str, uint8_t delay);
#define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
#define WARNING_TYPE_ASTERISK 0
#define WARNING_TYPE_CONFIRM 1
#define WARNING_TYPE_INPUT 2
extern const pm_char * warningText;
extern const pm_char * warningInfoText;
extern uint8_t warningInfoLength;
extern uint8_t warningResult;
extern uint8_t warningType;
#define COPY_MODE 1
#define MOVE_MODE 2
extern uint8_t s_copyMode;
extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx;
extern uint8_t s_curveChan;
#define MENU_X 10
#define MENU_Y 16
#define MENU_W LCD_W-(2*MENU_X)
#define WARNING_LINE_LEN 20
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
void drawMessageBox();
void showMessageBox(const pm_char * pstr);
void runPopupWarning(uint8_t event);
#if defined(CPUARM)
extern void (*popupFunc)(uint8_t event);
extern int16_t warningInputValue;
extern int16_t warningInputValueMin;
extern int16_t warningInputValueMax;
extern uint8_t warningInfoFlags;
#endif
#if !defined(GUI)
#define DISPLAY_WARNING(...)
#define POPUP_WARNING(...)
#define POPUP_CONFIRMATION(...)
#define POPUP_INPUT(...)
#define WARNING_INFO_FLAGS 0
#define SET_WARNING_INFO(...)
#elif defined(CPUARM)
#define DISPLAY_WARNING (*popupFunc)
#define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max)
#define WARNING_INFO_FLAGS warningInfoFlags
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
#else
#define DISPLAY_WARNING runPopupWarning
#define POPUP_WARNING(s) warningText = s
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM)
#define WARNING_INFO_FLAGS ZCHAR
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len)
#endif
#if defined(SDCARD) || (defined(ROTARY_ENCODER_NAVIGATION) && !defined(CPUM64))
#define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) popupMenuItems[popupMenuNoItems++] = s
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while(0)
#define POPUP_MENU_MAX_LINES 6
#define MENU_MAX_DISPLAY_LINES POPUP_MENU_MAX_LINES
#if defined(SDCARD)
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s)
#else
#define POPUP_MENU_ADD_SD_ITEM(s)
#endif
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+1)
#define POPUP_MENU_ITEMS_FROM_BSS() (popupMenuFlags = BSS)
extern const char *popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems;
extern uint8_t popupMenuFlags;
extern uint16_t popupMenuOffset;
const char * runPopupMenu(uint8_t event);
extern void (*popupMenuHandler)(const char *result);
#else
#define popupMenuNoItems 0
#endif
#if defined(SDCARD)
#define STATUS_LINE_LENGTH 32
extern char statusLineMsg[STATUS_LINE_LENGTH];
void showStatusLine();
void drawStatusLine();
#else
#define drawStatusLine()
#endif
#if defined(CPUARM)
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(uint8_t event);
void pushMenuTextView(const char *filename);
void pushModelNotes();
#endif
#define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)
#if defined(ROTARY_ENCODER_NAVIGATION)
#define IS_ROTARY_LEFT(evt) (evt == EVT_ROTARY_LEFT)
#define IS_ROTARY_RIGHT(evt) (evt == EVT_ROTARY_RIGHT)
#define IS_ROTARY_BREAK(evt) (evt == EVT_ROTARY_BREAK)
#define IS_ROTARY_LONG(evt) (evt == EVT_ROTARY_LONG)
#define IS_ROTARY_EVENT(evt) (EVT_KEY_MASK(evt) >= 0x0e)
#define CASE_EVT_ROTARY_BREAK case EVT_ROTARY_BREAK:
#define CASE_EVT_ROTARY_LONG case EVT_ROTARY_LONG:
#define CASE_EVT_ROTARY_LEFT case EVT_ROTARY_LEFT:
#define CASE_EVT_ROTARY_RIGHT case EVT_ROTARY_RIGHT:
void repeatLastCursorMove(uint8_t event);
#define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) putEvent(event); else repeatLastCursorMove(event); }
#define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE()
#else
#define IS_ROTARY_LEFT(evt) (0)
#define IS_ROTARY_RIGHT(evt) (0)
#define IS_ROTARY_BREAK(evt) (0)
#define IS_ROTARY_LONG(evt) (0)
#define IS_ROTARY_EVENT(evt) (0)
#define CASE_EVT_ROTARY_BREAK
#define CASE_EVT_ROTARY_LONG
#define CASE_EVT_ROTARY_LEFT
#define CASE_EVT_ROTARY_RIGHT
void repeatLastCursorMove(uint8_t event);
#define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event)
#define MOVE_CURSOR_FROM_HERE() REPEAT_LAST_CURSOR_MOVE()
#endif
#define POS_HORZ_INIT(posVert) 0
#define EDIT_MODE_INIT -1
typedef int16_t (*FnFuncP) (int16_t x);
void drawFunction(FnFuncP fn, uint8_t offset=0);
uint8_t switchToMix(uint8_t source);
void deleteExpoMix(uint8_t expo, uint8_t idx);
#endif // _MENUS_H_ #endif // _MENUS_H_

View file

@ -20,73 +20,6 @@
#include "opentx.h" #include "opentx.h"
uint8_t s_curveChan;
int16_t curveFn(int16_t x)
{
return applyCustomCurve(x, s_curveChan);
}
struct point_t {
coord_t x;
coord_t y;
};
point_t getPoint(uint8_t i)
{
point_t result = {0, 0};
CurveInfo crv = curveInfo(s_curveChan);
int8_t *points = crv.crv;
bool custom = crv.custom;
uint8_t count = crv.points;
if (i < count) {
result.x = X0-1-WCHART+i*WCHART/(count/2);
result.y = (LCD_H-1) - (100 + points[i]) * (LCD_H-1) / 200;
if (custom && i>0 && i<count-1)
result.x = X0-1-WCHART + (100 + (100 + points[count+i-1]) * (2*WCHART)) / 200;
}
return result;
}
void DrawCurve(uint8_t offset=0)
{
drawFunction(curveFn, offset);
uint8_t i = 0;
do {
point_t point = getPoint(i);
i++;
if (point.x == 0) break;
lcdDrawFilledRect(point.x-offset, point.y-1, 3, 3, SOLID, FORCE); // do markup square
} while(1);
}
bool moveCurve(uint8_t index, int8_t shift, int8_t custom=0)
{
if (g_model.curves[MAX_CURVES-1] + shift > NUM_POINTS-5*MAX_CURVES) {
AUDIO_WARNING2();
return false;
}
int8_t *crv = curveAddress(index);
if (shift < 0) {
for (uint8_t i=0; i<custom; i++)
crv[i] = crv[2*i];
}
int8_t *nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+g_model.curves[MAX_CURVES-1]-g_model.curves[index]);
if (shift < 0) memclear(&g_model.points[NUM_POINTS-1] + shift, -shift);
while (index<MAX_CURVES)
g_model.curves[index++] += shift;
for (uint8_t i=0; i<custom-2; i++)
crv[custom+i] = -100 + ((200 * (i+1) + custom/2) / (custom-1)) ;
storageDirty(EE_MODEL);
return true;
}
void menuModelCurveOne(uint8_t event) void menuModelCurveOne(uint8_t event)
{ {
TITLE(STR_MENUCURVE); TITLE(STR_MENUCURVE);
@ -95,10 +28,11 @@ void menuModelCurveOne(uint8_t event)
CurveInfo crv = curveInfo(s_curveChan); CurveInfo crv = curveInfo(s_curveChan);
switch(event) { switch (event) {
case EVT_ENTRY: case EVT_ENTRY:
s_editMode = 1; s_editMode = 1;
break; break;
CASE_EVT_ROTARY_BREAK CASE_EVT_ROTARY_BREAK
case EVT_KEY_BREAK(KEY_ENTER): case EVT_KEY_BREAK(KEY_ENTER):
if (s_editMode <= 0) if (s_editMode <= 0)
@ -108,6 +42,7 @@ void menuModelCurveOne(uint8_t event)
else else
s_editMode = 1; s_editMode = 1;
break; break;
case EVT_KEY_LONG(KEY_ENTER): case EVT_KEY_LONG(KEY_ENTER):
if (s_editMode <= 0) { if (s_editMode <= 0) {
if (int8_t(++menuHorizontalPosition) > 4) if (int8_t(++menuHorizontalPosition) > 4)
@ -118,6 +53,7 @@ void menuModelCurveOne(uint8_t event)
killEvents(event); killEvents(event);
} }
break; break;
case EVT_KEY_BREAK(KEY_EXIT): case EVT_KEY_BREAK(KEY_EXIT):
if (s_editMode > 0) { if (s_editMode > 0) {
if (--s_editMode == 0) if (--s_editMode == 0)
@ -136,7 +72,7 @@ void menuModelCurveOne(uint8_t event)
if (crv.custom) { if (crv.custom) {
moveCurve(s_curveChan, -crv.points+2); moveCurve(s_curveChan, -crv.points+2);
} }
else if (crv.points > MIN_POINTS) { else if (crv.points > MIN_POINTS_PER_CURVE) {
moveCurve(s_curveChan, -1, (crv.points+1)/2); moveCurve(s_curveChan, -1, (crv.points+1)/2);
} }
else { else {
@ -154,7 +90,7 @@ void menuModelCurveOne(uint8_t event)
if (!crv.custom) { if (!crv.custom) {
moveCurve(s_curveChan, crv.points-2, crv.points); moveCurve(s_curveChan, crv.points-2, crv.points);
} }
else if (crv.points < MAX_POINTS) { else if (crv.points < MAX_POINTS_PER_CURVE) {
if (moveCurve(s_curveChan, 1)) { if (moveCurve(s_curveChan, 1)) {
for (int8_t i=crv.points+crv.points-2; i>=0; i--) { for (int8_t i=crv.points+crv.points-2; i>=0; i--) {
if (i%2) if (i%2)
@ -176,7 +112,7 @@ void menuModelCurveOne(uint8_t event)
lcdDrawNumber(5*FW-2, 7*FH, crv.points, LEFT|attr); lcdDrawNumber(5*FW-2, 7*FH, crv.points, LEFT|attr);
lcdDrawText(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr); lcdDrawText(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr);
DrawCurve(); drawCurve();
if (s_editMode>0) { if (s_editMode>0) {
uint8_t i = menuHorizontalPosition; uint8_t i = menuHorizontalPosition;
@ -201,59 +137,3 @@ void menuModelCurveOne(uint8_t event)
CHECK_INCDEC_MODELVAR(event, crv.crv[crv.points+i-1], i==1 ? -99 : crv.crv[crv.points+i-2]+1, i==crv.points-2 ? 99 : crv.crv[crv.points+i]-1); // edit X on left/right CHECK_INCDEC_MODELVAR(event, crv.crv[crv.points+i-1], i==1 ? -99 : crv.crv[crv.points+i-2]+1, i==crv.points-2 ? 99 : crv.crv[crv.points+i]-1); // edit X on left/right
} }
} }
#if defined(GVARS)
#define CURVE_SELECTED() (sub >= 0 && sub < MAX_CURVES)
#define GVAR_SELECTED() (sub >= MAX_CURVES)
#else
#define CURVE_SELECTED() (sub >= 0)
#endif
void menuModelCurvesAll(uint8_t event)
{
#if defined(GVARS) && defined(PCBSTD)
SIMPLE_MENU(STR_MENUCURVES, menuTabModel, MENU_MODEL_CURVES, 1+MAX_CURVES+MAX_GVARS);
#else
SIMPLE_MENU(STR_MENUCURVES, menuTabModel, MENU_MODEL_CURVES, 1+MAX_CURVES);
#endif
int8_t sub = menuVerticalPosition - 1;
switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK:
#endif
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_ENTER):
if (CURVE_SELECTED() && !READ_ONLY()) {
s_curveChan = sub;
pushMenu(menuModelCurveOne);
}
break;
}
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i + menuVerticalOffset;
uint8_t attr = (sub == k ? INVERS : 0);
#if defined(GVARS) && defined(PCBSTD)
if (k >= MAX_CURVES) {
drawStringWithIndex(0, y, STR_GV, k-MAX_CURVES+1);
if (GVAR_SELECTED()) {
if (attr && s_editMode>0) attr |= BLINK;
lcdDrawNumber(10*FW, y, GVAR_VALUE(k-MAX_CURVES, -1), attr);
if (attr) g_model.gvars[k-MAX_CURVES] = checkIncDec(event, g_model.gvars[k-MAX_CURVES], -1000, 1000, EE_MODEL);
}
}
else
#endif
{
drawStringWithIndex(0, y, STR_CV, k+1, attr);
}
}
if (CURVE_SELECTED()) {
s_curveChan = sub;
DrawCurve(23);
}
}

View file

@ -0,0 +1,241 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
enum MenuModelDisplayItems {
ITEM_DISPLAY_SCREEN_LABEL1,
ITEM_DISPLAY_SCREEN_LINE1,
ITEM_DISPLAY_SCREEN_LINE2,
ITEM_DISPLAY_SCREEN_LINE3,
ITEM_DISPLAY_SCREEN_LINE4,
ITEM_DISPLAY_SCREEN_LABEL2,
ITEM_DISPLAY_SCREEN_LINE5,
ITEM_DISPLAY_SCREEN_LINE6,
ITEM_DISPLAY_SCREEN_LINE7,
ITEM_DISPLAY_SCREEN_LINE8,
ITEM_DISPLAY_SCREEN_LABEL3,
ITEM_DISPLAY_SCREEN_LINE9,
ITEM_DISPLAY_SCREEN_LINE10,
ITEM_DISPLAY_SCREEN_LINE11,
ITEM_DISPLAY_SCREEN_LINE12,
ITEM_DISPLAY_SCREEN_LABEL4,
ITEM_DISPLAY_SCREEN_LINE13,
ITEM_DISPLAY_SCREEN_LINE14,
ITEM_DISPLAY_SCREEN_LINE15,
ITEM_DISPLAY_SCREEN_LINE16,
ITEM_DISPLAY_MAX
};
#define DISPLAY_COL1 (1*FW)
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_CZ)
#define DISPLAY_COL2 (9*FW)
#else
#define DISPLAY_COL2 (8*FW)
#endif
#define DISPLAY_COL3 (18*FW+2)
#if defined(LUA)
#define SCREEN_TYPE_ROWS 1
#define DISPLAY_LINE_ROWS(x) ((TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE || TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_SCRIPT) ? HIDDEN_ROW : (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_GAUGES ? (uint8_t)2 : (uint8_t)1))
#else
#define SCREEN_TYPE_ROWS 0
#define DISPLAY_LINE_ROWS(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_GAUGES ? (uint8_t)2 : (uint8_t)1))
#endif
#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x)
#define TELEMETRY_CURRENT_SCREEN(k) (k < ITEM_DISPLAY_SCREEN_LABEL2 ? 0 : (k < ITEM_DISPLAY_SCREEN_LABEL3 ? 1 : (k < ITEM_DISPLAY_SCREEN_LABEL4 ? 2 : 3)))
#if defined(LUA)
void onTelemetryScriptFileSelectionMenu(const char *result)
{
int screenIndex = TELEMETRY_CURRENT_SCREEN(menuVerticalPosition - HEADER_LINE);
if (result == STR_UPDATE_LIST) {
if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) {
POPUP_WARNING(STR_NO_SCRIPTS_ON_SD);
}
}
else {
// The user choosed a file in the list
memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file));
storageDirty(EE_MODEL);
LUA_LOAD_MODEL_SCRIPTS();
}
}
#endif
void menuModelDisplay(uint8_t event)
{
MENU(STR_MENU_DISPLAY, menuTabModel, MENU_MODEL_DISPLAY, HEADER_LINE + ITEM_DISPLAY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), TELEMETRY_SCREEN_ROWS(2), TELEMETRY_SCREEN_ROWS(3) });
int8_t sub = menuVerticalPosition - HEADER_LINE;
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
int k = i + menuVerticalOffset;
for (int j=0; j<=k; j++) {
if (mstate_tab[j+HEADER_LINE] == HIDDEN_ROW) {
k++;
}
}
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (sub == k ? blink : 0);
switch (k) {
case ITEM_DISPLAY_SCREEN_LABEL1:
case ITEM_DISPLAY_SCREEN_LABEL2:
case ITEM_DISPLAY_SCREEN_LABEL3:
case ITEM_DISPLAY_SCREEN_LABEL4:
{
uint8_t screenIndex = TELEMETRY_CURRENT_SCREEN(k);
drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex+1);
TelemetryScreenType oldScreenType = TELEMETRY_SCREEN_TYPE(screenIndex);
TelemetryScreenType newScreenType = (TelemetryScreenType)selectMenuItem(DISPLAY_COL2, y, PSTR(""), STR_VTELEMSCREENTYPE, oldScreenType, 0, TELEMETRY_SCREEN_TYPE_MAX, (menuHorizontalPosition==0 ? attr : 0), event);
if (newScreenType != oldScreenType) {
g_model.frsky.screensType = (g_model.frsky.screensType & (~(0x03 << (2*screenIndex)))) | (newScreenType << (2*screenIndex));
memset(&g_model.frsky.screens[screenIndex], 0, sizeof(g_model.frsky.screens[screenIndex]));
}
#if defined(LUA)
if (newScreenType == TELEMETRY_SCREEN_TYPE_SCRIPT) {
TelemetryScriptData & scriptData = g_model.frsky.screens[screenIndex].script;
// TODO better function name for ---
// TODO function for these lines
if (ZEXIST(scriptData.file))
lcdDrawSizedText(DISPLAY_COL2+7*FW, y, scriptData.file, sizeof(scriptData.file), (menuHorizontalPosition==1 ? attr : 0));
else
lcdDrawTextAtIndex(DISPLAY_COL2+7*FW, y, STR_VCSWFUNC, 0, (menuHorizontalPosition==1 ? attr : 0));
if (menuHorizontalPosition==1 && attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) {
s_editMode = 0;
if (sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), g_model.frsky.screens[screenIndex].script.file)) {
POPUP_MENU_START(onTelemetryScriptFileSelectionMenu);
}
else {
POPUP_WARNING(STR_NO_SCRIPTS_ON_SD);
}
}
}
else if (attr) {
MOVE_CURSOR_FROM_HERE();
}
#endif
break;
}
case ITEM_DISPLAY_SCREEN_LINE1:
case ITEM_DISPLAY_SCREEN_LINE2:
case ITEM_DISPLAY_SCREEN_LINE3:
case ITEM_DISPLAY_SCREEN_LINE4:
case ITEM_DISPLAY_SCREEN_LINE5:
case ITEM_DISPLAY_SCREEN_LINE6:
case ITEM_DISPLAY_SCREEN_LINE7:
case ITEM_DISPLAY_SCREEN_LINE8:
case ITEM_DISPLAY_SCREEN_LINE9:
case ITEM_DISPLAY_SCREEN_LINE10:
case ITEM_DISPLAY_SCREEN_LINE11:
case ITEM_DISPLAY_SCREEN_LINE12:
case ITEM_DISPLAY_SCREEN_LINE13:
case ITEM_DISPLAY_SCREEN_LINE14:
case ITEM_DISPLAY_SCREEN_LINE15:
case ITEM_DISPLAY_SCREEN_LINE16:
{
uint8_t screenIndex, lineIndex;
if (k < ITEM_DISPLAY_SCREEN_LABEL2) {
screenIndex = 0;
lineIndex = k-ITEM_DISPLAY_SCREEN_LINE1;
}
else if (k >= ITEM_DISPLAY_SCREEN_LABEL4) {
screenIndex = 3;
lineIndex = k-ITEM_DISPLAY_SCREEN_LINE13;
}
else if (k >= ITEM_DISPLAY_SCREEN_LABEL3) {
screenIndex = 2;
lineIndex = k-ITEM_DISPLAY_SCREEN_LINE9;
}
else {
screenIndex = 1;
lineIndex = k-ITEM_DISPLAY_SCREEN_LINE5;
}
if (IS_BARS_SCREEN(screenIndex)) {
FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex];
source_t barSource = bar.source;
drawSource(DISPLAY_COL1, y, barSource, menuHorizontalPosition==0 ? attr : 0);
int barMax = getMaximumValue(barSource);
int barMin = -barMax;
if (barSource) {
if (barSource <= MIXSRC_LAST_CH) {
putsChannelValue(DISPLAY_COL2, y, barSource, calc100toRESX(bar.barMin), (menuHorizontalPosition==1 ? attr : 0) | LEFT);
putsChannelValue(DISPLAY_COL3, y, barSource, calc100toRESX(bar.barMax), (menuHorizontalPosition==2 ? attr : 0) | LEFT);
}
else {
putsChannelValue(DISPLAY_COL2, y, barSource, bar.barMin, (menuHorizontalPosition==1 ? attr : 0) | LEFT);
putsChannelValue(DISPLAY_COL3, y, barSource, bar.barMax, (menuHorizontalPosition==2 ? attr : 0) | LEFT);
}
}
else if (attr) {
MOVE_CURSOR_FROM_HERE();
}
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
bar.source = checkIncDec(event, barSource, 0, MIXSRC_LAST_TELEM, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable);
if (checkIncDec_Ret) {
if (barSource <= MIXSRC_LAST_CH) {
bar.barMin = -100;
bar.barMax = 100;
}
else {
bar.barMin = 0;
bar.barMax = 0;
}
}
break;
case 1:
bar.barMin = checkIncDec(event, bar.barMin, barMin, bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
break;
case 2:
bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
break;
}
}
}
else {
for (int c=0; c<NUM_LINE_ITEMS; c++) {
LcdFlags cellAttr = (menuHorizontalPosition==c ? attr : 0);
source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c];
const coord_t pos[] = {DISPLAY_COL1, DISPLAY_COL2, DISPLAY_COL3};
drawSource(pos[c], y, value, cellAttr);
if (cellAttr && s_editMode>0) {
value = checkIncDec(event, value, 0, MIXSRC_LAST_TELEM, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable);
}
}
if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) {
REPEAT_LAST_CURSOR_MOVE();
}
}
break;
}
}
}
}

View file

@ -31,7 +31,31 @@ void displayFlightModes(coord_t x, coord_t y, FlightModesType value)
} while (p!=0); } while (p!=0);
} }
enum menuModelPhaseItems { #if !defined(CPUARM)
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
drawFieldLabel(x, y, STR_FLMODE);
uint8_t posHorz = menuHorizontalPosition;
for (uint8_t p=0; p<MAX_FLIGHT_MODES; p++) {
lcdDrawChar(x, y, '0'+p, ((posHorz==p) && attr) ? BLINK|INVERS : ((value & (1<<p)) ? 0 : INVERS));
x += FW;
}
if (attr) {
if (s_editMode && ((event==EVT_KEY_BREAK(KEY_ENTER) || p1valdiff))) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
#endif
enum MenuModelPhaseItems {
ITEM_MODEL_PHASE_NAME, ITEM_MODEL_PHASE_NAME,
ITEM_MODEL_PHASE_SWITCH, ITEM_MODEL_PHASE_SWITCH,
ITEM_MODEL_PHASE_TRIMS, ITEM_MODEL_PHASE_TRIMS,
@ -55,22 +79,27 @@ enum menuModelPhaseItems {
ITEM_MODEL_PHASE_MAX ITEM_MODEL_PHASE_MAX
}; };
bool isTrimModeAvailable(int mode)
{
return (mode < 0 || (mode%2) == 0 || (mode/2) != s_currIdx);
}
void menuModelPhaseOne(uint8_t event) void menuModelPhaseOne(uint8_t event)
{ {
FlightModeData *fm = flightModeAddress(s_currIdx); FlightModeData * fm = flightModeAddress(s_currIdx);
putsFlightMode(13*FW, 0, s_currIdx+1, (getFlightMode()==s_currIdx ? BOLD : 0)); drawFlightMode(13*FW, 0, s_currIdx+1, (getFlightMode()==s_currIdx ? BOLD : 0));
#if defined(GVARS) && !defined(PCBSTD) #if defined(GVARS) && !defined(GVARS_IN_CURVES_SCREEN)
static const pm_uint8_t mstate_tab_fm1[] PROGMEM = {0, 0, 0, (uint8_t)-1, 1, 1, 1, 1, 1}; static const pm_uint8_t mstate_tab_fm1[] PROGMEM = {0, 0, 0, (uint8_t)-1, 1, 1, 1, 1, 1};
static const pm_uint8_t mstate_tab_others[] PROGMEM = {0, 0, 3, IF_ROTARY_ENCODERS(NUM_ROTARY_ENCODERS-1) 0, 0, (uint8_t)-1, 2, 2, 2, 2, 2}; static const pm_uint8_t mstate_tab_others[] PROGMEM = {0, 0, 3, IF_ROTARY_ENCODERS(NUM_ROTARY_ENCODERS-1) 0, 0, (uint8_t)-1, 2, 2, 2, 2, 2};
check(event, 0, NULL, 0, (s_currIdx == 0) ? mstate_tab_fm1 : mstate_tab_others, DIM(mstate_tab_others)-1, ITEM_MODEL_PHASE_MAX - 1 - (s_currIdx==0 ? (ITEM_MODEL_PHASE_FADE_IN-ITEM_MODEL_PHASE_SWITCH) : 0)); check(event, 0, NULL, 0, (s_currIdx == 0) ? mstate_tab_fm1 : mstate_tab_others, DIM(mstate_tab_others)-1, ITEM_MODEL_PHASE_MAX - 1 - (s_currIdx==0 ? (ITEM_MODEL_PHASE_FADE_IN-ITEM_MODEL_PHASE_SWITCH) : 0));
TITLE(STR_MENUFLIGHTPHASE); TITLE(STR_MENUFLIGHTMODE);
#define PHASE_ONE_FIRST_LINE (1+1*FH) #define PHASE_ONE_FIRST_LINE (1+1*FH)
#else #else
SUBMENU(STR_MENUFLIGHTPHASE, 3 + (s_currIdx==0 ? 0 : 2 + (bool)NUM_ROTARY_ENCODERS), {0, 0, 3, IF_ROTARY_ENCODERS(NUM_ROTARY_ENCODERS-1) 0/*, 0*/}); SUBMENU(STR_MENUFLIGHTMODE, 3 + (s_currIdx==0 ? 0 : 2 + (bool)NUM_ROTARY_ENCODERS), {0, 0, 3, IF_ROTARY_ENCODERS(NUM_ROTARY_ENCODERS-1) 0/*, 0*/});
#define PHASE_ONE_FIRST_LINE (1+1*FH) #define PHASE_ONE_FIRST_LINE (1+1*FH)
#endif #endif
@ -90,27 +119,41 @@ void menuModelPhaseOne(uint8_t event)
if (s_currIdx == 0 && i==ITEM_MODEL_PHASE_SWITCH) i = ITEM_MODEL_PHASE_FADE_IN; if (s_currIdx == 0 && i==ITEM_MODEL_PHASE_SWITCH) i = ITEM_MODEL_PHASE_FADE_IN;
uint8_t attr = (sub==k ? (editMode>0 ? BLINK|INVERS : INVERS) : 0); uint8_t attr = (sub==k ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
#endif #endif
switch(i) { switch (i) {
case ITEM_MODEL_PHASE_NAME: case ITEM_MODEL_PHASE_NAME:
editSingleName(MIXES_2ND_COLUMN, y, STR_PHASENAME, fm->name, sizeof(fm->name), event, attr); editSingleName(MIXES_2ND_COLUMN, y, STR_PHASENAME, fm->name, sizeof(fm->name), event, attr);
break; break;
case ITEM_MODEL_PHASE_SWITCH: case ITEM_MODEL_PHASE_SWITCH:
fm->swtch = switchMenuItem(MIXES_2ND_COLUMN, y, fm->swtch, attr, event); fm->swtch = switchMenuItem(MIXES_2ND_COLUMN, y, fm->swtch, attr, event);
break; break;
case ITEM_MODEL_PHASE_TRIMS: case ITEM_MODEL_PHASE_TRIMS:
lcdDrawTextAlignedLeft(y, STR_TRIMS); lcdDrawTextAlignedLeft(y, STR_TRIMS);
for (uint8_t t=0; t<NUM_STICKS; t++) { #if defined(CPUARM)
putsTrimMode(MIXES_2ND_COLUMN+(t*FW), y, s_currIdx, t, menuHorizontalPosition==t ? attr : 0); for (uint8_t t = 0; t < NUM_STICKS; t++) {
if (attr && menuHorizontalPosition==t && ((editMode>0) || p1valdiff)) { drawTrimMode(MIXES_2ND_COLUMN + (t*2*FW), y, s_currIdx, t, menuHorizontalPosition == t ? attr : 0);
if (s_editMode && attr && menuHorizontalPosition == t) {
trim_t & v = fm->trim[t];
v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable);
}
}
#else
for (uint8_t t = 0; t < NUM_STICKS; t++) {
drawTrimMode(MIXES_2ND_COLUMN + (t*FW), y, s_currIdx, t, menuHorizontalPosition == t ? attr : 0);
if (attr && menuHorizontalPosition == t && ((editMode > 0) || p1valdiff)) {
int16_t v = getRawTrimValue(s_currIdx, t); int16_t v = getRawTrimValue(s_currIdx, t);
if (v < TRIM_EXTENDED_MAX) v = TRIM_EXTENDED_MAX; if (v < TRIM_EXTENDED_MAX)
v = checkIncDec(event, v, TRIM_EXTENDED_MAX, TRIM_EXTENDED_MAX+MAX_FLIGHT_MODES-1, EE_MODEL); v = TRIM_EXTENDED_MAX;
v = checkIncDec(event, v, TRIM_EXTENDED_MAX, TRIM_EXTENDED_MAX + MAX_FLIGHT_MODES - 1, EE_MODEL);
if (checkIncDec_Ret) { if (checkIncDec_Ret) {
if (v == TRIM_EXTENDED_MAX) v = 0; if (v == TRIM_EXTENDED_MAX)
v = 0;
setTrimValue(s_currIdx, t, v); setTrimValue(s_currIdx, t, v);
} }
} }
} }
#endif
break; break;
#if ROTARY_ENCODERS > 0 #if ROTARY_ENCODERS > 0
@ -158,7 +201,7 @@ void menuModelPhaseOne(uint8_t event)
if (v > GVAR_MAX) { if (v > GVAR_MAX) {
uint8_t p = v - GVAR_MAX - 1; uint8_t p = v - GVAR_MAX - 1;
if (p >= s_currIdx) p++; if (p >= s_currIdx) p++;
putsFlightMode(11*FW, y, p+1, posHorz==1 ? attr : 0); drawFlightMode(11*FW, y, p+1, posHorz==1 ? attr : 0);
} }
else { else {
lcdDrawText(11*FW, y, STR_OWN, posHorz==1 ? attr : 0); lcdDrawText(11*FW, y, STR_OWN, posHorz==1 ? attr : 0);
@ -205,9 +248,9 @@ void menuModelPhaseOne(uint8_t event)
void menuModelFlightModesAll(uint8_t event) void menuModelFlightModesAll(uint8_t event)
{ {
SIMPLE_MENU(STR_MENUFLIGHTPHASES, menuTabModel, MENU_MODEL_FLIGHT_MODES, 1+MAX_FLIGHT_MODES+1); SIMPLE_MENU(STR_MENUFLIGHTMODES, menuTabModel, MENU_MODEL_FLIGHT_MODES, HEADER_LINE+MAX_FLIGHT_MODES+1);
int8_t sub = menuVerticalPosition - 1; int8_t sub = menuVerticalPosition - HEADER_LINE;
switch (event) { switch (event) {
CASE_EVT_ROTARY_BREAK CASE_EVT_ROTARY_BREAK
@ -217,7 +260,9 @@ void menuModelFlightModesAll(uint8_t event)
trimsCheckTimer = 200; // 2 seconds trimsCheckTimer = 200; // 2 seconds
} }
// no break // no break
#if !defined(PCBX7D)
case EVT_KEY_FIRST(KEY_RIGHT): case EVT_KEY_FIRST(KEY_RIGHT):
#endif
if (sub >= 0 && sub < MAX_FLIGHT_MODES) { if (sub >= 0 && sub < MAX_FLIGHT_MODES) {
s_currIdx = sub; s_currIdx = sub;
pushMenu(menuModelPhaseOne); pushMenu(menuModelPhaseOne);
@ -234,17 +279,17 @@ void menuModelFlightModesAll(uint8_t event)
uint8_t y = 1 + (i+1)*FH; uint8_t y = 1 + (i+1)*FH;
#endif #endif
att = (i==sub ? INVERS : 0); att = (i==sub ? INVERS : 0);
FlightModeData *p = flightModeAddress(i); FlightModeData * p = flightModeAddress(i);
putsFlightMode(0, y, i+1, att|(getFlightMode()==i ? BOLD : 0)); drawFlightMode(0, y, i+1, att|(getFlightMode()==i ? BOLD : 0));
lcdDrawSizedText(4*FW+NAME_OFS, y, p->name, sizeof(p->name), ZCHAR); lcdDrawSizedText(4*FW+NAME_OFS, y, p->name, sizeof(p->name), ZCHAR);
if (i == 0) { if (i == 0) {
lcdDrawText((5+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, STR_DEFAULT); lcdDrawText((5+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, STR_DEFAULT);
} }
else { else {
putsSwitches((5+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, p->swtch, 0); drawSwitch((5+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, p->swtch, 0);
for (uint8_t t=0; t<NUM_STICKS; t++) { for (uint8_t t=0; t<NUM_STICKS; t++) {
putsTrimMode((9+LEN_FLIGHT_MODE_NAME+t)*FW+TRIMS_OFS, y, i, t, 0); drawShortTrimMode((9+LEN_FLIGHT_MODE_NAME+t)*FW+TRIMS_OFS, y, i, t, 0);
} }
#if defined(CPUM2560) #if defined(CPUM2560)
for (uint8_t t=0; t<NUM_ROTARY_ENCODERS; t++) { for (uint8_t t=0; t<NUM_ROTARY_ENCODERS; t++) {
@ -254,7 +299,7 @@ void menuModelFlightModesAll(uint8_t event)
} }
if (p->fadeIn || p->fadeOut) { if (p->fadeIn || p->fadeOut) {
lcdDrawChar(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, (p->fadeIn && p->fadeOut) ? '*' : (p->fadeIn ? 'I' : 'O')); lcdDrawChar(LCD_W-FW, y, (p->fadeIn && p->fadeOut) ? '*' : (p->fadeIn ? 'I' : 'O'));
} }
} }
@ -263,7 +308,7 @@ void menuModelFlightModesAll(uint8_t event)
#endif #endif
lcdDrawTextAlignedLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS); lcdDrawTextAlignedLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS);
putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, mixerCurrentFlightMode+1); drawFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, mixerCurrentFlightMode+1);
if (sub==MAX_FLIGHT_MODES && !trimsCheckTimer) { if (sub==MAX_FLIGHT_MODES && !trimsCheckTimer) {
lcdInvertLastLine(); lcdInvertLastLine();
} }

View file

@ -1,72 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
enum menuModelHeliItems {
ITEM_HELI_SWASHTYPE,
ITEM_HELI_COLLECTIVE,
ITEM_HELI_SWASHRING,
ITEM_HELI_ELEDIRECTION,
ITEM_HELI_AILDIRECTION,
ITEM_HELI_COLDIRECTION
};
#define HELI_PARAM_OFS (14*FW)
void menuModelHeli(uint8_t event)
{
SIMPLE_MENU(STR_MENUHELISETUP, menuTabModel, MENU_MODEL_HELI, 7);
uint8_t sub = menuVerticalPosition - 1;
for (uint8_t i=0; i<6; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t attr = (sub == i ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
switch(i) {
case ITEM_HELI_SWASHTYPE:
g_model.swashR.type = selectMenuItem(HELI_PARAM_OFS, y, STR_SWASHTYPE, STR_VSWASHTYPE, g_model.swashR.type, 0, SWASH_TYPE_MAX, attr, event);
break;
case ITEM_HELI_COLLECTIVE:
g_model.swashR.collectiveSource = selectMenuItem(HELI_PARAM_OFS, y, STR_COLLECTIVE, NULL, g_model.swashR.collectiveSource, 0, MIXSRC_LAST_CH, attr, event);
putsMixerSource(HELI_PARAM_OFS, y, g_model.swashR.collectiveSource, attr);
break;
case ITEM_HELI_SWASHRING:
lcdDrawTextAlignedLeft(y, STR_SWASHRING);
lcdDrawNumber(HELI_PARAM_OFS, y, g_model.swashR.value, LEFT|attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.swashR.value, 100);
break;
case ITEM_HELI_ELEDIRECTION:
g_model.swashR.invertELE = selectMenuItem(HELI_PARAM_OFS, y, STR_ELEDIRECTION, STR_MMMINV, g_model.swashR.invertELE, 0, 1, attr, event);
break;
case ITEM_HELI_AILDIRECTION:
g_model.swashR.invertAIL = selectMenuItem(HELI_PARAM_OFS, y, STR_AILDIRECTION, STR_MMMINV, g_model.swashR.invertAIL, 0, 1, attr, event);
break;
case ITEM_HELI_COLDIRECTION:
g_model.swashR.invertCOL = selectMenuItem(HELI_PARAM_OFS, y, STR_COLDIRECTION, STR_MMMINV, g_model.swashR.invertCOL, 0, 1, attr, event);
break;
}
}
}

View file

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

View file

@ -23,42 +23,7 @@
#define EXPO_ONE_2ND_COLUMN (7*FW+3*FW+2) #define EXPO_ONE_2ND_COLUMN (7*FW+3*FW+2)
#define EXPO_ONE_FM_WIDTH (5*FW) #define EXPO_ONE_FM_WIDTH (5*FW)
#if defined(FLIGHT_MODES) int expoFn(int x)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
drawFieldLabel(x, y, STR_FLMODE);
uint8_t posHorz = menuHorizontalPosition;
#if defined(CPUARM)
bool expoMenu = (x==EXPO_ONE_2ND_COLUMN-5*FW);
#endif
for (uint8_t p=0; p<MAX_FLIGHT_MODES; p++) {
#if defined(CPUARM)
if (expoMenu && ((attr && p < posHorz-4) || (x > EXPO_ONE_2ND_COLUMN-FW)))
continue;
#endif
lcdDrawChar(x, y, '0'+p, ((posHorz==p) && attr) ? BLINK|INVERS : ((value & (1<<p)) ? 0 : INVERS));
x += FW;
}
if (attr) {
if (s_editMode && ((event==EVT_KEY_BREAK(KEY_ENTER) || p1valdiff))) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
#else
#define displayFlightModes(...)
#endif
int16_t expoFn(int16_t x)
{ {
ExpoData *ed = expoAddress(s_currIdx); ExpoData *ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0}; int16_t anas[NUM_INPUTS] = {0};
@ -69,20 +34,20 @@ int16_t expoFn(int16_t x)
void drawFunction(FnFuncP fn, uint8_t offset) void drawFunction(FnFuncP fn, uint8_t offset)
{ {
lcdDrawVerticalLine(X0-offset, 0, LCD_H, 0xee); lcdDrawVerticalLine(CURVE_CENTER_X-offset, 0, LCD_H, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee); lcdDrawHorizontalLine(CURVE_CENTER_X-CURVE_SIDE_WIDTH-offset, CURVE_CENTER_Y, CURVE_SIDE_WIDTH*2, 0xee);
coord_t prev_yv = (coord_t)-1; coord_t prev_yv = (coord_t)-1;
for (int8_t xv=-WCHART; xv<=WCHART; xv++) { for (int8_t xv=-CURVE_SIDE_WIDTH; xv<=CURVE_SIDE_WIDTH; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX); coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/CURVE_SIDE_WIDTH))) / 2 * (LCD_H-1) / RESX);
if (prev_yv != (coord_t)-1) { if (prev_yv != (coord_t)-1) {
if (abs((int8_t)yv-prev_yv) <= 1) { if (abs((int8_t)yv-prev_yv) <= 1) {
lcdDrawPoint(X0+xv-offset-1, prev_yv, FORCE); lcdDrawPoint(CURVE_CENTER_X+xv-offset-1, prev_yv, FORCE);
} }
else { else {
uint8_t tmp = (prev_yv < yv ? 0 : 1); uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv); lcdDrawSolidVerticalLine(CURVE_CENTER_X+xv-offset-1, yv+tmp, prev_yv-yv);
} }
} }
prev_yv = yv; prev_yv = yv;
@ -220,7 +185,7 @@ bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
} }
if (tgt_idx == MAX_MIXERS) { if (tgt_idx == MAX_MIXERS) {
if (((MixData *)x)->destCh == NUM_CHNOUT-1) if (((MixData *)x)->destCh == MAX_OUTPUT_CHANNELS-1)
return false; return false;
((MixData *)x)->destCh++; ((MixData *)x)->destCh++;
return true; return true;
@ -234,7 +199,7 @@ bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
else return false; else return false;
} }
else { else {
if (destCh<NUM_CHNOUT-1) ((MixData *)x)->destCh++; if (destCh<MAX_OUTPUT_CHANNELS-1) ((MixData *)x)->destCh++;
else return false; else return false;
} }
return true; return true;
@ -266,21 +231,18 @@ enum ExposFields {
void menuModelExpoOne(uint8_t event) void menuModelExpoOne(uint8_t event)
{ {
ExpoData *ed = expoAddress(s_currIdx); ExpoData * ed = expoAddress(s_currIdx);
putsMixerSource(7*FW+FW/2, 0, MIXSRC_Rud+ed->chn, 0); drawSource(7*FW+FW/2, 0, MIXSRC_Rud+ed->chn, 0);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {CASE_CPUARM(0) 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {CASE_CPUARM(0) 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW);
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
coord_t y = MENU_HEADER_HEIGHT + 1; coord_t y = MENU_HEADER_HEIGHT + 1;
for (uint8_t i=0; i<EXPO_FIELD_MAX+1; i++) { for (uint8_t i=0; i<EXPO_FIELD_MAX+1; i++) {
uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) switch (i) {
{
#if defined(CPUARM) #if defined(CPUARM)
case EXPO_FIELD_NAME: case EXPO_FIELD_NAME:
editSingleName(EXPO_ONE_2ND_COLUMN-sizeof(ed->name)*FW, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr); editSingleName(EXPO_ONE_2ND_COLUMN-sizeof(ed->name)*FW, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr);
@ -289,7 +251,7 @@ void menuModelExpoOne(uint8_t event)
case EXPO_FIELD_WEIGHT: case EXPO_FIELD_WEIGHT:
lcdDrawTextAlignedLeft(y, STR_WEIGHT); lcdDrawTextAlignedLeft(y, STR_WEIGHT);
ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr, 0, event); ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN-4*FW, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr, 0, event);
break; break;
case EXPO_FIELD_EXPO: case EXPO_FIELD_EXPO:
@ -348,10 +310,10 @@ void menuModelExpoOne(uint8_t event)
lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0); lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0);
#if defined(CPUARM) #if defined(CPUARM)
x512 = X0+x512/(RESX/WCHART); x512 = CURVE_CENTER_X+x512/(RESX/CURVE_SIDE_WIDTH);
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX; y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
#else #else
x512 = X0+x512/(RESXu/WCHART); x512 = CURVE_CENTER_X+x512/(RESXu/CURVE_SIDE_WIDTH);
y512 = (LCD_H-1) - (uint16_t)((y512+RESX)/2) * (LCD_H-1) / RESX; y512 = (LCD_H-1) - (uint16_t)((y512+RESX)/2) * (LCD_H-1) / RESX;
#endif #endif
@ -457,34 +419,15 @@ void menuModelMixOne(uint8_t event)
SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, 1, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, 1, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/});
#endif #endif
#if MENU_COLUMNS > 1
lcdDrawSolidVerticalLine(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1);
#endif
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode; int8_t editMode = s_editMode;
for (uint8_t k=0; k<MENU_COLUMNS*(LCD_LINES-1); k++) { for (uint8_t k=0; k<LCD_LINES-1; k++) {
#if MENU_COLUMNS > 1
coord_t y;
coord_t COLUMN_X;
if (k >= LCD_LINES-1) {
y = 1 + (k-LCD_LINES+2)*FH;
COLUMN_X = MENU_COLUMN2_X;
}
else {
y = 1 + (k+1)*FH;
COLUMN_X = 0;
}
int8_t i = k;
#else
coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH;
int8_t i = k + menuVerticalOffset; int8_t i = k + menuVerticalOffset;
#endif
uint8_t attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0); uint8_t attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i) { switch (i) {
#if defined(CPUARM) #if defined(CPUARM)
case MIX_FIELD_NAME: case MIX_FIELD_NAME:
editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr); editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr);
@ -492,7 +435,7 @@ void menuModelMixOne(uint8_t event)
#endif #endif
case MIX_FIELD_SOURCE: case MIX_FIELD_SOURCE:
drawFieldLabel(COLUMN_X, y, NO_INDENT(STR_SOURCE)); drawFieldLabel(COLUMN_X, y, NO_INDENT(STR_SOURCE));
putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); drawSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break; break;
case MIX_FIELD_WEIGHT: case MIX_FIELD_WEIGHT:
@ -599,10 +542,6 @@ void menuModelMixOne(uint8_t event)
} }
} }
static uint8_t s_maxLines = 8;
static uint8_t s_copySrcIdx;
static uint8_t s_copySrcCh;
#define _STR_MAX(x) PSTR("/" #x) #define _STR_MAX(x) PSTR("/" #x)
#define STR_MAX(x) _STR_MAX(x) #define STR_MAX(x) _STR_MAX(x)
@ -613,7 +552,7 @@ static uint8_t s_copySrcCh;
#define EXPO_LINE_SIDE_POS 14*FW+2 #define EXPO_LINE_SIDE_POS 14*FW+2
#define EXPO_LINE_SELECT_POS 24 #define EXPO_LINE_SELECT_POS 24
#define EXPO_LINE_FM_POS #define EXPO_LINE_FM_POS
#define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH #define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW
#define MIX_LINE_SRC_POS 4*FW-1 #define MIX_LINE_SRC_POS 4*FW-1
#define MIX_LINE_WEIGHT_POS 11*FW+3 #define MIX_LINE_WEIGHT_POS 11*FW+3
#define MIX_LINE_CURVE_POS 12*FW+2 #define MIX_LINE_CURVE_POS 12*FW+2
@ -628,7 +567,7 @@ static uint8_t s_copySrcCh;
#else #else
#define EXPO_LINE_SIDE_POS 15*FW+2 #define EXPO_LINE_SIDE_POS 15*FW+2
#endif #endif
#define EXPO_LINE_FM_POS LCD_W-FW-MENUS_SCROLLBAR_WIDTH #define EXPO_LINE_FM_POS LCD_W-FW
#define EXPO_LINE_SELECT_POS 24 #define EXPO_LINE_SELECT_POS 24
#define MIX_LINE_SRC_POS 4*FW-1 #define MIX_LINE_SRC_POS 4*FW-1
#define MIX_LINE_WEIGHT_POS 11*FW+3 #define MIX_LINE_WEIGHT_POS 11*FW+3
@ -676,7 +615,7 @@ void displayMixInfos(coord_t y, MixData *md)
} }
if (md->swtch) { if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch); drawSwitch(MIX_LINE_SWITCH_POS, y, md->swtch);
} }
} }
@ -701,7 +640,7 @@ void displayExpoInfos(coord_t y, ExpoData *ed)
else else
displayGVar(EXPO_LINE_EXPO_POS, y, ed->curveParam, -100, 100); displayGVar(EXPO_LINE_EXPO_POS, y, ed->curveParam, -100, 100);
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0); drawSwitch(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
} }
#if defined(CPUARM) #if defined(CPUARM)
@ -884,13 +823,13 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
uint8_t cur = 1; uint8_t cur = 1;
uint8_t i = 0; uint8_t i = 0;
for (uint8_t ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) { for (uint8_t ch=1; ch<=(expo ? NUM_INPUTS : MAX_OUTPUT_CHANNELS); ch++) {
void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer; void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer;
coord_t y = MENU_HEADER_HEIGHT-FH+1+(cur-menuVerticalOffset)*FH; coord_t y = MENU_HEADER_HEIGHT-FH+1+(cur-menuVerticalOffset)*FH;
if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) { if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) {
if (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) { if (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) {
if (expo) { if (expo) {
putsMixerSource(0, y, MIXSRC_Rud+ch-1, 0); drawSource(0, y, MIXSRC_Rud+ch-1, 0);
} }
else { else {
putsChn(0, y, ch, 0); // show CHx putsChn(0, y, ch, 0); // show CHx
@ -923,7 +862,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
else { else {
if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0); if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); drawSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event);
@ -965,7 +904,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
} }
if (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) { if (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) {
if (expo) { if (expo) {
putsMixerSource(0, y, MIXSRC_Rud+ch-1, attr); drawSource(0, y, MIXSRC_Rud+ch-1, attr);
} }
else { else {
putsChn(0, y, ch, attr); // show CHx putsChn(0, y, ch, attr); // show CHx

View file

@ -64,9 +64,9 @@ void menuModelLogicalSwitchOne(uint8_t event)
LogicalSwitchData * cs = lswAddress(s_currIdx); LogicalSwitchData * cs = lswAddress(s_currIdx);
uint8_t sw = SWSRC_SW1+s_currIdx; uint8_t sw = SWSRC_SW1+s_currIdx;
putsSwitches(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0)); drawSwitch(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0));
SUBMENU_NOTITLE(LS_FIELD_COUNT, {0, 0, 1, 0 /*, 0...*/}); SUBMENU_NOTITLE(LS_FIELD_COUNT, { 0, 0, 1, 0 /*, 0...*/ });
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
@ -79,7 +79,8 @@ void menuModelLogicalSwitchOne(uint8_t event)
uint8_t i = k + menuVerticalOffset; uint8_t i = k + menuVerticalOffset;
uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
uint8_t cstate = lswFamily(cs->func); uint8_t cstate = lswFamily(cs->func);
switch(i) {
switch (i) {
case LS_FIELD_FUNCTION: case LS_FIELD_FUNCTION:
lcdDrawTextAlignedLeft(y, STR_FUNC); lcdDrawTextAlignedLeft(y, STR_FUNC);
lcdDrawTextAtIndex(CSWONE_2ND_COLUMN, y, STR_VCSWFUNC, cs->func, attr); lcdDrawTextAtIndex(CSWONE_2ND_COLUMN, y, STR_VCSWFUNC, cs->func, attr);
@ -99,12 +100,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
} }
} }
break; break;
case LS_FIELD_V1: case LS_FIELD_V1:
{ {
lcdDrawTextAlignedLeft(y, STR_V1); lcdDrawTextAlignedLeft(y, STR_V1);
int v1_min=0, v1_max=MIXSRC_LAST_TELEM; int v1_min=0, v1_max=MIXSRC_LAST_TELEM;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY || cstate == LS_FAMILY_EDGE) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY || cstate == LS_FAMILY_EDGE) {
putsSwitches(CSWONE_2ND_COLUMN, y, v1_val, attr); drawSwitch(CSWONE_2ND_COLUMN, y, v1_val, attr);
v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1;
} }
else if (cstate == LS_FAMILY_TIMER) { else if (cstate == LS_FAMILY_TIMER) {
@ -114,7 +116,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
} }
else { else {
v1_val = (uint8_t)cs->v1; v1_val = (uint8_t)cs->v1;
putsMixerSource(CSWONE_2ND_COLUMN, y, v1_val, attr); drawSource(CSWONE_2ND_COLUMN, y, v1_val, attr);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -123,12 +125,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
} }
break; break;
} }
case LS_FIELD_V2: case LS_FIELD_V2:
{ {
lcdDrawTextAlignedLeft(y, STR_V2); lcdDrawTextAlignedLeft(y, STR_V2);
int v2_min=0, v2_max=MIXSRC_LAST_TELEM; int v2_min=0, v2_max=MIXSRC_LAST_TELEM;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSWONE_2ND_COLUMN, y, cs->v2, attr); drawSwitch(CSWONE_2ND_COLUMN, y, cs->v2, attr);
v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1; v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1;
} }
else if (cstate == LS_FAMILY_TIMER) { else if (cstate == LS_FAMILY_TIMER) {
@ -146,7 +149,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
v2_min = -129; v2_max = 122; v2_min = -129; v2_max = 122;
} }
else if (cstate == LS_FAMILY_COMP) { else if (cstate == LS_FAMILY_COMP) {
putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr); drawSource(CSWONE_2ND_COLUMN, y, cs->v2, attr);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -184,11 +187,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
} }
break; break;
} }
case LS_FIELD_ANDSW: case LS_FIELD_ANDSW:
lcdDrawTextAlignedLeft(y, STR_AND_SWITCH); lcdDrawTextAlignedLeft(y, STR_AND_SWITCH);
putsSwitches(CSWONE_2ND_COLUMN, y, cs->andsw, attr); drawSwitch(CSWONE_2ND_COLUMN, y, cs->andsw, attr);
if (attr) CHECK_INCDEC_MODELVAR(event, cs->andsw, -MAX_LS_ANDSW, MAX_LS_ANDSW); if (attr) CHECK_INCDEC_MODELVAR(event, cs->andsw, -MAX_LS_ANDSW, MAX_LS_ANDSW);
break; break;
case LS_FIELD_DURATION: case LS_FIELD_DURATION:
lcdDrawTextAlignedLeft(y, STR_DURATION); lcdDrawTextAlignedLeft(y, STR_DURATION);
if (cs->duration > 0) if (cs->duration > 0)
@ -197,6 +202,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
lcdDrawTextAtIndex(CSWONE_2ND_COLUMN, y, STR_MMMINV, 0, attr); lcdDrawTextAtIndex(CSWONE_2ND_COLUMN, y, STR_MMMINV, 0, attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, cs->duration, MAX_LS_DURATION); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, cs->duration, MAX_LS_DURATION);
break; break;
case LS_FIELD_DELAY: case LS_FIELD_DELAY:
lcdDrawTextAlignedLeft(y, STR_DELAY); lcdDrawTextAlignedLeft(y, STR_DELAY);
if (cs->delay > 0) if (cs->delay > 0)
@ -211,17 +217,19 @@ void menuModelLogicalSwitchOne(uint8_t event)
void menuModelLogicalSwitches(uint8_t event) void menuModelLogicalSwitches(uint8_t event)
{ {
SIMPLE_MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, NUM_LOGICAL_SWITCH+1); SIMPLE_MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, HEADER_LINE+MAX_LOGICAL_SWITCHES);
coord_t y = 0; coord_t y = 0;
uint8_t k = 0; uint8_t k = 0;
int8_t sub = menuVerticalPosition - 1; int8_t sub = menuVerticalPosition - HEADER_LINE;
switch (event) { switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK: case EVT_ROTARY_BREAK:
#endif #endif
#if !defined(PCBX7D)
case EVT_KEY_FIRST(KEY_RIGHT): case EVT_KEY_FIRST(KEY_RIGHT):
#endif
case EVT_KEY_FIRST(KEY_ENTER): case EVT_KEY_FIRST(KEY_ENTER):
if (sub >= 0) { if (sub >= 0) {
s_currIdx = sub; s_currIdx = sub;
@ -232,13 +240,13 @@ void menuModelLogicalSwitches(uint8_t event)
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
y = 1 + (i+1)*FH; y = 1 + (i+1)*FH;
k = i+menuVerticalOffset; k = i + menuVerticalOffset;
LogicalSwitchData * cs = lswAddress(k); LogicalSwitchData * cs = lswAddress(k);
// CSW name // CSW name
uint8_t sw = SWSRC_SW1+k; uint8_t sw = SWSRC_SW1+k;
putsSwitches(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw) ? BOLD : 0)); drawSwitch(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw) ? BOLD : 0));
if (cs->func > 0) { if (cs->func > 0) {
// CSW func // CSW func
@ -248,15 +256,15 @@ void menuModelLogicalSwitches(uint8_t event)
uint8_t cstate = lswFamily(cs->func); uint8_t cstate = lswFamily(cs->func);
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, 0);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, 0); drawSwitch(CSW_3RD_COLUMN, y, cs->v2, 0);
} }
else if (cstate == LS_FAMILY_COMP) { else if (cstate == LS_FAMILY_COMP) {
putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, 0); drawSource(CSW_2ND_COLUMN, y, cs->v1, 0);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, 0); drawSource(CSW_3RD_COLUMN, y, cs->v2, 0);
} }
else if (cstate == LS_FAMILY_EDGE) { else if (cstate == LS_FAMILY_EDGE) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, 0);
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, 0, 0); putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, 0, 0);
} }
else if (cstate == LS_FAMILY_TIMER) { else if (cstate == LS_FAMILY_TIMER) {
@ -265,7 +273,7 @@ void menuModelLogicalSwitches(uint8_t event)
} }
else { else {
uint8_t v1 = cs->v1; uint8_t v1 = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1, 0); drawSource(CSW_2ND_COLUMN, y, v1, 0);
if (v1 >= MIXSRC_FIRST_TELEM) { if (v1 >= MIXSRC_FIRST_TELEM) {
#if defined(CPUARM) #if defined(CPUARM)
putsChannelValue(CSW_3RD_COLUMN, y, v1, convertLswTelemValue(cs), LEFT); putsChannelValue(CSW_3RD_COLUMN, y, v1, convertLswTelemValue(cs), LEFT);
@ -279,7 +287,7 @@ void menuModelLogicalSwitches(uint8_t event)
} }
// CSW and switch // CSW and switch
putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, 0); drawSwitch(CSW_4TH_COLUMN, y, cs->andsw, 0);
} }
} }
} }
@ -290,10 +298,10 @@ void menuModelLogicalSwitches(uint8_t event)
{ {
INCDEC_DECLARE_VARS(EE_MODEL); INCDEC_DECLARE_VARS(EE_MODEL);
MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, NUM_LOGICAL_SWITCH+1, {0, NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/}); MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, HEADER_LINE+MAX_LOGICAL_SWITCHES, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/});
uint8_t k = 0; uint8_t k = 0;
int8_t sub = menuVerticalPosition - 1; int8_t sub = menuVerticalPosition - HEADER_LINE;
horzpos_t horz = menuHorizontalPosition; horzpos_t horz = menuHorizontalPosition;
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
@ -306,7 +314,7 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW name // CSW name
uint8_t sw = SWSRC_SW1+k; uint8_t sw = SWSRC_SW1+k;
putsSwitches(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && CURSOR_ON_LINE()) ? INVERS : 0)); drawSwitch(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && CURSOR_ON_LINE()) ? INVERS : 0));
// CSW func // CSW func
lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, horz==0 ? attr : 0); lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, horz==0 ? attr : 0);
@ -322,8 +330,8 @@ void menuModelLogicalSwitches(uint8_t event)
#endif #endif
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
@ -331,7 +339,7 @@ void menuModelLogicalSwitches(uint8_t event)
} }
#if defined(CPUARM) #if defined(CPUARM)
else if (cstate == LS_FAMILY_EDGE) { else if (cstate == LS_FAMILY_EDGE) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, horz==LS_FIELD_V3 ? attr : 0); putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, horz==LS_FIELD_V3 ? attr : 0);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122; v2_min=-129; v2_max = 122;
@ -350,8 +358,8 @@ void menuModelLogicalSwitches(uint8_t event)
#if defined(CPUARM) #if defined(CPUARM)
v1_val = (uint8_t)cs->v1; v1_val = (uint8_t)cs->v1;
#endif #endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -367,7 +375,7 @@ void menuModelLogicalSwitches(uint8_t event)
#if defined(CPUARM) #if defined(CPUARM)
v1_val = (uint8_t)cs->v1; v1_val = (uint8_t)cs->v1;
#endif #endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) { if (horz == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches); INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -438,13 +446,13 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW AND switch // CSW AND switch
#if defined(CPUARM) #if defined(CPUARM)
putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==LS_FIELD_ANDSW ? attr : 0); drawSwitch(CSW_4TH_COLUMN, y, cs->andsw, horz==LS_FIELD_ANDSW ? attr : 0);
#else #else
uint8_t andsw = cs->andsw; uint8_t andsw = cs->andsw;
if (andsw > SWSRC_LAST_SWITCH) { if (andsw > SWSRC_LAST_SWITCH) {
andsw += SWSRC_SW1-SWSRC_LAST_SWITCH-1; andsw += SWSRC_SW1-SWSRC_LAST_SWITCH-1;
} }
putsSwitches(CSW_4TH_COLUMN, y, andsw, horz==LS_FIELD_ANDSW ? attr : 0); drawSwitch(CSW_4TH_COLUMN, y, andsw, horz==LS_FIELD_ANDSW ? attr : 0);
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)

View file

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

View file

@ -30,19 +30,19 @@ bool isThrottleOutput(uint8_t ch)
return false; return false;
} }
enum LimitsItems { enum MenuModelOutputsItems {
ITEM_LIMITS_OFFSET, ITEM_OUTPUTS_OFFSET,
ITEM_LIMITS_MIN, ITEM_OUTPUTS_MIN,
ITEM_LIMITS_MAX, ITEM_OUTPUTS_MAX,
ITEM_LIMITS_DIRECTION, ITEM_OUTPUTS_DIRECTION,
#if defined(PPM_CENTER_ADJUSTABLE) #if defined(PPM_CENTER_ADJUSTABLE)
ITEM_LIMITS_PPM_CENTER, ITEM_OUTPUTS_PPM_CENTER,
#endif #endif
#if defined(PPM_LIMITS_SYMETRICAL) #if defined(PPM_LIMITS_SYMETRICAL)
ITEM_LIMITS_SYMETRICAL, ITEM_OUTPUTS_SYMETRICAL,
#endif #endif
ITEM_LIMITS_COUNT, ITEM_OUTPUTS_COUNT,
ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1 ITEM_OUTPUTS_MAXROW = ITEM_OUTPUTS_COUNT-1
}; };
#if defined(PPM_UNIT_US) #if defined(PPM_UNIT_US)
@ -89,26 +89,26 @@ enum LimitsItems {
void menuModelLimits(uint8_t event) void menuModelLimits(uint8_t event)
{ {
uint8_t sub = menuVerticalPosition - 1; uint8_t sub = menuVerticalPosition - HEADER_LINE;
if (sub < NUM_CHNOUT) { if (sub < MAX_OUTPUT_CHANNELS) {
#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US) #if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US)
lcdDrawNumber(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, 0); lcdDrawNumber(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, RIGHT);
lcdDrawText(13*FW, 0, STR_US); lcdDrawText(13*FW, 0, STR_US);
#else #else
lcdDrawNumber(13*FW, 0, calcRESXto1000(channelOutputs[sub]), PREC1); lcdDrawNumber(13*FW, 0, calcRESXto1000(channelOutputs[sub]), RIGHT|PREC1);
#endif #endif
} }
#if defined(CPUARM) #if defined(CPUARM)
MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, 1+NUM_CHNOUT+1, {0, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, 0}); MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, HEADER_LINE+MAX_OUTPUT_CHANNELS+1, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_OUTPUTS_MAXROW, 0});
#else #else
MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, 1+NUM_CHNOUT+1, {0, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, 0}); MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, HEADER_LINE+MAX_OUTPUT_CHANNELS+1, { HEADER_LINE_COLUMNS ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, ITEM_OUTPUTS_MAXROW, 0});
#endif #endif
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
LimitData *ld = limitAddress(sub); LimitData * ld = limitAddress(sub);
ld->revert = !ld->revert; ld->revert = !ld->revert;
storageDirty(EE_MODEL); storageDirty(EE_MODEL);
} }
@ -117,13 +117,13 @@ void menuModelLimits(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) { if (k == MAX_OUTPUT_CHANNELS) {
// last line available - add the "copy trim menu" line // last line available - add the "copy trim menu" line
uint8_t attr = (sub==NUM_CHNOUT) ? INVERS : 0; LcdFlags attr = (sub==MAX_OUTPUT_CHANNELS) ? INVERS : 0;
lcdDrawText(CENTER_OFS, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr); lcdDrawText(CENTER_OFS, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr);
if (attr) { if (attr) {
s_editMode = 0; s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)) { if (event == EVT_KEY_LONG(KEY_ENTER)) {
START_NO_HIGHLIGHT(); START_NO_HIGHLIGHT();
killEvents(event); killEvents(event);
moveTrimsToOffsets(); // if highlighted and menu pressed - move trims to offsets moveTrimsToOffsets(); // if highlighted and menu pressed - move trims to offsets
@ -132,7 +132,7 @@ void menuModelLimits(uint8_t event)
return; return;
} }
LimitData *ld = limitAddress(k); LimitData * ld = limitAddress(k);
#if !defined(PPM_CENTER_ADJUSTABLE) #if !defined(PPM_CENTER_ADJUSTABLE)
int16_t v = (ld->revert) ? -LIMIT_OFS(ld) : LIMIT_OFS(ld); int16_t v = (ld->revert) ? -LIMIT_OFS(ld) : LIMIT_OFS(ld);
@ -145,19 +145,18 @@ void menuModelLimits(uint8_t event)
int8_t limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 100); int8_t limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 100);
putsChn(0, y, k+1, 0); putsChn(0, y, k+1, IS_LINE_SELECTED(sub, k) ? INVERS : 0);
for (uint8_t j=0; j<ITEM_LIMITS_COUNT; j++) { for (uint8_t j=0; j<ITEM_OUTPUTS_COUNT; j++) {
uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ;
if (active) STICK_SCROLL_DISABLE(); if (active) STICK_SCROLL_DISABLE();
switch(j) switch (j) {
{ case ITEM_OUTPUTS_OFFSET:
case ITEM_LIMITS_OFFSET:
#if defined(PPM_UNIT_US) #if defined(PPM_UNIT_US)
lcdDrawNumber(LIMITS_OFFSET_POS, y, ((int32_t)ld->offset*128) / 25, attr|PREC1); lcdDrawNumber(LIMITS_OFFSET_POS, y, ((int32_t)ld->offset*128) / 25, attr|PREC1|RIGHT);
#else #else
lcdDrawNumber(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1); lcdDrawNumber(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1|RIGHT);
#endif #endif
if (active) { if (active) {
#if defined(CPUARM) #if defined(CPUARM)
@ -172,8 +171,8 @@ void menuModelLimits(uint8_t event)
} }
break; break;
case ITEM_LIMITS_MIN: case ITEM_OUTPUTS_MIN:
lcdDrawNumber(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); lcdDrawNumber(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR|RIGHT);
#if defined(CPUARM) #if defined(CPUARM)
if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL, NULL, stops1000); if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL, NULL, stops1000);
#else #else
@ -181,8 +180,8 @@ void menuModelLimits(uint8_t event)
#endif #endif
break; break;
case ITEM_LIMITS_MAX: case ITEM_OUTPUTS_MAX:
lcdDrawNumber(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); lcdDrawNumber(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR|RIGHT);
#if defined(CPUARM) #if defined(CPUARM)
if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL, NULL, stops1000); if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL, NULL, stops1000);
#else #else
@ -190,7 +189,7 @@ void menuModelLimits(uint8_t event)
#endif #endif
break; break;
case ITEM_LIMITS_DIRECTION: case ITEM_OUTPUTS_DIRECTION:
{ {
uint8_t revert = ld->revert; uint8_t revert = ld->revert;
#if defined(PPM_CENTER_ADJUSTABLE) #if defined(PPM_CENTER_ADJUSTABLE)
@ -211,8 +210,8 @@ void menuModelLimits(uint8_t event)
} }
#if defined(PPM_CENTER_ADJUSTABLE) #if defined(PPM_CENTER_ADJUSTABLE)
case ITEM_LIMITS_PPM_CENTER: case ITEM_OUTPUTS_PPM_CENTER:
lcdDrawNumber(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, attr); lcdDrawNumber(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, RIGHT|attr);
if (active) { if (active) {
CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX); CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX);
} }
@ -220,11 +219,11 @@ void menuModelLimits(uint8_t event)
#endif #endif
#if defined(PPM_LIMITS_SYMETRICAL) #if defined(PPM_LIMITS_SYMETRICAL)
case ITEM_LIMITS_SYMETRICAL: case ITEM_OUTPUTS_SYMETRICAL:
#if defined(CPUARM) #if defined(CPUARM)
lcdDrawChar(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, ld->symetrical ? '=' : '\306', attr); lcdDrawChar(LCD_W-FW, y, ld->symetrical ? '=' : '\306', attr);
#else #else
lcdDrawChar(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, ld->symetrical ? '=' : '^', attr); lcdDrawChar(LCD_W-FW, y, ld->symetrical ? '=' : '^', attr);
#endif #endif
if (active) { if (active) {
CHECK_INCDEC_MODELVAR_ZERO(event, ld->symetrical, 1); CHECK_INCDEC_MODELVAR_ZERO(event, ld->symetrical, 1);

View file

@ -49,7 +49,7 @@ void onModelSelectMenu(const char *result)
else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) {
if (!sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) { if (!sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) {
POPUP_WARNING(STR_NO_MODELS_ON_SD); POPUP_WARNING(STR_NO_MODELS_ON_SD);
popupMenuFlags = 0; POPUP_MENU_UNSET_BSS_FLAG();
} }
} }
#endif #endif
@ -92,7 +92,7 @@ void menuModelSelect(uint8_t event)
int8_t oldSub = menuVerticalPosition; int8_t oldSub = menuVerticalPosition;
check_submenu_simple(_event_, MAX_MODELS-1); check_submenu_simple(_event_, MAX_MODELS-HEADER_LINE);
#if defined(NAVIGATION_POT2) #if defined(NAVIGATION_POT2)
if (event==0 && p2valdiff<0) { if (event==0 && p2valdiff<0) {
@ -110,8 +110,7 @@ void menuModelSelect(uint8_t event)
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
switch (event) switch (event) {
{
case EVT_ENTRY: case EVT_ENTRY:
menuVerticalPosition = sub = g_eeGeneral.currModel; menuVerticalPosition = sub = g_eeGeneral.currModel;
if (sub >= LCD_LINES-1) menuVerticalOffset = sub-LCD_LINES+2; if (sub >= LCD_LINES-1) menuVerticalOffset = sub-LCD_LINES+2;
@ -254,6 +253,16 @@ void menuModelSelect(uint8_t event)
} }
break; break;
#if defined(PCBX7D)
case EVT_KEY_LONG(KEY_PAGE):
chainMenu(menuTabModel[DIM(menuTabModel)-1]);
killEvents(event);
break;
case EVT_KEY_BREAK(KEY_PAGE):
chainMenu(menuModelSetup);
break;
#else
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LEFT: case EVT_ROTARY_LEFT:
case EVT_ROTARY_RIGHT: case EVT_ROTARY_RIGHT:
@ -273,6 +282,7 @@ void menuModelSelect(uint8_t event)
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
} }
// no break // no break
#endif
#endif #endif
case EVT_KEY_FIRST(KEY_UP): case EVT_KEY_FIRST(KEY_UP):
@ -302,13 +312,19 @@ void menuModelSelect(uint8_t event)
break; break;
} }
#if !defined(PCBSKY9X) #if defined(EEPROM_RLC) && defined(CPUARM)
lcdDrawText(9*FW-(LEN_FREE-4)*FW-4, 0, STR_FREE);
if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree();
lcdDrawNumber(lcdLastPos+3, 0, reusableBuffer.modelsel.eepromfree, LEFT);
#elif defined(EEPROM_RLC)
lcdDrawText(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE); lcdDrawText(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE);
if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree();
lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0); lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, RIGHT);
#endif #endif
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(PCBX7D)
drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), 0);
#elif defined(ROTARY_ENCODER_NAVIGATION)
drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0); drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0);
#else #else
drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0); drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0);
@ -320,7 +336,7 @@ void menuModelSelect(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
lcdDrawNumber(3*FW+2, y, k+1, LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2); lcdDrawNumber(3*FW+2, y, k+1, RIGHT+LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2);
if (s_copyMode == MOVE_MODE || (s_copyMode == COPY_MODE && s_copySrcRow >= 0)) { if (s_copyMode == MOVE_MODE || (s_copyMode == COPY_MODE && s_copySrcRow >= 0)) {
if (k == sub) { if (k == sub) {
@ -347,11 +363,12 @@ void menuModelSelect(uint8_t event)
char * name = reusableBuffer.modelsel.listnames[i]; char * name = reusableBuffer.modelsel.listnames[i];
if (event) eeLoadModelName(k, name); if (event) eeLoadModelName(k, name);
putsModelName(4*FW, y, name, k, 0); putsModelName(4*FW, y, name, k, 0);
lcdDrawNumber(20*FW, y, eeModelSize(k), 0); lcdDrawNumber(20*FW, y, eeModelSize(k), RIGHT);
#endif #endif
if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+menuVerticalOffset!=(vertpos_t)sub)) if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+menuVerticalOffset!=(vertpos_t)sub)) {
lcdDrawChar(1, y, '*'); lcdDrawChar(1, y, '*');
} }
}
if (s_copyMode && (vertpos_t)sub==i+menuVerticalOffset) { if (s_copyMode && (vertpos_t)sub==i+menuVerticalOffset) {
lcdDrawFilledRect(9, y, MODELSEL_W-1-9, 7); lcdDrawFilledRect(9, y, MODELSEL_W-1-9, 7);

View file

@ -25,7 +25,7 @@ uint8_t g_moduleIdx;
void menuModelFailsafe(uint8_t event); void menuModelFailsafe(uint8_t event);
#endif #endif
enum menuModelSetupItems { enum MenuModelSetupItems {
ITEM_MODEL_NAME, ITEM_MODEL_NAME,
ITEM_MODEL_TIMER1, ITEM_MODEL_TIMER1,
CASE_CPUARM(ITEM_MODEL_TIMER1_NAME) CASE_CPUARM(ITEM_MODEL_TIMER1_NAME)
@ -55,6 +55,13 @@ enum menuModelSetupItems {
ITEM_MODEL_SWITCHES_WARNING, ITEM_MODEL_SWITCHES_WARNING,
ITEM_MODEL_BEEP_CENTER, ITEM_MODEL_BEEP_CENTER,
CASE_CPUARM(ITEM_MODEL_USE_GLOBAL_FUNCTIONS) CASE_CPUARM(ITEM_MODEL_USE_GLOBAL_FUNCTIONS)
#if defined(PCBX7D)
ITEM_MODEL_INTERNAL_MODULE_LABEL,
ITEM_MODEL_INTERNAL_MODULE_MODE,
ITEM_MODEL_INTERNAL_MODULE_CHANNELS,
ITEM_MODEL_INTERNAL_MODULE_BIND,
ITEM_MODEL_INTERNAL_MODULE_FAILSAFE,
#endif
#if defined(CPUARM) #if defined(CPUARM)
ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_MODE, ITEM_MODEL_EXTERNAL_MODULE_MODE,
@ -79,6 +86,12 @@ enum menuModelSetupItems {
#else #else
ITEM_MODEL_PPM1_PROTOCOL, ITEM_MODEL_PPM1_PROTOCOL,
ITEM_MODEL_PPM1_PARAMS, ITEM_MODEL_PPM1_PARAMS,
#endif
#if defined(PCBX7D)
ITEM_MODEL_TRAINER_LABEL,
ITEM_MODEL_TRAINER_MODE,
ITEM_MODEL_TRAINER_CHANNELS,
ITEM_MODEL_TRAINER_SETTINGS,
#endif #endif
ITEM_MODEL_SETUP_MAX ITEM_MODEL_SETUP_MAX
}; };
@ -89,23 +102,37 @@ enum menuModelSetupItems {
#define FIELD_PROTOCOL_MAX 1 #define FIELD_PROTOCOL_MAX 1
#endif #endif
#define MODEL_SETUP_2ND_COLUMN (LCD_W-11*FW-MENUS_SCROLLBAR_WIDTH) #define MODEL_SETUP_2ND_COLUMN (LCD_W-11*FW)
#define MODEL_SETUP_BIND_OFS 2*FW+1 #define MODEL_SETUP_BIND_OFS 2*FW+1
#define MODEL_SETUP_RANGE_OFS 4*FW+3 #define MODEL_SETUP_RANGE_OFS 4*FW+3
#define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2 #define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2
#if defined(PCBSKY9X) && !defined(REVA) #if defined(PCBX7D)
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
#elif defined(PCBSKY9X) && !defined(REVA)
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE) #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE)
#else #else
#define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE) #define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE)
#endif #endif
void menuModelSetup(uint8_t event)
{
#if defined(CPUARM) #if defined(CPUARM)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)(x) : HIDDEN_ROW)
#if !defined(TARANIS_INTERNAL_PPM)
#define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols)
#else
#define INTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(INTERNAL_MODULE) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols
#endif
#if defined(TARANIS_INTERNAL_PPM)
#define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#else
#define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? HIDDEN_ROW : (uint8_t)(x))
#endif
#define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x)) #define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW)
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8) #define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)(x) : HIDDEN_ROW)
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)0 : (uint8_t)1) #define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)0 : (uint8_t)1)
#define EXTERNAL_MODULE_BIND_ROWS() (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW #define EXTERNAL_MODULE_BIND_ROWS() (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW
@ -114,10 +141,9 @@ void menuModelSetup(uint8_t event)
#else #else
#define OUTPUT_TYPE_ROWS() #define OUTPUT_TYPE_ROWS()
#endif #endif
#define TRAINER_CHANNELS_ROWS() (HIDDEN_ROW)
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0)
#if defined MULTIMODULE #if defined(MULTIMODULE)
#define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_DSM2 || x == MM_RF_PROTO_SFHSS || x >= MM_RF_PROTO_CUSTOM) #define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_DSM2 || x == MM_RF_PROTO_SFHSS || x >= MM_RF_PROTO_CUSTOM)
#define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].multi.rfProtocol))) ? (uint8_t) 0: HIDDEN_ROW #define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].multi.rfProtocol))) ? (uint8_t) 0: HIDDEN_ROW
#else #else
@ -140,16 +166,41 @@ void menuModelSetup(uint8_t event)
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 #define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#define CURSOR_ON_CELL (true) #define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX) #define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX)
#define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0) #define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS+NUM_SLIDERS : (uint8_t)0)
#define TIMER_ROWS 2, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 #define TIMER_ROWS 2, 0, CASE_PERSISTENT_TIMERS(0) 0, 0
#if defined(PCBSKY9X) && !defined(REVA) #if defined(PCBSKY9X) && !defined(REVA)
#define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2,
#else #else
#define EXTRA_MODULE_ROWS #define EXTRA_MODULE_ROWS
#endif #endif
#if defined(PCBX7D)
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
#define TRAINER_MODULE_ROWS LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)
#else
#define TRAINER_MODULE_ROWS #define TRAINER_MODULE_ROWS
MENU_TAB({ 0, 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, 0, #endif
#elif defined(CPUM64)
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? HEADER_LINE+ITEM_MODEL_SETUP_MAX : HEADER_LINE+ITEM_MODEL_SETUP_MAX-1)
#else
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? HEADER_LINE+ITEM_MODEL_SETUP_MAX : HEADER_LINE+ITEM_MODEL_SETUP_MAX-1)
#endif
void menuModelSetup(uint8_t event)
{
#if defined(CPUARM)
MENU_TAB({ HEADER_LINE_COLUMNS 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, NUM_SWITCHES-1, NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1, 0,
#if defined(PCBX7D)
LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS,
IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1),
IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)),
#endif
LABEL(ExternalModule), LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROWS, EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
@ -161,15 +212,11 @@ void menuModelSetup(uint8_t event)
EXTRA_MODULE_ROWS EXTRA_MODULE_ROWS
TRAINER_MODULE_ROWS }); TRAINER_MODULE_ROWS });
#elif defined(CPUM64) #elif defined(CPUM64)
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX)
uint8_t protocol = g_model.protocol; uint8_t protocol = g_model.protocol;
MENU_TAB({ 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 }); MENU_TAB({ HEADER_LINE_COLUMNS 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 });
#else #else
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX)
uint8_t protocol = g_model.protocol; uint8_t protocol = g_model.protocol;
MENU_TAB({ 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, NUM_SWITCHES, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, CASE_PCBSKY9X(1) CASE_PCBSKY9X(2) }); MENU_TAB({ HEADER_LINE_COLUMNS 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, NUM_SWITCHES, NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, CASE_PCBSKY9X(1) CASE_PCBSKY9X(2) });
#endif #endif
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, MODEL_SETUP_MAX_LINES); MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, MODEL_SETUP_MAX_LINES);
@ -185,7 +232,7 @@ void menuModelSetup(uint8_t event)
TITLE(STR_MENUSETUP); TITLE(STR_MENUSETUP);
uint8_t sub = menuVerticalPosition - 1; uint8_t sub = menuVerticalPosition - HEADER_LINE;
int8_t editMode = s_editMode; int8_t editMode = s_editMode;
for (uint8_t i=0; i<NUM_BODY_LINES; ++i) { for (uint8_t i=0; i<NUM_BODY_LINES; ++i) {
@ -193,7 +240,7 @@ void menuModelSetup(uint8_t event)
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
#if defined(CPUARM) #if defined(CPUARM)
for (int j=0; j<=k; j++) { for (int j=0; j<=k; j++) {
if (mstate_tab[j+1] == HIDDEN_ROW) { if (mstate_tab[j+HEADER_LINE] == HIDDEN_ROW) {
if (++k >= (int)DIM(mstate_tab)) { if (++k >= (int)DIM(mstate_tab)) {
return; return;
} }
@ -204,7 +251,7 @@ void menuModelSetup(uint8_t event)
LcdFlags blink = ((editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (sub == k ? blink : 0); LcdFlags attr = (sub == k ? blink : 0);
switch(k) { switch (k) {
case ITEM_MODEL_NAME: case ITEM_MODEL_NAME:
editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_MODELNAME, g_model.header.name, sizeof(g_model.header.name), event, attr); editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_MODELNAME, g_model.header.name, sizeof(g_model.header.name), event, attr);
#if defined(CPUARM) #if defined(CPUARM)
@ -220,8 +267,8 @@ void menuModelSetup(uint8_t event)
unsigned int timerIdx = (k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)); unsigned int timerIdx = (k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0));
TimerData * timer = &g_model.timers[timerIdx]; TimerData * timer = &g_model.timers[timerIdx];
drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1); drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1);
putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0); drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0);
putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, menuHorizontalPosition==1 ? attr : 0, menuHorizontalPosition==2 ? attr : 0); drawTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, RIGHT | (menuHorizontalPosition==1 ? attr : 0), menuHorizontalPosition==2 ? attr : 0);
if (attr && (editMode>0 || p1valdiff)) { if (attr && (editMode>0 || p1valdiff)) {
div_t qr = div(timer->start, 60); div_t qr = div(timer->start, 60);
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
@ -311,8 +358,8 @@ void menuModelSetup(uint8_t event)
} }
else { else {
drawStringWithIndex(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1); drawStringWithIndex(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1);
putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0); drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0);
putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, menuHorizontalPosition==1 ? attr : 0, menuHorizontalPosition==2 ? attr : 0); drawTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, menuHorizontalPosition==1 ? attr : 0, menuHorizontalPosition==2 ? attr : 0);
if (attr && (editMode>0 || p1valdiff)) { if (attr && (editMode>0 || p1valdiff)) {
div_t qr = div(timer->start, 60); div_t qr = div(timer->start, 60);
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
@ -358,7 +405,7 @@ void menuModelSetup(uint8_t event)
ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, attr, event); ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, attr, event);
#else #else
ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, menuHorizontalPosition<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0); ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, menuHorizontalPosition<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0);
lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_RESET_BTN, (menuHorizontalPosition>0 && !NO_HIGHLIGHT()) ? attr : 0); lcdDrawText(MODEL_SETUP_2ND_COLUMN+4*FW, y, STR_RESET_BTN, (menuHorizontalPosition>0 && !NO_HIGHLIGHT()) ? attr : 0);
if (attr && menuHorizontalPosition>0) { if (attr && menuHorizontalPosition>0) {
s_editMode = 0; s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)) { if (event==EVT_KEY_LONG(KEY_ENTER)) {
@ -390,13 +437,13 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_THROTTLE_TRACE: case ITEM_MODEL_THROTTLE_TRACE:
{ {
lcdDrawTextAlignedLeft(y, STR_TTRACE); lcdDrawTextAlignedLeft(y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_CHNOUT); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr; uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr) if (idx > MIXSRC_Thr)
idx += 1; idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS) if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS; idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr); drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break; break;
} }
@ -492,7 +539,7 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_BEEP_CENTER: case ITEM_MODEL_BEEP_CENTER:
lcdDrawTextAlignedLeft(y, STR_BEEPCTR); lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS; i++) {
// TODO flash saving, \001 not needed in STR_RETA123 // TODO flash saving, \001 not needed in STR_RETA123
coord_t x = MODEL_SETUP_2ND_COLUMN+i*FW; coord_t x = MODEL_SETUP_2ND_COLUMN+i*FW;
lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) ); lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) );
@ -516,6 +563,25 @@ void menuModelSetup(uint8_t event)
break; break;
#endif #endif
#if defined(PCBX7D)
case ITEM_MODEL_INTERNAL_MODULE_LABEL:
lcdDrawTextAlignedLeft(y, TR_INTERNALRF);
break;
case ITEM_MODEL_INTERNAL_MODULE_MODE:
lcdDrawTextAlignedLeft(y, STR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[0].rfProtocol, attr);
if (attr) {
g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, RF_PROTO_OFF, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[0].type = MODULE_TYPE_XJT;
g_model.moduleData[0].channelsStart = 0;
g_model.moduleData[0].channelsCount = 0;
}
}
break;
#endif
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
case ITEM_MODEL_EXTRA_MODULE_LABEL: case ITEM_MODEL_EXTRA_MODULE_LABEL:
lcdDrawTextAlignedLeft(y, "RF Port 2 (PPM)"); lcdDrawTextAlignedLeft(y, "RF Port 2 (PPM)");
@ -626,8 +692,8 @@ void menuModelSetup(uint8_t event)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break; break;
case MM_RF_PROTO_CUSTOM: case MM_RF_PROTO_CUSTOM:
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol & 0x1f, menuHorizontalPosition == 0 ? attr : 0, 2); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol & 0x1f, RIGHT | (menuHorizontalPosition == 0 ? attr : 0), 2);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 1 ? attr : 0, 2); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, RIGHT | (menuHorizontalPosition == 1 ? attr : 0), 2);
break; break;
} }
if (attr && (editMode > 0 || p1valdiff)) { if (attr && (editMode > 0 || p1valdiff)) {
@ -670,6 +736,23 @@ void menuModelSetup(uint8_t event)
} }
break; break;
#endif #endif
#if defined(PCBX7D)
case ITEM_MODEL_TRAINER_LABEL:
lcdDrawTextAlignedLeft(y, STR_TRAINER);
break;
case ITEM_MODEL_TRAINER_MODE:
lcdDrawTextAlignedLeft(y, STR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, attr);
if (attr) g_model.trainerMode = checkIncDec(event, g_model.trainerMode, 0, HAS_WIRELESS_TRAINER_HARDWARE() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, EE_MODEL, isTrainerModeAvailable);
break;
#endif
#if defined(PCBX7D)
case ITEM_MODEL_INTERNAL_MODULE_CHANNELS:
case ITEM_MODEL_TRAINER_CHANNELS:
#endif
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
case ITEM_MODEL_EXTRA_MODULE_CHANNELS: case ITEM_MODEL_EXTRA_MODULE_CHANNELS:
#endif #endif
@ -702,6 +785,10 @@ void menuModelSetup(uint8_t event)
} }
#endif #endif
#if defined(PCBX7D)
case ITEM_MODEL_TRAINER_SETTINGS:
case ITEM_MODEL_INTERNAL_MODULE_BIND:
#endif
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
case ITEM_MODEL_EXTRA_MODULE_BIND: case ITEM_MODEL_EXTRA_MODULE_BIND:
#endif #endif
@ -715,9 +802,8 @@ void menuModelSetup(uint8_t event)
lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT);
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u');
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (moduleData.ppm.delay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (moduleData.ppm.delay*50)+300, RIGHT | ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0));
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, moduleData.ppm.pulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0); lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, moduleData.ppm.pulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0);
if (attr && (editMode>0 || p1valdiff)) { if (attr && (editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
case 0: case 0:
@ -783,6 +869,9 @@ void menuModelSetup(uint8_t event)
} }
#endif #endif
#if defined(PCBX7D)
case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE:
#endif
#if defined(CPUARM) #if defined(CPUARM)
case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE: case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE:
{ {
@ -813,7 +902,7 @@ void menuModelSetup(uint8_t event)
} }
} }
else { else {
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W - MODEL_SETUP_2ND_COLUMN - MENUS_SCROLLBAR_WIDTH, 8); lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W - MODEL_SETUP_2ND_COLUMN, 8);
} }
} }
} }
@ -905,9 +994,9 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_PPM2_PARAMS: case ITEM_MODEL_PPM2_PARAMS:
lcdDrawTextAlignedLeft(y, STR_PPMFRAME); lcdDrawTextAlignedLeft(y, STR_PPMFRAME);
lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.moduleData[1].ppmFrameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.moduleData[1].ppmFrameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1 | LEFT);
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u');
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.moduleData[1].ppmDelay*50)+300, (menuHorizontalPosition < 0 || menuHorizontalPosition==1) ? attr : 0); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.moduleData[1].ppmDelay*50)+300, RIGHT | ((menuHorizontalPosition < 0 || menuHorizontalPosition==1) ? attr : 0));
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.moduleData[1].ppmPulsePol ? '+' : '-', (menuHorizontalPosition < 0 || menuHorizontalPosition==2) ? attr : 0); lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.moduleData[1].ppmPulsePol ? '+' : '-', (menuHorizontalPosition < 0 || menuHorizontalPosition==2) ? attr : 0);
if (attr && (editMode>0 || p1valdiff)) { if (attr && (editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
@ -1005,9 +1094,7 @@ void menuModelFailsafe(uint8_t event)
SEND_FAILSAFE_NOW(g_moduleIdx); SEND_FAILSAFE_NOW(g_moduleIdx);
} }
SIMPLE_SUBMENU_NOTITLE(NUM_CHNOUT); SIMPLE_SUBMENU_NOTITLE(MAX_OUTPUT_CHANNELS);
SET_SCROLLBAR_X(0);
#define COL_W (LCD_W) #define COL_W (LCD_W)
const uint8_t SLIDER_W = 90; const uint8_t SLIDER_W = 90;

View file

@ -59,7 +59,7 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
} }
if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), NULL)) { if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), NULL)) {
POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD);
popupMenuFlags = 0; POPUP_MENU_UNSET_BSS_FLAG();
} }
} }
else { else {
@ -72,7 +72,7 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext) void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext)
{ {
int8_t sub = menuVerticalPosition - 1; int8_t sub = menuVerticalPosition - HEADER_LINE;
#if defined(CPUARM) #if defined(CPUARM)
uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL; uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL;
@ -80,18 +80,18 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
uint8_t eeFlags = EE_MODEL; uint8_t eeFlags = EE_MODEL;
#endif #endif
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
CustomFunctionData *cfn = &functions[k]; CustomFunctionData * cfn = &functions[k];
uint8_t func = CFN_FUNC(cfn); uint8_t func = CFN_FUNC(cfn);
for (uint8_t j=0; j<5; j++) { for (uint8_t j=0; j<5; j++) {
uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff)); uint8_t active = (attr && (s_editMode>0 || p1valdiff));
switch (j) { switch (j) {
case 0: case 0:
putsSwitches(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); drawSwitch(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
#if defined(CPUARM) #if defined(CPUARM)
if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) { if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) {
@ -122,7 +122,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
case 2: case 2:
{ {
int8_t maxParam = NUM_CHNOUT-1; int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION) #if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) { if (func == FUNC_OVERRIDE_CHANNEL) {
putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr); putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr);
@ -132,9 +132,9 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
if (func == FUNC_TRAINER) { if (func == FUNC_TRAINER) {
maxParam = 4; maxParam = 4;
#if defined(CPUARM) #if defined(CPUARM)
putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); drawSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#else #else
putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); drawSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#endif #endif
} }
#if defined(GVARS) #if defined(GVARS)
@ -197,7 +197,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#if defined(CPUARM) #if defined(CPUARM)
else if (func == FUNC_SET_TIMER) { else if (func == FUNC_SET_TIMER) {
val_max = 539*60+59; val_max = 539*60+59;
putsTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT, attr); drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT, attr);
} }
#endif #endif
#if defined(AUDIO) #if defined(AUDIO)
@ -234,21 +234,21 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
} }
else { else {
POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD);
popupMenuFlags = 0; POPUP_MENU_UNSET_BSS_FLAG();
} }
} }
break; break;
} }
else if (func == FUNC_PLAY_VALUE) { else if (func == FUNC_PLAY_VALUE) {
val_max = MIXSRC_LAST_TELEM; val_max = MIXSRC_LAST_TELEM;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
else if (func == FUNC_VOLUME) { else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -278,7 +278,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
} }
else if (func == FUNC_PLAY_VALUE) { else if (func == FUNC_PLAY_VALUE) {
val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1; val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable); INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
} }
#endif #endif
@ -303,7 +303,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
break; break;
case FUNC_ADJUST_GVAR_SOURCE: case FUNC_ADJUST_GVAR_SOURCE:
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
break; break;
@ -377,6 +377,6 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
void menuModelSpecialFunctions(uint8_t event) void menuModelSpecialFunctions(uint8_t event)
{ {
MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
return menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext); return menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext);
} }

View file

@ -96,6 +96,8 @@ enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_VARIO_SOURCE, ITEM_TELEMETRY_VARIO_SOURCE,
#endif #endif
CASE_VARIO(ITEM_TELEMETRY_VARIO_RANGE) CASE_VARIO(ITEM_TELEMETRY_VARIO_RANGE)
#if !defined(CPUARM)
// TODO check the cost of moving them to a new screen on the 9X
ITEM_TELEMETRY_SCREEN_LABEL1, ITEM_TELEMETRY_SCREEN_LABEL1,
ITEM_TELEMETRY_SCREEN_LINE1, ITEM_TELEMETRY_SCREEN_LINE1,
ITEM_TELEMETRY_SCREEN_LINE2, ITEM_TELEMETRY_SCREEN_LINE2,
@ -106,17 +108,6 @@ enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_SCREEN_LINE6, ITEM_TELEMETRY_SCREEN_LINE6,
ITEM_TELEMETRY_SCREEN_LINE7, ITEM_TELEMETRY_SCREEN_LINE7,
ITEM_TELEMETRY_SCREEN_LINE8, ITEM_TELEMETRY_SCREEN_LINE8,
#if defined(CPUARM)
ITEM_TELEMETRY_SCREEN_LABEL3,
ITEM_TELEMETRY_SCREEN_LINE9,
ITEM_TELEMETRY_SCREEN_LINE10,
ITEM_TELEMETRY_SCREEN_LINE11,
ITEM_TELEMETRY_SCREEN_LINE12,
ITEM_TELEMETRY_SCREEN_LABEL4,
ITEM_TELEMETRY_SCREEN_LINE13,
ITEM_TELEMETRY_SCREEN_LINE14,
ITEM_TELEMETRY_SCREEN_LINE15,
ITEM_TELEMETRY_SCREEN_LINE16,
#endif #endif
ITEM_TELEMETRY_MAX ITEM_TELEMETRY_MAX
}; };
@ -181,12 +172,11 @@ enum MenuModelTelemetryFrskyItems {
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
#define TELEMETRY_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2) #define TELEMETRY_SCREENS_ROWS
#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x)
#define TELEMETRY_CURRENT_SCREEN(k) (k < ITEM_TELEMETRY_SCREEN_LABEL2 ? 0 : (k < ITEM_TELEMETRY_SCREEN_LABEL3 ? 1 : (k < ITEM_TELEMETRY_SCREEN_LABEL4 ? 2 : 3)))
#else #else
#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, 2, 2, 2, 2 #define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, 2, 2, 2, 2
#define TELEMETRY_CURRENT_CHANNEL(k) (k >= ITEM_TELEMETRY_A2_LABEL ? TELEM_ANA_A2 : TELEM_ANA_A1) #define TELEMETRY_CURRENT_CHANNEL(k) (k >= ITEM_TELEMETRY_A2_LABEL ? TELEM_ANA_A2 : TELEM_ANA_A1)
#define TELEMETRY_SCREENS_ROWS TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1)
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
@ -322,25 +312,25 @@ void menuModelSensor(uint8_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) { if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) { if (sensor->formula == TELEM_FORMULA_CELL) {
lcdDrawTextAlignedLeft(y, STR_CELLSENSOR); lcdDrawTextAlignedLeft(y, STR_CELLSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor); sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawTextAlignedLeft(y, STR_GPSSENSOR); lcdDrawTextAlignedLeft(y, STR_GPSSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor); sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) { else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
lcdDrawTextAlignedLeft(y, STR_CURRENTSENSOR); lcdDrawTextAlignedLeft(y, STR_CURRENTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCurrentSensor); sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCurrentSensor);
} }
break; break;
} }
@ -372,9 +362,9 @@ void menuModelSensor(uint8_t event)
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawTextAlignedLeft(y, STR_ALTSENSOR); lcdDrawTextAlignedLeft(y, STR_ALTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor);
} }
break; break;
} }
@ -396,14 +386,14 @@ void menuModelSensor(uint8_t event)
drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1); drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1]; int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
if (attr) { if (attr) {
source = checkIncDec(event, source, -MAX_SENSORS, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); source = checkIncDec(event, source, -MAX_TELEMETRY_SENSORS, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
if (source < 0) { if (source < 0) {
lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr); lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr);
putsMixerSource(lcdNextPos, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr); drawSource(lcdNextPos, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr);
} }
else { else {
putsMixerSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr);
} }
break; break;
} }
@ -436,14 +426,14 @@ void onSensorMenu(const char *result)
{ {
uint8_t index = menuVerticalPosition - 1 - ITEM_TELEMETRY_SENSOR1; uint8_t index = menuVerticalPosition - 1 - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) { if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) { if (result == STR_EDIT) {
pushMenu(menuModelSensor); pushMenu(menuModelSensor);
} }
else if (result == STR_DELETE) { else if (result == STR_DELETE) {
delTelemetryIndex(index); delTelemetryIndex(index);
index += 1; index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index)) if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1; menuVerticalPosition += 1;
else else
menuVerticalPosition = 1+ITEM_TELEMETRY_NEW_SENSOR; menuVerticalPosition = 1+ITEM_TELEMETRY_NEW_SENSOR;
@ -473,21 +463,23 @@ void menuModelTelemetryFrsky(uint8_t event)
#if defined(CPUARM) #if defined(CPUARM)
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) { for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i); delTelemetryIndex(i);
} }
} }
#endif #endif
MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, ITEM_TELEMETRY_MAX+1, {0, TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), CASE_CPUARM(TELEMETRY_SCREEN_ROWS(2)) CASE_CPUARM(TELEMETRY_SCREEN_ROWS(3))}); MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) TELEMETRY_SCREENS_ROWS });
uint8_t sub = menuVerticalPosition - 1; uint8_t sub = menuVerticalPosition - HEADER_LINE;
switch (event) { switch (event) {
case EVT_KEY_BREAK(KEY_DOWN): case EVT_KEY_BREAK(KEY_DOWN):
case EVT_KEY_BREAK(KEY_UP): case EVT_KEY_BREAK(KEY_UP):
#if !defined(PCBX7D)
case EVT_KEY_BREAK(KEY_LEFT): case EVT_KEY_BREAK(KEY_LEFT):
case EVT_KEY_BREAK(KEY_RIGHT): case EVT_KEY_BREAK(KEY_RIGHT):
#endif
if (s_editMode>0 && sub<=ITEM_TELEMETRY_RSSI_ALARM2) if (s_editMode>0 && sub<=ITEM_TELEMETRY_RSSI_ALARM2)
frskySendAlarms(); // update FrSky module when edit mode exited frskySendAlarms(); // update FrSky module when edit mode exited
break; break;
@ -498,7 +490,7 @@ void menuModelTelemetryFrsky(uint8_t event)
uint8_t k = i + menuVerticalOffset; uint8_t k = i + menuVerticalOffset;
#if defined(CPUARM) #if defined(CPUARM)
for (int j=0; j<=k; j++) { for (int j=0; j<=k; j++) {
if (mstate_tab[j+1] == HIDDEN_ROW) if (mstate_tab[j+HEADER_LINE] == HIDDEN_ROW)
k++; k++;
} }
#endif #endif
@ -513,7 +505,7 @@ void menuModelTelemetryFrsky(uint8_t event)
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)
if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_SENSORS) { if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_TELEMETRY_SENSORS) {
int index = k-ITEM_TELEMETRY_SENSOR1; int index = k-ITEM_TELEMETRY_SENSOR1;
lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr); lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr);
lcdDrawChar(lcdLastPos, y, ':', attr); lcdDrawChar(lcdLastPos, y, ':', attr);
@ -756,9 +748,9 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_VARIO_SOURCE: case ITEM_TELEMETRY_VARIO_SOURCE:
lcdDrawTextAlignedLeft(y, STR_SOURCE); lcdDrawTextAlignedLeft(y, STR_SOURCE);
#if defined(CPUARM) #if defined(CPUARM)
putsMixerSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr); drawSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr);
if (attr) { if (attr) {
g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
#else #else
lcdDrawTextAtIndex(TELEM_COL2, y, STR_VARIOSRC, g_model.frsky.varioSource, attr); lcdDrawTextAtIndex(TELEM_COL2, y, STR_VARIOSRC, g_model.frsky.varioSource, attr);
@ -784,8 +776,8 @@ void menuModelTelemetryFrsky(uint8_t event)
#else #else
lcdDrawNumber(TELEM_COL2, y, -10+g_model.frsky.varioMin, (menuHorizontalPosition<=0 ? attr : 0)|LEFT); lcdDrawNumber(TELEM_COL2, y, -10+g_model.frsky.varioMin, (menuHorizontalPosition<=0 ? attr : 0)|LEFT);
lcdDrawNumber(TELEM_COL2+7*FW-2, y, -5+g_model.frsky.varioCenterMin, ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0)|PREC1); lcdDrawNumber(TELEM_COL2+7*FW-2, y, -5+g_model.frsky.varioCenterMin, ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0)|PREC1);
lcdDrawNumber(TELEM_COL2+10*FW, y, 5+g_model.frsky.varioCenterMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0)|PREC1); lcdDrawNumber(TELEM_COL2+10*FW-1, y, 5+g_model.frsky.varioCenterMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0)|PREC1);
lcdDrawNumber(TELEM_COL2+13*FW+2, y, 10+g_model.frsky.varioMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==3) ? attr : 0)); lcdDrawNumber(TELEM_COL2+13*FW, y, 10+g_model.frsky.varioMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==3) ? attr : 0));
if (attr && (s_editMode>0 || p1valdiff)) { if (attr && (s_editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
case 0: case 0:
@ -806,23 +798,9 @@ void menuModelTelemetryFrsky(uint8_t event)
break; break;
#endif #endif
#if !defined(CPUARM)
case ITEM_TELEMETRY_SCREEN_LABEL1: case ITEM_TELEMETRY_SCREEN_LABEL1:
case ITEM_TELEMETRY_SCREEN_LABEL2: case ITEM_TELEMETRY_SCREEN_LABEL2:
#if defined(CPUARM)
case ITEM_TELEMETRY_SCREEN_LABEL3:
case ITEM_TELEMETRY_SCREEN_LABEL4:
{
uint8_t screenIndex = TELEMETRY_CURRENT_SCREEN(k);
drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex+1);
TelemetryScreenType oldScreenType = TELEMETRY_SCREEN_TYPE(screenIndex);
TelemetryScreenType newScreenType = (TelemetryScreenType)selectMenuItem(TELEM_SCRTYPE_COL, y, PSTR(""), STR_VTELEMSCREENTYPE, oldScreenType, 0, TELEMETRY_SCREEN_TYPE_MAX, (menuHorizontalPosition==0 ? attr : 0), event);
if (newScreenType != oldScreenType) {
g_model.frsky.screensType = (g_model.frsky.screensType & (~(0x03 << (2*screenIndex)))) | (newScreenType << (2*screenIndex));
memset(&g_model.frsky.screens[screenIndex], 0, sizeof(g_model.frsky.screens[screenIndex]));
}
break;
}
#else
{ {
uint8_t screenIndex = (k < ITEM_TELEMETRY_SCREEN_LABEL2 ? 1 : 2); uint8_t screenIndex = (k < ITEM_TELEMETRY_SCREEN_LABEL2 ? 1 : 2);
drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex); drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex);
@ -833,7 +811,6 @@ void menuModelTelemetryFrsky(uint8_t event)
#endif #endif
break; break;
} }
#endif
case ITEM_TELEMETRY_SCREEN_LINE1: case ITEM_TELEMETRY_SCREEN_LINE1:
case ITEM_TELEMETRY_SCREEN_LINE2: case ITEM_TELEMETRY_SCREEN_LINE2:
@ -843,33 +820,12 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_SCREEN_LINE6: case ITEM_TELEMETRY_SCREEN_LINE6:
case ITEM_TELEMETRY_SCREEN_LINE7: case ITEM_TELEMETRY_SCREEN_LINE7:
case ITEM_TELEMETRY_SCREEN_LINE8: case ITEM_TELEMETRY_SCREEN_LINE8:
#if defined(CPUARM)
case ITEM_TELEMETRY_SCREEN_LINE9:
case ITEM_TELEMETRY_SCREEN_LINE10:
case ITEM_TELEMETRY_SCREEN_LINE11:
case ITEM_TELEMETRY_SCREEN_LINE12:
case ITEM_TELEMETRY_SCREEN_LINE13:
case ITEM_TELEMETRY_SCREEN_LINE14:
case ITEM_TELEMETRY_SCREEN_LINE15:
case ITEM_TELEMETRY_SCREEN_LINE16:
#endif
{ {
uint8_t screenIndex, lineIndex; uint8_t screenIndex, lineIndex;
if (k < ITEM_TELEMETRY_SCREEN_LABEL2) { if (k < ITEM_TELEMETRY_SCREEN_LABEL2) {
screenIndex = 0; screenIndex = 0;
lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE1; lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE1;
} }
#if defined(CPUARM)
else if (k >= ITEM_TELEMETRY_SCREEN_LABEL4) {
screenIndex = 3;
lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE13;
}
else if (k >= ITEM_TELEMETRY_SCREEN_LABEL3) {
screenIndex = 2;
lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE9;
}
#endif
else { else {
screenIndex = 1; screenIndex = 1;
lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE5; lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE5;
@ -879,58 +835,28 @@ void menuModelTelemetryFrsky(uint8_t event)
if (IS_BARS_SCREEN(screenIndex)) { if (IS_BARS_SCREEN(screenIndex)) {
FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex]; FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex];
source_t barSource = bar.source; source_t barSource = bar.source;
#if defined(CPUARM)
putsMixerSource(TELEM_COL1, y, barSource, menuHorizontalPosition==0 ? attr : 0);
if (barSource) {
if (barSource <= MIXSRC_LAST_CH) {
putsChannelValue(TELEM_BARS_COLMIN, y, barSource, calc100toRESX(bar.barMin), (menuHorizontalPosition==1 ? attr : 0) | LEFT);
putsChannelValue(TELEM_BARS_COLMAX, y, barSource, calc100toRESX(bar.barMax), (menuHorizontalPosition==2 ? attr : 0) | LEFT);
}
else {
putsChannelValue(TELEM_BARS_COLMIN, y, barSource, bar.barMin, (menuHorizontalPosition==1 ? attr : 0) | LEFT);
putsChannelValue(TELEM_BARS_COLMAX, y, barSource, bar.barMax, (menuHorizontalPosition==2 ? attr : 0) | LEFT);
}
}
#else
lcdDrawTextAtIndex(TELEM_COL1, y, STR_VTELEMCHNS, barSource, menuHorizontalPosition==0 ? attr : 0); lcdDrawTextAtIndex(TELEM_COL1, y, STR_VTELEMCHNS, barSource, menuHorizontalPosition==0 ? attr : 0);
if (barSource) { if (barSource) {
putsTelemetryChannelValue(TELEM_BARS_COLMIN, y, barSource-1, convertBarTelemValue(barSource, bar.barMin), (menuHorizontalPosition==1 ? attr : 0) | LEFT); putsTelemetryChannelValue(TELEM_BARS_COLMIN, y, barSource-1, convertBarTelemValue(barSource, bar.barMin), (menuHorizontalPosition==1 ? attr : 0) | LEFT);
putsTelemetryChannelValue(TELEM_BARS_COLMAX, y, barSource-1, convertBarTelemValue(barSource, 255-bar.barMax), (menuHorizontalPosition==2 ? attr : 0) | LEFT); putsTelemetryChannelValue(TELEM_BARS_COLMAX, y, barSource-1, convertBarTelemValue(barSource, 255-bar.barMax), (menuHorizontalPosition==2 ? attr : 0) | LEFT);
} }
#endif
else if (attr && menuHorizontalPosition>0) { else if (attr && menuHorizontalPosition>0) {
menuHorizontalPosition = 0; menuHorizontalPosition = 0;
} }
if (attr && (s_editMode>0 || p1valdiff)) { if (attr && (s_editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
case 0: case 0:
#if defined(CPUARM)
bar.source = CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, barSource, MIXSRC_LAST_TELEM, isSourceAvailable);
#else
bar.source = CHECK_INCDEC_MODELVAR_ZERO(event, barSource, TELEM_DISPLAY_MAX); bar.source = CHECK_INCDEC_MODELVAR_ZERO(event, barSource, TELEM_DISPLAY_MAX);
#endif
if (checkIncDec_Ret) { if (checkIncDec_Ret) {
bar.barMin = 0; bar.barMin = 0;
#if defined(CPUARM)
bar.barMax = 0;
#else
bar.barMax = 255 - maxBarTelemValue(bar.source); bar.barMax = 255 - maxBarTelemValue(bar.source);
#endif
} }
break; break;
case 1: case 1:
#if defined(CPUARM)
bar.barMin = checkIncDec(event, bar.barMin, -30000, bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
#else
bar.barMin = checkIncDec(event, bar.barMin, 0, 254-bar.barMax, EE_MODEL|NO_INCDEC_MARKS); bar.barMin = checkIncDec(event, bar.barMin, 0, 254-bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
#endif
break; break;
case 2: case 2:
#if defined(CPUARM)
bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, 30000, EE_MODEL|NO_INCDEC_MARKS);
#else
bar.barMax = 255 - checkIncDec(event, 255-bar.barMax, bar.barMin+1, maxBarTelemValue(barSource), EE_MODEL|NO_INCDEC_MARKS); bar.barMax = 255 - checkIncDec(event, 255-bar.barMax, bar.barMin+1, maxBarTelemValue(barSource), EE_MODEL|NO_INCDEC_MARKS);
#endif
break; break;
} }
} }
@ -942,17 +868,10 @@ void menuModelTelemetryFrsky(uint8_t event)
uint8_t cellAttr = (menuHorizontalPosition==c ? attr : 0); uint8_t cellAttr = (menuHorizontalPosition==c ? attr : 0);
source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c]; source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c];
uint8_t pos[] = {INDENT_WIDTH, TELEM_COL2}; uint8_t pos[] = {INDENT_WIDTH, TELEM_COL2};
#if defined(CPUARM)
putsMixerSource(pos[c], y, value, cellAttr);
if (cellAttr && (s_editMode>0 || p1valdiff)) {
CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, value, MIXSRC_LAST_TELEM, isSourceAvailable);
}
#else
lcdDrawTextAtIndex(pos[c], y, STR_VTELEMCHNS, value, cellAttr); lcdDrawTextAtIndex(pos[c], y, STR_VTELEMCHNS, value, cellAttr);
if (cellAttr && (s_editMode>0 || p1valdiff)) { if (cellAttr && (s_editMode>0 || p1valdiff)) {
CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, value, (lineIndex==3 && c==0) ? TELEM_STATUS_MAX : TELEM_DISPLAY_MAX, isTelemetrySourceAvailable); CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, value, (lineIndex==3 && c==0) ? TELEM_STATUS_MAX : TELEM_DISPLAY_MAX, isTelemetrySourceAvailable);
} }
#endif
} }
if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) { if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) {
REPEAT_LAST_CURSOR_MOVE(); REPEAT_LAST_CURSOR_MOVE();
@ -960,6 +879,7 @@ void menuModelTelemetryFrsky(uint8_t event)
} }
break; break;
} }
#endif // !defined(CPUARM)
} }
} }
} }

View file

@ -23,7 +23,7 @@
vertpos_t menuVerticalOffset; vertpos_t menuVerticalOffset;
int8_t s_editMode; int8_t s_editMode;
uint8_t noHighlightCounter; uint8_t noHighlightCounter;
uint8_t calibrationState; uint8_t menuCalibrationState;
vertpos_t menuVerticalPosition; vertpos_t menuVerticalPosition;
horzpos_t menuHorizontalPosition; horzpos_t menuHorizontalPosition;
@ -41,7 +41,7 @@ int8_t checkIncDecMovedSwitch(int8_t val)
if (s_editMode>0) { if (s_editMode>0) {
int8_t swtch = getMovedSwitch(); int8_t swtch = getMovedSwitch();
if (swtch) { if (swtch) {
if (IS_MOMENTARY(val) && swtch==val) if (IS_CONFIG_TOGGLE(swtch) && swtch==val)
val = -val; val = -val;
else else
val = swtch; val = swtch;
@ -53,16 +53,229 @@ int8_t checkIncDecMovedSwitch(int8_t val)
int8_t checkIncDec_Ret; int8_t checkIncDec_Ret;
#if defined(PCBX7D)
#define DBLKEYS_PRESSED_RGT_LFT(in) (false)
#define DBLKEYS_PRESSED_UP_DWN(in) (false)
#define DBLKEYS_PRESSED_RGT_UP(in) (false)
#define DBLKEYS_PRESSED_LFT_DWN(in) (false)
#else
#define DBLKEYS_PRESSED_RGT_LFT(in) ((in & (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT)) == (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT)) #define DBLKEYS_PRESSED_RGT_LFT(in) ((in & (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT)) == (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT))
#define DBLKEYS_PRESSED_UP_DWN(in) ((in & (KEYS_GPIO_PIN_UP + KEYS_GPIO_PIN_DOWN)) == (KEYS_GPIO_PIN_UP + KEYS_GPIO_PIN_DOWN)) #define DBLKEYS_PRESSED_UP_DWN(in) ((in & (KEYS_GPIO_PIN_UP + KEYS_GPIO_PIN_DOWN)) == (KEYS_GPIO_PIN_UP + KEYS_GPIO_PIN_DOWN))
#define DBLKEYS_PRESSED_RGT_UP(in) ((in & (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_UP)) == (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_UP)) #define DBLKEYS_PRESSED_RGT_UP(in) ((in & (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_UP)) == (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_UP))
#define DBLKEYS_PRESSED_LFT_DWN(in) ((in & (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN)) == (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN)) #define DBLKEYS_PRESSED_LFT_DWN(in) ((in & (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN)) == (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN))
#endif
#if defined(CPUARM) #if defined(CPUARM)
INIT_STOPS(stops100, 3, -100, 0, 100) INIT_STOPS(stops100, 3, -100, 0, 100)
INIT_STOPS(stops1000, 3, -1000, 0, 1000) INIT_STOPS(stops1000, 3, -1000, 0, 1000)
INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST) INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST)
#if defined(PCBX7D)
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)
uint32_t 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 && (event==EVT_KEY_FIRST(KEY_PLUS) || event==EVT_KEY_REPT(KEY_PLUS))) {
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_KEY_ERROR();
}
}
else if (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_MINUS) || event==EVT_KEY_REPT(KEY_MINUS))) {
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_KEY_ERROR();
}
}
if (!READ_ONLY() && i_min==0 && i_max==1 && event==EVT_KEY_BREAK(KEY_ENTER)) {
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 != val) {
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && stops.contains(newval)) {
bool pause = (newval > val ? !stops.contains(newval+1) : !stops.contains(newval-1));
if (pause) {
pauseEvents(event); // delay before auto-repeat continues
}
}
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
if (!IS_KEY_REPT(event)) {
AUDIO_KEY_PRESS();
}
}
else {
checkIncDec_Ret = 0;
}
if (i_flags & INCDEC_SOURCE) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
// TODO checkIncDecSelection = MIXSRC_NONE;
if (i_min <= MIXSRC_FIRST_INPUT && i_max >= MIXSRC_FIRST_INPUT) {
if (getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable) != MIXSRC_NONE) {
POPUP_MENU_ADD_ITEM(STR_MENU_INPUTS);
}
}
#if defined(LUA_MODEL_SCRIPTS)
if (i_min <= MIXSRC_FIRST_LUA && i_max >= MIXSRC_FIRST_LUA) {
if (getFirstAvailable(MIXSRC_FIRST_LUA, MIXSRC_LAST_LUA, isSourceAvailable) != MIXSRC_NONE) {
POPUP_MENU_ADD_ITEM(STR_MENU_LUA);
}
}
#endif
if (i_min <= MIXSRC_FIRST_STICK && i_max >= MIXSRC_FIRST_STICK) POPUP_MENU_ADD_ITEM(STR_MENU_STICKS);
if (i_min <= MIXSRC_FIRST_POT && i_max >= MIXSRC_FIRST_POT) POPUP_MENU_ADD_ITEM(STR_MENU_POTS);
if (i_min <= MIXSRC_MAX && i_max >= MIXSRC_MAX) POPUP_MENU_ADD_ITEM(STR_MENU_MAX);
#if defined(HELI)
if (i_min <= MIXSRC_FIRST_HELI && i_max >= MIXSRC_FIRST_HELI) POPUP_MENU_ADD_ITEM(STR_MENU_HELI);
#endif
if (i_min <= MIXSRC_FIRST_TRIM && i_max >= MIXSRC_FIRST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= MIXSRC_FIRST_SWITCH && i_max >= MIXSRC_FIRST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= MIXSRC_FIRST_TRAINER && i_max >= MIXSRC_FIRST_TRAINER) POPUP_MENU_ADD_ITEM(STR_MENU_TRAINER);
if (i_min <= MIXSRC_FIRST_CH && i_max >= MIXSRC_FIRST_CH) POPUP_MENU_ADD_ITEM(STR_MENU_CHANNELS);
if (i_min <= MIXSRC_FIRST_GVAR && i_max >= MIXSRC_FIRST_GVAR && isValueAvailable(MIXSRC_FIRST_GVAR)) {
POPUP_MENU_ADD_ITEM(STR_MENU_GVARS);
}
if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) {
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) {
POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY);
break;
}
}
}
// TODO POPUP_MENU_START(onSourceLongEnterPress);
}
#if 0 // TODO
if (checkIncDecSelection != 0) {
newval = checkIncDecSelection;
if (checkIncDecSelection != MIXSRC_MAX)
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
}
#endif
}
#if 0 // TODO
else if (i_flags & INCDEC_SWITCH) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
checkIncDecSelection = SWSRC_NONE;
if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < MAX_LOGICAL_SWITCHES; i++) {
if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) {
POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES);
break;
}
}
}
if (isValueAvailable && isValueAvailable(SWSRC_ON)) POPUP_MENU_ADD_ITEM(STR_MENU_OTHER);
if (isValueAvailable && isValueAvailable(-newval)) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT);
POPUP_MENU_START(onSwitchLongEnterPress);
s_editMode = EDIT_MODIFY_FIELD;
}
if (checkIncDecSelection != 0) {
newval = (checkIncDecSelection == SWSRC_INVERT ? -newval : checkIncDecSelection);
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
}
}
#endif
return newval;
}
#else
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops) 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; int newval = val;
@ -182,6 +395,7 @@ int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int
} }
return newval; return newval;
} }
#endif
#else #else
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags)
{ {
@ -316,6 +530,253 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
tmr10ms_t menuEntryTime; tmr10ms_t menuEntryTime;
#endif #endif
#if defined(PCBX7D)
#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 MENU_FIRST_LINE_EDIT (menuTab ? (MAXCOL((uint16_t)0) >= HIDDEN_ROW ? (MAXCOL((uint16_t)1) >= HIDDEN_ROW ? 2 : 1) : 0) : 0)
#define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0)
#define EDIT_MODE_INIT 0 // TODO enum
void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, const pm_uint8_t * horTab, uint8_t horTabMax, vertpos_t rowcount)
{
vertpos_t l_posVert = menuVerticalPosition;
horzpos_t l_posHorz = menuHorizontalPosition;
uint8_t maxcol = MAXCOL(l_posVert);
if (menuTab) {
int cc = curr;
switch (event) {
#if 0 // TODO
case EVT_KEY_LONG(KEY_MENU):
if (menuTab == menuTabModel) {
killEvents(event);
if (modelHasNotes()) {
POPUP_MENU_ADD_SD_ITEM(STR_VIEW_CHANNELS);
POPUP_MENU_ADD_ITEM(STR_VIEW_NOTES);
POPUP_MENU_START(onLongMenuPress);
}
else {
pushMenu(menuChannelsView);
}
}
break;
#endif
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 (!menuCalibrationState && cc != curr) {
chainMenu((MenuHandlerFunc)pgm_read_adr(&menuTab[cc]));
}
// TODO if (!(flags&CHECK_FLAG_NO_SCREEN_INDEX)) {
drawScreenIndex(curr, menuTabSize, 0);
// }
// TODO lcdDrawFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, SOLID, FILL_WHITE|GREY_DEFAULT);
}
DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);
switch (event) {
case EVT_ENTRY:
menuEntryTime = get_tmr10ms();
s_editMode = EDIT_MODE_INIT;
l_posVert = MENU_FIRST_LINE_EDIT;
l_posHorz = POS_HORZ_INIT(l_posVert);
break;
case EVT_ENTRY_UP:
menuEntryTime = get_tmr10ms();
s_editMode = 0;
l_posHorz = POS_HORZ_INIT(l_posVert);
break;
case EVT_ROTARY_BREAK:
if (s_editMode > 1) break;
if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) {
l_posHorz = 0;
AUDIO_KEY_PRESS();
}
else if (READ_ONLY_UNLOCKED()) {
s_editMode = (s_editMode<=0);
AUDIO_KEY_PRESS();
}
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;
AUDIO_KEY_PRESS();
break;
}
if (l_posHorz >= 0 && (COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
l_posHorz = -1;
AUDIO_KEY_PRESS();
}
else {
uint8_t posVertInit = MENU_FIRST_LINE_EDIT;
if (menuVerticalOffset != 0 || l_posVert != posVertInit) {
menuVerticalOffset = 0;
l_posVert = posVertInit;
l_posHorz = POS_HORZ_INIT(l_posVert);
AUDIO_KEY_PRESS();
}
else {
popMenu();
}
}
break;
case EVT_KEY_FIRST(KEY_RIGHT):
AUDIO_KEY_PRESS();
// no break
case EVT_KEY_REPT(KEY_RIGHT):
if (s_editMode > 0) break; // TODO it was !=
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;
}
}
do {
INC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1);
} 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_KEY_FIRST(KEY_LEFT):
AUDIO_KEY_PRESS();
// no break
case EVT_KEY_REPT(KEY_LEFT):
if (s_editMode > 0) break; // TODO it was !=
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 {
l_posHorz = 0xff;
}
do {
DEC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1);
} 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;
}
int linesCount = rowcount;
if (l_posVert == 0 || (l_posVert==1 && MAXCOL(vertpos_t(0)) >= HIDDEN_ROW) || (l_posVert==2 && MAXCOL(vertpos_t(0)) >= HIDDEN_ROW && MAXCOL(vertpos_t(1)) >= HIDDEN_ROW)) {
menuVerticalOffset = 0;
if (horTab) {
linesCount = 0;
for (int i=0; i<rowcount; i++) {
if (i>horTabMax || horTab[i] != HIDDEN_ROW) {
linesCount++;
}
}
}
}
else if (horTab) {
if (rowcount > NUM_BODY_LINES) {
while (1) {
vertpos_t firstLine = 0;
for (int numLines=0; firstLine<rowcount && numLines<menuVerticalOffset; firstLine++) {
if (firstLine>=horTabMax || horTab[firstLine] != HIDDEN_ROW) {
numLines++;
}
}
if (l_posVert < firstLine) {
menuVerticalOffset--;
}
else {
vertpos_t lastLine = firstLine;
for (int numLines=0; lastLine<rowcount && numLines<NUM_BODY_LINES; lastLine++) {
if (lastLine>=horTabMax || horTab[lastLine] != HIDDEN_ROW) {
numLines++;
}
}
if (l_posVert >= lastLine) {
menuVerticalOffset++;
}
else {
linesCount = menuVerticalOffset + NUM_BODY_LINES;
for (int i=lastLine; i<rowcount; i++) {
if (i>horTabMax || horTab[i] != HIDDEN_ROW) {
linesCount++;
}
}
break;
}
}
}
}
}
else {
if (l_posVert>=NUM_BODY_LINES+menuVerticalOffset) {
menuVerticalOffset = l_posVert-NUM_BODY_LINES+1;
}
else if (l_posVert<menuVerticalOffset) {
menuVerticalOffset = l_posVert;
}
}
// TODO if (name) {
// title(name);
// }
menuVerticalPosition = l_posVert;
menuHorizontalPosition = l_posHorz;
}
#else
void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow) void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow)
{ {
vertpos_t l_posVert = menuVerticalPosition; vertpos_t l_posVert = menuVerticalPosition;
@ -356,8 +817,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
if (menuTab) { if (menuTab) {
uint8_t attr = 0; uint8_t attr = 0;
if (l_posVert==0 && !menuCalibrationState) {
if (l_posVert==0 && !calibrationState) {
attr = INVERS; attr = INVERS;
int8_t cc = curr; int8_t cc = curr;
@ -366,7 +826,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1)); cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1));
} }
switch(event) { switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK: case EVT_ROTARY_BREAK:
if (s_editMode < 0 && maxrow > 0) { if (s_editMode < 0 && maxrow > 0) {
@ -416,7 +876,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#endif #endif
} }
calibrationState = 0; menuCalibrationState = 0;
drawScreenIndex(curr, menuTabSize, attr); drawScreenIndex(curr, menuTabSize, attr);
} }
@ -434,7 +894,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
} }
} }
switch(event) switch (event)
{ {
case EVT_ENTRY: case EVT_ENTRY:
#if defined(CPUARM) #if defined(CPUARM)
@ -442,7 +902,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#endif #endif
l_posVert = 0; l_posVert = 0;
l_posHorz = POS_HORZ_INIT(l_posVert); l_posHorz = POS_HORZ_INIT(l_posVert);
SET_SCROLLBAR_X(LCD_W-1);
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
if (menuTab) { if (menuTab) {
s_editMode = EDIT_MODE_INIT; s_editMode = EDIT_MODE_INIT;
@ -457,7 +916,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ENTRY_UP: case EVT_ENTRY_UP:
s_editMode = 0; s_editMode = 0;
SET_SCROLLBAR_X(LCD_W-1);
break; break;
case EVT_ROTARY_BREAK: case EVT_ROTARY_BREAK:
@ -533,11 +991,12 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
break; break;
#endif #endif
case EVT_KEY_REPT(KEY_DOWN): //inc #if !defined(PCBX7D)
case EVT_KEY_REPT(KEY_DOWN):
if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break; if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break;
// no break // no break
case EVT_KEY_FIRST(KEY_DOWN): //inc case EVT_KEY_FIRST(KEY_DOWN):
if (s_editMode>0) break; if (s_editMode>0) break;
do { do {
INC(l_posVert, 0, maxrow); INC(l_posVert, 0, maxrow);
@ -547,8 +1006,9 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
s_editMode = 0; // if we go down, we must be in this mode s_editMode = 0; // if we go down, we must be in this mode
#endif #endif
l_posHorz = min(l_posHorz, MAXCOL(l_posVert)); l_posHorz = min<horzpos_t>(l_posHorz, MAXCOL(l_posVert));
break; break;
#endif
case EVT_KEY_REPT(KEY_LEFT): //dec case EVT_KEY_REPT(KEY_LEFT): //dec
if (l_posHorz==0) break; if (l_posHorz==0) break;
@ -576,10 +1036,11 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
break; break;
#endif #endif
case EVT_KEY_REPT(KEY_UP): //dec #if !defined(PCBX7D)
case EVT_KEY_REPT(KEY_UP):
if (!IS_ROTARY_LEFT(event) && l_posVert==0) break; if (!IS_ROTARY_LEFT(event) && l_posVert==0) break;
// no break // no break
case EVT_KEY_FIRST(KEY_UP): //dec case EVT_KEY_FIRST(KEY_UP):
if (s_editMode>0) break; if (s_editMode>0) break;
do { do {
@ -592,6 +1053,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
break; break;
#endif
} }
uint8_t maxLines = menuTab ? LCD_LINES-1 : LCD_LINES-2; uint8_t maxLines = menuTab ? LCD_LINES-1 : LCD_LINES-2;
@ -670,8 +1132,9 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
} }
#endif #endif
} }
#endif
void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t maxrow) void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, vertpos_t maxrow)
{ {
check(event, curr, menuTab, menuTabSize, 0, 0, maxrow); check(event, curr, menuTab, menuTabSize, 0, 0, maxrow);
} }

View file

@ -53,14 +53,14 @@ void showMessageBox(const pm_char * pstr)
lcdRefresh(); lcdRefresh();
} }
const pm_uchar asterisk_lbm[] PROGMEM = { const pm_uchar ASTERISK_BITMAP[] PROGMEM = {
#include "asterisk.lbm" #include "asterisk.lbm"
}; };
void showAlertBox(const pm_char * title, const pm_char * text, const char * action ALERT_SOUND_ARG) void drawAlertBox(const pm_char * title, const pm_char * text, const char * action)
{ {
lcdClear(); lcdClear();
lcd_img(2, 0, asterisk_lbm, 0, 0); lcd_img(2, 0, ASTERISK_BITMAP, 0, 0);
#define MESSAGE_LCD_OFFSET 6*FW #define MESSAGE_LCD_OFFSET 6*FW
@ -79,9 +79,15 @@ void showAlertBox(const pm_char * title, const pm_char * text, const char * acti
if (action) { if (action) {
lcdDrawTextAlignedLeft(7*FH, action); lcdDrawTextAlignedLeft(7*FH, action);
} }
AUDIO_ERROR_MESSAGE(sound);
#undef MESSAGE_LCD_OFFSET #undef MESSAGE_LCD_OFFSET
}
void showAlertBox(const pm_char * title, const pm_char * text, const char * action ALERT_SOUND_ARG)
{
drawAlertBox(title, text, action);
AUDIO_ERROR_MESSAGE(sound);
lcdRefresh(); lcdRefresh();
lcdSetContrast(); lcdSetContrast();
@ -134,7 +140,12 @@ uint8_t s_menu_item = 0;
uint16_t popupMenuNoItems = 0; uint16_t popupMenuNoItems = 0;
uint8_t popupMenuFlags = 0; uint8_t popupMenuFlags = 0;
uint16_t popupMenuOffset = 0; uint16_t popupMenuOffset = 0;
void (*popupMenuHandler)(const char *result); void (*popupMenuHandler)(const char * result);
#if defined(CPUARM)
uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL;
#endif
const char * runPopupMenu(uint8_t event) const char * runPopupMenu(uint8_t event)
{ {
const char * result = NULL; const char * result = NULL;

View file

@ -0,0 +1,107 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _POPUPS_H_
#define _POPUPS_H_
#define MENU_X 10
#define MENU_Y 16
#define MENU_W LCD_W-(2*MENU_X)
#define WARNING_LINE_LEN 20
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
void drawMessageBox();
void showMessageBox(const pm_char * title);
void runPopupWarning(uint8_t event);
#if defined(CPUARM)
extern void (*popupFunc)(uint8_t event);
extern int16_t warningInputValue;
extern int16_t warningInputValueMin;
extern int16_t warningInputValueMax;
extern uint8_t warningInfoFlags;
#endif
#if !defined(GUI)
#define DISPLAY_WARNING(...)
#define POPUP_WARNING(...)
#define POPUP_CONFIRMATION(...)
#define POPUP_INPUT(...)
#define WARNING_INFO_FLAGS 0
#define SET_WARNING_INFO(...)
#elif defined(CPUARM)
#define DISPLAY_WARNING (*popupFunc)
#define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max)
#define WARNING_INFO_FLAGS warningInfoFlags
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
#else
#define DISPLAY_WARNING runPopupWarning
#define POPUP_WARNING(s) warningText = s
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM)
#define WARNING_INFO_FLAGS ZCHAR
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len)
#endif
#if defined(SDCARD)
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s)
#else
#define POPUP_MENU_ADD_SD_ITEM(s)
#endif
#define MENU_MAX_DISPLAY_LINES 6
#if defined(CPUARM)
#define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) do { if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0)
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0)
#define POPUP_MENU_MAX_LINES 12
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+1)
#define POPUP_MENU_SET_BSS_FLAG()
#define POPUP_MENU_UNSET_BSS_FLAG()
enum {
MENU_OFFSET_INTERNAL,
MENU_OFFSET_EXTERNAL
};
extern uint8_t popupMenuOffsetType;
#elif defined(SDCARD) || (defined(ROTARY_ENCODER_NAVIGATION) && !defined(CPUM64))
#define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) do { if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0)
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0)
#define POPUP_MENU_MAX_LINES MENU_MAX_DISPLAY_LINES
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+1)
#define POPUP_MENU_SET_BSS_FLAG() (popupMenuFlags = BSS)
#define POPUP_MENU_UNSET_BSS_FLAG() (popupMenuFlags = 0)
extern uint8_t popupMenuFlags;
#else
#define popupMenuNoItems 0
#endif
#if defined(NAVIGATION_MENUS)
extern uint16_t popupMenuOffset;
extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems;
const char * runPopupMenu(uint8_t event);
extern void (*popupMenuHandler)(const char * result);
#endif
#endif // _POPUPS_H_

View file

@ -33,7 +33,7 @@ enum CalibrationState {
void menuCommonCalib(uint8_t event) 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 for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high vals for sticks and trims
int16_t vt = anaIn(i); int16_t vt = anaIn(i);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]); reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]); reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
@ -44,7 +44,7 @@ void menuCommonCalib(uint8_t event)
} }
} }
calibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating menuCalibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
switch (event) switch (event)
{ {
@ -70,7 +70,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS); lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
reusableBuffer.calib.loVals[i] = 15000; reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000; reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = anaIn(i); reusableBuffer.calib.midVals[i] = anaIn(i);
@ -83,7 +83,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS); lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) { if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i]; g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i]; int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
@ -113,7 +113,7 @@ void menuRadioCalibration(uint8_t event)
check_simple(event, MENU_RADIO_CALIBRATION, menuTabGeneral, DIM(menuTabGeneral), 0); check_simple(event, MENU_RADIO_CALIBRATION, menuTabGeneral, DIM(menuTabGeneral), 0);
if (menuEvent) { if (menuEvent) {
calibrationState = CALIB_START; menuCalibrationState = CALIB_START;
} }
TITLE(STR_MENUCALIBRATION); TITLE(STR_MENUCALIBRATION);
@ -123,7 +123,7 @@ void menuRadioCalibration(uint8_t event)
void menuFirstCalib(uint8_t event) void menuFirstCalib(uint8_t event)
{ {
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) { if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) {
calibrationState = CALIB_START; menuCalibrationState = CALIB_START;
chainMenu(menuMainView); chainMenu(menuMainView);
} }
else { else {

View file

@ -22,20 +22,21 @@
void menuRadioDiagAnalogs(uint8_t event) void menuRadioDiagAnalogs(uint8_t event)
{ {
// TODO enum
#if defined(TX_CAPACITY_MEASUREMENT) #if defined(TX_CAPACITY_MEASUREMENT)
#define ANAS_ITEMS_COUNT 4
#elif defined(PCBSKY9X)
#define ANAS_ITEMS_COUNT 3 #define ANAS_ITEMS_COUNT 3
#else #elif defined(PCBSKY9X)
#define ANAS_ITEMS_COUNT 2 #define ANAS_ITEMS_COUNT 2
#else
#define ANAS_ITEMS_COUNT 1
#endif #endif
SIMPLE_MENU(STR_MENUANA, menuTabGeneral, MENU_RADIO_DIAG_ANALOGS, ANAS_ITEMS_COUNT); SIMPLE_MENU(STR_MENU_RADIO_ANALOGS, menuTabGeneral, MENU_RADIO_ANALOGS_TEST, HEADER_LINE+ANAS_ITEMS_COUNT);
STICK_SCROLL_DISABLE(); STICK_SCROLL_DISABLE();
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
#if (NUM_STICKS+NUM_POTS) > 9 #if (NUM_STICKS+NUM_POTS+NUM_SLIDERS) > 9
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/3)*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + (i/3)*FH;
const uint8_t x_coord[] = {0, 70, 154}; const uint8_t x_coord[] = {0, 70, 154};
uint8_t x = x_coord[i%3]; uint8_t x = x_coord[i%3];
@ -43,39 +44,48 @@ void menuRadioDiagAnalogs(uint8_t event)
lcdDrawChar(x+2*FW-2, y, ':'); lcdDrawChar(x+2*FW-2, y, ':');
#else #else
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? 64+5 : 0; uint8_t x = (i & 1) ? LCD_W/2+FW : 0;
drawStringWithIndex(x, y, PSTR("A"), i+1); drawStringWithIndex(x, y, PSTR("A"), i+1);
lcdDrawChar(lcdNextPos, y, ':'); lcdDrawChar(lcdNextPos, y, ':');
#endif #endif
lcdDrawHexNumber(x+3*FW-1, y, anaIn(i)); lcdDrawHexNumber(x+3*FW-1, y, anaIn(i));
#if defined(CPUARM)
lcdDrawNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256, RIGHT);
#else
lcdDraw8bitsNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256); lcdDraw8bitsNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#endif
} }
#if !defined(CPUARM) #if !defined(CPUARM)
// Display raw BandGap result (debug) // Display raw BandGap result (debug)
lcdDrawText(64+5, MENU_HEADER_HEIGHT+1+3*FH, STR_BG); lcdDrawText(64+5, MENU_HEADER_HEIGHT+1+3*FH, STR_BG);
lcdDrawNumber(64+5+6*FW-3, 1+4*FH, BandGap, 0); lcdDrawNumber(64+5+6*FW-3, 1+4*FH, BandGap, RIGHT);
#endif #endif
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+4*FH, STR_BATT_CALIB); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+4*FH, STR_BATT_CALIB);
static int32_t adcBatt; static int32_t adcBatt;
// TODO board.cpp
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8; adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8;
uint32_t batCalV = (adcBatt + adcBatt*(g_eeGeneral.txVoltageCalibration)/128) * 4191; uint32_t batCalV = (adcBatt + adcBatt*(g_eeGeneral.txVoltageCalibration)/128) * 4191;
batCalV /= 55296; batCalV /= 55296;
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+4*FH, batCalV, (menuVerticalPosition==1 ? INVERS : 0)); putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+4*FH, batCalV, (menuVerticalPosition==HEADER_LINE ? INVERS : 0));
#elif defined(PCBGRUVIN9X) #elif defined(PCBGRUVIN9X)
lcdDrawTextAlignedLeft(6*FH-2, STR_BATT_CALIB); lcdDrawTextAlignedLeft(6*FH-2, STR_BATT_CALIB);
// Gruvin wants 2 decimal places and instant update of volts calib field when button pressed // Gruvin wants 2 decimal places and instant update of volts calib field when button pressed
// TODO board.cpp
static uint16_t adcBatt; static uint16_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8; // running average, sourced directly (to avoid unending debate :P) 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.txVoltageCalibration)/8) / BandGap; uint32_t batCalV = ((uint32_t)adcBatt*1390 + (10*(int32_t)adcBatt*g_eeGeneral.txVoltageCalibration)/8) / BandGap;
lcdDrawNumber(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, batCalV, PREC2|(menuVerticalPosition==1 ? INVERS : 0)); lcdDrawNumber(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, batCalV, PREC2|(menuVerticalPosition==HEADER_LINE ? INVERS : 0));
#else #else
lcdDrawTextAlignedLeft(6*FH-2, STR_BATT_CALIB); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH, STR_BATT_CALIB);
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, g_vbat100mV, (menuVerticalPosition==1 ? INVERS : 0)); putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH, g_vbat100mV, (menuVerticalPosition==HEADER_LINE ? INVERS : 0));
#endif #endif
if (menuVerticalPosition==1) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
if (menuVerticalPosition == HEADER_LINE) {
CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
}
#if defined(TX_CAPACITY_MEASUREMENT) #if defined(TX_CAPACITY_MEASUREMENT)
lcdDrawTextAlignedLeft(6*FH+1, STR_CURRENT_CALIB); lcdDrawTextAlignedLeft(6*FH+1, STR_CURRENT_CALIB);

View file

@ -20,45 +20,55 @@
#include "opentx.h" #include "opentx.h"
void displayKeyState(uint8_t x, uint8_t y, EnumKeys key) void displayKeyState(uint8_t x, uint8_t y, uint8_t key)
{ {
uint8_t t = switchState(key); uint8_t t = keyState(key);
lcdDrawChar(x, y, t+'0', t ? INVERS : 0); lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
} }
void menuRadioDiagKeys(uint8_t event) void menuRadioDiagKeys(uint8_t event)
{ {
SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, MENU_RADIO_DIAG_KEYS, 1); SIMPLE_MENU(STR_MENU_RADIO_SWITCHES, menuTabGeneral, MENU_RADIO_SWITCHES_TEST, 1);
lcdDrawText(14*FW, MENU_HEADER_HEIGHT+2*FH, STR_VTRIM); lcdDrawText(14*FW, MENU_HEADER_HEIGHT+2*FH, STR_VTRIM);
for(uint8_t i=0; i<9; i++) { for (uint8_t i=0; i<9; i++) {
coord_t y; coord_t y;
if (i<8) { if (i < 8) {
y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2); y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0); if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i)); displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
} }
if (i<6) { if (i < 6) {
y = i*FH+MENU_HEADER_HEIGHT+FH; y = MENU_HEADER_HEIGHT + FH + FH*i;
lcdDrawTextAtIndex(0, y, STR_VKEYS, (5-i), 0); lcdDrawTextAtIndex(0, y, STR_VKEYS, (5-i), 0);
displayKeyState(5*FW+2, y, (EnumKeys)(KEY_MENU+(5-i))); displayKeyState(5*FW+2, y, KEY_MENU+(5-i));
} }
if (i != SW_ID0-SW_BASE) { #if defined(PCBTARANIS)
y = MENU_HEADER_HEIGHT+i*FH-2*FH; if (i < NUM_SWITCHES) {
putsSwitches(8*FW, y, i+1, 0); //ohne off,on if (SWITCH_EXISTS(i)) {
displayKeyState(11*FW+2, y, (EnumKeys)(SW_BASE+i)); getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
drawSwitch(8*FW, y, sw, 0);
} }
} }
#else
if (i != SW_ID0) {
y = MENU_HEADER_HEIGHT +i*FH - 2*FH;
drawSwitch(8*FW, y, i+1, 0);
displayKeyState(11*FW+2, y, i);
}
#endif
}
#if defined(ROTARY_ENCODERS) || defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODERS) || defined(ROTARY_ENCODER_NAVIGATION) // TODO || defined(PCBX7D)
for(uint8_t i=0; i<DIM(g_rotenc); i++) { for (uint8_t i=0; i<DIM(g_rotenc); i++) {
coord_t y = MENU_HEADER_HEIGHT /* ??? + 1 ??? */ + i*FH; coord_t y = MENU_HEADER_HEIGHT /* ??? + 1 ??? */ + i*FH;
lcdDrawTextAtIndex(14*FW, y, STR_VRENCODERS, i, 0); lcdDrawTextAtIndex(14*FW, y, STR_VRENCODERS, i, 0);
lcdDrawNumber(18*FW, y, g_rotenc[i], LEFT|(switchState((EnumKeys)(BTN_REa+i)) ? INVERS : 0)); lcdDrawNumber(18*FW, y, g_rotenc[i], LEFT|(keyState(BTN_REa+i) ? INVERS : 0));
} }
#endif #endif

View file

@ -20,22 +20,24 @@
#include "opentx.h" #include "opentx.h"
enum menuRadioHwItems { enum MenuRadioHardwareItems {
ITEM_SETUP_HW_OPTREX_DISPLAY, ITEM_RADIO_HARDWARE_OPTREX_DISPLAY,
ITEM_SETUP_HW_STICKS_GAINS_LABELS, ITEM_RADIO_HARDWARE_STICKS_GAINS_LABELS,
ITEM_SETUP_HW_STICK_LV_GAIN, ITEM_RADIO_HARDWARE_STICK_LV_GAIN,
ITEM_SETUP_HW_STICK_LH_GAIN, ITEM_RADIO_HARDWARE_STICK_LH_GAIN,
ITEM_SETUP_HW_STICK_RV_GAIN, ITEM_RADIO_HARDWARE_STICK_RV_GAIN,
ITEM_SETUP_HW_STICK_RH_GAIN, ITEM_RADIO_HARDWARE_STICK_RH_GAIN,
IF_ROTARY_ENCODERS(ITEM_SETUP_HW_ROTARY_ENCODER) IF_ROTARY_ENCODERS(ITEM_RADIO_HARDWARE_ROTARY_ENCODER)
CASE_BLUETOOTH(ITEM_SETUP_HW_BT_BAUDRATE) CASE_BLUETOOTH(ITEM_RADIO_HARDWARE_BT_BAUDRATE)
ITEM_SETUP_HW_MAX ITEM_RADIO_HARDWARE_MAX
}; };
#define GENERAL_HW_PARAM_OFS (2+(15*FW)) #define GENERAL_HW_PARAM_OFS (2+(15*FW))
void menuRadioHardware(uint8_t event) void menuRadioHardware(uint8_t event)
{ {
MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)}); #if defined(PCBX7D)
#else
MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
uint8_t sub = menuVerticalPosition - 1; uint8_t sub = menuVerticalPosition - 1;
@ -46,22 +48,22 @@ void menuRadioHardware(uint8_t event)
uint8_t attr = (sub == k ? blink : 0); uint8_t attr = (sub == k ? blink : 0);
switch(k) { switch(k) {
case ITEM_SETUP_HW_OPTREX_DISPLAY: case ITEM_RADIO_HARDWARE_OPTREX_DISPLAY:
g_eeGeneral.optrexDisplay = selectMenuItem(GENERAL_HW_PARAM_OFS, y, STR_LCD, STR_VLCD, g_eeGeneral.optrexDisplay, 0, 1, attr, event); g_eeGeneral.optrexDisplay = selectMenuItem(GENERAL_HW_PARAM_OFS, y, STR_LCD, STR_VLCD, g_eeGeneral.optrexDisplay, 0, 1, attr, event);
break; break;
case ITEM_SETUP_HW_STICKS_GAINS_LABELS: case ITEM_RADIO_HARDWARE_STICKS_GAINS_LABELS:
lcdDrawTextAlignedLeft(y, PSTR("Sticks")); lcdDrawTextAlignedLeft(y, PSTR("Sticks"));
break; break;
case ITEM_SETUP_HW_STICK_LV_GAIN: case ITEM_RADIO_HARDWARE_STICK_LV_GAIN:
case ITEM_SETUP_HW_STICK_LH_GAIN: case ITEM_RADIO_HARDWARE_STICK_LH_GAIN:
case ITEM_SETUP_HW_STICK_RV_GAIN: case ITEM_RADIO_HARDWARE_STICK_RV_GAIN:
case ITEM_SETUP_HW_STICK_RH_GAIN: case ITEM_RADIO_HARDWARE_STICK_RH_GAIN:
{ {
lcdDrawTextAtIndex(INDENT_WIDTH, y, PSTR("\002LVLHRVRH"), k-ITEM_SETUP_HW_STICK_LV_GAIN, 0); lcdDrawTextAtIndex(INDENT_WIDTH, y, PSTR("\002LVLHRVRH"), k-ITEM_RADIO_HARDWARE_STICK_LV_GAIN, 0);
lcdDrawText(INDENT_WIDTH+3*FW, y, PSTR("Gain")); lcdDrawText(INDENT_WIDTH+3*FW, y, PSTR("Gain"));
uint8_t mask = (1<<(k-ITEM_SETUP_HW_STICK_LV_GAIN)); uint8_t mask = (1<<(k-ITEM_RADIO_HARDWARE_STICK_LV_GAIN));
uint8_t val = (g_eeGeneral.sticksGain & mask ? 1 : 0); uint8_t val = (g_eeGeneral.sticksGain & mask ? 1 : 0);
lcdDrawChar(GENERAL_HW_PARAM_OFS, y, val ? '2' : '1', attr); lcdDrawChar(GENERAL_HW_PARAM_OFS, y, val ? '2' : '1', attr);
if (attr) { if (attr) {
@ -75,20 +77,20 @@ void menuRadioHardware(uint8_t event)
} }
#if defined(ROTARY_ENCODERS) #if defined(ROTARY_ENCODERS)
case ITEM_SETUP_HW_ROTARY_ENCODER: case ITEM_RADIO_HARDWARE_ROTARY_ENCODER:
g_eeGeneral.rotarySteps = selectMenuItem(GENERAL_HW_PARAM_OFS, y, PSTR("Rotary Encoder"), PSTR("\0062steps4steps"), g_eeGeneral.rotarySteps, 0, 1, attr, event); g_eeGeneral.rotarySteps = selectMenuItem(GENERAL_HW_PARAM_OFS, y, PSTR("Rotary Encoder"), PSTR("\0062steps4steps"), g_eeGeneral.rotarySteps, 0, 1, attr, event);
break; break;
#endif #endif
#if defined(BLUETOOTH) #if defined(BLUETOOTH)
case ITEM_SETUP_HW_BT_BAUDRATE: case ITEM_RADIO_HARDWARE_BT_BAUDRATE:
g_eeGeneral.btBaudrate = selectMenuItem(GENERAL_HW_PARAM_OFS, y, STR_BAUDRATE, PSTR("\005115k 9600 19200"), g_eeGeneral.btBaudrate, 0, 2, attr, event); 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) { if (attr && checkIncDec_Ret) {
btInit(); btInit();
} }
break; break;
#endif #endif
} }
} }
#endif
} }

View file

@ -97,13 +97,6 @@ void onSdManagerMenu(const char *result)
void menuRadioSdManager(uint8_t _event) void menuRadioSdManager(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 defined(SDCARD)
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
@ -126,27 +119,30 @@ void menuRadioSdManager(uint8_t _event)
#endif #endif
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event); 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, MENU_RADIO_SD_MANAGER, 1+reusableBuffer.sdmanager.count);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, MENU_RADIO_SD_MANAGER, HEADER_LINE+reusableBuffer.sdmanager.count);
if (s_editMode > 0) if (s_editMode > 0)
s_editMode = 0; s_editMode = 0;
switch(_event) { switch (_event) {
case EVT_ENTRY: case EVT_ENTRY:
f_chdir(ROOT_PATH); f_chdir(ROOT_PATH);
reusableBuffer.sdmanager.offset = 65535; reusableBuffer.sdmanager.offset = 65535;
break; break;
#if !defined(PCBX7D)
CASE_EVT_ROTARY_BREAK CASE_EVT_ROTARY_BREAK
case EVT_KEY_FIRST(KEY_RIGHT): case EVT_KEY_FIRST(KEY_RIGHT):
#endif
case EVT_KEY_FIRST(KEY_ENTER): case EVT_KEY_FIRST(KEY_ENTER):
{ {
if (menuVerticalPosition > 0) { if (menuVerticalPosition >= HEADER_LINE) {
vertpos_t index = menuVerticalPosition-1-menuVerticalOffset; vertpos_t index = menuVerticalPosition-HEADER_LINE-menuVerticalOffset;
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) { if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
f_chdir(reusableBuffer.sdmanager.lines[index]); f_chdir(reusableBuffer.sdmanager.lines[index]);
menuVerticalOffset = 0; menuVerticalOffset = 0;
menuVerticalPosition = 1; menuVerticalPosition = HEADER_LINE;
reusableBuffer.sdmanager.offset = 65535; reusableBuffer.sdmanager.offset = 65535;
killEvents(_event); killEvents(_event);
break; break;
@ -157,6 +153,7 @@ void menuRadioSdManager(uint8_t _event)
// no break; // no break;
} }
#if !defined(PCBX7D)
case EVT_KEY_LONG(KEY_ENTER): case EVT_KEY_LONG(KEY_ENTER):
killEvents(_event); killEvents(_event);
if (menuVerticalPosition == 0) { if (menuVerticalPosition == 0) {
@ -186,9 +183,17 @@ void menuRadioSdManager(uint8_t _event)
} }
POPUP_MENU_START(onSdManagerMenu); POPUP_MENU_START(onSdManagerMenu);
break; break;
#endif
} }
if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { if (reusableBuffer.sdmanager.offset != menuVerticalOffset) {
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 (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
reusableBuffer.sdmanager.offset = 0; reusableBuffer.sdmanager.offset = 0;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
@ -209,7 +214,7 @@ void menuRadioSdManager(uint8_t _event)
reusableBuffer.sdmanager.count = 0; reusableBuffer.sdmanager.count = 0;
FRESULT res = f_opendir(&dir, "."); /* Open the directory */ FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) { if (res == FR_OK) {
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
@ -228,7 +233,7 @@ void menuRadioSdManager(uint8_t _event)
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
char *line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { 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)); 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])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
@ -240,7 +245,7 @@ void menuRadioSdManager(uint8_t _event)
} }
else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) {
for (int8_t i=6; i>=0; i--) { for (int8_t i=6; i>=0; i--) {
char *line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { 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); 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])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
@ -273,7 +278,7 @@ void menuRadioSdManager(uint8_t _event)
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
lcdNextPos = 0; lcdNextPos = 0;
uint8_t attr = (menuVerticalPosition-1-menuVerticalOffset == i ? BSS|INVERS : BSS); uint8_t attr = (menuVerticalPosition-HEADER_LINE-menuVerticalOffset == i ? BSS|INVERS : BSS);
if (reusableBuffer.sdmanager.lines[i][0]) { if (reusableBuffer.sdmanager.lines[i][0]) {
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcdDrawChar(0, y, '[', attr); } if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcdDrawChar(0, y, '[', attr); }
lcdDrawText(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr); lcdDrawText(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);

View file

@ -26,9 +26,9 @@ const pm_uchar sticks[] PROGMEM = {
#include "sticks.lbm" #include "sticks.lbm"
}; };
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH) #define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#define RADIO_SETUP_DATE_COLUMN (FW*15+7) #define RADIO_SETUP_DATE_COLUMN (FW*15+7)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#if !defined(CPUM64) #if !defined(CPUM64)
#define SLIDER_5POS(y, value, label, event, attr) { \ #define SLIDER_5POS(y, value, label, event, attr) { \
@ -58,7 +58,7 @@ const pm_uchar sticks[] PROGMEM = {
#define CASE_BATTGRAPH(x) #define CASE_BATTGRAPH(x)
#endif #endif
enum menuRadioSetupItems { enum MenuRadioSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE) CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME) CASE_RTCLOCK(ITEM_SETUP_TIME)
CASE_BATTGRAPH(ITEM_SETUP_BATT_RANGE) CASE_BATTGRAPH(ITEM_SETUP_BATT_RANGE)
@ -139,34 +139,35 @@ void menuRadioSetup(uint8_t event)
} }
#endif #endif
MENU(STR_MENURADIOSETUP, menuTabGeneral, MENU_RADIO_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_CAPACITY(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*/}); MENU(STR_MENURADIOSETUP, menuTabGeneral, MENU_RADIO_SETUP, HEADER_LINE+ITEM_SETUP_MAX, { HEADER_LINE_COLUMNS 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_CAPACITY(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, 0, 1/*to force edit mode*/});
if (event == EVT_ENTRY) { if (event == EVT_ENTRY) {
reusableBuffer.generalSettings.stickMode = g_eeGeneral.stickMode; reusableBuffer.generalSettings.stickMode = g_eeGeneral.stickMode;
} }
uint8_t sub = menuVerticalPosition - 1; uint8_t sub = menuVerticalPosition - HEADER_LINE;
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i + menuVerticalOffset;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
uint8_t attr = (sub == k ? blink : 0); uint8_t attr = (sub == k ? blink : 0);
switch(k) { switch (k) {
#if defined(RTCLOCK) #if defined(RTCLOCK)
case ITEM_SETUP_DATE: case ITEM_SETUP_DATE:
lcdDrawTextAlignedLeft(y, STR_DATE); lcdDrawTextAlignedLeft(y, STR_DATE);
lcdDrawChar(RADIO_SETUP_DATE_COLUMN, y, '-'); lcdDrawChar(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-'); lcdDrawChar(RADIO_SETUP_DATE_COLUMN, y, '-');
lcdDrawChar(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-');
for (uint8_t j=0; j<3; j++) { for (uint8_t j=0; j<3; j++) {
uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0); uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0);
switch (j) { switch (j) {
case 0: case 0:
lcdDrawNumber(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr); lcdDrawNumber(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr|RIGHT);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0);
break; break;
case 1: case 1:
lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0, 2); lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0|RIGHT, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0);
break; break;
case 2: case 2:
@ -175,7 +176,7 @@ void menuRadioSetup(uint8_t event)
int8_t dlim = (((((year%4==0) && (year%100!=0)) || (year%400==0)) && (t.tm_mon==1)) ? 1 : 0); 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 }; 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]); dlim += pgm_read_byte(&dmon[t.tm_mon]);
lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0, 2); lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0|RIGHT, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0);
break; break;
} }
@ -193,21 +194,22 @@ void menuRadioSetup(uint8_t event)
uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0); uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0);
switch (j) { switch (j) {
case 0: case 0:
lcdDrawNumber(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0, 2); lcdDrawNumber(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0|RIGHT, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0);
break; break;
case 1: case 1:
lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0, 2); lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0|RIGHT, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0);
break; break;
case 2: case 2:
lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0, 2); lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0|RIGHT, 2);
if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0); if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0);
break; break;
} }
} }
if (attr && checkIncDec_Ret) if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break; break;
#endif #endif
@ -238,7 +240,7 @@ void menuRadioSetup(uint8_t event)
#endif #endif
break; break;
#if defined(BUZZER) #if defined(BUZZER) // AUDIO + BUZZER
case ITEM_SETUP_BUZZER_MODE: 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); g_eeGeneral.buzzerMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_BUZZER, STR_VBEEPMODE, g_eeGeneral.buzzerMode, -2, 1, attr, event);
#if defined(TELEMETRY_FRSKY) #if defined(TELEMETRY_FRSKY)
@ -246,7 +248,7 @@ void menuRadioSetup(uint8_t event)
#endif #endif
break; break;
#endif #endif
#elif defined(BUZZER) #elif defined(BUZZER) // BUZZER only
case ITEM_SETUP_BUZZER_MODE: 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); g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event);
#if defined(TELEMETRY_FRSKY) #if defined(TELEMETRY_FRSKY)
@ -563,7 +565,7 @@ void menuRadioSetup(uint8_t event)
case ITEM_SETUP_STICK_MODE: case ITEM_SETUP_STICK_MODE:
lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr); lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr);
for (uint8_t i=0; i<4; i++) { for (uint8_t i=0; i<4; i++) {
putsMixerSource((6+4*i)*FW, y, MIXSRC_Rud + pgm_read_byte(modn12x3 + 4*reusableBuffer.generalSettings.stickMode + i), 0); drawSource((6+4*i)*FW, y, MIXSRC_Rud + pgm_read_byte(modn12x3 + 4*reusableBuffer.generalSettings.stickMode + i), 0);
} }
if (attr && s_editMode>0) { if (attr && s_editMode>0) {
CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3); CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3);

View file

@ -20,14 +20,12 @@
#include "opentx.h" #include "opentx.h"
#define TRAINER_CALIB_POS 8
void menuRadioTrainer(uint8_t event) void menuRadioTrainer(uint8_t event)
{ {
uint8_t y; uint8_t y;
bool slave = SLAVE_MODE(); bool slave = SLAVE_MODE();
MENU(STR_MENUTRAINER, menuTabGeneral, MENU_RADIO_TRAINER, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/}); MENU(STR_MENUTRAINER, menuTabGeneral, MENU_RADIO_TRAINER, (slave ? HEADER_LINE : HEADER_LINE+6), {HEADER_LINE_COLUMNS 2, 2, 2, 2, 0/*, 0*/});
if (slave) { if (slave) {
lcdDrawText(7*FW, 4*FH, STR_SLAVE); lcdDrawText(7*FW, 4*FH, STR_SLAVE);
@ -40,24 +38,24 @@ void menuRadioTrainer(uint8_t event)
y = MENU_HEADER_HEIGHT + 1 + FH; y = MENU_HEADER_HEIGHT + 1 + FH;
for (uint8_t i=1; i<=NUM_STICKS; i++) { for (uint8_t i=HEADER_LINE; i<HEADER_LINE+NUM_STICKS; i++) {
uint8_t chan = channel_order(i); uint8_t chan = channel_order(i);
volatile TrainerMix *td = &g_eeGeneral.trainer.mix[chan-1]; volatile TrainerMix *td = &g_eeGeneral.trainer.mix[chan-1];
putsMixerSource(0, y, MIXSRC_Rud-1+chan, (menuVerticalPosition==i && CURSOR_ON_LINE()) ? INVERS : 0); drawSource(0, y, MIXSRC_Rud-1+chan, (menuVerticalPosition==i && CURSOR_ON_LINE()) ? INVERS : 0);
for (uint8_t j=0; j<3; j++) { for (uint8_t j=0; j<3; j++) {
attr = ((menuVerticalPosition==i && menuHorizontalPosition==j) ? blink : 0); attr = ((menuVerticalPosition==i && menuHorizontalPosition==j) ? blink : 0);
switch(j) { switch (j) {
case 0: case 0:
lcdDrawTextAtIndex(4*FW, y, STR_TRNMODE, td->mode, attr); lcdDrawTextAtIndex(4*FW, y, STR_TRNMODE, td->mode, attr);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->mode, 0, 2); if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->mode, 0, 2);
break; break;
case 1: case 1:
lcdDrawNumber(11*FW, y, td->studWeight, attr); lcdDrawNumber(11*FW, y, td->studWeight, attr|RIGHT);
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->studWeight, -125, 125); if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->studWeight, -125, 125);
break; break;
@ -70,20 +68,20 @@ void menuRadioTrainer(uint8_t event)
y += FH; y += FH;
} }
attr = (menuVerticalPosition==5) ? blink : 0; attr = (menuVerticalPosition==HEADER_LINE+4) ? blink : 0;
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+5*FH, STR_MULTIPLIER); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+5*FH, STR_MULTIPLIER);
lcdDrawNumber(LEN_MULTIPLIER*FW+3*FW, MENU_HEADER_HEIGHT+1+5*FH, g_eeGeneral.PPM_Multiplier+10, attr|PREC1); lcdDrawNumber(LEN_MULTIPLIER*FW+3*FW, MENU_HEADER_HEIGHT+1+5*FH, g_eeGeneral.PPM_Multiplier+10, attr|PREC1|RIGHT);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.PPM_Multiplier, -10, 40); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.PPM_Multiplier, -10, 40);
attr = (menuVerticalPosition==6) ? INVERS : 0; attr = (menuVerticalPosition==HEADER_LINE+5) ? INVERS : 0;
if (attr) s_editMode = 0;
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr); lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr);
for (uint8_t i=0; i<4; i++) { for (uint8_t i=0; i<4; i++) {
uint8_t x = (i*TRAINER_CALIB_POS+16)*FW/2; uint8_t x = (i*8+16)*FW/2;
lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, 0); lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, RIGHT);
} }
if (attr) { if (attr) {
s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)){ if (event==EVT_KEY_LONG(KEY_ENTER)){
memcpy(g_eeGeneral.trainer.calib, ppmInput, sizeof(g_eeGeneral.trainer.calib)); memcpy(g_eeGeneral.trainer.calib, ppmInput, sizeof(g_eeGeneral.trainer.calib));
storageDirty(EE_GENERAL); storageDirty(EE_GENERAL);

View file

@ -22,6 +22,21 @@
void menuRadioVersion(uint8_t event) void menuRadioVersion(uint8_t event)
{ {
#if defined(CPUARM) && defined(EEPROM_RLC)
if (warningResult) {
warningResult = 0;
showMessageBox(STR_STORAGE_FORMAT);
storageEraseAll(false);
NVIC_SystemReset();
}
#endif
#if defined(STM32)
if (event == EVT_ENTRY) {
getCPUUniqueID(reusableBuffer.version.id);
}
#endif
SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, MENU_RADIO_VERSION, 1); SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, MENU_RADIO_VERSION, 1);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+FH, vers_stamp); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+FH, vers_stamp);
@ -34,5 +49,16 @@ void menuRadioVersion(uint8_t event)
else { else {
lcdDrawTextAlignedLeft(6*FH, PSTR("CoPr: ---")); lcdDrawTextAlignedLeft(6*FH, PSTR("CoPr: ---"));
} }
#elif defined(CPUARM) && defined(EEPROM_RLC)
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+5*FH+1, STR_EEBACKUP);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+6*FH+1, STR_FACTORYRESET);
lcdDrawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID);
if (event == EVT_KEY_LONG(KEY_ENTER)) {
eepromBackup();
}
else if (event == EVT_KEY_LONG(KEY_MENU)) {
POPUP_CONFIRMATION(STR_CONFIRMRESET);
}
#endif #endif
} }

View file

@ -0,0 +1,116 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
void menuChannelsView(uint8_t event)
{
static bool longNames = false;
bool newLongNames = false;
static bool secondPage = false;
#ifdef MIXERS_MONITOR
static bool mixersView = false;
#endif
uint8_t ch;
switch(event)
{
case EVT_KEY_BREAK(KEY_EXIT):
popMenu();
break;
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_LEFT):
secondPage = !secondPage;
break;
#ifdef MIXERS_MONITOR
case EVT_KEY_FIRST(KEY_ENTER):
mixersView = !mixersView;
break;
#endif
}
if (secondPage)
ch = 16;
else
ch = 0;
#ifdef MIXERS_MONITOR
if (mixersView)
lcd_putsCenter(0*FH, MIXERS_MONITOR);
else
#endif
lcd_putsCenter(0*FH, CHANNELS_MONITOR);
lcdInvertLine(0);
// Column separator
lcdDrawSolidVerticalLine(LCD_W/2, FH, LCD_H-FH);
for (uint8_t col=0; col<2; col++) {
uint8_t x = col*LCD_W/2+1;
// Channels
for (uint8_t line=0; line<8; line++) {
uint8_t y = 9+line*7;
#ifdef MIXERS_MONITOR
int32_t val = (mixersView) ? ex_chans[ch] : channelOutputs[ch];
#else
int32_t val = channelOutputs[ch];
#endif
uint8_t ofs = (col ? 0 : 1);
// Channel name if present, number if not
uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
if (lenLabel > 4) {
newLongNames = longNames = true;
}
if (lenLabel > 0)
lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE);
else
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
// Value
#if defined(PPM_UNIT_US)
uint8_t wbar = (longNames ? 54 : 64);
lcdDrawNumber(x+LCD_W/2-3-wbar-ofs, y+1, PPM_CH_CENTER(ch)+val/2, TINSIZE|RIGHT);
#elif defined(PPM_UNIT_PERCENT_PREC1)
uint8_t wbar = (longNames ? 48 : 58);
lcdDrawNumber(x+LCD_W/2-3-wbar-ofs, y+1, calcRESXto1000(val), PREC1|TINSIZE|RIGHT);
#else
uint8_t wbar = (longNames ? 54 : 64);
lcdDrawNumber(x+LCD_W/2-3-wbar-ofs, y+1, calcRESXto1000(val)/10, TINSIZE|RIGHT);
#endif
// Gauge
#ifdef MIXERS_MONITOR
uint16_t lim = mixersView ? 512*2*2 : (g_model.extendedLimits ? 640*2 : 512*2);
#else
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
#endif
// TODO ? drawGauge(x+LCD_W/2-3-wbar-ofs, y, wbar, 6, val, lim);
ch++;
}
}
longNames = newLongNames;
}

View file

@ -46,10 +46,9 @@
void drawPotsBars() void drawPotsBars()
{ {
// Optimization by Mike Blandford // Optimization by Mike Blandford
uint8_t x, i, len ; // declare temporary variables for (uint8_t x=LCD_W/2 - (NUM_POTS+NUM_SLIDERS-1) * 5 / 2, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; x+=5, i++) {
for (x=LCD_W/2-5, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS; x+=5, i++) { if (IS_POT_OR_SLIDER_AVAILABLE(i)) {
if (IS_POT_AVAILABLE(i)) { uint8_t len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
V_BAR(x, LCD_H-8, len); V_BAR(x, LCD_H-8, len);
} }
} }
@ -168,7 +167,7 @@ void displayTimers()
if (g_model.timers[0].mode) { if (g_model.timers[0].mode) {
TimerState & timerState = timersStates[0]; TimerState & timerState = timersStates[0];
LcdFlags att = DBLSIZE | (timerState.val<0 ? BLINK|INVERS : 0); LcdFlags att = DBLSIZE | (timerState.val<0 ? BLINK|INVERS : 0);
putsTimer(12*FW+2+10*FWNUM-4, FH*2, timerState.val, att, att); drawTimer(12*FW+2+10*FWNUM-4, FH*2, timerState.val, att, att);
uint8_t xLabel = (timerState.val >= 0 ? MAINTMR_LBL_COL : MAINTMR_LBL_COL-7); uint8_t xLabel = (timerState.val >= 0 ? MAINTMR_LBL_COL : MAINTMR_LBL_COL-7);
#if defined(CPUARM) #if defined(CPUARM)
uint8_t len = zlen(g_model.timers[0].name, LEN_TIMER_NAME); uint8_t len = zlen(g_model.timers[0].name, LEN_TIMER_NAME);
@ -177,10 +176,10 @@ void displayTimers()
lcdDrawSizedText(xLabel, FH*3, g_model.timers[0].name, len, ZCHAR); lcdDrawSizedText(xLabel, FH*3, g_model.timers[0].name, len, ZCHAR);
} }
else { else {
putsTimerMode(xLabel, FH*3, g_model.timers[0].mode); drawTimerMode(xLabel, FH*3, g_model.timers[0].mode);
} }
#else #else
putsTimerMode(xLabel, FH*3, g_model.timers[0].mode); drawTimerMode(xLabel, FH*3, g_model.timers[0].mode);
#endif #endif
} }
} }
@ -188,7 +187,7 @@ void displayTimers()
void displayBattVoltage() void displayBattVoltage()
{ {
#if defined(BATTGRAPH) #if defined(BATTGRAPH)
putsVBat(VBATT_X-8, VBATT_Y+1, 0); putsVBat(VBATT_X-8, VBATT_Y+1, RIGHT);
lcdDrawFilledRect(VBATT_X-25, VBATT_Y+9, 21, 5); lcdDrawFilledRect(VBATT_X-25, VBATT_Y+9, 21, 5);
lcdDrawSolidVerticalLine(VBATT_X-4, VBATT_Y+10, 3); lcdDrawSolidVerticalLine(VBATT_X-4, VBATT_Y+10, 3);
uint8_t count = GET_TXBATT_BARS(); uint8_t count = GET_TXBATT_BARS();
@ -207,10 +206,10 @@ void displayBattVoltage()
void displayVoltageOrAlarm() void displayVoltageOrAlarm()
{ {
if (g_eeGeneral.temperatureWarn && getTemperature() >= g_eeGeneral.temperatureWarn) { if (g_eeGeneral.temperatureWarn && getTemperature() >= g_eeGeneral.temperatureWarn) {
putsValueWithUnit(6*FW-1, 2*FH, getTemperature(), UNIT_TEMPERATURE, BLINK|INVERS|DBLSIZE); putsValueWithUnit(6*FW-1, 2*FH, getTemperature(), UNIT_TEMPERATURE, BLINK|INVERS|DBLSIZE|RIGHT);
} }
else if (g_eeGeneral.mAhWarn && (g_eeGeneral.mAhUsed + Current_used * (488 + g_eeGeneral.txCurrentCalibration)/8192/36) / 500 >= g_eeGeneral.mAhWarn) { else if (g_eeGeneral.mAhWarn && (g_eeGeneral.mAhUsed + Current_used * (488 + g_eeGeneral.txCurrentCalibration)/8192/36) / 500 >= g_eeGeneral.mAhWarn) {
putsValueWithUnit(7*FW-1, 2*FH, (g_eeGeneral.mAhUsed + Current_used*(488 + g_eeGeneral.txCurrentCalibration)/8192/36)/10, UNIT_MAH, BLINK|INVERS|DBLSIZE); putsValueWithUnit(7*FW-1, 2*FH, (g_eeGeneral.mAhUsed + Current_used*(488 + g_eeGeneral.txCurrentCalibration)/8192/36)/10, UNIT_MAH, BLINK|INVERS|DBLSIZE|RIGHT);
} }
else { else {
displayBattVoltage(); displayBattVoltage();
@ -220,11 +219,22 @@ void displayVoltageOrAlarm()
#define displayVoltageOrAlarm() displayBattVoltage() #define displayVoltageOrAlarm() displayBattVoltage()
#endif #endif
#if defined(PCBX7D)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGE)
#define EVT_KEY_MODEL_MENU EVT_KEY_BREAK(KEY_MENU)
#define EVT_KEY_GENERAL_MENU EVT_KEY_LONG(KEY_MENU)
#define EVT_KEY_TELEMETRY EVT_KEY_LONG(KEY_PAGE)
#else
#define EVT_KEY_CONTEXT_MENU EVT_KEY_BREAK(KEY_MENU)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_UP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_DOWN)
#define EVT_KEY_MODEL_MENU EVT_KEY_LONG(KEY_RIGHT) #define EVT_KEY_MODEL_MENU EVT_KEY_LONG(KEY_RIGHT)
#define EVT_KEY_GENERAL_MENU EVT_KEY_LONG(KEY_LEFT) #define EVT_KEY_GENERAL_MENU EVT_KEY_LONG(KEY_LEFT)
#define EVT_KEY_LAST_MENU EVT_KEY_LONG(KEY_MENU)
#define EVT_KEY_TELEMETRY EVT_KEY_LONG(KEY_DOWN) #define EVT_KEY_TELEMETRY EVT_KEY_LONG(KEY_DOWN)
#define EVT_KEY_STATISTICS EVT_KEY_LONG(KEY_UP) #define EVT_KEY_STATISTICS EVT_KEY_LONG(KEY_UP)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_BREAK(KEY_MENU) #endif
#if defined(NAVIGATION_MENUS) #if defined(NAVIGATION_MENUS)
void onMainViewMenu(const char *result) void onMainViewMenu(const char *result)
@ -280,8 +290,7 @@ void menuMainView(uint8_t event)
uint8_t view = g_eeGeneral.view; uint8_t view = g_eeGeneral.view;
uint8_t view_base = view & 0x0f; uint8_t view_base = view & 0x0f;
switch(event) { switch (event) {
case EVT_ENTRY: case EVT_ENTRY:
killEvents(KEY_EXIT); killEvents(KEY_EXIT);
killEvents(KEY_UP); killEvents(KEY_UP);
@ -300,7 +309,7 @@ void menuMainView(uint8_t event)
case EVT_KEY_BREAK(KEY_RIGHT): case EVT_KEY_BREAK(KEY_RIGHT):
case EVT_KEY_BREAK(KEY_LEFT): case EVT_KEY_BREAK(KEY_LEFT):
if (view_base <= VIEW_INPUTS) { if (view_base <= VIEW_INPUTS) {
#if defined(PCBSKY9X) #if defined(CPUARM)
if (view_base == VIEW_INPUTS) if (view_base == VIEW_INPUTS)
g_eeGeneral.view ^= ALTERNATE_VIEW; g_eeGeneral.view ^= ALTERNATE_VIEW;
else else
@ -343,10 +352,12 @@ void menuMainView(uint8_t event)
#endif #endif
#if MENUS_LOCK != 2 /*no menus*/ #if MENUS_LOCK != 2 /*no menus*/
case EVT_KEY_LONG(KEY_MENU):// go to last menu #if defined(EVT_KEY_LAST_MENU)
case EVT_KEY_LAST_MENU:
pushMenu(lastPopMenu()); pushMenu(lastPopMenu());
killEvents(event); killEvents(event);
break; break;
#endif
CASE_EVT_ROTARY_BREAK CASE_EVT_ROTARY_BREAK
case EVT_KEY_MODEL_MENU: case EVT_KEY_MODEL_MENU:
@ -361,16 +372,27 @@ void menuMainView(uint8_t event)
break; break;
#endif #endif
case EVT_KEY_BREAK(KEY_UP): #if defined(EVT_KEY_PREVIOUS_VIEW)
case EVT_KEY_BREAK(KEY_DOWN): // TODO try to split those 2 cases on 9X
g_eeGeneral.view = (event == EVT_KEY_BREAK(KEY_UP) ? (view_base == VIEW_COUNT-1 ? 0 : view_base+1) : (view_base == 0 ? VIEW_COUNT-1 : view_base-1)); case EVT_KEY_PREVIOUS_VIEW:
case EVT_KEY_NEXT_VIEW:
// TODO try to split those 2 cases on 9X
g_eeGeneral.view = (event == EVT_KEY_PREVIOUS_VIEW ? (view_base == VIEW_COUNT-1 ? 0 : view_base+1) : (view_base == 0 ? VIEW_COUNT-1 : view_base-1));
storageDirty(EE_GENERAL); storageDirty(EE_GENERAL);
break; break;
#else
case EVT_KEY_NEXT_VIEW:
g_eeGeneral.view = (view_base == 0 ? VIEW_COUNT-1 : view_base-1);
storageDirty(EE_GENERAL);
break;
#endif
#if defined(EVT_KEY_STATISTICS)
case EVT_KEY_STATISTICS: case EVT_KEY_STATISTICS:
chainMenu(menuStatisticsView); chainMenu(menuStatisticsView);
killEvents(event); killEvents(event);
break; break;
#endif
case EVT_KEY_TELEMETRY: case EVT_KEY_TELEMETRY:
#if defined(TELEMETRY_FRSKY) #if defined(TELEMETRY_FRSKY)
@ -432,7 +454,7 @@ void menuMainView(uint8_t event)
if (view_base < VIEW_INPUTS) { if (view_base < VIEW_INPUTS) {
// scroll bar // scroll bar
lcdDrawHorizontalLine(38, 34, 54, DOTTED); lcdDrawHorizontalLine(38, 34, 54, DOTTED);
#if defined(PCBSKY9X) #if defined(CPUARM)
lcdDrawSolidHorizontalLine(38 + (g_eeGeneral.view / ALTERNATE_VIEW) * 13, 34, 13, SOLID); lcdDrawSolidHorizontalLine(38 + (g_eeGeneral.view / ALTERNATE_VIEW) * 13, 34, 13, SOLID);
#else #else
lcdDrawSolidHorizontalLine((g_eeGeneral.view & ALTERNATE_VIEW) ? 64 : 38, 34, 26, SOLID); lcdDrawSolidHorizontalLine((g_eeGeneral.view & ALTERNATE_VIEW) ? 64 : 38, 34, 26, SOLID);
@ -440,7 +462,7 @@ void menuMainView(uint8_t event)
for (uint8_t i=0; i<8; i++) { for (uint8_t i=0; i<8; i++) {
uint8_t x0,y0; uint8_t x0,y0;
#if defined(PCBSKY9X) #if defined(CPUARM)
uint8_t chan = 8*(g_eeGeneral.view / ALTERNATE_VIEW) + i; uint8_t chan = 8*(g_eeGeneral.view / ALTERNATE_VIEW) + i;
#else #else
uint8_t chan = (g_eeGeneral.view & ALTERNATE_VIEW) ? 8+i : i; uint8_t chan = (g_eeGeneral.view & ALTERNATE_VIEW) ? 8+i : i;
@ -448,17 +470,16 @@ void menuMainView(uint8_t event)
int16_t val = channelOutputs[chan]; int16_t val = channelOutputs[chan];
switch(view_base) switch (view_base) {
{
case VIEW_OUTPUTS_VALUES: case VIEW_OUTPUTS_VALUES:
x0 = (i%4*9+3)*FW/2; x0 = (i%4*9+3)*FW/2;
y0 = i/4*FH+40; y0 = i/4*FH+40;
#if defined(PPM_UNIT_US) #if defined(PPM_UNIT_US)
lcdDrawNumber(x0+4*FW , y0, PPM_CH_CENTER(chan)+val/2, 0); lcdDrawNumber(x0+4*FW , y0, PPM_CH_CENTER(chan)+val/2, RIGHT);
#elif defined(PPM_UNIT_PERCENT_PREC1) #elif defined(PPM_UNIT_PERCENT_PREC1)
lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val), PREC1); lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val), RIGHT|PREC1);
#else #else
lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val)/10, 0); // G: Don't like the decimal part* lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val)/10, RIGHT); // G: Don't like the decimal part*
#endif #endif
break; break;
@ -470,15 +491,15 @@ void menuMainView(uint8_t event)
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2; uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
int8_t len = (abs(val) * WBAR2 + lim/2) / lim; int8_t len = (abs(val) * WBAR2 + lim/2) / lim;
if(len>WBAR2) len = WBAR2; // prevent bars from going over the end - comment for debugging if (len>WBAR2) len = WBAR2; // prevent bars from going over the end - comment for debugging
lcdDrawHorizontalLine(x0-WBAR2, y0, WBAR2*2+1, DOTTED); lcdDrawHorizontalLine(x0-WBAR2, y0, WBAR2*2+1, DOTTED);
lcdDrawSolidVerticalLine(x0,y0-2,5); lcdDrawSolidVerticalLine(x0, y0-2,5 );
if (val>0) if (val > 0)
x0+=1; x0 += 1;
else else
x0-=len; x0 -= len;
lcdDrawSolidHorizontalLine(x0,y0+1,len); lcdDrawSolidHorizontalLine(x0, y0+1, len);
lcdDrawSolidHorizontalLine(x0,y0-1,len); lcdDrawSolidHorizontalLine(x0, y0-1, len);
break; break;
} }
} }
@ -489,15 +510,17 @@ void menuMainView(uint8_t event)
doMainScreenGraphics(); doMainScreenGraphics();
// Switches // Switches
#if !defined(PCBX7D)
for (uint8_t i=SWSRC_THR; i<=SWSRC_TRN; i++) { for (uint8_t i=SWSRC_THR; i<=SWSRC_TRN; i++) {
int8_t sw = (i == SWSRC_TRN ? (switchState(SW_ID0) ? SWSRC_ID0 : (switchState(SW_ID1) ? SWSRC_ID1 : SWSRC_ID2)) : i); int8_t sw = (i == SWSRC_TRN ? (switchState(SW_ID0) ? SWSRC_ID0 : (switchState(SW_ID1) ? SWSRC_ID1 : SWSRC_ID2)) : i);
uint8_t x = 2*FW-2, y = i*FH+1; uint8_t x = 2*FW-2, y = i*FH+1;
if (i>=SWSRC_AIL) { if (i >= SWSRC_AIL) {
x = 17*FW-1; x = 17*FW-1;
y -= 3*FH; y -= 3*FH;
} }
putsSwitches(x, y, sw, getSwitch(i) ? INVERS : 0); drawSwitch(x, y, sw, getSwitch(i) ? INVERS : 0);
} }
#endif
} }
else { else {
#if defined(PCBMEGA2560) && defined(ROTARY_ENCODERS) #if defined(PCBMEGA2560) && defined(ROTARY_ENCODERS)
@ -515,22 +538,22 @@ void menuMainView(uint8_t event)
#endif // PCBGRUVIN9X && ROTARY_ENCODERS #endif // PCBGRUVIN9X && ROTARY_ENCODERS
// Logical Switches // Logical Switches
#if defined(PCBSKY9X) #if defined(CPUARM)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) { for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++) {
int8_t len = getSwitch(SWSRC_SW1+i) ? BAR_HEIGHT : 1; int8_t len = getSwitch(SWSRC_SW1+i) ? BAR_HEIGHT : 1;
uint8_t x = VSWITCH_X(i); uint8_t x = VSWITCH_X(i);
lcdDrawSolidVerticalLine(x-1, VSWITCH_Y-len, len); lcdDrawSolidVerticalLine(x-1, VSWITCH_Y-len, len);
lcdDrawSolidVerticalLine(x, VSWITCH_Y-len, len); lcdDrawSolidVerticalLine(x, VSWITCH_Y-len, len);
} }
#elif defined(CPUM2560) #elif defined(CPUM2560)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
putsSwitches(2*FW-3 + (i/3)*(i/3>2 ? 3*FW+2 : (3*FW-1)) + (i/3>2 ? 2*FW : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); drawSwitch(2*FW-3 + (i/3)*(i/3>2 ? 3*FW+2 : (3*FW-1)) + (i/3>2 ? 2*FW : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#elif !defined(PCBSTD) #elif !defined(PCBSTD)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
putsSwitches(2*FW-2 + (i/3)*(4*FW-1), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); drawSwitch(2*FW-2 + (i/3)*(4*FW-1), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#else #else
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
putsSwitches(2*FW-3 + (i/3)*(4*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); drawSwitch(2*FW-3 + (i/3)*(4*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#endif #endif
} }
} }
@ -540,8 +563,8 @@ void menuMainView(uint8_t event)
#else #else
#define TMR2_LBL_COL (20-FW/2+5) #define TMR2_LBL_COL (20-FW/2+5)
#endif #endif
putsTimer(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE, DBLSIZE); drawTimer(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE|RIGHT, DBLSIZE);
putsTimerMode(timersStates[1].val >= 0 ? TMR2_LBL_COL : TMR2_LBL_COL-7, FH*6, g_model.timers[1].mode); drawTimerMode(timersStates[1].val >= 0 ? TMR2_LBL_COL : TMR2_LBL_COL-7, FH*6, g_model.timers[1].mode);
// lcdDrawNumber(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s // lcdDrawNumber(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s
} }

View file

@ -25,7 +25,7 @@
#include "view_mavlink.h" #include "view_mavlink.h"
#define VIEW_MAVLINK_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH) #define VIEW_MAVLINK_2ND_COLUMN (LCD_W-6*FW-3)
uint8_t MAVLINK_menu = MENU_INFO; uint8_t MAVLINK_menu = MENU_INFO;

View file

@ -24,8 +24,7 @@ void menuStatisticsView(uint8_t event)
{ {
TITLE(STR_MENUSTAT); TITLE(STR_MENUSTAT);
switch(event) switch (event) {
{
case EVT_KEY_FIRST(KEY_UP): case EVT_KEY_FIRST(KEY_UP):
chainMenu(menuStatisticsDebug); chainMenu(menuStatisticsDebug);
break; break;
@ -43,13 +42,14 @@ void menuStatisticsView(uint8_t event)
} }
lcdDrawText( 1*FW, FH*0, STR_TOTTM1TM2THRTHP); lcdDrawText( 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); drawTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, RIGHT, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0); drawTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, RIGHT, 0);
putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0); drawTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, RIGHT, 0);
drawTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, RIGHT, 0);
drawTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, RIGHT, 0);
#if defined(THRTRACE) #if defined(THRTRACE)
const coord_t x = 5; const coord_t x = 5;
@ -68,7 +68,7 @@ void menuStatisticsView(uint8_t event)
#endif #endif
} }
#if defined(PCBSKY9X) #if defined(CPUARM)
#define MENU_DEBUG_COL1_OFS (11*FW-3) #define MENU_DEBUG_COL1_OFS (11*FW-3)
#define MENU_DEBUG_COL2_OFS (17*FW) #define MENU_DEBUG_COL2_OFS (17*FW)
#define MENU_DEBUG_Y_CURRENT (1*FH) #define MENU_DEBUG_Y_CURRENT (1*FH)
@ -85,20 +85,20 @@ void menuStatisticsDebug(uint8_t event)
{ {
TITLE(STR_MENUDEBUG); TITLE(STR_MENUDEBUG);
switch(event) switch (event) {
{
#if defined(CPUARM) #if defined(CPUARM)
case EVT_KEY_LONG(KEY_ENTER): case EVT_KEY_LONG(KEY_ENTER):
g_eeGeneral.mAhUsed = 0;
g_eeGeneral.globalTimer = 0;
storageDirty(EE_GENERAL);
#if defined(PCBSKY9X) #if defined(PCBSKY9X)
g_eeGeneral.mAhUsed = 0;
Current_used = 0; Current_used = 0;
#endif #endif
g_eeGeneral.globalTimer = 0;
sessionTimer = 0; sessionTimer = 0;
storageDirty(EE_GENERAL);
killEvents(event); killEvents(event);
break; break;
#endif #endif
case EVT_KEY_FIRST(KEY_ENTER): case EVT_KEY_FIRST(KEY_ENTER):
#if !defined(CPUARM) #if !defined(CPUARM)
g_tmr1Latency_min = 0xff; g_tmr1Latency_min = 0xff;
@ -116,6 +116,7 @@ void menuStatisticsDebug(uint8_t event)
case EVT_KEY_FIRST(KEY_DOWN): case EVT_KEY_FIRST(KEY_DOWN):
chainMenu(menuStatisticsView); chainMenu(menuStatisticsView);
break; break;
case EVT_KEY_FIRST(KEY_EXIT): case EVT_KEY_FIRST(KEY_EXIT):
chainMenu(menuMainView); chainMenu(menuMainView);
break; break;

View file

@ -236,7 +236,7 @@ bool displayGaugesTelemetryScreen(FrSkyScreenData & screen)
if (source && barMax > barMin) { if (source && barMax > barMin) {
uint8_t y = barHeight+6+i*(barHeight+6); uint8_t y = barHeight+6+i*(barHeight+6);
#if defined(CPUARM) #if defined(CPUARM)
putsMixerSource(0, y+barHeight-5, source, 0); drawSource(0, y+barHeight-5, source, 0);
#else #else
lcdDrawTextAtIndex(0, y+barHeight-5, STR_VTELEMCHNS, source, 0); lcdDrawTextAtIndex(0, y+barHeight-5, STR_VTELEMCHNS, source, 0);
#endif #endif
@ -334,7 +334,7 @@ bool displayNumbersTelemetryScreen(FrSkyScreenData & screen)
// we don't display GPS name, no space for it // we don't display GPS name, no space for it
} }
else { else {
putsMixerSource(pos[j], 1+FH+2*FH*i, field, 0); drawSource(pos[j], 1+FH+2*FH*i, field, 0);
} }
if (field >= MIXSRC_FIRST_TELEM) { if (field >= MIXSRC_FIRST_TELEM) {
@ -448,7 +448,7 @@ bool displayTelemetryScreen()
} }
#endif #endif
lcdDrawTelemetryTopBar(); drawTelemetryTopBar();
if (s_frsky_view < MAX_TELEMETRY_SCREENS) { if (s_frsky_view < MAX_TELEMETRY_SCREENS) {
return displayCustomTelemetryScreen(s_frsky_view); return displayCustomTelemetryScreen(s_frsky_view);
@ -533,8 +533,8 @@ void menuViewTelemetryFrsky(uint8_t event)
} }
} }
lcdDrawTelemetryTopBar(); drawTelemetryTopBar();
lcdDrawText(8*FW, 3*FH, "No Telemetry Screens"); lcdDrawText(2*FW, 3*FH, "No Telemetry Screens");
displayRssiLine(); displayRssiLine();
#else #else
if (!displayTelemetryScreen()) { if (!displayTelemetryScreen()) {

View file

@ -125,7 +125,7 @@ void menuTextView(uint8_t event)
lcdDrawText(0, i*FH+FH+1, s_text_screen[i], FIXEDWIDTH); lcdDrawText(0, i*FH+FH+1, s_text_screen[i], FIXEDWIDTH);
} }
char *title = s_text_file; char * title = s_text_file;
#if defined(SIMU) #if defined(SIMU)
if (!strncmp(title, "./", 2)) title += 2; if (!strncmp(title, "./", 2)) title += 2;
#else #else

View file

@ -49,10 +49,10 @@ void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr) void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
{ {
lcdDrawNumber(LCD_W, 0, count, attr); lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2); coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
lcdDrawChar(x, 0, '/', attr); lcdDrawChar(x, 0, '/', attr);
lcdDrawNumber(x, 0, index+1, attr); lcdDrawNumber(x, 0, index+1, RIGHT | attr);
} }
#if !defined(CPUM64) #if !defined(CPUM64)
@ -76,7 +76,7 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, c
{ {
drawFieldLabel(x, y, label); drawFieldLabel(x, y, label);
if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
if (attr) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL);
return value; return value;
} }
@ -93,8 +93,8 @@ uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label,
int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event) int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event)
{ {
drawFieldLabel(x, y, STR_SWITCH); drawFieldLabel(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr); drawSwitch(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
return value; return value;
} }

View file

@ -24,6 +24,10 @@
#include "gui_common.h" #include "gui_common.h"
#include "lcd.h" #include "lcd.h"
#include "menus.h" #include "menus.h"
#include "popups.h"
#define HEADER_LINE 0
#define HEADER_LINE_COLUMNS
#define DEFAULT_SCROLLBAR_X (LCD_W-1) #define DEFAULT_SCROLLBAR_X (LCD_W-1)
#define NUM_BODY_LINES (LCD_LINES-1) #define NUM_BODY_LINES (LCD_LINES-1)
@ -36,9 +40,9 @@
#define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT) #define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)
#define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap) #define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap)
#define WCHART (LCD_H/2) #define CURVE_SIDE_WIDTH (LCD_H/2)
#define X0 (LCD_W-WCHART-2) #define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
#define Y0 (LCD_H/2) #define CURVE_CENTER_Y (LCD_H/2)
#if defined(TRANSLATIONS_FR) #if defined(TRANSLATIONS_FR)
#define MENU_COLUMNS 1 #define MENU_COLUMNS 1
@ -84,6 +88,7 @@ void updateProgressBar(int num, int den);
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max);
void drawColumnHeader(const char * const * headers, uint8_t index); void drawColumnHeader(const char * const * headers, uint8_t index);
void drawStick(coord_t centrex, int16_t xval, int16_t yval); void drawStick(coord_t centrex, int16_t xval, int16_t yval);
void drawCurveRef(coord_t x, coord_t y, CurveRef & curve, LcdFlags att);
void drawAlertBox(const char * title, const char * text, const char * action); void drawAlertBox(const char * title, const char * text, const char * action);
#define ALERT_SOUND_ARG , uint8_t sound #define ALERT_SOUND_ARG , uint8_t sound
@ -91,7 +96,6 @@ void showAlertBox(const char * title, const char * text, const char * action, ui
void doMainScreenGraphics(); void doMainScreenGraphics();
typedef uint16_t FlightModesType; typedef uint16_t FlightModesType;
extern int8_t checkIncDec_Ret; // global helper vars extern int8_t checkIncDec_Ret; // global helper vars
@ -254,7 +258,7 @@ int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int
#endif #endif
extern uint8_t s_curveChan; extern uint8_t s_curveChan;
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t attr); void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, LcdFlags flags);
extern uint8_t editNameCursorPos; extern uint8_t editNameCursorPos;
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr=ZCHAR); void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr=ZCHAR);
@ -299,49 +303,6 @@ uint8_t getMixesCount();
void deleteMix(uint8_t idx); void deleteMix(uint8_t idx);
void insertMix(uint8_t idx); void insertMix(uint8_t idx);
#define MENU_X 30
#define MENU_Y 16
#define MENU_W LCD_W-(2*MENU_X)
#define WARNING_LINE_LEN 32
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
void drawMessageBox(const char * title);
void showMessageBox(const char * title);
void runPopupWarning(uint8_t event);
extern void (*popupFunc)(uint8_t event);
extern int16_t warningInputValue;
extern int16_t warningInputValueMin;
extern int16_t warningInputValueMax;
extern uint8_t warningInfoFlags;
#define DISPLAY_WARNING (*popupFunc)
#define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max)
#define WARNING_INFO_FLAGS warningInfoFlags
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
#define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0)
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while(0)
#define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 6
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s)
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define POPUP_MENU_ITEMS_FROM_BSS()
extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset;
enum {
MENU_OFFSET_INTERNAL,
MENU_OFFSET_EXTERNAL
};
extern uint8_t popupMenuOffsetType;
const char * runPopupMenu(uint8_t event);
extern void (*popupMenuHandler)(const char *result);
#define STATUS_LINE_LENGTH 32 #define STATUS_LINE_LENGTH 32
extern char statusLineMsg[STATUS_LINE_LENGTH]; extern char statusLineMsg[STATUS_LINE_LENGTH];
void showStatusLine(); void showStatusLine();
@ -357,21 +318,8 @@ void menuChannelsView(uint8_t event);
#define LABEL(...) (uint8_t)-1 #define LABEL(...) (uint8_t)-1
#if defined(PCBX9E) && !defined(SIMU) #define CURSOR_MOVED_LEFT(event) (EVT_KEY_MASK(event) == KEY_LEFT)
#define KEY_UP KEY_MINUS #define CURSOR_MOVED_RIGHT(event) (EVT_KEY_MASK(event) == KEY_RIGHT)
#define KEY_DOWN KEY_PLUS
#define KEY_RIGHT KEY_PLUS
#define KEY_LEFT KEY_MINUS
#define CURSOR_MOVED_LEFT(event) (EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (EVT_KEY_MASK(event) == KEY_RIGHT)
#else
#define KEY_UP KEY_PLUS
#define KEY_DOWN KEY_MINUS
#define KEY_RIGHT KEY_MINUS
#define KEY_LEFT KEY_PLUS
#define CURSOR_MOVED_LEFT(event) (EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (EVT_KEY_MASK(event) == KEY_RIGHT)
#endif
#define REPEAT_LAST_CURSOR_MOVE() { if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) putEvent(event); else menuHorizontalPosition = 0; } #define REPEAT_LAST_CURSOR_MOVE() { if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) putEvent(event); else menuHorizontalPosition = 0; }
#define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE() #define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE()
@ -380,7 +328,7 @@ void menuChannelsView(uint8_t event);
#define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0) #define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0)
#define EDIT_MODE_INIT 0 // TODO enum #define EDIT_MODE_INIT 0 // TODO enum
typedef int16_t (*FnFuncP) (int16_t x); typedef int (*FnFuncP) (int x);
void drawFunction(FnFuncP fn, uint8_t offset=0); void drawFunction(FnFuncP fn, uint8_t offset=0);
void onSourceLongEnterPress(const char *result); void onSourceLongEnterPress(const char *result);
@ -396,7 +344,7 @@ extern const pm_uchar sticks[] PROGMEM;
void displayFlightModes(coord_t x, coord_t y, FlightModesType value); void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr); FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr);
#else #else
#define displayFlightModes(...) #define displayFlightModes(...)
#endif #endif
#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView

View file

@ -314,8 +314,9 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
lcdLastPos = x; lcdLastPos = x;
lcdNextPos = x; lcdNextPos = x;
if (fontsize == MIDSIZE) if (fontsize == MIDSIZE) {
lcdLastPos += 1; lcdLastPos += 1;
}
if (flags & RIGHT) { if (flags & RIGHT) {
lcdLastPos -= width; lcdLastPos -= width;
@ -578,30 +579,30 @@ void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat,
} }
} }
void lcdDrawTelemetryTopBar() void drawTelemetryTopBar()
{ {
putsModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0); putsModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0);
uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0); uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0);
putsVBat(12*FW, 0, att); putsVBat(12*FW, 0, att);
if (g_model.timers[0].mode) { if (g_model.timers[0].mode) {
att = (timersStates[0].val<0 ? BLINK : 0); att = (timersStates[0].val<0 ? BLINK : 0);
putsTimer(22*FW, 0, timersStates[0].val, att, att); drawTimer(22*FW, 0, timersStates[0].val, att, att);
putsMixerSource(18*FW+2, 1, MIXSRC_TIMER1, SMLSIZE); drawSource(18*FW+2, 1, MIXSRC_TIMER1, SMLSIZE);
} }
if (g_model.timers[1].mode) { if (g_model.timers[1].mode) {
att = (timersStates[1].val<0 ? BLINK : 0); att = (timersStates[1].val<0 ? BLINK : 0);
putsTimer(31*FW, 0, timersStates[1].val, att, att); drawTimer(31*FW, 0, timersStates[1].val, att, att);
putsMixerSource(27*FW+2, 1, MIXSRC_TIMER2, SMLSIZE); drawSource(27*FW+2, 1, MIXSRC_TIMER2, SMLSIZE);
} }
lcdInvertLine(0); lcdInvertLine(0);
} }
void putsRtcTime(coord_t x, coord_t y, LcdFlags att) void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
{ {
putsTimer(x, y, getValue(MIXSRC_TX_TIME), att, att); drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att);
} }
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2) void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2)
{ {
div_t qr; div_t qr;
@ -656,19 +657,13 @@ void putsVBat(coord_t x, coord_t y, LcdFlags att)
putsVolts(x, y, g_vbat100mV, att); putsVolts(x, y, g_vbat100mV, att);
} }
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att)
{
lcdDrawText(x, y, str, att & ~LEADING0);
lcdDrawNumber(lcdNextPos, y, idx, att|LEFT, 2);
}
void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att) void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
{ {
uint8_t length = STR_VSRCRAW[0]; uint8_t length = STR_VSRCRAW[0];
lcdDrawSizedText(x, y, STR_VSRCRAW+2+length*(idx+1), length-1, att); lcdDrawSizedText(x, y, STR_VSRCRAW+2+length*(idx+1), length-1, att);
} }
void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att) void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
{ {
if (idx == MIXSRC_NONE) { if (idx == MIXSRC_NONE) {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
@ -724,7 +719,7 @@ void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
else if (idx < MIXSRC_SW1) else if (idx < MIXSRC_SW1)
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
putsSwitches(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att); drawSwitch(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
else if (idx < MIXSRC_CH1) else if (idx < MIXSRC_CH1)
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att); drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
else if (idx <= MIXSRC_LAST_CH) { else if (idx <= MIXSRC_LAST_CH) {
@ -738,7 +733,7 @@ void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att); drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
} }
else if (idx < MIXSRC_FIRST_TELEM) { else if (idx < MIXSRC_FIRST_TELEM) {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-NUM_LOGICAL_SWITCH-NUM_TRAINER-NUM_CHNOUT-MAX_GVARS, att); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-MAX_LOGICAL_SWITCHES-MAX_TRAINER_CHANNELS-MAX_OUTPUT_CHANNELS-MAX_GVARS, att);
} }
else { else {
idx -= MIXSRC_FIRST_TELEM; idx -= MIXSRC_FIRST_TELEM;
@ -765,115 +760,21 @@ void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
} }
} }
void putsSwitches(coord_t x, coord_t y, int32_t idx, LcdFlags att) void drawSwitch(coord_t x, coord_t y, int32_t idx, LcdFlags flags)
{ {
if (idx == SWSRC_NONE) { char s[8];
return lcdDrawTextAtIndex(x, y, STR_VSWITCHES, 0, att); getSwitchString(s, idx);
} lcdDrawText(x, y, s, flags);
else if (idx == SWSRC_OFF) {
return lcdDrawTextAtIndex(x, y, STR_OFFON, 0, att);
}
if (idx < 0) {
lcdDrawChar(x-2, y, '!', att);
idx = -idx;
}
if (idx <= SWSRC_LAST_SWITCH) {
div_t swinfo = switchInfo(idx);
if (ZEXIST(g_eeGeneral.switchNames[swinfo.quot])) {
lcdDrawSizedText(x, y, g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME, ZCHAR|att);
}
else {
lcdDrawChar(x, y, 'S', att);
lcdDrawChar(lcdNextPos, y, 'A'+swinfo.quot, att);
}
char c = "\300-\301"[swinfo.rem];
lcdDrawChar(lcdNextPos, y, c, att);
}
else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) {
div_t swinfo = div(idx - SWSRC_FIRST_MULTIPOS_SWITCH, XPOTS_MULTIPOS_COUNT);
drawStringWithIndex(x, y, "S", swinfo.quot*10+swinfo.rem+11, att);
}
else if (idx <= SWSRC_LAST_TRIM) {
lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx-SWSRC_FIRST_TRIM+1, att);
}
else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) {
drawStringWithIndex(x, y, "L", idx-SWSRC_FIRST_LOGICAL_SWITCH+1, att);
}
else if (idx <= SWSRC_ONE) {
lcdDrawTextAtIndex(x, y, STR_VSWITCHES, idx-SWSRC_ON+1+(2*NUM_STICKS), att);
}
else if (idx <= SWSRC_LAST_FLIGHT_MODE) {
drawStringWithIndex(x, y, STR_FP, idx-SWSRC_FIRST_FLIGHT_MODE, att);
}
else if (idx == SWSRC_TELEMETRY_STREAMING) {
lcdDrawText(x, y, "Tele", att);
}
else if (idx <= SWSRC_LAST_FLIGHT_MODE) {
drawStringWithIndex(x, y, STR_FP, idx-SWSRC_FIRST_FLIGHT_MODE, att);
}
else if (idx == SWSRC_TELEMETRY_STREAMING) {
lcdDrawText(x, y, "Tele", att);
}
else {
lcdDrawSizedText(x, y, g_model.telemetrySensors[idx-SWSRC_FIRST_SENSOR].label, TELEM_LABEL_LEN, ZCHAR|att);
}
}
#if defined(FLIGHT_MODES)
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att)
{
if (idx==0)
lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, att);
else
drawStringWithIndex(x, y, STR_FP, idx-1, att);
}
#endif
void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att)
{
if (curve.value != 0) {
switch (curve.type) {
case CURVE_REF_DIFF:
lcdDrawChar(x, y, 'D', att);
GVAR_MENU_ITEM(x+FW, y, curve.value, -100, 100, LEFT|att, 0, 0);
break;
case CURVE_REF_EXPO:
lcdDrawChar(x, y, 'E', att);
GVAR_MENU_ITEM(x+FW, y, curve.value, -100, 100, LEFT|att, 0, 0);
break;
case CURVE_REF_FUNC:
lcdDrawTextAtIndex(x, y, STR_VCURVEFUNC, curve.value, att);
break;
case CURVE_REF_CUSTOM:
drawCurveName(x, y, curve.value, att);
break;
}
}
} }
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags) void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags)
{ {
if (idx == 0) { char s[8];
return lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, flags); getCurveString(s, idx);
} lcdDrawText(x, y, s, flags);
if (idx < 0) {
lcdDrawChar(x-3, y, '!', flags);
idx = -idx;
}
if (ZEXIST(g_model.curves[idx-1].name))
lcdDrawSizedText(x, y, g_model.curves[idx-1].name, LEN_CURVE_NAME, ZCHAR|flags);
else
drawStringWithIndex(x, y, STR_CV, idx, flags);
} }
void putsTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att) void drawTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att)
{ {
if (mode >= 0) { if (mode >= 0) {
if (mode < TMRMODE_COUNT) if (mode < TMRMODE_COUNT)
@ -881,10 +782,10 @@ void putsTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att)
else else
mode -= (TMRMODE_COUNT-1); mode -= (TMRMODE_COUNT-1);
} }
putsSwitches(x, y, mode, att); drawSwitch(x, y, mode, att);
} }
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att) void drawTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att)
{ {
trim_t v = getRawTrimValue(phase, idx); trim_t v = getRawTrimValue(phase, idx);
unsigned int mode = v.mode; unsigned int mode = v.mode;
@ -997,7 +898,7 @@ void displayGpsCoords(coord_t x, coord_t y, TelemetryItem & telemetryItem, LcdFl
void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, int32_t value, LcdFlags att) void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, int32_t value, LcdFlags att)
{ {
if (channel >= MAX_SENSORS) if (channel >= MAX_TELEMETRY_SENSORS)
return; // Lua luaLcdDrawChannel() can call us with a bad value return; // Lua luaLcdDrawChannel() can call us with a bad value
TelemetryItem & telemetryItem = telemetryItems[channel]; TelemetryItem & telemetryItem = telemetryItems[channel];
@ -1074,7 +975,7 @@ void putsChannelValue(coord_t x, coord_t y, source_t channel, int32_t value, Lcd
putsTelemetryChannelValue(x, y, channel, value, att); putsTelemetryChannelValue(x, y, channel, value, att);
} }
else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) { else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) {
putsTimer(x, y, value, att, att); drawTimer(x, y, value, att, att);
} }
else if (channel == MIXSRC_TX_VOLTAGE) { else if (channel == MIXSRC_TX_VOLTAGE) {
lcdDrawNumber(x, y, value, att|PREC1); lcdDrawNumber(x, y, value, att|PREC1);

View file

@ -21,8 +21,7 @@
#ifndef _LCD_H_ #ifndef _LCD_H_
#define _LCD_H_ #define _LCD_H_
#define LCD_W 212
#define LCD_H 64
#define BOX_WIDTH 31 #define BOX_WIDTH 31
#define coord_t int #define coord_t int
#define scoord_t int #define scoord_t int
@ -97,12 +96,6 @@
extern display_t displayBuf[DISPLAY_BUFFER_SIZE]; extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#endif #endif
#if (defined(PCBX9E) || defined(PCBX9DP)) && !defined(LCD_DUAL_BUFFER) && !defined(SIMU)
void lcdRefreshWait();
#else
#define lcdRefreshWait()
#endif
extern coord_t lcdLastPos; extern coord_t lcdLastPos;
extern coord_t lcdNextPos; extern coord_t lcdNextPos;
@ -133,18 +126,14 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att=0); void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att=0);
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
void putsSwitches(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0); void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0);
void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0); void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
#if !defined(BOOT)
void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att);
#endif
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att=0); void drawTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att=0);
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att); void drawTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
#define putsChn(x, y, idx, att) putsMixerSource(x, y, MIXSRC_CH1+idx-1, att) #define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_CH1+idx-1, att)
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att); void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
@ -158,8 +147,8 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, int32_t va
#define putstime_t int32_t #define putstime_t int32_t
void putsRtcTime(coord_t x, coord_t y, LcdFlags att); void drawRtcTime(coord_t x, coord_t y, LcdFlags att);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2); void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
#define SOLID 0xff #define SOLID 0xff
#define DOTTED 0x55 #define DOTTED 0x55
@ -185,9 +174,9 @@ inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0)
void lcdInvertLine(int8_t line); void lcdInvertLine(int8_t line);
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1) #define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
void drawShutdownBitmap(uint32_t index); void drawShutdownAnimation(uint32_t index);
void drawSleepBitmap(); void drawSleepBitmap();
void lcdDrawTelemetryTopBar(); void drawTelemetryTopBar();
#define V_BAR(xx, yy, ll) \ #define V_BAR(xx, yy, ll) \
lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \ lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \
@ -199,15 +188,7 @@ void lcd_img(coord_t x, coord_t y, const pm_uchar * img, uint8_t idx, LcdFlags a
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0); void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0);
#define LCD_ICON(x, y, icon) lcdDrawBitmap(x, y, icons, icon) #define LCD_ICON(x, y, icon) lcdDrawBitmap(x, y, icons, icon)
void lcdSetRefVolt(unsigned char val);
void lcdClear(); void lcdClear();
void lcdSetContrast();
#if (defined(PCBX9E) || defined(PCBX9DP)) && !defined(SIMU)
void lcdRefresh(bool wait=true);
#else
void lcdRefresh();
#endif
uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height); uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height);
const char * writeScreenshot(); const char * writeScreenshot();

View file

@ -71,7 +71,7 @@ uint8_t s_copySrcCh;
uint8_t editNameCursorPos = 0; uint8_t editNameCursorPos = 0;
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr) void editName(coord_t x, coord_t y, char * name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr)
{ {
uint8_t mode = 0; uint8_t mode = 0;
if (active) { if (active) {
@ -159,7 +159,7 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
} }
} }
void editSingleName(coord_t x, coord_t y, const pm_char *label, char *name, uint8_t size, uint8_t event, uint8_t active) void editSingleName(coord_t x, coord_t y, const pm_char * label, char *name, uint8_t size, uint8_t event, uint8_t active)
{ {
lcdDrawTextAlignedLeft(y, label); lcdDrawTextAlignedLeft(y, label);
editName(x, y, name, size, event, active); editName(x, y, name, size, event, active);

View file

@ -34,6 +34,6 @@ const MenuHandlerFunc menuTabGeneral[] = {
void menuRadioSpecialFunctions(uint8_t event) void menuRadioSpecialFunctions(uint8_t event)
{ {
MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, NUM_CFN, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ });
return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext); return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext);
} }

View file

@ -23,15 +23,16 @@
#include "keys.h" #include "keys.h"
typedef uint16_t vertpos_t;
typedef int8_t horzpos_t; typedef int8_t horzpos_t;
typedef uint16_t vertpos_t;
typedef void (*MenuHandlerFunc)(uint8_t event); typedef void (*MenuHandlerFunc)(uint8_t event);
extern tmr10ms_t menuEntryTime; extern tmr10ms_t menuEntryTime;
extern vertpos_t menuVerticalPosition; extern vertpos_t menuVerticalPosition;
extern horzpos_t menuHorizontalPosition; extern horzpos_t menuHorizontalPosition;
extern vertpos_t menuVerticalOffset; extern vertpos_t menuVerticalOffset;
extern uint8_t calibrationState; extern uint8_t menuCalibrationState;
extern MenuHandlerFunc menuHandlers[5]; extern MenuHandlerFunc menuHandlers[5];
extern uint8_t menuVerticalPositions[4]; extern uint8_t menuVerticalPositions[4];
@ -48,9 +49,7 @@ void menuFirstCalib(uint8_t event);
void menuMainViewChannelsMonitor(uint8_t event); void menuMainViewChannelsMonitor(uint8_t event);
void menuChannelsView(uint8_t event); void menuChannelsView(uint8_t event);
void menuMainView(uint8_t event); void menuMainView(uint8_t event);
#if defined(TELEMETRY_FRSKY)
void menuViewTelemetryFrsky(uint8_t event); void menuViewTelemetryFrsky(uint8_t event);
#endif
void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
void menuModelNotes(uint8_t event); void menuModelNotes(uint8_t event);
void menuStatisticsView(uint8_t event); void menuStatisticsView(uint8_t event);
@ -60,14 +59,14 @@ void menuAboutView(uint8_t event);
void menuTraceBuffer(uint8_t event); void menuTraceBuffer(uint8_t event);
#endif #endif
enum EnumTabRadio { enum MenuRadioIndexes {
MENU_RADIO_SETUP, MENU_RADIO_SETUP,
MENU_RADIO_SD_MANAGER, MENU_RADIO_SD_MANAGER,
MENU_RADIO_SPECIAL_FUNCTIONS, MENU_RADIO_SPECIAL_FUNCTIONS,
MENU_RADIO_TRAINER, MENU_RADIO_TRAINER,
MENU_RADIO_VERSION, MENU_RADIO_VERSION,
MENU_RADIO_DIAG_KEYS, MENU_RADIO_SWITCHES_TEST,
MENU_RADIO_DIAG_ANALOGS, MENU_RADIO_ANALOGS_TEST,
MENU_RADIO_HARDWARE, MENU_RADIO_HARDWARE,
MENU_RADIO_CALIBRATION, MENU_RADIO_CALIBRATION,
MENU_RADIO_PAGES_COUNT MENU_RADIO_PAGES_COUNT
@ -85,7 +84,7 @@ void menuRadioCalibration(uint8_t event);
extern const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT]; extern const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT];
enum EnumTabModel { enum MenuModelIndexes {
MENU_MODEL_SELECT, MENU_MODEL_SELECT,
MENU_MODEL_SETUP, MENU_MODEL_SETUP,
CASE_HELI(MENU_MODEL_HELI) CASE_HELI(MENU_MODEL_HELI)

View file

@ -97,7 +97,7 @@ void menuModelCustomScriptOne(uint8_t event)
} }
else { else {
uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx]; uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx];
putsMixerSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr); drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr);
if (attr) { if (attr) {
CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def);
} }
@ -110,7 +110,7 @@ void menuModelCustomScriptOne(uint8_t event)
lcdDrawText(SCRIPT_ONE_3RD_COLUMN_POS, FH+1, STR_OUTPUTS); lcdDrawText(SCRIPT_ONE_3RD_COLUMN_POS, FH+1, STR_OUTPUTS);
for (int i=0; i<scriptInputsOutputs[s_currIdx].outputsCount; i++) { for (int i=0; i<scriptInputsOutputs[s_currIdx].outputsCount; i++) {
putsMixerSource(SCRIPT_ONE_3RD_COLUMN_POS+INDENT_WIDTH, FH+1+FH+i*FH, MIXSRC_FIRST_LUA+(s_currIdx*MAX_SCRIPT_OUTPUTS)+i, 0); drawSource(SCRIPT_ONE_3RD_COLUMN_POS+INDENT_WIDTH, FH+1+FH+i*FH, MIXSRC_FIRST_LUA+(s_currIdx*MAX_SCRIPT_OUTPUTS)+i, 0);
lcdDrawNumber(SCRIPT_ONE_3RD_COLUMN_POS+11*FW+3, FH+1+FH+i*FH, calcRESXto1000(scriptInputsOutputs[s_currIdx].outputs[i].value), PREC1|RIGHT); lcdDrawNumber(SCRIPT_ONE_3RD_COLUMN_POS+11*FW+3, FH+1+FH+i*FH, calcRESXto1000(scriptInputsOutputs[s_currIdx].outputs[i].value), PREC1|RIGHT);
} }
} }

View file

@ -20,7 +20,7 @@
#include "opentx.h" #include "opentx.h"
enum menuModelDisplayItems { enum MenuModelDisplayItems {
ITEM_DISPLAY_TOP_BAR_LABEL, ITEM_DISPLAY_TOP_BAR_LABEL,
ITEM_DISPLAY_TOP_BAR_VOLTAGE, ITEM_DISPLAY_TOP_BAR_VOLTAGE,
ITEM_DISPLAY_TOP_BAR_ALTITUDE, ITEM_DISPLAY_TOP_BAR_ALTITUDE,
@ -103,17 +103,17 @@ void menuModelDisplay(uint8_t event)
case ITEM_DISPLAY_TOP_BAR_VOLTAGE: case ITEM_DISPLAY_TOP_BAR_VOLTAGE:
lcdDrawTextAlignedLeft(y, STR_VOLTAGE); lcdDrawTextAlignedLeft(y, STR_VOLTAGE);
putsMixerSource(DISPLAY_COL2, y, g_model.frsky.voltsSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.voltsSource-1) : 0, attr); drawSource(DISPLAY_COL2, y, g_model.frsky.voltsSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.voltsSource-1) : 0, attr);
if (attr) { if (attr) {
g_model.frsky.voltsSource = checkIncDec(event, g_model.frsky.voltsSource, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isVoltsSensor); g_model.frsky.voltsSource = checkIncDec(event, g_model.frsky.voltsSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isVoltsSensor);
} }
break; break;
case ITEM_DISPLAY_TOP_BAR_ALTITUDE: case ITEM_DISPLAY_TOP_BAR_ALTITUDE:
lcdDrawTextAlignedLeft(y, STR_ALTITUDE); lcdDrawTextAlignedLeft(y, STR_ALTITUDE);
putsMixerSource(DISPLAY_COL2, y, g_model.frsky.altitudeSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.altitudeSource-1) : 0, attr); drawSource(DISPLAY_COL2, y, g_model.frsky.altitudeSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.altitudeSource-1) : 0, attr);
if (attr) { if (attr) {
g_model.frsky.altitudeSource = checkIncDec(event, g_model.frsky.altitudeSource, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); g_model.frsky.altitudeSource = checkIncDec(event, g_model.frsky.altitudeSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor);
} }
break; break;
@ -196,7 +196,7 @@ void menuModelDisplay(uint8_t event)
if (IS_BARS_SCREEN(screenIndex)) { if (IS_BARS_SCREEN(screenIndex)) {
FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex]; FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex];
source_t barSource = bar.source; source_t barSource = bar.source;
putsMixerSource(DISPLAY_COL1, y, barSource, menuHorizontalPosition==0 ? attr : 0); drawSource(DISPLAY_COL1, y, barSource, menuHorizontalPosition==0 ? attr : 0);
int barMax = getMaximumValue(barSource); int barMax = getMaximumValue(barSource);
int barMin = -barMax; int barMin = -barMax;
if (barSource) { if (barSource) {
@ -241,7 +241,7 @@ void menuModelDisplay(uint8_t event)
LcdFlags cellAttr = (menuHorizontalPosition==c ? attr : 0); LcdFlags cellAttr = (menuHorizontalPosition==c ? attr : 0);
source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c]; source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c];
const coord_t pos[] = {DISPLAY_COL1, DISPLAY_COL2, DISPLAY_COL3}; const coord_t pos[] = {DISPLAY_COL1, DISPLAY_COL2, DISPLAY_COL3};
putsMixerSource(pos[c], y, value, cellAttr); drawSource(pos[c], y, value, cellAttr);
if (cellAttr && s_editMode>0) { if (cellAttr && s_editMode>0) {
value = checkIncDec(event, value, 0, MIXSRC_LAST_TELEM, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable); value = checkIncDec(event, value, 0, MIXSRC_LAST_TELEM, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable);
} }

View file

@ -30,36 +30,6 @@ void displayFlightModes(coord_t x, coord_t y, FlightModesType value)
} }
} }
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
drawFieldLabel(x, y, STR_FLMODE);
int posHorz = menuHorizontalPosition;
for (int p=0; p<MAX_FLIGHT_MODES; p++) {
LcdFlags flags = 0;
if (attr) {
flags |= INVERS;
if (posHorz==p) flags |= BLINK;
}
if (value & (1<<p))
lcdDrawChar(x, y, ' ', flags|FIXEDWIDTH);
else
lcdDrawChar(x, y, '0'+p, flags);
x += FW;
}
if (attr) {
if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
value ^= (1<<posHorz);
storageDirty(EE_MODEL);
}
}
return value;
}
enum FlightModesItems { enum FlightModesItems {
ITEM_FLIGHT_MODES_NAME, ITEM_FLIGHT_MODES_NAME,
ITEM_FLIGHT_MODES_SWITCH, ITEM_FLIGHT_MODES_SWITCH,
@ -80,7 +50,7 @@ bool isTrimModeAvailable(int mode)
void menuModelFlightModesAll(uint8_t event) void menuModelFlightModesAll(uint8_t event)
{ {
MENU(STR_MENUFLIGHTPHASES, menuTabModel, MENU_MODEL_FLIGHT_MODES, MAX_FLIGHT_MODES+1, { NAVIGATION_LINE_BY_LINE|(ITEM_FLIGHT_MODES_LAST-1), NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, 0 }); MENU(STR_MENUFLIGHTMODES, menuTabModel, MENU_MODEL_FLIGHT_MODES, MAX_FLIGHT_MODES+1, { NAVIGATION_LINE_BY_LINE|(ITEM_FLIGHT_MODES_LAST-1), NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, 0 });
int8_t sub = menuVerticalPosition; int8_t sub = menuVerticalPosition;
@ -95,11 +65,11 @@ void menuModelFlightModesAll(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
if (k==MAX_FLIGHT_MODES) { if (k == MAX_FLIGHT_MODES) {
// last line available - add the "check trims" line // last line available - add the "check trims" line
lcdDrawTextAlignedLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS); lcdDrawTextAlignedLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS);
putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, mixerCurrentFlightMode+1); drawFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, mixerCurrentFlightMode+1);
if (sub==MAX_FLIGHT_MODES) { if (sub == MAX_FLIGHT_MODES) {
if (!trimsCheckTimer) { if (!trimsCheckTimer) {
if (event == EVT_KEY_FIRST(KEY_ENTER)) { if (event == EVT_KEY_FIRST(KEY_ENTER)) {
trimsCheckTimer = 200; // 2 seconds trims cancelled trimsCheckTimer = 200; // 2 seconds trims cancelled
@ -124,7 +94,7 @@ void menuModelFlightModesAll(uint8_t event)
FlightModeData *p = flightModeAddress(k); FlightModeData *p = flightModeAddress(k);
putsFlightMode(0, y, k+1, (getFlightMode()==k ? BOLD : 0) | ((sub==k && menuHorizontalPosition<0) ? INVERS : 0)); drawFlightMode(0, y, k+1, (getFlightMode()==k ? BOLD : 0) | ((sub==k && menuHorizontalPosition<0) ? INVERS : 0));
for (uint8_t j=0; j<ITEM_FLIGHT_MODES_COUNT; j++) { for (uint8_t j=0; j<ITEM_FLIGHT_MODES_COUNT; j++) {
uint8_t attr = ((sub==k && posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t attr = ((sub==k && posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
@ -136,7 +106,7 @@ void menuModelFlightModesAll(uint8_t event)
case ITEM_FLIGHT_MODES_SWITCH: case ITEM_FLIGHT_MODES_SWITCH:
if (k>0) { if (k>0) {
putsSwitches((4+LEN_FLIGHT_MODE_NAME)*FW+FW/2, y, p->swtch, attr); drawSwitch((4+LEN_FLIGHT_MODE_NAME)*FW+FW/2, y, p->swtch, attr);
if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
} }
break; break;
@ -147,7 +117,7 @@ void menuModelFlightModesAll(uint8_t event)
case ITEM_FLIGHT_MODES_TRIM_AIL: case ITEM_FLIGHT_MODES_TRIM_AIL:
{ {
uint8_t t = j-ITEM_FLIGHT_MODES_TRIM_RUD; uint8_t t = j-ITEM_FLIGHT_MODES_TRIM_RUD;
putsTrimMode((4+LEN_FLIGHT_MODE_NAME)*FW+j*(5*FW/2), y, k, t, attr); drawTrimMode((4+LEN_FLIGHT_MODE_NAME)*FW+j*(5*FW/2), y, k, t, attr);
if (active) { if (active) {
trim_t & v = p->trim[t]; trim_t & v = p->trim[t];
v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable); v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable);

View file

@ -28,7 +28,7 @@ void editGVarValue(coord_t x, coord_t y, uint8_t event, uint8_t gvar, uint8_t fl
if (v > GVAR_MAX) { if (v > GVAR_MAX) {
uint8_t fm = v - GVAR_MAX - 1; uint8_t fm = v - GVAR_MAX - 1;
if (fm >= flightMode) fm++; if (fm >= flightMode) fm++;
putsFlightMode(x, y, fm + 1, flags&(~LEFT)); drawFlightMode(x, y, fm + 1, flags&(~LEFT));
vmin = GVAR_MAX + 1; vmin = GVAR_MAX + 1;
vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1; vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1;
} }

View file

@ -23,7 +23,7 @@
#define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90) #define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90)
#define EXPO_ONE_FM_WIDTH (9*FW) #define EXPO_ONE_FM_WIDTH (9*FW)
int16_t expoFn(int16_t x) int expoFn(int x)
{ {
ExpoData * ed = expoAddress(s_currIdx); ExpoData * ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0}; int16_t anas[NUM_INPUTS] = {0};
@ -33,20 +33,20 @@ int16_t expoFn(int16_t x)
void drawFunction(FnFuncP fn, uint8_t offset) void drawFunction(FnFuncP fn, uint8_t offset)
{ {
lcdDrawVerticalLine(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee); lcdDrawVerticalLine(CURVE_CENTER_X-offset, CURVE_CENTER_Y-CURVE_SIDE_WIDTH, CURVE_SIDE_WIDTH*2, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee); lcdDrawHorizontalLine(CURVE_CENTER_X-CURVE_SIDE_WIDTH-offset, CURVE_CENTER_Y, CURVE_SIDE_WIDTH*2, 0xee);
coord_t prev_yv = (coord_t)-1; coord_t prev_yv = (coord_t)-1;
for (int xv=-WCHART; xv<=WCHART; xv++) { for (int xv=-CURVE_SIDE_WIDTH; xv<=CURVE_SIDE_WIDTH; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX); coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/CURVE_SIDE_WIDTH))) / 2 * (LCD_H-1) / RESX);
if (prev_yv != (coord_t)-1) { if (prev_yv != (coord_t)-1) {
if (abs((int8_t)yv-prev_yv) <= 1) { if (abs((int8_t)yv-prev_yv) <= 1) {
lcdDrawPoint(X0+xv-offset-1, prev_yv, FORCE); lcdDrawPoint(CURVE_CENTER_X+xv-offset-1, prev_yv, FORCE);
} }
else { else {
uint8_t tmp = (prev_yv < yv ? 0 : 1); uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv); lcdDrawSolidVerticalLine(CURVE_CENTER_X+xv-offset-1, yv+tmp, prev_yv-yv);
} }
} }
prev_yv = yv; prev_yv = yv;
@ -183,7 +183,7 @@ void menuModelExpoOne(uint8_t event)
} }
ExpoData * ed = expoAddress(s_currIdx); ExpoData * ed = expoAddress(s_currIdx);
putsMixerSource(PSIZE(TR_MENUINPUTS)*FW+FW, 0, MIXSRC_FIRST_INPUT+ed->chn, 0); drawSource(PSIZE(TR_MENUINPUTS)*FW+FW, 0, MIXSRC_FIRST_INPUT+ed->chn, 0);
lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT);
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
@ -214,7 +214,7 @@ void menuModelExpoOne(uint8_t event)
case EXPO_FIELD_SOURCE: case EXPO_FIELD_SOURCE:
lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE)); lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr); drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr);
if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
break; break;
@ -243,6 +243,7 @@ void menuModelExpoOne(uint8_t event)
#if defined(FLIGHT_MODES) #if defined(FLIGHT_MODES)
case EXPO_FIELD_FLIGHT_MODES: case EXPO_FIELD_FLIGHT_MODES:
drawFieldLabel(EXPO_ONE_2ND_COLUMN, y, STR_FLMODE);
ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr); ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
break; break;
#endif #endif
@ -281,7 +282,7 @@ void menuModelExpoOne(uint8_t event)
y512 = limit(-1024, y512, 1024); y512 = limit(-1024, y512, 1024);
lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), RIGHT | PREC1); lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), RIGHT | PREC1);
x512 = X0+x512/(RESX/WCHART); x512 = CURVE_CENTER_X+x512/(RESX/CURVE_SIDE_WIDTH);
y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX; y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;
lcdDrawSolidVerticalLine(x512, y512-3, 3*2+1); lcdDrawSolidVerticalLine(x512, y512-3, 3*2+1);
@ -327,15 +328,15 @@ void onExposMenu(const char * result)
} }
} }
void displayExpoInfos(coord_t y, ExpoData *ed) void displayExpoInfos(coord_t y, ExpoData * ed)
{ {
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0); drawCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0);
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0); drawSwitch(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
} }
void displayExpoLine(coord_t y, ExpoData *ed) void displayExpoLine(coord_t y, ExpoData * ed)
{ {
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0); drawSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0);
if (ed->carryTrim != TRIM_ON) { if (ed->carryTrim != TRIM_ON) {
lcdDrawChar(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]); lcdDrawChar(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]);
@ -507,7 +508,7 @@ void menuModelExposAll(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH; coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH;
if (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) { if (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) { if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(0, y, ch, 0); drawSource(0, y, ch, 0);
} }
uint8_t mixCnt = 0; uint8_t mixCnt = 0;
do { do {
@ -561,7 +562,7 @@ void menuModelExposAll(uint8_t event)
} }
} }
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) { if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(0, y, ch, attr); drawSource(0, y, ch, attr);
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lcdDrawRect(EXPO_LINE_SELECT_POS, y-1, LCD_W-EXPO_LINE_SELECT_POS, 9, DOTTED); lcdDrawRect(EXPO_LINE_SELECT_POS, y-1, LCD_W-EXPO_LINE_SELECT_POS, 9, DOTTED);
} }

View file

@ -76,7 +76,7 @@ void menuModelLogicalSwitches(uint8_t event)
{ {
INCDEC_DECLARE_VARS(EE_MODEL); INCDEC_DECLARE_VARS(EE_MODEL);
MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, NUM_LOGICAL_SWITCH, { NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/ }); MENU(STR_MENULOGICALSWITCHES, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, MAX_LOGICAL_SWITCHES, { NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/ });
int k = 0; int k = 0;
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
@ -108,7 +108,7 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW name // CSW name
unsigned int sw = SWSRC_SW1+k; unsigned int sw = SWSRC_SW1+k;
putsSwitches(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && CURSOR_ON_LINE()) ? INVERS : 0)); drawSwitch(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && CURSOR_ON_LINE()) ? INVERS : 0));
// CSW func // CSW func
lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, horz==0 ? attr : 0); lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, horz==0 ? attr : 0);
@ -120,15 +120,15 @@ void menuModelLogicalSwitches(uint8_t event)
int v3_min=-1, v3_max=100; int v3_min=-1, v3_max=100;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches); INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
} }
else if (cstate == LS_FAMILY_EDGE) { else if (cstate == LS_FAMILY_EDGE) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, horz==LS_FIELD_V3 ? attr : 0); putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, horz==LS_FIELD_V3 ? attr : 0);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122; v2_min=-129; v2_max = 122;
@ -144,8 +144,8 @@ void menuModelLogicalSwitches(uint8_t event)
} }
else if (cstate == LS_FAMILY_COMP) { else if (cstate == LS_FAMILY_COMP) {
v1_val = cs->v1; v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -159,7 +159,7 @@ void menuModelLogicalSwitches(uint8_t event)
} }
else { else {
v1_val = cs->v1; v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) { if (horz == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches); INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -179,7 +179,7 @@ void menuModelLogicalSwitches(uint8_t event)
} }
// CSW AND switch // CSW AND switch
putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==LS_FIELD_ANDSW ? attr : 0); drawSwitch(CSW_4TH_COLUMN, y, cs->andsw, horz==LS_FIELD_ANDSW ? attr : 0);
// CSW duration // CSW duration
if (cs->duration > 0) if (cs->duration > 0)

View file

@ -96,7 +96,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
} }
if (tgt_idx == MAX_MIXERS) { if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1) if (x->destCh == MAX_OUTPUT_CHANNELS-1)
return false; return false;
x->destCh++; x->destCh++;
return true; return true;
@ -110,7 +110,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
else return false; else return false;
} }
else { else {
if (destCh<NUM_CHNOUT-1) x->destCh++; if (destCh<MAX_OUTPUT_CHANNELS-1) x->destCh++;
else return false; else return false;
} }
return true; return true;
@ -235,7 +235,7 @@ void menuModelMixOne(uint8_t event)
case MIX_FIELD_SOURCE: case MIX_FIELD_SOURCE:
lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE)); lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); drawSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break; break;
@ -270,6 +270,7 @@ void menuModelMixOne(uint8_t event)
#if defined(FLIGHT_MODES) #if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_MODE: case MIX_FIELD_FLIGHT_MODE:
drawFieldLabel(MIXES_2ND_COLUMN, y, STR_FLMODE);
md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr); md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break; break;
#endif #endif
@ -355,16 +356,16 @@ void displayHeaderChannelName(uint8_t ch)
} }
} }
void displayMixInfos(coord_t y, MixData *md) void displayMixInfos(coord_t y, MixData * md)
{ {
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0); drawCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0);
if (md->swtch) { if (md->swtch) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch); drawSwitch(MIX_LINE_SWITCH_POS, y, md->swtch);
} }
} }
void displayMixLine(coord_t y, MixData *md) void displayMixLine(coord_t y, MixData * md)
{ {
if (md->name[0]) if (md->name[0])
lcdDrawSizedText(MIX_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR); lcdDrawSizedText(MIX_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR);
@ -372,6 +373,13 @@ void displayMixLine(coord_t y, MixData *md)
displayMixInfos(y, md); displayMixInfos(y, md);
else else
displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes); displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes);
char cs = ' ';
if (md->speedDown || md->speedUp)
cs = 'S';
if (md->delayUp || md->delayDown)
cs = (cs == 'S' ? '*' : 'D');
lcdDrawChar(MIX_LINE_DELAY_POS, y, cs);
} }
void menuModelMixAll(uint8_t event) void menuModelMixAll(uint8_t event)
@ -527,7 +535,7 @@ void menuModelMixAll(uint8_t event)
int cur = 0; int cur = 0;
int i = 0; int i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) { for (int ch=1; ch<=MAX_OUTPUT_CHANNELS; ch++) {
MixData * md; MixData * md;
coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH; coord_t y = MENU_HEADER_HEIGHT+1+(cur-menuVerticalOffset)*FH;
if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) { if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) {
@ -554,19 +562,12 @@ void menuModelMixAll(uint8_t event)
if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0); if (mixCnt > 0) lcdDrawTextAtIndex(FW, y, STR_VMLTPX2, md->mltpx, 0);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); drawSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, RIGHT | attr | (isMixActive(i) ? BOLD : 0), 0); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, RIGHT | attr | (isMixActive(i) ? BOLD : 0), 0);
displayMixLine(y, md); displayMixLine(y, md);
char cs = ' ';
if (md->speedDown || md->speedUp)
cs = 'S';
if (md->delayUp || md->delayDown)
cs = (cs =='S' ? '*' : 'D');
lcdDrawChar(MIX_LINE_DELAY_POS, y, cs);
if (s_copyMode) { if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */ /* draw a border around the raw on selection mode (copy/move) */

View file

@ -101,7 +101,7 @@ void menuModelLimits(uint8_t event)
{ {
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
if (sub < NUM_CHNOUT) { if (sub < MAX_OUTPUT_CHANNELS) {
#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US) #if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US)
lcdDrawNumber(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, RIGHT); lcdDrawNumber(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, RIGHT);
lcdDrawText(13*FW, 0, STR_US); lcdDrawText(13*FW, 0, STR_US);
@ -110,9 +110,9 @@ void menuModelLimits(uint8_t event)
#endif #endif
} }
MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, NUM_CHNOUT+1, { NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, 0 }); MENU(STR_MENULIMITS, menuTabModel, MENU_MODEL_OUTPUTS, MAX_OUTPUT_CHANNELS+1, { NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, 0 });
if (sub<NUM_CHNOUT && menuHorizontalPosition>=0) { if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition); drawColumnHeader(STR_LIMITS_HEADERS, menuHorizontalPosition);
} }
@ -127,9 +127,9 @@ void menuModelLimits(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) { if (k==MAX_OUTPUT_CHANNELS) {
// last line available - add the "copy trim menu" line // last line available - add the "copy trim menu" line
uint8_t attr = (sub==NUM_CHNOUT) ? INVERS : 0; uint8_t attr = (sub==MAX_OUTPUT_CHANNELS) ? INVERS : 0;
lcdDrawText(CENTER_OFS, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr); lcdDrawText(CENTER_OFS, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr);
if (attr) { if (attr) {
s_editMode = 0; s_editMode = 0;

View file

@ -23,7 +23,7 @@
uint8_t g_moduleIdx; uint8_t g_moduleIdx;
void menuModelFailsafe(uint8_t event); void menuModelFailsafe(uint8_t event);
enum menuModelSetupItems { enum MenuModelSetupItems {
ITEM_MODEL_NAME, ITEM_MODEL_NAME,
ITEM_MODEL_BITMAP, ITEM_MODEL_BITMAP,
ITEM_MODEL_TIMER1, ITEM_MODEL_TIMER1,
@ -126,8 +126,8 @@ void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event)
{ {
TimerData & timer = g_model.timers[timerIdx]; TimerData & timer = g_model.timers[timerIdx];
drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1); drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1);
putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer.mode, menuHorizontalPosition==0 ? attr : 0); drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer.mode, menuHorizontalPosition==0 ? attr : 0);
putsTimer(MODEL_SETUP_3RD_COLUMN, y, timer.start, menuHorizontalPosition==1 ? attr|TIMEHOUR : TIMEHOUR, menuHorizontalPosition==2 ? attr|TIMEHOUR : TIMEHOUR); drawTimer(MODEL_SETUP_3RD_COLUMN, y, timer.start, menuHorizontalPosition==1 ? attr|TIMEHOUR : TIMEHOUR, menuHorizontalPosition==2 ? attr|TIMEHOUR : TIMEHOUR);
if (attr && menuHorizontalPosition < 0) { if (attr && menuHorizontalPosition < 0) {
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 13*FW-3, FH+1); lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 13*FW-3, FH+1);
} }
@ -250,11 +250,11 @@ int getSwitchWarningsCount()
#endif #endif
#if defined(PCBX9E) #if defined(PCBX9E)
#define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW), uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW) #define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW), uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW)
#define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|NUM_POTS : 0), uint8_t(g_model.potsWarnMode ? TITLE_ROW : HIDDEN_ROW) #define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0), uint8_t(g_model.potsWarnMode ? TITLE_ROW : HIDDEN_ROW)
#define TOPLCD_ROWS 0, #define TOPLCD_ROWS 0,
#else #else
#define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount()) #define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount())
#define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|NUM_POTS : 0) #define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0)
#define TOPLCD_ROWS #define TOPLCD_ROWS
#endif #endif
@ -266,7 +266,7 @@ void menuModelSetup(uint8_t event)
#if defined(TARANIS_INTERNAL_PPM) #if defined(TARANIS_INTERNAL_PPM)
MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0,
LABEL(Throttle), 0, 0, 0, LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule), LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS, INTERNAL_MODULE_CHANNELS_ROWS,
@ -280,7 +280,7 @@ void menuModelSetup(uint8_t event)
LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
#else #else
MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(),
NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule), LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS, INTERNAL_MODULE_CHANNELS_ROWS,
@ -451,13 +451,13 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_THROTTLE_TRACE: case ITEM_MODEL_THROTTLE_TRACE:
{ {
lcdDrawTextAlignedLeft(y, STR_TTRACE); lcdDrawTextAlignedLeft(y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_CHNOUT, isThrottleSourceAvailable); if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS, isThrottleSourceAvailable);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr; uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr) if (idx > MIXSRC_Thr)
idx += 1; idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS) if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS; idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr); drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break; break;
} }
@ -592,8 +592,8 @@ void menuModelSetup(uint8_t event)
} }
if (g_model.potsWarnMode) { if (g_model.potsWarnMode) {
coord_t x = MODEL_SETUP_2ND_COLUMN+28; coord_t x = MODEL_SETUP_2ND_COLUMN+28;
for (int i=0; i<NUM_POTS; ++i) { for (int i=0; i<NUM_POTS+NUM_SLIDERS; ++i) {
if (i<NUM_XPOTS && !IS_POT_AVAILABLE(POT1+i)) { if (i<NUM_XPOTS && !IS_POT_OR_SLIDER_AVAILABLE(POT1+i)) {
if (attr && (menuHorizontalPosition==i+1)) REPEAT_LAST_CURSOR_MOVE(); if (attr && (menuHorizontalPosition==i+1)) REPEAT_LAST_CURSOR_MOVE();
} }
else { else {
@ -627,8 +627,8 @@ void menuModelSetup(uint8_t event)
{ {
lcdDrawTextAlignedLeft(y, STR_BEEPCTR); lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
coord_t x = MODEL_SETUP_2ND_COLUMN; coord_t x = MODEL_SETUP_2ND_COLUMN;
for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS; i++) { for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS; i++) {
if (i>=POT1 && i<POT1+NUM_XPOTS && !IS_POT_AVAILABLE(i)) { if (i>=POT1 && i<POT1+NUM_XPOTS && !IS_POT_OR_SLIDER_AVAILABLE(i)) {
if (attr && menuHorizontalPosition == i) REPEAT_LAST_CURSOR_MOVE(); if (attr && menuHorizontalPosition == i) REPEAT_LAST_CURSOR_MOVE();
continue; continue;
} }

View file

@ -94,13 +94,13 @@ void onCustomFunctionsMenu(const char * result)
storageDirty(eeFlags); storageDirty(eeFlags);
} }
else if (result == STR_INSERT) { else if (result == STR_INSERT) {
memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); memmove(cfn+1, cfn, (MAX_SPECIAL_FUNCTIONS-sub-1)*sizeof(CustomFunctionData));
memset(cfn, 0, sizeof(CustomFunctionData)); memset(cfn, 0, sizeof(CustomFunctionData));
storageDirty(eeFlags); storageDirty(eeFlags);
} }
else if (result == STR_DELETE) { else if (result == STR_DELETE) {
memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); memmove(cfn, cfn+1, (MAX_SPECIAL_FUNCTIONS-sub-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); memset(&g_model.customFn[MAX_SPECIAL_FUNCTIONS-1], 0, sizeof(CustomFunctionData));
storageDirty(eeFlags); storageDirty(eeFlags);
} }
} }
@ -155,11 +155,11 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
POPUP_MENU_ADD_ITEM(STR_COPY); POPUP_MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION) if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
POPUP_MENU_ADD_ITEM(STR_PASTE); POPUP_MENU_ADD_ITEM(STR_PASTE);
if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1])) if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[MAX_SPECIAL_FUNCTIONS-1]))
POPUP_MENU_ADD_ITEM(STR_INSERT); POPUP_MENU_ADD_ITEM(STR_INSERT);
if (!CFN_EMPTY(cfn)) if (!CFN_EMPTY(cfn))
POPUP_MENU_ADD_ITEM(STR_CLEAR); POPUP_MENU_ADD_ITEM(STR_CLEAR);
for (int i=sub+1; i<NUM_CFN; i++) { for (int i=sub+1; i<MAX_SPECIAL_FUNCTIONS; i++) {
if (!CFN_EMPTY(&functions[i])) { if (!CFN_EMPTY(&functions[i])) {
POPUP_MENU_ADD_ITEM(STR_DELETE); POPUP_MENU_ADD_ITEM(STR_DELETE);
break; break;
@ -181,7 +181,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
uint8_t active = (attr && s_editMode>0); uint8_t active = (attr && s_editMode>0);
switch (j) { switch (j) {
case ITEM_CUSTOM_FUNCTIONS_SWITCH: case ITEM_CUSTOM_FUNCTIONS_SWITCH:
putsSwitches(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); drawSwitch(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) { if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) {
func = CFN_FUNC(cfn) = func+1; func = CFN_FUNC(cfn) = func+1;
@ -206,7 +206,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
case ITEM_CUSTOM_FUNCTIONS_PARAM1: case ITEM_CUSTOM_FUNCTIONS_PARAM1:
{ {
int8_t maxParam = NUM_CHNOUT-1; int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION) #if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) { if (func == FUNC_OVERRIDE_CHANNEL) {
putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr); putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr);
@ -215,7 +215,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#endif #endif
if (func == FUNC_TRAINER) { if (func == FUNC_TRAINER) {
maxParam = NUM_STICKS; maxParam = NUM_STICKS;
putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); drawSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
} }
#if defined(GVARS) #if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) { else if (func == FUNC_ADJUST_GVAR) {
@ -268,7 +268,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
} }
else if (func == FUNC_SET_TIMER) { else if (func == FUNC_SET_TIMER) {
val_max = 539*60+59; //8:59:59 val_max = 539*60+59; //8:59:59
putsTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT|TIMEHOUR, attr); drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT|TIMEHOUR, attr);
} }
else if (func == FUNC_PLAY_SOUND) { else if (func == FUNC_PLAY_SOUND) {
val_max = AU_SPECIAL_SOUND_LAST-AU_SPECIAL_SOUND_FIRST-1; val_max = AU_SPECIAL_SOUND_LAST-AU_SPECIAL_SOUND_FIRST-1;
@ -308,7 +308,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
} }
else if (func == FUNC_PLAY_VALUE) { else if (func == FUNC_PLAY_VALUE) {
val_max = MIXSRC_LAST_TELEM; val_max = MIXSRC_LAST_TELEM;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable); INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
@ -317,7 +317,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#endif #endif
else if (func == FUNC_VOLUME) { else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -350,7 +350,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
break; break;
case FUNC_ADJUST_GVAR_SOURCE: case FUNC_ADJUST_GVAR_SOURCE:
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -423,6 +423,6 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
void menuModelSpecialFunctions(uint8_t event) void menuModelSpecialFunctions(uint8_t event)
{ {
MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, NUM_CFN, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ });
return menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext); return menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext);
} }

View file

@ -226,33 +226,33 @@ void menuModelSensor(uint8_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) { if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) { if (sensor->formula == TELEM_FORMULA_CELL) {
lcdDrawTextAlignedLeft(y, STR_CELLSENSOR); lcdDrawTextAlignedLeft(y, STR_CELLSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor); sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawTextAlignedLeft(y, STR_GPSSENSOR); lcdDrawTextAlignedLeft(y, STR_GPSSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor); sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) { else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
lcdDrawTextAlignedLeft(y, STR_CURRENTSENSOR); lcdDrawTextAlignedLeft(y, STR_CURRENTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_TOTALIZE) { else if (sensor->formula == TELEM_FORMULA_TOTALIZE) {
lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE)); lcdDrawTextAlignedLeft(y, NO_INDENT(STR_SOURCE));
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
break; break;
} }
@ -284,9 +284,9 @@ void menuModelSensor(uint8_t event)
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawTextAlignedLeft(y, STR_ALTSENSOR); lcdDrawTextAlignedLeft(y, STR_ALTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor);
} }
break; break;
} }
@ -314,14 +314,14 @@ void menuModelSensor(uint8_t event)
drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1); drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1]; int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
if (attr) { if (attr) {
source = checkIncDec(event, source, -MAX_SENSORS, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); source = checkIncDec(event, source, -MAX_TELEMETRY_SENSORS, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
if (source < 0) { if (source < 0) {
lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr); lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr);
putsMixerSource(lcdNextPos, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr); drawSource(lcdNextPos, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr);
} }
else { else {
putsMixerSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr);
} }
break; break;
} }
@ -360,14 +360,14 @@ void onSensorMenu(const char *result)
{ {
int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1; int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) { if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) { if (result == STR_EDIT) {
pushMenu(menuModelSensor); pushMenu(menuModelSensor);
} }
else if (result == STR_DELETE) { else if (result == STR_DELETE) {
delTelemetryIndex(index); delTelemetryIndex(index);
index += 1; index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index)) if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1; menuVerticalPosition += 1;
else else
menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR; menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR;
@ -395,7 +395,7 @@ void menuModelTelemetryFrsky(uint8_t event)
{ {
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) { for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i); delTelemetryIndex(i);
} }
} }
@ -413,7 +413,7 @@ void menuModelTelemetryFrsky(uint8_t event)
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (menuVerticalPosition == k ? blink : 0); LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_SENSORS) { if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_TELEMETRY_SENSORS) {
int index = k-ITEM_TELEMETRY_SENSOR1; int index = k-ITEM_TELEMETRY_SENSOR1;
lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr); lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr);
lcdDrawChar(lcdLastPos, y, ':', attr); lcdDrawChar(lcdLastPos, y, ':', attr);
@ -535,9 +535,9 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_VARIO_SOURCE: case ITEM_TELEMETRY_VARIO_SOURCE:
lcdDrawTextAlignedLeft(y, STR_SOURCE); lcdDrawTextAlignedLeft(y, STR_SOURCE);
putsMixerSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr); drawSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr);
if (attr) { if (attr) {
g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
break; break;

View file

@ -25,7 +25,7 @@ vertpos_t menuVerticalPosition;
horzpos_t menuHorizontalPosition; horzpos_t menuHorizontalPosition;
int8_t s_editMode; int8_t s_editMode;
uint8_t noHighlightCounter; uint8_t noHighlightCounter;
uint8_t calibrationState; uint8_t menuCalibrationState;
int checkIncDecSelection = 0; int checkIncDecSelection = 0;
#if defined(AUTOSWITCH) #if defined(AUTOSWITCH)
@ -35,7 +35,7 @@ swsrc_t checkIncDecMovedSwitch(swsrc_t val)
swsrc_t swtch = getMovedSwitch(); swsrc_t swtch = getMovedSwitch();
if (swtch) { if (swtch) {
div_t info = switchInfo(swtch); div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) { if (IS_CONFIG_TOGGLE(info.quot)) {
if (info.rem != 0) { if (info.rem != 0) {
val = (val == swtch ? swtch-2 : swtch); val = (val == swtch ? swtch-2 : swtch);
} }
@ -82,7 +82,7 @@ void onSourceLongEnterPress(const char * result)
else if (result == STR_MENU_GVARS) else if (result == STR_MENU_GVARS)
checkIncDecSelection = MIXSRC_FIRST_GVAR; checkIncDecSelection = MIXSRC_FIRST_GVAR;
else if (result == STR_MENU_TELEMETRY) { else if (result == STR_MENU_TELEMETRY) {
for (int i = 0; i < MAX_SENSORS; i++) { for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i]; TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) { if (sensor->isAvailable()) {
checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i; checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i;
@ -99,7 +99,7 @@ void onSwitchLongEnterPress(const char *result)
else if (result == STR_MENU_TRIMS) else if (result == STR_MENU_TRIMS)
checkIncDecSelection = SWSRC_FIRST_TRIM; checkIncDecSelection = SWSRC_FIRST_TRIM;
else if (result == STR_MENU_LOGICAL_SWITCHES) else if (result == STR_MENU_LOGICAL_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, NUM_LOGICAL_SWITCH, isLogicalSwitchAvailable); checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, MAX_LOGICAL_SWITCHES, isLogicalSwitchAvailable);
else if (result == STR_MENU_OTHER) else if (result == STR_MENU_OTHER)
checkIncDecSelection = SWSRC_ON; checkIncDecSelection = SWSRC_ON;
else if (result == STR_MENU_INVERT) else if (result == STR_MENU_INVERT)
@ -267,7 +267,7 @@ int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int
} }
if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) { if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) {
for (int i = 0; i < MAX_SENSORS; i++) { for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i]; TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) { if (sensor->isAvailable()) {
POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY); POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY);
@ -291,7 +291,7 @@ int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int
if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) { if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) { for (int i = 0; i < MAX_LOGICAL_SWITCHES; i++) {
if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) { if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) {
POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES); POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES);
break; break;
@ -374,7 +374,7 @@ void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc
break; break;
} }
if (!calibrationState && cc != curr) { if (!menuCalibrationState && cc != curr) {
chainMenu((MenuHandlerFunc)pgm_read_adr(&menuTab[cc])); chainMenu((MenuHandlerFunc)pgm_read_adr(&menuTab[cc]));
} }
@ -387,8 +387,7 @@ void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc
DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);
switch(event) switch (event) {
{
case EVT_ENTRY: case EVT_ENTRY:
menuEntryTime = get_tmr10ms(); menuEntryTime = get_tmr10ms();
s_editMode = EDIT_MODE_INIT; s_editMode = EDIT_MODE_INIT;

View file

@ -51,14 +51,14 @@ void showMessageBox(const char * title)
lcdRefresh(); lcdRefresh();
} }
const pm_uchar asterisk_lbm[] PROGMEM = { const pm_uchar ASTERISK_BITMAP[] PROGMEM = {
#include "asterisk.lbm" #include "asterisk.lbm"
}; };
void drawAlertBox(const char * title, const char * text, const char * action) void drawAlertBox(const char * title, const char * text, const char * action)
{ {
lcdClear(); lcdClear();
lcdDrawBitmap(0, 0, asterisk_lbm); lcdDrawBitmap(0, 0, ASTERISK_BITMAP);
#define MESSAGE_LCD_OFFSET 60 #define MESSAGE_LCD_OFFSET 60

View file

@ -0,0 +1,67 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _POPUPS_H_
#define _POPUPS_H_
#define MENU_X 30
#define MENU_Y 16
#define MENU_W LCD_W-(2*MENU_X)
#define WARNING_LINE_LEN 32
#define WARNING_LINE_X 16
#define WARNING_LINE_Y 3*FH
void drawMessageBox(const char * title);
void showMessageBox(const char * title);
void runPopupWarning(uint8_t event);
extern void (*popupFunc)(uint8_t event);
extern int16_t warningInputValue;
extern int16_t warningInputValueMin;
extern int16_t warningInputValueMax;
extern uint8_t warningInfoFlags;
#define DISPLAY_WARNING (*popupFunc)
#define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning)
#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max)
#define WARNING_INFO_FLAGS warningInfoFlags
#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags)
#define NAVIGATION_MENUS
#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0)
#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0)
#define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 6
#define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s)
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define POPUP_MENU_SET_BSS_FLAG()
extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset;
enum {
MENU_OFFSET_INTERNAL,
MENU_OFFSET_EXTERNAL
};
extern uint8_t popupMenuOffsetType;
const char * runPopupMenu(uint8_t event);
extern void (*popupMenuHandler)(const char * result);
#endif // _POPUPS_H_

View file

@ -36,10 +36,9 @@ enum CalibrationState {
void drawPotsBars() void drawPotsBars()
{ {
// Optimization by Mike Blandford // Optimization by Mike Blandford
uint8_t x, i, len ; // declare temporary variables for (uint8_t x=LCD_W/2-(NUM_POTS+NUM_SLIDERS/2)*BAR_SPACING+BAR_SPACING/2, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; x+=BAR_SPACING, i++) {
for (x=LCD_W/2-(NUM_POTS/2)*BAR_SPACING+BAR_SPACING/2, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS; x+=BAR_SPACING, i++) { if (IS_POT_OR_SLIDER_AVAILABLE(i)) {
if (IS_POT_AVAILABLE(i)) { uint8_t len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
V_BAR(x, LCD_H-8, len); V_BAR(x, LCD_H-8, len);
putsStickName(x-2, LCD_H-6, i, TINSIZE); putsStickName(x-2, LCD_H-6, i, TINSIZE);
} }
@ -48,7 +47,7 @@ void drawPotsBars()
void menuCommonCalib(uint8_t event) 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 for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high vals for sticks and trims
int16_t vt = anaIn(i); int16_t vt = anaIn(i);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]); reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]); reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
@ -89,7 +88,7 @@ void menuCommonCalib(uint8_t event)
} }
} }
calibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating menuCalibrationState = reusableBuffer.calib.state; // make sure we don't scroll while calibrating
switch (event) { switch (event) {
case EVT_ENTRY: case EVT_ENTRY:
@ -115,7 +114,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS); lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
reusableBuffer.calib.loVals[i] = 15000; reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000; reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1; reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
@ -132,7 +131,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS); lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE); lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) { if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i]; g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i]; int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
@ -202,14 +201,14 @@ void menuRadioCalibration(uint8_t event)
check_simple(STR_MENUCALIBRATION, event, MENU_RADIO_CALIBRATION, menuTabGeneral, DIM(menuTabGeneral), 0); check_simple(STR_MENUCALIBRATION, event, MENU_RADIO_CALIBRATION, menuTabGeneral, DIM(menuTabGeneral), 0);
menuCommonCalib(READ_ONLY() ? 0 : event); menuCommonCalib(READ_ONLY() ? 0 : event);
if (menuEvent) { if (menuEvent) {
calibrationState = CALIB_START; menuCalibrationState = CALIB_START;
} }
} }
void menuFirstCalib(uint8_t event) void menuFirstCalib(uint8_t event)
{ {
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) { if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) {
calibrationState = CALIB_START; menuCalibrationState = CALIB_START;
chainMenu(menuMainView); chainMenu(menuMainView);
} }
else { else {

View file

@ -22,11 +22,11 @@
void menuRadioDiagAnalogs(uint8_t event) void menuRadioDiagAnalogs(uint8_t event)
{ {
SIMPLE_MENU(STR_MENUANA, menuTabGeneral, MENU_RADIO_DIAG_ANALOGS, 0); SIMPLE_MENU(STR_MENU_RADIO_ANALOGS, menuTabGeneral, MENU_RADIO_ANALOGS_TEST, 0);
STICK_SCROLL_DISABLE(); STICK_SCROLL_DISABLE();
for (int i=0; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? LCD_W/2 + FW : 0; uint8_t x = i&1 ? LCD_W/2 + FW : 0;
lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2); lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2);

View file

@ -20,31 +20,31 @@
#include "opentx.h" #include "opentx.h"
void displayKeyState(uint8_t x, uint8_t y, EnumKeys key) void displayKeyState(uint8_t x, uint8_t y, uint8_t key)
{ {
uint8_t t = switchState(key); uint8_t t = keyState(key);
lcdDrawChar(x, y, t+'0', t ? INVERS : 0); lcdDrawChar(x, y, t+'0', t ? INVERS : 0);
} }
void menuRadioDiagKeys(uint8_t event) void menuRadioDiagKeys(uint8_t event)
{ {
SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, MENU_RADIO_DIAG_KEYS, 1); SIMPLE_MENU(STR_MENU_RADIO_SWITCHES, menuTabGeneral, MENU_RADIO_SWITCHES_TEST, 1);
lcdDrawText(14*FW, MENU_HEADER_HEIGHT+2*FH, STR_VTRIM); lcdDrawText(14*FW, MENU_HEADER_HEIGHT+2*FH, STR_VTRIM);
for(uint8_t i=0; i<9; i++) { for (uint8_t i=0; i<9; i++) {
coord_t y; coord_t y;
if (i<8) { if (i<8) {
y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2); y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0); if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i)); displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
} }
if (i<6) { if (i<6) {
y = i*FH+MENU_HEADER_HEIGHT+FH; y = i*FH+MENU_HEADER_HEIGHT+FH;
lcdDrawTextAtIndex(0, y, STR_VKEYS, (5-i), 0); lcdDrawTextAtIndex(0, y, STR_VKEYS, (5-i), 0);
displayKeyState(5*FW+2, y, (EnumKeys)(KEY_MENU+(5-i))); displayKeyState(5*FW+2, y, KEY_MENU+(5-i));
} }
} }
} }

View file

@ -21,43 +21,43 @@
#include "opentx.h" #include "opentx.h"
enum menuRadioHwItems { enum menuRadioHwItems {
ITEM_SETUP_HW_LABEL_STICKS, ITEM_RADIO_HARDWARE_LABEL_STICKS,
ITEM_SETUP_HW_STICK1, ITEM_RADIO_HARDWARE_STICK1,
ITEM_SETUP_HW_STICK2, ITEM_RADIO_HARDWARE_STICK2,
ITEM_SETUP_HW_STICK3, ITEM_RADIO_HARDWARE_STICK3,
ITEM_SETUP_HW_STICK4, ITEM_RADIO_HARDWARE_STICK4,
ITEM_SETUP_HW_LABEL_POTS, ITEM_RADIO_HARDWARE_LABEL_POTS,
ITEM_SETUP_HW_POT1, ITEM_RADIO_HARDWARE_POT1,
ITEM_SETUP_HW_POT2, ITEM_RADIO_HARDWARE_POT2,
CASE_PCBX9E_PCBX9DP(ITEM_SETUP_HW_POT3) CASE_PCBX9E_PCBX9DP(ITEM_RADIO_HARDWARE_POT3)
CASE_PCBX9E(ITEM_SETUP_HW_POT4) CASE_PCBX9E(ITEM_RADIO_HARDWARE_POT4)
ITEM_SETUP_HW_LS, ITEM_RADIO_HARDWARE_LS,
ITEM_SETUP_HW_RS, ITEM_RADIO_HARDWARE_RS,
CASE_PCBX9E(ITEM_SETUP_HW_LS2) CASE_PCBX9E(ITEM_RADIO_HARDWARE_LS2)
CASE_PCBX9E(ITEM_SETUP_HW_RS2) CASE_PCBX9E(ITEM_RADIO_HARDWARE_RS2)
ITEM_SETUP_HW_LABEL_SWITCHES, ITEM_RADIO_HARDWARE_LABEL_SWITCHES,
ITEM_SETUP_HW_SA, ITEM_RADIO_HARDWARE_SA,
ITEM_SETUP_HW_SB, ITEM_RADIO_HARDWARE_SB,
ITEM_SETUP_HW_SC, ITEM_RADIO_HARDWARE_SC,
ITEM_SETUP_HW_SD, ITEM_RADIO_HARDWARE_SD,
ITEM_SETUP_HW_SE, ITEM_RADIO_HARDWARE_SE,
ITEM_SETUP_HW_SF, ITEM_RADIO_HARDWARE_SF,
ITEM_SETUP_HW_SG, ITEM_RADIO_HARDWARE_SG,
ITEM_SETUP_HW_SH, ITEM_RADIO_HARDWARE_SH,
CASE_PCBX9E(ITEM_SETUP_HW_SI) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SI)
CASE_PCBX9E(ITEM_SETUP_HW_SJ) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SJ)
CASE_PCBX9E(ITEM_SETUP_HW_SK) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SK)
CASE_PCBX9E(ITEM_SETUP_HW_SL) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SL)
CASE_PCBX9E(ITEM_SETUP_HW_SM) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SM)
CASE_PCBX9E(ITEM_SETUP_HW_SN) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SN)
CASE_PCBX9E(ITEM_SETUP_HW_SO) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SO)
CASE_PCBX9E(ITEM_SETUP_HW_SP) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SP)
CASE_PCBX9E(ITEM_SETUP_HW_SQ) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SQ)
CASE_PCBX9E(ITEM_SETUP_HW_SR) CASE_PCBX9E(ITEM_RADIO_HARDWARE_SR)
CASE_PCBX9E(ITEM_SETUP_HW_BLUETOOTH) CASE_PCBX9E(ITEM_RADIO_HARDWARE_BLUETOOTH)
ITEM_SETUP_HW_UART3_MODE, ITEM_RADIO_HARDWARE_UART3_MODE,
ITEM_SETUP_HW_JITTER_FILTER, ITEM_RADIO_HARDWARE_JITTER_FILTER,
ITEM_SETUP_HW_MAX ITEM_RADIO_HARDWARE_MAX
}; };
#define HW_SETTINGS_COLUMN 15*FW #define HW_SETTINGS_COLUMN 15*FW
@ -83,7 +83,7 @@ enum menuRadioHwItems {
void menuRadioHardware(uint8_t event) void menuRadioHardware(uint8_t event)
{ {
MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_SETUP_HW_MAX, { LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, BLUETOOTH_ROWS 0 }); MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, BLUETOOTH_ROWS 0 });
uint8_t sub = menuVerticalPosition; uint8_t sub = menuVerticalPosition;
@ -96,17 +96,17 @@ void menuRadioHardware(uint8_t event)
} }
LcdFlags attr = (sub == k ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); LcdFlags attr = (sub == k ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
switch (k) { switch (k) {
case ITEM_SETUP_HW_LABEL_STICKS: case ITEM_RADIO_HARDWARE_LABEL_STICKS:
lcdDrawTextAlignedLeft(y, STR_STICKS); lcdDrawTextAlignedLeft(y, STR_STICKS);
break; break;
case ITEM_SETUP_HW_STICK1: case ITEM_RADIO_HARDWARE_STICK1:
case ITEM_SETUP_HW_STICK2: case ITEM_RADIO_HARDWARE_STICK2:
case ITEM_SETUP_HW_STICK3: case ITEM_RADIO_HARDWARE_STICK3:
case ITEM_SETUP_HW_STICK4: case ITEM_RADIO_HARDWARE_STICK4:
case ITEM_SETUP_HW_LS: case ITEM_RADIO_HARDWARE_LS:
case ITEM_SETUP_HW_RS: case ITEM_RADIO_HARDWARE_RS:
{ {
int idx = (k<=ITEM_SETUP_HW_STICK4 ? k-ITEM_SETUP_HW_STICK1 : k-ITEM_SETUP_HW_LS+MIXSRC_SLIDER1-MIXSRC_Rud); int idx = (k<=ITEM_RADIO_HARDWARE_STICK4 ? k-ITEM_RADIO_HARDWARE_STICK1 : k-ITEM_RADIO_HARDWARE_LS+MIXSRC_SLIDER1-MIXSRC_Rud);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, idx+1, 0); lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, idx+1, 0);
if (ZEXIST(g_eeGeneral.anaNames[idx]) || attr) if (ZEXIST(g_eeGeneral.anaNames[idx]) || attr)
editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, event, attr); editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, event, attr);
@ -115,10 +115,10 @@ void menuRadioHardware(uint8_t event)
break; break;
} }
#if defined(PCBX9E) #if defined(PCBX9E)
case ITEM_SETUP_HW_LS2: case ITEM_RADIO_HARDWARE_LS2:
case ITEM_SETUP_HW_RS2: case ITEM_RADIO_HARDWARE_RS2:
{ {
int idx = k - ITEM_SETUP_HW_LS2; int idx = k - ITEM_RADIO_HARDWARE_LS2;
uint8_t mask = (0x01 << idx); uint8_t mask = (0x01 << idx);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+NUM_XPOTS+2+idx+1, menuHorizontalPosition < 0 ? attr : 0); lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+NUM_XPOTS+2+idx+1, menuHorizontalPosition < 0 ? attr : 0);
if (ZEXIST(g_eeGeneral.anaNames[NUM_STICKS+NUM_XPOTS+2+idx]) || (attr && menuHorizontalPosition == 0)) if (ZEXIST(g_eeGeneral.anaNames[NUM_STICKS+NUM_XPOTS+2+idx]) || (attr && menuHorizontalPosition == 0))
@ -132,19 +132,19 @@ void menuRadioHardware(uint8_t event)
break; break;
} }
#endif #endif
case ITEM_SETUP_HW_LABEL_POTS: case ITEM_RADIO_HARDWARE_LABEL_POTS:
lcdDrawTextAlignedLeft(y, STR_POTS); lcdDrawTextAlignedLeft(y, STR_POTS);
break; break;
case ITEM_SETUP_HW_POT1: case ITEM_RADIO_HARDWARE_POT1:
case ITEM_SETUP_HW_POT2: case ITEM_RADIO_HARDWARE_POT2:
#if defined(PCBX9DP) || defined(PCBX9E) #if defined(PCBX9DP) || defined(PCBX9E)
case ITEM_SETUP_HW_POT3: case ITEM_RADIO_HARDWARE_POT3:
#endif #endif
#if defined(PCBX9E) #if defined(PCBX9E)
case ITEM_SETUP_HW_POT4: case ITEM_RADIO_HARDWARE_POT4:
#endif #endif
{ {
int idx = k - ITEM_SETUP_HW_POT1; int idx = k - ITEM_RADIO_HARDWARE_POT1;
uint8_t shift = (2*idx); uint8_t shift = (2*idx);
uint8_t mask = (0x03 << shift); uint8_t mask = (0x03 << shift);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+idx+1, menuHorizontalPosition < 0 ? attr : 0); lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+idx+1, menuHorizontalPosition < 0 ? attr : 0);
@ -158,31 +158,31 @@ void menuRadioHardware(uint8_t event)
g_eeGeneral.potsConfig |= (potType << shift); g_eeGeneral.potsConfig |= (potType << shift);
break; break;
} }
case ITEM_SETUP_HW_LABEL_SWITCHES: case ITEM_RADIO_HARDWARE_LABEL_SWITCHES:
lcdDrawTextAlignedLeft(y, STR_SWITCHES); lcdDrawTextAlignedLeft(y, STR_SWITCHES);
break; break;
case ITEM_SETUP_HW_SA: case ITEM_RADIO_HARDWARE_SA:
case ITEM_SETUP_HW_SB: case ITEM_RADIO_HARDWARE_SB:
case ITEM_SETUP_HW_SC: case ITEM_RADIO_HARDWARE_SC:
case ITEM_SETUP_HW_SD: case ITEM_RADIO_HARDWARE_SD:
case ITEM_SETUP_HW_SE: case ITEM_RADIO_HARDWARE_SE:
case ITEM_SETUP_HW_SF: case ITEM_RADIO_HARDWARE_SF:
case ITEM_SETUP_HW_SG: case ITEM_RADIO_HARDWARE_SG:
case ITEM_SETUP_HW_SH: case ITEM_RADIO_HARDWARE_SH:
#if defined(PCBX9E) #if defined(PCBX9E)
case ITEM_SETUP_HW_SI: case ITEM_RADIO_HARDWARE_SI:
case ITEM_SETUP_HW_SJ: case ITEM_RADIO_HARDWARE_SJ:
case ITEM_SETUP_HW_SK: case ITEM_RADIO_HARDWARE_SK:
case ITEM_SETUP_HW_SL: case ITEM_RADIO_HARDWARE_SL:
case ITEM_SETUP_HW_SM: case ITEM_RADIO_HARDWARE_SM:
case ITEM_SETUP_HW_SN: case ITEM_RADIO_HARDWARE_SN:
case ITEM_SETUP_HW_SO: case ITEM_RADIO_HARDWARE_SO:
case ITEM_SETUP_HW_SP: case ITEM_RADIO_HARDWARE_SP:
case ITEM_SETUP_HW_SQ: case ITEM_RADIO_HARDWARE_SQ:
case ITEM_SETUP_HW_SR: case ITEM_RADIO_HARDWARE_SR:
#endif #endif
{ {
int index = k-ITEM_SETUP_HW_SA; int index = k-ITEM_RADIO_HARDWARE_SA;
int config = SWITCH_CONFIG(index); int config = SWITCH_CONFIG(index);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH-MIXSRC_Rud+index+1, menuHorizontalPosition < 0 ? attr : 0); lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH-MIXSRC_Rud+index+1, menuHorizontalPosition < 0 ? attr : 0);
if (ZEXIST(g_eeGeneral.switchNames[index]) || (attr && menuHorizontalPosition == 0)) if (ZEXIST(g_eeGeneral.switchNames[index]) || (attr && menuHorizontalPosition == 0))
@ -197,7 +197,7 @@ void menuRadioHardware(uint8_t event)
break; break;
} }
#if defined(PCBX9E) #if defined(PCBX9E)
case ITEM_SETUP_HW_BLUETOOTH: case ITEM_RADIO_HARDWARE_BLUETOOTH:
lcdDrawTextAlignedLeft(y, "Bluetooth"); lcdDrawTextAlignedLeft(y, "Bluetooth");
drawCheckBox(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 0); drawCheckBox(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 0);
if (attr && menuHorizontalPosition == 0) { if (attr && menuHorizontalPosition == 0) {
@ -206,13 +206,13 @@ void menuRadioHardware(uint8_t event)
editName(HW_SETTINGS_COLUMN+5*FW, y, g_eeGeneral.bluetoothName, LEN_BLUETOOTH_NAME, event, menuHorizontalPosition == 1 ? attr : 0); editName(HW_SETTINGS_COLUMN+5*FW, y, g_eeGeneral.bluetoothName, LEN_BLUETOOTH_NAME, event, menuHorizontalPosition == 1 ? attr : 0);
break; break;
#endif #endif
case ITEM_SETUP_HW_UART3_MODE: case ITEM_RADIO_HARDWARE_UART3_MODE:
g_eeGeneral.serial2Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.serial2Mode, 0, UART_MODE_MAX, attr, event); g_eeGeneral.serial2Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.serial2Mode, 0, UART_MODE_MAX, attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL()); serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
} }
break; break;
case ITEM_SETUP_HW_JITTER_FILTER: case ITEM_RADIO_HARDWARE_JITTER_FILTER:
{ {
uint8_t b = 1-g_eeGeneral.jitterFilter; uint8_t b = 1-g_eeGeneral.jitterFilter;
g_eeGeneral.jitterFilter = 1 - editCheckBox(b, HW_SETTINGS_COLUMN, y, STR_JITTER_FILTER, attr, event); g_eeGeneral.jitterFilter = 1 - editCheckBox(b, HW_SETTINGS_COLUMN, y, STR_JITTER_FILTER, attr, event);

View file

@ -250,7 +250,7 @@ void menuRadioSdManager(event_t _event)
int index = menuVerticalPosition-menuVerticalOffset; int index = menuVerticalPosition-menuVerticalOffset;
switch(_event) { switch (_event) {
case EVT_ENTRY: case EVT_ENTRY:
f_chdir(ROOT_PATH); f_chdir(ROOT_PATH);
REFRESH_FILES(); REFRESH_FILES();
@ -366,7 +366,7 @@ void menuRadioSdManager(event_t _event)
reusableBuffer.sdmanager.count = 0; reusableBuffer.sdmanager.count = 0;
FRESULT res = f_opendir(&dir, "."); /* Open the directory */ FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) { if (res == FR_OK) {
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
@ -384,8 +384,8 @@ void menuRadioSdManager(event_t _event)
bool isfile = !(fno.fattrib & AM_DIR); bool isfile = !(fno.fattrib & AM_DIR);
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
for (int i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
char *line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) {
if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i)); if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
@ -397,7 +397,7 @@ void menuRadioSdManager(event_t _event)
} }
else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) {
for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) { for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) {
char *line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { 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); 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[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
@ -427,7 +427,7 @@ void menuRadioSdManager(event_t _event)
reusableBuffer.sdmanager.offset = menuVerticalOffset; reusableBuffer.sdmanager.offset = menuVerticalOffset;
for (int i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
lcdNextPos = 0; lcdNextPos = 0;
LcdFlags attr = (index == i ? INVERS : 0); LcdFlags attr = (index == i ? INVERS : 0);

View file

@ -42,7 +42,7 @@ const pm_uchar sticks[] PROGMEM = {
#define CASE_SPLASH_PARAM(x) #define CASE_SPLASH_PARAM(x)
#endif #endif
enum menuRadioSetupItems { enum MenuRadioSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE) CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME) CASE_RTCLOCK(ITEM_SETUP_TIME)
ITEM_SETUP_BATTERY_CALIB, ITEM_SETUP_BATTERY_CALIB,
@ -123,13 +123,13 @@ void menuRadioSetup(uint8_t event)
int sub = menuVerticalPosition; int sub = menuVerticalPosition;
for (unsigned int i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i + menuVerticalOffset;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
uint8_t attr = (sub == k ? blink : 0); uint8_t attr = (sub == k ? blink : 0);
switch(k) { switch (k) {
case ITEM_SETUP_DATE: case ITEM_SETUP_DATE:
lcdDrawTextAlignedLeft(y, STR_DATE); lcdDrawTextAlignedLeft(y, STR_DATE);
lcdDrawChar(RADIO_SETUP_DATE_COLUMN, y, '-'); lcdDrawChar(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-'); lcdDrawChar(RADIO_SETUP_DATE_COLUMN, y, '-'); lcdDrawChar(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-');
@ -183,8 +183,9 @@ void menuRadioSetup(uint8_t event)
} }
} }
if (attr && menuHorizontalPosition < 0) lcdDrawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); if (attr && menuHorizontalPosition < 0) lcdDrawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
if (attr && checkIncDec_Ret) if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break; break;
case ITEM_SETUP_BATTERY_CALIB: case ITEM_SETUP_BATTERY_CALIB:

View file

@ -20,62 +20,13 @@
#include "opentx.h" #include "opentx.h"
void backupEeprom()
{
char filename[60];
uint8_t buffer[1024];
FIL file;
lcdClear();
drawProgressBar(STR_WRITING);
// reset unexpectedShutdown to prevent warning when user restores EEPROM backup
g_eeGeneral.unexpectedShutdown = 0;
storageDirty(EE_GENERAL);
storageCheck(true);
// create the directory if needed...
const char * error = sdCheckAndCreateDirectory(EEPROMS_PATH);
if (error) {
POPUP_WARNING(error);
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;
eepromReadBlock(buffer, i, 1024);
f_write(&file, buffer, 1024, &count);
updateProgressBar(i, EESIZE);
SIMU_SLEEP(100/*ms*/);
}
f_close(&file);
//set back unexpectedShutdown
g_eeGeneral.unexpectedShutdown = 1;
storageDirty(EE_GENERAL);
storageCheck(true);
}
void menuRadioVersion(uint8_t event) void menuRadioVersion(uint8_t event)
{ {
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
showMessageBox(STR_STORAGE_FORMAT); showMessageBox(STR_STORAGE_FORMAT);
storageEraseAll(false); storageEraseAll(false);
#if !defined(SIMU)
NVIC_SystemReset(); NVIC_SystemReset();
#else
exit(0);
#endif
} }
if (event == EVT_ENTRY) { if (event == EVT_ENTRY) {
@ -93,7 +44,7 @@ void menuRadioVersion(uint8_t event)
lcdDrawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID); lcdDrawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID);
if (event == EVT_KEY_LONG(KEY_ENTER)) { if (event == EVT_KEY_LONG(KEY_ENTER)) {
backupEeprom(); eepromBackup();
} }
else if (event == EVT_KEY_LONG(KEY_MENU)) { else if (event == EVT_KEY_LONG(KEY_MENU)) {
POPUP_CONFIRMATION(STR_CONFIRMRESET); POPUP_CONFIRMATION(STR_CONFIRMRESET);

View file

@ -39,7 +39,7 @@
#define TIMERS_H 25 #define TIMERS_H 25
#define TIMERS_R 193 #define TIMERS_R 193
#define REBOOT_X (LCD_W-FW) #define REBOOT_X (LCD_W-FW)
#define VSWITCH_X(i) (((i>=NUM_LOGICAL_SWITCH*3/4) ? BITMAP_X+28 : ((i>=NUM_LOGICAL_SWITCH/2) ? BITMAP_X+25 : ((i>=NUM_LOGICAL_SWITCH/4) ? 21 : 18))) + 3*i) #define VSWITCH_X(i) (((i>=MAX_LOGICAL_SWITCHES*3/4) ? BITMAP_X+28 : ((i>=MAX_LOGICAL_SWITCHES/2) ? BITMAP_X+25 : ((i>=MAX_LOGICAL_SWITCHES/4) ? 21 : 18))) + 3*i)
#define VSWITCH_Y (LCD_H-9) #define VSWITCH_Y (LCD_H-9)
#define TRIM_LH_X (32+9) #define TRIM_LH_X (32+9)
#define TRIM_LV_X 10 #define TRIM_LV_X 10
@ -161,7 +161,7 @@ void displayTrims(uint8_t phase)
void drawSliders() void drawSliders()
{ {
for (uint8_t i=NUM_STICKS; i<NUM_STICKS+NUM_POTS; i++) { for (uint8_t i=NUM_STICKS; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
#if defined(PCBX9E) #if defined(PCBX9E)
if (i < SLIDER1) continue; // TODO change and display more values if (i < SLIDER1) continue; // TODO change and display more values
coord_t x = ((i==SLIDER1 || i==SLIDER3) ? 3 : LCD_W-5); coord_t x = ((i==SLIDER1 || i==SLIDER3) ? 3 : LCD_W-5);
@ -220,7 +220,7 @@ void displayTopBar()
altitude_icon_x = batt_icon_x+7*FW+3; altitude_icon_x = batt_icon_x+7*FW+3;
if (g_model.frsky.voltsSource) { if (g_model.frsky.voltsSource) {
uint8_t item = g_model.frsky.voltsSource-1; uint8_t item = g_model.frsky.voltsSource-1;
if (item < MAX_SENSORS) { if (item < MAX_TELEMETRY_SENSORS) {
TelemetryItem & voltsItem = telemetryItems[item]; TelemetryItem & voltsItem = telemetryItems[item];
if (voltsItem.isAvailable()) { if (voltsItem.isAvailable()) {
putsTelemetryChannelValue(batt_icon_x+7*FW+2, BAR_Y+1, item, voltsItem.value, LEFT); putsTelemetryChannelValue(batt_icon_x+7*FW+2, BAR_Y+1, item, voltsItem.value, LEFT);
@ -232,7 +232,7 @@ void displayTopBar()
/* Altitude */ /* Altitude */
if (g_model.frsky.altitudeSource) { if (g_model.frsky.altitudeSource) {
uint8_t item = g_model.frsky.altitudeSource-1; uint8_t item = g_model.frsky.altitudeSource-1;
if (item < MAX_SENSORS) { if (item < MAX_TELEMETRY_SENSORS) {
TelemetryItem & altitudeItem = telemetryItems[item]; TelemetryItem & altitudeItem = telemetryItems[item];
if (altitudeItem.isAvailable()) { if (altitudeItem.isAvailable()) {
LCD_ICON(altitude_icon_x, BAR_Y, ICON_ALTITUDE); LCD_ICON(altitude_icon_x, BAR_Y, ICON_ALTITUDE);
@ -289,7 +289,7 @@ void displayTopBar()
LCD_ICON(BAR_VOLUME_X, BAR_Y, ICON_SPEAKER3); LCD_ICON(BAR_VOLUME_X, BAR_Y, ICON_SPEAKER3);
/* RTC time */ /* RTC time */
putsRtcTime(BAR_TIME_X, BAR_Y+1, LEFT|TIMEBLINK); drawRtcTime(BAR_TIME_X, BAR_Y+1, LEFT|TIMEBLINK);
/* The background */ /* The background */
lcdDrawFilledRect(BAR_X, BAR_Y, BAR_W, BAR_H, SOLID, FILL_WHITE|GREY(12)|ROUND); lcdDrawFilledRect(BAR_X, BAR_Y, BAR_W, BAR_H, SOLID, FILL_WHITE|GREY(12)|ROUND);
@ -315,9 +315,9 @@ void displayTimers()
lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE); lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE);
} }
else { else {
putsTimerMode(TIMERS_X, y-7, timerData.mode, SMLSIZE); drawTimerMode(TIMERS_X, y-7, timerData.mode, SMLSIZE);
} }
putsTimer(TIMERS_X, y, timerState.val, TIMEHOUR|MIDSIZE|LEFT, TIMEHOUR|MIDSIZE|LEFT); drawTimer(TIMERS_X, y, timerState.val, TIMEHOUR|MIDSIZE|LEFT, TIMEHOUR|MIDSIZE|LEFT);
if (timerData.persistent) { if (timerData.persistent) {
lcdDrawChar(TIMERS_R, y+1, 'P', SMLSIZE); lcdDrawChar(TIMERS_R, y+1, 'P', SMLSIZE);
} }
@ -542,7 +542,7 @@ void menuMainView(uint8_t event)
if (SWITCH_EXISTS(i)) { if (SWITCH_EXISTS(i)) {
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i); getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3)); getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
putsSwitches((g_model.view == VIEW_INPUTS) ? (index<4 ? 8*FW+1 : 23*FW+2) : (index<4 ? 3*FW+1 : 8*FW-2), (index%4)*FH+3*FH, sw, 0); drawSwitch((g_model.view == VIEW_INPUTS) ? (index<4 ? 8*FW+1 : 23*FW+2) : (index<4 ? 3*FW+1 : 8*FW-2), (index%4)*FH+3*FH, sw, 0);
index++; index++;
} }
} }

View file

@ -48,23 +48,23 @@ void menuStatisticsView(uint8_t event)
// Session and Total timers // Session and Total timers
lcdDrawText(STATS_1ST_COLUMN, FH*1+1, "SES", BOLD); lcdDrawText(STATS_1ST_COLUMN, FH*1+1, "SES", BOLD);
putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*1+1, sessionTimer, 0, 0); drawTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*1+1, sessionTimer, 0, 0);
lcdDrawText(STATS_1ST_COLUMN, FH*2+1, "TOT", BOLD); lcdDrawText(STATS_1ST_COLUMN, FH*2+1, "TOT", BOLD);
putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*2+1, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0); drawTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*2+1, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0);
// Throttle special timers // Throttle special timers
lcdDrawText(STATS_2ND_COLUMN, FH*0+1, "THR", BOLD); lcdDrawText(STATS_2ND_COLUMN, FH*0+1, "THR", BOLD);
putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*0+1, s_timeCumThr, 0, 0); drawTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*0+1, s_timeCumThr, 0, 0);
lcdDrawText(STATS_2ND_COLUMN, FH*1+1, "TH%", BOLD); lcdDrawText(STATS_2ND_COLUMN, FH*1+1, "TH%", BOLD);
putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*1+1, s_timeCum16ThrP/16, 0, 0); drawTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*1+1, s_timeCum16ThrP/16, 0, 0);
// Timers // Timers
for (int i=0; i<TIMERS; i++) { for (int i=0; i<TIMERS; i++) {
drawStringWithIndex(STATS_3RD_COLUMN, FH*i+1, "TM", i+1, BOLD); drawStringWithIndex(STATS_3RD_COLUMN, FH*i+1, "TM", i+1, BOLD);
if (timersStates[i].val > 3600) if (timersStates[i].val > 3600)
putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, TIMEHOUR, 0); drawTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, TIMEHOUR, 0);
else else
putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, 0, 0); drawTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, 0, 0);
} }
#if defined(THRTRACE) #if defined(THRTRACE)
@ -228,7 +228,7 @@ void menuTraceBuffer(uint8_t event)
if (te) { if (te) {
//time //time
putstime_t tme = te->time % SECS_PER_DAY; putstime_t tme = te->time % SECS_PER_DAY;
putsTimer(4*FW, y, tme, TIMEHOUR|LEFT, TIMEHOUR|LEFT); drawTimer(4*FW, y, tme, TIMEHOUR|LEFT, TIMEHOUR|LEFT);
//event //event
lcdDrawNumber(14*FW, y, te->event, LEADING0|LEFT, 3); lcdDrawNumber(14*FW, y, te->event, LEADING0|LEFT, 3);
//data //data

View file

@ -69,7 +69,7 @@ void displayGaugesTelemetryScreen(FrSkyScreenData & screen)
} }
if (source && barMax > barMin) { if (source && barMax > barMin) {
int y = barHeight+6+i*(barHeight+6); int y = barHeight+6+i*(barHeight+6);
putsMixerSource(0, y+barHeight-5, source, 0); drawSource(0, y+barHeight-5, source, 0);
lcdDrawRect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2); lcdDrawRect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
getvalue_t value = getValue(source); getvalue_t value = getValue(source);
putsChannel(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT); putsChannel(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT);
@ -130,7 +130,7 @@ bool displayNumbersTelemetryScreen(FrSkyScreenData & screen)
// we don't display GPS name, no space for it // we don't display GPS name, no space for it
} }
else { else {
putsMixerSource(pos[j], 1+FH+2*FH*i, field, 0); drawSource(pos[j], 1+FH+2*FH*i, field, 0);
} }
if (field >= MIXSRC_FIRST_TELEM) { if (field >= MIXSRC_FIRST_TELEM) {
@ -186,7 +186,7 @@ bool displayTelemetryScreen()
return false; return false;
} }
lcdDrawTelemetryTopBar(); drawTelemetryTopBar();
if (s_frsky_view < MAX_TELEMETRY_SCREENS) { if (s_frsky_view < MAX_TELEMETRY_SCREENS) {
displayCustomTelemetryScreen(s_frsky_view); displayCustomTelemetryScreen(s_frsky_view);
@ -253,7 +253,7 @@ void menuViewTelemetryFrsky(uint8_t event)
} }
} }
lcdDrawTelemetryTopBar(); drawTelemetryTopBar();
lcdDrawText(8*FW, 3*FH, "No Telemetry Screens"); lcdDrawText(8*FW, 3*FH, "No Telemetry Screens");
displayRssiLine(); displayRssiLine();
} }

View file

@ -40,7 +40,7 @@ const pm_uchar bmp_shutdown[] PROGMEM = {
#define SHUTDOWN_BITMAP_WIDTH 60 #define SHUTDOWN_BITMAP_WIDTH 60
#define SHUTDOWN_BITMAP_HEIGHT 60 #define SHUTDOWN_BITMAP_HEIGHT 60
void drawShutdownBitmap(uint32_t index) void drawShutdownAnimation(uint32_t index)
{ {
index /= (PWR_PRESS_SHUTDOWN / 4); index /= (PWR_PRESS_SHUTDOWN / 4);
lcdRefreshWait(); lcdRefreshWait();
@ -133,7 +133,7 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, c
{ {
drawFieldLabel(x, y, label); drawFieldLabel(x, y, label);
if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
if (attr) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL);
return value; return value;
} }
@ -146,8 +146,8 @@ uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const pm_char *label,
swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8_t event) swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8_t event)
{ {
drawFieldLabel(x, y, STR_SWITCH); drawFieldLabel(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr); drawSwitch(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
return value; return value;
} }

View file

@ -210,9 +210,9 @@ void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, Lc
} }
#endif #endif
void putsRtcTime(coord_t x, coord_t y, LcdFlags att) void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
{ {
putsTimer(x, y, getValue(MIXSRC_TX_TIME), att); drawTimer(x, y, getValue(MIXSRC_TX_TIME), att);
} }
void getTimerString(char * str, putstime_t tme, LcdFlags att) void getTimerString(char * str, putstime_t tme, LcdFlags att)
@ -243,7 +243,7 @@ void getTimerString(char * str, putstime_t tme, LcdFlags att)
*str = '\0'; *str = '\0';
} }
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att) void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att)
{ {
char str[LEN_TIMER_STRING]; // "-00:00:00" char str[LEN_TIMER_STRING]; // "-00:00:00"
getTimerString(str, tme, att); getTimerString(str, tme, att);
@ -263,152 +263,7 @@ void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
lcdDrawSizedText(x, y, STR_VSRCRAW+2+length*(idx+1), length-1, att); lcdDrawSizedText(x, y, STR_VSRCRAW+2+length*(idx+1), length-1, att);
} }
char * getStringAtIndex(char * dest, const char * s, int idx) void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags flags)
{
uint8_t len = s[0];
strncpy(dest, s+1+len*idx, len);
dest[len] = '\0';
return dest;
}
char * getStringWithIndex(char * dest, const char * s, int idx)
{
strAppendUnsigned(strAppend(dest, s), abs(idx));
return dest;
}
char * getSwitchString(char * dest, swsrc_t idx)
{
if (idx == SWSRC_NONE) {
return getStringAtIndex(dest, STR_VSWITCHES, 0);
}
else if (idx == SWSRC_OFF) {
return getStringAtIndex(dest, STR_OFFON, 0);
}
char * s = dest;
if (idx < 0) {
*s++ = '!';
idx = -idx;
}
if (idx <= SWSRC_LAST_SWITCH) {
div_t swinfo = switchInfo(idx);
if (ZEXIST(g_eeGeneral.switchNames[swinfo.quot])) {
s += zchar2str(s, g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME);
// TODO tous zchar2str
}
else {
*s++ = 'S';
*s++ = 'A'+swinfo.quot;
}
*s++ = "\300-\301"[swinfo.rem];
*s = '\0';
}
else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) {
div_t swinfo = div(idx - SWSRC_FIRST_MULTIPOS_SWITCH, XPOTS_MULTIPOS_COUNT);
getStringWithIndex(s, "S", swinfo.quot*10+swinfo.rem+11);
}
else if (idx <= SWSRC_LAST_TRIM) {
getStringAtIndex(s, STR_VSWITCHES, idx-SWSRC_FIRST_TRIM+1);
}
else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) {
getStringWithIndex(s, "L", idx-SWSRC_FIRST_LOGICAL_SWITCH+1);
}
else if (idx <= SWSRC_ONE) {
getStringAtIndex(s, STR_VSWITCHES, idx-SWSRC_ON+2+(SWSRC_LAST_TRIM-SWSRC_FIRST_TRIM));
}
else if (idx <= SWSRC_LAST_FLIGHT_MODE) {
getStringWithIndex(s, STR_FP, idx-SWSRC_FIRST_FLIGHT_MODE);
}
else if (idx == SWSRC_TELEMETRY_STREAMING) {
strcpy(s, "Tele");
}
else {
zchar2str(s, g_model.telemetrySensors[idx-SWSRC_FIRST_SENSOR].label, TELEM_LABEL_LEN);
}
return dest;
}
char * getSourceString(char * dest, mixsrc_t idx)
{
if (idx == MIXSRC_NONE) {
return getStringAtIndex(dest, STR_VSRCRAW, 0);
}
else if (idx <= MIXSRC_LAST_INPUT) {
idx -= MIXSRC_FIRST_INPUT;
*dest++ = '\314';
if (ZEXIST(g_model.inputNames[idx])) {
zchar2str(dest, g_model.inputNames[idx], LEN_INPUT_NAME);
dest[LEN_INPUT_NAME] = '\0';
}
else {
strAppendUnsigned(dest, idx, 2);
}
}
else if (idx <= MIXSRC_LAST_LUA) {
#if defined(LUA_MODEL_SCRIPTS)
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
*dest++ = '\322';
// *dest++ = '1'+qr.quot;
strcpy(dest, scriptInputsOutputs[qr.quot].outputs[qr.rem].name);
}
#endif
}
else if (idx <= MIXSRC_LAST_POT) {
idx -= MIXSRC_Rud;
if (ZEXIST(g_eeGeneral.anaNames[idx])) {
zchar2str(dest, g_eeGeneral.anaNames[idx], LEN_ANA_NAME);
dest[LEN_ANA_NAME] = '\0';
}
else {
getStringAtIndex(dest, STR_VSRCRAW, idx + 1);
}
}
else if (idx <= MIXSRC_LAST_TRIM) {
idx -= MIXSRC_Rud;
getStringAtIndex(dest, STR_VSRCRAW, idx + 1);
}
else if (idx <= MIXSRC_LAST_SWITCH) {
idx -= MIXSRC_FIRST_SWITCH;
if (ZEXIST(g_eeGeneral.switchNames[idx])) {
zchar2str(dest, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME);
dest[LEN_SWITCH_NAME] = '\0';
}
else {
getStringAtIndex(dest, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1);
}
}
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) {
getSwitchString(dest, SWSRC_SW1 + idx - MIXSRC_SW1);
}
else if (idx <= MIXSRC_LAST_TRAINER) {
getStringWithIndex(dest, STR_PPM_TRAINER, idx - MIXSRC_FIRST_TRAINER + 1);
}
else if (idx <= MIXSRC_LAST_CH) {
getStringWithIndex(dest, STR_CH, idx - MIXSRC_CH1 + 1);
}
else if (idx <= MIXSRC_LAST_GVAR) {
getStringWithIndex(dest, STR_GV, idx - MIXSRC_GVAR1 + 1);
}
else if (idx < MIXSRC_FIRST_TELEM) {
getStringAtIndex(dest, STR_VSRCRAW, idx-MIXSRC_Rud+1-NUM_LOGICAL_SWITCH-NUM_TRAINER-NUM_CHNOUT-MAX_GVARS);
}
else {
idx -= MIXSRC_FIRST_TELEM;
div_t qr = div(idx, 3);
dest[0] = '\321';
int pos = 1 + zchar2str(&dest[1], g_model.telemetrySensors[qr.quot].label, sizeof(g_model.telemetrySensors[qr.quot].label));
if (qr.rem) dest[pos++] = (qr.rem==2 ? '+' : '-');
dest[pos] = '\0';
}
return dest;
}
void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags flags)
{ {
char s[16]; char s[16];
getSourceString(s, idx); getSourceString(s, idx);
@ -432,70 +287,21 @@ void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
} }
} }
void putsSwitches(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags) void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags)
{ {
char s[8]; char s[8];
getSwitchString(s, idx); getSwitchString(s, idx);
lcdDrawText(x, y, s, flags); lcdDrawText(x, y, s, flags);
} }
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att)
{
if (idx==0) {
lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, att);
}
else {
drawStringWithIndex(x, y, STR_FP, abs(idx)-1, att);
}
}
void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att)
{
if (curve.value != 0) {
switch (curve.type) {
case CURVE_REF_DIFF:
lcdDrawText(x, y, "D", att);
GVAR_MENU_ITEM(lcdNextPos, y, curve.value, -100, 100, LEFT|att, 0, 0);
break;
case CURVE_REF_EXPO:
lcdDrawText(x, y, "E", att);
GVAR_MENU_ITEM(lcdNextPos, y, curve.value, -100, 100, LEFT|att, 0, 0);
break;
case CURVE_REF_FUNC:
lcdDrawTextAtIndex(x, y, STR_VCURVEFUNC, curve.value, att);
break;
case CURVE_REF_CUSTOM:
drawCurveName(x, y, curve.value, att);
break;
}
}
}
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags) void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags)
{ {
if (idx == 0) { char s[8];
return lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, flags); getCurveString(s, idx);
} lcdDrawText(x, y, s, flags);
bool neg = false;
if (idx < 0) {
idx = -idx;
neg = true;
}
if (ZEXIST(g_model.curves[idx-1].name))
lcdDrawSizedText(x, y, g_model.curves[idx-1].name, LEN_CURVE_NAME, ZCHAR|flags);
else
drawStringWithIndex(x, y, STR_CV, idx, flags);
if (neg) {
if ((flags&INVERS) && ((~flags&BLINK) || BLINK_ON_PHASE))
flags &= ~(INVERS|BLINK);
lcdDrawChar(x-3, y, '!', flags);
}
} }
void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att) void drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
{ {
if (mode >= 0) { if (mode >= 0) {
if (mode < TMRMODE_COUNT) if (mode < TMRMODE_COUNT)
@ -503,10 +309,10 @@ void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
else else
mode -= (TMRMODE_COUNT-1); mode -= (TMRMODE_COUNT-1);
} }
putsSwitches(x, y, mode, att); drawSwitch(x, y, mode, att);
} }
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att) void drawTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att)
{ {
trim_t v = getRawTrimValue(phase, idx); trim_t v = getRawTrimValue(phase, idx);
unsigned int mode = v.mode; unsigned int mode = v.mode;
@ -583,7 +389,7 @@ void putsChannelValue(coord_t x, coord_t y, source_t channel, int32_t value, Lcd
putsTelemetryChannelValue(x, y, channel, value, att); putsTelemetryChannelValue(x, y, channel, value, att);
} }
else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) { else if (channel >= MIXSRC_FIRST_TIMER || channel == MIXSRC_TX_TIME) {
putsTimer(x, y, value, att); drawTimer(x, y, value, att);
} }
else if (channel == MIXSRC_TX_VOLTAGE) { else if (channel == MIXSRC_TX_VOLTAGE) {
lcdDrawNumber(x, y, value, att|PREC1); lcdDrawNumber(x, y, value, att|PREC1);

View file

@ -23,14 +23,10 @@
#include "bitmapbuffer.h" #include "bitmapbuffer.h"
#if defined(PCBHORUS) #if LCD_W >= 480
#define LCD_W 480
#define LCD_H 272
#define LCD_COLS 30
#else
#define LCD_W 800
#define LCD_H 480
#define LCD_COLS 40 #define LCD_COLS 40
#else
#define LCD_COLS 30
#endif #endif
#define CENTER #define CENTER
@ -106,8 +102,6 @@ extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#define displayBuf lcd->getData() #define displayBuf lcd->getData()
#endif #endif
#define lcdRefreshWait()
#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE) #define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE)
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END) #define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
@ -138,15 +132,13 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags=0, uint8_t
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, int idx, LcdFlags att=0, const char *prefix=""); void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, int idx, LcdFlags att=0, const char *prefix="");
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void putsSwitches(coord_t x, coord_t y, swsrc_t swtch, LcdFlags flags=0); void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags flags=0);
void putsMixerSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0); void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsCurveRef(coord_t x, coord_t y, CurveRef &curve, LcdFlags att=0);
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0); void drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0);
void putsTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att); void drawTrimMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
#define putsChn(x, y, idx, att) putsMixerSource(x, y, MIXSRC_CH1+idx-1, att) #define putsChn(x, y, idx, att) drawSource(x, y, MIXSRC_CH1+idx-1, att)
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
void putsChannelValue(coord_t x, coord_t y, source_t channel, int32_t val, LcdFlags att=0); void putsChannelValue(coord_t x, coord_t y, source_t channel, int32_t val, LcdFlags att=0);
@ -157,8 +149,8 @@ void putsTelemetryChannelValue(coord_t x, coord_t y, uint8_t channel, int32_t va
#define LEN_TIMER_STRING 10 #define LEN_TIMER_STRING 10
void getTimerString(char * str, putstime_t tme, LcdFlags att=0); void getTimerString(char * str, putstime_t tme, LcdFlags att=0);
void putsRtcTime(coord_t x, coord_t y, LcdFlags att=0); void drawRtcTime(coord_t x, coord_t y, LcdFlags att=0);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att=0); void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att=0);
#define SOLID 0xff #define SOLID 0xff
#define DOTTED 0x55 #define DOTTED 0x55
@ -259,10 +251,6 @@ inline void lcdDrawBitmapPattern(coord_t x, coord_t y, const uint8_t * img, LcdF
lcd->drawBitmapPattern(x, y, img, flags, offset, width); lcd->drawBitmapPattern(x, y, img, flags, offset, width);
} }
#define lcdSetRefVolt(...)
void lcdSetContrast();
#define lcdOff(...)
#if defined(BOOT) #if defined(BOOT)
#define BLINK_ON_PHASE (0) #define BLINK_ON_PHASE (0)
#else #else

View file

@ -43,7 +43,7 @@ const MenuHandlerFunc menuTabModel[] = {
extern uint8_t s_curveChan; extern uint8_t s_curveChan;
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, uint8_t attr); void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags attr);
uint8_t editDelay(const coord_t x, const coord_t y, const event_t event, const uint8_t attr, uint8_t delay) uint8_t editDelay(const coord_t x, const coord_t y, const event_t event, const uint8_t attr, uint8_t delay)
{ {

View file

@ -31,6 +31,6 @@ const MenuHandlerFunc menuTabGeneral[] = {
bool menuRadioSpecialFunctions(event_t event) bool menuRadioSpecialFunctions(event_t event)
{ {
MENU(STR_MENUSPECIALFUNCS, RADIO_ICONS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, NUM_CFN, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); MENU(STR_MENUSPECIALFUNCS, RADIO_ICONS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ });
return menuSpecialFunctions(event, g_eeGeneral.customFn, globalFunctionsContext); return menuSpecialFunctions(event, g_eeGeneral.customFn, globalFunctionsContext);
} }

View file

@ -34,7 +34,7 @@ extern uint16_t linesCount;
extern int menuVerticalPosition; extern int menuVerticalPosition;
extern int menuHorizontalPosition; extern int menuHorizontalPosition;
extern int menuVerticalOffset; extern int menuVerticalOffset;
extern uint8_t calibrationState; extern uint8_t menuCalibrationState;
// Temporary no highlight // Temporary no highlight
extern uint8_t noHighlightCounter; extern uint8_t noHighlightCounter;
@ -422,7 +422,7 @@ extern uint8_t editNameCursorPos;
void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event, uint8_t active, LcdFlags flags=ZCHAR); void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event, uint8_t active, LcdFlags flags=ZCHAR);
uint8_t editDelay(const coord_t x, const coord_t y, const event_t event, const uint8_t attr, uint8_t delay); uint8_t editDelay(const coord_t x, const coord_t y, const event_t event, const uint8_t attr, uint8_t delay);
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, uint8_t attr); void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags);
extern uint8_t s_curveChan; extern uint8_t s_curveChan;
@ -491,7 +491,7 @@ extern uint8_t warningInfoFlags;
#define POPUP_MENU_MAX_LINES 12 #define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 9 #define MENU_MAX_DISPLAY_LINES 9
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
#define POPUP_MENU_ITEMS_FROM_BSS() #define POPUP_MENU_SET_BSS_FLAG()
extern const char * popupMenuItems[POPUP_MENU_MAX_LINES]; extern const char * popupMenuItems[POPUP_MENU_MAX_LINES];
extern uint16_t popupMenuNoItems; extern uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset; extern uint16_t popupMenuOffset;

View file

@ -21,69 +21,9 @@
#include <stdio.h> #include <stdio.h>
#include "opentx.h" #include "opentx.h"
uint8_t s_curveChan;
int curveFn(int x)
{
return applyCustomCurve(x, s_curveChan);
}
struct point_t {
coord_t x;
coord_t y;
};
point_t getPoint(uint8_t i)
{
point_t result = {0, 0};
CurveInfo & crv = g_model.curves[s_curveChan];
int8_t * points = curveAddress(s_curveChan);
bool custom = (crv.type == CURVE_TYPE_CUSTOM);
uint8_t count = 5+crv.points;
if (i < count) {
result.x = CURVE_CENTER_X-1-CURVE_SIDE_WIDTH+i*CURVE_SIDE_WIDTH*2/(count-1);
result.y = CURVE_CENTER_Y - (points[i]) * (CURVE_SIDE_WIDTH-1) / 100;
if (custom && i>0 && i<count-1) {
result.x = CURVE_CENTER_X - 1 - CURVE_SIDE_WIDTH + (100 + (100 + points[count + i - 1]) * (2 * CURVE_SIDE_WIDTH)) / 200;
}
}
return result;
}
void drawCurve(int x, int y, int width) void drawCurve(int x, int y, int width)
{ {
drawFunction(curveFn, x, y, width); drawFunction(applyCurrentCurve, x, y, width);
}
extern int8_t * curveEnd[MAX_CURVES];
bool moveCurve(uint8_t index, int8_t shift)
{
if (curveEnd[MAX_CURVES-1] + shift > g_model.points + sizeof(g_model.points)) {
AUDIO_WARNING2();
return false;
}
int8_t *nextCrv = curveAddress(index+1);
memmove(nextCrv+shift, nextCrv, 5*(MAX_CURVES-index-1)+curveEnd[MAX_CURVES-1]-curveEnd[index]);
if (shift < 0) memclear(&g_model.points[NUM_POINTS-1] + shift, -shift);
while (index<MAX_CURVES) {
curveEnd[index++] += shift;
}
storageDirty(EE_MODEL);
return true;
}
int8_t getCurveX(int noPoints, int point)
{
return -100 + div_and_round((point*2000) / (noPoints-1), 10);
}
void resetCustomCurveX(int8_t * points, int noPoints)
{
for (int i=0; i<noPoints-2; i++) {
points[noPoints+i] = getCurveX(noPoints, i+1);
}
} }
void displayPresetChoice(event_t event) void displayPresetChoice(event_t event)
@ -194,7 +134,7 @@ bool menuModelCurveOne(event_t event)
if (attr) { if (attr) {
int count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts int count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
if (checkIncDec_Ret) { if (checkIncDec_Ret) {
int newPoints[MAX_POINTS]; int newPoints[MAX_POINTS_PER_CURVE];
newPoints[0] = points[0]; newPoints[0] = points[0];
newPoints[4+count] = points[4+crv.points]; newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++) for (int i=1; i<4+count; i++)
@ -312,7 +252,7 @@ bool menuModelCurveOne(event_t event)
return true; return true;
} }
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, uint8_t attr) void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags attr)
{ {
lcdDrawTextAtIndex(x, y, "\004DiffExpoFuncCstm", curve.type, (menuHorizontalPosition==0 ? attr : 0)); lcdDrawTextAtIndex(x, y, "\004DiffExpoFuncCstm", curve.type, (menuHorizontalPosition==0 ? attr : 0));
if (attr && menuHorizontalPosition==0) { if (attr && menuHorizontalPosition==0) {

View file

@ -97,7 +97,7 @@ bool menuModelCustomScriptOne(event_t event)
} }
else { else {
uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx]; uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx];
putsMixerSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr); drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr);
if (attr) { if (attr) {
CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def);
} }
@ -110,7 +110,7 @@ bool menuModelCustomScriptOne(event_t event)
// lcdDrawText(SCRIPT_ONE_3RD_COLUMN_POS, FH+1, STR_OUTPUTS); // lcdDrawText(SCRIPT_ONE_3RD_COLUMN_POS, FH+1, STR_OUTPUTS);
for (int i=0; i<scriptInputsOutputs[s_currIdx].outputsCount; i++) { for (int i=0; i<scriptInputsOutputs[s_currIdx].outputsCount; i++) {
putsMixerSource(SCRIPT_ONE_3RD_COLUMN_POS+INDENT_WIDTH, MENU_CONTENT_TOP+i*FH, MIXSRC_FIRST_LUA+(s_currIdx*MAX_SCRIPT_OUTPUTS)+i, 0); drawSource(SCRIPT_ONE_3RD_COLUMN_POS+INDENT_WIDTH, MENU_CONTENT_TOP+i*FH, MIXSRC_FIRST_LUA+(s_currIdx*MAX_SCRIPT_OUTPUTS)+i, 0);
lcdDrawNumber(SCRIPT_ONE_3RD_COLUMN_POS+130, MENU_CONTENT_TOP+i*FH, calcRESXto1000(scriptInputsOutputs[s_currIdx].outputs[i].value), PREC1); lcdDrawNumber(SCRIPT_ONE_3RD_COLUMN_POS+130, MENU_CONTENT_TOP+i*FH, calcRESXto1000(scriptInputsOutputs[s_currIdx].outputs[i].value), PREC1);
} }
} }

View file

@ -78,7 +78,7 @@ bool isTrimModeAvailable(int mode)
bool menuModelFlightModesAll(event_t event) bool menuModelFlightModesAll(event_t event)
{ {
MENU(STR_MENUFLIGHTPHASES, MODEL_ICONS, menuTabModel, MENU_MODEL_FLIGHT_MODES, MAX_FLIGHT_MODES+1, { NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, 0}); MENU(STR_MENUFLIGHTMODES, MODEL_ICONS, menuTabModel, MENU_MODEL_FLIGHT_MODES, MAX_FLIGHT_MODES+1, { NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_FLIGHT_MODES_LAST, 0});
if (menuVerticalPosition==0 && menuHorizontalPosition==ITEM_FLIGHT_MODES_SWITCH) { if (menuVerticalPosition==0 && menuHorizontalPosition==ITEM_FLIGHT_MODES_SWITCH) {
menuHorizontalPosition += CURSOR_MOVED_LEFT(event) ? -1 : +1; menuHorizontalPosition += CURSOR_MOVED_LEFT(event) ? -1 : +1;
@ -123,7 +123,7 @@ bool menuModelFlightModesAll(event_t event)
FlightModeData *p = flightModeAddress(k); FlightModeData *p = flightModeAddress(k);
putsFlightMode(MENUS_MARGIN_LEFT, y, k+1, (getFlightMode()==k ? BOLD : 0) | ((menuVerticalPosition==k && menuHorizontalPosition<0) ? INVERS : 0)); drawFlightMode(MENUS_MARGIN_LEFT, y, k+1, (getFlightMode()==k ? BOLD : 0) | ((menuVerticalPosition==k && menuHorizontalPosition<0) ? INVERS : 0));
for (int j=0; j<ITEM_FLIGHT_MODES_COUNT; j++) { for (int j=0; j<ITEM_FLIGHT_MODES_COUNT; j++) {
LcdFlags attr = ((menuVerticalPosition==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); LcdFlags attr = ((menuVerticalPosition==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
@ -138,7 +138,7 @@ bool menuModelFlightModesAll(event_t event)
if (k == 0) if (k == 0)
lcdDrawText(FLIGHT_MODES_SWITCH_COLUMN, y, "N/A"); lcdDrawText(FLIGHT_MODES_SWITCH_COLUMN, y, "N/A");
else else
putsSwitches(FLIGHT_MODES_SWITCH_COLUMN, y, p->swtch, attr); drawSwitch(FLIGHT_MODES_SWITCH_COLUMN, y, p->swtch, attr);
break; break;
case ITEM_FLIGHT_MODES_TRIM_RUD: case ITEM_FLIGHT_MODES_TRIM_RUD:
@ -153,7 +153,7 @@ bool menuModelFlightModesAll(event_t event)
trim_t & v = p->trim[t]; trim_t & v = p->trim[t];
v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable); v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable);
} }
putsTrimMode(FLIGHT_MODES_TRIMS_COLUMN+j*FLIGHT_MODES_TRIM_WIDTH, y, k, t, attr); drawTrimMode(FLIGHT_MODES_TRIMS_COLUMN+j*FLIGHT_MODES_TRIM_WIDTH, y, k, t, attr);
break; break;
} }

View file

@ -71,7 +71,7 @@ bool menuModelGVars(event_t event)
if (v > GVAR_MAX) { if (v > GVAR_MAX) {
uint8_t p = v - GVAR_MAX - 1; uint8_t p = v - GVAR_MAX - 1;
if (p >= j-1) p++; if (p >= j-1) p++;
putsFlightMode(x-21, y, p+1, attr); drawFlightMode(x-21, y, p+1, attr);
vmin = GVAR_MAX+1; vmax = GVAR_MAX+MAX_FLIGHT_MODES-1; vmin = GVAR_MAX+1; vmax = GVAR_MAX+MAX_FLIGHT_MODES-1;
} }
else { else {

View file

@ -20,7 +20,7 @@
#include "opentx.h" #include "opentx.h"
enum menuModelHeliItems { enum MenuModelHeliItems {
ITEM_HELI_SWASHTYPE, ITEM_HELI_SWASHTYPE,
ITEM_HELI_SWASHRING, ITEM_HELI_SWASHRING,
ITEM_HELI_ELE, ITEM_HELI_ELE,
@ -38,9 +38,9 @@ bool menuModelHeli(event_t event)
{ {
SIMPLE_MENU(STR_MENUHELISETUP, MODEL_ICONS, menuTabModel, MENU_MODEL_HELI, ITEM_HELI_MAX); SIMPLE_MENU(STR_MENUHELISETUP, MODEL_ICONS, menuTabModel, MENU_MODEL_HELI, ITEM_HELI_MAX);
int sub = menuVerticalPosition; uint8_t sub = menuVerticalPosition;
for (unsigned int i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
coord_t y = MENU_CONTENT_TOP + i*FH; coord_t y = MENU_CONTENT_TOP + i*FH;
int k = i+menuVerticalOffset; int k = i+menuVerticalOffset;
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
@ -60,7 +60,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_ELE: case ITEM_HELI_ELE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ELEVATOR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ELEVATOR);
putsMixerSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorSource, attr); drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorSource, attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.elevatorSource, 0, MIXSRC_LAST_CH); if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.elevatorSource, 0, MIXSRC_LAST_CH);
break; break;
@ -72,7 +72,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_AIL: case ITEM_HELI_AIL:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_AILERON); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_AILERON);
putsMixerSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronSource, attr); drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronSource, attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.aileronSource, 0, MIXSRC_LAST_CH); if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.aileronSource, 0, MIXSRC_LAST_CH);
break; break;
@ -84,7 +84,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_COL: case ITEM_HELI_COL:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_COLLECTIVE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_COLLECTIVE);
putsMixerSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveSource, attr); drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveSource, attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.collectiveSource, 0, MIXSRC_LAST_CH); if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.collectiveSource, 0, MIXSRC_LAST_CH);
break; break;

View file

@ -233,7 +233,7 @@ bool menuModelExpoOne(event_t event)
case EXPO_FIELD_SOURCE: case EXPO_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE)); lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, menuHorizontalPosition==0 ? attr : 0); drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, menuHorizontalPosition==0 ? attr : 0);
if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) { if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN+60, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0)); putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN+60, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0));
@ -336,20 +336,20 @@ void onExposMenu(const char * result)
} }
} }
void displayExpoInfos(coord_t y, ExpoData *ed) void displayExpoInfos(coord_t y, ExpoData * ed)
{ {
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve); drawCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve);
if (ed->swtch) { if (ed->swtch) {
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch); drawSwitch(EXPO_LINE_SWITCH_POS, y, ed->swtch);
} }
if (ed->mode != 3) { if (ed->mode != 3) {
lcdDrawText(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? "\176" : "\177"); lcdDrawText(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? "\176" : "\177");
} }
} }
void displayExpoLine(coord_t y, ExpoData *ed) void displayExpoLine(coord_t y, ExpoData * ed)
{ {
putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw); drawSource(EXPO_LINE_SRC_POS, y, ed->srcRaw);
displayExpoInfos(y, ed); displayExpoInfos(y, ed);
displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes, 0); displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes, 0);
@ -493,7 +493,7 @@ bool menuModelExposAll(event_t event)
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH; coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
if ((i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed))) { if ((i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed))) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) { if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch); drawSource(MENUS_MARGIN_LEFT, y, ch);
} }
uint8_t mixCnt = 0; uint8_t mixCnt = 0;
do { do {
@ -544,7 +544,7 @@ bool menuModelExposAll(event_t event)
} }
} }
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) { if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch, attr); drawSource(MENUS_MARGIN_LEFT, y, ch, attr);
if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) {
lineExpoSurround(y); lineExpoSurround(y);
} }

View file

@ -76,7 +76,7 @@ bool menuModelLogicalSwitches(event_t event)
{ {
INCDEC_DECLARE_VARS(EE_MODEL); INCDEC_DECLARE_VARS(EE_MODEL);
MENU(STR_MENULOGICALSWITCHES, MODEL_ICONS, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, NUM_LOGICAL_SWITCH, { NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/} ); MENU(STR_MENULOGICALSWITCHES, MODEL_ICONS, menuTabModel, MENU_MODEL_LOGICAL_SWITCHES, MAX_LOGICAL_SWITCHES, { NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/} );
LogicalSwitchData * cs = lswAddress(menuVerticalPosition); LogicalSwitchData * cs = lswAddress(menuVerticalPosition);
uint8_t cstate = lswFamily(cs->func); uint8_t cstate = lswFamily(cs->func);
@ -110,7 +110,7 @@ bool menuModelLogicalSwitches(event_t event)
// CSW name // CSW name
unsigned int sw = SWSRC_SW1+k; unsigned int sw = SWSRC_SW1+k;
putsSwitches(MENUS_MARGIN_LEFT, y, sw, (getSwitch(sw) ? BOLD : 0) | ((menuVerticalPosition==k && CURSOR_ON_LINE()) ? INVERS : 0)); drawSwitch(MENUS_MARGIN_LEFT, y, sw, (getSwitch(sw) ? BOLD : 0) | ((menuVerticalPosition==k && CURSOR_ON_LINE()) ? INVERS : 0));
// CSW func // CSW func
lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, menuHorizontalPosition==0 ? attr : 0); lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, menuHorizontalPosition==0 ? attr : 0);
@ -122,15 +122,15 @@ bool menuModelLogicalSwitches(event_t event)
int v3_min=-1, v3_max=100; int v3_min=-1, v3_max=100;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches); INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
} }
else if (cstate == LS_FAMILY_EDGE) { else if (cstate == LS_FAMILY_EDGE) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, (menuHorizontalPosition==LS_FIELD_V3 ? attr : 0)); putsEdgeDelayParam(CSW_3RD_COLUMN, y, cs, attr2, (menuHorizontalPosition==LS_FIELD_V3 ? attr : 0));
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122; v2_min=-129; v2_max = 122;
@ -146,8 +146,8 @@ bool menuModelLogicalSwitches(event_t event)
} }
else if (cstate == LS_FAMILY_COMP) { else if (cstate == LS_FAMILY_COMP) {
v1_val = cs->v1; v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
} }
@ -161,7 +161,7 @@ bool menuModelLogicalSwitches(event_t event)
} }
else { else {
v1_val = cs->v1; v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (menuHorizontalPosition == 1) { if (menuHorizontalPosition == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches); INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -176,7 +176,7 @@ bool menuModelLogicalSwitches(event_t event)
} }
// CSW AND switch // CSW AND switch
putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, menuHorizontalPosition==LS_FIELD_ANDSW ? attr : 0); drawSwitch(CSW_4TH_COLUMN, y, cs->andsw, menuHorizontalPosition==LS_FIELD_ANDSW ? attr : 0);
// CSW duration // CSW duration
if (cs->duration > 0) if (cs->duration > 0)

View file

@ -24,7 +24,7 @@
int getMixesLinesCount() int getMixesLinesCount()
{ {
int lastch = -1; int lastch = -1;
uint8_t count = NUM_CHNOUT; uint8_t count = MAX_OUTPUT_CHANNELS;
for (int i=0; i<MAX_MIXERS; i++) { for (int i=0; i<MAX_MIXERS; i++) {
bool valid = mixAddress(i)->srcRaw; bool valid = mixAddress(i)->srcRaw;
if (!valid) if (!valid)
@ -116,7 +116,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
} }
if (tgt_idx == MAX_MIXERS) { if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1) if (x->destCh == MAX_OUTPUT_CHANNELS-1)
return false; return false;
x->destCh++; x->destCh++;
return true; return true;
@ -130,7 +130,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
else return false; else return false;
} }
else { else {
if (destCh<NUM_CHNOUT-1) x->destCh++; if (destCh<MAX_OUTPUT_CHANNELS-1) x->destCh++;
else return false; else return false;
} }
return true; return true;
@ -201,7 +201,7 @@ bool menuModelMixOne(event_t event)
break; break;
case MIX_FIELD_SOURCE: case MIX_FIELD_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE)); lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(MIXES_2ND_COLUMN, y, md2->srcRaw, attr); drawSource(MIXES_2ND_COLUMN, y, md2->srcRaw, attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
break; break;
case MIX_FIELD_WEIGHT: case MIX_FIELD_WEIGHT:
@ -324,11 +324,11 @@ void onMixesMenu(const char * result)
void displayMixInfos(coord_t y, MixData *md) void displayMixInfos(coord_t y, MixData *md)
{ {
if (md->curve.value != 0 ) lcd->drawBitmap(MIX_LINE_CURVE_ICON, y + 2, mixerSetupCurveBitmap); if (md->curve.value != 0 ) lcd->drawBitmap(MIX_LINE_CURVE_ICON, y + 2, mixerSetupCurveBitmap);
putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve); drawCurveRef(MIX_LINE_CURVE_POS, y, md->curve);
if (md->swtch) { if (md->swtch) {
lcd->drawBitmap(MIX_LINE_SWITCH_ICON, y + 2, mixerSetupSwitchBitmap); lcd->drawBitmap(MIX_LINE_SWITCH_ICON, y + 2, mixerSetupSwitchBitmap);
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch); drawSwitch(MIX_LINE_SWITCH_POS, y, md->swtch);
} }
} }
@ -519,7 +519,7 @@ bool menuModelMixAll(event_t event)
int cur = 0; int cur = 0;
int i = 0; int i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) { for (int ch=1; ch<=MAX_OUTPUT_CHANNELS; ch++) {
MixData * md; MixData * md;
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH; coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) { if (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch) {
@ -547,7 +547,7 @@ bool menuModelMixAll(event_t event)
if (mixCnt > 0) lcd->drawBitmap(10, y, mpx_mode[md->mltpx]); if (mixCnt > 0) lcd->drawBitmap(10, y, mpx_mode[md->mltpx]);
putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw); drawSource(MIX_LINE_SRC_POS, y, md->srcRaw);
gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, RIGHT | attr | (isMixActive(i) ? BOLD : 0), event); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, RIGHT | attr | (isMixActive(i) ? BOLD : 0), event);

View file

@ -23,7 +23,7 @@
bool isThrottleOutput(uint8_t ch) bool isThrottleOutput(uint8_t ch)
{ {
for (uint8_t i=0; i<MAX_MIXERS; i++) { for (uint8_t i=0; i<MAX_MIXERS; i++) {
MixData *mix = mixAddress(i); MixData * mix = mixAddress(i);
if (mix->destCh==ch && mix->srcRaw==MIXSRC_Thr) if (mix->destCh==ch && mix->srcRaw==MIXSRC_Thr)
return true; return true;
} }
@ -49,15 +49,15 @@ enum LimitsItems {
ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1 ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1
}; };
#define LIMITS_NAME_POS 52 #define LIMITS_NAME_POS 52
#define LIMITS_OFFSET_POS 160 #define LIMITS_OFFSET_POS 160
#define LIMITS_MIN_POS 220 #define LIMITS_MIN_POS 220
#define LIMITS_DIRECTION_POS 240 #define LIMITS_DIRECTION_POS 235
#define LIMITS_MAX_POS 300 #define LIMITS_MAX_POS 300
#define LIMITS_REVERT_POS 320 #define LIMITS_REVERT_POS 312
#define LIMITS_CURVE_POS 350 #define LIMITS_CURVE_POS 340
#define LIMITS_PPM_CENTER_POS 440 #define LIMITS_PPM_CENTER_POS 440
#define LIMITS_SYMETRICAL_POS 450 #define LIMITS_SYMETRICAL_POS 450
#define LIMITS_MIN_MAX_OFFSET 1000 #define LIMITS_MIN_MAX_OFFSET 1000
#define CONVERT_US_MIN_MAX(x) (((x)*1280)/250) #define CONVERT_US_MIN_MAX(x) (((x)*1280)/250)
@ -93,7 +93,7 @@ void onLimitsMenu(const char *result)
bool menuModelLimits(event_t event) bool menuModelLimits(event_t event)
{ {
MENU(STR_MENULIMITS, MODEL_ICONS, menuTabModel, MENU_MODEL_OUTPUTS, NUM_CHNOUT+1, MENU(STR_MENULIMITS, MODEL_ICONS, menuTabModel, MENU_MODEL_OUTPUTS, MAX_OUTPUT_CHANNELS+1,
{ NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, { NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW,
NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW,
NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW,
@ -102,7 +102,7 @@ bool menuModelLimits(event_t event)
uint32_t sub = menuVerticalPosition; uint32_t sub = menuVerticalPosition;
if (sub<NUM_CHNOUT && menuHorizontalPosition>=0) { if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition); drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition);
} }
@ -117,9 +117,9 @@ bool menuModelLimits(event_t event)
coord_t y = MENU_CONTENT_TOP + i*FH; coord_t y = MENU_CONTENT_TOP + i*FH;
uint8_t k = i+menuVerticalOffset; uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) { if (k==MAX_OUTPUT_CHANNELS) {
// last line available - add the "copy trim menu" line // last line available - add the "copy trim menu" line
uint8_t attr = (sub==NUM_CHNOUT) ? INVERS : 0; uint8_t attr = (sub==MAX_OUTPUT_CHANNELS) ? INVERS : 0;
// TODO CENTER attribute // TODO CENTER attribute
lcdDrawText(100, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr); lcdDrawText(100, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : attr);
if (attr) { if (attr) {

View file

@ -110,8 +110,8 @@ void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, event_t event)
lcdDrawSolidFilledRect(MODEL_SETUP_2ND_COLUMN-INVERT_HORZ_MARGIN, y-INVERT_VERT_MARGIN+1, 115+2*INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR); lcdDrawSolidFilledRect(MODEL_SETUP_2ND_COLUMN-INVERT_HORZ_MARGIN, y-INVERT_VERT_MARGIN+1, 115+2*INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR);
} }
drawStringWithIndex(MENUS_MARGIN_LEFT, y, STR_TIMER, timerIdx+1); drawStringWithIndex(MENUS_MARGIN_LEFT, y, STR_TIMER, timerIdx+1);
putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer.mode, (menuHorizontalPosition<=0 ? attr : 0)); drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer.mode, (menuHorizontalPosition<=0 ? attr : 0));
putsTimer(MODEL_SETUP_2ND_COLUMN+50, y, timer.start, (menuHorizontalPosition!=0 ? attr|TIMEHOUR : TIMEHOUR)); drawTimer(MODEL_SETUP_2ND_COLUMN+50, y, timer.start, (menuHorizontalPosition!=0 ? attr|TIMEHOUR : TIMEHOUR));
if (attr && s_editMode>0) { if (attr && s_editMode>0) {
switch (menuHorizontalPosition) { switch (menuHorizontalPosition) {
case 0: case 0:
@ -217,7 +217,7 @@ int getSwitchWarningsCount()
#endif #endif
#define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)) #define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1))
#define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0) #define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? uint8_t(NUM_POTS+NUM_SLIDERS) : (uint8_t)0)
bool menuModelSetup(event_t event) bool menuModelSetup(event_t event)
{ {
@ -234,7 +234,7 @@ bool menuModelSetup(event_t event)
MENU(STR_MENUSETUP, MODEL_ICONS, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_MAX, MENU(STR_MENUSETUP, MODEL_ICONS, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_MAX,
{ 0, 0, TIMERS_ROWS, 0, 1, 0, 0, { 0, 0, TIMERS_ROWS, 0, 1, 0, 0,
LABEL(Throttle), 0, 0, 0, LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule), LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS, INTERNAL_MODULE_CHANNELS_ROWS,
@ -406,13 +406,13 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_THROTTLE_TRACE: case ITEM_MODEL_THROTTLE_TRACE:
{ {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRACE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_CHNOUT); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr; uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr) if (idx > MIXSRC_Thr)
idx += 1; idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS) if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS; idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr); drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break; break;
} }
@ -508,7 +508,7 @@ bool menuModelSetup(event_t event)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), g_model.potsWarnMode, (menuHorizontalPosition == 0) ? attr : 0); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), g_model.potsWarnMode, (menuHorizontalPosition == 0) ? attr : 0);
if (g_model.potsWarnMode) { if (g_model.potsWarnMode) {
coord_t x = MODEL_SETUP_2ND_COLUMN+30; coord_t x = MODEL_SETUP_2ND_COLUMN+30;
for (int i=0; i<NUM_POTS; ++i) { for (int i=0; i<NUM_POTS+NUM_SLIDERS; ++i) {
LcdFlags flags = (((menuHorizontalPosition==i+1) && attr) ? INVERS : 0); LcdFlags flags = (((menuHorizontalPosition==i+1) && attr) ? INVERS : 0);
flags |= (g_model.potsWarnEnabled & (1 << i)) ? TEXT_DISABLE_COLOR : TEXT_COLOR; flags |= (g_model.potsWarnEnabled & (1 << i)) ? TEXT_DISABLE_COLOR : TEXT_COLOR;
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, NUM_STICKS+1+i, flags); lcdDrawTextAtIndex(x, y, STR_VSRCRAW, NUM_STICKS+1+i, flags);
@ -526,7 +526,7 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_BEEP_CENTER: case ITEM_MODEL_BEEP_CENTER:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BEEPCTR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BEEPCTR);
lcdNextPos = MODEL_SETUP_2ND_COLUMN - 3; lcdNextPos = MODEL_SETUP_2ND_COLUMN - 3;
for (int i=0; i<NUM_STICKS+NUM_POTS; i++) { for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
LcdFlags flags = ((menuHorizontalPosition==i && attr) ? INVERS : 0); LcdFlags flags = ((menuHorizontalPosition==i && attr) ? INVERS : 0);
flags |= (g_model.beepANACenter & ((BeepANACenter)1<<i)) ? TEXT_COLOR : (TEXT_DISABLE_COLOR | NO_FONTCACHE); flags |= (g_model.beepANACenter & ((BeepANACenter)1<<i)) ? TEXT_COLOR : (TEXT_DISABLE_COLOR | NO_FONTCACHE);
if (attr && menuHorizontalPosition < 0) flags |= INVERS; if (attr && menuHorizontalPosition < 0) flags |= INVERS;

View file

@ -93,13 +93,13 @@ void onCustomFunctionsMenu(const char *result)
storageDirty(eeFlags); storageDirty(eeFlags);
} }
else if (result == STR_INSERT) { else if (result == STR_INSERT) {
memmove(cfn+1, cfn, (NUM_CFN-menuVerticalPosition-1)*sizeof(CustomFunctionData)); memmove(cfn+1, cfn, (MAX_SPECIAL_FUNCTIONS-menuVerticalPosition-1)*sizeof(CustomFunctionData));
memset(cfn, 0, sizeof(CustomFunctionData)); memset(cfn, 0, sizeof(CustomFunctionData));
storageDirty(eeFlags); storageDirty(eeFlags);
} }
else if (result == STR_DELETE) { else if (result == STR_DELETE) {
memmove(cfn, cfn+1, (NUM_CFN-menuVerticalPosition-1)*sizeof(CustomFunctionData)); memmove(cfn, cfn+1, (MAX_SPECIAL_FUNCTIONS-menuVerticalPosition-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); memset(&g_model.customFn[MAX_SPECIAL_FUNCTIONS-1], 0, sizeof(CustomFunctionData));
storageDirty(eeFlags); storageDirty(eeFlags);
} }
} }
@ -154,11 +154,11 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
POPUP_MENU_ADD_ITEM(STR_COPY); POPUP_MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION) if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
POPUP_MENU_ADD_ITEM(STR_PASTE); POPUP_MENU_ADD_ITEM(STR_PASTE);
if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1])) if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[MAX_SPECIAL_FUNCTIONS-1]))
POPUP_MENU_ADD_ITEM(STR_INSERT); POPUP_MENU_ADD_ITEM(STR_INSERT);
if (!CFN_EMPTY(cfn)) if (!CFN_EMPTY(cfn))
POPUP_MENU_ADD_ITEM(STR_CLEAR); POPUP_MENU_ADD_ITEM(STR_CLEAR);
for (int i=menuVerticalPosition+1; i<NUM_CFN; i++) { for (int i=menuVerticalPosition+1; i<MAX_SPECIAL_FUNCTIONS; i++) {
if (!CFN_EMPTY(&functions[i])) { if (!CFN_EMPTY(&functions[i])) {
POPUP_MENU_ADD_ITEM(STR_DELETE); POPUP_MENU_ADD_ITEM(STR_DELETE);
break; break;
@ -183,7 +183,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
if (active || AUTOSWITCH_ENTER_LONG()) { if (active || AUTOSWITCH_ENTER_LONG()) {
CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
} }
putsSwitches(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); drawSwitch(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
break; break;
case ITEM_SPECIAL_FUNCTIONS_FUNCTION: case ITEM_SPECIAL_FUNCTIONS_FUNCTION:
@ -204,7 +204,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
case ITEM_SPECIAL_FUNCTIONS_PARAM: case ITEM_SPECIAL_FUNCTIONS_PARAM:
{ {
int8_t maxParam = NUM_CHNOUT-1; int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION) #if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) { if (func == FUNC_OVERRIDE_CHANNEL) {
putsChn(MODEL_SPECIAL_FUNC_2ND_COLUMN_EXT, y, CFN_CH_INDEX(cfn)+1, attr); putsChn(MODEL_SPECIAL_FUNC_2ND_COLUMN_EXT, y, CFN_CH_INDEX(cfn)+1, attr);
@ -213,7 +213,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#endif #endif
if (func == FUNC_TRAINER) { if (func == FUNC_TRAINER) {
maxParam = 4; maxParam = 4;
putsMixerSource(MODEL_SPECIAL_FUNC_2ND_COLUMN_EXT, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); drawSource(MODEL_SPECIAL_FUNC_2ND_COLUMN_EXT, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
} }
#if defined(GVARS) #if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) { else if (func == FUNC_ADJUST_GVAR) {
@ -260,7 +260,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#endif #endif
else if (func == FUNC_SET_TIMER) { else if (func == FUNC_SET_TIMER) {
val_max = 59*60+59; val_max = 59*60+59;
putsTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
} }
else if (func == FUNC_PLAY_SOUND) { else if (func == FUNC_PLAY_SOUND) {
val_max = AU_SPECIAL_SOUND_LAST-AU_SPECIAL_SOUND_FIRST-1; val_max = AU_SPECIAL_SOUND_LAST-AU_SPECIAL_SOUND_FIRST-1;
@ -301,7 +301,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
} }
else if (func == FUNC_PLAY_VALUE) { else if (func == FUNC_PLAY_VALUE) {
val_max = MIXSRC_LAST_TELEM; val_max = MIXSRC_LAST_TELEM;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(functions == g_eeGeneral.customFn ? isSourceAvailableInGlobalFunctions : isSourceAvailable); INCDEC_ENABLE_CHECK(functions == g_eeGeneral.customFn ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
@ -310,7 +310,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#endif #endif
else if (func == FUNC_VOLUME) { else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -342,7 +342,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
break; break;
case FUNC_ADJUST_GVAR_SOURCE: case FUNC_ADJUST_GVAR_SOURCE:
val_max = MIXSRC_LAST_CH; val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr); drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) { if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable); INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -415,6 +415,6 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
bool menuModelSpecialFunctions(event_t event) bool menuModelSpecialFunctions(event_t event)
{ {
MENU(STR_MENUCUSTOMFUNC, MODEL_ICONS, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, NUM_CFN, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); MENU(STR_MENUCUSTOMFUNC, MODEL_ICONS, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ });
return menuSpecialFunctions(event, g_model.customFn, modelFunctionsContext); return menuSpecialFunctions(event, g_model.customFn, modelFunctionsContext);
} }

View file

@ -229,33 +229,33 @@ bool menuModelSensor(event_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) { if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) { if (sensor->formula == TELEM_FORMULA_CELL) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CELLSENSOR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CELLSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor); sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_GPSSENSOR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_GPSSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor); sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) { else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURRENTSENSOR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CURRENTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isTelemetryFieldAvailable); sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isTelemetryFieldAvailable);
} }
break; break;
} }
else if (sensor->formula == TELEM_FORMULA_TOTALIZE) { else if (sensor->formula == TELEM_FORMULA_TOTALIZE) {
lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE)); lcdDrawText(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE));
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr);
if (attr) { if (attr) {
sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isTelemetryFieldComparisonAvailable); sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isTelemetryFieldComparisonAvailable);
} }
break; break;
} }
@ -288,9 +288,9 @@ bool menuModelSensor(event_t event)
} }
else if (sensor->formula == TELEM_FORMULA_DIST) { else if (sensor->formula == TELEM_FORMULA_DIST) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALTSENSOR); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALTSENSOR);
putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr);
if (attr) { if (attr) {
sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor);
} }
break; break;
} }
@ -318,14 +318,14 @@ bool menuModelSensor(event_t event)
drawStringWithIndex(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1); drawStringWithIndex(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1]; int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
if (attr) { if (attr) {
source = checkIncDec(event, source, -MAX_SENSORS, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); source = checkIncDec(event, source, -MAX_TELEMETRY_SENSORS, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
if (source < 0) { if (source < 0) {
lcdDrawText(SENSOR_2ND_COLUMN, y, "-", attr); lcdDrawText(SENSOR_2ND_COLUMN, y, "-", attr);
putsMixerSource(SENSOR_2ND_COLUMN+5, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr); drawSource(SENSOR_2ND_COLUMN+5, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr);
} }
else { else {
putsMixerSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr); drawSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr);
} }
break; break;
} }
@ -367,14 +367,14 @@ void onSensorMenu(const char *result)
{ {
int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1; int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) { if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) { if (result == STR_EDIT) {
pushMenu(menuModelSensor); pushMenu(menuModelSensor);
} }
else if (result == STR_DELETE) { else if (result == STR_DELETE) {
delTelemetryIndex(index); delTelemetryIndex(index);
index += 1; index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index)) if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1; menuVerticalPosition += 1;
else else
menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR; menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR;
@ -402,7 +402,7 @@ bool menuModelTelemetryFrsky(event_t event)
{ {
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) { for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i); delTelemetryIndex(i);
} }
} }
@ -420,7 +420,7 @@ bool menuModelTelemetryFrsky(event_t event)
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
LcdFlags attr = (menuVerticalPosition == k ? blink : 0); LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_SENSORS) { if (k>=ITEM_TELEMETRY_SENSOR1 && k<ITEM_TELEMETRY_SENSOR1+MAX_TELEMETRY_SENSORS) {
int index = k-ITEM_TELEMETRY_SENSOR1; int index = k-ITEM_TELEMETRY_SENSOR1;
lcdDrawNumber(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, index+1, LEFT|attr, 0, NULL, ":"); lcdDrawNumber(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, index+1, LEFT|attr, 0, NULL, ":");
lcdDrawSizedText(60, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR); lcdDrawSizedText(60, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR);
@ -539,9 +539,9 @@ bool menuModelTelemetryFrsky(event_t event)
case ITEM_TELEMETRY_VARIO_SOURCE: case ITEM_TELEMETRY_VARIO_SOURCE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SOURCE); lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SOURCE);
putsMixerSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr); drawSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr);
if (attr) { if (attr) {
g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable);
} }
break; break;

View file

@ -25,7 +25,7 @@ int menuVerticalPosition;
int menuHorizontalPosition; int menuHorizontalPosition;
int8_t s_editMode; int8_t s_editMode;
uint8_t noHighlightCounter; uint8_t noHighlightCounter;
uint8_t calibrationState; // TODO rename this variable uint8_t menuCalibrationState; // TODO rename this variable
int checkIncDecSelection = 0; int checkIncDecSelection = 0;
#if defined(AUTOSWITCH) #if defined(AUTOSWITCH)
@ -35,7 +35,7 @@ swsrc_t checkIncDecMovedSwitch(swsrc_t val)
swsrc_t swtch = getMovedSwitch(); swsrc_t swtch = getMovedSwitch();
if (swtch) { if (swtch) {
div_t info = switchInfo(swtch); div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) { if (IS_CONFIG_TOGGLE(info.quot)) {
if (info.rem != 0) { if (info.rem != 0) {
val = (val == swtch ? swtch-2 : swtch); val = (val == swtch ? swtch-2 : swtch);
} }
@ -82,7 +82,7 @@ void onSourceLongEnterPress(const char * result)
else if (result == STR_MENU_GVARS) else if (result == STR_MENU_GVARS)
checkIncDecSelection = MIXSRC_FIRST_GVAR; checkIncDecSelection = MIXSRC_FIRST_GVAR;
else if (result == STR_MENU_TELEMETRY) { else if (result == STR_MENU_TELEMETRY) {
for (int i = 0; i < MAX_SENSORS; i++) { for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i]; TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) { if (sensor->isAvailable()) {
checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i; checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i;
@ -99,7 +99,7 @@ void onSwitchLongEnterPress(const char *result)
else if (result == STR_MENU_TRIMS) else if (result == STR_MENU_TRIMS)
checkIncDecSelection = SWSRC_FIRST_TRIM; checkIncDecSelection = SWSRC_FIRST_TRIM;
else if (result == STR_MENU_LOGICAL_SWITCHES) else if (result == STR_MENU_LOGICAL_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, NUM_LOGICAL_SWITCH, isLogicalSwitchAvailable); checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, MAX_LOGICAL_SWITCHES, isLogicalSwitchAvailable);
else if (result == STR_MENU_OTHER) else if (result == STR_MENU_OTHER)
checkIncDecSelection = SWSRC_ON; checkIncDecSelection = SWSRC_ON;
else if (result == STR_MENU_INVERT) else if (result == STR_MENU_INVERT)
@ -241,7 +241,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla
} }
if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) { if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) {
for (int i = 0; i < MAX_SENSORS; i++) { for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
TelemetrySensor * sensor = & g_model.telemetrySensors[i]; TelemetrySensor * sensor = & g_model.telemetrySensors[i];
if (sensor->isAvailable()) { if (sensor->isAvailable()) {
POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY); POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY);
@ -265,7 +265,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla
if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES);
if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) { if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) { for (int i = 0; i < MAX_LOGICAL_SWITCHES; i++) {
if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) { if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) {
POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES); POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES);
break; break;
@ -366,7 +366,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
return false; return false;
} }
if (menuTab && !calibrationState) { if (menuTab && !menuCalibrationState) {
int cc = curr; int cc = curr;
switch (event) { switch (event) {
case EVT_KEY_FIRST(KEY_PGDN): case EVT_KEY_FIRST(KEY_PGDN):
@ -436,7 +436,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
menuHorizontalPosition = POS_HORZ_INIT(menuVerticalPosition); menuHorizontalPosition = POS_HORZ_INIT(menuVerticalPosition);
AUDIO_KEY_PRESS(); AUDIO_KEY_PRESS();
} }
else if (!calibrationState) { else if (!menuCalibrationState) {
popMenu(); popMenu();
} }
} }

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