From edc3d7372e274b3b6ec7fd85871249439a27e1e5 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 4 Dec 2018 09:29:36 +0100 Subject: [PATCH 01/13] POC X7 --- radio/src/CMakeLists.txt | 5 --- radio/src/bitfield.h | 51 ++++++++++++++++++++++++++++ radio/src/gui/128x64/model_setup.cpp | 12 ++----- radio/src/gui/gui_common.h | 5 +-- radio/src/gui/gui_common_arm.cpp | 22 +++++++++--- radio/src/opentx.h | 1 + radio/src/pulses/pulses_arm.h | 6 ++-- radio/src/pulses/pxx2.cpp | 1 + radio/src/telemetry/frsky.cpp | 11 +++++- radio/src/telemetry/frsky.h | 3 +- radio/src/telemetry/telemetry.cpp | 7 ++-- radio/src/telemetry/telemetry.h | 3 +- radio/src/translations.h | 8 +++-- radio/util/fwoptions.py | 6 ---- 14 files changed, 104 insertions(+), 37 deletions(-) create mode 100644 radio/src/bitfield.h diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index e6c42e288..35b9922fd 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -46,7 +46,6 @@ option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF) option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF) option(NANO "Use nano newlib and binalloc") option(NIGHTLY_BUILD_WARNING "Warn this is a nightly build" OFF) -option(MODULE_R9M_FLEX_FW "Add R9M options for non certified firmwwares" OFF) # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -312,10 +311,6 @@ if(NIGHTLY_BUILD_WARNING) add_definitions(-DNIGHTLY_BUILD_WARNING) endif(NIGHTLY_BUILD_WARNING) -if(MODULE_R9M_FLEX_FW) - add_definitions(-DMODULE_R9M_FLEX_FW) -endif() - set(SRC ${SRC} opentx.cpp diff --git a/radio/src/bitfield.h b/radio/src/bitfield.h new file mode 100644 index 000000000..84b3632b5 --- /dev/null +++ b/radio/src/bitfield.h @@ -0,0 +1,51 @@ +/* + * 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 + * + * This file is based on work published at http://www.coranac.com/documents/working-with-bits-and-bitfields + * + * 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 BITFIELD_H +#define BITFIELD_H + +// A set of bitfield handling macros +#define BF_BIT(n) ( 1<<(n) ) +#define BF_BIT_GET(y, mask) ( y & (mask) ) +#define BF_BIT_SET(y, mask) ( y |= (mask) ) +#define BF_BIT_CLEAR(y, mask) ( y &= ~(mask) ) +#define BF_BIT_FLIP(y, mask) ( y ^= (mask) ) +#define BF_SINGLE_BIT_GET(y, i) BF_BIT_GET(y, BF_BIT(i)) +#define BF_SINGLE_BIT_SET(y, i) BF_BIT_SET(y, BF_BIT(i)) + +//! Create a bitmask of length 'len'. +#define BF_BITMASK(len) ( BF_BIT(len)-1 ) + +//! Create a bitfield mask of length 'len' starting at bit 'start'. +#define BF_MASK(start, len) ( BF_BITMASK(len)<<(start) ) + +//! Prepare a bitmask for insertion or combining. +#define BF_PREP(x, start, len) ( ((x)&BF_BITMASK(len)) << (start) ) + +//! Extract a bitfield of length 'len' starting at bit 'start' from 'y'. +#define BF_GET(y, start, len) ( ((y)>>(start)) & BF_BITMASK(len) ) + +//! Insert 'len' bits of 'x 'into 'y', starting at bit 'start' from 'y'. +#define BF_SET(y, x, start, len) \ + ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) ) + +#endif //BITFIELD_H \ No newline at end of file diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 6b2298f09..7db9f56ea 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -161,7 +161,7 @@ enum MenuModelSetupItems { #endif #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) - #define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 + #define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 #define CURSOR_ON_CELL (true) #define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX) @@ -727,7 +727,7 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); - else if (isModuleR9M(EXTERNAL_MODULE)) + else if (isR9ModuleRunning(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { @@ -1192,13 +1192,7 @@ void menuModelSetup(event_t event) } #endif if (isModuleR9M(moduleIdx)) { - lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY); - if (IS_TELEMETRY_INTERNAL_MODULE()) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); - } - else { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); - } + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, TR_R9MFLEX_FREQ, BF_GET(g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1), attr); } else if (isModuleSBUS(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index c48ee4463..5959484da 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -54,6 +54,7 @@ bool isSwitchAvailableInCustomFunctions(int swtch); bool isSwitchAvailableInMixes(int swtch); bool isSwitchAvailableInTimers(int swtch); bool isR9MModeAvailable(int mode); +bool isR9ModuleRunning(int module); bool isModuleAvailable(int module); bool isRfProtocolAvailable(int protocol); bool isTelemetryProtocolAvailable(int protocol); @@ -155,12 +156,12 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); #define FAILSAFE_ROWS(x) ((isModuleXJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || isModuleR9M(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW -#define EXTERNAL_MODULE_OPTION_ROW (isModuleR9M(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#define EXTERNAL_MODULE_OPTION_ROW (isR9ModuleRunning(EXTERNAL_MODULE) ? HIDDEN_ROW : isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) #if defined(PCBXLITE) && !defined(MODULE_R9M_FULLSIZE) #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (isModuleR9M_FCC_VARIANT(EXTERNAL_MODULE) ? TITLE_ROW : (uint8_t) 0) : HIDDEN_ROW #else -#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW +#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isR9ModuleRunning(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW #endif void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index 0fad2f4c4..343103bd6 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -486,13 +486,18 @@ bool isSourceAvailableInResetSpecialFunction(int index) } } +bool isR9ModuleRunning(int module) +{ +#if defined(SIMU) + return g_model.moduleData[module].type == MODULE_TYPE_R9M && TELEMETRY_STREAMING(); // Simu uses telemetry simu to activate/desactivate R9 +#else + return g_model.moduleData[module].type == MODULE_TYPE_R9M && R9ModuleStreaming; +#endif +} + bool isR9MModeAvailable(int mode) { -#if defined(MODULE_R9M_FLEX_FW) - return mode >= MODULE_SUBTYPE_R9M_EUPLUS; -#else - return mode <= MODULE_SUBTYPE_R9M_EU; -#endif + return mode <= MODULE_SUBTYPE_R9M_EUPLUS; } bool isModuleAvailable(int module) @@ -516,6 +521,9 @@ bool isModuleAvailable(int module) return false; } #endif + if (module == MODULE_TYPE_R9M && g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) { + return false; + } return true; } @@ -531,6 +539,10 @@ bool isRfProtocolAvailable(int protocol) return false; } #endif + if (protocol != RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { + return false; + } + return true; } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index daf616120..0039e0a3f 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -27,6 +27,7 @@ #include #include "definitions.h" #include "opentx_types.h" +#include "bitfield.h" #if defined(STM32) #include "usbd_conf.h" #endif diff --git a/radio/src/pulses/pulses_arm.h b/radio/src/pulses/pulses_arm.h index 3c7311988..8b7e047a2 100644 --- a/radio/src/pulses/pulses_arm.h +++ b/radio/src/pulses/pulses_arm.h @@ -184,8 +184,10 @@ enum R9MLBTPowerValues { #else -#define LEN_R9M_REGION "\006" -#define TR_R9M_REGION "FCC\0 ""EU\0 ""868MHz""915MHz" +#define LEN_R9M_REGION "\004" +#define TR_R9M_REGION "FCC\0""EU\0 ""FLEX" +#define LEN_R9MFLEX_FREQ "\006" +#define TR_R9MFLEX_FREQ "868Mhz""915Mhz" #define LEN_R9M_FCC_POWER_VALUES "\006" #define LEN_R9M_LBT_POWER_VALUES "\013" #define TR_R9M_FCC_POWER_VALUES "10 mW\0" "100 mW" "500 mW" "1 W\0" diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 2ae1adfd8..7cce0f298 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -45,6 +45,7 @@ void Pxx2Pulses::setupFrame(uint8_t port) #if defined(LUA) if (outputTelemetryBufferTrigger != 0x00 && outputTelemetryBufferSize > 0) { + TRACE("SENDING TELEM"); // primID (1 byte) + dataID (2 bytes) + value (4 bytes) for (uint8_t i=0; i<7; i++) { addByte(outputTelemetryBuffer[i]); diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 249776c17..e5eb12ff9 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -59,6 +59,11 @@ void processFrskyPXX2Data(uint8_t data) telemetryRxBuffer[telemetryRxBufferCount++] = data; if (telemetryRxBuffer[0] + 3 /* 1 byte for length, 2 bytes for CRC */ == telemetryRxBufferCount) { if (checkPXX2PacketCRC(telemetryRxBuffer)) { + R9ModuleStreaming = TELEMETRY_TIMEOUT10ms; // reset counter only if valid packets are being detected + uint8_t R9Region = (telemetryRxBuffer[3] & 0x30) >> 4; + if (R9Region != 0x04) { + BF_SET(g_model.moduleData[EXTERNAL_MODULE].subType, R9Region, 1, 2); // heading bit holds flex frequency + } if (telemetryRxBuffer[2] & 0x80) { createFrSkyPXX2Sensor(RSSI_ID, telemetryRxBuffer[2] & 0x7f); } @@ -68,7 +73,11 @@ void processFrskyPXX2Data(uint8_t data) if((telemetryRxBuffer[3] & 0x04) == 0) { createFrSkyPXX2Sensor(R9_PWR_ID, (telemetryRxBuffer[3] & 0x03)); } - sportProcessTelemetryPacketWithoutCrc(telemetryRxBuffer + 6 /* LEN, TYPE, RSSI/BAT, TP/SS/FW_T, FW_VER, Data ID */); + + if (telemetryRxBuffer[0] == 0x0c) { + sportProcessTelemetryPacketWithoutCrc(telemetryRxBuffer + 5 /* LEN, TYPE, RSSI/BAT, TP/SS/FW_T, FW_VER, Data ID */); + TRACE("Got TELEM data"); + } } telemetryRxBufferCount = 0; dataState = STATE_DATA_IDLE; diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index 7b789edeb..2e88e4843 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -190,9 +190,10 @@ enum FrSkyDataState { #define BATT_ID 0xf104 #define RAS_ID 0xf105 #define XJT_VERSION_ID 0xf106 +#define R9_PWR_ID 0xf107 #define FUEL_QTY_FIRST_ID 0x0a10 #define FUEL_QTY_LAST_ID 0x0a1f -#define R9_PWR_ID 0xf107 // TODO: *CRITICAL* agree on ID with FrSky, this value is just a placeholder + // Default sensor data IDs (Physical IDs + CRC) diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 96124792c..8fabe7692 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -21,6 +21,7 @@ #include "opentx.h" uint8_t telemetryStreaming = 0; +uint8_t R9ModuleStreaming = 0; uint8_t telemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; // Receive buffer. 9 bytes (full packet), worst case 18 bytes with byte-stuffing (+1) uint8_t telemetryRxBufferCount = 0; @@ -120,7 +121,7 @@ void telemetryWakeup() varioWakeup(); } #endif - + #define FRSKY_BAD_ANTENNA() (IS_RAS_VALUE_VALID() && telemetryData.swr.value > 0x33) static tmr10ms_t alarmsCheckTime = 0; @@ -202,7 +203,9 @@ void telemetryInterrupt10ms() wshhStreaming--; } #endif - + if (R9ModuleStreaming > 0) { + R9ModuleStreaming--; + } if (telemetryStreaming > 0) { telemetryStreaming--; } diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 3170bae7f..400a27ed6 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -36,6 +36,7 @@ #endif extern uint8_t telemetryStreaming; // >0 (true) == data is streaming in. 0 = no data detected for some time +extern uint8_t R9ModuleStreaming; // >0 (true) == R9 module is connected and sending data 0 = no data detected for some time #if defined(WS_HOW_HIGH) extern uint8_t wshhStreaming; @@ -130,7 +131,7 @@ inline uint8_t modelTelemetryProtocol() if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { return PROTOCOL_TELEMETRY_PXX2; } - + #if defined(MULTIMODULE) if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { return PROTOCOL_TELEMETRY_MULTIMODULE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 2ec3981dd..4e2191070 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -188,8 +188,9 @@ extern const char STR_OPEN9X[]; #define OFS_VFAILSAFE (OFS_USBMODES + sizeof(TR_USBMODES)) #define OFS_VTRAINERMODES (OFS_VFAILSAFE + sizeof(TR_VFAILSAFE)) #define OFS_TARANIS_PROTOCOLS (OFS_VTRAINERMODES + sizeof(TR_VTRAINERMODES)) - #define OFS_R9M_REGION (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS)) - #define OFS_R9M_FCC_POWER_VALUES (OFS_R9M_REGION + sizeof(TR_R9M_REGION)) + #define OFS_R9M_REGION (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS)) + #define OFS_R9MFLEX_FREQ (OFS_R9M_REGION + sizeof(TR_R9M_REGION)) + #define OFS_R9M_FCC_POWER_VALUES (OFS_R9MFLEX_FREQ + sizeof(TR_R9MFLEX_FREQ)) #define OFS_R9M_LBT_POWER_VALUES (OFS_R9M_FCC_POWER_VALUES + sizeof(TR_R9M_FCC_POWER_VALUES)) #define OFS_TELEMETRY_PROTOCOLS (OFS_R9M_LBT_POWER_VALUES + sizeof(TR_R9M_LBT_POWER_VALUES)) #define OFS_XJT_PROTOCOLS (OFS_TELEMETRY_PROTOCOLS + sizeof(TR_TELEMETRY_PROTOCOLS)) @@ -294,7 +295,8 @@ extern const char STR_OPEN9X[]; #define STR_VTRAINERMODES (STR_OPEN9X + OFS_VTRAINERMODES) #define STR_TARANIS_PROTOCOLS (STR_OPEN9X + OFS_TARANIS_PROTOCOLS) - #define STR_R9M_REGION (STR_OPEN9X + OFS_R9M_REGION) + #define STR_R9M_REGION (STR_OPEN9X + OFS_R9M_REGION) + #define STR_R9MFLEX_FREQ (STR_OPEN9X + OFS_R9MFLEX_FREQ) #define STR_R9M_FCC_POWER_VALUES (STR_OPEN9X + OFS_R9M_FCC_POWER_VALUES) #define STR_R9M_LBT_POWER_VALUES (STR_OPEN9X + OFS_R9M_LBT_POWER_VALUES) #define STR_TELEMETRY_PROTOCOLS (STR_OPEN9X + OFS_TELEMETRY_PROTOCOLS) diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py index 3e16c3b4f..50b61319e 100755 --- a/radio/util/fwoptions.py +++ b/radio/util/fwoptions.py @@ -79,7 +79,6 @@ options_taranis = { "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_taranisplus = { @@ -97,7 +96,6 @@ options_taranisplus = { "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_xlite = { @@ -114,7 +112,6 @@ options_xlite = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), "stdr9m": ("MODULE_R9M_FULLSIZE", "YES", None), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_taranisx9e = { @@ -132,7 +129,6 @@ options_taranisx9e = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "horussticks": ("STICKS", "HORUS", "STANDARD"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_x12s = { @@ -147,7 +143,6 @@ options_x12s = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), "pcbdev": ("PCBREV", "10", None), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_x10 = { @@ -161,5 +156,4 @@ options_x10 = { "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } From 22c1d5895abd262890e8836b4c17fab4ddf56ef9 Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 12 Dec 2018 13:27:11 +0100 Subject: [PATCH 02/13] X7 POC for R9 region sensing --- radio/src/gui/128x64/model_setup.cpp | 35 ++++++++++++++-------------- radio/src/gui/gui_common.h | 1 + radio/src/gui/gui_common_arm.cpp | 13 ++++++++++- radio/src/pulses/pulses_arm.h | 2 ++ radio/src/telemetry/frsky.cpp | 2 +- radio/src/translations.cpp | 2 ++ radio/src/translations.h | 1 + radio/src/translations/cz.h.txt | 1 + radio/src/translations/de.h.txt | 1 + radio/src/translations/en.h.txt | 1 + radio/src/translations/es.h.txt | 1 + radio/src/translations/fi.h.txt | 1 + radio/src/translations/fr.h.txt | 1 + radio/src/translations/it.h.txt | 1 + radio/src/translations/nl.h.txt | 1 + radio/src/translations/pl.h.txt | 1 + radio/src/translations/pt.h.txt | 1 + radio/src/translations/se.h.txt | 1 + 18 files changed, 48 insertions(+), 19 deletions(-) diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 7db9f56ea..67fa85ef6 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -97,6 +97,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, + ITEM_MODEL_EXTERNAL_MODULE_FREQ, #if defined(PCBSKY9X) && !defined(REVA) ITEM_MODEL_EXTRA_MODULE_LABEL, ITEM_MODEL_EXTRA_MODULE_CHANNELS, @@ -170,7 +171,7 @@ enum MenuModelSetupItems { #if defined(PCBSKY9X) && !defined(REVA) #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, #else - #define EXTRA_MODULE_ROWS + #define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW #endif #if defined(PCBX7) @@ -273,7 +274,7 @@ void menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, - EXTRA_MODULE_ROWS + EXTRA_MODULE_ROWS, FAILSAFE_ROWS(EXTERNAL_MODULE), TRAINER_ROWS }); #else @@ -728,7 +729,7 @@ void menuModelSetup(event_t event) else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isR9ModuleRunning(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType & 0x03, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -755,16 +756,6 @@ void menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); - else if (isModuleR9M(EXTERNAL_MODULE)) { - uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); - if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { - POPUP_WARNING(STR_R9MFLEXWARN1); - const char * w = STR_R9MFLEXWARN2; - SET_WARNING_INFO(w, strlen(w), 0); - } - g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; - } - #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -1191,10 +1182,7 @@ void menuModelSetup(event_t event) } } #endif - if (isModuleR9M(moduleIdx)) { - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, TR_R9MFLEX_FREQ, BF_GET(g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1), attr); - } - else if (isModuleSBUS(moduleIdx)) { + if (isModuleSBUS(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); } @@ -1241,6 +1229,19 @@ void menuModelSetup(event_t event) } break; + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + uint8_t frequency = BF_GET(g_model.moduleData[moduleIdx].subType, 2, 1); + lcdDrawTextAlignedLeft(y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, frequency, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, frequency, 1); + BF_SET(g_model.moduleData[moduleIdx].subType, frequency, 2, 1); + } + } + #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 5959484da..91711344e 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -55,6 +55,7 @@ bool isSwitchAvailableInMixes(int swtch); bool isSwitchAvailableInTimers(int swtch); bool isR9MModeAvailable(int mode); bool isR9ModuleRunning(int module); +bool isR9MMFlex(int module); bool isModuleAvailable(int module); bool isRfProtocolAvailable(int protocol); bool isTelemetryProtocolAvailable(int protocol); diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index 343103bd6..86545034a 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -490,7 +490,7 @@ bool isR9ModuleRunning(int module) { #if defined(SIMU) return g_model.moduleData[module].type == MODULE_TYPE_R9M && TELEMETRY_STREAMING(); // Simu uses telemetry simu to activate/desactivate R9 -#else +#else return g_model.moduleData[module].type == MODULE_TYPE_R9M && R9ModuleStreaming; #endif } @@ -500,6 +500,11 @@ bool isR9MModeAvailable(int mode) return mode <= MODULE_SUBTYPE_R9M_EUPLUS; } +bool isR9MMFlex(int module) +{ + return g_model.moduleData[module].subType >= MODULE_SUBTYPE_R9M_EUPLUS; +} + bool isModuleAvailable(int module) { #if defined(CROSSFIRE) @@ -521,10 +526,14 @@ bool isModuleAvailable(int module) return false; } #endif +#if !defined(PCBSKY9X) if (module == MODULE_TYPE_R9M && g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) { return false; } +#endif + return true; + } bool isRfProtocolAvailable(int protocol) @@ -539,9 +548,11 @@ bool isRfProtocolAvailable(int protocol) return false; } #endif +#if defined(pxx) if (protocol != RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { return false; } +#endif return true; } diff --git a/radio/src/pulses/pulses_arm.h b/radio/src/pulses/pulses_arm.h index 8b7e047a2..79a2347e1 100644 --- a/radio/src/pulses/pulses_arm.h +++ b/radio/src/pulses/pulses_arm.h @@ -166,6 +166,8 @@ void setCustomFailsafe(uint8_t moduleIndex); #define LEN_R9M_LBT_POWER_VALUES "\015" #define TR_R9M_FCC_POWER_VALUES "(100 mW)" #define TR_R9M_LBT_POWER_VALUES "25 mW 8ch\0 ""25 mW 16ch\0 ""100mW no tele" +#define LEN_R9MFLEX_FREQ "\006" +#define TR_R9MFLEX_FREQ "868Mhz""915Mhz" enum R9MFCCPowerValues { R9M_FCC_POWER_100 = 0, diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index e5eb12ff9..9ddf55d09 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -62,7 +62,7 @@ void processFrskyPXX2Data(uint8_t data) R9ModuleStreaming = TELEMETRY_TIMEOUT10ms; // reset counter only if valid packets are being detected uint8_t R9Region = (telemetryRxBuffer[3] & 0x30) >> 4; if (R9Region != 0x04) { - BF_SET(g_model.moduleData[EXTERNAL_MODULE].subType, R9Region, 1, 2); // heading bit holds flex frequency + BF_SET(g_model.moduleData[EXTERNAL_MODULE].subType, R9Region, 0, 2); // heading bit holds flex frequency } if (telemetryRxBuffer[2] & 0x80) { createFrSkyPXX2Sensor(RSSI_ID, telemetryRxBuffer[2] & 0x7f); diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 6684816da..c49b8d83f 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -92,6 +92,7 @@ const char STR_OPEN9X[] = ISTR(VTRAINERMODES) ISTR(TARANIS_PROTOCOLS) ISTR(R9M_REGION) + ISTR(R9MFLEX_FREQ) ISTR(R9M_FCC_POWER_VALUES) ISTR(R9M_LBT_POWER_VALUES) ISTR(TELEMETRY_PROTOCOLS) @@ -144,6 +145,7 @@ const char STR_PPMFRAME[] = TR_PPMFRAME; const char STR_REFRESHRATE[] = TR_REFRESHRATE; const char SSTR_WARN_BATTVOLTAGE[] = STR_WARN_BATTVOLTAGE; const char STR_MS[] = TR_MS; +const char STR_FREQUENCY[] = TR_FREQUENCY; const char STR_SWITCH[] = TR_SWITCH; const char STR_TRIMS[] = TR_TRIMS; const char STR_FADEIN[] = TR_FADEIN; diff --git a/radio/src/translations.h b/radio/src/translations.h index 4e2191070..bca41eb21 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -363,6 +363,7 @@ extern const char STR_PPMFRAME[]; extern const char STR_REFRESHRATE[]; extern const char SSTR_WARN_BATTVOLTAGE[]; extern const char STR_MS[]; +extern const char STR_FREQUENCY[]; extern const char STR_SWITCH[]; extern const char STR_TRIMS[]; extern const char STR_FADEIN[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 232c8042f..b4c6dcad8 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -563,6 +563,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Spínač" #define TR_TRIMS "Trimy" #define TR_FADEIN "Přechod Zap" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 99f732b24..61acde6a7 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -568,6 +568,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Schalt.", "Schalter") #define TR_TRIMS "Trims" #define TR_FADEIN "Langs. Ein" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index d83e74e5e..6515ccc31 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -566,6 +566,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Switch" #define TR_TRIMS "Trims" #define TR_FADEIN "Fade in" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 95ea1e70d..401a7f32a 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -571,6 +571,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Interr" #define TR_TRIMS "Trims" #define TR_FADEIN "Inicio" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 713f76875..ee3987d8c 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -563,6 +563,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Switch" #define TR_TRIMS "Trims" #define TR_FADEIN "Fade In" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index e3856eb73..28eb453ec 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -580,6 +580,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Inter", "Interrupteur") #define TR_TRIMS "Trims" #define TR_FADEIN "Fondu ON" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 8440f38c3..33330d96b 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -569,6 +569,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Inter." #define TR_TRIMS "Trims" #define TR_FADEIN "Diss.In" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 47cfbf8ea..d860725a7 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -563,6 +563,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Schak.", "Schakelaar") #define TR_TRIMS "Trims" #define TR_FADEIN "Fade in" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index a560a2b90..23a97885a 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -570,6 +570,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Przełą" #define TR_TRIMS "Trymy" #define TR_FADEIN "Pojawia" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 6cedfde68..97b505244 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -570,6 +570,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Chave" #define TR_TRIMS "Trims" #define TR_FADEIN "Aparecer" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index e8ae0b8ec..f6133f73a 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -582,6 +582,7 @@ #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Brytare" #define TR_TRIMS "Trimmar" #define TR_FADEIN "Tona In" From b850470783e039bab37bee07fa545df3c07b6c86 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 13 Dec 2018 08:15:00 +0100 Subject: [PATCH 03/13] Extra union added --- radio/src/datastructs.h | 15 ++++++++++++--- radio/src/gui/128x64/model_setup.cpp | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 44eb39f6a..1010276fe 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -406,9 +406,18 @@ PACK(struct ModuleData { int8_t rfProtocol:4; uint8_t channelsStart; int8_t channelsCount; // 0=8 channels - uint8_t failsafeMode:4; // only 3 bits used - uint8_t subType:3; - uint8_t invertedSerial:1; // telemetry serial inverted from standard + union { + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t subType:3; + uint8_t invertedSerial:1; // telemetry serial inverted from standard + }; + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t freq:2; + uint8_t region:2; + } r9m; + }; int16_t failsafeChannels[MAX_OUTPUT_CHANNELS]; union { struct { diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 67fa85ef6..20118ad8c 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1232,7 +1232,7 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_FREQ: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); - uint8_t frequency = BF_GET(g_model.moduleData[moduleIdx].subType, 2, 1); + uint8_t frequency = BF_GET(g_model.moduleData[moduleIdx].r9m.freq, 2, 1); lcdDrawTextAlignedLeft(y, STR_FREQUENCY); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, frequency, LEFT | attr); if (attr) From 50e004df9a0f810e06305da803a7ff7a1cf3e4e2 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 08:28:28 +0100 Subject: [PATCH 04/13] A more elegant approach (thank @bsongis) --- radio/src/gui/128x64/model_setup.cpp | 8 +++----- radio/src/gui/gui_common_arm.cpp | 2 +- radio/src/telemetry/frsky.cpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 20118ad8c..2385ea836 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -729,7 +729,7 @@ void menuModelSetup(event_t event) else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isR9ModuleRunning(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType & 0x03, (menuHorizontalPosition==1 ? attr : 0)); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -1232,13 +1232,11 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_FREQ: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); - uint8_t frequency = BF_GET(g_model.moduleData[moduleIdx].r9m.freq, 2, 1); lcdDrawTextAlignedLeft(y, STR_FREQUENCY); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, frequency, LEFT | attr); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, frequency, 1); - BF_SET(g_model.moduleData[moduleIdx].subType, frequency, 2, 1); + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); } } diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index 86545034a..a2c2bbb78 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -502,7 +502,7 @@ bool isR9MModeAvailable(int mode) bool isR9MMFlex(int module) { - return g_model.moduleData[module].subType >= MODULE_SUBTYPE_R9M_EUPLUS; + return g_model.moduleData[module].r9m.region == 0x02; } bool isModuleAvailable(int module) diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 9ddf55d09..22edba920 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -62,7 +62,7 @@ void processFrskyPXX2Data(uint8_t data) R9ModuleStreaming = TELEMETRY_TIMEOUT10ms; // reset counter only if valid packets are being detected uint8_t R9Region = (telemetryRxBuffer[3] & 0x30) >> 4; if (R9Region != 0x04) { - BF_SET(g_model.moduleData[EXTERNAL_MODULE].subType, R9Region, 0, 2); // heading bit holds flex frequency + g_model.moduleData[EXTERNAL_MODULE].r9m.region = R9Region; } if (telemetryRxBuffer[2] & 0x80) { createFrSkyPXX2Sensor(RSSI_ID, telemetryRxBuffer[2] & 0x7f); From cc6660291da96690e52fb480c5538b1b95d022e6 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 08:54:41 +0100 Subject: [PATCH 05/13] Cleanups and fixes related to R9 region changes --- radio/src/myeeprom.h | 9 +++++++++ radio/src/pulses/modules.h | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index ba58a329d..15713ab96 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -321,6 +321,15 @@ enum R9MSubTypes MODULE_SUBTYPE_R9M_LAST=MODULE_SUBTYPE_R9M_AUPLUS }; +enum R9MRegion +{ + MODULE_REGION_R9M_FCC, + MODULE_REGION_R9M_EU, + MODULE_REGION_R9M_FLEX, + MODULE_REGION_R9M_LAST=MODULE_REGION_R9M_FLEX +}; + + enum MultiModuleRFProtocols { MM_RF_PROTO_CUSTOM = -1, MM_RF_PROTO_FIRST = MM_RF_PROTO_CUSTOM, diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index 2ecb78168..cbc26a5df 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -106,27 +106,27 @@ inline bool isModuleR9M(uint8_t idx) inline bool isModuleR9M_FCC(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_FCC; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FCC; } inline bool isModuleR9M_LBT(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_EU; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_EU; } inline bool isModuleR9M_FCC_VARIANT(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_EU; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region != MODULE_REGION_R9M_EU; } inline bool isModuleR9M_EUPLUS(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_EUPLUS; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FLEX && g_model.moduleData[idx].r9m.freq == 0x00; } inline bool isModuleR9M_AU_PLUS(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_AUPLUS; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FLEX && g_model.moduleData[idx].r9m.freq == 0x01; } From 1c3d306c48600412b42a79abedc2a994f6089c05 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 12:59:04 +0100 Subject: [PATCH 06/13] Tidy up --- radio/src/bitfield.h | 51 ---------------------------- radio/src/gui/128x64/model_setup.cpp | 1 + radio/src/gui/gui_common_arm.cpp | 6 ++-- radio/src/myeeprom.h | 14 +++++--- radio/src/opentx.h | 1 - radio/src/pulses/modules.h | 10 +++--- radio/src/pulses/pxx2.cpp | 1 - radio/src/telemetry/frsky.cpp | 1 - 8 files changed, 19 insertions(+), 66 deletions(-) delete mode 100644 radio/src/bitfield.h diff --git a/radio/src/bitfield.h b/radio/src/bitfield.h deleted file mode 100644 index 84b3632b5..000000000 --- a/radio/src/bitfield.h +++ /dev/null @@ -1,51 +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 - * - * This file is based on work published at http://www.coranac.com/documents/working-with-bits-and-bitfields - * - * 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 BITFIELD_H -#define BITFIELD_H - -// A set of bitfield handling macros -#define BF_BIT(n) ( 1<<(n) ) -#define BF_BIT_GET(y, mask) ( y & (mask) ) -#define BF_BIT_SET(y, mask) ( y |= (mask) ) -#define BF_BIT_CLEAR(y, mask) ( y &= ~(mask) ) -#define BF_BIT_FLIP(y, mask) ( y ^= (mask) ) -#define BF_SINGLE_BIT_GET(y, i) BF_BIT_GET(y, BF_BIT(i)) -#define BF_SINGLE_BIT_SET(y, i) BF_BIT_SET(y, BF_BIT(i)) - -//! Create a bitmask of length 'len'. -#define BF_BITMASK(len) ( BF_BIT(len)-1 ) - -//! Create a bitfield mask of length 'len' starting at bit 'start'. -#define BF_MASK(start, len) ( BF_BITMASK(len)<<(start) ) - -//! Prepare a bitmask for insertion or combining. -#define BF_PREP(x, start, len) ( ((x)&BF_BITMASK(len)) << (start) ) - -//! Extract a bitfield of length 'len' starting at bit 'start' from 'y'. -#define BF_GET(y, start, len) ( ((y)>>(start)) & BF_BITMASK(len) ) - -//! Insert 'len' bits of 'x 'into 'y', starting at bit 'start' from 'y'. -#define BF_SET(y, x, start, len) \ - ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) ) - -#endif //BITFIELD_H \ No newline at end of file diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 2385ea836..bffa812c6 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1239,6 +1239,7 @@ void menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); } } + break; #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index a2c2bbb78..771f6fb0a 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -502,7 +502,7 @@ bool isR9MModeAvailable(int mode) bool isR9MMFlex(int module) { - return g_model.moduleData[module].r9m.region == 0x02; + return g_model.moduleData[module].r9m.region == MODULE_R9M_REGION_FLEX; } bool isModuleAvailable(int module) @@ -526,7 +526,7 @@ bool isModuleAvailable(int module) return false; } #endif -#if !defined(PCBSKY9X) +#if defined(PCBTARANIS) || defined(PCBHORUS) if (module == MODULE_TYPE_R9M && g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) { return false; } @@ -548,7 +548,7 @@ bool isRfProtocolAvailable(int protocol) return false; } #endif -#if defined(pxx) +#if defined(PCBTARANIS) || defined(PCBHORUS) if (protocol != RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { return false; } diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 15713ab96..8f435befe 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -323,12 +323,18 @@ enum R9MSubTypes enum R9MRegion { - MODULE_REGION_R9M_FCC, - MODULE_REGION_R9M_EU, - MODULE_REGION_R9M_FLEX, - MODULE_REGION_R9M_LAST=MODULE_REGION_R9M_FLEX + MODULE_R9M_REGION_FCC, + MODULE_R9M_REGION_EU, + MODULE_R9M_REGION_FLEX, + MODULE_R9M_REGION_LAST=MODULE_R9M_REGION_FLEX }; +enum R9MFrenquency +{ + MODULE_R9M_FREQ_868MHZ + MODULE_R9M_FREQ_915MHZ, + MODULE_R9M_FREQ_LAST=MODULE_R9M_FREQ_915MHZ +}; enum MultiModuleRFProtocols { MM_RF_PROTO_CUSTOM = -1, diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 0039e0a3f..daf616120 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -27,7 +27,6 @@ #include #include "definitions.h" #include "opentx_types.h" -#include "bitfield.h" #if defined(STM32) #include "usbd_conf.h" #endif diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index cbc26a5df..8a8dd2bec 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -106,27 +106,27 @@ inline bool isModuleR9M(uint8_t idx) inline bool isModuleR9M_FCC(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FCC; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FCC; } inline bool isModuleR9M_LBT(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_EU; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_EU; } inline bool isModuleR9M_FCC_VARIANT(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region != MODULE_REGION_R9M_EU; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region != MODULE_R9M_REGION_EU; } inline bool isModuleR9M_EUPLUS(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FLEX && g_model.moduleData[idx].r9m.freq == 0x00; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FLEX && g_model.moduleData[idx].r9m.freq == MODULE_R9M_FREQ_868MHZ; } inline bool isModuleR9M_AU_PLUS(uint8_t idx) { - return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_REGION_R9M_FLEX && g_model.moduleData[idx].r9m.freq == 0x01; + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FLEX && g_model.moduleData[idx].r9m.freq == MODULE_R9M_FREQ_915MHZ; } diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 7cce0f298..2ae1adfd8 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -45,7 +45,6 @@ void Pxx2Pulses::setupFrame(uint8_t port) #if defined(LUA) if (outputTelemetryBufferTrigger != 0x00 && outputTelemetryBufferSize > 0) { - TRACE("SENDING TELEM"); // primID (1 byte) + dataID (2 bytes) + value (4 bytes) for (uint8_t i=0; i<7; i++) { addByte(outputTelemetryBuffer[i]); diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 22edba920..6b5d61edf 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -76,7 +76,6 @@ void processFrskyPXX2Data(uint8_t data) if (telemetryRxBuffer[0] == 0x0c) { sportProcessTelemetryPacketWithoutCrc(telemetryRxBuffer + 5 /* LEN, TYPE, RSSI/BAT, TP/SS/FW_T, FW_VER, Data ID */); - TRACE("Got TELEM data"); } } telemetryRxBufferCount = 0; From 32146e767a4b864b4e1ac1efdb6691b29666162b Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 14:16:14 +0100 Subject: [PATCH 07/13] typo, fix compilation --- radio/src/myeeprom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 8f435befe..dacfab2d6 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -331,7 +331,7 @@ enum R9MRegion enum R9MFrenquency { - MODULE_R9M_FREQ_868MHZ + MODULE_R9M_FREQ_868MHZ, MODULE_R9M_FREQ_915MHZ, MODULE_R9M_FREQ_LAST=MODULE_R9M_FREQ_915MHZ }; From 0f8c4a7a7fa068f1e7149c308e01557598567f2e Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 17:35:07 +0100 Subject: [PATCH 08/13] Fix Xlite R9 UI (pulse still wrong) --- radio/src/gui/128x64/model_setup.cpp | 46 +++++++++++++++++++++++++--- radio/src/gui/gui_common.h | 6 ++++ radio/src/gui/gui_common_arm.cpp | 12 +++++++- radio/src/pulses/modules.h | 33 +++++++++++++++++++- 4 files changed, 90 insertions(+), 7 deletions(-) diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index bffa812c6..600f980c1 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -97,7 +97,9 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, +#if !defined(PCBXLITE) ITEM_MODEL_EXTERNAL_MODULE_FREQ, +#endif #if defined(PCBSKY9X) && !defined(REVA) ITEM_MODEL_EXTRA_MODULE_LABEL, ITEM_MODEL_EXTRA_MODULE_CHANNELS, @@ -161,17 +163,21 @@ enum MenuModelSetupItems { #define OUTPUT_TYPE_ROWS() #endif #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) - +#if defined(PCBXLITE) + #define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +#else #define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 - +#endif #define CURSOR_ON_CELL (true) #define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX) #define POT_WARN_ITEMS() ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) #define TIMER_ROWS 2, 0, 0, 0, 0 #if defined(PCBSKY9X) && !defined(REVA) #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, +#elif defined(PCBXLITE) + #define EXTRA_MODULE_ROWS #else - #define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW + #define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, #endif #if defined(PCBX7) @@ -274,7 +280,7 @@ void menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, - EXTRA_MODULE_ROWS, + EXTRA_MODULE_ROWS FAILSAFE_ROWS(EXTERNAL_MODULE), TRAINER_ROWS }); #else @@ -728,8 +734,13 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); +#if defined(PCBXLITE) + else if (isModuleR9M(EXTERNAL_MODULE)) + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); +#else else if (isR9ModuleRunning(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); +#endif #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -756,6 +767,17 @@ void menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); +#if defined(PCBXLITE) + else if (isModuleR9M(EXTERNAL_MODULE)) { + uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); + if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { + POPUP_WARNING(STR_R9MFLEXWARN1); + const char * w = STR_R9MFLEXWARN2; + SET_WARNING_INFO(w, strlen(w), 0); + } + g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; + } +#endif #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -1182,7 +1204,20 @@ void menuModelSetup(event_t event) } } #endif +#if defined(PCBXLITE) + if (isModuleR9M(moduleIdx)) { + lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY); + if (IS_TELEMETRY_INTERNAL_MODULE()) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); + } + else { + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); + } + } + else if (isModuleSBUS(moduleIdx)) { +#else if (isModuleSBUS(moduleIdx)) { +#endif lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); } @@ -1228,7 +1263,7 @@ void menuModelSetup(event_t event) } break; - +#if !defined(PCBXLITE) case ITEM_MODEL_EXTERNAL_MODULE_FREQ: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); @@ -1240,6 +1275,7 @@ void menuModelSetup(event_t event) } } break; +#endif #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 91711344e..1b06616ce 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -157,10 +157,16 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); #define FAILSAFE_ROWS(x) ((isModuleXJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || isModuleR9M(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW +#if defined(PCBXLITE) +#define EXTERNAL_MODULE_OPTION_ROW (isModuleR9M(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#else #define EXTERNAL_MODULE_OPTION_ROW (isR9ModuleRunning(EXTERNAL_MODULE) ? HIDDEN_ROW : isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#endif #if defined(PCBXLITE) && !defined(MODULE_R9M_FULLSIZE) #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (isModuleR9M_FCC_VARIANT(EXTERNAL_MODULE) ? TITLE_ROW : (uint8_t) 0) : HIDDEN_ROW +#elif defined(PCBXLITE) +#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW #else #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isR9ModuleRunning(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW #endif diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index 771f6fb0a..38ae22b4a 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -494,12 +494,22 @@ bool isR9ModuleRunning(int module) return g_model.moduleData[module].type == MODULE_TYPE_R9M && R9ModuleStreaming; #endif } +#if defined(PCBXLITE) +bool isR9MModeAvailable(int mode) +{ +#if defined(MODULE_R9M_FLEX_FW) + return mode >= MODULE_SUBTYPE_R9M_EUPLUS; +#else + return mode <= MODULE_SUBTYPE_R9M_EU; +#endif +} +#else bool isR9MModeAvailable(int mode) { return mode <= MODULE_SUBTYPE_R9M_EUPLUS; } - +#endif bool isR9MMFlex(int module) { return g_model.moduleData[module].r9m.region == MODULE_R9M_REGION_FLEX; diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index 8a8dd2bec..0af8a58ef 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -99,6 +99,37 @@ inline bool isModulePPM(uint8_t idx) } #endif +#if defined(PCBXLITE) +inline bool isModuleR9M(uint8_t idx) +{ + return g_model.moduleData[idx].type == MODULE_TYPE_R9M; +} + +inline bool isModuleR9M_FCC(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_FCC; +} + +inline bool isModuleR9M_LBT(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_EU; +} + +inline bool isModuleR9M_FCC_VARIANT(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_EU; +} + +inline bool isModuleR9M_EUPLUS(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_EUPLUS; +} + +inline bool isModuleR9M_AU_PLUS(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_AUPLUS; +} +#else inline bool isModuleR9M(uint8_t idx) { return g_model.moduleData[idx].type == MODULE_TYPE_R9M; @@ -128,7 +159,7 @@ inline bool isModuleR9M_AU_PLUS(uint8_t idx) { return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FLEX && g_model.moduleData[idx].r9m.freq == MODULE_R9M_FREQ_915MHZ; } - +#endif inline bool isModulePXX(uint8_t idx) { From 03c162b8da106ad3ae4a909c6ae138aec6887a1e Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 13 Dec 2018 17:53:57 +0100 Subject: [PATCH 09/13] Fix Xlite R9 pulse (untested) --- radio/src/pulses/pulses_arm.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/radio/src/pulses/pulses_arm.cpp b/radio/src/pulses/pulses_arm.cpp index 4cd7ab383..290369e3a 100755 --- a/radio/src/pulses/pulses_arm.cpp +++ b/radio/src/pulses/pulses_arm.cpp @@ -66,7 +66,11 @@ uint8_t getRequiredProtocol(uint8_t port) required_protocol = PROTOCOL_CHANNELS_PXX; break; case MODULE_TYPE_R9M: +#if defined(PCBXLITE) + required_protocol = PROTOCOL_CHANNELS_PXX; +#else required_protocol = PROTOCOL_CHANNELS_PXX2; +#endif break; case MODULE_TYPE_SBUS: required_protocol = PROTOCOL_CHANNELS_SBUS; From d08910778b6cd7c739a3519ad0af6ac30366ee35 Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 14 Dec 2018 09:38:26 +0100 Subject: [PATCH 10/13] X9 UI --- radio/src/gui/212x64/model_setup.cpp | 41 +++++++++++++--------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 4f8c5ead2..193f3b805 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -88,6 +88,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, + ITEM_MODEL_EXTERNAL_MODULE_FREQ, ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, ITEM_MODEL_TRAINER_LINE1, @@ -253,7 +254,8 @@ int getSwitchWarningsCount() #define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0 -#define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : isModuleMultimodule(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0 +#define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +#define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, #if TIMERS == 1 #define TIMERS_ROWS TIMER_ROWS(0) @@ -296,6 +298,7 @@ void menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, + EXTRA_MODULE_ROWS LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS}); MENU_CHECK(STR_MENUSETUP, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_MAX); @@ -733,8 +736,8 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); - else if (isModuleR9M(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + else if (isR9ModuleRunning(EXTERNAL_MODULE)) + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -771,15 +774,6 @@ void menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); - else if (isModuleR9M(EXTERNAL_MODULE)) { - uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); - if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { - POPUP_WARNING(STR_R9MFLEXWARN1); - const char * w = STR_R9MFLEXWARN2; - SET_WARNING_INFO(w, strlen(w), 0); - } - g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; - } #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -1129,16 +1123,7 @@ void menuModelSetup(event_t event) } } #endif - if (isModuleR9M(moduleIdx)) { - lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY); - if (IS_TELEMETRY_INTERNAL_MODULE()) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); - } - else { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); - } - } - else if (isModuleSBUS(moduleIdx)) { + if (isModuleSBUS(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); } @@ -1174,6 +1159,18 @@ void menuModelSetup(event_t event) break; } + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); + } + } + break; + #if defined (MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) From de6574f45c68ee03c24941a140084523b2ef5f30 Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 14 Dec 2018 10:26:55 +0100 Subject: [PATCH 11/13] HORUS UI --- radio/src/gui/480x272/model_setup.cpp | 41 +++++++++++++-------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 0931e475b..ef90129b2 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -82,6 +82,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, + ITEM_MODEL_EXTERNAL_MODULE_FREQ, ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, ITEM_MODEL_TRAINER_LINE1, @@ -236,7 +237,8 @@ int getSwitchWarningsCount() #define TIMER_ROWS(x) NAVIGATION_LINE_BY_LINE|1, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 : (uint8_t)0 -#define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : isModuleMultimodule(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0 +#define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +#define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, #if TIMERS == 1 #define TIMERS_ROWS TIMER_ROWS(0) @@ -285,6 +287,7 @@ bool menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, + EXTRA_MODULE_ROWS LABEL(Trainer), 0, TRAINER_LINE1_ROWS, @@ -693,8 +696,8 @@ bool menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0)); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0)); - else if (isModuleR9M(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + else if (isR9ModuleRunning(EXTERNAL_MODULE)) + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -728,15 +731,6 @@ bool menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); - else if (isModuleR9M(EXTERNAL_MODULE)) { - uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); - if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { - POPUP_WARNING(STR_R9MFLEXWARN1); - const char * w = STR_R9MFLEXWARN2; - SET_WARNING_INFO(w, strlen(w), 0); - } - g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; - } #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -1068,16 +1062,7 @@ bool menuModelSetup(event_t event) } } #endif - if (isModuleR9M(moduleIdx)) { - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODULE_TELEMETRY); - if (IS_TELEMETRY_INTERNAL_MODULE()) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); - } - else { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); - } - } - else if (isModuleSBUS(moduleIdx)) { + if (isModuleSBUS(moduleIdx)) { lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WARN_BATTVOLTAGE); drawValueWithUnit(MODEL_SETUP_4TH_COLUMN, y, getBatteryVoltage(), UNIT_VOLTS, attr|PREC2|LEFT); } @@ -1116,6 +1101,18 @@ bool menuModelSetup(event_t event) } break; + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); + } + } + break; + #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) From 15cf9748e39bae2522b8ff1d18948c576f487bdb Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 14 Dec 2018 12:03:24 +0100 Subject: [PATCH 12/13] Fix R9M lite telemetry on Xlite --- radio/src/telemetry/telemetry.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 400a27ed6..daaf9947d 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -129,7 +129,11 @@ inline uint8_t modelTelemetryProtocol() } if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { +#if defined(PCBXLITE) + return PROTOCOL_TELEMETRY_FRSKY_SPORT; +#else return PROTOCOL_TELEMETRY_PXX2; +#endif } #if defined(MULTIMODULE) From 0e0943ba974c1140b0938baf001aba2aef39cd6b Mon Sep 17 00:00:00 2001 From: Kilrah Date: Sun, 16 Dec 2018 10:36:37 +0100 Subject: [PATCH 13/13] Compilation fix --- radio/src/pulses/modules.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index 0af8a58ef..7d9a7275c 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -88,7 +88,7 @@ inline bool isModulePPM(uint8_t idx) { return idx == TRAINER_MODULE || (idx == INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || - (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM)); + (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM); } #else inline bool isModulePPM(uint8_t idx)