1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-23 16:25:12 +03:00

Merge pull request #6620 from opentx/bsongis/X10_pulses_fix

[X10] Pulses fix
This commit is contained in:
Bertrand Songis 2019-08-14 17:30:37 +02:00 committed by GitHub
commit 21ad592585
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 880 additions and 285 deletions

View file

@ -1077,7 +1077,7 @@ void menuModelSetup(event_t event)
break; break;
case 1: case 1:
CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(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); SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
} }
break; break;

View file

@ -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 #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)) if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE))
return 1; return 1;
#if defined(MULTIMODULE) #if defined(MULTIMODULE)
else if (isModuleMultimodule(EXTERNAL_MODULE)) { else if (isModuleMultimodule(EXTERNAL_MODULE)) {
return 2 + MULTIMODULE_RFPROTO_ROWS(EXTERNAL_MODULE); return 2 + MULTIMODULE_RFPROTO_COLUMNS(EXTERNAL_MODULE);
} }
#endif #endif
else else
@ -362,7 +363,7 @@ void menuModelSetup(event_t event)
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3 IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3
LABEL(ExternalModule), LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROWS(), EXTERNAL_MODULE_MODE_ROW(),
MULTIMODULE_STATUS_ROWS MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS, EXTERNAL_MODULE_CHANNELS_ROWS,
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_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) #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); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(INTERNAL_MODULE)) 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)) 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 (attr) {
if (menuHorizontalPosition == 0) { if (menuHorizontalPosition == 0) {
uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); 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)) { 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) { if (checkIncDec_Ret) {
g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1; g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1;
g_model.moduleData[0].channelsStart = 0; g_model.moduleData[0].channelsStart = 0;
@ -777,7 +778,7 @@ void menuModelSetup(event_t event)
} }
} }
else if (isModulePXX2(INTERNAL_MODULE)) { 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 #else
@ -1038,16 +1039,10 @@ void menuModelSetup(event_t event)
CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount);
break; break;
case 1: case 1:
CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart)); CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr);
#if defined(INTERNAL_MODULE_PPM) if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_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)) {
SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); 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; break;
} }
} }

View file

@ -8,6 +8,8 @@ set(GUI_SRC
menu_model.cpp menu_model.cpp
model_select.cpp model_select.cpp
model_setup.cpp model_setup.cpp
model_module_options.cpp
model_receiver_options.cpp
model_failsafe.cpp model_failsafe.cpp
model_logical_switches.cpp model_logical_switches.cpp
model_special_functions.cpp model_special_functions.cpp

View file

@ -179,6 +179,8 @@ bool menuModelCustomScripts(event_t event);
bool menuModelTelemetryFrsky(event_t event); bool menuModelTelemetryFrsky(event_t event);
bool menuModelSensor(event_t event); bool menuModelSensor(event_t event);
bool menuModelExpoOne(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]; extern const MenuHandlerFunc menuTabModel[MENU_MODEL_PAGES_COUNT];

View file

@ -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 <opentx.h>
#include <math.h>
#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; k<NUM_BODY_LINES + 1/*plus one line in submenus*/; k++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH;
uint8_t i = k + menuVerticalOffset;
for (int j=0; j<=i; ++j) {
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
++i;
}
}
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (i) {
case 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;
}

View file

@ -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<uint8_t>(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; k<NUM_BODY_LINES + 1/*plus one line in submenus*/; k++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH;
uint8_t i = k + menuVerticalOffset;
for (int j=0; j<=i; ++j) {
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
++i;
}
}
LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
switch (i) {
case 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<uint8_t>(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;
}

View file

@ -84,18 +84,25 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL, ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE, ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
#if defined(MULTIMODULE) #if defined(MULTIMODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS,
#endif #endif
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND, 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, ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
#if defined(MULTIMODULE) #if defined(MULTIMODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND, ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND,
#endif #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_LABEL,
ITEM_MODEL_SETUP_TRAINER_MODE, ITEM_MODEL_SETUP_TRAINER_MODE,
#if defined(BLUETOOTH) #if defined(BLUETOOTH)
@ -202,12 +209,13 @@ void onPXX2ReceiverMenu(const char * result)
memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings));
reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx; reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx;
g_moduleIdx = moduleIdx; g_moduleIdx = moduleIdx;
// TODO pushMenu(menuModelReceiverOptions); pushMenu(menuModelReceiverOptions);
} }
else if (result == STR_BIND) { else if (result == STR_BIND) {
memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation)); memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation));
reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx; reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx;
if (isModuleR9MAccess(moduleIdx)) { if (isModuleR9MAccess(moduleIdx)) {
reusableBuffer.moduleSetup.bindInformation.step = BIND_MODULE_TX_INFORMATION_REQUEST;
#if defined(SIMU) #if defined(SIMU)
reusableBuffer.moduleSetup.pxx2.moduleInformation.information.modelID = 1; reusableBuffer.moduleSetup.pxx2.moduleInformation.information.modelID = 1;
reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant = 2; 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_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)) #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 #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 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 #if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS(0) #define TIMERS_ROWS TIMER_ROWS(0)
@ -595,14 +610,20 @@ bool menuModelSetup(event_t event)
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */ IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */
LABEL(ExternalModule), LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROWS, EXTERNAL_MODULE_MODE_ROW(),
EXTERNAL_MODULE_POWER_ROW,
MULTIMODULE_STATUS_ROWS MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS, EXTERNAL_MODULE_CHANNELS_ROWS,
EXTERNAL_MODULE_BIND_ROWS, IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS),
FAILSAFE_ROWS(EXTERNAL_MODULE), IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum for ACCESS
EXTERNAL_MODULE_OPTION_ROW, IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW),
MULTIMODULE_MODULE_ROWS 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 TRAINER_ROWS
}); });
@ -964,9 +985,9 @@ bool menuModelSetup(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODE); 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); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(INTERNAL_MODULE)) 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)) 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 (attr) {
if (menuHorizontalPosition == 0) { if (menuHorizontalPosition == 0) {
uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); 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)) { 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) { if (checkIncDec_Ret) {
g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1; g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1;
g_model.moduleData[0].channelsStart = 0; g_model.moduleData[0].channelsStart = 0;
@ -1136,7 +1157,7 @@ bool menuModelSetup(event_t event)
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
ModuleData & moduleData = g_model.moduleData[moduleIdx]; ModuleData & moduleData = g_model.moduleData[moduleIdx];
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CHANNELRANGE); 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); drawStringWithIndex(MODEL_SETUP_2ND_COLUMN, y, STR_CH, moduleData.channelsStart+1, menuHorizontalPosition==0 ? attr : 0);
lcdDrawText(lcdNextPos+5, y, "-"); lcdDrawText(lcdNextPos+5, y, "-");
drawStringWithIndex(lcdNextPos+5, y, STR_CH, moduleData.channelsStart+sentModuleChannels(moduleIdx), menuHorizontalPosition==1 ? attr : 0); 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); CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount);
break; break;
case 1: case 1:
CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min<int8_t>(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart)); CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min<int8_t>(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); SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
}
break; break;
} }
} }
@ -1305,12 +1327,12 @@ bool menuModelSetup(event_t event)
break; break;
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS: 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); lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_OPTIONS);
drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr);
if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) {
g_moduleIdx = CURRENT_MODULE_EDITED(k); g_moduleIdx = CURRENT_MODULE_EDITED(k);
memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); pushMenu(menuModelModuleOptions);
// TODO pushMenu(menuModelModuleOptions);
} }
break; break;

View file

@ -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 }); 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); 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; i<NUM_BODY_LINES+1; i++) { for (uint8_t i=0; i<NUM_BODY_LINES + 1/*plus one line in submenus*/; i++) {
coord_t y = MENU_CONTENT_TOP - FH - 2 + i*FH; coord_t y = MENU_CONTENT_TOP - FH - 2 + i*FH;
int k = i + menuVerticalOffset; int k = i + menuVerticalOffset;

View file

@ -161,7 +161,7 @@ void menuModelModuleOptions(event_t event)
switch (i) { switch (i) {
case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA:
reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, "Ext. antenna", attr, event); reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, STR_EXT_ANTENNA, attr, event);
if (attr && checkIncDec_Ret) { if (attr && checkIncDec_Ret) {
reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY; reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY;
} }

View file

@ -565,25 +565,23 @@ bool isInternalModuleAvailable(int moduleType)
if (moduleType == MODULE_TYPE_NONE) if (moduleType == MODULE_TYPE_NONE)
return true; return true;
#if defined(PXX2) && defined(INTERNAL_MODULE_PXX1) if (moduleType == MODULE_TYPE_XJT_PXX1) {
if (moduleType == MODULE_TYPE_XJT_PXX1) #if defined(PXX1) && defined(INTERNAL_MODULE_PXX1)
return !isModuleUsingSport(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type); return !isModuleUsingSport(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type);
#elif defined(PXX1)
if (moduleType == MODULE_TYPE_XJT_PXX1)
return !isModuleUsingSport(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type);
#else
if (moduleType == MODULE_TYPE_XJT_PXX1)
return false;
#endif #endif
}
#if defined(PXX2) && !defined(INTERNAL_MODULE_PXX1) if (moduleType == MODULE_TYPE_ISRM_PXX2) {
if (moduleType == MODULE_TYPE_ISRM_PXX2) #if defined(PXX2) && defined(INTERNAL_MODULE_PXX2)
#if defined(INTMODULE_USART)
return true; return true;
#else
return (!isModuleUsingSport(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type));
#endif #endif
}
if (moduleType == MODULE_TYPE_PPM) {
#if defined(PPM) && defined(INTERNAL_MODULE_PPM)
return true;
#endif #endif
}
return false; return false;
} }

View file

@ -61,7 +61,7 @@ bool isSwitchAvailableInTimers(int swtch);
bool isR9MModeAvailable(int mode); bool isR9MModeAvailable(int mode);
bool isPxx2IsrmChannelsCountAllowed(int channels); bool isPxx2IsrmChannelsCountAllowed(int channels);
bool isExternalModuleAvailable(int moduleType); bool isExternalModuleAvailable(int moduleType);
bool isInternalModuleAvailable(int module); bool isInternalModuleAvailable(int moduleType);
bool isRfProtocolAvailable(int protocol); bool isRfProtocolAvailable(int protocol);
bool isTelemetryProtocolAvailable(int protocol); bool isTelemetryProtocolAvailable(int protocol);
bool isTrainerModeAvailable(int mode); bool isTrainerModeAvailable(int mode);
@ -141,11 +141,11 @@ inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx)
{ {
return getMultiProtocolDefinition(moduleIdx)->maxSubtype > 0; return getMultiProtocolDefinition(moduleIdx)->maxSubtype > 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); 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_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 #define MULTIMODULE_OPTIONS_ROW (isModuleMultimodule(EXTERNAL_MODULE) && MULTIMODULE_HASOPTIONS(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW

View file

@ -61,27 +61,32 @@ uint8_t getRequiredProtocol(uint8_t module)
break; break;
} }
#endif #endif
// no break protocol = PROTOCOL_CHANNELS_PXX1_PULSES;
break;
case MODULE_TYPE_R9M_PXX1: case MODULE_TYPE_R9M_PXX1:
protocol = PROTOCOL_CHANNELS_PXX1_PULSES; protocol = PROTOCOL_CHANNELS_PXX1_PULSES;
break; break;
#if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
case MODULE_TYPE_R9M_LITE_PXX1: case MODULE_TYPE_R9M_LITE_PXX1:
case MODULE_TYPE_R9M_LITE_PRO_PXX1: case MODULE_TYPE_R9M_LITE_PRO_PXX1:
protocol = PROTOCOL_CHANNELS_PXX1_SERIAL; protocol = PROTOCOL_CHANNELS_PXX1_SERIAL;
break; 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: case MODULE_TYPE_R9M_LITE_PXX2:
protocol = PROTOCOL_CHANNELS_PXX2_LOWSPEED; protocol = PROTOCOL_CHANNELS_PXX2_LOWSPEED;
break; 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: case MODULE_TYPE_SBUS:
protocol = PROTOCOL_CHANNELS_SBUS; protocol = PROTOCOL_CHANNELS_SBUS;
@ -149,7 +154,7 @@ void enablePulsesExternalModule(uint8_t protocol)
break; break;
#endif #endif
#if defined(PXX1) && defined(EXTMODULE_USART) #if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
case PROTOCOL_CHANNELS_PXX1_SERIAL: case PROTOCOL_CHANNELS_PXX1_SERIAL:
extmodulePxx1SerialStart(); extmodulePxx1SerialStart();
break; break;
@ -212,7 +217,7 @@ void setupPulsesExternalModule(uint8_t protocol)
break; break;
#endif #endif
#if defined(PXX1) && defined(EXTMODULE_USART) #if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
case PROTOCOL_CHANNELS_PXX1_SERIAL: case PROTOCOL_CHANNELS_PXX1_SERIAL:
extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE); extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE);
scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD); scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD);

View file

@ -281,7 +281,7 @@ union InternalModulePulsesData {
union ExternalModulePulsesData { union ExternalModulePulsesData {
#if defined(PXX1) #if defined(PXX1)
#if defined(EXTMODULE_USART) #if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
UartPxx1Pulses pxx_uart; UartPxx1Pulses pxx_uart;
#endif #endif
#if defined(PPM_PIN_SERIAL) #if defined(PPM_PIN_SERIAL)

View file

@ -23,14 +23,14 @@
#include <inttypes.h> #include <inttypes.h>
#if defined(PCBX12S) && PCBREV < 13 #if defined(EXTMODULE_TIMER_32BITS)
#define pulse_duration_t uint32_t typedef uint32_t pulse_duration_t;
#define trainer_pulse_duration_t uint16_t
#else #else
#define pulse_duration_t uint16_t typedef uint16_t pulse_duration_t;
#define trainer_pulse_duration_t uint16_t
#endif #endif
typedef uint16_t trainer_pulse_duration_t;
template <class T, int SIZE> template <class T, int SIZE>
class DataBuffer { class DataBuffer {
public: public:

View file

@ -1,5 +1,5 @@
option(DISK_CACHE "Enable SD card disk cache" YES) option(DISK_CACHE "Enable SD card disk cache" ON)
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" YES) option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON)
option(PXX1 "PXX1 protocol support" ON) option(PXX1 "PXX1 protocol support" ON)
option(PXX2 "PXX2 protocol support" OFF) option(PXX2 "PXX2 protocol support" OFF)
@ -28,6 +28,7 @@ endif()
if (PCB STREQUAL X10) if (PCB STREQUAL X10)
set(FLAVOUR x10) set(FLAVOUR x10)
set(PCBREV "STD" CACHE STRING "PCB Revision")
add_definitions(-DPCBX10) add_definitions(-DPCBX10)
add_definitions(-DSOFTWARE_VOLUME) add_definitions(-DSOFTWARE_VOLUME)
set(TARGET_SRC set(TARGET_SRC
@ -40,6 +41,13 @@ if (PCB STREQUAL X10)
set(FONTS_TARGET x10_fonts) set(FONTS_TARGET x10_fonts)
set(LCD_DRIVER lcd_driver.cpp) set(LCD_DRIVER lcd_driver.cpp)
set(LUA_EXPORT lua_export_x10) 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) elseif (PCB STREQUAL X12S)
set(FLAVOUR x12s) set(FLAVOUR x12s)
set(PCBREV "13" CACHE STRING "PCB Revision") set(PCBREV "13" CACHE STRING "PCB Revision")
@ -59,14 +67,16 @@ elseif (PCB STREQUAL X12S)
adc_driver.cpp adc_driver.cpp
gps_driver.cpp gps_driver.cpp
) )
set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp)
set(BITMAPS_TARGET x12s_bitmaps) set(BITMAPS_TARGET x12s_bitmaps)
set(FONTS_TARGET x12s_fonts) set(FONTS_TARGET x12s_fonts)
set(LCD_DRIVER lcd_driver.cpp) set(LCD_DRIVER lcd_driver.cpp)
set(LUA_EXPORT lua_export_x12s) set(LUA_EXPORT lua_export_x12s)
add_definitions(-DPCBREV=${PCBREV})
endif() endif()
add_definitions(-DPCBREV=${PCBREV})
add_definitions(-DPCBREV_${PCBREV})
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${BITMAPS_TARGET}) set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${BITMAPS_TARGET})
add_definitions(-DPCBHORUS -DSTM32F429_439xx -DSDRAM -DCOLORLCD) add_definitions(-DPCBHORUS -DSTM32F429_439xx -DSDRAM -DCOLORLCD)
@ -120,8 +130,6 @@ if(INTERNAL_GPS)
message("Horus: Internal GPS enabled") message("Horus: Internal GPS enabled")
endif() endif()
set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp)
set(GVAR_SCREEN model_gvars.cpp) set(GVAR_SCREEN model_gvars.cpp)
set(TARGET_SRC set(TARGET_SRC
@ -171,3 +179,11 @@ if(PYTHONINTERP_FOUND)
DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py
) )
endif() endif()
if(INTERNAL_MODULE_PXX1)
add_definitions(-DINTERNAL_MODULE_PXX1)
endif()
if(INTERNAL_MODULE_PXX2)
add_definitions(-DINTERNAL_MODULE_PXX2)
endif()

View file

@ -139,7 +139,7 @@ void adcInit()
uint16_t getRTCBatteryVoltage() uint16_t getRTCBatteryVoltage()
{ {
return rtcBatteryVoltage * 330 / 2048; return (rtcBatteryVoltage * ADC_VREF_PREC2) / 2048;
} }
const uint16_t adcCommands[MOUSE1+2] = const uint16_t adcCommands[MOUSE1+2] =

View file

@ -33,26 +33,23 @@ void backlightInit()
GPIO_PinAFConfig(BACKLIGHT_GPIO, BACKLIGHT_GPIO_PinSource, BACKLIGHT_GPIO_AF); GPIO_PinAFConfig(BACKLIGHT_GPIO, BACKLIGHT_GPIO_PinSource, BACKLIGHT_GPIO_AF);
// TIMER init // TIMER init
#if defined(PCBX12S) #if defined(PCBX12S) && PCBREV >= 13
if (IS_HORUS_PROD()) { BACKLIGHT_TIMER->ARR = 100;
BACKLIGHT_TIMER->ARR = 100; BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz
BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz BACKLIGHT_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; // PWM
BACKLIGHT_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; // PWM BACKLIGHT_TIMER->CCER = TIM_CCER_CC4E;
BACKLIGHT_TIMER->CCER = TIM_CCER_CC4E; BACKLIGHT_TIMER->CCR4 = 0;
BACKLIGHT_TIMER->CCR4 = 0; BACKLIGHT_TIMER->EGR = 0;
BACKLIGHT_TIMER->EGR = 0; BACKLIGHT_TIMER->CR1 = TIM_CR1_CEN; // Counter enable
BACKLIGHT_TIMER->CR1 = TIM_CR1_CEN; // Counter enable #elif defined(PCBX12S)
} BACKLIGHT_TIMER->ARR = 100;
else { BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz
BACKLIGHT_TIMER->ARR = 100; BACKLIGHT_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM
BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 10000 - 1; // 1kHz BACKLIGHT_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
BACKLIGHT_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM BACKLIGHT_TIMER->CCR1 = 100;
BACKLIGHT_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; BACKLIGHT_TIMER->EGR = 1;
BACKLIGHT_TIMER->CCR1 = 100; BACKLIGHT_TIMER->CR1 |= TIM_CR1_CEN; // Counter enable
BACKLIGHT_TIMER->EGR = 1; BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE;
BACKLIGHT_TIMER->CR1 |= TIM_CR1_CEN; // Counter enable
BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE;
}
#elif defined(PCBX10) #elif defined(PCBX10)
BACKLIGHT_TIMER->ARR = 100; BACKLIGHT_TIMER->ARR = 100;
BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 1000000 - 1; // 10kHz (same as FrOS) BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 1000000 - 1; // 10kHz (same as FrOS)
@ -67,13 +64,10 @@ void backlightInit()
void backlightEnable(uint8_t dutyCycle) void backlightEnable(uint8_t dutyCycle)
{ {
#if defined(PCBX12S) #if defined(PCBX12S) && PCBREV >= 13
if (IS_HORUS_PROD()) { BACKLIGHT_TIMER->CCR4 = dutyCycle;
BACKLIGHT_TIMER->CCR4 = dutyCycle; #elif defined(PCBX12S)
} BACKLIGHT_TIMER->CCR1 = BACKLIGHT_LEVEL_MAX - dutyCycle;
else {
BACKLIGHT_TIMER->CCR1 = BACKLIGHT_LEVEL_MAX - dutyCycle;
}
#elif defined(PCBX10) #elif defined(PCBX10)
BACKLIGHT_TIMER->CCR3 = BACKLIGHT_LEVEL_MAX - dutyCycle; BACKLIGHT_TIMER->CCR3 = BACKLIGHT_LEVEL_MAX - dutyCycle;
#endif #endif

View file

@ -18,14 +18,22 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifndef _BOARD_HORUS_H_ #ifndef _BOARD_H_
#define _BOARD_HORUS_H_ #define _BOARD_H_
#include "../definitions.h" #include "../definitions.h"
#include "../opentx_constants.h" #include "../opentx_constants.h"
#include "board_common.h" #include "board_common.h"
#include "hal.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) #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_sdio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.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 #endif
// Board driver // Board driver
void boardInit(void); void boardInit();
void boardOff(void); void boardOff();
// Timers driver // Timers driver
void init2MhzTimer(); void init2MhzTimer();
void init5msTimer(); void init5msTimer();
// PCBREV driver // PCBREV driver
#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) enum {
#if defined(SIMU) || defined(PCBX10) // 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 #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true
#elif PCBREV >= 13 #elif defined(PCBX10)
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD() #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 #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 #endif
// SD driver // SD driver
@ -88,7 +113,7 @@ void sdInit(void);
void sdMount(void); void sdMount(void);
void sdDone(void); void sdDone(void);
#define sdPoll10ms() #define sdPoll10ms()
uint32_t sdMounted(void); uint32_t sdMounted();
#else #else
#define SD_IS_HC() (0) #define SD_IS_HC() (0)
#define SD_GET_SPEED() (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 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_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 IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define INTERNAL_MODULE_PXX1
#if !defined(PXX2) #if !defined(PXX2)
#define IS_PXX2_INTERNAL_ENABLED() (false) #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 extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted);
void extmoduleInvertedSerialStart(uint32_t baudrate); void extmoduleInvertedSerialStart(uint32_t baudrate);
void extmoduleSendBuffer(const uint8_t * data, uint8_t size);
void extmoduleSendNextFrame(); void extmoduleSendNextFrame();
// Trainer driver // Trainer driver
@ -553,6 +578,7 @@ void gpsSendByte(uint8_t byte);
#endif #endif
// Second serial port driver // Second serial port driver
#if defined(PCBX12S)
#define AUX_SERIAL #define AUX_SERIAL
#define DEBUG_BAUDRATE 115200 #define DEBUG_BAUDRATE 115200
extern uint8_t auxSerialMode; extern uint8_t auxSerialMode;
@ -561,6 +587,7 @@ void auxSerialPutc(char c);
#define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) #define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol)
void auxSerialSbusInit(void); void auxSerialSbusInit(void);
void auxSerialStop(void); void auxSerialStop(void);
#endif
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
// BT driver // BT driver
@ -581,17 +608,4 @@ extern DMAFifo<512> telemetryFifo;
extern DMAFifo<32> auxSerialRxFifo; extern DMAFifo<32> auxSerialRxFifo;
#endif #endif
#if NUM_PWMSTICKS > 0 #endif // _BOARD_H_
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_

View file

@ -24,10 +24,10 @@ void extmoduleStop()
{ {
EXTERNAL_MODULE_OFF(); EXTERNAL_MODULE_OFF();
NVIC_DisableIRQ(EXTMODULE_DMA_IRQn); NVIC_DisableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn);
NVIC_DisableIRQ(EXTMODULE_TIMER_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->DIER &= ~(TIM_DIER_CC2IE | TIM_DIER_UDE);
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
@ -44,7 +44,7 @@ void extmodulePpmStart()
{ {
EXTERNAL_MODULE_ON(); 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_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN;
@ -68,34 +68,40 @@ void extmodulePpmStart()
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
EXTMODULE_TIMER->ARR = 45000;
#if defined(PCBX10) || PCBREV >= 13 #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->BDTR = TIM_BDTR_MOE;
EXTMODULE_TIMER->EGR = 1; // Reloads register values now EXTMODULE_TIMER->EGR = 1; // Reloads register values now
EXTMODULE_TIMER->DIER = TIM_DIER_UDE; // Update DMA request EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1
EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer
#else #else
EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; 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->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->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; // Reloads register values now 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->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; // Start timer
#endif #endif
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); EXTMODULE_TIMER->ARR = 45000;
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); 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() void extmodulePxx1PulsesStart()
{ {
EXTERNAL_MODULE_ON(); 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_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN;
@ -107,47 +113,41 @@ void extmodulePxx1PulsesStart()
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
EXTMODULE_TIMER->ARR = 18000;
#if defined(PCBX10) || PCBREV >= 13 #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->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->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->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->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->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
#endif #endif
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); EXTMODULE_TIMER->ARR = 45000;
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); 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) void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us, bool inverted)
{ {
EXTERNAL_MODULE_ON(); 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_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; 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->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
EXTMODULE_TIMER->ARR = period_half_us;
#if defined(PCBX10) || PCBREV >= 13 #if defined(PCBX10) || PCBREV >= 13
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P; EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P;
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
EXTMODULE_TIMER->CCR3 = 0; EXTMODULE_TIMER->CCR3 = 0;
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; // Restart 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->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0;
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
#else #else
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P;
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
EXTMODULE_TIMER->CCR1 = 0; EXTMODULE_TIMER->CCR1 = 0;
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; // Restart 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->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
#endif #endif
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn); EXTMODULE_TIMER->ARR = 45000;
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7); EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); 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) #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) void extmoduleSendBuffer(const uint8_t * data, uint8_t size)
{ {
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(EXTMODULE_DMA_STREAM); DMA_DeInit(EXTMODULE_USART_TX_DMA_STREAM);
DMA_InitStructure.DMA_Channel = EXTMODULE_DMA_CHANNEL; DMA_InitStructure.DMA_Channel = EXTMODULE_USART_TX_DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR); DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR);
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(data); 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_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(EXTMODULE_DMA_STREAM, &DMA_InitStructure); DMA_Init(EXTMODULE_USART_TX_DMA_STREAM, &DMA_InitStructure);
DMA_Cmd(EXTMODULE_DMA_STREAM, ENABLE); DMA_Cmd(EXTMODULE_USART_TX_DMA_STREAM, ENABLE);
USART_DMACmd(EXTMODULE_USART, USART_DMAReq_Tx, 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 #endif
void extmoduleSendNextFrame() void extmoduleSendNextFrame()
{ {
if (moduleState[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PPM) { switch (moduleState[EXTERNAL_MODULE].protocol) {
case PROTOCOL_CHANNELS_PPM:
#if defined(PCBX10) || PCBREV >= 13 #if defined(PCBX10) || PCBREV >= 13
EXTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; 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->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->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_TIMER_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_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 #else
EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; 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->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->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_TIMER_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_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 #endif
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses); EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses);
EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.ppm.ptr - extmodulePulsesData.ppm.pulses; EXTMODULE_TIMER_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->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
} break;
#if defined(PXX1) #if defined(PXX1)
else if (moduleState[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PXX1_PULSES) { case PROTOCOL_CHANNELS_PXX1_PULSES:
EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#if defined(PCBX10) || PCBREV >= 13 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_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_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
#else EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData());
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_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize();
EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
break;
#endif #endif
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); #if defined(PXX1) && defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize(); case PROTOCOL_CHANNELS_PXX1_SERIAL:
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA extmoduleSendBuffer(extmodulePulsesData.pxx_uart.getData(), extmodulePulsesData.pxx_uart.getSize());
} break;
#endif #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) #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)) { case PROTOCOL_CHANNELS_SBUS:
EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#if defined(PCBX10) || PCBREV >= 13 #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 EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed
#else #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 EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed
#endif #endif
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); // no break
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); case PROTOCOL_CHANNELS_DSM2_LP45:
EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses; case PROTOCOL_CHANNELS_DSM2_DSM2:
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA 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 #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; 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->SR &= ~TIM_SR_CC2IF; // Clear flag
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt

View file

@ -301,9 +301,17 @@
#endif #endif
// PCBREV // 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_RCC_AHB1Periph RCC_AHB1Periph_GPIOI
#define PCBREV_GPIO GPIOI #define PCBREV_GPIO GPIOI
#define PCBREV_GPIO_PIN GPIO_Pin_11 // PI.11 #define PCBREV_GPIO_PIN GPIO_Pin_11 // PI.11
#define PCBREV_VALUE() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN)
#endif
// Led // Led
#define STATUS_LEDS #define STATUS_LEDS
@ -321,6 +329,7 @@
#endif #endif
// Serial Port (DEBUG) // Serial Port (DEBUG)
#if defined(PCBX12S)
#define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3 #define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3
#define AUX_SERIAL_GPIO GPIOB #define AUX_SERIAL_GPIO GPIOB
@ -334,6 +343,10 @@
#define AUX_SERIAL_USART_IRQn USART3_IRQn #define AUX_SERIAL_USART_IRQn USART3_IRQn
#define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1 #define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1
#define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4 #define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4
#else
#define AUX_SERIAL_RCC_AHB1Periph 0
#define AUX_SERIAL_RCC_APB1Periph 0
#endif
// Telemetry // Telemetry
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1)
@ -591,42 +604,75 @@
#endif #endif
// External Module // External Module
#define EXTMODULE_PWR_GPIO GPIOB #define EXTMODULE_PWR_GPIO GPIOB
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03 #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03
#if defined(PCBX10) || PCBREV >= 13 #if defined(PCBX10) && defined(PCBREV_EXPRESS)
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define EXTMODULE_RCC_APB1Periph 0 #define EXTMODULE_RCC_APB1Periph (RCC_APB1Periph_TIM2 | RCC_APB1Periph_USART3)
#define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1 #define EXTMODULE_RCC_APB2Periph 0
#define EXTMODULE_TX_GPIO GPIOA #define EXTMODULE_TX_GPIO GPIOB
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PA.10 #define EXTMODULE_USART_GPIO EXTMODULE_TX_GPIO
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10 #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PB.10 (TIM2_CH3)
#define EXTMODULE_TX_GPIO_AF GPIO_AF_TIM1 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10
#define EXTMODULE_TIMER TIM1 #define EXTMODULE_RX_GPIO_PIN GPIO_Pin_11 // PB.11
#define EXTMODULE_TIMER_IRQn TIM1_CC_IRQn #define EXTMODULE_RX_GPIO_PinSource GPIO_PinSource11
#define EXTMODULE_TIMER_IRQHandler TIM1_CC_IRQHandler #define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM2
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #define EXTMODULE_TIMER TIM2
#define EXTMODULE_DMA_CHANNEL DMA_Channel_6 #define EXTMODULE_TIMER_32BITS
#define EXTMODULE_DMA_STREAM DMA2_Stream5 #define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1)
#define EXTMODULE_DMA_IRQn DMA2_Stream5_IRQn #define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define EXTMODULE_DMA_IRQHandler DMA2_Stream5_IRQHandler #define EXTMODULE_TIMER_CC_IRQn TIM2_IRQn
#define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF5 #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 #else
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 #define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2
#define EXTMODULE_RCC_APB2Periph 0 #define EXTMODULE_RCC_APB2Periph 0
#define EXTMODULE_TX_GPIO GPIOA #define EXTMODULE_TX_GPIO GPIOA
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_15 // PA.15 #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_15 // PA.15 (TIM2_CH1)
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource15 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource15
#define EXTMODULE_TX_GPIO_AF GPIO_AF_TIM2 #define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM2
#define EXTMODULE_TIMER TIM2 #define EXTMODULE_TIMER TIM2
#define EXTMODULE_TIMER_IRQn TIM2_IRQn #define EXTMODULE_TIMER_32BITS
#define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler #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_DMA_CHANNEL DMA_Channel_3 #define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler
#define EXTMODULE_DMA_STREAM DMA1_Stream7 #define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define EXTMODULE_DMA_IRQn DMA1_Stream7_IRQn #define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_3
#define EXTMODULE_DMA_IRQHandler DMA1_Stream7_IRQHandler #define EXTMODULE_TIMER_DMA_STREAM DMA1_Stream7
#define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF7 #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 #endif
// Heartbeat // Heartbeat

View file

@ -53,10 +53,15 @@ void pwrInit()
GPIO_Init(PWR_SWITCH_GPIO, &GPIO_InitStructure); GPIO_Init(PWR_SWITCH_GPIO, &GPIO_InitStructure);
// PCBREV // 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_ResetBits(PCBREV_GPIO, PCBREV_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = PCBREV_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = PCBREV_GPIO_PIN;
GPIO_Init(PCBREV_GPIO, &GPIO_InitStructure); GPIO_Init(PCBREV_GPIO, &GPIO_InitStructure);
#endif
// SD-DETECT PIN // SD-DETECT PIN
GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN); GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN);

View file

@ -64,17 +64,16 @@ void extmodulePpmStart()
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz 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->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->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->BDTR = TIM_BDTR_MOE;
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; 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->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->SR &= ~TIM_SR_CC2IF; // Clear flag
EXTMODULE_TIMER->ARR = 45000;
EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms 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; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); 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->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz 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->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (inverted ? 0 : EXTMODULE_TIMER_OUTPUT_POLARITY);
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
EXTMODULE_TIMER->CCR1 = 0; EXTMODULE_TIMER->CCR1 = 0;
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; // Restart 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->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->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; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn);
@ -215,17 +213,16 @@ void extmodulePxx1PulsesStart()
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) 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->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; // polarity, default low
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
EXTMODULE_TIMER->CCR1 = 18; EXTMODULE_TIMER->CCR1 = 18;
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
EXTMODULE_TIMER->EGR = 1; // Restart 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->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->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; EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn);
@ -244,7 +241,7 @@ void extmodulePxx1SerialStart()
void extmoduleSendNextFrame() void extmoduleSendNextFrame()
{ {
switch(moduleState[EXTERNAL_MODULE].protocol) { switch (moduleState[EXTERNAL_MODULE].protocol) {
case PROTOCOL_CHANNELS_PPM: case PROTOCOL_CHANNELS_PPM:
EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE) * 2; 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->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

View file

@ -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_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_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0)
#define ADC_EXT_SAMPTIME 3 // sample time = 56 cycles #define ADC_EXT_SAMPTIME 3 // sample time = 56 cycles
#define ADC_VREF_PREC2 330 #define ADC_VREF_PREC2 200
#elif defined(PCBX9DP) #elif defined(PCBX9DP)
#define HARDWARE_POT1 #define HARDWARE_POT1
#define HARDWARE_POT2 #define HARDWARE_POT2
@ -907,7 +907,9 @@
#if !defined(RADIO_T12) #if !defined(RADIO_T12)
#define HARDWARE_INTERNAL_MODULE #define HARDWARE_INTERNAL_MODULE
#endif #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 #define INTERNAL_MODULE_PXX1
#endif #endif
#define INTMODULE_FLASH_BAUDRATE 57600 #define INTMODULE_FLASH_BAUDRATE 57600
@ -1046,7 +1048,7 @@
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #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 IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define EXTMODULE_TX_GPIO GPIOC #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_PIN GPIO_Pin_6 // PC.06
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource6 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource6
#define EXTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PC.07 #define EXTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PC.07