/* * 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 MenuModelTelemetryFrskyItems { ITEM_TELEMETRY_PROTOCOL_TYPE, ITEM_TELEMETRY_RSSI_LABEL, ITEM_TELEMETRY_RSSI_ALARM1, ITEM_TELEMETRY_RSSI_ALARM2, ITEM_TELEMETRY_DISABLE_ALARMS, ITEM_TELEMETRY_SENSORS_LABEL, ITEM_TELEMETRY_SENSOR1, ITEM_TELEMETRY_SENSOR2, ITEM_TELEMETRY_SENSOR3, ITEM_TELEMETRY_SENSOR4, ITEM_TELEMETRY_SENSOR5, ITEM_TELEMETRY_SENSOR6, ITEM_TELEMETRY_SENSOR7, ITEM_TELEMETRY_SENSOR8, ITEM_TELEMETRY_SENSOR9, ITEM_TELEMETRY_SENSOR10, ITEM_TELEMETRY_SENSOR11, ITEM_TELEMETRY_SENSOR12, ITEM_TELEMETRY_SENSOR13, ITEM_TELEMETRY_SENSOR14, ITEM_TELEMETRY_SENSOR15, ITEM_TELEMETRY_SENSOR16, ITEM_TELEMETRY_SENSOR17, ITEM_TELEMETRY_SENSOR18, ITEM_TELEMETRY_SENSOR19, ITEM_TELEMETRY_SENSOR20, ITEM_TELEMETRY_SENSOR21, ITEM_TELEMETRY_SENSOR22, ITEM_TELEMETRY_SENSOR23, ITEM_TELEMETRY_SENSOR24, ITEM_TELEMETRY_SENSOR25, ITEM_TELEMETRY_SENSOR26, ITEM_TELEMETRY_SENSOR27, ITEM_TELEMETRY_SENSOR28, ITEM_TELEMETRY_SENSOR29, ITEM_TELEMETRY_SENSOR30, ITEM_TELEMETRY_SENSOR31, ITEM_TELEMETRY_SENSOR32, ITEM_TELEMETRY_SENSOR33, ITEM_TELEMETRY_SENSOR34, ITEM_TELEMETRY_SENSOR35, ITEM_TELEMETRY_SENSOR36, ITEM_TELEMETRY_SENSOR37, ITEM_TELEMETRY_SENSOR38, ITEM_TELEMETRY_SENSOR39, ITEM_TELEMETRY_SENSOR40, ITEM_TELEMETRY_SENSOR41, ITEM_TELEMETRY_SENSOR42, ITEM_TELEMETRY_SENSOR43, ITEM_TELEMETRY_SENSOR44, ITEM_TELEMETRY_SENSOR45, ITEM_TELEMETRY_SENSOR46, ITEM_TELEMETRY_SENSOR47, ITEM_TELEMETRY_SENSOR48, ITEM_TELEMETRY_SENSOR49, ITEM_TELEMETRY_SENSOR50, ITEM_TELEMETRY_SENSOR51, ITEM_TELEMETRY_SENSOR52, ITEM_TELEMETRY_SENSOR53, ITEM_TELEMETRY_SENSOR54, ITEM_TELEMETRY_SENSOR55, ITEM_TELEMETRY_SENSOR56, ITEM_TELEMETRY_SENSOR57, ITEM_TELEMETRY_SENSOR58, ITEM_TELEMETRY_SENSOR59, ITEM_TELEMETRY_SENSOR60, ITEM_TELEMETRY_SENSOR61, ITEM_TELEMETRY_SENSOR62, ITEM_TELEMETRY_SENSOR63, ITEM_TELEMETRY_SENSOR64, ITEM_TELEMETRY_DISCOVER_SENSORS, ITEM_TELEMETRY_NEW_SENSOR, ITEM_TELEMETRY_DELETE_ALL_SENSORS, ITEM_TELEMETRY_IGNORE_SENSOR_INSTANCE, #if defined(VARIO) ITEM_TELEMETRY_VARIO_LABEL, ITEM_TELEMETRY_VARIO_SOURCE, ITEM_TELEMETRY_VARIO_RANGE, ITEM_TELEMETRY_VARIO_CENTER, #endif ITEM_TELEMETRY_MAX }; #define TELEM_COL2 200 #define TELEM_COL3 275 #define TELEM_COL4 350 #define TELEM_COL5 425 #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) #define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), \ SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40),SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50),SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59),SENSOR_ROWS(60),SENSOR_ROWS(61), SENSOR_ROWS(62), SENSOR_ROWS(63), 0, 0, 0, 0, #if defined(VARIO) #define VARIO_ROWS LABEL(Vario), 0, 1, 2, #else #define VARIO_ROWS #endif #define RSSI_ROWS LABEL(RSSI), 0, 0, 0, #define TELEMETRY_TYPE_ROWS (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, void onSensorMenu(const char * result) { uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1; if (index < MAX_TELEMETRY_SENSORS) { if (result == STR_EDIT) { pushMenu(menuModelSensor); } else if (result == STR_DELETE) { delTelemetryIndex(index); index += 1; if (index= 0) { TelemetrySensor & sourceSensor = g_model.telemetrySensors[index]; TelemetrySensor & newSensor = g_model.telemetrySensors[newIndex]; newSensor = sourceSensor; TelemetryItem & sourceItem = telemetryItems[index]; TelemetryItem & newItem = telemetryItems[newIndex]; newItem = sourceItem; storageDirty(EE_MODEL); } else { POPUP_WARNING(STR_TELEMETRYFULL); } } } } bool menuModelTelemetryFrsky(event_t event) { if (warningResult) { warningResult = 0; for (int i=0; i0) ? BLINK|INVERS : INVERS); LcdFlags attr = (menuVerticalPosition == k ? blink : 0); if (k>=ITEM_TELEMETRY_SENSOR1 && kid, LEFT); } else #endif if (sensor->type == TELEM_TYPE_CUSTOM && !g_model.ignoreSensorIds) { lcdDrawNumber(TELEM_COL5, y, sensor->instance, LEFT); } if (attr) { s_editMode = 0; s_currIdx = index; if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); POPUP_MENU_ADD_ITEM(STR_EDIT); POPUP_MENU_ADD_ITEM(STR_COPY); POPUP_MENU_ADD_ITEM(STR_DELETE); POPUP_MENU_START(onSensorMenu); } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { pushMenu(menuModelSensor); } } } else switch (k) { case ITEM_TELEMETRY_PROTOCOL_TYPE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TELEMETRY_TYPE); lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr); g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable); break; case ITEM_TELEMETRY_SENSORS_LABEL: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TELEMETRY_SENSORS); lcdDrawText(TELEM_COL2, y, STR_VALUE, 0); if (!g_model.ignoreSensorIds && !IS_SPEKTRUM_PROTOCOL()) { lcdDrawText(TELEM_COL5, y, STR_ID, 0); } break; case ITEM_TELEMETRY_DISCOVER_SENSORS: lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, allowNewSensors ? NO_INDENT(STR_STOP_DISCOVER_SENSORS) : NO_INDENT(STR_DISCOVER_SENSORS), attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; allowNewSensors = !allowNewSensors; } break; case ITEM_TELEMETRY_NEW_SENSOR: lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, NO_INDENT(STR_TELEMETRY_NEWSENSOR), attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; int res = availableTelemetryIndex(); if (res >= 0) { s_currIdx = res; pushMenu(menuModelSensor); } else { POPUP_WARNING(STR_TELEMETRYFULL); } } break; case ITEM_TELEMETRY_DELETE_ALL_SENSORS: lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, NO_INDENT(STR_DELETE_ALL_SENSORS), attr); if (attr) s_editMode = 0; if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { killEvents(KEY_ENTER); POPUP_CONFIRMATION(STR_CONFIRMDELETE); } break; case ITEM_TELEMETRY_IGNORE_SENSOR_INSTANCE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_IGNORE_INSTANCE); g_model.ignoreSensorIds = editCheckBox(g_model.ignoreSensorIds, TELEM_COL2, y, attr, event); break; case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FS_AFHDS2A) lcdDrawText(MENUS_MARGIN_LEFT, y, "RSNR"); else #endif lcdDrawText(MENUS_MARGIN_LEFT, y, "RSSI"); break; case ITEM_TELEMETRY_RSSI_ALARM1: case ITEM_TELEMETRY_RSSI_ALARM2: { bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1); lcdDrawText(MENUS_MARGIN_LEFT, y, (warning ? STR_LOWALARM : STR_CRITICALALARM)); lcdDrawNumber(TELEM_COL2, y, warning? g_model.rssiAlarms.getWarningRssi() : g_model.rssiAlarms.getCriticalRssi(), LEFT|attr, 3); if (attr && s_editMode>0) { if (warning) CHECK_INCDEC_MODELVAR(event, g_model.rssiAlarms.warning, -30, 30); else CHECK_INCDEC_MODELVAR(event, g_model.rssiAlarms.critical, -30, 30); } break; } case ITEM_TELEMETRY_DISABLE_ALARMS: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_DISABLE_ALARM); g_model.rssiAlarms.disabled = editCheckBox(g_model.rssiAlarms.disabled, TELEM_COL3, y, attr, event); break; #if defined(VARIO) case ITEM_TELEMETRY_VARIO_LABEL: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_VARIO); break; case ITEM_TELEMETRY_VARIO_SOURCE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SOURCE); 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_TELEMETRY_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); } break; case ITEM_TELEMETRY_VARIO_RANGE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RANGE); lcdDrawNumber(TELEM_COL2, y, -10+g_model.frsky.varioMin, (menuHorizontalPosition==0 ? attr : 0)|LEFT); lcdDrawNumber(TELEM_COL3, y, 10+g_model.frsky.varioMax, (menuHorizontalPosition==1 ? attr : 0)|LEFT); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMin, -7, 7); break; case 1: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMax, -7, 7); break; } } break; case ITEM_TELEMETRY_VARIO_CENTER: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CENTER); lcdDrawNumber(TELEM_COL2, y, -5+g_model.frsky.varioCenterMin, (menuHorizontalPosition==0 ? attr : 0)|PREC1|LEFT); lcdDrawNumber(TELEM_COL3, y, 5+g_model.frsky.varioCenterMax, (menuHorizontalPosition==1 ? attr : 0)|PREC1|LEFT); lcdDrawTextAtIndex(TELEM_COL4, y, STR_VVARIOCENTER, g_model.frsky.varioCenterSilent, (menuHorizontalPosition==2 ? attr : 0)); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMin, -16, 5+min(10, g_model.frsky.varioCenterMax+5)); break; case 1: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMax, -5+max(-10, g_model.frsky.varioCenterMin-5), +15); break; case 2: CHECK_INCDEC_MODELVAR_ZERO(event, g_model.frsky.varioCenterSilent, 1); break; } } break; #endif } } return true; }