Compare commits
1 Commits
multipatchv4
...
mm_v2
| Author | SHA1 | Date | |
|---|---|---|---|
| fe72bb028c |
@@ -382,7 +382,7 @@ if(ARCH STREQUAL ARM)
|
||||
set(TARGET_SRC ${TARGET_SRC} haptic_driver.cpp)
|
||||
endif()
|
||||
add_definitions(-DCPUARM)
|
||||
add_definitions(-DFRSKY -DFRSKY_SPORT -DFRSKY_HUB -DGPS -DPXX -DDSM2)
|
||||
add_definitions(-DFRSKY -DFRSKY_SPORT -DFRSKY_HUB -DGPS -DPXX -DDSM2 -DMULTIMODULE)
|
||||
include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR})
|
||||
include_directories(${COOS_DIR} ${COOS_DIR}/kernel ${COOS_DIR}/portable)
|
||||
foreach(LANGUAGE cz de en es fr it pt sk se pl hu) # TODO add nl
|
||||
@@ -442,6 +442,7 @@ if(ARCH STREQUAL ARM)
|
||||
ppm_arm.cpp
|
||||
pxx_arm.cpp
|
||||
dsm2_arm.cpp
|
||||
multi_arm.cpp
|
||||
crossfire.cpp
|
||||
)
|
||||
else()
|
||||
|
||||
@@ -230,6 +230,10 @@ PXX = NO
|
||||
# Values = NO, SERIAL, PPM
|
||||
DSM2 = NO
|
||||
|
||||
# Multimodule support
|
||||
# https://github.com/pascallanger/DIY-Multiprotocol-TX-Module
|
||||
MULTIMODULE = NO
|
||||
|
||||
# HUBSAN protocol
|
||||
# Values = NO, YES
|
||||
HUBSAN = NO
|
||||
@@ -1056,6 +1060,9 @@ ifeq ($(PCB), TARANIS)
|
||||
ifeq ($(DSM2), PPM)
|
||||
CPPSRC += pulses/dsm2_arm.cpp
|
||||
endif
|
||||
ifeq ($(MULTIMODULE), YES)
|
||||
CPPSRC += pulses/multi_arm.cpp
|
||||
endif
|
||||
ifeq ($(HUBSAN), YES)
|
||||
CPPDEFS += -DHUBSAN
|
||||
CPPSRC += pulses/hubsan.cpp
|
||||
@@ -1670,6 +1677,10 @@ ifeq ($(DSM2), PPM)
|
||||
CPPDEFS += -DDSM2 -DDSM2_PPM
|
||||
endif
|
||||
|
||||
ifeq ($(MULTIMODULE), YES)
|
||||
CPPDEFS += -DMULTIMODULE
|
||||
endif
|
||||
|
||||
ifeq ($(TX_CADDY), YES)
|
||||
CPPDEFS += -DTX_CADDY
|
||||
endif
|
||||
|
||||
@@ -190,12 +190,18 @@ int getSwitchWarningsCount()
|
||||
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
|
||||
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
|
||||
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1)
|
||||
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE)) ? (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_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)0 : (uint8_t)1)
|
||||
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
|
||||
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS()))
|
||||
#define FAILSAFE_ROWS(x) (HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW)
|
||||
#define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0
|
||||
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
|
||||
#if defined(MULTIMODULE)
|
||||
#define MULTIMODULE_MODE_ROWS(x) (g_model.moduleData[x].rfProtocol == MM_RF_PROTO_HISKY || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_DSM2 || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_SYMAX || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_CG023 || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_CX10 || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_FLYSKY || g_model.moduleData[x].rfProtocol == MM_RF_PROTO_YD717) ? (uint8_t)2 : (uint8_t)1
|
||||
#else
|
||||
#define MULTIMODULE_MODE_ROWS(x) (uint8_t)0
|
||||
#endif
|
||||
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
|
||||
|
||||
#if TIMERS == 1
|
||||
#define TIMERS_ROWS TIMER_ROWS
|
||||
#elif TIMERS == 2
|
||||
@@ -226,9 +232,9 @@ void menuModelSetup(uint8_t event)
|
||||
IF_INTERNAL_MODULE_ON(IS_MODULE_XJT(INTERNAL_MODULE) ? (HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1) : (IS_MODULE_PPM(INTERNAL_MODULE) ? (uint8_t)1 : HIDDEN_ROW)),
|
||||
IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW),
|
||||
LABEL(ExternalModule),
|
||||
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0,
|
||||
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNALE_MODULE)) ? (uint8_t)1 : (uint8_t)0,
|
||||
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)) ? (uint8_t)2 : HIDDEN_ROW,
|
||||
(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_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
|
||||
IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)),
|
||||
LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
|
||||
#else
|
||||
@@ -242,7 +248,7 @@ void menuModelSetup(uint8_t event)
|
||||
LABEL(ExternalModule),
|
||||
EXTERNAL_MODULE_MODE_ROWS,
|
||||
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)) ? (uint8_t)2 : HIDDEN_ROW,
|
||||
(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_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
|
||||
IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)),
|
||||
LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
|
||||
#endif
|
||||
@@ -663,6 +669,35 @@ void menuModelSetup(uint8_t event)
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
|
||||
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
|
||||
#if defined(MULTIMODULE)
|
||||
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol+8, menuHorizontalPosition==1 ? attr : 0);
|
||||
|
||||
switch(g_model.moduleData[EXTERNAL_MODULE].rfProtocol) {
|
||||
case MM_RF_PROTO_FLYSKY:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_FLYSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_HISKY:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_HISKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_DSM2:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType+1, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_YD717:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_YD717, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_SYMAX:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_SYMAX, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_CX10:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_CX10, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
case MM_RF_PROTO_CG023:
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_CG023, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (attr && s_editMode>0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
@@ -676,12 +711,38 @@ void menuModelSetup(uint8_t event)
|
||||
case 1:
|
||||
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
|
||||
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, MM_RF_PROTO_FIRST, MM_RF_PROTO_LAST);
|
||||
if (checkIncDec_Ret)
|
||||
g_model.moduleData[EXTERNAL_MODULE].subType=0;
|
||||
}
|
||||
else
|
||||
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable);
|
||||
if (checkIncDec_Ret) {
|
||||
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
|
||||
g_model.moduleData[EXTERNAL_MODULE].channelsCount = 0;
|
||||
}
|
||||
break;
|
||||
#if defined(MULTIMODULE)
|
||||
case 2:
|
||||
switch (g_model.moduleData[EXTERNAL_MODULE].rfProtocol) {
|
||||
case MM_RF_PROTO_HISKY:
|
||||
case MM_RF_PROTO_DSM2:
|
||||
case MM_RF_PROTO_SYMAX:
|
||||
case MM_RF_PROTO_CG023:
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1);
|
||||
break;
|
||||
case MM_RF_PROTO_CX10:
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 2);
|
||||
break;
|
||||
case MM_RF_PROTO_FLYSKY:
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3);
|
||||
break;
|
||||
case MM_RF_PROTO_YD717:
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -725,7 +786,7 @@ void menuModelSetup(uint8_t event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ITEM_MODEL_INTERNAL_MODULE_BIND:
|
||||
case ITEM_MODEL_EXTERNAL_MODULE_BIND:
|
||||
case ITEM_MODEL_TRAINER_SETTINGS:
|
||||
@@ -765,11 +826,13 @@ void menuModelSetup(uint8_t event)
|
||||
else {
|
||||
lcd_putsLeft(y, STR_RXNUM);
|
||||
}
|
||||
if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx)) {
|
||||
if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx) || IS_MODULE_MULTIMODULE(moduleIdx)) {
|
||||
if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
|
||||
if (attr && l_posHorz==0) {
|
||||
if (s_editMode>0) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], IS_MODULE_DSM2(moduleIdx) ? 20 : 63);
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx],
|
||||
IS_MODULE_DSM2(moduleIdx) ? 20 :
|
||||
IS_MODULE_MULTIMODULE(moduleIdx) ? 15 : 63);
|
||||
if (checkIncDec_Ret) {
|
||||
modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx];
|
||||
}
|
||||
|
||||
+29
-1
@@ -489,7 +489,8 @@ PACK(typedef struct {
|
||||
int8_t rfProtocol:4;
|
||||
uint8_t channelsStart;
|
||||
int8_t channelsCount; // 0=8 channels
|
||||
uint8_t failsafeMode:7;
|
||||
uint8_t failsafeMode:4;
|
||||
uint8_t subType:3;
|
||||
uint8_t invertedSerial:1; // telemetry serial inverted from standard
|
||||
int16_t failsafeChannels[NUM_CHNOUT];
|
||||
int8_t ppmDelay:6;
|
||||
@@ -2171,6 +2172,9 @@ enum Protocols {
|
||||
#if defined(CROSSFIRE)
|
||||
PROTO_CROSSFIRE,
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
PROTO_MULTIMODULE,
|
||||
#endif
|
||||
#if defined(IRPROTOS)
|
||||
// we will need 4 bytes for proto :(
|
||||
PROTO_SILV,
|
||||
@@ -2199,6 +2203,27 @@ enum DSM2Protocols {
|
||||
DSM2_PROTO_DSMX,
|
||||
};
|
||||
|
||||
|
||||
// rfProtcol is currently a signed int
|
||||
enum MultiModuleRFProtocols {
|
||||
MM_RF_PROTO_FLYSKY=-8,
|
||||
MM_RF_PROTO_FIRST=MM_RF_PROTO_FLYSKY,
|
||||
MM_RF_PROTO_HUBSAN,
|
||||
MM_RF_PROTO_FRSKY_D8,
|
||||
MM_RF_PROTO_HISKY,
|
||||
MM_RF_PROTO_V2X2,
|
||||
MM_RF_PROTO_DSM2,
|
||||
MM_RF_PROTO_DEVO,
|
||||
MM_RF_PROTO_YD717,
|
||||
MM_RF_PROTO_V977,
|
||||
MM_RF_PROTO_SYMAX,
|
||||
MM_RF_PROTO_SLT,
|
||||
MM_RF_PROTO_CX10,
|
||||
MM_RF_PROTO_CG023,
|
||||
MM_RF_PROTO_BAYANG,
|
||||
MM_RF_PROTO_LAST= MM_RF_PROTO_BAYANG
|
||||
};
|
||||
|
||||
enum ModuleTypes {
|
||||
MODULE_TYPE_NONE = 0,
|
||||
MODULE_TYPE_PPM,
|
||||
@@ -2208,6 +2233,9 @@ enum ModuleTypes {
|
||||
#endif
|
||||
#if defined(CROSSFIRE)
|
||||
MODULE_TYPE_CROSSFIRE,
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
MODULE_TYPE_MULTIMODULE,
|
||||
#endif
|
||||
MODULE_TYPE_COUNT
|
||||
};
|
||||
|
||||
@@ -471,6 +471,11 @@
|
||||
#else
|
||||
#define IS_MODULE_CROSSFIRE(idx) (false)
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
#define IS_MODULE_MULTIMODULE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_MULTIMODULE)
|
||||
#else
|
||||
#define IS_MODULE_MULTIMODULE(idx) (false)
|
||||
#endif
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
#define MAX_INTERNAL_MODULE_CHANNELS() ((g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[0].rfProtocol] : maxChannelsModules[g_model.moduleData[INTERNAL_MODULE].type])
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
// MULTI protocol definition (from mbtx:radio/er9x/src/pulses.cpp)
|
||||
/*
|
||||
Serial: 125000 Baud 8n1 _ xxxx xxxx - ---
|
||||
Channels:
|
||||
Nbr=8
|
||||
10bits=0..1023
|
||||
0 -125%
|
||||
96 -100%
|
||||
512 0%
|
||||
928 +100%
|
||||
1023 +125%
|
||||
Stream[0] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
|
||||
sub_protocol is 0..31 (bits 0..4)
|
||||
=> Reserved 0
|
||||
Flysky 1
|
||||
Hubsan 2
|
||||
Frsky 3
|
||||
Hisky 4
|
||||
V2x2 5
|
||||
DSM2 6
|
||||
Devo 7
|
||||
YD717 8
|
||||
KN 9
|
||||
SymaX 10
|
||||
SLT 11
|
||||
CX10 12
|
||||
CG023 13
|
||||
Bayang 14
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
Stream[1] = RxNum | Power | Type;
|
||||
RxNum value is 0..15 (bits 0..3)
|
||||
Type is 0..7 <<4 (bit 4..6)
|
||||
sub_protocol==Flysky
|
||||
Flysky 0
|
||||
V9x9 1
|
||||
V6x6 2
|
||||
V912 3
|
||||
sub_protocol==Hisky
|
||||
Hisky 0
|
||||
HK310 1
|
||||
sub_protocol==DSM2
|
||||
DSM2 0
|
||||
DSMX 1
|
||||
sub_protocol==YD717
|
||||
YD717 0
|
||||
SKYWLKR 1
|
||||
SYMAX2 2
|
||||
XINXUN 3
|
||||
NIHUI 4
|
||||
sub_protocol==SYMAX
|
||||
SYMAX 0
|
||||
SYMAX5C 1
|
||||
sub_protocol==CX10
|
||||
CX10_GREEN 0
|
||||
CX10_BLUE 1 // also compatible with CX10-A, CX12
|
||||
DM007 2
|
||||
sub_protocol==CG023
|
||||
CG023 0
|
||||
YD829 1
|
||||
Power value => 0x80 0=High/1=Low
|
||||
Stream[2] = option_protocol;
|
||||
option_protocol value is -127..127
|
||||
Stream[i+3] = lowByte(channel[i]) // with i[0..7]
|
||||
Stream[11] = highByte(channel[0])<<6 | highByte(channel[1])<<4 | highByte(channel[2])<<2 | highByte(channel[3])
|
||||
Stream[12] = highByte(channel[4])<<6 | highByte(channel[5])<<4 | highByte(channel[6])<<2 | highByte(channel[7])
|
||||
Stream[13] = lowByte(CRC16(Stream[0..12])
|
||||
*/
|
||||
|
||||
/* Lenght 3 (header) + 8 (channel low bytes) + 2 (channel high bits) + 1 (crc) */
|
||||
#define MULTI_CHANS 8
|
||||
#define MULTI_FRAME_LENGTH 2+MULTI_CHANS+2+1
|
||||
|
||||
/* 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)
|
||||
|
||||
void sendByteMulti(uint8_t b)
|
||||
{
|
||||
sendByteDsm2(b);
|
||||
}
|
||||
|
||||
extern const uint16_t CRCTable[];
|
||||
inline void sendByteMultiCRC(uint16_t & crcsum, uint8_t b)
|
||||
{
|
||||
crcsum = (crcsum << 8) ^ (CRCTable[((crcsum>>8)^b) & 0xff]);
|
||||
sendByteMulti(b);
|
||||
}
|
||||
|
||||
|
||||
// This is the data stream to send, prepare after 19.5 mS
|
||||
// Send after 22.5 mS
|
||||
|
||||
//static uint8_t *Dsm2_pulsePtr = pulses2MHz.pbyte ;
|
||||
void setupPulsesMultimodule(unsigned int port)
|
||||
{
|
||||
|
||||
uint16_t crcsum =0;
|
||||
#if defined(PCBSKY9X)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ;
|
||||
#else
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 0;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index = 1;
|
||||
#endif
|
||||
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 100;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.value;
|
||||
#endif
|
||||
|
||||
uint8_t protoByte=0;
|
||||
|
||||
|
||||
if (moduleFlag[port] == MODULE_BIND)
|
||||
protoByte |= MULTI_SEND_BIND;
|
||||
else if (moduleFlag[port] == MODULE_RANGECHECK)
|
||||
protoByte |= MULTI_SEND_RANGECHECK;
|
||||
|
||||
// rfProtocol = -8..7 => 1..15
|
||||
protoByte |= ((g_model.moduleData[port].rfProtocol+9) & 0xf);
|
||||
sendByteMultiCRC(crcsum, protoByte);
|
||||
|
||||
|
||||
// power always set to high (0 << 7)
|
||||
int subtype = g_model.moduleData[port].subType;
|
||||
sendByteMultiCRC(crcsum, (g_model.header.modelId[port] & 0x0f)
|
||||
| (0 << 7) | ((subtype & 0x7) << 4));
|
||||
|
||||
|
||||
//TODO: option_protocol, use same default as multi module
|
||||
int8_t option_protocol=0xd7;
|
||||
sendByteMultiCRC (crcsum, option_protocol);
|
||||
|
||||
uint16_t highbits=0;
|
||||
for (int i=0; i<MULTI_CHANS; i++) {
|
||||
int channel = g_model.moduleData[port].channelsStart+i;
|
||||
int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER;
|
||||
uint16_t pulse = limit(0, ((value*13)>>5)+512, 1023);
|
||||
sendByteMultiCRC(crcsum,pulse & 0xff);
|
||||
highbits = (highbits << 2) | ( (pulse >> 8) & 0x03);
|
||||
}
|
||||
|
||||
// Send high bits
|
||||
sendByteMultiCRC(crcsum, (highbits >> 8) & 0xff);
|
||||
sendByteMultiCRC(crcsum, highbits & 0xff);
|
||||
|
||||
|
||||
//send CRC
|
||||
|
||||
sendByteMulti(crcsum & 0xff);
|
||||
|
||||
putDsm2Flush();
|
||||
}
|
||||
@@ -68,6 +68,16 @@ enum ModuleFlag
|
||||
#define IS_DSM2_SERIAL_PROTOCOL(protocol) (0)
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
#define IS_MULTIMODULE_PROTOCOL(protocol) (protocol==PROTO_MULTIMODULE)
|
||||
#if !defined(DSM2)
|
||||
#error You need to enable DSM2 = PPM for MULTIMODULE support
|
||||
#endif
|
||||
#else
|
||||
#define IS_MULTIMODULE_PROTOCOL(protocol) (0)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CPUARM)
|
||||
#include "pulses_arm.h"
|
||||
#else
|
||||
|
||||
@@ -64,6 +64,11 @@ void setupPulses(unsigned int port)
|
||||
case MODULE_TYPE_XJT:
|
||||
required_protocol = PROTO_PXX;
|
||||
break;
|
||||
#if defined(MULTIMODULE)
|
||||
case MODULE_TYPE_MULTIMODULE:
|
||||
required_protocol = PROTO_MULTIMODULE;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PCBTARANIS) && defined(DSM2)
|
||||
case MODULE_TYPE_DSM2:
|
||||
required_protocol = limit<uint8_t>(PROTO_DSM2_LP45, PROTO_DSM2_LP45+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, PROTO_DSM2_DSMX);
|
||||
@@ -123,6 +128,11 @@ void setupPulses(unsigned int port)
|
||||
case PROTO_CROSSFIRE:
|
||||
disable_crossfire(port);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
case PROTO_MULTIMODULE:
|
||||
disable_dsm2(port);
|
||||
break;
|
||||
#endif
|
||||
case PROTO_PPM:
|
||||
disable_ppm(port);
|
||||
@@ -149,6 +159,11 @@ void setupPulses(unsigned int port)
|
||||
case PROTO_CROSSFIRE:
|
||||
init_crossfire(port);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
case PROTO_MULTIMODULE:
|
||||
init_dsm2(port);
|
||||
break;
|
||||
#endif
|
||||
case PROTO_PPM:
|
||||
init_ppm(port);
|
||||
@@ -182,6 +197,11 @@ void setupPulses(unsigned int port)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
case PROTO_MULTIMODULE:
|
||||
setupPulsesDSM2(port);
|
||||
break;
|
||||
#endif
|
||||
case PROTO_PPM:
|
||||
setupPulsesPPM(port);
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
||||
void setupPulses(unsigned int port);
|
||||
@@ -32,7 +32,7 @@ static void intmodulePxxStop( void ) ;
|
||||
#endif
|
||||
static void extmodulePxxStart( void ) ;
|
||||
static void extmodulePxxStop( void ) ;
|
||||
#if defined(DSM2)
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
static void extmoduleDsm2Start( void ) ;
|
||||
static void extmoduleDsm2Stop( void ) ;
|
||||
#endif
|
||||
@@ -61,7 +61,7 @@ void disable_pxx(uint32_t port)
|
||||
extmodulePxxStop() ;
|
||||
}
|
||||
|
||||
#if defined(DSM2)
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
void init_dsm2(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
@@ -472,7 +472,7 @@ static void extmodulePxxStop()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DSM2)
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
static void extmoduleDsm2Start()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
@@ -596,7 +596,9 @@ extern "C" void TIM8_CC_IRQHandler()
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
}
|
||||
#if defined(DSM2)
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) {
|
||||
else if ((s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) || IS_MULTIMODULE_PROTOCOL (s_current_protocol[EXTERNAL_MODULE]))
|
||||
|
||||
{
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits
|
||||
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
|
||||
|
||||
@@ -542,6 +542,10 @@ void processSerialData(uint8_t data);
|
||||
#if defined(CROSSFIRE)
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_CROSSFIRE)
|
||||
return PROTOCOL_PULSES_CROSSFIRE;
|
||||
#endif
|
||||
#ifdef MULTIMODULE
|
||||
else if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE)
|
||||
return PROTOCOL_FRSKY_D;
|
||||
#endif
|
||||
if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM)
|
||||
return g_model.telemetryProtocol;
|
||||
|
||||
@@ -107,6 +107,15 @@ const pm_char STR_OPEN9X[] PROGMEM =
|
||||
ISTR(TARANIS_PROTOCOLS)
|
||||
ISTR(XJT_PROTOCOLS)
|
||||
ISTR(DSM_PROTOCOLS)
|
||||
#if defined(MULTIMODULE)
|
||||
ISTR(MULTI_PROTOCOLS)
|
||||
ISTR(SUBTYPE_FLYSKY)
|
||||
ISTR(SUBTYPE_HISKY)
|
||||
ISTR(SUBTYPE_YD717)
|
||||
ISTR(SUBTYPE_SYMAX)
|
||||
ISTR(SUBTYPE_CX10)
|
||||
ISTR(SUBTYPE_CG023)
|
||||
#endif
|
||||
ISTR(VOLTSRC)
|
||||
ISTR(CURVE_TYPES)
|
||||
ISTR(VSENSORTYPES)
|
||||
|
||||
@@ -183,7 +183,18 @@ extern const pm_char STR_OPEN9X[];
|
||||
#define OFS_TARANIS_PROTOCOLS (OFS_VTRAINERMODES + sizeof(TR_VTRAINERMODES))
|
||||
#define OFS_XJT_PROTOCOLS (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS))
|
||||
#define OFS_DSM_PROTOCOLS (OFS_XJT_PROTOCOLS + sizeof(TR_XJT_PROTOCOLS))
|
||||
#if defined(MULTIMODULE)
|
||||
#define OFS_MULTI_PROTOCOLS (OFS_DSM_PROTOCOLS + sizeof(TR_DSM_PROTOCOLS))
|
||||
#define OFS_SUBTYPE_FLYSKY (OFS_MULTI_PROTOCOLS + sizeof(TR_MULTI_PROTOCOLS))
|
||||
#define OFS_SUBTYPE_HISKY (OFS_SUBTYPE_FLYSKY + sizeof(TR_SUBTYPE_FLYSKY))
|
||||
#define OFS_SUBTYPE_YD717 (OFS_SUBTYPE_HISKY + sizeof(TR_SUBTYPE_HISKY))
|
||||
#define OFS_SUBTYPE_SYMAX (OFS_SUBTYPE_YD717 + sizeof(TR_SUBTYPE_YD717))
|
||||
#define OFS_SUBTYPE_CX10 (OFS_SUBTYPE_SYMAX + sizeof(TR_SUBTYPE_SYMAX))
|
||||
#define OFS_SUBTYPE_CG023 (OFS_SUBTYPE_CX10 + sizeof(TR_SUBTYPE_CX10))
|
||||
#define OFS_VOLTSRC (OFS_SUBTYPE_CG023 + sizeof(TR_SUBTYPE_CG023))
|
||||
#else
|
||||
#define OFS_VOLTSRC (OFS_DSM_PROTOCOLS + sizeof(TR_DSM_PROTOCOLS))
|
||||
#endif
|
||||
#define OFS_CURVE_TYPES (OFS_VOLTSRC + sizeof(TR_VOLTSRC))
|
||||
#define OFS_VSENSORTYPES (OFS_CURVE_TYPES + sizeof(TR_CURVE_TYPES))
|
||||
#define OFS_VFORMULAS (OFS_VSENSORTYPES + sizeof(TR_VSENSORTYPES))
|
||||
@@ -298,6 +309,15 @@ extern const pm_char STR_OPEN9X[];
|
||||
#define STR_TARANIS_PROTOCOLS (STR_OPEN9X + OFS_TARANIS_PROTOCOLS)
|
||||
#define STR_XJT_PROTOCOLS (STR_OPEN9X + OFS_XJT_PROTOCOLS)
|
||||
#define STR_DSM_PROTOCOLS (STR_OPEN9X + OFS_DSM_PROTOCOLS)
|
||||
#if defined(MULTIMODULE)
|
||||
#define STR_MULTI_PROTOCOLS (STR_OPEN9X + OFS_MULTI_PROTOCOLS)
|
||||
#define STR_SUBTYPE_FLYSKY (STR_OPEN9X + OFS_SUBTYPE_FLYSKY)
|
||||
#define STR_SUBTYPE_HISKY (STR_OPEN9X + OFS_SUBTYPE_HISKY)
|
||||
#define STR_SUBTYPE_YD717 (STR_OPEN9X + OFS_SUBTYPE_YD717)
|
||||
#define STR_SUBTYPE_SYMAX (STR_OPEN9X + OFS_SUBTYPE_SYMAX)
|
||||
#define STR_SUBTYPE_CX10 (STR_OPEN9X + OFS_SUBTYPE_CX10)
|
||||
#define STR_SUBTYPE_CG023 (STR_OPEN9X + OFS_SUBTYPE_CG023)
|
||||
#endif
|
||||
#define STR_CURVE_TYPES (STR_OPEN9X + OFS_CURVE_TYPES)
|
||||
#define STR_VSENSORTYPES (STR_OPEN9X + OFS_VSENSORTYPES)
|
||||
#define STR_VFORMULAS (STR_OPEN9X + OFS_VFORMULAS)
|
||||
@@ -524,6 +544,9 @@ extern const pm_char STR_GF[];
|
||||
extern const pm_char STR_FAS_OFFSET[];
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
extern const pm_char STR_MULTI_OPT[];
|
||||
#endif
|
||||
#if defined(DSM2) || defined(PXX)
|
||||
extern const pm_char STR_RXNUM[];
|
||||
#endif
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
#define TR_COUNTRYCODES TR("US""JP""EU", "America""Japan\0 ""Europe\0")
|
||||
|
||||
#define LEN_TARANIS_PROTOCOLS "\004"
|
||||
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF"
|
||||
#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT"
|
||||
|
||||
#define LEN_XJT_PROTOCOLS "\004"
|
||||
#define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12"
|
||||
@@ -112,6 +112,29 @@
|
||||
#define LEN_DSM_PROTOCOLS "\004"
|
||||
#define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX"
|
||||
|
||||
#define LEN_MULTI_PROTOCOLS "\006"
|
||||
#define TR_MULTI_PROTOCOLS "FlySky""Hubsan""D8\0 ""Hisky\0""V2x2\0 ""DSM2\0 ""Devo\0 ""YD717\0""KN\0 ""SymaX\0""SLT\0 ""CX10\0 ""CG023\0""Bayang"
|
||||
|
||||
#define LEN_SUBTYPE_FLYSKY "\004"
|
||||
#define TR_SUBTYPE_FLYSKY "Std\0""V9x9""V6x6""V912"
|
||||
|
||||
#define LEN_SUBTYPE_HISKY "\005"
|
||||
#define TR_SUBTYPE_HISKY "HiSky""HK310"
|
||||
|
||||
// SUBTYPE FOR DSMX use TR_DSM_PROTOCOLS with offset +1 instead
|
||||
|
||||
#define LEN_SUBTYPE_YD717 "\007"
|
||||
#define TR_SUBTYPE_YD717 "YD717\0 ""SKYWLKR""SYMAX2\0""XINXUN\0""NIHUI\0 "
|
||||
|
||||
#define LEN_SUBTYPE_SYMAX "\007"
|
||||
#define TR_SUBTYPE_SYMAX "Std\0 ""5c"
|
||||
|
||||
#define LEN_SUBTYPE_CX10 "\005"
|
||||
#define TR_SUBTYPE_CX10 "Green""Blue\0""DM007"
|
||||
|
||||
#define LEN_SUBTYPE_CG023 "\005"
|
||||
#define TR_SUBTYPE_CG023 "CG023""YD829"
|
||||
|
||||
#define LEN_VTRIMINC TR("\006", "\013")
|
||||
#define TR_VTRIMINC TR("Expo\0 ""ExFine""Fine\0 ""Medium""Coarse", "Exponential""Extra Fine\0""Fine\0 ""Medium\0 ""Coarse\0 ")
|
||||
|
||||
@@ -796,7 +819,6 @@
|
||||
#define TR_MENUINPUTS "STICKS"
|
||||
#define TR_MENULIMITS "SERVOS"
|
||||
#endif
|
||||
|
||||
#define TR_MENUCURVES "CURVES"
|
||||
#define TR_MENUCURVE "CURVE"
|
||||
#define TR_MENULOGICALSWITCH "LOGICAL SWITCH"
|
||||
@@ -813,6 +835,7 @@
|
||||
#else
|
||||
#define TR_RXNUM "RxNum"
|
||||
#endif
|
||||
#define TR_MULTI_OPT INDENT "Protocol Opt."
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT "Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
Reference in New Issue
Block a user