From e43ad9adc612c6e5d32f72996f7d95fc211bfafb Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 21 Mar 2019 17:54:32 +0100 Subject: [PATCH] TX options added --- radio/src/gui/128x64/menus.cpp | 7 + radio/src/gui/128x64/menus.h | 1 + radio/src/gui/128x64/model_setup.cpp | 201 +++++++++++++++++++------ radio/src/gui/128x64/radio_version.cpp | 88 +++++++++-- radio/src/opentx.h | 32 ++-- radio/src/pulses/pulses.h | 1 + radio/src/pulses/pxx2.cpp | 43 ++++-- radio/src/pulses/pxx2.h | 21 ++- radio/src/telemetry/frsky_pxx2.cpp | 49 ++++-- radio/src/translations.h | 2 +- 10 files changed, 348 insertions(+), 97 deletions(-) diff --git a/radio/src/gui/128x64/menus.cpp b/radio/src/gui/128x64/menus.cpp index e153fda4e..e09448460 100644 --- a/radio/src/gui/128x64/menus.cpp +++ b/radio/src/gui/128x64/menus.cpp @@ -33,6 +33,13 @@ void popMenu() TRACE("popMenu(%d)", menuLevel); } +void abortPopMenu() +{ + menuLevel = menuLevel + 1; + menuEvent = 0; + TRACE("popMenu(%d) aborted", menuLevel); +} + void chainMenu(MenuHandlerFunc newMenu) { menuHandlers[menuLevel] = newMenu; diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index b8890dc0d..0f7c64342 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -56,6 +56,7 @@ extern uint8_t menuEvent; void chainMenu(MenuHandlerFunc newMenu); void pushMenu(MenuHandlerFunc newMenu); void popMenu(); +void abortPopMenu(); inline bool isRadioMenuDisplayed() { diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 15a670a52..83f331138 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -39,6 +39,7 @@ void drawReceiverName(uint8_t x, uint8_t y, uint8_t receiverSlot) } void menuModelFailsafe(event_t event); +void menuModelModuleOptions(event_t event); void menuModelReceiverOptions(event_t event); #if defined(PCBTARANIS) @@ -100,6 +101,7 @@ enum MenuModelSetupItems { #endif ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, ITEM_MODEL_INTERNAL_MODULE_PXX2_REGISTER_RANGE, + ITEM_MODEL_INTERNAL_MODULE_PXX2_OPTIONS, ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL, ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS, ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE, @@ -136,6 +138,7 @@ enum MenuModelSetupItems { #endif ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, ITEM_MODEL_EXTERNAL_MODULE_PXX2_REGISTER_RANGE, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_OPTIONS, ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL, ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS, ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE, @@ -188,7 +191,7 @@ enum MenuModelSetupItems { #if defined(PCBTARANIS) #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) - #define CURRENT_RECEIVER_EDITED(k) ((k - (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL : ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) / 3) + #define CURRENT_RECEIVER_EDITED(k) ((k - (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL : ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) / (ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL - ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) #elif defined(PCBSKY9X) && !defined(REVA) #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE) #else @@ -207,7 +210,7 @@ enum MenuModelSetupItems { #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) #endif -#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW ) +#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) #define EXTERNAL_MODULE_BIND_ROWS() ((isModuleXJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW @@ -241,26 +244,26 @@ enum MenuModelSetupItems { #if defined(PCBX7) || defined(PCBX3) #define ANTENNA_ROW #if defined(BLUETOOTH) - #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) - #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) - #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)), + #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) + #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) + #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)), #else #define TRAINER_BLUETOOTH_ROW #endif - #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) - #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) - #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW + #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) + #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW #elif defined(PCBXLITES) - #define ANTENNA_ROW IF_INTERNAL_MODULE_ON(0), + #define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), #define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW) #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)) #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) - #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) #define TRAINER_ROWS LABEL(Trainer), 0, IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW #elif defined(PCBXLITE) - #define ANTENNA_ROW IF_INTERNAL_MODULE_ON(0), + #define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), #define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW) #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) @@ -461,6 +464,7 @@ void menuModelSetup(event_t event) ANTENNA_ROW IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), // Module start channel IF_PXX2_MODULE(INTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(INTERNAL_MODULE, 0), // Module options IF_PXX2_MODULE(INTERNAL_MODULE, 0), // Receiver Name + Add/Del buttons IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 0, 0), // Receiver Pinmap IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 0, 1), // Receiver Bind/Share @@ -488,6 +492,7 @@ void menuModelSetup(event_t event) EXTERNAL_MODULE_FREQ_ROW FAILSAFE_ROWS(EXTERNAL_MODULE), IF_PXX2_MODULE(EXTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Receiver Name + Add/Del buttons IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 0, 0), // Receiver Pinmap IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 0, 1), // Receiver Bind/Share @@ -1310,6 +1315,17 @@ void menuModelSetup(event_t event) } break; + case ITEM_MODEL_INTERNAL_MODULE_PXX2_OPTIONS: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_OPTIONS: + lcdDrawText(INDENT_WIDTH, y, STR_OPTIONS); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); + if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { + g_moduleIdx = CURRENT_MODULE_EDITED(k); + memclear(&reusableBuffer.moduleSettings, sizeof(reusableBuffer.moduleSettings)); + pushMenu(menuModelModuleOptions); + } + break; + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS: case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS: case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS: @@ -1318,19 +1334,17 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS: case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS: case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_OPTIONS: - { lcdDrawText(INDENT_WIDTH * 2, y, STR_OPTIONS); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { g_moduleIdx = CURRENT_MODULE_EDITED(k); uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); uint8_t receiverSlot = g_model.moduleData[g_moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1; - memclear(&reusableBuffer.receiverSetup, sizeof(reusableBuffer.receiverSetup)); - reusableBuffer.receiverSetup.receiverId = receiverSlot; + memclear(&reusableBuffer.receiverSettings, sizeof(reusableBuffer.receiverSettings)); + reusableBuffer.receiverSettings.receiverId = receiverSlot; pushMenu(menuModelReceiverOptions); } - } - break; + break; case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE: case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE: @@ -1942,40 +1956,133 @@ void menuModelFailsafe(event_t event) } } -enum MenuModelReceiverOptions { +#define RECEIVER_OPTIONS_2ND_COLUMN 80 + +void onTxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.moduleSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.moduleSettings.dirty = 0; + reusableBuffer.moduleSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; + } + else { + reusableBuffer.moduleSettings.dirty = 0; + popMenu(); + } +} + +enum MenuModelModuleOptionsItems { + ITEM_MODULE_SETTINGS_RF_PROTOCOL, + ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, + ITEM_MODULE_SETTINGS_POWER, + ITEM_MODULE_SETTINGS_COUNT +}; + +void menuModelModuleOptions(event_t event) +{ + SIMPLE_SUBMENU_NOTITLE(ITEM_MODULE_SETTINGS_COUNT); + + if (menuEvent) { + moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.moduleSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION("Update TX options?", onTxOptionsUpdateConfirm); + } + else { + return; + } + } + + int8_t sub = menuVerticalPosition; + + lcdDrawTextAlignedLeft(0, "Module options"); + lcdInvertLine(0); + + if (event == EVT_ENTRY) { +#if defined(SIMU) + reusableBuffer.moduleSettings.state = PXX2_SETTINGS_OK; +#else + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; +#endif + } + + if (reusableBuffer.moduleSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_MODULE_SETTINGS_RF_PROTOCOL: + lcdDrawText(0, y, "RF Protocol"); + lcdDrawTextAtIndex(RECEIVER_OPTIONS_2ND_COLUMN, y, STR_XJT_PROTOCOLS, reusableBuffer.moduleSettings.rfProtocol + 1, attr); + if (attr) { + reusableBuffer.moduleSettings.rfProtocol = checkIncDec(event, reusableBuffer.moduleSettings.rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, 0, nullptr); + if (checkIncDec_Ret) { + reusableBuffer.moduleSettings.dirty = true; + } + } + break; + + case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: + reusableBuffer.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, "Ext. antenna", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.moduleSettings.dirty = true; + } + break; + + case ITEM_MODULE_SETTINGS_POWER: + lcdDrawText(0, y, "Power"); + lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.moduleSettings.txPower, attr); + lcdDrawText(lcdNextPos, y, "dBm"); + if (attr) { + reusableBuffer.moduleSettings.txPower = checkIncDec(event, reusableBuffer.moduleSettings.txPower, -127, 127); + if (checkIncDec_Ret) { + reusableBuffer.moduleSettings.dirty = true; + } + } + break; + } + } + } + else { + lcdDrawText(4 * FW, 4 * FH, "Waiting for TX..."); + } +} + +void onRxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.receiverSettings.dirty = 0; + reusableBuffer.receiverSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + else { + reusableBuffer.receiverSettings.dirty = 0; + popMenu(); + } +} + +enum MenuModelReceiverOptionsItems { ITEM_RECEIVER_TELEMETRY, ITEM_RECEIVER_PWM_RATE, ITEM_RECEIVER_PINMAP_FIRST }; -#define RECEIVER_OPTIONS_2ND_COLUMN 80 - -void onRxOptionsUpdateConfirm(const char * result) -{ - if (result == STR_OK) { - reusableBuffer.receiverSetup.state = RECEIVER_SETTINGS_WRITE; - reusableBuffer.receiverSetup.dirty = 0; - reusableBuffer.receiverSetup.timeout = 0; - moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; - } - else { - reusableBuffer.receiverSetup.dirty = 0; - popMenu(); - } -} - void menuModelReceiverOptions(event_t event) { const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; uint8_t wbar = LCD_W / 2 - 20; - uint8_t outputsCount = min(16, reusableBuffer.receiverSetup.outputsCount); + uint8_t outputsCount = min(16, reusableBuffer.receiverSettings.outputsCount); SIMPLE_SUBMENU_NOTITLE(ITEM_RECEIVER_PINMAP_FIRST + outputsCount); if (menuEvent) { moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; - if (reusableBuffer.receiverSetup.dirty) { - pushMenu(menuModelReceiverOptions); + if (reusableBuffer.receiverSettings.dirty) { + abortPopMenu(); POPUP_CONFIRMATION("Update RX options?", onRxOptionsUpdateConfirm); } else { @@ -1986,19 +2093,19 @@ void menuModelReceiverOptions(event_t event) int8_t sub = menuVerticalPosition; lcdDrawTextAlignedLeft(0, STR_RECEIVER_OPTIONS); - drawReceiverName(FW * 13, 0, reusableBuffer.receiverSetup.receiverId); + drawReceiverName(FW * 13, 0, reusableBuffer.receiverSettings.receiverId); lcdInvertLine(0); if (event == EVT_ENTRY) { #if defined(SIMU) - reusableBuffer.receiverSetup.state = RECEIVER_SETTINGS_OK; - reusableBuffer.receiverSetup.outputsCount = 8; + reusableBuffer.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.receiverSettings.outputsCount = 8; #else moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; #endif } - if (reusableBuffer.receiverSetup.state == RECEIVER_SETTINGS_OK) { + if (reusableBuffer.receiverSettings.state == PXX2_SETTINGS_OK) { for (uint8_t k=0; k= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + lcdDrawText(INDENT_WIDTH, y, "Model"); + lcdDrawText(12 * FW, y, modulesModels[reusableBuffer.hardware.modules[module].modelID]); + } + y += FH; + // Module version if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { lcdDrawText(INDENT_WIDTH, y, "Version"); - if (reusableBuffer.hardware.modules[module].hw_version) { - lcdDrawNumber(12 * FW, y, reusableBuffer.hardware.modules[module].hw_version, LEADING0, 3); - lcdDrawText(lcdLastRightPos, y, "/"); - lcdDrawNumber(lcdLastRightPos, y, reusableBuffer.hardware.modules[module].sw_version, LEADING0, 3); + if (reusableBuffer.hardware.modules[module].hwVersion.data) { + drawPXX2FullVersion(12 * FW, y, reusableBuffer.hardware.modules[module].hwVersion, reusableBuffer.hardware.modules[module].swVersion); } } y += FH; - // RX versions for (uint8_t receiver=0; receiver= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { lcdDrawText(INDENT_WIDTH, y, "Receiver"); lcdDrawNumber(lcdLastRightPos + 2, y, receiver + 1); - lcdDrawNumber(12 * FW, y, reusableBuffer.hardware.modules[module].receivers[receiver].hw_version, LEADING0, 3); - lcdDrawText(lcdLastRightPos, y, "/"); - lcdDrawNumber(lcdLastRightPos, y, reusableBuffer.hardware.modules[module].receivers[receiver].sw_version, LEADING0, 3); + lcdDrawText(12 * FW, y, receiversModels[reusableBuffer.hardware.modules[module].receivers[receiver].modelID]); + } + y += FH; + + // Receiver version + if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + drawPXX2FullVersion(12 * FW, y, reusableBuffer.hardware.modules[module].receivers[receiver].hwVersion, reusableBuffer.hardware.modules[module].receivers[receiver].swVersion); } y += FH; } @@ -176,7 +240,7 @@ void menuRadioVersion(event_t event) #endif #if defined(PXX2) - lcdDrawText(0, y, BUTTON("Modules / RX version"), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0); + lcdDrawText(INDENT_WIDTH, y, BUTTON("Modules / RX version"), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0); y += FH; if (menuVerticalPosition == ITEM_RADIO_MODULES_VERSION && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; @@ -185,14 +249,14 @@ void menuRadioVersion(event_t event) #endif #if defined(EEPROM_RLC) - lcdDrawText(0, y, BUTTON(TR_EEBACKUP), menuVerticalPosition == ITEM_RADIO_BACKUP_EEPROM ? INVERS : 0); + lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_EEBACKUP), menuVerticalPosition == ITEM_RADIO_BACKUP_EEPROM ? INVERS : 0); y += FH; if (menuVerticalPosition == ITEM_RADIO_BACKUP_EEPROM && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; eepromBackup(); } - lcdDrawText(0, y, BUTTON(TR_FACTORYRESET), menuVerticalPosition == ITEM_RADIO_FACTORY_RESET ? INVERS : 0); + lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_FACTORYRESET), menuVerticalPosition == ITEM_RADIO_FACTORY_RESET ? INVERS : 0); // y += FH; if (menuVerticalPosition == ITEM_RADIO_FACTORY_RESET && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; diff --git a/radio/src/opentx.h b/radio/src/opentx.h index a9821c9c7..055ac369b 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1045,10 +1045,6 @@ enum AUDIO_SOUNDS { #endif #include "buzzer.h" - - - - #include "translations.h" #include "fonts.h" @@ -1141,17 +1137,25 @@ union ReusableBuffer }; } moduleSetup; + struct { + uint8_t state; // 0x00 = READ 0x40 = WRITE + tmr10ms_t timeout; + uint8_t dirty; + uint8_t rfProtocol; + uint8_t externalAntenna; + int8_t txPower; + } moduleSettings; + struct { uint8_t state; // 0x00 = READ 0x40 = WRITE tmr10ms_t timeout; - tmr10ms_t updateTime; uint8_t receiverId; - uint8_t outputsCount; - uint8_t outputsMapping[24]; + uint8_t dirty; uint8_t telemetryDisabled; uint8_t pwmRate; - uint8_t dirty; - } receiverSetup; + uint8_t outputsCount; + uint8_t outputsMapping[24]; + } receiverSettings; // 103 bytes struct { @@ -1184,11 +1188,13 @@ union ReusableBuffer struct { int8_t step; uint8_t timeout; - uint32_t hw_version; - uint32_t sw_version; + uint8_t modelID; + PXX2Version hwVersion; + PXX2Version swVersion; struct { - uint32_t hw_version; - uint32_t sw_version; + uint8_t modelID; + PXX2Version hwVersion; + PXX2Version swVersion; } receivers[PXX2_MAX_RECEIVERS_PER_MODULE]; } modules[NUM_MODULES]; uint32_t updateTime; diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 37a6d35b3..405956259 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -69,6 +69,7 @@ enum ModuleSettingsMode MODULE_MODE_SPECTRUM_ANALYSER, MODULE_MODE_POWER_METER, MODULE_MODE_GET_HARDWARE_INFO, + MODULE_MODE_MODULE_SETTINGS, MODULE_MODE_RECEIVER_SETTINGS, MODULE_MODE_BEEP_FIRST, MODULE_MODE_REGISTER = MODULE_MODE_BEEP_FIRST, diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 71f4c0400..9abb29acf 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -154,27 +154,49 @@ void Pxx2Pulses::setupRegisterFrame(uint8_t module) } } +void Pxx2Pulses::setupModuleSettingsFrame(uint8_t module) +{ + if (get_tmr10ms() > reusableBuffer.moduleSettings.timeout) { + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_TX_SETTINGS); + uint8_t flag0 = 0; + if (reusableBuffer.moduleSettings.state == PXX2_SETTINGS_WRITE) + flag0 |= PXX2_TX_SETTINGS_FLAG0_WRITE; + Pxx2Transport::addByte(flag0); + if (reusableBuffer.moduleSettings.state == PXX2_SETTINGS_WRITE) { + uint8_t flag1 = reusableBuffer.moduleSettings.rfProtocol << 4; + if (reusableBuffer.moduleSettings.externalAntenna) + flag1 |= PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA; + Pxx2Transport::addByte(flag1); + Pxx2Transport::addByte(reusableBuffer.moduleSettings.txPower); + } + reusableBuffer.moduleSettings.timeout = get_tmr10ms() + 200/*next try in 2s*/; + } + else { + setupChannelsFrame(module); + } +} + void Pxx2Pulses::setupReceiverSettingsFrame(uint8_t module) { - if (get_tmr10ms() > reusableBuffer.receiverSetup.timeout) { + if (get_tmr10ms() > reusableBuffer.receiverSettings.timeout) { addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETTINGS); - uint8_t flag0 = reusableBuffer.receiverSetup.receiverId; - if (reusableBuffer.receiverSetup.state == RECEIVER_SETTINGS_WRITE) + uint8_t flag0 = reusableBuffer.receiverSettings.receiverId; + if (reusableBuffer.receiverSettings.state == PXX2_SETTINGS_WRITE) flag0 |= PXX2_RX_SETTINGS_FLAG0_WRITE; Pxx2Transport::addByte(flag0); - if (reusableBuffer.receiverSetup.state == RECEIVER_SETTINGS_WRITE) { + if (reusableBuffer.receiverSettings.state == PXX2_SETTINGS_WRITE) { uint8_t flag1 = 0; - if (reusableBuffer.receiverSetup.telemetryDisabled) + if (reusableBuffer.receiverSettings.telemetryDisabled) flag1 |= PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED; - if (reusableBuffer.receiverSetup.pwmRate) + if (reusableBuffer.receiverSettings.pwmRate) flag1 |= PXX2_RX_SETTINGS_FLAG1_FASTPWM; Pxx2Transport::addByte(flag1); - uint8_t outputsCount = min(16, reusableBuffer.receiverSetup.outputsCount); + uint8_t outputsCount = min(16, reusableBuffer.receiverSettings.outputsCount); for (int i = 0; i < outputsCount; i++) { - Pxx2Transport::addByte(reusableBuffer.receiverSetup.outputsMapping[i]); + Pxx2Transport::addByte(reusableBuffer.receiverSettings.outputsMapping[i]); } } - reusableBuffer.receiverSetup.timeout = get_tmr10ms() + 200/*next try in 2s*/; + reusableBuffer.receiverSettings.timeout = get_tmr10ms() + 200/*next try in 2s*/; } else { setupChannelsFrame(module); @@ -262,6 +284,9 @@ void Pxx2Pulses::setupFrame(uint8_t module) case MODULE_MODE_GET_HARDWARE_INFO: setupHardwareInfoFrame(module); break; + case MODULE_MODE_MODULE_SETTINGS: + setupModuleSettingsFrame(module); + break; case MODULE_MODE_RECEIVER_SETTINGS: setupReceiverSettingsFrame(module); break; diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 46131fff0..31e5f3a36 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -50,6 +50,9 @@ #define PXX2_RX_SETTINGS_FLAG1_READONLY (1 << 6) #define PXX2_RX_SETTINGS_FLAG1_FASTPWM (1 << 4) +#define PXX2_TX_SETTINGS_FLAG0_WRITE (1 << 6) +#define PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA (1 << 3) + enum PXX2RegisterSteps { REGISTER_START, REGISTER_RX_NAME_RECEIVED, @@ -65,9 +68,9 @@ enum PXX2BindSteps { }; enum PXX2ReceiverStatus { - RECEIVER_SETTINGS_READ, - RECEIVER_SETTINGS_WRITE, - RECEIVER_SETTINGS_OK + PXX2_SETTINGS_READ, + PXX2_SETTINGS_WRITE, + PXX2_SETTINGS_OK }; extern ModuleFifo intmoduleFifo; @@ -123,6 +126,8 @@ class Pxx2Pulses: public PxxPulses { void setupShareMode(uint8_t module); + void setupModuleSettingsFrame(uint8_t module); + void setupReceiverSettingsFrame(uint8_t module); void setupChannelsFrame(uint8_t module); @@ -192,4 +197,14 @@ class Pxx2Pulses: public PxxPulses { } }; +union PXX2Version +{ + uint16_t data; + struct { + uint8_t major; + uint8_t minor:4; + uint8_t revision:4; + }; +}; + #endif diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index f309d3b4a..208342561 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -51,15 +51,36 @@ void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) uint8_t index = frame[3]; if (index == 0xFF) { - reusableBuffer.hardware.modules[module].hw_version = *((uint16_t *)&frame[4]); - reusableBuffer.hardware.modules[module].sw_version = *((uint16_t *)&frame[6]); + reusableBuffer.hardware.modules[module].modelID = frame[4]; + reusableBuffer.hardware.modules[module].hwVersion.data = *((uint16_t *)&frame[5]); + reusableBuffer.hardware.modules[module].swVersion.data = *((uint16_t *)&frame[7]); } - else if (index < PXX2_MAX_RECEIVERS_PER_MODULE){ - reusableBuffer.hardware.modules[module].receivers[index].hw_version = *((uint16_t *)&frame[4]); - reusableBuffer.hardware.modules[module].receivers[index].sw_version = *((uint16_t *)&frame[6]); + else if (index < PXX2_MAX_RECEIVERS_PER_MODULE) { + reusableBuffer.hardware.modules[module].receivers[index].modelID = frame[4]; + reusableBuffer.hardware.modules[module].receivers[index].hwVersion.data = *((uint16_t *)&frame[5]); + reusableBuffer.hardware.modules[module].receivers[index].swVersion.data = *((uint16_t *)&frame[7]); } } +void processModuleSettingsFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_MODULE_SETTINGS) { + return; + } + + // Flag1 + reusableBuffer.moduleSettings.txPower = frame[4] >> 4; + if (frame[4] & PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA) + reusableBuffer.moduleSettings.externalAntenna = 1; + + // Power + reusableBuffer.moduleSettings.txPower = frame[5]; + + reusableBuffer.moduleSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.moduleSettings.timeout = 0; + moduleSettings[module].mode = MODULE_MODE_NORMAL; +} + void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) { if (moduleSettings[module].mode != MODULE_MODE_RECEIVER_SETTINGS) { @@ -67,21 +88,21 @@ void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) } if (frame[4] & PXX2_RX_SETTINGS_FLAG1_FASTPWM) - reusableBuffer.receiverSetup.pwmRate = 1; + reusableBuffer.receiverSettings.pwmRate = 1; if (frame[4] & PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED) - reusableBuffer.receiverSetup.telemetryDisabled = 1; + reusableBuffer.receiverSettings.telemetryDisabled = 1; uint8_t outputsCount = min(16, frame[0] - 4); - reusableBuffer.receiverSetup.outputsCount = outputsCount; + reusableBuffer.receiverSettings.outputsCount = outputsCount; for (uint8_t pin = 0; pin < outputsCount; pin++) { - reusableBuffer.receiverSetup.outputsMapping[pin] = frame[5 + pin]; + reusableBuffer.receiverSettings.outputsMapping[pin] = frame[5 + pin]; } - reusableBuffer.receiverSetup.state = RECEIVER_SETTINGS_OK; - reusableBuffer.receiverSetup.timeout = 0; + reusableBuffer.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.receiverSettings.timeout = 0; moduleSettings[module].mode = MODULE_MODE_NORMAL; - } +} void processRegisterFrame(uint8_t module, uint8_t * frame) { @@ -193,6 +214,10 @@ void processModuleFrame(uint8_t module, uint8_t *frame) processGetHardwareInfoFrame(module, frame); break; + case PXX2_TYPE_ID_TX_SETTINGS: + processModuleSettingsFrame(module, frame); + break; + case PXX2_TYPE_ID_RX_SETTINGS: processReceiverSettingsFrame(module, frame); break; diff --git a/radio/src/translations.h b/radio/src/translations.h index 62e7d11e7..43b1a6792 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -980,7 +980,7 @@ extern const char STR_BUTTON_SHARE[]; #if defined(PCBTARANIS) || defined(DSM2) extern const char STR_MODULE_RANGE[]; extern const char STR_RECEIVER_OPTIONS[]; - extern const char STR_DEL_BUTTON[]; +extern const char STR_DEL_BUTTON[]; #endif extern const char STR_ABOUTUS[];