Implement SBUS output for external module bay. (#5225)

* Implement SBUS output for external module bay.

* Bugfixes and Companion support
This commit is contained in:
Arne Schwabe
2017-09-29 18:29:39 +02:00
committed by Bertrand Songis
parent 710e6ddc4c
commit fd782538d8
39 changed files with 367 additions and 150 deletions
@@ -98,15 +98,11 @@ class ProtocolsConversionTable: public ConversionTable
addConversion(PULSES_DSM2, val++);
addConversion(PULSES_DSMX, val++);
}
if (IS_HORUS_OR_TARANIS(board)) {
if (IS_ARM(board)) {
addConversion(PULSES_CROSSFIRE, val++);
addConversion(PULSES_MULTIMODULE, val++);
addConversion(PULSES_PXX_R9M, val++);
}
else if (IS_ARM(board)) {
val++;
addConversion(PULSES_MULTIMODULE, val++);
addConversion(PULSES_PXX_R9M, val++);
addConversion(PULSES_SBUS, val++);
}
}
};
@@ -806,6 +806,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_DSM2:
case PULSES_DSMX:
case PULSES_CROSSFIRE:
case PULSES_SBUS:
return 1;
case PULSES_MULTIMODULE:
return id.contains("multimodule") ? 1 : 0;
@@ -837,6 +838,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_LP45:
case PULSES_DSM2:
case PULSES_DSMX:
case PULSES_SBUS:
return 1;
case PULSES_MULTIMODULE:
return id.contains("multimodule") ? 1 : 0;
+10 -5
View File
@@ -171,6 +171,7 @@ void TimerPanel::on_name_editingFinished()
#define MASK_ANTENNA 256
#define MASK_MULTIOPTION 512
#define MASK_R9M 1024
#define MASK_SBUSPPM_FIELDS 2048
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
@@ -391,11 +392,15 @@ void ModulePanel::update()
module.channelsCount = 16;
break;
case PULSES_PPM:
mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT;
mask |= MASK_PPM_FIELDS | MASK_SBUSPPM_FIELDS| MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT;
if (IS_9XRPRO(firmware->getBoard())) {
mask |= MASK_OPEN_DRAIN;
}
break;
case PULSES_SBUS:
module.channelsCount = 16;
mask |= MASK_SBUSPPM_FIELDS| MASK_CHANNELS_RANGE;
break;
case PULSES_MULTIMODULE:
mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE;
max_rx_num = 15;
@@ -441,8 +446,8 @@ void ModulePanel::update()
ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2);
// PPM settings fields
ui->label_ppmPolarity->setVisible(mask & MASK_PPM_FIELDS);
ui->ppmPolarity->setVisible(mask & MASK_PPM_FIELDS);
ui->label_ppmPolarity->setVisible(mask & MASK_SBUSPPM_FIELDS);
ui->ppmPolarity->setVisible(mask & MASK_SBUSPPM_FIELDS);
ui->ppmPolarity->setCurrentIndex(module.ppm.pulsePol);
ui->label_ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN);
ui->ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN);
@@ -450,8 +455,8 @@ void ModulePanel::update()
ui->label_ppmDelay->setVisible(mask & MASK_PPM_FIELDS);
ui->ppmDelay->setVisible(mask & MASK_PPM_FIELDS);
ui->ppmDelay->setValue(module.ppm.delay);
ui->label_ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS);
ui->ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS);
ui->label_ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS);
ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS);
ui->ppmFrameLength->setMinimum(module.channelsCount*(model->extendedLimits ? 2.250 : 2)+3.5);
ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength));
ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5);
+2 -1
View File
@@ -120,7 +120,8 @@ QString ModelPrinter::printModuleProtocol(unsigned int protocol)
"FrSky XJT (D16)", "FrSky XJT (D8)", "FrSky XJT (LR12)", "FrSky DJT",
"Crossfire",
"DIY Multiprotocol Module",
"FrSky R9M Module"
"FrSky R9M Module",
"SBUS output at VBat"
};
return CHECK_IN_ARRAY(strings, protocol);
+1
View File
@@ -775,6 +775,7 @@ enum PulsesProtocol {
PULSES_CROSSFIRE,
PULSES_MULTIMODULE,
PULSES_PXX_R9M,
PULSES_SBUS,
PULSES_PROTOCOL_LAST
};
+6
View File
@@ -682,6 +682,12 @@ PACK(struct ModuleData {
uint8_t sport_out:1;
uint8_t spare3;
} pxx);
NOBACKUP(struct {
uint8_t spare:6;
uint8_t noninverted:1;
uint8_t spare2:1;
int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)
} sbus);
};
// Helper functions to set both of the rfProto protocol at the same time
+24 -1
View File
@@ -133,7 +133,7 @@ enum MenuModelSetupItems {
#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW )
#define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW)
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
#define EXTERNAL_MODULE_BIND_ROWS() (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW
#define EXTERNAL_MODULE_BIND_ROWS() ((IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || IS_MODULE_SBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW
#if defined(PCBSKY9X) && defined(REVX)
#define OUTPUT_TYPE_ROWS() (IS_MODULE_PPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW) ,
@@ -727,6 +727,8 @@ void menuModelSetup(event_t event)
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE);
if (IS_MODULE_SBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
}
break;
case 1:
@@ -934,6 +936,23 @@ void menuModelSetup(event_t event)
}
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_REFRESHRATE);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT);
lcdDrawText(lcdLastRightPos, y, STR_MS);
lcdDrawText(MODEL_SETUP_2ND_COLUMN+5*FW+2, y, moduleData.sbus.noninverted ? "no inv" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35);
break;
case 1:
CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1);
break;
}
}
}
else {
horzpos_t l_posHorz = menuHorizontalPosition;
coord_t xOffsetBind = MODEL_SETUP_BIND_OFS;
@@ -1100,6 +1119,10 @@ void menuModelSetup(event_t event)
g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_SPORT_OUT, attr, event);
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE);
putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT);
}
break;
}
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
+24 -1
View File
@@ -305,7 +305,7 @@ void menuModelSetup(event_t event)
EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_STATUS_ROW
EXTERNAL_MODULE_CHANNELS_ROWS,
(IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
((IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol))|| IS_MODULE_SBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
FAILSAFE_ROWS(EXTERNAL_MODULE), EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW,
LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS});
#endif
@@ -767,6 +767,8 @@ void menuModelSetup(event_t event)
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE);
if (IS_MODULE_SBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
}
break;
case 1:
@@ -935,6 +937,23 @@ void menuModelSetup(event_t event)
}
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_REFRESHRATE);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT);
lcdDrawText(lcdLastRightPos, y, STR_MS);
lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? "not inverted" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35);
break;
case 1:
CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1);
break;
}
}
}
else {
horzpos_t l_posHorz = menuHorizontalPosition;
coord_t xOffsetBind = MODEL_SETUP_BIND_OFS;
@@ -1089,6 +1108,10 @@ void menuModelSetup(event_t event)
g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_SPORT_OUT, attr, event);
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE);
putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT);
}
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
+23 -1
View File
@@ -262,7 +262,7 @@ bool menuModelSetup(event_t event)
EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_STATUS_ROW
EXTERNAL_MODULE_CHANNELS_ROWS,
(IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
((IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) || IS_MODULE_SBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
FAILSAFE_ROWS(EXTERNAL_MODULE), EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW,
LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS });
@@ -688,6 +688,8 @@ bool menuModelSetup(event_t event)
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE);
if (IS_MODULE_SBUS(EXTERNAL_MODULE))
g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31;
}
break;
case 1:
@@ -845,6 +847,22 @@ bool menuModelSetup(event_t event)
}
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_REFRESHRATE);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT, 0, NULL, STR_MS);
lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? "not inverted" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0);
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35);
break;
case 1:
CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1);
break;
}
}
}
else {
int l_posHorz = menuHorizontalPosition;
coord_t xOffsetBind = MODEL_SETUP_BIND_OFS;
@@ -988,6 +1006,10 @@ bool menuModelSetup(event_t event)
g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, attr, event);
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WARN_BATTVOLTAGE);
drawValueWithUnit(MODEL_SETUP_4TH_COLUMN, y, getBatteryVoltage(), UNIT_VOLTS, attr|PREC2|LEFT);
}
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
+2 -2
View File
@@ -115,7 +115,7 @@ void runFatalErrorScreen(const char * message);
void lcdDrawMMM(coord_t x, coord_t y, LcdFlags flags=0);
// model_setup Defines that are used in all uis in the same way
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE) || (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) != MM_RF_PROTO_DSM2)) ? (uint8_t)0 : (uint8_t)1)
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE) || IS_MODULE_SBUS(EXTERNAL_MODULE) || (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) != MM_RF_PROTO_DSM2)) ? (uint8_t)0 : (uint8_t)1)
#if defined(MULTIMODULE)
@@ -159,7 +159,7 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol);
#define FAILSAFE_ROWS(x) ((IS_MODULE_XJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || IS_MODULE_R9M(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW
#define R9M_OPTION_ROW (IS_TELEMETRY_INTERNAL_MODULE ? TITLE_ROW : (uint8_t) 0)
#define EXTERNAL_MODULE_OPTION_ROW (IS_MODULE_R9M(EXTERNAL_MODULE) ? R9M_OPTION_ROW : MULTIMODULE_OPTIONS_ROW)
#define EXTERNAL_MODULE_OPTION_ROW (IS_MODULE_R9M(EXTERNAL_MODULE) ? R9M_OPTION_ROW : IS_MODULE_SBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW)
#define EXTERNAL_MODULE_POWER_ROW (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) || IS_MODULE_R9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags);
+5 -2
View File
@@ -48,6 +48,7 @@
#endif
#define GET_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol
#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted
#define GET_PPM_DELAY(idx) (g_model.moduleData[idx].ppm.delay * 50 + 300)
#define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppm.frameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount)
@@ -473,7 +474,7 @@ enum Protocols {
PROTO_DSM2_DSM2,
PROTO_DSM2_DSMX,
#endif
#if defined(CROSSFIRE) || defined(MULTIMODULE)
#if defined(CPUARM)
PROTO_CROSSFIRE,
#endif
#if defined(IRPROTOS)
@@ -484,8 +485,9 @@ enum Protocols {
PROTO_PICZ,
PROTO_SWIFT,
#endif
#if defined(MULTIMODULE)
#if defined(CPUARM)
PROTO_MULTIMODULE,
PROTO_SBUS,
#endif
PROTO_MAX,
PROTO_NONE
@@ -570,6 +572,7 @@ enum ModuleTypes {
MODULE_TYPE_CROSSFIRE,
MODULE_TYPE_MULTIMODULE,
MODULE_TYPE_R9M,
MODULE_TYPE_SBUS,
MODULE_TYPE_COUNT
};
+12 -9
View File
@@ -398,12 +398,14 @@ void memswap(void * a, void * b, uint8_t size);
#include "pulses/pulses.h"
#if defined(CPUARM)
// Order is the same as in enum Protocols in myeeprom.h (none, ppm, xjt, dsm, crossfire, multi, r9m)
static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4, 8}; // relative to 8!
// Order is the same as in enum Protocols in myeeprom.h (none, ppm, xjt, dsm, crossfire, multi, r9m, sbus)
static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4, 8, 8}; // relative to 8!
static const int8_t maxChannelsXJT[] = { 0, 8, 0, 4 }; // relative to 8!
#define MAX_TRAINER_CHANNELS_M8() (MAX_TRAINER_CHANNELS-8)
#endif
#if defined(MULTIMODULE)
#define IS_MODULE_MULTIMODULE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_MULTIMODULE)
#else
@@ -417,11 +419,7 @@ void memswap(void * a, void * b, uint8_t size);
#define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM))
#endif
#define IS_MODULE_XJT(idx) (g_model.moduleData[idx].type==MODULE_TYPE_XJT)
#if defined(DSM2)
#define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2)
#else
#define IS_MODULE_DSM2(idx) (false)
#endif
#if defined(CROSSFIRE)
#define IS_MODULE_CROSSFIRE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_CROSSFIRE)
#else
@@ -438,7 +436,6 @@ void memswap(void * a, void * b, uint8_t size);
#elif defined(PCBSKY9X) && !defined(REVA)
#define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || idx==EXTRA_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM))
#define IS_MODULE_XJT(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT)
#define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2)
#define MAX_EXTERNAL_MODULE_CHANNELS() ((g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[0].rfProtocol] : maxChannelsModules[g_model.moduleData[EXTERNAL_MODULE].type])
#define MAX_EXTRA_MODULE_CHANNELS() (8) // Only PPM (16ch PPM)
#define MAX_CHANNELS(idx) (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : (idx==EXTRA_MODULE ? MAX_EXTRA_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8()))
@@ -447,7 +444,6 @@ void memswap(void * a, void * b, uint8_t size);
#else
#define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM))
#define IS_MODULE_XJT(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT)
#define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2)
#define MAX_EXTERNAL_MODULE_CHANNELS() ((g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol] : maxChannelsModules[g_model.moduleData[EXTERNAL_MODULE].type])
#define MAX_CHANNELS(idx) (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8())
#define NUM_CHANNELS(idx) (8+g_model.moduleData[idx].channelsCount)
@@ -455,6 +451,13 @@ void memswap(void * a, void * b, uint8_t size);
#define IS_MODULE_R9M(idx) (g_model.moduleData[idx].type==MODULE_TYPE_R9M)
#define IS_MODULE_PXX(idx) (IS_MODULE_XJT(idx) || IS_MODULE_R9M(idx))
#if defined(DSM2)
#define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2)
#define IS_MODULE_SBUS(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_SBUS)
#else
#define IS_MODULE_DSM2(idx) (false)
#endif
#if defined(MULTIMODULE)
#define IS_MULTIMODULE_DSM(idx) (IS_MODULE_MULTIMODULE(idx) && g_model.moduleData[idx].getMultiProtocol(true) == MM_RF_PROTO_DSM2)
+6 -72
View File
@@ -26,77 +26,11 @@
/* The protocol is heavily inspired by the DSM2 protocol, so reuse some the definitions where they are identical */
#define MULTI_SEND_BIND (1 << 7)
#define MULTI_SEND_RANGECHECK (1 << 5)
#define MULTI_SEND_AUTOBIND (1 << 6)
#define BITLEN_MULTI (10*2) //100000 Baud => 10uS per bit
#if defined(PPM_PIN_SERIAL)
static void sendByteMulti(uint8_t b)
{
uint8_t parity = 1;
putDsm2SerialBit(0); // Start bit
for (uint8_t i=0; i<8; i++) { // 8 data Bits
putDsm2SerialBit(b & 1);
parity = parity ^ (b & 1);
b >>= 1;
}
putDsm2SerialBit(!parity); // Even Parity bit
putDsm2SerialBit(1); // Stop bit
putDsm2SerialBit(1); // Stop bit
}
#else
static void _send_level(uint8_t v)
{
/* Copied over from DSM, this looks doubious and in my logic analyzer
output the low->high is about 2 ns late */
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1)
v += 2;
else
v -= 2;
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1;
modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1;
modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v;
}
static void sendByteMulti(uint8_t b) //max 11 changes 0 10 10 10 10 P 1
{
bool lev = 0;
uint8_t parity = 1;
uint8_t len = BITLEN_MULTI; //max val: 10*20 < 256
for (uint8_t i=0; i<=9; i++) { //8Bits + 1Parity + Stop=1
bool nlev = b & 1; //lsb first
parity = parity ^ (uint8_t)nlev;
if (lev == nlev) {
len += BITLEN_MULTI;
}
else {
_send_level(len);
len = BITLEN_MULTI;
lev = nlev;
}
b = (b>>1) | 0x80; //shift in ones for stop bit and parity
if (i==7)
b = b ^ parity; // lowest bit is one from previous line
}
_send_level(len+ BITLEN_MULTI); // enlarge the last bit to be two stop bits long
}
#endif
// This is the data stream to send, prepare after 19.5 mS
// Send after 22.5 mS
//static uint8_t *Dsm2_pulsePtr = pulses2MHz.pbyte ;
#define MULTI_CHANS 16
#define MULTI_CHAN_BITS 11
void setupPulsesMultimodule(uint8_t port)
@@ -180,9 +114,9 @@ void setupPulsesMultimodule(uint8_t port)
// header, byte 0, 0x55 for proto 0-31 0x54 for 32-63
if (type <= 31)
sendByteMulti(0x55);
sendByteSbus(0x55);
else
sendByteMulti(0x54);
sendByteSbus(0x54);
// protocol byte
@@ -190,16 +124,16 @@ void setupPulsesMultimodule(uint8_t port)
if(g_model.moduleData[port].getMultiProtocol(true) != MM_RF_PROTO_DSM2)
protoByte |= (g_model.moduleData[port].multi.autoBindMode << 6);
sendByteMulti(protoByte);
sendByteSbus(protoByte);
// byte 2, subtype, powermode, model id
sendByteMulti((uint8_t) ((g_model.header.modelId[port] & 0x0f)
sendByteSbus((uint8_t) ((g_model.header.modelId[port] & 0x0f)
| ((subtype & 0x7) << 4)
| (g_model.moduleData[port].multi.lowPowerMode << 7))
);
// byte 3
sendByteMulti((uint8_t) optionValue);
sendByteSbus((uint8_t) optionValue);
uint32_t bits = 0;
uint8_t bitsavailable = 0;
@@ -216,7 +150,7 @@ void setupPulsesMultimodule(uint8_t port)
bits |= limit(0, value, 2047) << bitsavailable;
bitsavailable += MULTI_CHAN_BITS;
while (bitsavailable >= 8) {
sendByteMulti((uint8_t) (bits & 0xff));
sendByteSbus((uint8_t) (bits & 0xff));
bits >>= 8;
bitsavailable -= 8;
}
+6
View File
@@ -77,6 +77,12 @@ enum ModuleFlag
#define IS_MULTIMODULE_PROTOCOL(protocol) (0)
#endif
#if defined(CPUARM)
#define IS_SBUS_PROTOCOL(protocol) (protocol == PROTO_SBUS)
#else
#define IS_SBUS_PROTOCOL(protocol) (0)
#endif
#if defined(CPUARM)
#include "pulses_arm.h"
+14 -4
View File
@@ -65,6 +65,9 @@ uint8_t getRequiredProtocol(uint8_t port)
case MODULE_TYPE_R9M:
required_protocol = PROTO_PXX;
break;
case MODULE_TYPE_SBUS:
required_protocol = PROTO_SBUS;
break;
#if defined(MULTIMODULE)
case MODULE_TYPE_MULTIMODULE:
required_protocol = PROTO_MULTIMODULE;
@@ -145,9 +148,10 @@ void setupPulses(uint8_t port)
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
disable_multimodule(port);
break;
#endif
case PROTO_SBUS:
disable_sbusOut(port);
break;
case PROTO_PPM:
disable_ppm(port);
@@ -166,6 +170,10 @@ void setupPulses(uint8_t port)
setupPulsesPXX(port);
scheduleNextMixerCalculation(port, 9);
break;
case PROTO_SBUS:
setupPulsesSbus(port);
scheduleNextMixerCalculation(port, (45+g_model.moduleData[port].sbus.refreshRate)/2);
break;
#if defined(DSM2)
case PROTO_DSM2_LP45:
@@ -240,9 +248,11 @@ void setupPulses(uint8_t port)
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
init_multimodule(port);
break;
#endif
case PROTO_SBUS:
init_sbusOut(port);
break;
case PROTO_PPM:
init_ppm(port);
+4 -4
View File
@@ -79,6 +79,7 @@ PACK(struct PxxUartPulsesData {
/* DSM2 uses 2 header + 12 channel bytes, with max 10 changes (8n2) per byte + 16 bits trailer ~= 156 max pulses */
/* Multimodule uses 3 bytes header + 22 channel bytes with max 11 changes per byte (8e2) + 16 bits trailer ~= 291 max pulses */
/* Multimodule reuses some of the DSM2 function and structs since the protocols are similar enough */
/* sbus is 1 byte header, 22 channel bytes (11bit * 16ch) + 1 byte flags */
PACK(struct PxxTimerPulsesData {
pulse_duration_t pulses[200];
pulse_duration_t * ptr;
@@ -87,11 +88,7 @@ PACK(struct PxxTimerPulsesData {
uint32_t pcmOnesCount;
});
#if defined(MULTIMODULE)
#define MAX_PULSES_TRANSITIONS 300
#else
#define MAX_PULSES_TRANSITIONS 200
#endif
PACK(struct Dsm2TimerPulsesData {
pulse_duration_t pulses[MAX_PULSES_TRANSITIONS];
@@ -128,6 +125,7 @@ union ModulePulsesData {
* sizeof(ModulePulsesData). __ALIGNED is required for sizeof(ModulePulsesData) to be a multiple of the alignment.
*/
/* TODO: internal pulsedata only needs 200 bytes vs 300 bytes for external, both use 300 byte since we have a common struct */
extern ModulePulsesData modulePulsesData[NUM_MODULES];
union TrainerPulsesData {
@@ -140,12 +138,14 @@ extern const uint16_t CRCTable[];
void setupPulses(uint8_t port);
void setupPulsesDSM2(uint8_t port);
void setupPulsesMultimodule(uint8_t port);
void setupPulsesSbus(uint8_t port);
void setupPulsesPXX(uint8_t port);
void setupPulsesPPMModule(uint8_t port);
void setupPulsesPPMTrainer();
void sendByteDsm2(uint8_t b);
void putDsm2Flush();
void putDsm2SerialBit(uint8_t bit);
void sendByteSbus(uint8_t byte);
#if defined(HUBSAN)
void Hubsan_Init();
+157
View File
@@ -0,0 +1,157 @@
/*
* 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 BITLEN_SBUS (10*2) //100000 Baud => 10uS per bit
/* The protocol reuse some the DSM2 definitions where they are identical */
#if defined(PPM_PIN_SERIAL)
void sendByteSbus(uint8_t b)
{
uint8_t parity = 1;
putDsm2SerialBit(0); // Start bit
for (uint8_t i=0; i<8; i++) { // 8 data Bits
putDsm2SerialBit(b & 1);
parity = parity ^ (b & 1);
b >>= 1;
}
putDsm2SerialBit(!parity); // Even Parity bit
putDsm2SerialBit(1); // Stop bit
putDsm2SerialBit(1); // Stop bit
}
#else
static void _send_level(uint8_t v)
{
/* Copied over from DSM, this looks doubious and in my logic analyzer
output the low->high is about 2 ns late */
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1)
v += 2;
else
v -= 2;
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1;
modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1;
modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v;
}
void sendByteSbus(uint8_t b) //max 11 changes 0 10 10 10 10 P 1
{
bool lev = 0;
uint8_t parity = 1;
uint8_t len = BITLEN_SBUS; //max val: 10*20 < 256
for (uint8_t i=0; i<=9; i++) { //8Bits + 1Parity + Stop=1
bool nlev = b & 1; //lsb first
parity = parity ^ (uint8_t)nlev;
if (lev == nlev) {
len += BITLEN_SBUS;
}
else {
_send_level(len);
len = BITLEN_SBUS;
lev = nlev;
}
b = (b>>1) | 0x80; //shift in ones for stop bit and parity
if (i==7)
b = b ^ parity; // lowest bit is one from previous line
}
_send_level(len+ BITLEN_SBUS); // enlarge the last bit to be two stop bits long
}
#endif
#define SBUS_NORMAL_CHANS 16
#define SBUS_CHAN_BITS 11
/* Definitions from CleanFlight/BetaFlight */
#define SBUS_FLAG_CHANNEL_17 (1 << 0)
#define SBUS_FLAG_CHANNEL_18 (1 << 1)
#define SBUS_FLAG_SIGNAL_LOSS (1 << 2)
#define SBUS_FLAG_FAILSAFE_ACTIVE (1 << 3)
#define SBUS_FRAME_BEGIN_BYTE 0x0F
#define SBUS_CHAN_CENTER 992
inline int getChannelValue(uint8_t port, int channel) {
int ch = g_model.moduleData[port].channelsStart+channel;
// We will ignore 17 and 18th if that brings us over the limit
if (ch > 31)
return 0;
return channelOutputs[ch] + 2*PPM_CH_CENTER(ch) - 2*PPM_CENTER;
}
void setupPulsesSbus(uint8_t port)
{
#if defined(PPM_PIN_SERIAL)
modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ;
modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ;
#else
modulePulsesData[EXTERNAL_MODULE].dsm2.rest = (g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225)*200 ;
modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0;
#endif
modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
// Sync Byte
sendByteSbus(SBUS_FRAME_BEGIN_BYTE);
uint32_t bits = 0;
uint8_t bitsavailable = 0;
// byte 1-22, channels 0..2047, limits not really clear (B
for (int i=0; i<SBUS_NORMAL_CHANS; i++) {
int value = getChannelValue(port, i);
value = value*8/10 + SBUS_CHAN_CENTER;
bits |= limit(0, value, 2047) << bitsavailable;
bitsavailable += SBUS_CHAN_BITS;
while (bitsavailable >= 8) {
sendByteSbus((uint8_t) (bits & 0xff));
bits >>= 8;
bitsavailable -= 8;
}
}
// Flags
uint8_t flags=0;
if (getChannelValue(port, 16) > 0)
flags |=SBUS_FLAG_CHANNEL_17;
if (getChannelValue(port, 17) > 0)
flags |=SBUS_FLAG_CHANNEL_18;
sendByteSbus(flags);
// Last byte, always 0x0
sendByteSbus(0x0);
putDsm2Flush();
}
+2 -1
View File
@@ -132,4 +132,5 @@ set(PULSES_SRC
ppm_arm.cpp
pxx_arm.cpp
dsm2_arm.cpp
)
sbus_arm.cpp
)
+2 -5
View File
@@ -194,11 +194,8 @@ void init_dsm2(uint32_t module_index);
void disable_dsm2(uint32_t module_index);
void init_crossfire(uint32_t module_index);
void disable_crossfire(uint32_t module_index);
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
void init_sbusOut(uint32_t module_index);
void disable_sbusOut(uint32_t module_index);
// Trainer driver
void init_trainer_ppm(void);
+5 -1
View File
@@ -271,13 +271,17 @@ void extmoduleSendNextFrame()
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
}
else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) {
else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) {
EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#if defined(PCBX10) || PCBREV >= 13
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]))
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed
#else
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]))
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed
#endif
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
+2 -4
View File
@@ -96,17 +96,15 @@ void disable_dsm2(uint32_t port)
}
#endif
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
void init_sbusOut(uint32_t port)
{
init_dsm2(port);
}
void disable_multimodule(uint32_t port)
void disable_sbusOut(uint32_t port)
{
disable_dsm2(port);
}
#endif
void init_crossfire(uint32_t port)
{
+2 -4
View File
@@ -260,10 +260,8 @@ void disable_pxx(uint32_t port);
void init_dsm2(uint32_t port);
void disable_dsm2(uint32_t port);
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
void init_sbusOut(uint32_t module_index);
void disable_sbusOut(uint32_t module_index);
// SD driver
#if defined(SIMU)
+5 -5
View File
@@ -244,8 +244,7 @@ void disable_dsm2(uint32_t port)
}
}
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
void init_sbusOut(uint32_t port)
{
if (port == EXTERNAL_MODULE) {
init_main_ppm(3500 * 2, 0);
@@ -256,11 +255,10 @@ void init_multimodule(uint32_t port)
}
}
void disable_multimodule(uint32_t port)
void disable_sbusOut(uint32_t port)
{
disable_dsm2(port);
}
#endif
#if !defined(SIMU)
extern "C" void PWM_IRQHandler(void)
@@ -321,6 +319,9 @@ extern "C" void PWM_IRQHandler(void)
#if defined(MULTIMODULE)
case PROTO_MULTIMODULE:
#endif
case PROTO_SBUS:
// Todo: how to do inverted polarity on this platform?
// Alternate periods of 5.5mS and 3.5 mS
period = pwmptr->PWM_CH_NUM[3].PWM_CPDR;
if (period == 3500 * 2) {
@@ -341,7 +342,6 @@ extern "C" void PWM_IRQHandler(void)
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
}
break;
#endif
default:
pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++;
+2 -5
View File
@@ -194,11 +194,8 @@ void init_dsm2( uint32_t module_index );
void disable_dsm2( uint32_t module_index );
void init_crossfire( uint32_t module_index );
void disable_crossfire( uint32_t module_index );
#if defined(MULTIMODULE)
void init_multimodule(uint32_t module_index);
void disable_multimodule(uint32_t module_index);
#endif
void init_sbusOut(uint32_t module_index);
void disable_sbusOut(uint32_t module_index);
// Trainer driver
void init_trainer_ppm(void);
@@ -117,7 +117,7 @@ void extmodulePxxStart()
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
EXTMODULE_TIMER->ARR = 18000;
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; //polarity, default low
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
EXTMODULE_TIMER->CCR1 = 18;
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
@@ -220,7 +220,9 @@ void extmoduleSendNextFrame()
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
}
else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) {
else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) {
if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]))
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1NP : 0); // reverse polarity for Sbus if needed
EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
+2 -4
View File
@@ -71,17 +71,15 @@ void disable_dsm2(uint32_t port)
}
#endif
#if defined(MULTIMODULE)
void init_multimodule(uint32_t port)
void init_sbusOut(uint32_t port)
{
init_dsm2(port);
}
void disable_multimodule(uint32_t port)
void disable_sbusOut(uint32_t port)
{
disable_dsm2(port);
}
#endif
void init_ppm(uint32_t port)
+4
View File
@@ -161,6 +161,10 @@ const pm_char STR_USE_GLOBAL_FUNCS[] PROGMEM = TR_USE_GLOBAL_FUNCS;
#endif
const pm_char STR_PROTO[] PROGMEM = TR_PROTO;
const pm_char STR_PPMFRAME[] PROGMEM = TR_PPMFRAME;
#if defined(CPUARM)
const pm_char STR_REFRESHRATE[] PROGMEM = TR_REFRESHRATE;
const pm_char SSTR_WARN_BATTVOLTAGE[] PROGMEM = STR_WARN_BATTVOLTAGE;
#endif
const pm_char STR_MS[] PROGMEM = TR_MS;
const pm_char STR_SWITCH[] PROGMEM = TR_SWITCH;
const pm_char STR_TRIMS[] PROGMEM = TR_TRIMS;
+4
View File
@@ -410,6 +410,10 @@ extern const pm_char STR_USE_GLOBAL_FUNCS[];
#endif
extern const pm_char STR_PROTO[];
extern const pm_char STR_PPMFRAME[];
#if defined(CPUARM)
extern const pm_char STR_REFRESHRATE[];
extern const pm_char SSTR_WARN_BATTVOLTAGE[];
#endif
extern const pm_char STR_MS[];
extern const pm_char STR_SWITCH[];
extern const pm_char STR_TRIMS[];
+3 -1
View File
@@ -96,7 +96,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "Vyp\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "Vyp\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (kabel)Spektrum\0 "
@@ -650,6 +650,8 @@
#define TR_PROTO INDENT "Protokol"
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM frame"
#endif
+3 -1
View File
@@ -102,7 +102,7 @@
#define TR_USBMODES TR("Fragen""Joyst\0""SDCard""Serial", "Fragen\0 ""Joystick""Speicher""Seriell\0")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (Kabel)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -670,6 +670,8 @@
#define TR_PROTO TR(INDENT "Protok.", INDENT "Protokoll")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM frame"
#endif
+3 -1
View File
@@ -102,7 +102,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -653,6 +653,8 @@
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM frame"
#endif
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -643,6 +643,8 @@
#endif
#define TR_PROTO TR(INDENT"Proto",INDENT"Protocol")
#define TR_PPMFRAME "Trama PPM"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_MS "ms"
#define TR_SWITCH "Interr"
#define TR_TRIMS "Trims"
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -639,6 +639,8 @@
#endif
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
#define TR_PPMFRAME TR("PPM frame", INDENT "PPM frame")
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_MS "ms"
#define TR_SWITCH "Switch"
#define TR_TRIMS "Trims"
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Popup\0""Joyst\0""SDCard""Série\0", "Demander""Joystick""Stockage""Série\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -657,6 +657,8 @@
#define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "Trame PPM"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "Trame PPM"
#endif
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -655,6 +655,8 @@
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocollo")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM frame"
#endif
+3 -1
View File
@@ -103,7 +103,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -643,6 +643,8 @@
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM frame"
#endif
+3 -1
View File
@@ -99,7 +99,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -657,6 +657,8 @@
#define TR_PROTO TR(INDENT "Proto", INDENT "Protokół")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "Ramka PPM"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME INDENT "Ramka PPM"
#endif
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -644,6 +644,8 @@
#endif
#define TR_PROTO INDENT"Proto"
#define TR_PPMFRAME "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_MS "ms"
#define TR_SWITCH "Chave"
#define TR_TRIMS "Trims"
+3 -1
View File
@@ -98,7 +98,7 @@
#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ")
#define LEN_TARANIS_PROTOCOLS "\004"
#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0"
#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS"
#define LEN_TELEMETRY_PROTOCOLS "\017"
#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry"
@@ -668,6 +668,8 @@
#define TR_PROTO TR(INDENT "Proto", INDENT "Protokoll")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM-paket"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#else
#define TR_PPMFRAME "PPM-paket"
#endif