1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-14 11:59:50 +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_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_REGEX "[ A-Za-z0-9_.-,]*"

View file

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

View file

@ -32,6 +32,7 @@
#define REVB
#define NUM_POTS 3
#define NUM_SLIDERS 0
#define SWSRC_SW1 DSW_SW1
#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_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_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 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) {
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));
}
}

View file

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

View file

@ -16,8 +16,8 @@
#include <stdint.h>
#if !defined(NUM_LOGICAL_SWITCH) && defined(NUM_CSW)
#define NUM_LOGICAL_SWITCH NUM_CSW
#if !defined(MAX_LOGICAL_SWITCHES) && defined(NUM_CSW)
#define MAX_LOGICAL_SWITCHES NUM_CSW
#endif
#ifdef INIT_IMPORT
@ -31,7 +31,7 @@ telemetryStreaming = 20;
#undef SETVALUES_IMPORT
for (int i=0; i<NUM_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];
for (int i=0; i<C9X_NUM_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));
for (unsigned int i=0; i<DIM(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)
outputs.vsw[i] = getSwitch(SWSRC_SW1+i);
#else

View file

@ -18,10 +18,11 @@ option(FAI "Competition mode (no telemetry)" OFF)
option(AUTOSOURCE "Automatic source detection in menus" ON)
option(AUTOSWITCH "Automatic switch detection in menus" ON)
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_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(TEMPLATES "Model templates menu" OFF)
enable_language(ASM)
set(OPT s)
@ -40,7 +41,6 @@ configure_file(stamp.h.in stamp.h @ONLY)
add_subdirectory(translations)
add_subdirectory(bitmaps)
add_subdirectory(fonts)
add_subdirectory(lua)
set(EEPROM_VARIANT 0)
set(GVARS_VARIANT 1)
@ -52,12 +52,6 @@ set(M128_VARIANT 32768)
set(FIRMWARE_DEPENDENCIES firmware_translations)
set(9X_GUI_SRC
model_inputs_mixes.cpp
radio_diagkeys.cpp
radio_diaganas.cpp
)
set(FATFS_SRC
${FATFS_DIR}/ff.c
${FATFS_DIR}/fattime.c
@ -83,7 +77,11 @@ elseif(PCB STREQUAL 9X2561)
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561)
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)
add_definitions(-DSP22)
endif()
@ -99,8 +97,6 @@ else()
message(FATAL_ERROR "Unknown PCB '${PCB}'")
endif()
include_directories(gui gui/${GUI_DIR})
if(NOT PCB STREQUAL 9XR AND NOT PCB STREQUAL 9XRPRO)
option(DBLKEYS "Double Keys" ON)
if(DBLKEYS)
@ -157,47 +153,14 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR})
set(GUI_SRC
${GUI_SRC}
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
)
add_subdirectory(lua)
include(gui/CMakeLists.txt)
if(RAMBACKUP)
add_definitions(-DRAMBACKUP)
set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp)
endif()
if(VIRTUAL_INPUTS)
add_definitions(-DVIRTUALINPUTS)
set(TEMPLATES OFF)
else()
option(TEMPLATES "Model Templates Menu" ON)
endif()
if(TEMPLATES)
add_definitions(-DTEMPLATES)
set(SRC ${SRC} templates.cpp)
@ -224,7 +187,6 @@ endif()
if(HELI)
add_definitions(-DHELI)
set(GUI_SRC ${GUI_SRC} model_heli.cpp)
endif()
if(FLIGHT_MODES)
@ -234,7 +196,6 @@ endif()
if(CURVES)
add_definitions(-DCURVES)
set(GUI_SRC ${GUI_SRC} model_curves.cpp)
endif()
if(GVARS)
@ -318,13 +279,19 @@ set(SRC
functions.cpp
strhelpers.cpp
switches.cpp
curves.cpp
mixer.cpp
stamp.cpp
timers.cpp
trainer_input.cpp
)
if(CURVES)
set(SRC
${SRC}
curves.cpp
)
endif()
if(GUI)
add_definitions(-DGUI)
set(SRC
@ -402,7 +369,7 @@ endif()
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")
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)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/${TARGET_DIR}/bootloader)
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader)

View file

@ -388,7 +388,7 @@ void referenceModelAudioFiles()
}
// 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++) {
getLogicalSwitchAudioFile(path, i, event);
// 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];
strncpy(name, STR_VKEYS+1+len*i, len);
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)
serialPrint("[Enc.] = %d", rotencValue / 2);
#endif
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++) {
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
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")) {
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]);
}
}
@ -533,7 +533,7 @@ int cliDisplay(const char ** argv)
else if (!strcmp(argv[1], "volume")) {
serialPrint("volume = %d", getVolume());
}
#if defined(CPUSTM32)
#if defined(STM32)
else if (!strcmp(argv[1], "uid")) {
char str[LEN_CPU_UID+1];
getCPUUniqueID(str);

View file

@ -20,7 +20,9 @@
#include "opentx.h"
#if defined(XCURVES)
uint8_t s_curveChan;
#if defined(CPUARM)
int8_t * curveEnd[MAX_CURVES];
void loadCurves()
{
@ -42,10 +44,41 @@ void loadCurves()
curveEnd[i] = tmp;
}
}
int8_t * curveAddress(uint8_t idx)
{
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
int8_t * curveAddress(uint8_t idx)
{
@ -68,13 +101,41 @@ CurveInfo curveInfo(uint8_t idx)
}
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
#if defined(XCURVES)
#if defined(CPUARM)
#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;
#define MMULT 1024
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);
}
else {
s32 delta = (2 * 100) / (num_points - 1);
int32_t delta = (2 * 100) / (num_points - 1);
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);
}
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;
}
}
@ -107,7 +168,7 @@ s32 compute_tangent(CurveInfo * crv, int8_t * points, int i)
//apply monotone rules from
//http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
//1) compute slopes of secant lines
s32 d0=0, d1=0;
int32_t d0=0, d1=0;
if (crv->type == CURVE_TYPE_CUSTOM) {
int8_t x0 = CUSTOM_POINT_X(points, num_points, i-1);
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);
}
else {
s32 delta = (2 * 100) / (num_points - 1);
int32_t delta = (2 * 100) / (num_points - 1);
d0 = (MMULT * (points[i] - points[i-1])) / (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;
for (int i=0; i<count-1; i++) {
s32 p0x, p3x;
int32_t p0x, p3x;
if (custom) {
p0x = (i>0 ? calc100toRESX(points[count+i-1]) : -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) {
s32 p0y = calc100toRESX(points[i]);
s32 p3y = calc100toRESX(points[i+1]);
s32 m0 = compute_tangent(&crv, points, i);
s32 m3 = compute_tangent(&crv, points, i+1);
s32 y;
s32 h = p3x - p0x;
s32 t = (h > 0 ? (MMULT * (x - p0x)) / h : 0);
s32 t2 = t * t / MMULT;
s32 t3 = t2 * t / MMULT;
s32 h00 = 2*t3 - 3*t2 + MMULT;
s32 h10 = t3 - 2*t2 + t;
s32 h01 = -2*t3 + 3*t2;
s32 h11 = t3 - t2;
int32_t p0y = calc100toRESX(points[i]);
int32_t p3y = calc100toRESX(points[i+1]);
int32_t m0 = compute_tangent(&crv, points, i);
int32_t m3 = compute_tangent(&crv, points, i+1);
int32_t y;
int32_t h = p3x - p0x;
int32_t t = (h > 0 ? (MMULT * (x - p0x)) / h : 0);
int32_t t2 = t * t / MMULT;
int32_t t3 = t2 * t / MMULT;
int32_t h00 = 2*t3 - 3*t2 + MMULT;
int32_t h10 = t3 - 2*t2 + t;
int32_t h01 = -2*t3 + 3*t2;
int32_t h11 = t3 - t2;
y = p0y * h00 + h * (m0 * h10 / MMULT) + p3y * h01 + h * (m3 * h11 / MMULT);
y /= MMULT;
return y;
@ -189,7 +250,7 @@ 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
{
#if defined(XCURVES)
#if defined(CPUARM)
CurveInfo & crv = g_model.curves[idx];
int8_t * points = curveAddress(idx);
uint8_t count = crv.points+5;
@ -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;
}
#if defined(CURVES) && defined(XCURVES)
#if defined(CPUARM)
int applyCurve(int x, CurveRef & curve)
{
switch (curve.type) {
case CURVE_REF_DIFF:
{
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode);
if (curveParam > 0 && x < 0)
x = (x * (1000 - curveParam)) / 1000;
else if (curveParam < 0 && x > 0)
x = (x * (1000 + curveParam)) / 1000;
return x;
#else
int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode));
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:
{
#if defined(CPUARM)
int curveParam = GET_GVAR_PREC1(curve.value, -100, 100, mixerCurrentFlightMode) / 10;
#else
int curveParam = GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode);
#endif
return expo(x, curveParam);
}
@ -312,7 +360,7 @@ int applyCustomCurve(int x, uint8_t idx)
else
return intpol(x, idx);
}
#elif defined(CURVES)
#else
int applyCurve(int x, int8_t idx)
{
/* already tried to have only one return at the end */
@ -435,3 +483,32 @@ int expo(int x, int k)
}
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_
#define _DATACONSTANTS_H_
#include "board.h"
#define NUM_STICKS 4
#if defined(EXPORT)
#define LUA_EXPORT(...) LEXP(__VA_ARGS__)
#define LUA_EXPORT_MULTIPLE(...) LEXP_MULTIPLE(__VA_ARGS__)
@ -31,104 +35,87 @@
#define LUA_EXPORT_EXTRA(...)
#endif
#define NUM_STICKS 4
#if defined(PCBHORUS)
#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_MIXERS 64
#define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 64 // number of custom switches
#define NUM_CFN 64 // number of functions assigned to switches
#define MAX_LOGICAL_SWITCHES 64
#define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 9
#define MAX_INPUTS 32
#define NUM_TRAINER 16
#define NUM_POTS 7
#define NUM_XPOTS 3
#define MAX_SENSORS 32
#define MAX_TRAINER_CHANNELS 16
#define MAX_TELEMETRY_SENSORS 32
#define MAX_CUSTOM_SCREENS 5
#elif defined(PCBFLAMENCO)
#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_MIXERS 64
#define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 32 // number of custom switches
#define NUM_CFN 64 // number of functions assigned to switches
#define MAX_LOGICAL_SWITCHES 32
#define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 7
#define MAX_INPUTS 32
#define NUM_TRAINER 16
#define NUM_POTS 4
#define NUM_XPOTS 0
#define MAX_SENSORS 32
#define MAX_TRAINER_CHANNELS 16
#define NUM_POTS 4 // TODO board.h
#define NUM_SLIDERS 0 // TODO board.h
#define NUM_XPOTS 0 // TODO board.h
#define MAX_TELEMETRY_SENSORS 32
#elif defined(PCBTARANIS)
#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_MIXERS 64
#define MAX_EXPOS 64
#define NUM_LOGICAL_SWITCH 64 // number of logical switches
#define NUM_CFN 64 // number of functions assigned to switches
#define MAX_LOGICAL_SWITCHES 64
#define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_SCRIPTS 7
#define MAX_INPUTS 32
#define NUM_TRAINER 16
#if defined(PCBX9E)
#define NUM_POTS 8
#define NUM_XPOTS 4
#else
#define NUM_POTS 5
#define NUM_XPOTS 3
#endif
#define MAX_SENSORS 32
#define MAX_TRAINER_CHANNELS 16
#define MAX_TELEMETRY_SENSORS 32
#elif defined(PCBSKY9X)
#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_MIXERS 64
#define MAX_EXPOS 32
#define NUM_LOGICAL_SWITCH 64 // number of custom switches
#define NUM_CFN 64 // number of functions assigned to switches
#define NUM_TRAINER 16
#define NUM_POTS 3
#define NUM_XPOTS 0
#define MAX_SENSORS 32
#define MAX_LOGICAL_SWITCHES 64
#define MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
#define MAX_INPUTS 32
#define MAX_TRAINER_CHANNELS 16
#define MAX_TELEMETRY_SENSORS 32
#elif defined(CPUM2560) || defined(CPUM2561)
#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_MIXERS 32
#define MAX_EXPOS 16
#define NUM_LOGICAL_SWITCH 12 // number of custom switches
#define NUM_CFN 24 // number of functions assigned to switches
#define NUM_TRAINER 8
#define NUM_POTS 3
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#define MAX_LOGICAL_SWITCHES 12
#define MAX_SPECIAL_FUNCTIONS 24 // number of functions assigned to switches
#define MAX_TRAINER_CHANNELS 8
#define MAX_TELEMETRY_SENSORS 0
#elif defined(CPUM128)
#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_MIXERS 32
#define MAX_EXPOS 14
#define NUM_LOGICAL_SWITCH 12 // number of custom switches
#define NUM_CFN 24 // number of functions assigned to switches
#define NUM_TRAINER 8
#define NUM_POTS 3
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#define MAX_LOGICAL_SWITCHES 12
#define MAX_SPECIAL_FUNCTIONS 24 // number of functions assigned to switches
#define MAX_TRAINER_CHANNELS 8
#define MAX_TELEMETRY_SENSORS 0
#else
#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_MIXERS 32
#define MAX_EXPOS 14
#define NUM_LOGICAL_SWITCH 12 // number of custom switches
#define NUM_CFN 16 // number of functions assigned to switches
#define NUM_TRAINER 8
#define NUM_POTS 3
#define NUM_XPOTS 0
#define MAX_SENSORS 0
#define MAX_LOGICAL_SWITCHES 12
#define MAX_SPECIAL_FUNCTIONS 16 // number of functions assigned to switches
#define MAX_TRAINER_CHANNELS 8
#define MAX_TELEMETRY_SENSORS 0
#endif
#if defined(CPUARM)
@ -146,8 +133,13 @@ enum CurveType {
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
};
#define MIN_POINTS 3
#define MAX_POINTS 17
#if defined(CPUARM)
#define MIN_POINTS_PER_CURVE 3
#else
#define MIN_POINTS_PER_CURVE 3
#endif
#define MAX_POINTS_PER_CURVE 17
#if defined(PCBHORUS)
#define LEN_MODEL_NAME 15
@ -158,9 +150,9 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 6
#define LEN_FUNCTION_NAME 6
#define MAX_CURVES 32
#define NUM_POINTS 512
#define MAX_CURVE_POINTS 512
#elif defined(PCBFLAMENCO)
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
@ -169,9 +161,20 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8
#define LEN_FUNCTION_NAME 8
#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)
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
@ -181,22 +184,14 @@ enum CurveType {
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8
#define LEN_FUNCTION_NAME 8
#define MAX_CURVES 32
#define NUM_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
#define MAX_CURVE_POINTS 512
#else
#define LEN_MODEL_NAME 10
#define LEN_FLIGHT_MODE_NAME 6
#define MAX_CURVES 8
#define NUM_POINTS (112-MAX_CURVES)
#define MAX_CURVE_POINTS (112-MAX_CURVES)
#endif
#if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS)
@ -206,13 +201,7 @@ enum CurveType {
#endif
#if defined(PCBFLAMENCO)
#define NUM_SWITCHES 5
#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
#define NUM_SWITCHES 5 // TODO in board.h
#endif
#define XPOTS_MULTIPOS_COUNT 6
@ -250,7 +239,7 @@ enum MainViews {
VIEW_TELEM4,
VIEW_COUNT
};
#elif defined(PCBTARANIS)
#elif LCD_W >= 212
enum MainViews {
VIEW_TIMERS,
VIEW_INPUTS,
@ -325,10 +314,7 @@ enum UartModes {
#define LEN_ANA_NAME 3
#define LEN_MODEL_FILENAME 16
#define LEN_BLUETOOTH_NAME 10
#elif defined(PCBFLAMENCO)
#define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3
#elif defined(PCBTARANIS)
#elif defined(CPUARM)
#define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3
#define LEN_BLUETOOTH_NAME 10
@ -487,7 +473,7 @@ enum TelemetryUnit {
};
#endif
#if defined(PCBTARANIS)
#if LCD_W >= 212
#define NUM_LINE_ITEMS 3
#else
#define NUM_LINE_ITEMS 2
@ -699,7 +685,7 @@ enum SwitchSources {
SWSRC_SWA,
SWSRC_SWB,
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_ONE,
@ -710,7 +696,7 @@ enum SwitchSources {
SWSRC_TELEMETRY_STREAMING,
SWSRC_FIRST_SENSOR,
SWSRC_LAST_SENSOR = SWSRC_FIRST_SENSOR+MAX_SENSORS-1,
SWSRC_LAST_SENSOR = SWSRC_FIRST_SENSOR+MAX_TELEMETRY_SENSORS-1,
#endif
SWSRC_COUNT,
@ -739,10 +725,12 @@ enum SwitchSources {
enum MixSources {
MIXSRC_NONE,
#if defined(VIRTUALINPUTS)
#if defined(VIRTUAL_INPUTS)
MIXSRC_FIRST_INPUT, LUA_EXPORT_MULTIPLE("input", "Input [I%d]", MAX_INPUTS)
MIXSRC_LAST_INPUT = MIXSRC_FIRST_INPUT+MAX_INPUTS-1,
#endif
#if defined(LUA_INPUTS)
MIXSRC_FIRST_LUA,
MIXSRC_LAST_LUA = MIXSRC_FIRST_LUA+(MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)-1,
#endif
@ -877,18 +865,18 @@ enum MixSources {
MIXSRC_LAST_SWITCH = MIXSRC_TRN,
#endif
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_SWA,
MIXSRC_SWB,
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_LAST_TRAINER = MIXSRC_FIRST_TRAINER+NUM_TRAINER-1,
MIXSRC_FIRST_TRAINER, LUA_EXPORT_MULTIPLE("trn", "Trainer input %d", MAX_TRAINER_CHANNELS)
MIXSRC_LAST_TRAINER = MIXSRC_FIRST_TRAINER+MAX_TRAINER_CHANNELS-1,
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_CH3,
MIXSRC_CH4,
@ -904,7 +892,7 @@ enum MixSources {
MIXSRC_CH14,
MIXSRC_CH15,
MIXSRC_CH16,
MIXSRC_LAST_CH = MIXSRC_CH1+NUM_CHNOUT-1,
MIXSRC_LAST_CH = MIXSRC_CH1+MAX_OUTPUT_CHANNELS-1,
MIXSRC_FIRST_GVAR,
MIXSRC_GVAR1 = MIXSRC_FIRST_GVAR, LUA_EXPORT_MULTIPLE("gvar", "Global variable %d", MAX_GVARS)
@ -927,7 +915,7 @@ enum MixSources {
MIXSRC_FIRST_TELEM,
#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
MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+NUM_TELEMETRY-1
#endif
@ -1029,7 +1017,7 @@ enum ResetFunctionParam {
#endif
#if defined(CPUARM)
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
FUNC_RESET_PARAMS_COUNT,
FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1,

View file

@ -76,7 +76,7 @@ typedef uint8_t source_t;
* Mixer structure
*/
#if defined(VIRTUALINPUTS)
#if defined(CPUARM)
PACK(struct CurveRef {
uint8_t type;
int8_t value;
@ -100,29 +100,9 @@ PACK(struct MixData {
uint8_t speedDown;
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)
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 noExpo:1;
uint8_t weightMode:1;
@ -144,7 +124,7 @@ PACK(struct MixData {
});
#else
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 noExpo:1;
uint8_t weightMode:1;
@ -169,7 +149,7 @@ PACK(struct MixData {
* Expo/Input structure
*/
#if defined(VIRTUALINPUTS)
#if defined(CPUARM)
PACK(struct ExpoData {
uint16_t mode:2;
uint16_t scale:14;
@ -184,17 +164,6 @@ PACK(struct ExpoData {
int8_t offset;
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)
PACK(struct ExpoData {
uint8_t mode:2; // 0=end, 1=pos, 2=neg, 3=both
@ -222,7 +191,7 @@ PACK(struct ExpoData {
* Limit structure
*/
#if defined(VIRTUALINPUTS)
#if defined(CPUARM)
PACK(struct LimitData {
int32_t min:11;
int32_t max:11;
@ -287,7 +256,7 @@ PACK(struct CustomFunctionData {
uint16_t func:7;
PACK(union {
NOBACKUP(PACK(struct {
char name[LEN_CFN_NAME];
char name[LEN_FUNCTION_NAME];
}) play);
PACK(struct {
@ -341,7 +310,7 @@ PACK(struct CustomFunctionData {
* FlightMode structure
*/
#if defined(VIRTUALINPUTS)
#if defined(CPUARM)
PACK(struct trim_t {
int16_t value:11;
uint16_t mode:5;
@ -394,15 +363,13 @@ PACK(struct FlightModeData {
* Curve structure
*/
#if defined(XCURVES)
#if defined(CPUARM)
PACK(struct CurveData {
uint8_t type:1;
uint8_t smooth:1;
int8_t points:6; // TODO conversion
NOBACKUP(char name[LEN_CURVE_NAME]);
});
#elif defined(CPUARM)
typedef int16_t CurveData;
#else
typedef int8_t CurveData;
#endif
@ -463,7 +430,7 @@ PACK(struct TimerData {
* Swash Ring structure
*/
#if defined(VIRTUALINPUTS)
#if defined(VIRTUAL_INPUTS)
PACK(struct SwashRingData {
uint8_t type;
uint8_t value;
@ -685,7 +652,7 @@ PACK(struct ModuleData {
uint8_t failsafeMode:4; //only 3 bits used
uint8_t subType:3;
uint8_t invertedSerial:1; // telemetry serial inverted from standard
int16_t failsafeChannels[NUM_CHNOUT];
int16_t failsafeChannels[MAX_OUTPUT_CHANNELS];
union {
struct {
int8_t delay:6;
@ -786,13 +753,13 @@ PACK(struct CustomScreenData {
#endif
#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)
#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)
#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)
#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
#define MODELDATA_EXTRA
#endif
@ -817,14 +784,14 @@ PACK(struct ModelData {
AVR_FIELD(int8_t ppmDelay)
BeepANACenter beepANACenter;
MixData mixData[MAX_MIXERS];
LimitData limitData[NUM_CHNOUT];
LimitData limitData[MAX_OUTPUT_CHANNELS];
ExpoData expoData[MAX_EXPOS];
CurveData curves[MAX_CURVES];
int8_t points[NUM_POINTS];
int8_t points[MAX_CURVE_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
CustomFunctionData customFn[NUM_CFN];
LogicalSwitchData logicalSw[MAX_LOGICAL_SWITCHES];
CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES];
@ -840,7 +807,7 @@ PACK(struct ModelData {
MODELDATA_EXTRA
ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors[MAX_SENSORS]))
ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS]))
TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer)
@ -903,7 +870,7 @@ PACK(struct TrainerData {
NOBACKUP(int8_t varioPitch); \
NOBACKUP(int8_t varioRange); \
NOBACKUP(int8_t varioRepeat); \
CustomFunctionData customFn[NUM_CFN];
CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
#endif
#if defined(PCBHORUS)
@ -914,7 +881,7 @@ PACK(struct TrainerData {
uint32_t switchConfig; \
uint8_t potsConfig; /* two bits per pot */ \
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(uint8_t bluetoothEnable:1); \
NOBACKUP(uint8_t blOffBright:7); \
@ -927,7 +894,7 @@ PACK(struct TrainerData {
uint32_t switchConfig; \
uint8_t potsType; /*two bits for every pot*/\
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)
#if defined(PCBX9E)
#define BLUETOOTH_FIELDS \
@ -945,7 +912,7 @@ PACK(struct TrainerData {
swarnstate_t switchUnlockStates; \
swconfig_t switchConfig; \
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
#elif defined(PCBSKY9X)
#define EXTRA_GENERAL_FIELDS \
@ -957,7 +924,9 @@ PACK(struct TrainerData {
int8_t temperatureCalib; \
uint8_t optrexDisplay; \
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)
#define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM
#elif defined(PXX)
@ -978,7 +947,7 @@ PACK(struct TrainerData {
PACK(struct RadioData {
NOBACKUP(uint8_t version);
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);
N_HORUS_FIELD(int8_t currModel);
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 CHKTYPE(x, y) check_size<x, y>()
#if defined(VIRTUALINPUTS)
#if defined(CPUARM)
CHKSIZE(CurveRef, 2);
#endif
/* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */
/* 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(ExpoData, 19);
CHKSIZE(LimitData, 13);
@ -1081,6 +1052,9 @@ static inline void check_struct()
#if defined(PCBX9E)
CHKSIZE(RadioData, 952);
CHKSIZE(ModelData, 6520);
#elif defined(PCBX7D)
CHKSIZE(RadioData, 839);
CHKSIZE(ModelData, 6504);
#else
CHKSIZE(RadioData, 872);
CHKSIZE(ModelData, 6507);
@ -1105,19 +1079,19 @@ static inline void check_struct()
#elif defined(PCBSKY9X)
CHKSIZE(MixData, 20);
CHKSIZE(ExpoData, 11);
CHKSIZE(LimitData, 5);
CHKSIZE(ExpoData, 17);
CHKSIZE(LimitData, 13);
CHKSIZE(CustomFunctionData, 9);
CHKSIZE(FlightModeData, 38);
CHKSIZE(TimerData, 11);
CHKSIZE(SwashRingData, 3);
CHKSIZE(SwashRingData, 8);
CHKSIZE(FrSkyBarData, 5);
CHKSIZE(FrSkyLineData, 2);
CHKSIZE(FrSkyTelemetryData, 90);
CHKSIZE(ModelHeader, 12);
CHKTYPE(CurveData, 2);
CHKSIZE(RadioData, 685);
CHKSIZE(ModelData, 4671);
CHKTYPE(CurveData, 4);
CHKSIZE(RadioData, 727);
CHKSIZE(ModelData, 5252);
#else
// Common for all variants
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;
#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)
#else
#define PLAY_INDEX (i+1)
@ -273,7 +273,7 @@ void evalFunctions()
#endif
#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;
}
#endif
@ -284,7 +284,7 @@ void evalFunctions()
}
#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];
int8_t swtch = CFN_SWITCH(cfn);
if (swtch) {
@ -358,7 +358,7 @@ void evalFunctions()
#if defined(CPUARM)
if (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();
}
}
@ -376,7 +376,7 @@ void evalFunctions()
{
unsigned int moduleIndex = CFN_PARAM(cfn);
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) {
g_model.moduleData[moduleIndex].failsafeChannels[ch] = 0;
}

View file

@ -22,25 +22,401 @@
#define _GUI_H_
#include "gui_common.h"
#include "lcd.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 MENU_HEADER_HEIGHT FH
#define MENU_INIT_VPOS 0
#define DEFAULT_SCROLLBAR_X (LCD_W-1)
#define WCHART (LCD_H/2)
#define X0 (LCD_W-WCHART-2)
#define Y0 (LCD_H/2)
#define CURVE_SIDE_WIDTH (LCD_H/2)
#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
#define CURVE_CENTER_Y (LCD_H/2)
#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 drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
void drawStick(coord_t centrex, int16_t xval, int16_t yval);
void drawPotsBars();
void doMainScreenGraphics();
inline void drawProgressBar(const char * label)
{
// TODO
@ -59,7 +435,7 @@ void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uin
#endif
#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
#if defined(VOICE)
@ -81,4 +457,16 @@ void showAlertBox(const pm_char * title, const pm_char * text, const char * acti
#endif
#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_

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)
{
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);
}
#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)
{
const coord_t orig_x = x;
#if defined(CPUARM)
const uint8_t orig_len = len;
uint32_t fontsize = FONTSIZE(flags);
#endif
#if defined(CPUARM) && !defined(BOOT)
uint8_t width = 0;
if (flags & RIGHT) {
width = getTextWidth(s, len, flags);
x -= width;
}
#endif
bool setx = false;
while (len--) {
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;
lcdNextPos = x;
#if defined(CPUARM)
if (fontsize == MIDSIZE)
#if defined(CPUARM) && !defined(BOOT)
if (fontsize == MIDSIZE) {
lcdLastPos += 1;
}
if (flags & RIGHT) {
lcdLastPos -= width;
lcdNextPos -= width;
}
#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;
int8_t mode = MODE(flags);
flags &= ~LEADING0;
#if defined(CPUARM)
uint32_t fontsize = FONTSIZE(flags);
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;
}
else {
if (flags & LEFT) {
if (mode > 0)
if (IS_LEFT_ALIGNED(flags)) {
if (mode > 0) {
x += 2;
}
}
#if defined(BOLD_FONT) && !defined(CPUM64) || defined(TELEMETRY_NONE)
if (flags & BOLD) fw += 1;
#endif
}
if (flags & LEFT) {
if (IS_LEFT_ALIGNED(flags)) {
x += len * fw;
if (neg) {
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
}
void lcdDrawTelemetryTopBar()
void drawTelemetryTopBar()
{
putsModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0);
uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0);
putsVBat(14*FW,0,att);
if (g_model.timers[0].mode) {
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);
}
#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
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;
if (!(att & LEFT)) {
if (IS_RIGHT_ALIGNED(att)) {
att -= RIGHT;
if (att & DBLSIZE)
x -= 5*(2*FWNUM)-4;
else if (att & MIDSIZE)
@ -627,7 +758,7 @@ void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2
else
#endif
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
@ -642,20 +773,97 @@ void putsVBat(coord_t x, coord_t y, LcdFlags 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);
lcdDrawNumber(lcdNextPos, y, idx, att|LEFT, 2);
if (idx == MIXSRC_NONE) {
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
}
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
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 drawSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
{
if (idx < MIXSRC_THR)
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx, att);
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)
putsSwitches(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
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) {
@ -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);
#endif
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)
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);
#endif
}
#endif
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)
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
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
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);
}
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 < TMRMODE_COUNT)
@ -746,22 +952,52 @@ void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
else
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) {
uint8_t p = v - TRIM_EXTENDED_MAX - 1;
if (p >= phase) p++;
if (p >= fm) p++;
lcdDrawChar(x, y, '0'+p, att);
}
else {
putsChnLetter(x, y, idx+1, att);
}
}
#endif
#if ROTARY_ENCODERS > 0
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)
{
if (channel >= MAX_SENSORS) return;
if (channel >= MAX_TELEMETRY_SENSORS) return;
TelemetryItem & telemetryItem = telemetryItems[channel];
TelemetrySensor & telemetrySensor = g_model.telemetrySensors[channel];
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);
}
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) {
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) {
#if defined(CPUARM) && defined(RTCLOCK)
case TELEM_TX_TIME-1:
{
putsRtcTime(x, y, att);
drawRtcTime(x, y, att);
break;
}
#endif
case TELEM_TIMER1-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:
#endif
att &= ~NO_UNIT;
putsTimer(x, y, val, att, att);
drawTimer(x, y, val, att, att);
break;
#if defined(TELEMETRY_FRSKY)
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_TIMER2-1:
att &= ~NO_UNIT;
putsTimer(x, y, val, att, att);
drawTimer(x, y, val, att, att);
break;
case TELEM_TX_VOLTAGE-1:
@ -1251,44 +1485,6 @@ void lcdDrawChar(coord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
}
#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)
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
// 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)
{
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);
}
}
#endif
void lcdInvertLine(int8_t y)
#if defined(PWR_PRESS_BUTTON)
void drawShutdownAnimation(uint32_t index)
{
uint8_t *p = &displayBuf[y * LCD_W];
for (coord_t x=0; x<LCD_W; x++) {
ASSERT_IN_DISPLAY(p);
*p++ ^= 0xff;
lcdClear();
int quarter = index / (PWR_PRESS_SHUTDOWN / 5);
for (int i=1; i<=4; i++) {
if (quarter >= i) {
lcdDrawFilledRect(LCD_W / 2 - 28 + 10 * i, LCD_H / 2 - 3, 6, 6, SOLID, 0);
}
}
#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; \
} \
} \
lcdRefresh();
}
#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

View file

@ -23,8 +23,6 @@
#include <inttypes.h>
#define LCD_W 128
#define LCD_H 64
#define BOX_WIDTH 23
#define coord_t uint8_t
#define scoord_t int8_t
@ -34,11 +32,11 @@
#define CONTRAST_MAX 45
#if defined(CPUARM)
#define lcdint_t int32_t
#define lcduint_t uint32_t
typedef int32_t lcdint_t;
typedef uint32_t lcduint_t;
#else
#define lcdint_t int16_t
#define lcduint_t uint16_t
typedef int16_t lcdint_t;
typedef uint16_t lcduint_t;
#endif
#define FW 6
@ -78,8 +76,16 @@
#define PREC1 0x20
#define PREC2 0x30
#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 RIGHT 0x00 /* fake */
#define IS_LEFT_ALIGNED(att) ((att) & LEFT)
#endif
#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att))
/* line, rect, square flags */
#define FORCE 0x02
@ -116,9 +122,9 @@
#endif
#if defined(CPUARM)
#define LcdFlags uint32_t
typedef uint32_t LcdFlags;
#else
#define LcdFlags uint8_t
typedef uint8_t LcdFlags;
#endif
#define display_t uint8_t
@ -126,8 +132,6 @@
extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#define lcdRefreshWait()
extern coord_t lcdLastPos;
extern coord_t lcdNextPos;
@ -172,17 +176,25 @@ 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 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);
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void putsFlightMode(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
#if !defined(BOOT) // TODO not here ...
void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, 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 putsTimerMode(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 drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0);
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)
void putsRotaryEncoderMode(coord_t x, coord_t y, uint8_t phase, uint8_t idx, LcdFlags att);
#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 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
#endif
void putsRtcTime(coord_t x, coord_t y, LcdFlags att);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
void drawRtcTime(coord_t x, coord_t y, LcdFlags att);
void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
#define SOLID 0xff
#define DOTTED 0x55
@ -230,7 +242,7 @@ void lcdInvertLine(int8_t line);
#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); }
void lcdDrawTelemetryTopBar();
void drawTelemetryTopBar();
#define V_BAR(xx, yy, 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"
#endif
void lcdClear(void);
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)
#define BLINK_ON_PHASE (0)
#else
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
#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();
void drawShutdownAnimation(uint32_t index);
#endif // _LCD_H_

View file

@ -35,13 +35,106 @@ uint8_t editDelay(const coord_t y, const uint8_t event, const uint8_t attr, cons
uint8_t s_copyMode = 0;
int8_t s_copySrcRow;
int8_t s_copyTgtOfs;
uint8_t s_maxLines = 8;
uint8_t s_copySrcIdx;
uint8_t s_copySrcCh;
#if defined(CPUM64)
#define editNameCursorPos menuHorizontalPosition
#else
static uint8_t editNameCursorPos = 0;
uint8_t editNameCursorPos = 0;
#endif
#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)
@ -125,6 +218,7 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
editNameCursorPos = cur;
}
}
#endif
#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)

View file

@ -23,7 +23,7 @@
#if defined(CPUARM)
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);
}
#endif

View file

@ -23,19 +23,23 @@
#include "keys.h"
#define MENUS_SCROLLBAR_WIDTH 0
#define MENU_COLUMNS 1
#define COLUMN_X 0
#define drawFieldLabel(x, y, str) lcdDrawTextAlignedLeft(y, str)
#if defined(PCBX7D)
typedef int8_t horzpos_t;
#define NAVIGATION_LINE_BY_LINE 0x40
#define IS_LINE_SELECTED(sub, k) ((sub)==(k) && menuHorizontalPosition < 0)
#else
typedef uint8_t horzpos_t;
#define NAVIGATION_LINE_BY_LINE 0
#define IS_LINE_SELECTED(sub, k) (false)
#endif
// Menus related stuff ...
#if defined(SDCARD)
typedef uint16_t vertpos_t;
#else
typedef uint8_t vertpos_t;
#endif
#define horzpos_t uint8_t
typedef void (*MenuHandlerFunc)(uint8_t event);
#if defined(CPUARM)
extern tmr10ms_t menuEntryTime;
@ -44,43 +48,28 @@
extern vertpos_t menuVerticalPosition;
extern horzpos_t menuHorizontalPosition;
extern vertpos_t menuVerticalOffset;
extern uint8_t calibrationState;
// 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 uint8_t menuCalibrationState;
extern MenuHandlerFunc menuHandlers[5];
extern uint8_t menuVerticalPositions[4];
extern uint8_t menuLevel;
extern uint8_t menuEvent;
/// goto given Menu, but substitute current menu in menuStack
void chainMenu(MenuHandlerFunc newMenu);
/// goto given Menu, store current menu in menuStack
void pushMenu(MenuHandlerFunc newMenu);
/// return to last menu in menustack
void popMenu();
///deliver address of last menu which was popped from
inline MenuHandlerFunc lastPopMenu()
{
return menuHandlers[menuLevel+1];
}
void drawPotsBars();
void doMainScreenGraphics();
void menuFirstCalib(uint8_t event);
void onMainViewMenu(const char * result);
void menuFirstCalib(uint8_t event);
void menuMainView(uint8_t event);
void menuViewTelemetryFrsky(uint8_t event);
void menuViewTelemetryMavlink(uint8_t event);
void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
enum MenuRadioIndexes
@ -90,9 +79,9 @@ enum MenuRadioIndexes
CASE_CPUARM(MENU_RADIO_SPECIAL_FUNCTIONS)
MENU_RADIO_TRAINER,
MENU_RADIO_VERSION,
MENU_RADIO_DIAG_KEYS,
MENU_RADIO_DIAG_ANALOGS,
CASE_CPUARM(MENU_RADIO_HARDWARE)
MENU_RADIO_SWITCHES_TEST,
MENU_RADIO_ANALOGS_TEST,
CASE_PCBSKY9X(MENU_RADIO_HARDWARE)
MENU_RADIO_CALIBRATION,
MENU_RADIO_PAGES_COUNT
};
@ -115,11 +104,11 @@ static const MenuHandlerFunc menuTabGeneral[] PROGMEM = {
menuRadioVersion,
menuRadioDiagKeys,
menuRadioDiagAnalogs,
CASE_CPUARM(menuRadioHardware)
CASE_PCBSKY9X(menuRadioHardware)
menuRadioCalibration
};
enum EnumTabModel {
enum MenuModelIndexes {
MENU_MODEL_SELECT,
MENU_MODEL_SETUP,
CASE_HELI(MENU_MODEL_HELI)
@ -132,6 +121,7 @@ enum EnumTabModel {
MENU_MODEL_SPECIAL_FUNCTIONS,
CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY)
CASE_MAVLINK(MENU_MODEL_TELEMETRY_MAVLINK)
CASE_CPUARM(MENU_MODEL_DISPLAY)
CASE_TEMPLATES(MENU_MODEL_TEMPLATES)
MENU_MODEL_PAGES_COUNT
};
@ -150,6 +140,7 @@ void menuModelLogicalSwitches(uint8_t event);
void menuModelSpecialFunctions(uint8_t event);
void menuModelTelemetryFrsky(uint8_t event);
void menuModelTelemetryMavlink(uint8_t event);
void menuModelDisplay(uint8_t event);
void menuModelTemplates(uint8_t event);
void menuModelExpoOne(uint8_t event);
@ -166,404 +157,16 @@ static const MenuHandlerFunc menuTabModel[] PROGMEM = {
menuModelSpecialFunctions,
CASE_FRSKY(menuModelTelemetryFrsky)
CASE_MAVLINK(menuModelTelemetryMavlink)
CASE_CPUARM(menuModelDisplay)
CASE_TEMPLATES(menuModelTemplates)
};
void menuStatisticsView(uint8_t event);
void menuStatisticsDebug(uint8_t event);
void menuAboutView(uint8_t event);
#if defined(DEBUG_TRACE_BUFFER)
void menuTraceBuffer(uint8_t event);
#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_

View file

@ -20,73 +20,6 @@
#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)
{
TITLE(STR_MENUCURVE);
@ -99,6 +32,7 @@ void menuModelCurveOne(uint8_t event)
case EVT_ENTRY:
s_editMode = 1;
break;
CASE_EVT_ROTARY_BREAK
case EVT_KEY_BREAK(KEY_ENTER):
if (s_editMode <= 0)
@ -108,6 +42,7 @@ void menuModelCurveOne(uint8_t event)
else
s_editMode = 1;
break;
case EVT_KEY_LONG(KEY_ENTER):
if (s_editMode <= 0) {
if (int8_t(++menuHorizontalPosition) > 4)
@ -118,6 +53,7 @@ void menuModelCurveOne(uint8_t event)
killEvents(event);
}
break;
case EVT_KEY_BREAK(KEY_EXIT):
if (s_editMode > 0) {
if (--s_editMode == 0)
@ -136,7 +72,7 @@ void menuModelCurveOne(uint8_t event)
if (crv.custom) {
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);
}
else {
@ -154,7 +90,7 @@ void menuModelCurveOne(uint8_t event)
if (!crv.custom) {
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)) {
for (int8_t i=crv.points+crv.points-2; i>=0; i--) {
if (i%2)
@ -176,7 +112,7 @@ void menuModelCurveOne(uint8_t event)
lcdDrawNumber(5*FW-2, 7*FH, crv.points, LEFT|attr);
lcdDrawText(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr);
DrawCurve();
drawCurve();
if (s_editMode>0) {
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
}
}
#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);
}
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_SWITCH,
ITEM_MODEL_PHASE_TRIMS,
@ -55,22 +79,27 @@ enum menuModelPhaseItems {
ITEM_MODEL_PHASE_MAX
};
bool isTrimModeAvailable(int mode)
{
return (mode < 0 || (mode%2) == 0 || (mode/2) != s_currIdx);
}
void menuModelPhaseOne(uint8_t event)
{
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_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));
TITLE(STR_MENUFLIGHTPHASE);
TITLE(STR_MENUFLIGHTMODE);
#define PHASE_ONE_FIRST_LINE (1+1*FH)
#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)
#endif
@ -94,23 +123,37 @@ void menuModelPhaseOne(uint8_t event)
case ITEM_MODEL_PHASE_NAME:
editSingleName(MIXES_2ND_COLUMN, y, STR_PHASENAME, fm->name, sizeof(fm->name), event, attr);
break;
case ITEM_MODEL_PHASE_SWITCH:
fm->swtch = switchMenuItem(MIXES_2ND_COLUMN, y, fm->swtch, attr, event);
break;
case ITEM_MODEL_PHASE_TRIMS:
lcdDrawTextAlignedLeft(y, STR_TRIMS);
#if defined(CPUARM)
for (uint8_t t = 0; t < NUM_STICKS; t++) {
putsTrimMode(MIXES_2ND_COLUMN+(t*FW), y, s_currIdx, t, menuHorizontalPosition==t ? attr : 0);
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);
if (v < TRIM_EXTENDED_MAX) v = TRIM_EXTENDED_MAX;
if (v < TRIM_EXTENDED_MAX)
v = TRIM_EXTENDED_MAX;
v = checkIncDec(event, v, TRIM_EXTENDED_MAX, TRIM_EXTENDED_MAX + MAX_FLIGHT_MODES - 1, EE_MODEL);
if (checkIncDec_Ret) {
if (v == TRIM_EXTENDED_MAX) v = 0;
if (v == TRIM_EXTENDED_MAX)
v = 0;
setTrimValue(s_currIdx, t, v);
}
}
}
#endif
break;
#if ROTARY_ENCODERS > 0
@ -158,7 +201,7 @@ void menuModelPhaseOne(uint8_t event)
if (v > GVAR_MAX) {
uint8_t p = v - GVAR_MAX - 1;
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 {
lcdDrawText(11*FW, y, STR_OWN, posHorz==1 ? attr : 0);
@ -205,9 +248,9 @@ void menuModelPhaseOne(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) {
CASE_EVT_ROTARY_BREAK
@ -217,7 +260,9 @@ void menuModelFlightModesAll(uint8_t event)
trimsCheckTimer = 200; // 2 seconds
}
// no break
#if !defined(PCBX7D)
case EVT_KEY_FIRST(KEY_RIGHT):
#endif
if (sub >= 0 && sub < MAX_FLIGHT_MODES) {
s_currIdx = sub;
pushMenu(menuModelPhaseOne);
@ -235,16 +280,16 @@ void menuModelFlightModesAll(uint8_t event)
#endif
att = (i==sub ? INVERS : 0);
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);
if (i == 0) {
lcdDrawText((5+LEN_FLIGHT_MODE_NAME)*FW+SWITCH_OFS, y, STR_DEFAULT);
}
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++) {
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)
for (uint8_t t=0; t<NUM_ROTARY_ENCODERS; t++) {
@ -254,7 +299,7 @@ void menuModelFlightModesAll(uint8_t event)
}
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
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) {
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_FM_WIDTH (5*FW)
#if defined(FLIGHT_MODES)
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr)
{
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)
int expoFn(int x)
{
ExpoData *ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
@ -69,20 +34,20 @@ int16_t expoFn(int16_t x)
void drawFunction(FnFuncP fn, uint8_t offset)
{
lcdDrawVerticalLine(X0-offset, 0, LCD_H, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee);
lcdDrawVerticalLine(CURVE_CENTER_X-offset, 0, LCD_H, 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 (int8_t xv=-WCHART; xv<=WCHART; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX);
for (int8_t 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(X0+xv-offset-1, prev_yv, FORCE);
lcdDrawPoint(CURVE_CENTER_X+xv-offset-1, prev_yv, FORCE);
}
else {
uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv);
lcdDrawSolidVerticalLine(CURVE_CENTER_X+xv-offset-1, yv+tmp, 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 (((MixData *)x)->destCh == NUM_CHNOUT-1)
if (((MixData *)x)->destCh == MAX_OUTPUT_CHANNELS-1)
return false;
((MixData *)x)->destCh++;
return true;
@ -234,7 +199,7 @@ bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up)
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) ((MixData *)x)->destCh++;
if (destCh<MAX_OUTPUT_CHANNELS-1) ((MixData *)x)->destCh++;
else return false;
}
return true;
@ -267,20 +232,17 @@ enum ExposFields {
void menuModelExpoOne(uint8_t event)
{
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 /*, ...*/});
SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW);
int8_t sub = menuVerticalPosition;
coord_t y = MENU_HEADER_HEIGHT + 1;
for (uint8_t i=0; i<EXPO_FIELD_MAX+1; i++) {
uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch(i)
{
switch (i) {
#if defined(CPUARM)
case EXPO_FIELD_NAME:
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:
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;
case EXPO_FIELD_EXPO:
@ -348,10 +310,10 @@ void menuModelExpoOne(uint8_t event)
lcdDrawNumber(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0);
#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;
#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;
#endif
@ -457,31 +419,12 @@ 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 /*, ...*/});
#endif
#if MENU_COLUMNS > 1
lcdDrawSolidVerticalLine(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1);
#endif
int8_t sub = menuVerticalPosition;
int8_t editMode = s_editMode;
for (uint8_t k=0; k<MENU_COLUMNS*(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
for (uint8_t k=0; k<LCD_LINES-1; k++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH;
int8_t i = k + menuVerticalOffset;
#endif
uint8_t attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (i) {
@ -492,7 +435,7 @@ void menuModelMixOne(uint8_t event)
#endif
case MIX_FIELD_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);
break;
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) _STR_MAX(x)
@ -613,7 +552,7 @@ static uint8_t s_copySrcCh;
#define EXPO_LINE_SIDE_POS 14*FW+2
#define EXPO_LINE_SELECT_POS 24
#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_WEIGHT_POS 11*FW+3
#define MIX_LINE_CURVE_POS 12*FW+2
@ -628,7 +567,7 @@ static uint8_t s_copySrcCh;
#else
#define EXPO_LINE_SIDE_POS 15*FW+2
#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 MIX_LINE_SRC_POS 4*FW-1
#define MIX_LINE_WEIGHT_POS 11*FW+3
@ -676,7 +615,7 @@ void displayMixInfos(coord_t y, MixData *md)
}
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
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)
@ -884,13 +823,13 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
uint8_t cur = 1;
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;
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 (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) {
if (expo) {
putsMixerSource(0, y, MIXSRC_Rud+ch-1, 0);
drawSource(0, y, MIXSRC_Rud+ch-1, 0);
}
else {
putsChn(0, y, ch, 0); // show CHx
@ -923,7 +862,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
else {
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);
@ -965,7 +904,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
}
if (menuVerticalOffset < cur && cur-menuVerticalOffset < LCD_LINES) {
if (expo) {
putsMixerSource(0, y, MIXSRC_Rud+ch-1, attr);
drawSource(0, y, MIXSRC_Rud+ch-1, attr);
}
else {
putsChn(0, y, ch, attr); // show CHx

View file

@ -64,7 +64,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
LogicalSwitchData * cs = lswAddress(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...*/ });
@ -79,6 +79,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
uint8_t i = k + menuVerticalOffset;
uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
uint8_t cstate = lswFamily(cs->func);
switch (i) {
case LS_FIELD_FUNCTION:
lcdDrawTextAlignedLeft(y, STR_FUNC);
@ -99,12 +100,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
}
break;
case LS_FIELD_V1:
{
lcdDrawTextAlignedLeft(y, STR_V1);
int v1_min=0, v1_max=MIXSRC_LAST_TELEM;
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;
}
else if (cstate == LS_FAMILY_TIMER) {
@ -114,7 +116,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
else {
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_ENABLE_CHECK(isSourceAvailable);
}
@ -123,12 +125,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
break;
}
case LS_FIELD_V2:
{
lcdDrawTextAlignedLeft(y, STR_V2);
int v2_min=0, v2_max=MIXSRC_LAST_TELEM;
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;
}
else if (cstate == LS_FAMILY_TIMER) {
@ -146,7 +149,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
v2_min = -129; v2_max = 122;
}
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_ENABLE_CHECK(isSourceAvailable);
}
@ -184,11 +187,13 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
break;
}
case LS_FIELD_ANDSW:
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);
break;
case LS_FIELD_DURATION:
lcdDrawTextAlignedLeft(y, STR_DURATION);
if (cs->duration > 0)
@ -197,6 +202,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
lcdDrawTextAtIndex(CSWONE_2ND_COLUMN, y, STR_MMMINV, 0, attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, cs->duration, MAX_LS_DURATION);
break;
case LS_FIELD_DELAY:
lcdDrawTextAlignedLeft(y, STR_DELAY);
if (cs->delay > 0)
@ -211,17 +217,19 @@ void menuModelLogicalSwitchOne(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;
uint8_t k = 0;
int8_t sub = menuVerticalPosition - 1;
int8_t sub = menuVerticalPosition - HEADER_LINE;
switch (event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_BREAK:
#endif
#if !defined(PCBX7D)
case EVT_KEY_FIRST(KEY_RIGHT):
#endif
case EVT_KEY_FIRST(KEY_ENTER):
if (sub >= 0) {
s_currIdx = sub;
@ -238,7 +246,7 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW name
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) {
// CSW func
@ -248,15 +256,15 @@ void menuModelLogicalSwitches(uint8_t event)
uint8_t cstate = lswFamily(cs->func);
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, 0);
drawSwitch(CSW_2ND_COLUMN, y, cs->v1, 0);
drawSwitch(CSW_3RD_COLUMN, y, cs->v2, 0);
}
else if (cstate == LS_FAMILY_COMP) {
putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, 0);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, 0);
drawSource(CSW_2ND_COLUMN, y, cs->v1, 0);
drawSource(CSW_3RD_COLUMN, y, cs->v2, 0);
}
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);
}
else if (cstate == LS_FAMILY_TIMER) {
@ -265,7 +273,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
else {
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 defined(CPUARM)
putsChannelValue(CSW_3RD_COLUMN, y, v1, convertLswTelemValue(cs), LEFT);
@ -279,7 +287,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
// 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);
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;
int8_t sub = menuVerticalPosition - 1;
int8_t sub = menuVerticalPosition - HEADER_LINE;
horzpos_t horz = menuHorizontalPosition;
for (uint8_t i=0; i<LCD_LINES-1; i++) {
@ -306,7 +314,7 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW name
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
lcdDrawTextAtIndex(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, horz==0 ? attr : 0);
@ -322,8 +330,8 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
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;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
@ -331,7 +339,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
#if defined(CPUARM)
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);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122;
@ -350,8 +358,8 @@ void menuModelLogicalSwitches(uint8_t event)
#if defined(CPUARM)
v1_val = (uint8_t)cs->v1;
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
@ -367,7 +375,7 @@ void menuModelLogicalSwitches(uint8_t event)
#if defined(CPUARM)
v1_val = (uint8_t)cs->v1;
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -438,13 +446,13 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW AND switch
#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
uint8_t andsw = cs->andsw;
if (andsw > SWSRC_LAST_SWITCH) {
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
#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;
}
enum LimitsItems {
ITEM_LIMITS_OFFSET,
ITEM_LIMITS_MIN,
ITEM_LIMITS_MAX,
ITEM_LIMITS_DIRECTION,
enum MenuModelOutputsItems {
ITEM_OUTPUTS_OFFSET,
ITEM_OUTPUTS_MIN,
ITEM_OUTPUTS_MAX,
ITEM_OUTPUTS_DIRECTION,
#if defined(PPM_CENTER_ADJUSTABLE)
ITEM_LIMITS_PPM_CENTER,
ITEM_OUTPUTS_PPM_CENTER,
#endif
#if defined(PPM_LIMITS_SYMETRICAL)
ITEM_LIMITS_SYMETRICAL,
ITEM_OUTPUTS_SYMETRICAL,
#endif
ITEM_LIMITS_COUNT,
ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1
ITEM_OUTPUTS_COUNT,
ITEM_OUTPUTS_MAXROW = ITEM_OUTPUTS_COUNT-1
};
#if defined(PPM_UNIT_US)
@ -89,21 +89,21 @@ enum LimitsItems {
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)
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);
#else
lcdDrawNumber(13*FW, 0, calcRESXto1000(channelOutputs[sub]), PREC1);
lcdDrawNumber(13*FW, 0, calcRESXto1000(channelOutputs[sub]), RIGHT|PREC1);
#endif
}
#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
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
if (warningResult) {
@ -117,9 +117,9 @@ void menuModelLimits(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) {
if (k == MAX_OUTPUT_CHANNELS) {
// 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);
if (attr) {
s_editMode = 0;
@ -145,19 +145,18 @@ void menuModelLimits(uint8_t event)
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 active = (attr && (s_editMode>0 || p1valdiff)) ;
if (active) STICK_SCROLL_DISABLE();
switch(j)
{
case ITEM_LIMITS_OFFSET:
switch (j) {
case ITEM_OUTPUTS_OFFSET:
#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
lcdDrawNumber(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1);
lcdDrawNumber(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1|RIGHT);
#endif
if (active) {
#if defined(CPUARM)
@ -172,8 +171,8 @@ void menuModelLimits(uint8_t event)
}
break;
case ITEM_LIMITS_MIN:
lcdDrawNumber(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR);
case ITEM_OUTPUTS_MIN:
lcdDrawNumber(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR|RIGHT);
#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);
#else
@ -181,8 +180,8 @@ void menuModelLimits(uint8_t event)
#endif
break;
case ITEM_LIMITS_MAX:
lcdDrawNumber(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR);
case ITEM_OUTPUTS_MAX:
lcdDrawNumber(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR|RIGHT);
#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);
#else
@ -190,7 +189,7 @@ void menuModelLimits(uint8_t event)
#endif
break;
case ITEM_LIMITS_DIRECTION:
case ITEM_OUTPUTS_DIRECTION:
{
uint8_t revert = ld->revert;
#if defined(PPM_CENTER_ADJUSTABLE)
@ -211,8 +210,8 @@ void menuModelLimits(uint8_t event)
}
#if defined(PPM_CENTER_ADJUSTABLE)
case ITEM_LIMITS_PPM_CENTER:
lcdDrawNumber(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, attr);
case ITEM_OUTPUTS_PPM_CENTER:
lcdDrawNumber(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, RIGHT|attr);
if (active) {
CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX);
}
@ -220,11 +219,11 @@ void menuModelLimits(uint8_t event)
#endif
#if defined(PPM_LIMITS_SYMETRICAL)
case ITEM_LIMITS_SYMETRICAL:
case ITEM_OUTPUTS_SYMETRICAL:
#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
lcdDrawChar(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, ld->symetrical ? '=' : '^', attr);
lcdDrawChar(LCD_W-FW, y, ld->symetrical ? '=' : '^', attr);
#endif
if (active) {
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) {
if (!sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) {
POPUP_WARNING(STR_NO_MODELS_ON_SD);
popupMenuFlags = 0;
POPUP_MENU_UNSET_BSS_FLAG();
}
}
#endif
@ -92,7 +92,7 @@ void menuModelSelect(uint8_t event)
int8_t oldSub = menuVerticalPosition;
check_submenu_simple(_event_, MAX_MODELS-1);
check_submenu_simple(_event_, MAX_MODELS-HEADER_LINE);
#if defined(NAVIGATION_POT2)
if (event==0 && p2valdiff<0) {
@ -110,8 +110,7 @@ void menuModelSelect(uint8_t event)
int8_t sub = menuVerticalPosition;
switch (event)
{
switch (event) {
case EVT_ENTRY:
menuVerticalPosition = sub = g_eeGeneral.currModel;
if (sub >= LCD_LINES-1) menuVerticalOffset = sub-LCD_LINES+2;
@ -254,6 +253,16 @@ void menuModelSelect(uint8_t event)
}
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)
case EVT_ROTARY_LEFT:
case EVT_ROTARY_RIGHT:
@ -273,6 +282,7 @@ void menuModelSelect(uint8_t event)
#if defined(ROTARY_ENCODER_NAVIGATION)
}
// no break
#endif
#endif
case EVT_KEY_FIRST(KEY_UP):
@ -302,13 +312,19 @@ void menuModelSelect(uint8_t event)
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);
if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree();
lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0);
lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, RIGHT);
#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);
#else
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;
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 (k == sub) {
@ -347,11 +363,12 @@ void menuModelSelect(uint8_t event)
char * name = reusableBuffer.modelsel.listnames[i];
if (event) eeLoadModelName(k, name);
putsModelName(4*FW, y, name, k, 0);
lcdDrawNumber(20*FW, y, eeModelSize(k), 0);
lcdDrawNumber(20*FW, y, eeModelSize(k), RIGHT);
#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, '*');
}
}
if (s_copyMode && (vertpos_t)sub==i+menuVerticalOffset) {
lcdDrawFilledRect(9, y, MODELSEL_W-1-9, 7);

View file

@ -25,7 +25,7 @@ uint8_t g_moduleIdx;
void menuModelFailsafe(uint8_t event);
#endif
enum menuModelSetupItems {
enum MenuModelSetupItems {
ITEM_MODEL_NAME,
ITEM_MODEL_TIMER1,
CASE_CPUARM(ITEM_MODEL_TIMER1_NAME)
@ -55,6 +55,13 @@ enum menuModelSetupItems {
ITEM_MODEL_SWITCHES_WARNING,
ITEM_MODEL_BEEP_CENTER,
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)
ITEM_MODEL_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_MODE,
@ -79,6 +86,12 @@ enum menuModelSetupItems {
#else
ITEM_MODEL_PPM1_PROTOCOL,
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
ITEM_MODEL_SETUP_MAX
};
@ -89,23 +102,37 @@ enum menuModelSetupItems {
#define FIELD_PROTOCOL_MAX 1
#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_RANGE_OFS 4*FW+3
#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)
#else
#define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE)
#endif
void menuModelSetup(uint8_t event)
{
#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_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW)
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)(x) : HIDDEN_ROW)
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_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
@ -114,10 +141,9 @@ void menuModelSetup(uint8_t event)
#else
#define OUTPUT_TYPE_ROWS()
#endif
#define TRAINER_CHANNELS_ROWS() (HIDDEN_ROW)
#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_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].multi.rfProtocol))) ? (uint8_t) 0: HIDDEN_ROW
#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 CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX)
#define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
#define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX)
#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
#if defined(PCBSKY9X) && !defined(REVA)
#define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2,
#else
#define EXTRA_MODULE_ROWS
#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
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),
EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
@ -161,15 +212,11 @@ void menuModelSetup(uint8_t event)
EXTRA_MODULE_ROWS
TRAINER_MODULE_ROWS });
#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;
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
#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;
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
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, MODEL_SETUP_MAX_LINES);
@ -185,7 +232,7 @@ void menuModelSetup(uint8_t event)
TITLE(STR_MENUSETUP);
uint8_t sub = menuVerticalPosition - 1;
uint8_t sub = menuVerticalPosition - HEADER_LINE;
int8_t editMode = s_editMode;
for (uint8_t i=0; i<NUM_BODY_LINES; ++i) {
@ -193,7 +240,7 @@ void menuModelSetup(uint8_t event)
uint8_t k = i+menuVerticalOffset;
#if defined(CPUARM)
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)) {
return;
}
@ -220,8 +267,8 @@ void menuModelSetup(uint8_t event)
unsigned int timerIdx = (k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0));
TimerData * timer = &g_model.timers[timerIdx];
drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1);
putsTimerMode(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);
drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? 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)) {
div_t qr = div(timer->start, 60);
switch (menuHorizontalPosition) {
@ -311,8 +358,8 @@ void menuModelSetup(uint8_t event)
}
else {
drawStringWithIndex(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1);
putsTimerMode(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);
drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? 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)) {
div_t qr = div(timer->start, 60);
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);
#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);
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) {
s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)) {
@ -390,13 +437,13 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_THROTTLE_TRACE:
{
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;
if (idx > MIXSRC_Thr)
idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS;
putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break;
}
@ -492,7 +539,7 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_BEEP_CENTER:
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
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 ) );
@ -516,6 +563,25 @@ void menuModelSetup(uint8_t event)
break;
#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)
case ITEM_MODEL_EXTRA_MODULE_LABEL:
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);
break;
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 + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 1 ? 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, RIGHT | (menuHorizontalPosition == 1 ? attr : 0), 2);
break;
}
if (attr && (editMode > 0 || p1valdiff)) {
@ -670,6 +736,23 @@ void menuModelSetup(uint8_t event)
}
break;
#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)
case ITEM_MODEL_EXTRA_MODULE_CHANNELS:
#endif
@ -702,6 +785,10 @@ void menuModelSetup(uint8_t event)
}
#endif
#if defined(PCBX7D)
case ITEM_MODEL_TRAINER_SETTINGS:
case ITEM_MODEL_INTERNAL_MODULE_BIND:
#endif
#if defined(PCBSKY9X)
case ITEM_MODEL_EXTRA_MODULE_BIND:
#endif
@ -715,9 +802,8 @@ void menuModelSetup(uint8_t event)
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);
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);
if (attr && (editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) {
case 0:
@ -783,6 +869,9 @@ void menuModelSetup(uint8_t event)
}
#endif
#if defined(PCBX7D)
case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE:
#endif
#if defined(CPUARM)
case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE:
{
@ -813,7 +902,7 @@ void menuModelSetup(uint8_t event)
}
}
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);
}
}
}
@ -907,7 +996,7 @@ void menuModelSetup(uint8_t event)
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);
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);
if (attr && (editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) {
@ -1005,9 +1094,7 @@ void menuModelFailsafe(uint8_t event)
SEND_FAILSAFE_NOW(g_moduleIdx);
}
SIMPLE_SUBMENU_NOTITLE(NUM_CHNOUT);
SET_SCROLLBAR_X(0);
SIMPLE_SUBMENU_NOTITLE(MAX_OUTPUT_CHANNELS);
#define COL_W (LCD_W)
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)) {
POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD);
popupMenuFlags = 0;
POPUP_MENU_UNSET_BSS_FLAG();
}
}
else {
@ -72,7 +72,7 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext)
{
int8_t sub = menuVerticalPosition - 1;
int8_t sub = menuVerticalPosition - HEADER_LINE;
#if defined(CPUARM)
uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL;
@ -80,7 +80,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
uint8_t eeFlags = EE_MODEL;
#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;
uint8_t k = i+menuVerticalOffset;
@ -91,7 +91,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
uint8_t active = (attr && (s_editMode>0 || p1valdiff));
switch (j) {
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 defined(CPUARM)
if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) {
@ -122,7 +122,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
case 2:
{
int8_t maxParam = NUM_CHNOUT-1;
int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) {
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) {
maxParam = 4;
#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
putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
drawSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#endif
}
#if defined(GVARS)
@ -197,7 +197,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#if defined(CPUARM)
else if (func == FUNC_SET_TIMER) {
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
#if defined(AUDIO)
@ -234,21 +234,21 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
}
else {
POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD);
popupMenuFlags = 0;
POPUP_MENU_UNSET_BSS_FLAG();
}
}
break;
}
else if (func == FUNC_PLAY_VALUE) {
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);
}
#endif
#if defined(CPUARM)
else if (func == FUNC_VOLUME) {
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_ENABLE_CHECK(isSourceAvailable);
}
@ -278,7 +278,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
}
else if (func == FUNC_PLAY_VALUE) {
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);
}
#endif
@ -303,7 +303,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
break;
case FUNC_ADJUST_GVAR_SOURCE:
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_ENABLE_CHECK(isSourceAvailable);
break;
@ -377,6 +377,6 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
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);
}

View file

@ -96,6 +96,8 @@ enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_VARIO_SOURCE,
#endif
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_LINE1,
ITEM_TELEMETRY_SCREEN_LINE2,
@ -106,17 +108,6 @@ enum MenuModelTelemetryFrskyItems {
ITEM_TELEMETRY_SCREEN_LINE6,
ITEM_TELEMETRY_SCREEN_LINE7,
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
ITEM_TELEMETRY_MAX
};
@ -181,12 +172,11 @@ enum MenuModelTelemetryFrskyItems {
#endif
#if defined(CPUARM)
#define TELEMETRY_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2)
#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)))
#define TELEMETRY_SCREENS_ROWS
#else
#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_SCREENS_ROWS TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1)
#endif
#if defined(CPUARM)
@ -322,25 +312,25 @@ void menuModelSensor(uint8_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
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) {
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;
}
@ -372,9 +362,9 @@ void menuModelSensor(uint8_t event)
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
@ -396,14 +386,14 @@ void menuModelSensor(uint8_t event)
drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
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) {
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 {
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;
}
@ -436,14 +426,14 @@ void onSensorMenu(const char *result)
{
uint8_t index = menuVerticalPosition - 1 - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) {
if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) {
pushMenu(menuModelSensor);
}
else if (result == STR_DELETE) {
delTelemetryIndex(index);
index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index))
if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1;
else
menuVerticalPosition = 1+ITEM_TELEMETRY_NEW_SENSOR;
@ -473,21 +463,23 @@ void menuModelTelemetryFrsky(uint8_t event)
#if defined(CPUARM)
if (warningResult) {
warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
}
#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) {
case EVT_KEY_BREAK(KEY_DOWN):
case EVT_KEY_BREAK(KEY_UP):
#if !defined(PCBX7D)
case EVT_KEY_BREAK(KEY_LEFT):
case EVT_KEY_BREAK(KEY_RIGHT):
#endif
if (s_editMode>0 && sub<=ITEM_TELEMETRY_RSSI_ALARM2)
frskySendAlarms(); // update FrSky module when edit mode exited
break;
@ -498,7 +490,7 @@ void menuModelTelemetryFrsky(uint8_t event)
uint8_t k = i + menuVerticalOffset;
#if defined(CPUARM)
for (int j=0; j<=k; j++) {
if (mstate_tab[j+1] == HIDDEN_ROW)
if (mstate_tab[j+HEADER_LINE] == HIDDEN_ROW)
k++;
}
#endif
@ -513,7 +505,7 @@ void menuModelTelemetryFrsky(uint8_t event)
#endif
#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;
lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr);
lcdDrawChar(lcdLastPos, y, ':', attr);
@ -756,9 +748,9 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_VARIO_SOURCE:
lcdDrawTextAlignedLeft(y, STR_SOURCE);
#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) {
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
lcdDrawTextAtIndex(TELEM_COL2, y, STR_VARIOSRC, g_model.frsky.varioSource, attr);
@ -784,8 +776,8 @@ void menuModelTelemetryFrsky(uint8_t event)
#else
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+10*FW, 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+10*FW-1, y, 5+g_model.frsky.varioCenterMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0)|PREC1);
lcdDrawNumber(TELEM_COL2+13*FW, y, 10+g_model.frsky.varioMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==3) ? attr : 0));
if (attr && (s_editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) {
case 0:
@ -806,23 +798,9 @@ void menuModelTelemetryFrsky(uint8_t event)
break;
#endif
#if !defined(CPUARM)
case ITEM_TELEMETRY_SCREEN_LABEL1:
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);
drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex);
@ -833,7 +811,6 @@ void menuModelTelemetryFrsky(uint8_t event)
#endif
break;
}
#endif
case ITEM_TELEMETRY_SCREEN_LINE1:
case ITEM_TELEMETRY_SCREEN_LINE2:
@ -843,33 +820,12 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_SCREEN_LINE6:
case ITEM_TELEMETRY_SCREEN_LINE7:
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;
if (k < ITEM_TELEMETRY_SCREEN_LABEL2) {
screenIndex = 0;
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 {
screenIndex = 1;
lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE5;
@ -879,58 +835,28 @@ void menuModelTelemetryFrsky(uint8_t event)
if (IS_BARS_SCREEN(screenIndex)) {
FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex];
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);
if (barSource) {
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);
}
#endif
else if (attr && menuHorizontalPosition>0) {
menuHorizontalPosition = 0;
}
if (attr && (s_editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) {
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);
#endif
if (checkIncDec_Ret) {
bar.barMin = 0;
#if defined(CPUARM)
bar.barMax = 0;
#else
bar.barMax = 255 - maxBarTelemValue(bar.source);
#endif
}
break;
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);
#endif
break;
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);
#endif
break;
}
}
@ -942,17 +868,10 @@ void menuModelTelemetryFrsky(uint8_t event)
uint8_t cellAttr = (menuHorizontalPosition==c ? attr : 0);
source_t & value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c];
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);
if (cellAttr && (s_editMode>0 || p1valdiff)) {
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) {
REPEAT_LAST_CURSOR_MOVE();
@ -960,6 +879,7 @@ void menuModelTelemetryFrsky(uint8_t event)
}
break;
}
#endif // !defined(CPUARM)
}
}
}

View file

@ -23,7 +23,7 @@
vertpos_t menuVerticalOffset;
int8_t s_editMode;
uint8_t noHighlightCounter;
uint8_t calibrationState;
uint8_t menuCalibrationState;
vertpos_t menuVerticalPosition;
horzpos_t menuHorizontalPosition;
@ -41,7 +41,7 @@ int8_t checkIncDecMovedSwitch(int8_t val)
if (s_editMode>0) {
int8_t swtch = getMovedSwitch();
if (swtch) {
if (IS_MOMENTARY(val) && swtch==val)
if (IS_CONFIG_TOGGLE(swtch) && swtch==val)
val = -val;
else
val = swtch;
@ -53,16 +53,229 @@ int8_t checkIncDecMovedSwitch(int8_t val)
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_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_LFT_DWN(in) ((in & (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN)) == (KEYS_GPIO_PIN_LEFT + KEYS_GPIO_PIN_DOWN))
#endif
#if defined(CPUARM)
INIT_STOPS(stops100, 3, -100, 0, 100)
INIT_STOPS(stops1000, 3, -1000, 0, 1000)
INIT_STOPS(stopsSwitch, 15, SWSRC_FIRST, CATEGORY_END(-SWSRC_FIRST_LOGICAL_SWITCH), CATEGORY_END(-SWSRC_FIRST_TRIM), CATEGORY_END(-SWSRC_LAST_SWITCH+1), 0, CATEGORY_END(SWSRC_LAST_SWITCH), CATEGORY_END(SWSRC_FIRST_TRIM-1), CATEGORY_END(SWSRC_FIRST_LOGICAL_SWITCH-1), SWSRC_LAST)
#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 newval = val;
@ -182,6 +395,7 @@ int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int
}
return newval;
}
#endif
#else
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;
#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)
{
vertpos_t l_posVert = menuVerticalPosition;
@ -356,8 +817,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
if (menuTab) {
uint8_t attr = 0;
if (l_posVert==0 && !calibrationState) {
if (l_posVert==0 && !menuCalibrationState) {
attr = INVERS;
int8_t cc = curr;
@ -416,7 +876,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#endif
}
calibrationState = 0;
menuCalibrationState = 0;
drawScreenIndex(curr, menuTabSize, attr);
}
@ -442,7 +902,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#endif
l_posVert = 0;
l_posHorz = POS_HORZ_INIT(l_posVert);
SET_SCROLLBAR_X(LCD_W-1);
#if defined(ROTARY_ENCODER_NAVIGATION)
if (menuTab) {
s_editMode = EDIT_MODE_INIT;
@ -457,7 +916,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ENTRY_UP:
s_editMode = 0;
SET_SCROLLBAR_X(LCD_W-1);
break;
case EVT_ROTARY_BREAK:
@ -533,11 +991,12 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
break;
#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;
// no break
case EVT_KEY_FIRST(KEY_DOWN): //inc
case EVT_KEY_FIRST(KEY_DOWN):
if (s_editMode>0) break;
do {
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
#endif
l_posHorz = min(l_posHorz, MAXCOL(l_posVert));
l_posHorz = min<horzpos_t>(l_posHorz, MAXCOL(l_posVert));
break;
#endif
case EVT_KEY_REPT(KEY_LEFT): //dec
if (l_posHorz==0) break;
@ -576,10 +1036,11 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
break;
#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;
// no break
case EVT_KEY_FIRST(KEY_UP): //dec
case EVT_KEY_FIRST(KEY_UP):
if (s_editMode>0) break;
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));
break;
#endif
}
uint8_t maxLines = menuTab ? LCD_LINES-1 : LCD_LINES-2;
@ -670,6 +1132,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t
}
#endif
}
#endif
void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, vertpos_t maxrow)
{

View file

@ -53,14 +53,14 @@ void showMessageBox(const pm_char * pstr)
lcdRefresh();
}
const pm_uchar asterisk_lbm[] PROGMEM = {
const pm_uchar ASTERISK_BITMAP[] PROGMEM = {
#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();
lcd_img(2, 0, asterisk_lbm, 0, 0);
lcd_img(2, 0, ASTERISK_BITMAP, 0, 0);
#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) {
lcdDrawTextAlignedLeft(7*FH, action);
}
AUDIO_ERROR_MESSAGE(sound);
#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();
lcdSetContrast();
@ -135,6 +141,11 @@ uint16_t popupMenuNoItems = 0;
uint8_t popupMenuFlags = 0;
uint16_t popupMenuOffset = 0;
void (*popupMenuHandler)(const char * result);
#if defined(CPUARM)
uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL;
#endif
const char * runPopupMenu(uint8_t event)
{
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)
{
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);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[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)
{
@ -70,7 +70,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = anaIn(i);
@ -83,7 +83,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; 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) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[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);
if (menuEvent) {
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
}
TITLE(STR_MENUCALIBRATION);
@ -123,7 +123,7 @@ void menuRadioCalibration(uint8_t event)
void menuFirstCalib(uint8_t event)
{
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) {
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
chainMenu(menuMainView);
}
else {

View file

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

View file

@ -20,15 +20,15 @@
#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);
}
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);
@ -38,27 +38,37 @@ void menuRadioDiagKeys(uint8_t event)
if (i < 8) {
y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i));
displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
}
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);
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)
if (i < NUM_SWITCHES) {
if (SWITCH_EXISTS(i)) {
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
drawSwitch(8*FW, y, sw, 0);
}
}
#else
if (i != SW_ID0) {
y = MENU_HEADER_HEIGHT +i*FH - 2*FH;
putsSwitches(8*FW, y, i+1, 0); //ohne off,on
displayKeyState(11*FW+2, y, (EnumKeys)(SW_BASE+i));
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++) {
coord_t y = MENU_HEADER_HEIGHT /* ??? + 1 ??? */ + i*FH;
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

View file

@ -20,22 +20,24 @@
#include "opentx.h"
enum menuRadioHwItems {
ITEM_SETUP_HW_OPTREX_DISPLAY,
ITEM_SETUP_HW_STICKS_GAINS_LABELS,
ITEM_SETUP_HW_STICK_LV_GAIN,
ITEM_SETUP_HW_STICK_LH_GAIN,
ITEM_SETUP_HW_STICK_RV_GAIN,
ITEM_SETUP_HW_STICK_RH_GAIN,
IF_ROTARY_ENCODERS(ITEM_SETUP_HW_ROTARY_ENCODER)
CASE_BLUETOOTH(ITEM_SETUP_HW_BT_BAUDRATE)
ITEM_SETUP_HW_MAX
enum MenuRadioHardwareItems {
ITEM_RADIO_HARDWARE_OPTREX_DISPLAY,
ITEM_RADIO_HARDWARE_STICKS_GAINS_LABELS,
ITEM_RADIO_HARDWARE_STICK_LV_GAIN,
ITEM_RADIO_HARDWARE_STICK_LH_GAIN,
ITEM_RADIO_HARDWARE_STICK_RV_GAIN,
ITEM_RADIO_HARDWARE_STICK_RH_GAIN,
IF_ROTARY_ENCODERS(ITEM_RADIO_HARDWARE_ROTARY_ENCODER)
CASE_BLUETOOTH(ITEM_RADIO_HARDWARE_BT_BAUDRATE)
ITEM_RADIO_HARDWARE_MAX
};
#define GENERAL_HW_PARAM_OFS (2+(15*FW))
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;
@ -46,22 +48,22 @@ void menuRadioHardware(uint8_t event)
uint8_t attr = (sub == k ? blink : 0);
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);
break;
case ITEM_SETUP_HW_STICKS_GAINS_LABELS:
case ITEM_RADIO_HARDWARE_STICKS_GAINS_LABELS:
lcdDrawTextAlignedLeft(y, PSTR("Sticks"));
break;
case ITEM_SETUP_HW_STICK_LV_GAIN:
case ITEM_SETUP_HW_STICK_LH_GAIN:
case ITEM_SETUP_HW_STICK_RV_GAIN:
case ITEM_SETUP_HW_STICK_RH_GAIN:
case ITEM_RADIO_HARDWARE_STICK_LV_GAIN:
case ITEM_RADIO_HARDWARE_STICK_LH_GAIN:
case ITEM_RADIO_HARDWARE_STICK_RV_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"));
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);
lcdDrawChar(GENERAL_HW_PARAM_OFS, y, val ? '2' : '1', attr);
if (attr) {
@ -75,20 +77,20 @@ void menuRadioHardware(uint8_t event)
}
#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);
break;
#endif
#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);
if (attr && checkIncDec_Ret) {
btInit();
}
break;
#endif
}
}
#endif
}

View file

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

View file

@ -26,9 +26,9 @@ const pm_uchar sticks[] PROGMEM = {
#include "sticks.lbm"
};
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3-MENUS_SCROLLBAR_WIDTH)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3)
#define RADIO_SETUP_DATE_COLUMN (FW*15+7)
#define RADIO_SETUP_TIME_COLUMN (FW*15+9)
#if !defined(CPUM64)
#define SLIDER_5POS(y, value, label, event, attr) { \
@ -58,7 +58,7 @@ const pm_uchar sticks[] PROGMEM = {
#define CASE_BATTGRAPH(x)
#endif
enum menuRadioSetupItems {
enum MenuRadioSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME)
CASE_BATTGRAPH(ITEM_SETUP_BATT_RANGE)
@ -139,13 +139,13 @@ void menuRadioSetup(uint8_t event)
}
#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) {
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++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
@ -157,16 +157,17 @@ void menuRadioSetup(uint8_t event)
#if defined(RTCLOCK)
case ITEM_SETUP_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++) {
uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0);
switch (j) {
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);
break;
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);
break;
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);
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]);
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);
break;
}
@ -193,21 +194,22 @@ void menuRadioSetup(uint8_t event)
uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0);
switch (j) {
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);
break;
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);
break;
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);
break;
}
}
if (attr && checkIncDec_Ret)
if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break;
#endif
@ -238,7 +240,7 @@ void menuRadioSetup(uint8_t event)
#endif
break;
#if defined(BUZZER)
#if defined(BUZZER) // AUDIO + BUZZER
case ITEM_SETUP_BUZZER_MODE:
g_eeGeneral.buzzerMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_BUZZER, STR_VBEEPMODE, g_eeGeneral.buzzerMode, -2, 1, attr, event);
#if defined(TELEMETRY_FRSKY)
@ -246,7 +248,7 @@ void menuRadioSetup(uint8_t event)
#endif
break;
#endif
#elif defined(BUZZER)
#elif defined(BUZZER) // BUZZER only
case ITEM_SETUP_BUZZER_MODE:
g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event);
#if defined(TELEMETRY_FRSKY)
@ -563,7 +565,7 @@ void menuRadioSetup(uint8_t event)
case ITEM_SETUP_STICK_MODE:
lcdDrawChar(2*FW, y, '1'+reusableBuffer.generalSettings.stickMode, attr);
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) {
CHECK_INCDEC_GENVAR(event, reusableBuffer.generalSettings.stickMode, 0, 3);

View file

@ -20,14 +20,12 @@
#include "opentx.h"
#define TRAINER_CALIB_POS 8
void menuRadioTrainer(uint8_t event)
{
uint8_t y;
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) {
lcdDrawText(7*FW, 4*FH, STR_SLAVE);
@ -40,11 +38,11 @@ void menuRadioTrainer(uint8_t event)
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);
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++) {
@ -57,7 +55,7 @@ void menuRadioTrainer(uint8_t event)
break;
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);
break;
@ -70,20 +68,20 @@ void menuRadioTrainer(uint8_t event)
y += FH;
}
attr = (menuVerticalPosition==5) ? blink : 0;
attr = (menuVerticalPosition==HEADER_LINE+4) ? blink : 0;
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);
attr = (menuVerticalPosition==6) ? INVERS : 0;
if (attr) s_editMode = 0;
attr = (menuVerticalPosition==HEADER_LINE+5) ? INVERS : 0;
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr);
for (uint8_t i=0; i<4; i++) {
uint8_t x = (i*TRAINER_CALIB_POS+16)*FW/2;
lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, 0);
uint8_t x = (i*8+16)*FW/2;
lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, RIGHT);
}
if (attr) {
s_editMode = 0;
if (event==EVT_KEY_LONG(KEY_ENTER)){
memcpy(g_eeGeneral.trainer.calib, ppmInput, sizeof(g_eeGeneral.trainer.calib));
storageDirty(EE_GENERAL);

View file

@ -22,6 +22,21 @@
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);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+FH, vers_stamp);
@ -34,5 +49,16 @@ void menuRadioVersion(uint8_t event)
else {
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
}

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()
{
// Optimization by Mike Blandford
uint8_t x, i, len ; // declare temporary variables
for (x=LCD_W/2-5, i=NUM_STICKS; i<NUM_STICKS+NUM_POTS; x+=5, i++) {
if (IS_POT_AVAILABLE(i)) {
len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
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++) {
if (IS_POT_OR_SLIDER_AVAILABLE(i)) {
uint8_t len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
V_BAR(x, LCD_H-8, len);
}
}
@ -168,7 +167,7 @@ void displayTimers()
if (g_model.timers[0].mode) {
TimerState & timerState = timersStates[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);
#if defined(CPUARM)
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);
}
else {
putsTimerMode(xLabel, FH*3, g_model.timers[0].mode);
drawTimerMode(xLabel, FH*3, g_model.timers[0].mode);
}
#else
putsTimerMode(xLabel, FH*3, g_model.timers[0].mode);
drawTimerMode(xLabel, FH*3, g_model.timers[0].mode);
#endif
}
}
@ -188,7 +187,7 @@ void displayTimers()
void displayBattVoltage()
{
#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);
lcdDrawSolidVerticalLine(VBATT_X-4, VBATT_Y+10, 3);
uint8_t count = GET_TXBATT_BARS();
@ -207,10 +206,10 @@ void displayBattVoltage()
void displayVoltageOrAlarm()
{
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) {
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 {
displayBattVoltage();
@ -220,11 +219,22 @@ void displayVoltageOrAlarm()
#define displayVoltageOrAlarm() displayBattVoltage()
#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_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_STATISTICS EVT_KEY_LONG(KEY_UP)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_BREAK(KEY_MENU)
#endif
#if defined(NAVIGATION_MENUS)
void onMainViewMenu(const char *result)
@ -281,7 +291,6 @@ void menuMainView(uint8_t event)
uint8_t view_base = view & 0x0f;
switch (event) {
case EVT_ENTRY:
killEvents(KEY_EXIT);
killEvents(KEY_UP);
@ -300,7 +309,7 @@ void menuMainView(uint8_t event)
case EVT_KEY_BREAK(KEY_RIGHT):
case EVT_KEY_BREAK(KEY_LEFT):
if (view_base <= VIEW_INPUTS) {
#if defined(PCBSKY9X)
#if defined(CPUARM)
if (view_base == VIEW_INPUTS)
g_eeGeneral.view ^= ALTERNATE_VIEW;
else
@ -343,10 +352,12 @@ void menuMainView(uint8_t event)
#endif
#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());
killEvents(event);
break;
#endif
CASE_EVT_ROTARY_BREAK
case EVT_KEY_MODEL_MENU:
@ -361,16 +372,27 @@ void menuMainView(uint8_t event)
break;
#endif
case EVT_KEY_BREAK(KEY_UP):
case EVT_KEY_BREAK(KEY_DOWN):
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));
#if defined(EVT_KEY_PREVIOUS_VIEW)
// TODO try to split those 2 cases on 9X
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);
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:
chainMenu(menuStatisticsView);
killEvents(event);
break;
#endif
case EVT_KEY_TELEMETRY:
#if defined(TELEMETRY_FRSKY)
@ -432,7 +454,7 @@ void menuMainView(uint8_t event)
if (view_base < VIEW_INPUTS) {
// scroll bar
lcdDrawHorizontalLine(38, 34, 54, DOTTED);
#if defined(PCBSKY9X)
#if defined(CPUARM)
lcdDrawSolidHorizontalLine(38 + (g_eeGeneral.view / ALTERNATE_VIEW) * 13, 34, 13, SOLID);
#else
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++) {
uint8_t x0,y0;
#if defined(PCBSKY9X)
#if defined(CPUARM)
uint8_t chan = 8*(g_eeGeneral.view / ALTERNATE_VIEW) + i;
#else
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];
switch(view_base)
{
switch (view_base) {
case VIEW_OUTPUTS_VALUES:
x0 = (i%4*9+3)*FW/2;
y0 = i/4*FH+40;
#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)
lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val), PREC1);
lcdDrawNumber(x0+4*FW , y0, calcRESXto1000(val), RIGHT|PREC1);
#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
break;
@ -489,6 +510,7 @@ void menuMainView(uint8_t event)
doMainScreenGraphics();
// Switches
#if !defined(PCBX7D)
for (uint8_t i=SWSRC_THR; i<=SWSRC_TRN; i++) {
int8_t sw = (i == SWSRC_TRN ? (switchState(SW_ID0) ? SWSRC_ID0 : (switchState(SW_ID1) ? SWSRC_ID1 : SWSRC_ID2)) : i);
uint8_t x = 2*FW-2, y = i*FH+1;
@ -496,8 +518,9 @@ void menuMainView(uint8_t event)
x = 17*FW-1;
y -= 3*FH;
}
putsSwitches(x, y, sw, getSwitch(i) ? INVERS : 0);
drawSwitch(x, y, sw, getSwitch(i) ? INVERS : 0);
}
#endif
}
else {
#if defined(PCBMEGA2560) && defined(ROTARY_ENCODERS)
@ -515,22 +538,22 @@ void menuMainView(uint8_t event)
#endif // PCBGRUVIN9X && ROTARY_ENCODERS
// Logical Switches
#if defined(PCBSKY9X)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) {
#if defined(CPUARM)
for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++) {
int8_t len = getSwitch(SWSRC_SW1+i) ? BAR_HEIGHT : 1;
uint8_t x = VSWITCH_X(i);
lcdDrawSolidVerticalLine(x-1, VSWITCH_Y-len, len);
lcdDrawSolidVerticalLine(x, VSWITCH_Y-len, len);
}
#elif defined(CPUM2560)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; 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);
for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
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)
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; 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);
for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
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
for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++)
putsSwitches(2*FW-3 + (i/3)*(4*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++)
drawSwitch(2*FW-3 + (i/3)*(4*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#endif
}
}
@ -540,8 +563,8 @@ void menuMainView(uint8_t event)
#else
#define TMR2_LBL_COL (20-FW/2+5)
#endif
putsTimer(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE, DBLSIZE);
putsTimerMode(timersStates[1].val >= 0 ? TMR2_LBL_COL : TMR2_LBL_COL-7, FH*6, g_model.timers[1].mode);
drawTimer(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE|RIGHT, DBLSIZE);
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
}

View file

@ -25,7 +25,7 @@
#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;

View file

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

View file

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

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)
{
lcdDrawNumber(LCD_W, 0, count, attr);
lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
lcdDrawChar(x, 0, '/', attr);
lcdDrawNumber(x, 0, index+1, attr);
lcdDrawNumber(x, 0, index+1, RIGHT | attr);
}
#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);
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;
}
@ -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)
{
drawFieldLabel(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
drawSwitch(x, y, value, attr);
if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
return value;
}

View file

@ -24,6 +24,10 @@
#include "gui_common.h"
#include "lcd.h"
#include "menus.h"
#include "popups.h"
#define HEADER_LINE 0
#define HEADER_LINE_COLUMNS
#define DEFAULT_SCROLLBAR_X (LCD_W-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 LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap)
#define WCHART (LCD_H/2)
#define X0 (LCD_W-WCHART-2)
#define Y0 (LCD_H/2)
#define CURVE_SIDE_WIDTH (LCD_H/2)
#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
#define CURVE_CENTER_Y (LCD_H/2)
#if defined(TRANSLATIONS_FR)
#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 drawColumnHeader(const char * const * headers, uint8_t index);
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);
#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();
typedef uint16_t FlightModesType;
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
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;
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 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
extern char statusLineMsg[STATUS_LINE_LENGTH];
void showStatusLine();
@ -357,21 +318,8 @@ void menuChannelsView(uint8_t event);
#define LABEL(...) (uint8_t)-1
#if defined(PCBX9E) && !defined(SIMU)
#define KEY_UP KEY_MINUS
#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 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 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 onSourceLongEnterPress(const char *result);

View file

@ -314,8 +314,9 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
lcdLastPos = x;
lcdNextPos = x;
if (fontsize == MIDSIZE)
if (fontsize == MIDSIZE) {
lcdLastPos += 1;
}
if (flags & RIGHT) {
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);
uint8_t att = (IS_TXBATT_WARNING() ? BLINK : 0);
putsVBat(12*FW, 0, att);
if (g_model.timers[0].mode) {
att = (timersStates[0].val<0 ? BLINK : 0);
putsTimer(22*FW, 0, timersStates[0].val, att, att);
putsMixerSource(18*FW+2, 1, MIXSRC_TIMER1, SMLSIZE);
drawTimer(22*FW, 0, timersStates[0].val, att, att);
drawSource(18*FW+2, 1, MIXSRC_TIMER1, SMLSIZE);
}
if (g_model.timers[1].mode) {
att = (timersStates[1].val<0 ? BLINK : 0);
putsTimer(31*FW, 0, timersStates[1].val, att, att);
putsMixerSource(27*FW+2, 1, MIXSRC_TIMER2, SMLSIZE);
drawTimer(31*FW, 0, timersStates[1].val, att, att);
drawSource(27*FW+2, 1, MIXSRC_TIMER2, SMLSIZE);
}
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;
@ -656,19 +657,13 @@ void putsVBat(coord_t x, coord_t y, LcdFlags 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)
{
uint8_t length = STR_VSRCRAW[0];
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) {
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)
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
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)
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
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);
}
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 {
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) {
return lcdDrawTextAtIndex(x, y, STR_VSWITCHES, 0, att);
}
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;
}
}
char s[8];
getSwitchString(s, idx);
lcdDrawText(x, y, s, flags);
}
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags)
{
if (idx == 0) {
return lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, flags);
char s[8];
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 < TMRMODE_COUNT)
@ -881,10 +782,10 @@ void putsTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att)
else
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);
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)
{
if (channel >= MAX_SENSORS)
if (channel >= MAX_TELEMETRY_SENSORS)
return; // Lua luaLcdDrawChannel() can call us with a bad value
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);
}
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) {
lcdDrawNumber(x, y, value, att|PREC1);

View file

@ -21,8 +21,7 @@
#ifndef _LCD_H_
#define _LCD_H_
#define LCD_W 212
#define LCD_H 64
#define BOX_WIDTH 31
#define coord_t int
#define scoord_t int
@ -97,12 +96,6 @@
extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#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 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 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 putsMixerSource(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 drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsTimerMode(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 drawTimerMode(coord_t x, coord_t y, int32_t mode, LcdFlags att=0);
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 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
void putsRtcTime(coord_t x, coord_t y, LcdFlags att);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
void drawRtcTime(coord_t x, coord_t y, LcdFlags att);
void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att, LcdFlags att2);
#define SOLID 0xff
#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);
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
void drawShutdownBitmap(uint32_t index);
void drawShutdownAnimation(uint32_t index);
void drawSleepBitmap();
void lcdDrawTelemetryTopBar();
void drawTelemetryTopBar();
#define V_BAR(xx, yy, 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);
#define LCD_ICON(x, y, icon) lcdDrawBitmap(x, y, icons, icon)
void lcdSetRefVolt(unsigned char val);
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);
const char * writeScreenshot();

View file

@ -34,6 +34,6 @@ const MenuHandlerFunc menuTabGeneral[] = {
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);
}

View file

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

View file

@ -97,7 +97,7 @@ void menuModelCustomScriptOne(uint8_t event)
}
else {
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) {
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);
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);
}
}

View file

@ -20,7 +20,7 @@
#include "opentx.h"
enum menuModelDisplayItems {
enum MenuModelDisplayItems {
ITEM_DISPLAY_TOP_BAR_LABEL,
ITEM_DISPLAY_TOP_BAR_VOLTAGE,
ITEM_DISPLAY_TOP_BAR_ALTITUDE,
@ -103,17 +103,17 @@ void menuModelDisplay(uint8_t event)
case ITEM_DISPLAY_TOP_BAR_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) {
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;
case ITEM_DISPLAY_TOP_BAR_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) {
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;
@ -196,7 +196,7 @@ void menuModelDisplay(uint8_t event)
if (IS_BARS_SCREEN(screenIndex)) {
FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex];
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 barMin = -barMax;
if (barSource) {
@ -241,7 +241,7 @@ void menuModelDisplay(uint8_t event)
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};
putsMixerSource(pos[c], y, value, cellAttr);
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);
}

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 {
ITEM_FLIGHT_MODES_NAME,
ITEM_FLIGHT_MODES_SWITCH,
@ -80,7 +50,7 @@ bool isTrimModeAvailable(int mode)
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;
@ -98,7 +68,7 @@ void menuModelFlightModesAll(uint8_t event)
if (k == MAX_FLIGHT_MODES) {
// last line available - add the "check trims" line
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 (!trimsCheckTimer) {
if (event == EVT_KEY_FIRST(KEY_ENTER)) {
@ -124,7 +94,7 @@ void menuModelFlightModesAll(uint8_t event)
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++) {
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:
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);
}
break;
@ -147,7 +117,7 @@ void menuModelFlightModesAll(uint8_t event)
case ITEM_FLIGHT_MODES_TRIM_AIL:
{
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) {
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);

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) {
uint8_t fm = v - GVAR_MAX - 1;
if (fm >= flightMode) fm++;
putsFlightMode(x, y, fm + 1, flags&(~LEFT));
drawFlightMode(x, y, fm + 1, flags&(~LEFT));
vmin = GVAR_MAX + 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_FM_WIDTH (9*FW)
int16_t expoFn(int16_t x)
int expoFn(int x)
{
ExpoData * ed = expoAddress(s_currIdx);
int16_t anas[NUM_INPUTS] = {0};
@ -33,20 +33,20 @@ int16_t expoFn(int16_t x)
void drawFunction(FnFuncP fn, uint8_t offset)
{
lcdDrawVerticalLine(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee);
lcdDrawHorizontalLine(X0-WCHART-offset, Y0, WCHART*2, 0xee);
lcdDrawVerticalLine(CURVE_CENTER_X-offset, 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=-WCHART; xv<=WCHART; xv++) {
coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX);
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(X0+xv-offset-1, prev_yv, FORCE);
lcdDrawPoint(CURVE_CENTER_X+xv-offset-1, prev_yv, FORCE);
}
else {
uint8_t tmp = (prev_yv < yv ? 0 : 1);
lcdDrawSolidVerticalLine(X0+xv-offset-1, yv+tmp, prev_yv-yv);
lcdDrawSolidVerticalLine(CURVE_CENTER_X+xv-offset-1, yv+tmp, prev_yv-yv);
}
}
prev_yv = yv;
@ -183,7 +183,7 @@ void menuModelExpoOne(uint8_t event)
}
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);
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:
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);
break;
@ -243,6 +243,7 @@ void menuModelExpoOne(uint8_t event)
#if defined(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);
break;
#endif
@ -281,7 +282,7 @@ void menuModelExpoOne(uint8_t event)
y512 = limit(-1024, y512, 1024);
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;
lcdDrawSolidVerticalLine(x512, y512-3, 3*2+1);
@ -329,13 +330,13 @@ void onExposMenu(const char * result)
void displayExpoInfos(coord_t y, ExpoData * ed)
{
putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0);
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
drawCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0);
drawSwitch(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0);
}
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) {
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;
if (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(0, y, ch, 0);
drawSource(0, y, ch, 0);
}
uint8_t mixCnt = 0;
do {
@ -561,7 +562,7 @@ void menuModelExposAll(uint8_t event)
}
}
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) {
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);
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 sub = menuVerticalPosition;
@ -108,7 +108,7 @@ void menuModelLogicalSwitches(uint8_t event)
// CSW name
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
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;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
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;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
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);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122;
@ -144,8 +144,8 @@ void menuModelLogicalSwitches(uint8_t event)
}
else if (cstate == LS_FAMILY_COMP) {
v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
@ -159,7 +159,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
else {
v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -179,7 +179,7 @@ void menuModelLogicalSwitches(uint8_t event)
}
// 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
if (cs->duration > 0)

View file

@ -96,7 +96,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
}
if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1)
if (x->destCh == MAX_OUTPUT_CHANNELS-1)
return false;
x->destCh++;
return true;
@ -110,7 +110,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) x->destCh++;
if (destCh<MAX_OUTPUT_CHANNELS-1) x->destCh++;
else return false;
}
return true;
@ -235,7 +235,7 @@ void menuModelMixOne(uint8_t event)
case MIX_FIELD_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);
break;
@ -270,6 +270,7 @@ void menuModelMixOne(uint8_t event)
#if defined(FLIGHT_MODES)
case MIX_FIELD_FLIGHT_MODE:
drawFieldLabel(MIXES_2ND_COLUMN, y, STR_FLMODE);
md2->flightModes = editFlightModes(MIXES_2ND_COLUMN, y, event, md2->flightModes, attr);
break;
#endif
@ -357,10 +358,10 @@ void displayHeaderChannelName(uint8_t ch)
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) {
putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch);
drawSwitch(MIX_LINE_SWITCH_POS, y, md->swtch);
}
}
@ -372,6 +373,13 @@ void displayMixLine(coord_t y, MixData *md)
displayMixInfos(y, md);
else
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)
@ -527,7 +535,7 @@ void menuModelMixAll(uint8_t event)
int cur = 0;
int i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) {
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) {
@ -554,19 +562,12 @@ void menuModelMixAll(uint8_t event)
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);
displayMixLine(y, md);
char cs = ' ';
if (md->speedDown || md->speedUp)
cs = 'S';
if (md->delayUp || md->delayDown)
cs = (cs =='S' ? '*' : 'D');
lcdDrawChar(MIX_LINE_DELAY_POS, y, cs);
if (s_copyMode) {
if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) {
/* draw a border around the raw on selection mode (copy/move) */

View file

@ -101,7 +101,7 @@ void menuModelLimits(uint8_t event)
{
int sub = menuVerticalPosition;
if (sub < NUM_CHNOUT) {
if (sub < MAX_OUTPUT_CHANNELS) {
#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US)
lcdDrawNumber(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, RIGHT);
lcdDrawText(13*FW, 0, STR_US);
@ -110,9 +110,9 @@ void menuModelLimits(uint8_t event)
#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);
}
@ -127,9 +127,9 @@ void menuModelLimits(uint8_t event)
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) {
if (k==MAX_OUTPUT_CHANNELS) {
// 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);
if (attr) {
s_editMode = 0;

View file

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

View file

@ -94,13 +94,13 @@ void onCustomFunctionsMenu(const char * result)
storageDirty(eeFlags);
}
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));
storageDirty(eeFlags);
}
else if (result == STR_DELETE) {
memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData));
memmove(cfn, cfn+1, (MAX_SPECIAL_FUNCTIONS-sub-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[MAX_SPECIAL_FUNCTIONS-1], 0, sizeof(CustomFunctionData));
storageDirty(eeFlags);
}
}
@ -155,11 +155,11 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
POPUP_MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
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);
if (!CFN_EMPTY(cfn))
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])) {
POPUP_MENU_ADD_ITEM(STR_DELETE);
break;
@ -181,7 +181,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
uint8_t active = (attr && s_editMode>0);
switch (j) {
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 (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) {
func = CFN_FUNC(cfn) = func+1;
@ -206,7 +206,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
case ITEM_CUSTOM_FUNCTIONS_PARAM1:
{
int8_t maxParam = NUM_CHNOUT-1;
int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) {
putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr);
@ -215,7 +215,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#endif
if (func == FUNC_TRAINER) {
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)
else if (func == FUNC_ADJUST_GVAR) {
@ -268,7 +268,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
}
else if (func == FUNC_SET_TIMER) {
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) {
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) {
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
@ -317,7 +317,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
#endif
else if (func == FUNC_VOLUME) {
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -350,7 +350,7 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
break;
case FUNC_ADJUST_GVAR_SOURCE:
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -423,6 +423,6 @@ void menuSpecialFunctions(uint8_t event, CustomFunctionData * functions, CustomF
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);
}

View file

@ -226,33 +226,33 @@ void menuModelSensor(uint8_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_TOTALIZE) {
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) {
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;
}
@ -284,9 +284,9 @@ void menuModelSensor(uint8_t event)
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
@ -314,14 +314,14 @@ void menuModelSensor(uint8_t event)
drawStringWithIndex(0, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
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) {
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 {
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;
}
@ -360,14 +360,14 @@ void onSensorMenu(const char *result)
{
int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) {
if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) {
pushMenu(menuModelSensor);
}
else if (result == STR_DELETE) {
delTelemetryIndex(index);
index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index))
if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1;
else
menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR;
@ -395,7 +395,7 @@ void menuModelTelemetryFrsky(uint8_t event)
{
if (warningResult) {
warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
}
@ -413,7 +413,7 @@ void menuModelTelemetryFrsky(uint8_t event)
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
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;
lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr);
lcdDrawChar(lcdLastPos, y, ':', attr);
@ -535,9 +535,9 @@ void menuModelTelemetryFrsky(uint8_t event)
case ITEM_TELEMETRY_VARIO_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) {
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;

View file

@ -25,7 +25,7 @@ vertpos_t menuVerticalPosition;
horzpos_t menuHorizontalPosition;
int8_t s_editMode;
uint8_t noHighlightCounter;
uint8_t calibrationState;
uint8_t menuCalibrationState;
int checkIncDecSelection = 0;
#if defined(AUTOSWITCH)
@ -35,7 +35,7 @@ swsrc_t checkIncDecMovedSwitch(swsrc_t val)
swsrc_t swtch = getMovedSwitch();
if (swtch) {
div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) {
if (IS_CONFIG_TOGGLE(info.quot)) {
if (info.rem != 0) {
val = (val == swtch ? swtch-2 : swtch);
}
@ -82,7 +82,7 @@ void onSourceLongEnterPress(const char * result)
else if (result == STR_MENU_GVARS)
checkIncDecSelection = MIXSRC_FIRST_GVAR;
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];
if (sensor->isAvailable()) {
checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i;
@ -99,7 +99,7 @@ void onSwitchLongEnterPress(const char *result)
else if (result == STR_MENU_TRIMS)
checkIncDecSelection = SWSRC_FIRST_TRIM;
else if (result == STR_MENU_LOGICAL_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, NUM_LOGICAL_SWITCH, isLogicalSwitchAvailable);
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, MAX_LOGICAL_SWITCHES, isLogicalSwitchAvailable);
else if (result == STR_MENU_OTHER)
checkIncDecSelection = SWSRC_ON;
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) {
for (int i = 0; i < MAX_SENSORS; i++) {
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);
@ -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_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) {
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;
@ -374,7 +374,7 @@ void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc
break;
}
if (!calibrationState && cc != curr) {
if (!menuCalibrationState && cc != curr) {
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);
switch(event)
{
switch (event) {
case EVT_ENTRY:
menuEntryTime = get_tmr10ms();
s_editMode = EDIT_MODE_INIT;

View file

@ -51,14 +51,14 @@ void showMessageBox(const char * title)
lcdRefresh();
}
const pm_uchar asterisk_lbm[] PROGMEM = {
const pm_uchar ASTERISK_BITMAP[] PROGMEM = {
#include "asterisk.lbm"
};
void drawAlertBox(const char * title, const char * text, const char * action)
{
lcdClear();
lcdDrawBitmap(0, 0, asterisk_lbm);
lcdDrawBitmap(0, 0, ASTERISK_BITMAP);
#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()
{
// Optimization by Mike Blandford
uint8_t x, i, len ; // declare temporary variables
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_AVAILABLE(i)) {
len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
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++) {
if (IS_POT_OR_SLIDER_AVAILABLE(i)) {
uint8_t len = ((calibratedStick[i]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
V_BAR(x, LCD_H-8, len);
putsStickName(x-2, LCD_H-6, i, TINSIZE);
}
@ -48,7 +47,7 @@ void drawPotsBars()
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);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[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) {
case EVT_ENTRY:
@ -115,7 +114,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_SETMIDPOINT, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) {
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
@ -132,7 +131,7 @@ void menuCommonCalib(uint8_t event)
lcdDrawText(0*FW, MENU_HEADER_HEIGHT+FH, STR_MOVESTICKSPOTS, INVERS);
lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+2*FH, STR_MENUWHENDONE);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; 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) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[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);
menuCommonCalib(READ_ONLY() ? 0 : event);
if (menuEvent) {
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
}
}
void menuFirstCalib(uint8_t event)
{
if (event == EVT_KEY_BREAK(KEY_EXIT) || reusableBuffer.calib.state == CALIB_FINISHED) {
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
chainMenu(menuMainView);
}
else {

View file

@ -22,11 +22,11 @@
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();
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;
uint8_t x = i&1 ? LCD_W/2 + FW : 0;
lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2);

View file

@ -20,15 +20,15 @@
#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);
}
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);
@ -38,13 +38,13 @@ void menuRadioDiagKeys(uint8_t event)
if (i<8) {
y = MENU_HEADER_HEIGHT + FH*3 + FH*(i/2);
if (i&1) lcd_img(14*FW, y, sticks, i/2, 0);
displayKeyState(i&1? 20*FW : 18*FW, y, (EnumKeys)(TRM_BASE+i));
displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
}
if (i<6) {
y = i*FH+MENU_HEADER_HEIGHT+FH;
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"
enum menuRadioHwItems {
ITEM_SETUP_HW_LABEL_STICKS,
ITEM_SETUP_HW_STICK1,
ITEM_SETUP_HW_STICK2,
ITEM_SETUP_HW_STICK3,
ITEM_SETUP_HW_STICK4,
ITEM_SETUP_HW_LABEL_POTS,
ITEM_SETUP_HW_POT1,
ITEM_SETUP_HW_POT2,
CASE_PCBX9E_PCBX9DP(ITEM_SETUP_HW_POT3)
CASE_PCBX9E(ITEM_SETUP_HW_POT4)
ITEM_SETUP_HW_LS,
ITEM_SETUP_HW_RS,
CASE_PCBX9E(ITEM_SETUP_HW_LS2)
CASE_PCBX9E(ITEM_SETUP_HW_RS2)
ITEM_SETUP_HW_LABEL_SWITCHES,
ITEM_SETUP_HW_SA,
ITEM_SETUP_HW_SB,
ITEM_SETUP_HW_SC,
ITEM_SETUP_HW_SD,
ITEM_SETUP_HW_SE,
ITEM_SETUP_HW_SF,
ITEM_SETUP_HW_SG,
ITEM_SETUP_HW_SH,
CASE_PCBX9E(ITEM_SETUP_HW_SI)
CASE_PCBX9E(ITEM_SETUP_HW_SJ)
CASE_PCBX9E(ITEM_SETUP_HW_SK)
CASE_PCBX9E(ITEM_SETUP_HW_SL)
CASE_PCBX9E(ITEM_SETUP_HW_SM)
CASE_PCBX9E(ITEM_SETUP_HW_SN)
CASE_PCBX9E(ITEM_SETUP_HW_SO)
CASE_PCBX9E(ITEM_SETUP_HW_SP)
CASE_PCBX9E(ITEM_SETUP_HW_SQ)
CASE_PCBX9E(ITEM_SETUP_HW_SR)
CASE_PCBX9E(ITEM_SETUP_HW_BLUETOOTH)
ITEM_SETUP_HW_UART3_MODE,
ITEM_SETUP_HW_JITTER_FILTER,
ITEM_SETUP_HW_MAX
ITEM_RADIO_HARDWARE_LABEL_STICKS,
ITEM_RADIO_HARDWARE_STICK1,
ITEM_RADIO_HARDWARE_STICK2,
ITEM_RADIO_HARDWARE_STICK3,
ITEM_RADIO_HARDWARE_STICK4,
ITEM_RADIO_HARDWARE_LABEL_POTS,
ITEM_RADIO_HARDWARE_POT1,
ITEM_RADIO_HARDWARE_POT2,
CASE_PCBX9E_PCBX9DP(ITEM_RADIO_HARDWARE_POT3)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_POT4)
ITEM_RADIO_HARDWARE_LS,
ITEM_RADIO_HARDWARE_RS,
CASE_PCBX9E(ITEM_RADIO_HARDWARE_LS2)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_RS2)
ITEM_RADIO_HARDWARE_LABEL_SWITCHES,
ITEM_RADIO_HARDWARE_SA,
ITEM_RADIO_HARDWARE_SB,
ITEM_RADIO_HARDWARE_SC,
ITEM_RADIO_HARDWARE_SD,
ITEM_RADIO_HARDWARE_SE,
ITEM_RADIO_HARDWARE_SF,
ITEM_RADIO_HARDWARE_SG,
ITEM_RADIO_HARDWARE_SH,
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SI)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SJ)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SK)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SL)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SM)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SN)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SO)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SP)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SQ)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_SR)
CASE_PCBX9E(ITEM_RADIO_HARDWARE_BLUETOOTH)
ITEM_RADIO_HARDWARE_UART3_MODE,
ITEM_RADIO_HARDWARE_JITTER_FILTER,
ITEM_RADIO_HARDWARE_MAX
};
#define HW_SETTINGS_COLUMN 15*FW
@ -83,7 +83,7 @@ enum menuRadioHwItems {
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;
@ -96,17 +96,17 @@ void menuRadioHardware(uint8_t event)
}
LcdFlags attr = (sub == k ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
switch (k) {
case ITEM_SETUP_HW_LABEL_STICKS:
case ITEM_RADIO_HARDWARE_LABEL_STICKS:
lcdDrawTextAlignedLeft(y, STR_STICKS);
break;
case ITEM_SETUP_HW_STICK1:
case ITEM_SETUP_HW_STICK2:
case ITEM_SETUP_HW_STICK3:
case ITEM_SETUP_HW_STICK4:
case ITEM_SETUP_HW_LS:
case ITEM_SETUP_HW_RS:
case ITEM_RADIO_HARDWARE_STICK1:
case ITEM_RADIO_HARDWARE_STICK2:
case ITEM_RADIO_HARDWARE_STICK3:
case ITEM_RADIO_HARDWARE_STICK4:
case ITEM_RADIO_HARDWARE_LS:
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);
if (ZEXIST(g_eeGeneral.anaNames[idx]) || 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;
}
#if defined(PCBX9E)
case ITEM_SETUP_HW_LS2:
case ITEM_SETUP_HW_RS2:
case ITEM_RADIO_HARDWARE_LS2:
case ITEM_RADIO_HARDWARE_RS2:
{
int idx = k - ITEM_SETUP_HW_LS2;
int idx = k - ITEM_RADIO_HARDWARE_LS2;
uint8_t mask = (0x01 << idx);
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))
@ -132,19 +132,19 @@ void menuRadioHardware(uint8_t event)
break;
}
#endif
case ITEM_SETUP_HW_LABEL_POTS:
case ITEM_RADIO_HARDWARE_LABEL_POTS:
lcdDrawTextAlignedLeft(y, STR_POTS);
break;
case ITEM_SETUP_HW_POT1:
case ITEM_SETUP_HW_POT2:
case ITEM_RADIO_HARDWARE_POT1:
case ITEM_RADIO_HARDWARE_POT2:
#if defined(PCBX9DP) || defined(PCBX9E)
case ITEM_SETUP_HW_POT3:
case ITEM_RADIO_HARDWARE_POT3:
#endif
#if defined(PCBX9E)
case ITEM_SETUP_HW_POT4:
case ITEM_RADIO_HARDWARE_POT4:
#endif
{
int idx = k - ITEM_SETUP_HW_POT1;
int idx = k - ITEM_RADIO_HARDWARE_POT1;
uint8_t shift = (2*idx);
uint8_t mask = (0x03 << shift);
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);
break;
}
case ITEM_SETUP_HW_LABEL_SWITCHES:
case ITEM_RADIO_HARDWARE_LABEL_SWITCHES:
lcdDrawTextAlignedLeft(y, STR_SWITCHES);
break;
case ITEM_SETUP_HW_SA:
case ITEM_SETUP_HW_SB:
case ITEM_SETUP_HW_SC:
case ITEM_SETUP_HW_SD:
case ITEM_SETUP_HW_SE:
case ITEM_SETUP_HW_SF:
case ITEM_SETUP_HW_SG:
case ITEM_SETUP_HW_SH:
case ITEM_RADIO_HARDWARE_SA:
case ITEM_RADIO_HARDWARE_SB:
case ITEM_RADIO_HARDWARE_SC:
case ITEM_RADIO_HARDWARE_SD:
case ITEM_RADIO_HARDWARE_SE:
case ITEM_RADIO_HARDWARE_SF:
case ITEM_RADIO_HARDWARE_SG:
case ITEM_RADIO_HARDWARE_SH:
#if defined(PCBX9E)
case ITEM_SETUP_HW_SI:
case ITEM_SETUP_HW_SJ:
case ITEM_SETUP_HW_SK:
case ITEM_SETUP_HW_SL:
case ITEM_SETUP_HW_SM:
case ITEM_SETUP_HW_SN:
case ITEM_SETUP_HW_SO:
case ITEM_SETUP_HW_SP:
case ITEM_SETUP_HW_SQ:
case ITEM_SETUP_HW_SR:
case ITEM_RADIO_HARDWARE_SI:
case ITEM_RADIO_HARDWARE_SJ:
case ITEM_RADIO_HARDWARE_SK:
case ITEM_RADIO_HARDWARE_SL:
case ITEM_RADIO_HARDWARE_SM:
case ITEM_RADIO_HARDWARE_SN:
case ITEM_RADIO_HARDWARE_SO:
case ITEM_RADIO_HARDWARE_SP:
case ITEM_RADIO_HARDWARE_SQ:
case ITEM_RADIO_HARDWARE_SR:
#endif
{
int index = k-ITEM_SETUP_HW_SA;
int index = k-ITEM_RADIO_HARDWARE_SA;
int config = SWITCH_CONFIG(index);
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))
@ -197,7 +197,7 @@ void menuRadioHardware(uint8_t event)
break;
}
#if defined(PCBX9E)
case ITEM_SETUP_HW_BLUETOOTH:
case ITEM_RADIO_HARDWARE_BLUETOOTH:
lcdDrawTextAlignedLeft(y, "Bluetooth");
drawCheckBox(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 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);
break;
#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);
if (attr && checkIncDec_Ret) {
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
}
break;
case ITEM_SETUP_HW_JITTER_FILTER:
case ITEM_RADIO_HARDWARE_JITTER_FILTER:
{
uint8_t b = 1-g_eeGeneral.jitterFilter;
g_eeGeneral.jitterFilter = 1 - editCheckBox(b, HW_SETTINGS_COLUMN, y, STR_JITTER_FILTER, attr, event);

View file

@ -366,7 +366,7 @@ void menuRadioSdManager(event_t _event)
reusableBuffer.sdmanager.count = 0;
FRESULT res = f_opendir(&dir, "."); /* Open the directory */
FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
@ -384,7 +384,7 @@ void menuRadioSdManager(event_t _event)
bool isfile = !(fno.fattrib & AM_DIR);
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];
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));
@ -427,7 +427,7 @@ void menuRadioSdManager(event_t _event)
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;
lcdNextPos = 0;
LcdFlags attr = (index == i ? INVERS : 0);

View file

@ -42,7 +42,7 @@ const pm_uchar sticks[] PROGMEM = {
#define CASE_SPLASH_PARAM(x)
#endif
enum menuRadioSetupItems {
enum MenuRadioSetupItems {
CASE_RTCLOCK(ITEM_SETUP_DATE)
CASE_RTCLOCK(ITEM_SETUP_TIME)
ITEM_SETUP_BATTERY_CALIB,
@ -123,7 +123,7 @@ void menuRadioSetup(uint8_t event)
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;
uint8_t k = i + menuVerticalOffset;
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
@ -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 && checkIncDec_Ret)
if (attr && checkIncDec_Ret) {
g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated
}
break;
case ITEM_SETUP_BATTERY_CALIB:

View file

@ -20,62 +20,13 @@
#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)
{
if (warningResult) {
warningResult = 0;
showMessageBox(STR_STORAGE_FORMAT);
storageEraseAll(false);
#if !defined(SIMU)
NVIC_SystemReset();
#else
exit(0);
#endif
}
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);
if (event == EVT_KEY_LONG(KEY_ENTER)) {
backupEeprom();
eepromBackup();
}
else if (event == EVT_KEY_LONG(KEY_MENU)) {
POPUP_CONFIRMATION(STR_CONFIRMRESET);

View file

@ -39,7 +39,7 @@
#define TIMERS_H 25
#define TIMERS_R 193
#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 TRIM_LH_X (32+9)
#define TRIM_LV_X 10
@ -161,7 +161,7 @@ void displayTrims(uint8_t phase)
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 (i < SLIDER1) continue; // TODO change and display more values
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;
if (g_model.frsky.voltsSource) {
uint8_t item = g_model.frsky.voltsSource-1;
if (item < MAX_SENSORS) {
if (item < MAX_TELEMETRY_SENSORS) {
TelemetryItem & voltsItem = telemetryItems[item];
if (voltsItem.isAvailable()) {
putsTelemetryChannelValue(batt_icon_x+7*FW+2, BAR_Y+1, item, voltsItem.value, LEFT);
@ -232,7 +232,7 @@ void displayTopBar()
/* Altitude */
if (g_model.frsky.altitudeSource) {
uint8_t item = g_model.frsky.altitudeSource-1;
if (item < MAX_SENSORS) {
if (item < MAX_TELEMETRY_SENSORS) {
TelemetryItem & altitudeItem = telemetryItems[item];
if (altitudeItem.isAvailable()) {
LCD_ICON(altitude_icon_x, BAR_Y, ICON_ALTITUDE);
@ -289,7 +289,7 @@ void displayTopBar()
LCD_ICON(BAR_VOLUME_X, BAR_Y, ICON_SPEAKER3);
/* RTC time */
putsRtcTime(BAR_TIME_X, BAR_Y+1, LEFT|TIMEBLINK);
drawRtcTime(BAR_TIME_X, BAR_Y+1, LEFT|TIMEBLINK);
/* The background */
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);
}
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) {
lcdDrawChar(TIMERS_R, y+1, 'P', SMLSIZE);
}
@ -542,7 +542,7 @@ void menuMainView(uint8_t event)
if (SWITCH_EXISTS(i)) {
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i);
getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3));
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++;
}
}

View file

@ -48,23 +48,23 @@ void menuStatisticsView(uint8_t event)
// Session and Total timers
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);
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
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);
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
for (int i=0; i<TIMERS; i++) {
drawStringWithIndex(STATS_3RD_COLUMN, FH*i+1, "TM", i+1, BOLD);
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
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)
@ -228,7 +228,7 @@ void menuTraceBuffer(uint8_t event)
if (te) {
//time
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
lcdDrawNumber(14*FW, y, te->event, LEADING0|LEFT, 3);
//data

View file

@ -69,7 +69,7 @@ void displayGaugesTelemetryScreen(FrSkyScreenData & screen)
}
if (source && barMax > barMin) {
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);
getvalue_t value = getValue(source);
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
}
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) {
@ -186,7 +186,7 @@ bool displayTelemetryScreen()
return false;
}
lcdDrawTelemetryTopBar();
drawTelemetryTopBar();
if (s_frsky_view < MAX_TELEMETRY_SCREENS) {
displayCustomTelemetryScreen(s_frsky_view);
@ -253,7 +253,7 @@ void menuViewTelemetryFrsky(uint8_t event)
}
}
lcdDrawTelemetryTopBar();
drawTelemetryTopBar();
lcdDrawText(8*FW, 3*FH, "No Telemetry Screens");
displayRssiLine();
}

View file

@ -40,7 +40,7 @@ const pm_uchar bmp_shutdown[] PROGMEM = {
#define SHUTDOWN_BITMAP_WIDTH 60
#define SHUTDOWN_BITMAP_HEIGHT 60
void drawShutdownBitmap(uint32_t index)
void drawShutdownAnimation(uint32_t index)
{
index /= (PWR_PRESS_SHUTDOWN / 4);
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);
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;
}
@ -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)
{
drawFieldLabel(x, y, STR_SWITCH);
putsSwitches(x, y, value, attr);
if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
drawSwitch(x, y, value, attr);
if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
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
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)
@ -243,7 +243,7 @@ void getTimerString(char * str, putstime_t tme, LcdFlags att)
*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"
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);
}
char * getStringAtIndex(char * dest, const char * s, int idx)
{
uint8_t len = s[0];
strncpy(dest, s+1+len*idx, len);
dest[len] = '\0';
return dest;
}
char * getStringWithIndex(char * dest, const char * s, int idx)
{
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)
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags flags)
{
char s[16];
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];
getSwitchString(s, idx);
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)
{
if (idx == 0) {
return lcdDrawTextAtIndex(x, y, STR_MMMINV, 0, 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);
}
char s[8];
getCurveString(s, idx);
lcdDrawText(x, y, s, 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 < TMRMODE_COUNT)
@ -503,10 +309,10 @@ void putsTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att)
else
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);
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);
}
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) {
lcdDrawNumber(x, y, value, att|PREC1);

View file

@ -23,14 +23,10 @@
#include "bitmapbuffer.h"
#if defined(PCBHORUS)
#define LCD_W 480
#define LCD_H 272
#define LCD_COLS 30
#else
#define LCD_W 800
#define LCD_H 480
#if LCD_W >= 480
#define LCD_COLS 40
#else
#define LCD_COLS 30
#endif
#define CENTER
@ -106,8 +102,6 @@ extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
#define displayBuf lcd->getData()
#endif
#define lcdRefreshWait()
#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE)
#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 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 putsSwitches(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 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 drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags flags=0);
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void putsTimerMode(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 drawTimerMode(coord_t x, coord_t y, int8_t mode, LcdFlags att=0);
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 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
void getTimerString(char * str, putstime_t tme, LcdFlags att=0);
void putsRtcTime(coord_t x, coord_t y, LcdFlags att=0);
void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att=0);
void drawRtcTime(coord_t x, coord_t y, LcdFlags att=0);
void drawTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att=0);
#define SOLID 0xff
#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);
}
#define lcdSetRefVolt(...)
void lcdSetContrast();
#define lcdOff(...)
#if defined(BOOT)
#define BLINK_ON_PHASE (0)
#else

View file

@ -43,7 +43,7 @@ const MenuHandlerFunc menuTabModel[] = {
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)
{

View file

@ -31,6 +31,6 @@ const MenuHandlerFunc menuTabGeneral[] = {
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);
}

View file

@ -34,7 +34,7 @@ extern uint16_t linesCount;
extern int menuVerticalPosition;
extern int menuHorizontalPosition;
extern int menuVerticalOffset;
extern uint8_t calibrationState;
extern uint8_t menuCalibrationState;
// Temporary no highlight
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);
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;
@ -491,7 +491,7 @@ extern uint8_t warningInfoFlags;
#define POPUP_MENU_MAX_LINES 12
#define MENU_MAX_DISPLAY_LINES 9
#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 uint16_t popupMenuNoItems;
extern uint16_t popupMenuOffset;

View file

@ -21,69 +21,9 @@
#include <stdio.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)
{
drawFunction(curveFn, 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);
}
drawFunction(applyCurrentCurve, x, y, width);
}
void displayPresetChoice(event_t event)
@ -194,7 +134,7 @@ bool menuModelCurveOne(event_t event)
if (attr) {
int count = checkIncDecModel(event, crv.points, -3, 12); // 2pts - 17pts
if (checkIncDec_Ret) {
int newPoints[MAX_POINTS];
int newPoints[MAX_POINTS_PER_CURVE];
newPoints[0] = points[0];
newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++)
@ -312,7 +252,7 @@ bool menuModelCurveOne(event_t event)
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));
if (attr && menuHorizontalPosition==0) {

View file

@ -97,7 +97,7 @@ bool menuModelCustomScriptOne(event_t event)
}
else {
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) {
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);
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);
}
}

View file

@ -78,7 +78,7 @@ bool isTrimModeAvailable(int mode)
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) {
menuHorizontalPosition += CURSOR_MOVED_LEFT(event) ? -1 : +1;
@ -123,7 +123,7 @@ bool menuModelFlightModesAll(event_t event)
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++) {
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)
lcdDrawText(FLIGHT_MODES_SWITCH_COLUMN, y, "N/A");
else
putsSwitches(FLIGHT_MODES_SWITCH_COLUMN, y, p->swtch, attr);
drawSwitch(FLIGHT_MODES_SWITCH_COLUMN, y, p->swtch, attr);
break;
case ITEM_FLIGHT_MODES_TRIM_RUD:
@ -153,7 +153,7 @@ bool menuModelFlightModesAll(event_t event)
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);
}
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;
}

View file

@ -71,7 +71,7 @@ bool menuModelGVars(event_t event)
if (v > GVAR_MAX) {
uint8_t p = v - GVAR_MAX - 1;
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;
}
else {

View file

@ -20,7 +20,7 @@
#include "opentx.h"
enum menuModelHeliItems {
enum MenuModelHeliItems {
ITEM_HELI_SWASHTYPE,
ITEM_HELI_SWASHRING,
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);
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;
int k = i+menuVerticalOffset;
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
@ -60,7 +60,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_ELE:
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);
break;
@ -72,7 +72,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_AIL:
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);
break;
@ -84,7 +84,7 @@ bool menuModelHeli(event_t event)
case ITEM_HELI_COL:
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);
break;

View file

@ -233,7 +233,7 @@ bool menuModelExpoOne(event_t event)
case EXPO_FIELD_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 (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));
@ -338,9 +338,9 @@ void onExposMenu(const char * result)
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) {
putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch);
drawSwitch(EXPO_LINE_SWITCH_POS, y, ed->swtch);
}
if (ed->mode != 3) {
lcdDrawText(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? "\176" : "\177");
@ -349,7 +349,7 @@ void displayExpoInfos(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);
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;
if ((i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed))) {
if (cur-menuVerticalOffset >= 0 && cur-menuVerticalOffset < NUM_BODY_LINES) {
putsMixerSource(MENUS_MARGIN_LEFT, y, ch);
drawSource(MENUS_MARGIN_LEFT, y, ch);
}
uint8_t mixCnt = 0;
do {
@ -544,7 +544,7 @@ bool menuModelExposAll(event_t event)
}
}
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) {
lineExpoSurround(y);
}

View file

@ -76,7 +76,7 @@ bool menuModelLogicalSwitches(event_t event)
{
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);
uint8_t cstate = lswFamily(cs->func);
@ -110,7 +110,7 @@ bool menuModelLogicalSwitches(event_t event)
// CSW name
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
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;
if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) {
putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1);
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSwitch(CSW_2ND_COLUMN, y, cs->v1, attr1);
drawSwitch(CSW_3RD_COLUMN, y, cs->v2, attr2);
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;
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
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));
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min=-129; v2_max = 122;
@ -146,8 +146,8 @@ bool menuModelLogicalSwitches(event_t event)
}
else if (cstate == LS_FAMILY_COMP) {
v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
@ -161,7 +161,7 @@ bool menuModelLogicalSwitches(event_t event)
}
else {
v1_val = cs->v1;
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (menuHorizontalPosition == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
@ -176,7 +176,7 @@ bool menuModelLogicalSwitches(event_t event)
}
// 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
if (cs->duration > 0)

View file

@ -24,7 +24,7 @@
int getMixesLinesCount()
{
int lastch = -1;
uint8_t count = NUM_CHNOUT;
uint8_t count = MAX_OUTPUT_CHANNELS;
for (int i=0; i<MAX_MIXERS; i++) {
bool valid = mixAddress(i)->srcRaw;
if (!valid)
@ -116,7 +116,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
}
if (tgt_idx == MAX_MIXERS) {
if (x->destCh == NUM_CHNOUT-1)
if (x->destCh == MAX_OUTPUT_CHANNELS-1)
return false;
x->destCh++;
return true;
@ -130,7 +130,7 @@ bool swapMixes(uint8_t & idx, uint8_t up)
else return false;
}
else {
if (destCh<NUM_CHNOUT-1) x->destCh++;
if (destCh<MAX_OUTPUT_CHANNELS-1) x->destCh++;
else return false;
}
return true;
@ -201,7 +201,7 @@ bool menuModelMixOne(event_t event)
break;
case MIX_FIELD_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);
break;
case MIX_FIELD_WEIGHT:
@ -324,11 +324,11 @@ void onMixesMenu(const char * result)
void displayMixInfos(coord_t y, MixData *md)
{
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) {
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 i = 0;
for (int ch=1; ch<=NUM_CHNOUT; ch++) {
for (int ch=1; ch<=MAX_OUTPUT_CHANNELS; ch++) {
MixData * md;
coord_t y = MENU_CONTENT_TOP + (cur-menuVerticalOffset)*FH;
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]);
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);

View file

@ -52,10 +52,10 @@ enum LimitsItems {
#define LIMITS_NAME_POS 52
#define LIMITS_OFFSET_POS 160
#define LIMITS_MIN_POS 220
#define LIMITS_DIRECTION_POS 240
#define LIMITS_DIRECTION_POS 235
#define LIMITS_MAX_POS 300
#define LIMITS_REVERT_POS 320
#define LIMITS_CURVE_POS 350
#define LIMITS_REVERT_POS 312
#define LIMITS_CURVE_POS 340
#define LIMITS_PPM_CENTER_POS 440
#define LIMITS_SYMETRICAL_POS 450
@ -93,7 +93,7 @@ void onLimitsMenu(const char *result)
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,
@ -102,7 +102,7 @@ bool menuModelLimits(event_t event)
uint32_t sub = menuVerticalPosition;
if (sub<NUM_CHNOUT && menuHorizontalPosition>=0) {
if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition);
}
@ -117,9 +117,9 @@ bool menuModelLimits(event_t event)
coord_t y = MENU_CONTENT_TOP + i*FH;
uint8_t k = i+menuVerticalOffset;
if (k==NUM_CHNOUT) {
if (k==MAX_OUTPUT_CHANNELS) {
// 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
lcdDrawText(100, y, STR_TRIMS2OFFSETS, NO_HIGHLIGHT() ? 0 : 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);
}
drawStringWithIndex(MENUS_MARGIN_LEFT, y, STR_TIMER, timerIdx+1);
putsTimerMode(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));
drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer.mode, (menuHorizontalPosition<=0 ? attr : 0));
drawTimer(MODEL_SETUP_2ND_COLUMN+50, y, timer.start, (menuHorizontalPosition!=0 ? attr|TIMEHOUR : TIMEHOUR));
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
@ -217,7 +217,7 @@ int getSwitchWarningsCount()
#endif
#define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1))
#define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
#define POT_WARN_ITEMS() ((g_model.potsWarnMode >> 6) ? uint8_t(NUM_POTS+NUM_SLIDERS) : (uint8_t)0)
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,
{ 0, 0, TIMERS_ROWS, 0, 1, 0, 0,
LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(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),
INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS,
@ -406,13 +406,13 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_THROTTLE_TRACE:
{
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;
if (idx > MIXSRC_Thr)
idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS;
putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
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);
if (g_model.potsWarnMode) {
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);
flags |= (g_model.potsWarnEnabled & (1 << i)) ? TEXT_DISABLE_COLOR : TEXT_COLOR;
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, NUM_STICKS+1+i, flags);
@ -526,7 +526,7 @@ bool menuModelSetup(event_t event)
case ITEM_MODEL_BEEP_CENTER:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BEEPCTR);
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);
flags |= (g_model.beepANACenter & ((BeepANACenter)1<<i)) ? TEXT_COLOR : (TEXT_DISABLE_COLOR | NO_FONTCACHE);
if (attr && menuHorizontalPosition < 0) flags |= INVERS;

View file

@ -93,13 +93,13 @@ void onCustomFunctionsMenu(const char *result)
storageDirty(eeFlags);
}
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));
storageDirty(eeFlags);
}
else if (result == STR_DELETE) {
memmove(cfn, cfn+1, (NUM_CFN-menuVerticalPosition-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData));
memmove(cfn, cfn+1, (MAX_SPECIAL_FUNCTIONS-menuVerticalPosition-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[MAX_SPECIAL_FUNCTIONS-1], 0, sizeof(CustomFunctionData));
storageDirty(eeFlags);
}
}
@ -154,11 +154,11 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
POPUP_MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
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);
if (!CFN_EMPTY(cfn))
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])) {
POPUP_MENU_ADD_ITEM(STR_DELETE);
break;
@ -183,7 +183,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
if (active || AUTOSWITCH_ENTER_LONG()) {
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;
case ITEM_SPECIAL_FUNCTIONS_FUNCTION:
@ -204,7 +204,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
case ITEM_SPECIAL_FUNCTIONS_PARAM:
{
int8_t maxParam = NUM_CHNOUT-1;
int8_t maxParam = MAX_OUTPUT_CHANNELS-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) {
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
if (func == FUNC_TRAINER) {
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)
else if (func == FUNC_ADJUST_GVAR) {
@ -260,7 +260,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#endif
else if (func == FUNC_SET_TIMER) {
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) {
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) {
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(functions == g_eeGeneral.customFn ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
@ -310,7 +310,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#endif
else if (func == FUNC_VOLUME) {
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -342,7 +342,7 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
break;
case FUNC_ADJUST_GVAR_SOURCE:
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) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
@ -415,6 +415,6 @@ bool menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
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);
}

View file

@ -229,33 +229,33 @@ bool menuModelSensor(event_t event)
if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
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) {
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;
}
else if (sensor->formula == TELEM_FORMULA_TOTALIZE) {
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) {
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;
}
@ -288,9 +288,9 @@ bool menuModelSensor(event_t event)
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
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) {
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;
}
@ -318,14 +318,14 @@ bool menuModelSensor(event_t event)
drawStringWithIndex(MENUS_MARGIN_LEFT, y, NO_INDENT(STR_SOURCE), k-SENSOR_FIELD_PARAM1+1);
int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1];
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) {
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 {
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;
}
@ -367,14 +367,14 @@ void onSensorMenu(const char *result)
{
int index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1;
if (index < MAX_SENSORS) {
if (index < MAX_TELEMETRY_SENSORS) {
if (result == STR_EDIT) {
pushMenu(menuModelSensor);
}
else if (result == STR_DELETE) {
delTelemetryIndex(index);
index += 1;
if (index<MAX_SENSORS && isTelemetryFieldAvailable(index))
if (index<MAX_TELEMETRY_SENSORS && isTelemetryFieldAvailable(index))
menuVerticalPosition += 1;
else
menuVerticalPosition = ITEM_TELEMETRY_NEW_SENSOR;
@ -402,7 +402,7 @@ bool menuModelTelemetryFrsky(event_t event)
{
if (warningResult) {
warningResult = 0;
for (int i=0; i<MAX_SENSORS; i++) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
}
@ -420,7 +420,7 @@ bool menuModelTelemetryFrsky(event_t event)
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
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;
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);
@ -539,9 +539,9 @@ bool menuModelTelemetryFrsky(event_t event)
case ITEM_TELEMETRY_VARIO_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) {
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;

View file

@ -25,7 +25,7 @@ int menuVerticalPosition;
int menuHorizontalPosition;
int8_t s_editMode;
uint8_t noHighlightCounter;
uint8_t calibrationState; // TODO rename this variable
uint8_t menuCalibrationState; // TODO rename this variable
int checkIncDecSelection = 0;
#if defined(AUTOSWITCH)
@ -35,7 +35,7 @@ swsrc_t checkIncDecMovedSwitch(swsrc_t val)
swsrc_t swtch = getMovedSwitch();
if (swtch) {
div_t info = switchInfo(swtch);
if (IS_TOGGLE(info.quot)) {
if (IS_CONFIG_TOGGLE(info.quot)) {
if (info.rem != 0) {
val = (val == swtch ? swtch-2 : swtch);
}
@ -82,7 +82,7 @@ void onSourceLongEnterPress(const char * result)
else if (result == STR_MENU_GVARS)
checkIncDecSelection = MIXSRC_FIRST_GVAR;
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];
if (sensor->isAvailable()) {
checkIncDecSelection = MIXSRC_FIRST_TELEM + 3*i;
@ -99,7 +99,7 @@ void onSwitchLongEnterPress(const char *result)
else if (result == STR_MENU_TRIMS)
checkIncDecSelection = SWSRC_FIRST_TRIM;
else if (result == STR_MENU_LOGICAL_SWITCHES)
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, NUM_LOGICAL_SWITCH, isLogicalSwitchAvailable);
checkIncDecSelection = SWSRC_FIRST_LOGICAL_SWITCH + getFirstAvailable(0, MAX_LOGICAL_SWITCHES, isLogicalSwitchAvailable);
else if (result == STR_MENU_OTHER)
checkIncDecSelection = SWSRC_ON;
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) {
for (int i = 0; i < MAX_SENSORS; i++) {
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);
@ -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_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS);
if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) {
for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) {
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;
@ -366,7 +366,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
return false;
}
if (menuTab && !calibrationState) {
if (menuTab && !menuCalibrationState) {
int cc = curr;
switch (event) {
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);
AUDIO_KEY_PRESS();
}
else if (!calibrationState) {
else if (!menuCalibrationState) {
popMenu();
}
}

View file

@ -81,8 +81,8 @@ bool menuCommonCalib(event_t event)
{
drawMenuTemplate(NULL, ICON_RADIO_CALIBRATION, NULL, OPTION_MENU_NO_FOOTER);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_MOUSE_ANALOGS; i++) { // get low and high vals for sticks and trims
int16_t vt = i<NUM_STICKS+NUM_POTS ? anaIn(i) : anaIn(MOUSE1+i-NUM_STICKS-NUM_POTS);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS; i++) { // get low and high vals for sticks and trims
int16_t vt = i<NUM_STICKS+NUM_POTS+NUM_SLIDERS ? anaIn(i) : anaIn(MOUSE1+i-NUM_STICKS-NUM_POTS-NUM_SLIDERS);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
if (i >= POT1 && i <= POT_LAST) {
@ -124,25 +124,25 @@ bool menuCommonCalib(event_t event)
switch (event) {
case EVT_ENTRY:
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
break;
case EVT_KEY_FIRST(KEY_EXIT):
if (calibrationState == CALIB_START) {
if (menuCalibrationState == CALIB_START) {
killEvents(KEY_EXIT);
popMenu();
}
else {
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
}
break;
case EVT_KEY_FIRST(KEY_ENTER):
calibrationState++;
menuCalibrationState++;
break;
}
switch (calibrationState) {
switch (menuCalibrationState) {
case CALIB_START:
// START CALIBRATION
if (!READ_ONLY()) {
@ -155,10 +155,10 @@ bool menuCommonCalib(event_t event)
// SET MIDPOINT
lcdDrawText(50, 3, STR_MENUCALIBRATION, MENU_TITLE_COLOR);
lcdDrawText(50, 3+FH, STR_SETMIDPOINT, MENU_TITLE_COLOR);
for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_MOUSE_ANALOGS; i++) {
for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS; i++) {
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
reusableBuffer.calib.midVals[i] = i<NUM_STICKS+NUM_POTS ? anaIn(i) : anaIn(MOUSE1+i-NUM_STICKS-NUM_POTS);
reusableBuffer.calib.midVals[i] = i<NUM_STICKS+NUM_POTS+NUM_SLIDERS ? anaIn(i) : anaIn(MOUSE1+i-NUM_STICKS-NUM_POTS+NUM_SLIDERS);
if (i < NUM_XPOTS) {
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
@ -170,7 +170,7 @@ bool menuCommonCalib(event_t event)
// MOVE STICKS/POTS
lcdDrawText(50, 3, STR_MENUCALIBRATION, MENU_TITLE_COLOR);
lcdDrawText(50, 3+FH, STR_MOVESTICKSPOTS, MENU_TITLE_COLOR);
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_MOUSE_ANALOGS; i++) {
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS; i++) {
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i]) > 50) {
g_eeGeneral.calib[i].mid = reusableBuffer.calib.midVals[i];
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
@ -207,11 +207,11 @@ bool menuCommonCalib(event_t event)
case CALIB_STORE:
g_eeGeneral.chkSum = evalChkSum();
storageDirty(EE_GENERAL);
calibrationState = CALIB_FINISHED;
menuCalibrationState = CALIB_FINISHED;
break;
default:
calibrationState = CALIB_START;
menuCalibrationState = CALIB_START;
break;
}
@ -230,8 +230,8 @@ bool menuCommonCalib(event_t event)
bool menuRadioCalibration(event_t event)
{
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", STR_MENUCALIBRATION);
if (calibrationState == CALIB_FINISHED) {
calibrationState = CALIB_START;
if (menuCalibrationState == CALIB_FINISHED) {
menuCalibrationState = CALIB_START;
popMenu();
return false;
}
@ -246,8 +246,8 @@ bool menuRadioCalibration(event_t event)
bool menuFirstCalib(event_t event)
{
if (event == EVT_KEY_BREAK(KEY_EXIT) || calibrationState == CALIB_FINISHED) {
calibrationState = CALIB_START;
if (event == EVT_KEY_BREAK(KEY_EXIT) || menuCalibrationState == CALIB_FINISHED) {
menuCalibrationState = CALIB_START;
chainMenu(menuMainView);
return false;
}

View file

@ -20,35 +20,35 @@
#include "opentx.h"
enum menuRadioHwItems {
ITEM_SETUP_HW_CALIBRATION,
ITEM_SETUP_HW_LABEL_STICKS,
ITEM_SETUP_HW_STICK1,
ITEM_SETUP_HW_STICK2,
ITEM_SETUP_HW_STICK3,
ITEM_SETUP_HW_STICK4,
ITEM_SETUP_HW_LABEL_POTS,
ITEM_SETUP_HW_POT1,
ITEM_SETUP_HW_POT2,
ITEM_SETUP_HW_POT3,
ITEM_SETUP_HW_LS,
ITEM_SETUP_HW_RS,
ITEM_SETUP_HW_LS2,
ITEM_SETUP_HW_RS2,
ITEM_SETUP_HW_LABEL_SWITCHES,
ITEM_SETUP_HW_SA,
ITEM_SETUP_HW_SB,
ITEM_SETUP_HW_SC,
ITEM_SETUP_HW_SD,
ITEM_SETUP_HW_SE,
ITEM_SETUP_HW_SF,
ITEM_SETUP_HW_SG,
ITEM_SETUP_HW_SH,
ITEM_SETUP_HW_BLUETOOTH,
// ITEM_SETUP_HW_UART3_MODE,
ITEM_SETUP_HW_JITTER_FILTER,
ITEM_SETUP_HW_BAT_CAL,
ITEM_SETUP_HW_MAX
enum MenuRadioHardwareItems {
ITEM_RADIO_HARDWARE_CALIBRATION,
ITEM_RADIO_HARDWARE_LABEL_STICKS,
ITEM_RADIO_HARDWARE_STICK1,
ITEM_RADIO_HARDWARE_STICK2,
ITEM_RADIO_HARDWARE_STICK3,
ITEM_RADIO_HARDWARE_STICK4,
ITEM_RADIO_HARDWARE_LABEL_POTS,
ITEM_RADIO_HARDWARE_POT1,
ITEM_RADIO_HARDWARE_POT2,
ITEM_RADIO_HARDWARE_POT3,
ITEM_RADIO_HARDWARE_LS,
ITEM_RADIO_HARDWARE_RS,
ITEM_RADIO_HARDWARE_LS2,
ITEM_RADIO_HARDWARE_RS2,
ITEM_RADIO_HARDWARE_LABEL_SWITCHES,
ITEM_RADIO_HARDWARE_SA,
ITEM_RADIO_HARDWARE_SB,
ITEM_RADIO_HARDWARE_SC,
ITEM_RADIO_HARDWARE_SD,
ITEM_RADIO_HARDWARE_SE,
ITEM_RADIO_HARDWARE_SF,
ITEM_RADIO_HARDWARE_SG,
ITEM_RADIO_HARDWARE_SH,
ITEM_RADIO_HARDWARE_BLUETOOTH,
// ITEM_RADIO_HARDWARE_UART3_MODE,
ITEM_RADIO_HARDWARE_JITTER_FILTER,
ITEM_RADIO_HARDWARE_BAT_CAL,
ITEM_RADIO_HARDWARE_MAX
};
#define HW_SETTINGS_COLUMN 150
@ -59,7 +59,7 @@ enum menuRadioHwItems {
bool menuRadioHardware(event_t event)
{
MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_SETUP_HW_MAX, { 0, LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, BLUETOOTH_ROWS 0 });
MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { 0, LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, BLUETOOTH_ROWS 0 });
uint8_t sub = menuVerticalPosition;
@ -72,21 +72,21 @@ bool menuRadioHardware(event_t event)
}
LcdFlags attr = (sub == k ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
switch (k) {
case ITEM_SETUP_HW_CALIBRATION:
case ITEM_RADIO_HARDWARE_CALIBRATION:
lcdDrawText(MENUS_MARGIN_LEFT, y, "Calibration", attr);
if (attr && s_editMode>0) {
pushMenu(menuRadioCalibration);
}
break;
case ITEM_SETUP_HW_LABEL_STICKS:
case ITEM_RADIO_HARDWARE_LABEL_STICKS:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_STICKS);
break;
case ITEM_SETUP_HW_STICK1:
case ITEM_SETUP_HW_STICK2:
case ITEM_SETUP_HW_STICK3:
case ITEM_SETUP_HW_STICK4:
case ITEM_RADIO_HARDWARE_STICK1:
case ITEM_RADIO_HARDWARE_STICK2:
case ITEM_RADIO_HARDWARE_STICK3:
case ITEM_RADIO_HARDWARE_STICK4:
{
int idx = k - ITEM_SETUP_HW_STICK1;
int idx = k - ITEM_RADIO_HARDWARE_STICK1;
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, idx+1, 0);
if (ZEXIST(g_eeGeneral.anaNames[idx]) || attr)
editName(HW_SETTINGS_COLUMN, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, event, attr);
@ -94,12 +94,12 @@ bool menuRadioHardware(event_t event)
lcdDrawTextAtIndex(HW_SETTINGS_COLUMN, y, STR_MMMINV, 0, 0);
break;
}
case ITEM_SETUP_HW_LS:
case ITEM_SETUP_HW_RS:
case ITEM_SETUP_HW_LS2:
case ITEM_SETUP_HW_RS2:
case ITEM_RADIO_HARDWARE_LS:
case ITEM_RADIO_HARDWARE_RS:
case ITEM_RADIO_HARDWARE_LS2:
case ITEM_RADIO_HARDWARE_RS2:
{
int idx = k - ITEM_SETUP_HW_LS;
int idx = k - ITEM_RADIO_HARDWARE_LS;
uint8_t mask = (0x01 << idx);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+NUM_XPOTS+idx+1, menuHorizontalPosition < 0 ? attr : 0);
if (ZEXIST(g_eeGeneral.anaNames[NUM_STICKS+NUM_XPOTS+2+idx]) || (attr && menuHorizontalPosition == 0))
@ -112,14 +112,14 @@ bool menuRadioHardware(event_t event)
g_eeGeneral.slidersConfig |= (potType << idx);
break;
}
case ITEM_SETUP_HW_LABEL_POTS:
case ITEM_RADIO_HARDWARE_LABEL_POTS:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POTS);
break;
case ITEM_SETUP_HW_POT1:
case ITEM_SETUP_HW_POT2:
case ITEM_SETUP_HW_POT3:
case ITEM_RADIO_HARDWARE_POT1:
case ITEM_RADIO_HARDWARE_POT2:
case ITEM_RADIO_HARDWARE_POT3:
{
int idx = k - ITEM_SETUP_HW_POT1;
int idx = k - ITEM_RADIO_HARDWARE_POT1;
uint8_t shift = (2*idx);
uint8_t mask = (0x03 << shift);
lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, NUM_STICKS+idx+1, menuHorizontalPosition < 0 ? attr : 0);
@ -133,19 +133,19 @@ bool menuRadioHardware(event_t event)
g_eeGeneral.potsConfig |= (potType << shift);
break;
}
case ITEM_SETUP_HW_LABEL_SWITCHES:
case ITEM_RADIO_HARDWARE_LABEL_SWITCHES:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SWITCHES);
break;
case ITEM_SETUP_HW_SA:
case ITEM_SETUP_HW_SB:
case ITEM_SETUP_HW_SC:
case ITEM_SETUP_HW_SD:
case ITEM_SETUP_HW_SE:
case ITEM_SETUP_HW_SF:
case ITEM_SETUP_HW_SG:
case ITEM_SETUP_HW_SH:
case ITEM_RADIO_HARDWARE_SA:
case ITEM_RADIO_HARDWARE_SB:
case ITEM_RADIO_HARDWARE_SC:
case ITEM_RADIO_HARDWARE_SD:
case ITEM_RADIO_HARDWARE_SE:
case ITEM_RADIO_HARDWARE_SF:
case ITEM_RADIO_HARDWARE_SG:
case ITEM_RADIO_HARDWARE_SH:
{
int index = k-ITEM_SETUP_HW_SA;
int index = k-ITEM_RADIO_HARDWARE_SA;
int config = SWITCH_CONFIG(index);
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))
@ -160,7 +160,7 @@ bool menuRadioHardware(event_t event)
break;
}
case ITEM_SETUP_HW_BLUETOOTH:
case ITEM_RADIO_HARDWARE_BLUETOOTH:
lcdDrawText(MENUS_MARGIN_LEFT, y, "Bluetooth");
drawCheckBox(HW_SETTINGS_COLUMN, y, g_eeGeneral.bluetoothEnable, menuHorizontalPosition == 0 ? attr : 0);
if (attr && menuHorizontalPosition == 0) {
@ -170,7 +170,7 @@ bool menuRadioHardware(event_t event)
break;
#if 0
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);
if (attr && checkIncDec_Ret) {
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
@ -178,7 +178,7 @@ bool menuRadioHardware(event_t event)
break;
#endif
case ITEM_SETUP_HW_JITTER_FILTER:
case ITEM_RADIO_HARDWARE_JITTER_FILTER:
{
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_JITTER_FILTER);
uint8_t b = 1-g_eeGeneral.jitterFilter;
@ -186,7 +186,7 @@ bool menuRadioHardware(event_t event)
break;
}
case ITEM_SETUP_HW_BAT_CAL:
case ITEM_RADIO_HARDWARE_BAT_CAL:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATT_CALIB);
lcdDrawNumber(HW_SETTINGS_COLUMN, y, getBatteryVoltage(), attr|LEFT|PREC2, 0, NULL, "V");
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);

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