diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index eee82aa61..04d253064 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1077,7 +1077,7 @@ void menuModelSetup(event_t event) break; case 1: CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); - if (k == ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) { + if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); } break; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 935f5bd2c..e7ac64a91 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -246,12 +246,13 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) #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 -inline uint8_t EXTERNAL_MODULE_MODE_ROWS() { +inline uint8_t EXTERNAL_MODULE_MODE_ROW() +{ if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) return 1; #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { - return 2 + MULTIMODULE_RFPROTO_ROWS(EXTERNAL_MODULE); + return 2 + MULTIMODULE_RFPROTO_COLUMNS(EXTERNAL_MODULE); } #endif else @@ -362,7 +363,7 @@ void menuModelSetup(event_t event) IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3 LABEL(ExternalModule), - EXTERNAL_MODULE_MODE_ROWS(), + EXTERNAL_MODULE_MODE_ROW(), MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), @@ -755,9 +756,9 @@ void menuModelSetup(event_t event) #if defined(INTERNAL_MODULE_PXX1) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(INTERNAL_MODULE)) - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1 + g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isModuleISRM(INTERNAL_MODULE)) - lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_ISRM_RF_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_ISRM_RF_PROTOCOLS, 1 + g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); if (attr) { if (menuHorizontalPosition == 0) { uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); @@ -769,7 +770,7 @@ void menuModelSetup(event_t event) } } else if (isModuleXJT(INTERNAL_MODULE)) { - g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, 0, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); + g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); if (checkIncDec_Ret) { g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1; g_model.moduleData[0].channelsStart = 0; @@ -777,7 +778,7 @@ void menuModelSetup(event_t event) } } else if (isModulePXX2(INTERNAL_MODULE)) { - g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_ISRM_PXX2_LAST, EE_MODEL, isRfProtocolAvailable); + g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_LR12, EE_MODEL, isRfProtocolAvailable); } } #else @@ -1038,16 +1039,10 @@ void menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); break; case 1: - CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart)); -#if defined(INTERNAL_MODULE_PPM) - if ((k == ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_SETUP_TRAINER_CHANNELS)) { + CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); + if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); } -#else - if ((k == ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_SETUP_TRAINER_CHANNELS)) { - SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); - } -#endif break; } } diff --git a/radio/src/gui/212x64/radio_hardware.cpp b/radio/src/gui/212x64/radio_hardware.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/radio/src/gui/480x272/CMakeLists.txt b/radio/src/gui/480x272/CMakeLists.txt index 1a722278f..de19e4b6a 100644 --- a/radio/src/gui/480x272/CMakeLists.txt +++ b/radio/src/gui/480x272/CMakeLists.txt @@ -8,6 +8,8 @@ set(GUI_SRC menu_model.cpp model_select.cpp model_setup.cpp + model_module_options.cpp + model_receiver_options.cpp model_failsafe.cpp model_logical_switches.cpp model_special_functions.cpp diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index 8ba739d7e..d141a1154 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -179,6 +179,8 @@ bool menuModelCustomScripts(event_t event); bool menuModelTelemetryFrsky(event_t event); bool menuModelSensor(event_t event); bool menuModelExpoOne(event_t event); +bool menuModelModuleOptions(event_t event); +bool menuModelReceiverOptions(event_t event); extern const MenuHandlerFunc menuTabModel[MENU_MODEL_PAGES_COUNT]; diff --git a/radio/src/gui/480x272/model_module_options.cpp b/radio/src/gui/480x272/model_module_options.cpp new file mode 100644 index 000000000..4d21f6b3b --- /dev/null +++ b/radio/src/gui/480x272/model_module_options.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#define RECEIVER_OPTIONS_2ND_COLUMN 200 + +extern uint8_t g_moduleIdx; + +enum { + MODULE_SETTINGS_OK = 0, + MODULE_SETTINGS_DIRTY = 1, + MODULE_SETTINGS_REBIND = 2, + MODULE_SETTINGS_WRITING = 4, +}; + +void onTxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_WRITING; + moduleState[g_moduleIdx].writeModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + else { + popMenu(); + } +} + +bool isTelemetryAvailable() +{ + return reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant != PXX2_VARIANT_EU || + reusableBuffer.hardwareAndSettings.moduleSettings.txPower <= 14; +} + +enum { + ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, + ITEM_MODULE_SETTINGS_POWER, + ITEM_MODULE_SETTINGS_TELEMETRY, + ITEM_MODULE_SETTINGS_COUNT +}; + +#define IF_MODULE_OPTIONS(option, count) uint8_t(isPXX2ModuleOptionAvailable(modelId, option) ? count : HIDDEN_ROW) + +bool isPowerAvailable(int value) +{ + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; + uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + + if (modelId == PXX2_MODULE_R9M_LITE) { + if (variant == PXX2_VARIANT_EU) + return (value == 14 /* 25 mW with telemetry */ || + value == 20 /* 100 mW without telemetry */); + else + return value == 20; /* 100 mW */ + } + else if (modelId == PXX2_MODULE_R9M || modelId == PXX2_MODULE_R9M_LITE_PRO) { + if (variant == PXX2_VARIANT_EU) + return (value == 14 /* 25 mW */ || + value == 23 /* 200 mW */ || + value == 27 /* 500 mW */); + else + return (value == 10 /* 10 mW */ || + value == 20 /* 100 mW */ || + value == 27 /* 500 mW */ || + value == 30 /* 1000 mW */); + } + else { + return (value <= 20); /* 100 mW max for XJTs */ + } +} + +bool menuModelModuleOptions(event_t event) +{ + if (event == EVT_ENTRY) { + memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; +#endif + } + + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; + // uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + uint8_t optionsAvailable = getPXX2ModuleOptions(modelId) & ((1 << MODULE_OPTION_EXTERNAL_ANTENNA) | (1 << MODULE_OPTION_POWER)); + + SUBMENU(STR_MODULE_OPTIONS, ICON_MODEL_SETUP, ITEM_MODULE_SETTINGS_COUNT, { + !optionsAvailable ? (uint8_t)0 : IF_MODULE_OPTIONS(MODULE_OPTION_EXTERNAL_ANTENNA, 0), + IF_MODULE_OPTIONS(MODULE_OPTION_POWER, 0), + IF_MODULE_OPTIONS(MODULE_OPTION_POWER, isTelemetryAvailable() ? HIDDEN_ROW : READONLY_ROW) + }); + + lcdDrawText(50, 3 + FH, getPXX2ModuleName(modelId), MENU_TITLE_COLOR); + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_HARDWARE_INFO && moduleState[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + if (!modelId) + moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[g_moduleIdx], PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); + else + moduleState[g_moduleIdx].readModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + + if (menuEvent) { + killEvents(KEY_EXIT); + moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION(STR_UPDATE_TX_OPTIONS, onTxOptionsUpdateConfirm); + } + else { + return false; + } + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_OK; + moduleState[g_moduleIdx].writeModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty == MODULE_SETTINGS_WRITING && reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + return false; + } + + if (modelId != 0 && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + menuVerticalPosition = 0; + while (menuVerticalPosition < ITEM_MODULE_SETTINGS_COUNT && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + ++menuVerticalPosition; + } + } + + int8_t sub = menuVerticalPosition; + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + if (optionsAvailable) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXT_ANTENNA); + reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY; + } + break; + + case ITEM_MODULE_SETTINGS_POWER: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWER); + lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, attr); + lcdDrawText(lcdNextPos, y, "dBm("); + drawPower(lcdNextPos, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower); + lcdDrawText(lcdNextPos, y, ")"); + if (attr) { + bool previousTelemetry = isTelemetryAvailable(); + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, 0, 30, 0, &isPowerAvailable); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY; + if (previousTelemetry != isTelemetryAvailable()) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty |= MODULE_SETTINGS_REBIND; + } + } + if (s_editMode == 0 && (reusableBuffer.hardwareAndSettings.moduleSettings.dirty & MODULE_SETTINGS_REBIND)) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty &= ~MODULE_SETTINGS_REBIND; + POPUP_WARNING(STR_REBIND); + } + } + break; + + case ITEM_MODULE_SETTINGS_TELEMETRY: + // only displayed in EU mode when TX power > 25mW + lcdDrawText(RECEIVER_OPTIONS_2ND_COLUMN, y, "Telem OFF", attr | SMLSIZE); + break; + } + } + } + else { + lcdDrawCenteredText(LCD_H/2, STR_NO_TX_OPTIONS); + s_editMode = 0; + } + } + else { + lcdDrawCenteredText(LCD_H/2, STR_WAITING_FOR_TX); + s_editMode = 0; + } + + return true; +} diff --git a/radio/src/gui/480x272/model_receiver_options.cpp b/radio/src/gui/480x272/model_receiver_options.cpp new file mode 100644 index 000000000..b1ab35036 --- /dev/null +++ b/radio/src/gui/480x272/model_receiver_options.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +#define RECEIVER_OPTIONS_2ND_COLUMN 200 + +extern uint8_t g_moduleIdx; + +enum { + RECEIVER_SETTINGS_OK = 0, + RECEIVER_SETTINGS_DIRTY = 1, + RECEIVER_SETTINGS_WRITING = 2, +}; + +void onRxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_WRITING; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleState[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + else { + popMenu(); + } +} + +enum { + ITEM_RECEIVER_SETTINGS_PWM_RATE, + ITEM_RECEIVER_SETTINGS_TELEMETRY, + ITEM_RECEIVER_SETTINGS_SPORT_FPORT, + ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1, + ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED2, + ITEM_RECEIVER_SETTINGS_PINMAP_FIRST +}; + + +#define IF_RECEIVER_CAPABILITY(capability, count) uint8_t((reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilities & (1 << capability)) ? count : HIDDEN_ROW) + +bool menuModelReceiverOptions(event_t event) +{ + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + uint8_t wbar = LCD_W / 2 - 20; + auto outputsCount = min(16, reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount); + + if (event == EVT_ENTRY) { + // reusableBuffer.hardwareSettings should have been cleared before calling this menu +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount = 16; +#endif + } + + uint8_t receiverId = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId; + uint8_t receiverModelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.modelID; + uint8_t receiverVariant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.variant; + + SUBMENU(STR_RECEIVER_OPTIONS, ICON_MODEL_SETUP, ITEM_RECEIVER_SETTINGS_PINMAP_FIRST + outputsCount, { + 0, // PWM rate + isModuleR9MAccess(g_moduleIdx) && receiverVariant == PXX2_VARIANT_EU && reusableBuffer.hardwareAndSettings.moduleSettings.txPower > 14 /*25mW*/ ? READONLY_ROW : (uint8_t)0, // Telemetry + IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT, 0), + uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW), + uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW), + 0 // channels ... + }); + + if (g_model.moduleData[g_moduleIdx].pxx2.receiverName[receiverId][0] != '\0') + lcdDrawSizedText(50, 3 + FH, g_model.moduleData[g_moduleIdx].pxx2.receiverName[receiverId], effectiveLen(g_model.moduleData[g_moduleIdx].pxx2.receiverName[receiverId], PXX2_LEN_RX_NAME), MENU_TITLE_COLOR); + else + lcdDrawText(50, 3 + FH, "---", MENU_TITLE_COLOR); + + if (menuEvent) { + killEvents(KEY_EXIT); + moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION(STR_UPDATE_RX_OPTIONS, onRxOptionsUpdateConfirm); + } + else { + return false; + } + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_HARDWARE_INFO && moduleState[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + if (!receiverModelId) + moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[g_moduleIdx], receiverId, receiverId); + else if (isModuleR9MAccess(g_moduleIdx) && receiverVariant == PXX2_VARIANT_EU && !reusableBuffer.hardwareAndSettings.moduleSettings.txPower) + moduleState[g_moduleIdx].readModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + else + moduleState[g_moduleIdx].readReceiverSettings(&reusableBuffer.hardwareAndSettings.receiverSettings); + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_OK; + moduleState[g_moduleIdx].writeReceiverSettings(&reusableBuffer.hardwareAndSettings.receiverSettings); + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty == RECEIVER_SETTINGS_WRITING && reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + return false; + } + + if (receiverModelId && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + menuVerticalPosition = 0; + while (menuVerticalPosition < ITEM_RECEIVER_SETTINGS_PINMAP_FIRST && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + ++menuVerticalPosition; + } + } + + int8_t sub = menuVerticalPosition; + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_RECEIVER_SETTINGS_PWM_RATE: + lcdDrawText(MENUS_MARGIN_LEFT, y, isModuleR9MAccess(g_moduleIdx) ? "6.67ms PWM": "9ms PWM"); + reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY; + } + break; + + case ITEM_RECEIVER_SETTINGS_TELEMETRY: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TELEMETRY_DISABLED); + reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY; + } + break; + + case ITEM_RECEIVER_SETTINGS_SPORT_FPORT: + lcdDrawText(MENUS_MARGIN_LEFT, y, "F.Port"); + reusableBuffer.hardwareAndSettings.receiverSettings.fport = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY; + } + break; + + case ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1: + lcdDrawText(LCD_W/2, y+1, STR_MORE_OPTIONS_AVAILABLE, SMLSIZE|CENTERED); + break; + + case ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED2: + lcdDrawText(LCD_W/2, y+1, STR_OPENTX_UPGRADE_REQUIRED, SMLSIZE|CENTERED); + break; + + default: + // Pin + { + uint8_t pin = i - ITEM_RECEIVER_SETTINGS_PINMAP_FIRST; + if (pin < reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount) { + uint8_t & mapping = reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin]; + uint8_t channel = g_model.moduleData[g_moduleIdx].channelsStart + mapping; + int32_t channelValue = channelOutputs[channel]; + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_PIN); + lcdDrawNumber(lcdNextPos + 1, y, pin + 1); + putsChn(100, y, channel + 1, attr); + + // Channel + if (attr) { + mapping = checkIncDec(event, mapping, 0, sentModuleChannels(g_moduleIdx) - 1); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY; + } + } + + // Bargraph + lcdDrawRect(RECEIVER_OPTIONS_2ND_COLUMN, y + 4, wbar + 1, 10); + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar / 2 + lim / 2) / lim, wbar / 2); + const coord_t xChannel = (channelValue > 0) ? RECEIVER_OPTIONS_2ND_COLUMN + wbar / 2 : RECEIVER_OPTIONS_2ND_COLUMN + wbar / 2 + 1 - lenChannel; + lcdDrawSolidFilledRect(xChannel, y + 5, lenChannel, 8, TEXT_INVERTED_BGCOLOR); + } + break; + } + } + } + } + else { + lcdDrawCenteredText(LCD_H/2, STR_WAITING_FOR_RX); + } + + return true; +} diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index ad6f31f72..6a99fd560 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -84,18 +84,25 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL, ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE, - ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS, #endif ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND, - ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM, ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS, #if defined(MULTIMODULE) ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND, #endif + ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_OPTIONS, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2, + ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3, + ITEM_MODEL_SETUP_TRAINER_LABEL, ITEM_MODEL_SETUP_TRAINER_MODE, #if defined(BLUETOOTH) @@ -202,12 +209,13 @@ void onPXX2ReceiverMenu(const char * result) memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx; g_moduleIdx = moduleIdx; - // TODO pushMenu(menuModelReceiverOptions); + pushMenu(menuModelReceiverOptions); } else if (result == STR_BIND) { memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation)); reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx; if (isModuleR9MAccess(moduleIdx)) { + reusableBuffer.moduleSetup.bindInformation.step = BIND_MODULE_TX_INFORMATION_REQUEST; #if defined(SIMU) reusableBuffer.moduleSetup.pxx2.moduleInformation.information.modelID = 1; reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant = 2; @@ -484,17 +492,24 @@ int getSwitchWarningsCount() #define IF_ACCESS_MODULE_RF(module, xxx) (isModuleRFAccess(module) ? (uint8_t)(xxx) : HIDDEN_ROW) #define IF_NOT_ACCESS_MODULE_RF(module, xxx) (isModuleRFAccess(module) ? HIDDEN_ROW : (uint8_t)(xxx)) -#if defined(INTERNAL_MODULE_PXX1) #define INTERNAL_MODULE_TYPE_ROWS ((isModuleXJT(INTERNAL_MODULE) || isModulePXX2(INTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols -#else -#define INTERNAL_MODULE_TYPE_ROWS 0 // Module type + RF protocols -#endif -#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) +#define MODULE_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) #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 (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +inline uint8_t EXTERNAL_MODULE_MODE_ROW() +{ + if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) + return 1; +#if defined(MULTIMODULE) + else if (isModuleMultimodule(EXTERNAL_MODULE)) { + return 2 + MULTIMODULE_RFPROTO_COLUMNS(EXTERNAL_MODULE); + } +#endif + else + return 0; +} #if TIMERS == 1 #define TIMERS_ROWS TIMER_ROWS(0) @@ -595,14 +610,20 @@ bool menuModelSetup(event_t event) IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */ LABEL(ExternalModule), - EXTERNAL_MODULE_MODE_ROWS, - EXTERNAL_MODULE_POWER_ROW, + EXTERNAL_MODULE_MODE_ROW(), MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, - EXTERNAL_MODULE_BIND_ROWS, - FAILSAFE_ROWS(EXTERNAL_MODULE), - EXTERNAL_MODULE_OPTION_ROW, + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum for ACCESS + IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW), MULTIMODULE_MODULE_ROWS + EXTERNAL_MODULE_POWER_ROW, + FAILSAFE_ROWS(EXTERNAL_MODULE), + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3 TRAINER_ROWS }); @@ -964,9 +985,9 @@ bool menuModelSetup(event_t event) lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODE); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(INTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_ACCST_RF_PROTOCOLS, 1 + g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); else if (isModuleISRM(INTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_ISRM_RF_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_ISRM_RF_PROTOCOLS, 1 + g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); if (attr) { if (menuHorizontalPosition == 0) { uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); @@ -978,7 +999,7 @@ bool menuModelSetup(event_t event) } } else if (isModuleXJT(INTERNAL_MODULE)) { - g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); + g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); if (checkIncDec_Ret) { g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1; g_model.moduleData[0].channelsStart = 0; @@ -1136,7 +1157,7 @@ bool menuModelSetup(event_t event) uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CHANNELRANGE); - if ((int8_t)PORT_CHANNELS_ROWS(moduleIdx) >= 0) { + if ((int8_t)MODULE_CHANNELS_ROWS(moduleIdx) >= 0) { drawStringWithIndex(MODEL_SETUP_2ND_COLUMN, y, STR_CH, moduleData.channelsStart+1, menuHorizontalPosition==0 ? attr : 0); lcdDrawText(lcdNextPos+5, y, "-"); drawStringWithIndex(lcdNextPos+5, y, STR_CH, moduleData.channelsStart+sentModuleChannels(moduleIdx), menuHorizontalPosition==1 ? attr : 0); @@ -1149,9 +1170,10 @@ bool menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); break; case 1: - CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart)); - if (k == ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) + CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); + if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + } break; } } @@ -1305,12 +1327,12 @@ bool menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_OPTIONS: lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_OPTIONS); drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { g_moduleIdx = CURRENT_MODULE_EDITED(k); - memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); - // TODO pushMenu(menuModelModuleOptions); + pushMenu(menuModelModuleOptions); } break; diff --git a/radio/src/gui/480x272/model_telemetry_sensor.cpp b/radio/src/gui/480x272/model_telemetry_sensor.cpp index 1926e1af5..f4d285efb 100644 --- a/radio/src/gui/480x272/model_telemetry_sensor.cpp +++ b/radio/src/gui/480x272/model_telemetry_sensor.cpp @@ -59,9 +59,9 @@ bool menuModelSensor(event_t event) SUBMENU("SENSOR", ICON_MODEL_TELEMETRY, SENSOR_FIELD_MAX, { 0, 0, sensor->type == TELEM_TYPE_CALCULATED ? (uint8_t)0 : (uint8_t)1, SENSOR_UNIT_ROWS, SENSOR_PREC_ROWS, SENSOR_PARAM1_ROWS, SENSOR_PARAM2_ROWS, SENSOR_PARAM3_ROWS, SENSOR_PARAM4_ROWS, SENSOR_AUTOOFFSET_ROWS, SENSOR_ONLYPOS_ROWS, SENSOR_FILTER_ROWS, SENSOR_PERSISTENT_ROWS, 0 }); lcdDrawNumber(lcdNextPos, 3, s_currIdx+1, MENU_TITLE_COLOR|LEFT); - drawSensorCustomValue(50, 3+FH, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), MENU_TITLE_COLOR|LEFT); + drawSensorCustomValue(50, 3 + FH, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), MENU_TITLE_COLOR|LEFT); - for (uint8_t i=0; imaxSubtype > 0; } -inline uint8_t MULTIMODULE_RFPROTO_ROWS(uint8_t moduleIdx) +inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx) { return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 1 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 0 : HIDDEN_ROW); } -#define MULTIMODULE_SUBTYPE_ROWS(x) isModuleMultimodule(x) ? MULTIMODULE_RFPROTO_ROWS(x) : HIDDEN_ROW, +#define MULTIMODULE_SUBTYPE_ROWS(x) isModuleMultimodule(x) ? MULTIMODULE_RFPROTO_COLUMNS(x) : HIDDEN_ROW, #define MULTIMODULE_HASOPTIONS(x) (getMultiProtocolDefinition(x)->optionsstr != nullptr) #define MULTIMODULE_OPTIONS_ROW (isModuleMultimodule(EXTERNAL_MODULE) && MULTIMODULE_HASOPTIONS(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index acd46b36c..7a8cae8ac 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -61,27 +61,32 @@ uint8_t getRequiredProtocol(uint8_t module) break; } #endif - // no break + protocol = PROTOCOL_CHANNELS_PXX1_PULSES; + break; case MODULE_TYPE_R9M_PXX1: protocol = PROTOCOL_CHANNELS_PXX1_PULSES; break; +#if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) case MODULE_TYPE_R9M_LITE_PXX1: case MODULE_TYPE_R9M_LITE_PRO_PXX1: protocol = PROTOCOL_CHANNELS_PXX1_SERIAL; break; - case MODULE_TYPE_ISRM_PXX2: - case MODULE_TYPE_XJT_LITE_PXX2: - case MODULE_TYPE_R9M_PXX2: - case MODULE_TYPE_R9M_LITE_PRO_PXX2: - protocol = PROTOCOL_CHANNELS_PXX2_HIGHSPEED; - break; - case MODULE_TYPE_R9M_LITE_PXX2: protocol = PROTOCOL_CHANNELS_PXX2_LOWSPEED; break; +#endif + + case MODULE_TYPE_ISRM_PXX2: + case MODULE_TYPE_R9M_PXX2: +#if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) + case MODULE_TYPE_XJT_LITE_PXX2: + case MODULE_TYPE_R9M_LITE_PRO_PXX2: +#endif + protocol = PROTOCOL_CHANNELS_PXX2_HIGHSPEED; + break; case MODULE_TYPE_SBUS: protocol = PROTOCOL_CHANNELS_SBUS; @@ -149,7 +154,7 @@ void enablePulsesExternalModule(uint8_t protocol) break; #endif -#if defined(PXX1) && defined(EXTMODULE_USART) +#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) case PROTOCOL_CHANNELS_PXX1_SERIAL: extmodulePxx1SerialStart(); break; @@ -212,7 +217,7 @@ void setupPulsesExternalModule(uint8_t protocol) break; #endif -#if defined(PXX1) && defined(EXTMODULE_USART) +#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) case PROTOCOL_CHANNELS_PXX1_SERIAL: extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE); scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD); diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index c2ee66d53..d583157fb 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -281,7 +281,7 @@ union InternalModulePulsesData { union ExternalModulePulsesData { #if defined(PXX1) - #if defined(EXTMODULE_USART) + #if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) UartPxx1Pulses pxx_uart; #endif #if defined(PPM_PIN_SERIAL) diff --git a/radio/src/pulses/pulses_common.h b/radio/src/pulses/pulses_common.h index f453c5f7c..83058f635 100644 --- a/radio/src/pulses/pulses_common.h +++ b/radio/src/pulses/pulses_common.h @@ -23,14 +23,14 @@ #include -#if defined(PCBX12S) && PCBREV < 13 - #define pulse_duration_t uint32_t - #define trainer_pulse_duration_t uint16_t +#if defined(EXTMODULE_TIMER_32BITS) + typedef uint32_t pulse_duration_t; #else - #define pulse_duration_t uint16_t - #define trainer_pulse_duration_t uint16_t + typedef uint16_t pulse_duration_t; #endif +typedef uint16_t trainer_pulse_duration_t; + template class DataBuffer { public: diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 9e9625ece..f88c92b1e 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -1,5 +1,5 @@ -option(DISK_CACHE "Enable SD card disk cache" YES) -option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" YES) +option(DISK_CACHE "Enable SD card disk cache" ON) +option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON) option(PXX1 "PXX1 protocol support" ON) option(PXX2 "PXX2 protocol support" OFF) @@ -28,6 +28,7 @@ endif() if (PCB STREQUAL X10) set(FLAVOUR x10) + set(PCBREV "STD" CACHE STRING "PCB Revision") add_definitions(-DPCBX10) add_definitions(-DSOFTWARE_VOLUME) set(TARGET_SRC @@ -40,6 +41,13 @@ if (PCB STREQUAL X10) set(FONTS_TARGET x10_fonts) set(LCD_DRIVER lcd_driver.cpp) set(LUA_EXPORT lua_export_x10) + if (PCBREV STREQUAL EXPRESS) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) + else() + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) + endif() elseif (PCB STREQUAL X12S) set(FLAVOUR x12s) set(PCBREV "13" CACHE STRING "PCB Revision") @@ -59,14 +67,16 @@ elseif (PCB STREQUAL X12S) adc_driver.cpp gps_driver.cpp ) - + set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) set(BITMAPS_TARGET x12s_bitmaps) set(FONTS_TARGET x12s_fonts) set(LCD_DRIVER lcd_driver.cpp) set(LUA_EXPORT lua_export_x12s) - add_definitions(-DPCBREV=${PCBREV}) endif() +add_definitions(-DPCBREV=${PCBREV}) +add_definitions(-DPCBREV_${PCBREV}) + set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${BITMAPS_TARGET}) add_definitions(-DPCBHORUS -DSTM32F429_439xx -DSDRAM -DCOLORLCD) @@ -120,8 +130,6 @@ if(INTERNAL_GPS) message("Horus: Internal GPS enabled") endif() -set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) - set(GVAR_SCREEN model_gvars.cpp) set(TARGET_SRC @@ -171,3 +179,11 @@ if(PYTHONINTERP_FOUND) DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py ) endif() + +if(INTERNAL_MODULE_PXX1) + add_definitions(-DINTERNAL_MODULE_PXX1) +endif() + +if(INTERNAL_MODULE_PXX2) + add_definitions(-DINTERNAL_MODULE_PXX2) +endif() \ No newline at end of file diff --git a/radio/src/targets/horus/adc_driver.cpp b/radio/src/targets/horus/adc_driver.cpp index 23c0becd8..932f752a0 100644 --- a/radio/src/targets/horus/adc_driver.cpp +++ b/radio/src/targets/horus/adc_driver.cpp @@ -139,7 +139,7 @@ void adcInit() uint16_t getRTCBatteryVoltage() { - return rtcBatteryVoltage * 330 / 2048; + return (rtcBatteryVoltage * ADC_VREF_PREC2) / 2048; } const uint16_t adcCommands[MOUSE1+2] = diff --git a/radio/src/targets/horus/backlight_driver.cpp b/radio/src/targets/horus/backlight_driver.cpp index 05026acf1..e141cf5dd 100644 --- a/radio/src/targets/horus/backlight_driver.cpp +++ b/radio/src/targets/horus/backlight_driver.cpp @@ -33,26 +33,23 @@ void backlightInit() GPIO_PinAFConfig(BACKLIGHT_GPIO, BACKLIGHT_GPIO_PinSource, BACKLIGHT_GPIO_AF); // TIMER init -#if defined(PCBX12S) - if (IS_HORUS_PROD()) { - BACKLIGHT_TIMER->ARR = 100; - BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz - BACKLIGHT_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; // PWM - BACKLIGHT_TIMER->CCER = TIM_CCER_CC4E; - BACKLIGHT_TIMER->CCR4 = 0; - BACKLIGHT_TIMER->EGR = 0; - BACKLIGHT_TIMER->CR1 = TIM_CR1_CEN; // Counter enable - } - else { - BACKLIGHT_TIMER->ARR = 100; - BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz - BACKLIGHT_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM - BACKLIGHT_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; - BACKLIGHT_TIMER->CCR1 = 100; - BACKLIGHT_TIMER->EGR = 1; - BACKLIGHT_TIMER->CR1 |= TIM_CR1_CEN; // Counter enable - BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE; - } +#if defined(PCBX12S) && PCBREV >= 13 + BACKLIGHT_TIMER->ARR = 100; + BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz + BACKLIGHT_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; // PWM + BACKLIGHT_TIMER->CCER = TIM_CCER_CC4E; + BACKLIGHT_TIMER->CCR4 = 0; + BACKLIGHT_TIMER->EGR = 0; + BACKLIGHT_TIMER->CR1 = TIM_CR1_CEN; // Counter enable +#elif defined(PCBX12S) + BACKLIGHT_TIMER->ARR = 100; + BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz + BACKLIGHT_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM + BACKLIGHT_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; + BACKLIGHT_TIMER->CCR1 = 100; + BACKLIGHT_TIMER->EGR = 1; + BACKLIGHT_TIMER->CR1 |= TIM_CR1_CEN; // Counter enable + BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE; #elif defined(PCBX10) BACKLIGHT_TIMER->ARR = 100; BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 1000000 - 1; // 10kHz (same as FrOS) @@ -67,13 +64,10 @@ void backlightInit() void backlightEnable(uint8_t dutyCycle) { -#if defined(PCBX12S) - if (IS_HORUS_PROD()) { - BACKLIGHT_TIMER->CCR4 = dutyCycle; - } - else { - BACKLIGHT_TIMER->CCR1 = BACKLIGHT_LEVEL_MAX - dutyCycle; - } +#if defined(PCBX12S) && PCBREV >= 13 + BACKLIGHT_TIMER->CCR4 = dutyCycle; +#elif defined(PCBX12S) + BACKLIGHT_TIMER->CCR1 = BACKLIGHT_LEVEL_MAX - dutyCycle; #elif defined(PCBX10) BACKLIGHT_TIMER->CCR3 = BACKLIGHT_LEVEL_MAX - dutyCycle; #endif diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index b8ca84225..0da73628c 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -18,14 +18,22 @@ * GNU General Public License for more details. */ -#ifndef _BOARD_HORUS_H_ -#define _BOARD_HORUS_H_ +#ifndef _BOARD_H_ +#define _BOARD_H_ #include "../definitions.h" #include "../opentx_constants.h" #include "board_common.h" #include "hal.h" +PACK(typedef struct { + uint8_t pcbrev : 2; + uint8_t sticksPwmDisabled : 1; + uint8_t pxx2Enabled : 1; +}) HardwareOptions; + +extern HardwareOptions hardwareOptions; + #if !defined(LUA_EXPORT_GENERATION) #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h" @@ -58,21 +66,38 @@ extern uint16_t sessionTimer; #endif // Board driver -void boardInit(void); -void boardOff(void); +void boardInit(); +void boardOff(); // Timers driver void init2MhzTimer(); void init5msTimer(); // PCBREV driver -#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) -#if defined(SIMU) || defined(PCBX10) +enum { + // X12S + PCBREV_X12S_LT13 = 0, + PCBREV_X12S_GTE13 = 1, + + // X10 + PCBREV_X10_STD = 0, + PCBREV_X10_EXPRESS = 3, +}; + +#if defined(SIMU) #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true -#elif PCBREV >= 13 - #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD() +#elif defined(PCBX10) + #if defined(PCBREV_EXPRESS) + #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (hardwareOptions.pcbrev == PCBREV_X10_EXPRESS) + #else + #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (hardwareOptions.pcbrev == PCBREV_X10_STD) + #endif #else - #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD()) + #if PCBREV >= 13 + #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (hardwareOptions.pcbrev == PCBREV_X12S_GTE13) + #else + #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (hardwareOptions.pcbrev == PCBREV_X12S_LT13) + #endif #endif // SD driver @@ -88,7 +113,7 @@ void sdInit(void); void sdMount(void); void sdDone(void); #define sdPoll10ms() -uint32_t sdMounted(void); +uint32_t sdMounted(); #else #define SD_IS_HC() (0) #define SD_GET_SPEED() (0) @@ -131,7 +156,6 @@ void SDRAM_Init(void); #define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) -#define INTERNAL_MODULE_PXX1 #if !defined(PXX2) #define IS_PXX2_INTERNAL_ENABLED() (false) @@ -156,6 +180,7 @@ void intmoduleSendNextFrame(); void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted); void extmoduleInvertedSerialStart(uint32_t baudrate); +void extmoduleSendBuffer(const uint8_t * data, uint8_t size); void extmoduleSendNextFrame(); // Trainer driver @@ -553,6 +578,7 @@ void gpsSendByte(uint8_t byte); #endif // Second serial port driver +#if defined(PCBX12S) #define AUX_SERIAL #define DEBUG_BAUDRATE 115200 extern uint8_t auxSerialMode; @@ -561,6 +587,7 @@ void auxSerialPutc(char c); #define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) void auxSerialSbusInit(void); void auxSerialStop(void); +#endif #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) // BT driver @@ -581,17 +608,4 @@ extern DMAFifo<512> telemetryFifo; extern DMAFifo<32> auxSerialRxFifo; #endif -#if NUM_PWMSTICKS > 0 -PACK(typedef struct { - uint8_t sticksPwmDisabled : 1; - uint8_t pxx2Enabled : 1; -}) HardwareOptions; -#else -PACK(typedef struct { - uint8_t pxx2Enabled : 1; -}) HardwareOptions; -#endif - -extern HardwareOptions hardwareOptions; - -#endif // _BOARD_HORUS_H_ +#endif // _BOARD_H_ diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index f7cd5b92b..99c5f811f 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -24,10 +24,10 @@ void extmoduleStop() { EXTERNAL_MODULE_OFF(); - NVIC_DisableIRQ(EXTMODULE_DMA_IRQn); - NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn); + NVIC_DisableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); + NVIC_DisableIRQ(EXTMODULE_TIMER_CC_IRQn); - EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_TIMER->DIER &= ~(TIM_DIER_CC2IE | TIM_DIER_UDE); EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; @@ -44,7 +44,7 @@ void extmodulePpmStart() { EXTERNAL_MODULE_ON(); - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TX_GPIO_AF); + GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TIMER_TX_GPIO_AF); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; @@ -68,34 +68,40 @@ void extmodulePpmStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = 45000; + #if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1 + EXTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); + EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Force O/P high EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; EXTMODULE_TIMER->EGR = 1; // Reloads register values now - EXTMODULE_TIMER->DIER = TIM_DIER_UDE; // Update DMA request - EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer + EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1 #else EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Reloads register values now - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Update DMA request EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1 - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; // Start timer #endif - NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); - NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); - NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); + EXTMODULE_TIMER->ARR = 45000; + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; // Enable this interrupt + EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer + + NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); + NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); } +#if defined(PXX1) void extmodulePxx1PulsesStart() { EXTERNAL_MODULE_ON(); - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TX_GPIO_AF); + GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TIMER_TX_GPIO_AF); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; @@ -107,47 +113,41 @@ void extmodulePxx1PulsesStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = 18000; - + #if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3NE; - EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR3 = 18; + EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3NE; EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high - EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update - EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; -#else - EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP; // TIM_CCER_CC1E | TIM_CCER_CC1P; EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs - EXTMODULE_TIMER->CCR1 = 18; - EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update + EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; +#else + EXTMODULE_TIMER->CCR1 = 18; + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP; // TIM_CCER_CC1E | TIM_CCER_CC1P; + EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high + EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs + EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; #endif - NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); - NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); - NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); + EXTMODULE_TIMER->ARR = 45000; + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; // Enable DMA on update + EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; + + NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); + NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); } +#endif -void extmoduleInvertedSerialStart(uint32_t baudrate) -{ - EXTERNAL_MODULE_ON(); - - // TODO -} - -#if defined(DSM2) void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool inverted) { EXTERNAL_MODULE_ON(); - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TX_GPIO_AF); + GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_TIMER_TX_GPIO_AF); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; @@ -159,41 +159,78 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool i EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = period_half_us; - + #if defined(PCBX10) || PCBREV >= 13 EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P; EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR3 = 0; EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; #else EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 0; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; #endif - NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); - NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); - NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); + EXTMODULE_TIMER->ARR = 45000; + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; + EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; + + NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); + NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); + NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); } -#endif #if defined(EXTMODULE_USART) +ModuleFifo extmoduleFifo; + +void extmoduleInvertedSerialStart(uint32_t baudrate) +{ + EXTERNAL_MODULE_ON(); + + // TX + RX Pins + GPIO_PinAFConfig(EXTMODULE_USART_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_USART_GPIO_AF); + GPIO_PinAFConfig(EXTMODULE_USART_GPIO, EXTMODULE_RX_GPIO_PinSource, EXTMODULE_USART_GPIO_AF); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN | EXTMODULE_RX_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(EXTMODULE_USART_GPIO, &GPIO_InitStructure); + + // UART config + USART_DeInit(EXTMODULE_USART); + USART_InitTypeDef USART_InitStructure; + USART_InitStructure.USART_BaudRate = baudrate; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(EXTMODULE_USART, &USART_InitStructure); + USART_Cmd(EXTMODULE_USART, ENABLE); + + extmoduleFifo.clear(); + + USART_ITConfig(EXTMODULE_USART, USART_IT_RXNE, ENABLE); + NVIC_SetPriority(EXTMODULE_USART_IRQn, 6); + NVIC_EnableIRQ(EXTMODULE_USART_IRQn); +} + void extmoduleSendBuffer(const uint8_t * data, uint8_t size) { DMA_InitTypeDef DMA_InitStructure; - DMA_DeInit(EXTMODULE_DMA_STREAM); - DMA_InitStructure.DMA_Channel = EXTMODULE_DMA_CHANNEL; + DMA_DeInit(EXTMODULE_USART_TX_DMA_STREAM); + DMA_InitStructure.DMA_Channel = EXTMODULE_USART_TX_DMA_CHANNEL; DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR); DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(data); @@ -208,78 +245,117 @@ void extmoduleSendBuffer(const uint8_t * data, uint8_t size) DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(EXTMODULE_DMA_STREAM, &DMA_InitStructure); - DMA_Cmd(EXTMODULE_DMA_STREAM, ENABLE); + DMA_Init(EXTMODULE_USART_TX_DMA_STREAM, &DMA_InitStructure); + DMA_Cmd(EXTMODULE_USART_TX_DMA_STREAM, ENABLE); USART_DMACmd(EXTMODULE_USART, USART_DMAReq_Tx, ENABLE); } + +#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +extern "C" void EXTMODULE_USART_IRQHandler(void) +{ + uint32_t status = EXTMODULE_USART->SR; + + while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { + uint8_t data = EXTMODULE_USART->DR; + if (status & USART_FLAG_ERRORS) { + extmoduleFifo.errors++; + } + else { + extmoduleFifo.push(data); + } + status = EXTMODULE_USART->SR; + } +} #endif void extmoduleSendNextFrame() { - if (moduleState[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PPM) { + switch (moduleState[EXTERNAL_MODULE].protocol) { + case PROTOCOL_CHANNELS_PPM: #if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); - EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance - EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; #else - EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); - EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance - EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; #endif - EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses); - EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.ppm.ptr - extmodulePulsesData.ppm.pulses; - EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.ppm.ptr - extmodulePulsesData.ppm.pulses; + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; + #if defined(PXX1) - else if (moduleState[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PXX1_PULSES) { - EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance - EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA -#if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; -#else - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + case PROTOCOL_CHANNELS_PXX1_PULSES: + EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize(); + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; #endif - EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); - EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize(); - EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } + +#if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + extmoduleSendBuffer(extmodulePulsesData.pxx_uart.getData(), extmodulePulsesData.pxx_uart.getSize()); + break; #endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: + case PROTOCOL_CHANNELS_PXX2_LOWSPEED: + extmoduleSendBuffer(extmodulePulsesData.pxx2.getData(), extmodulePulsesData.pxx2.getSize()); + break; +#endif + #if defined(DSM2) - else if (IS_DSM2_PROTOCOL(moduleState[EXTERNAL_MODULE].protocol) || IS_MULTIMODULE_PROTOCOL(moduleState[EXTERNAL_MODULE].protocol) || IS_SBUS_PROTOCOL(moduleState[EXTERNAL_MODULE].protocol)) { - EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance - EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + case PROTOCOL_CHANNELS_SBUS: #if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - if (IS_SBUS_PROTOCOL(moduleState[EXTERNAL_MODULE].protocol)) EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed #else - EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - if (IS_SBUS_PROTOCOL(moduleState[EXTERNAL_MODULE].protocol)) EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed #endif - EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); - EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses; - EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } + // no break + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: + case PROTOCOL_CHANNELS_MULTIMODULE: + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | EXTMODULE_TIMER_DMA_SIZE | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses; + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; #endif - else { - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + +#if defined(CROSSFIRE) + case PROTOCOL_CHANNELS_CROSSFIRE: + sportSendBuffer(extmodulePulsesData.crossfire.pulses, extmodulePulsesData.crossfire.length); + break; +#endif + + default: + EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + break; } } -extern "C" void EXTMODULE_DMA_IRQHandler() +extern "C" void EXTMODULE_TIMER_DMA_IRQHandler() { - if (!DMA_GetITStatus(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC)) + if (!DMA_GetITStatus(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC)) return; - DMA_ClearITPendingBit(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC); + DMA_ClearITPendingBit(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC); EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 3bc7abad3..640214cd3 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -301,9 +301,17 @@ #endif // PCBREV +#if defined(PCBX10) +#define PCBREV_RCC_AHB1Periph RCC_AHB1Periph_GPIOH +#define PCBREV_GPIO_PIN (GPIO_Pin_7 | GPIO_Pin_8) +#define PCBREV_GPIO GPIOH +#define PCBREV_VALUE() (GPIO_ReadInputDataBit(PCBREV_GPIO, GPIO_Pin_7) + (GPIO_ReadInputDataBit(PCBREV_GPIO, GPIO_Pin_8) << 1)) +#else #define PCBREV_RCC_AHB1Periph RCC_AHB1Periph_GPIOI #define PCBREV_GPIO GPIOI #define PCBREV_GPIO_PIN GPIO_Pin_11 // PI.11 +#define PCBREV_VALUE() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) +#endif // Led #define STATUS_LEDS @@ -321,6 +329,7 @@ #endif // Serial Port (DEBUG) +#if defined(PCBX12S) #define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3 #define AUX_SERIAL_GPIO GPIOB @@ -334,6 +343,10 @@ #define AUX_SERIAL_USART_IRQn USART3_IRQn #define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1 #define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4 +#else +#define AUX_SERIAL_RCC_AHB1Periph 0 +#define AUX_SERIAL_RCC_APB1Periph 0 +#endif // Telemetry #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) @@ -591,42 +604,75 @@ #endif // External Module -#define EXTMODULE_PWR_GPIO GPIOB -#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03 -#if defined(PCBX10) || PCBREV >= 13 - #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) - #define EXTMODULE_RCC_APB1Periph 0 - #define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1 - #define EXTMODULE_TX_GPIO GPIOA - #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PA.10 - #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10 - #define EXTMODULE_TX_GPIO_AF GPIO_AF_TIM1 - #define EXTMODULE_TIMER TIM1 - #define EXTMODULE_TIMER_IRQn TIM1_CC_IRQn - #define EXTMODULE_TIMER_IRQHandler TIM1_CC_IRQHandler - #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) - #define EXTMODULE_DMA_CHANNEL DMA_Channel_6 - #define EXTMODULE_DMA_STREAM DMA2_Stream5 - #define EXTMODULE_DMA_IRQn DMA2_Stream5_IRQn - #define EXTMODULE_DMA_IRQHandler DMA2_Stream5_IRQHandler - #define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF5 +#define EXTMODULE_PWR_GPIO GPIOB +#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03 +#if defined(PCBX10) && defined(PCBREV_EXPRESS) + #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) + #define EXTMODULE_RCC_APB1Periph (RCC_APB1Periph_TIM2 | RCC_APB1Periph_USART3) + #define EXTMODULE_RCC_APB2Periph 0 + #define EXTMODULE_TX_GPIO GPIOB + #define EXTMODULE_USART_GPIO EXTMODULE_TX_GPIO + #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PB.10 (TIM2_CH3) + #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10 + #define EXTMODULE_RX_GPIO_PIN GPIO_Pin_11 // PB.11 + #define EXTMODULE_RX_GPIO_PinSource GPIO_PinSource11 + #define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM2 + #define EXTMODULE_TIMER TIM2 + #define EXTMODULE_TIMER_32BITS + #define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1) + #define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + #define EXTMODULE_TIMER_CC_IRQn TIM2_IRQn + #define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler + #define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_3 + #define EXTMODULE_TIMER_DMA_STREAM DMA1_Stream1 + #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1 + #define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA1_Stream1_IRQn + #define EXTMODULE_TIMER_DMA_IRQHandler DMA1_Stream1_IRQHandler + #define EXTMODULE_USART_GPIO_AF GPIO_AF_USART3 + #define EXTMODULE_USART USART3 + #define EXTMODULE_USART_IRQn USART3_IRQn + #define EXTMODULE_USART_IRQHandler USART3_IRQHandler + #define EXTMODULE_USART_TX_DMA_CHANNEL DMA_Channel_4 + #define EXTMODULE_USART_TX_DMA_STREAM DMA1_Stream3 + #define EXTMODULE_USART_RX_DMA_CHANNEL DMA_Channel_4 + #define EXTMODULE_USART_RX_DMA_STREAM DMA1_Stream1 +#elif defined(PCBX10) || PCBREV >= 13 + #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) + #define EXTMODULE_RCC_APB1Periph 0 + #define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1 + #define EXTMODULE_TX_GPIO GPIOA + #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PA.10 (TIM1_CH3) + #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10 + #define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM1 + #define EXTMODULE_TIMER TIM1 + #define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0) + #define EXTMODULE_TIMER_CC_IRQn TIM1_CC_IRQn + #define EXTMODULE_TIMER_IRQHandler TIM1_CC_IRQHandler + #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) + #define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_6 + #define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream5 + #define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream5_IRQn + #define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream5_IRQHandler + #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF5 #else - #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) - #define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 - #define EXTMODULE_RCC_APB2Periph 0 - #define EXTMODULE_TX_GPIO GPIOA - #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_15 // PA.15 - #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource15 - #define EXTMODULE_TX_GPIO_AF GPIO_AF_TIM2 - #define EXTMODULE_TIMER TIM2 - #define EXTMODULE_TIMER_IRQn TIM2_IRQn - #define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler - #define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) - #define EXTMODULE_DMA_CHANNEL DMA_Channel_3 - #define EXTMODULE_DMA_STREAM DMA1_Stream7 - #define EXTMODULE_DMA_IRQn DMA1_Stream7_IRQn - #define EXTMODULE_DMA_IRQHandler DMA1_Stream7_IRQHandler - #define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF7 + #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) + #define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 + #define EXTMODULE_RCC_APB2Periph 0 + #define EXTMODULE_TX_GPIO GPIOA + #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_15 // PA.15 (TIM2_CH1) + #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource15 + #define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM2 + #define EXTMODULE_TIMER TIM2 + #define EXTMODULE_TIMER_32BITS + #define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1) + #define EXTMODULE_TIMER_CC_IRQn TIM2_IRQn + #define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler + #define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + #define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_3 + #define EXTMODULE_TIMER_DMA_STREAM DMA1_Stream7 + #define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA1_Stream7_IRQn + #define EXTMODULE_TIMER_DMA_IRQHandler DMA1_Stream7_IRQHandler + #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF7 #endif // Heartbeat diff --git a/radio/src/targets/horus/pwr_driver.cpp b/radio/src/targets/horus/pwr_driver.cpp index b8b820109..d007de8e6 100644 --- a/radio/src/targets/horus/pwr_driver.cpp +++ b/radio/src/targets/horus/pwr_driver.cpp @@ -53,10 +53,15 @@ void pwrInit() GPIO_Init(PWR_SWITCH_GPIO, &GPIO_InitStructure); // PCBREV - // TODO to be removed on X10? +#if defined(PCBX10) + GPIO_InitStructure.GPIO_Pin = PCBREV_GPIO_PIN; + GPIO_Init(PCBREV_GPIO, &GPIO_InitStructure); + hardwareOptions.pcbrev = PCBREV_VALUE(); +#else GPIO_ResetBits(PCBREV_GPIO, PCBREV_GPIO_PIN); GPIO_InitStructure.GPIO_Pin = PCBREV_GPIO_PIN; GPIO_Init(PCBREV_GPIO, &GPIO_InitStructure); +#endif // SD-DETECT PIN GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN); diff --git a/radio/src/targets/taranis/extmodule_driver.cpp b/radio/src/targets/taranis/extmodule_driver.cpp index 3876537dd..d9ed8feaa 100644 --- a/radio/src/targets/taranis/extmodule_driver.cpp +++ b/radio/src/targets/taranis/extmodule_driver.cpp @@ -64,17 +64,16 @@ void extmodulePpmStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = 45000; EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1 EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->ARR = 45000; EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); @@ -99,17 +98,16 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool i EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = period_half_us; EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (inverted ? 0 : EXTMODULE_TIMER_OUTPUT_POLARITY); EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 0; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; - EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->ARR = 45000; EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); @@ -215,17 +213,16 @@ void extmodulePxx1PulsesStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = PXX_PULSES_PERIOD * 2000; // 0.5uS (2Mhz) EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; // polarity, default low EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 18; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; - EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->ARR = 45000; EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->DIER |= TIM_DIER_UDE | TIM_DIER_CC2IE; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); @@ -244,7 +241,7 @@ void extmodulePxx1SerialStart() void extmoduleSendNextFrame() { - switch(moduleState[EXTERNAL_MODULE].protocol) { + switch (moduleState[EXTERNAL_MODULE].protocol) { case PROTOCOL_CHANNELS_PPM: EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE) * 2; EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 17400df49..872758f9a 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -703,7 +703,7 @@ #define ADC_EXT_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_EXT_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) #define ADC_EXT_SAMPTIME 3 // sample time = 56 cycles - #define ADC_VREF_PREC2 330 + #define ADC_VREF_PREC2 200 #elif defined(PCBX9DP) #define HARDWARE_POT1 #define HARDWARE_POT2 @@ -907,7 +907,9 @@ #if !defined(RADIO_T12) #define HARDWARE_INTERNAL_MODULE #endif -#if !defined(PCBXLITES) && !defined(PCBX9LITE) && !(defined(PCBX9DP) && PCBREV >= 2019) +#if defined(PCBXLITES) || defined(PCBX9LITE) || (defined(PCBX9DP) && PCBREV >= 2019) + #define INTERNAL_MODULE_PXX2 +#else #define INTERNAL_MODULE_PXX1 #endif #define INTMODULE_FLASH_BAUDRATE 57600 @@ -1046,7 +1048,7 @@ #define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) #define EXTMODULE_TX_GPIO GPIOC - #define EXTMODULE_USART_GPIO GPIOC + #define EXTMODULE_USART_GPIO EXTMODULE_TX_GPIO #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_6 // PC.06 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource6 #define EXTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PC.07