[Taranis] DSM2 BIND code
This commit is contained in:
+14
-7
@@ -928,7 +928,7 @@ void menuModelSetup(uint8_t event)
|
||||
#define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX)
|
||||
|
||||
bool CURSOR_ON_CELL = (m_posHorz >= 0);
|
||||
MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_PORT1_ON(1), IF_PORT1_ON(2), IF_PORT1_ON(FAILSAFE_ROWS(0)), LABEL(ExternalModule), (g_model.externalModule==MODULE_TYPE_XJT || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, PORT2_CHANNELS_ROWS(), (IS_MODULE_PPM(1) || IS_MODULE_XJT(1)) ? (uint8_t)2 : (IS_MODULE_DSM2(1) ? (uint8_t)1 : HIDDEN_ROW), IF_PORT2_XJT(FAILSAFE_ROWS(1)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
|
||||
MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), LABEL(InternalModule), 0, IF_PORT1_ON(1), IF_PORT1_ON(2), IF_PORT1_ON(FAILSAFE_ROWS(0)), LABEL(ExternalModule), (g_model.externalModule==MODULE_TYPE_XJT || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, PORT2_CHANNELS_ROWS(), (IS_MODULE_PPM(1) || IS_MODULE_XJT(1) || IS_MODULE_DSM2(1)) ? (uint8_t)2 : HIDDEN_ROW, IF_PORT2_XJT(FAILSAFE_ROWS(1)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
|
||||
#elif defined(CPUM64)
|
||||
#define CURSOR_ON_CELL (true)
|
||||
#define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX)
|
||||
@@ -945,7 +945,7 @@ void menuModelSetup(uint8_t event)
|
||||
|
||||
if (!MENU_CHECK(menuTabModel, e_ModelSetup, MODEL_SETUP_MAX_LINES)) {
|
||||
#if defined(DSM2)
|
||||
s_rangecheck_mode = false;
|
||||
dsm2Flag = 0;
|
||||
#endif
|
||||
#if defined(PCBTARANIS)
|
||||
pxxFlag[INTERNAL_MODULE] = 0;
|
||||
@@ -1293,9 +1293,9 @@ void menuModelSetup(uint8_t event)
|
||||
if (editMode==0 && event==EVT_KEY_BREAK(KEY_ENTER))
|
||||
checkModelIdUnique(g_eeGeneral.currModel);
|
||||
}
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MODULE_BIND, m_posHorz==1 ? attr : 0);
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_MODULE_RANGE, m_posHorz==2 ? attr : 0);
|
||||
if (IS_MODULE_XJT(moduleIdx)) {
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MODULE_BIND, m_posHorz==1 ? attr : 0);
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_MODULE_RANGE, m_posHorz==2 ? attr : 0);
|
||||
uint8_t newFlag = 0;
|
||||
if (attr && m_posHorz>0 && s_editMode>0) {
|
||||
if (m_posHorz == 1)
|
||||
@@ -1308,8 +1308,15 @@ void menuModelSetup(uint8_t event)
|
||||
}
|
||||
#if defined(DSM2)
|
||||
else {
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MODULE_RANGE, m_posHorz==1 ? attr : 0);
|
||||
s_rangecheck_mode = (attr && m_posHorz>0 && editMode>0); // [MENU] key toggles range check mode
|
||||
uint8_t newFlag = 0;
|
||||
if (attr && m_posHorz>0 && s_editMode>0) {
|
||||
if (m_posHorz == 1)
|
||||
newFlag = DSM2_BIND_FLAG;
|
||||
else if (m_posHorz == 2) {
|
||||
newFlag = DSM2_RANGECHECK_FLAG;
|
||||
}
|
||||
}
|
||||
dsm2Flag = newFlag;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1541,7 +1548,7 @@ void menuModelSetup(uint8_t event)
|
||||
#if defined(DSM2)
|
||||
if (IS_DSM2_PROTOCOL(protocol)) {
|
||||
lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+4*FW, y, STR_MODULE_RANGE, m_posHorz!=0 ? attr : 0);
|
||||
s_rangecheck_mode = (attr && m_posHorz>0 && editMode>0); // [MENU] key toggles range check mode
|
||||
dsm2Flag = (attr && m_posHorz>0 && editMode>0) ? DSM2_RANGE_CHECK_FLAG : 0; // [MENU] key toggles range check mode
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -838,7 +838,7 @@ void menuMainView(uint8_t event)
|
||||
#endif
|
||||
|
||||
#if defined(DSM2)
|
||||
if (s_bind_mode) // Issue 98
|
||||
if (dsm2Flag == DSM2_BIND_FLAG) // Issue 98
|
||||
lcd_putsAtt(15*FW, 0, PSTR("BIND"), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
+7
-4
@@ -124,10 +124,11 @@ audioQueue audio;
|
||||
|
||||
#if defined(DSM2)
|
||||
// TODO move elsewhere
|
||||
bool s_bind_mode = false;
|
||||
bool s_rangecheck_mode = false;
|
||||
uint8_t dsm2Flag = 0;
|
||||
#if !defined(PCBTARANIS)
|
||||
uint8_t s_bind_allowed = 255;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint8_t heartbeat;
|
||||
|
||||
@@ -3449,21 +3450,23 @@ void doMixerCalculations()
|
||||
|
||||
#if defined(DSM2)
|
||||
static uint8_t count_dsm_range = 0;
|
||||
if (s_rangecheck_mode)
|
||||
if (dsm2Flag & (DSM2_BIND_FLAG | DSM2_RANGECHECK_FLAG)) {
|
||||
if (++count_dsm_range >= 200) {
|
||||
AUDIO_PLAY(AU_FRSKY_CHEEP);
|
||||
count_dsm_range = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PXX)
|
||||
static uint8_t count_pxx = 0;
|
||||
for (uint8_t i = 0; i < NUM_MODULES; i++) {
|
||||
if((pxxFlag[i] & PXX_SEND_RANGECHECK) || (pxxFlag[i] & PXX_SEND_RXNUM))
|
||||
if (pxxFlag[i] & (PXX_SEND_RANGECHECK | PXX_SEND_RXNUM)) {
|
||||
if (++count_pxx >= 250) {
|
||||
AUDIO_PLAY(AU_FRSKY_CHEEP);
|
||||
count_pxx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+6
-2
@@ -463,11 +463,15 @@ enum EnumKeys {
|
||||
#define LOAD_MODEL_BITMAP()
|
||||
#endif
|
||||
|
||||
// TODO elsewhere ...
|
||||
#if defined(DSM2)
|
||||
extern bool s_bind_mode;
|
||||
extern bool s_rangecheck_mode;
|
||||
#define DSM2_BIND_FLAG 0x80
|
||||
#define DSM2_RANGECHECK_FLAG 0x20
|
||||
extern uint8_t dsm2Flag;
|
||||
#if !defined(PCBTARANIS)
|
||||
extern uint8_t s_bind_allowed;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define IS_PPM_PROTOCOL(protocol) (protocol==PROTO_PPM)
|
||||
|
||||
+30
-32
@@ -37,8 +37,9 @@
|
||||
#include "../opentx.h"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
uint16_t dsm2Stream[400]; // Likely more than we need
|
||||
uint16_t dsm2Stream[400]; // Likely more than we need
|
||||
uint16_t *dsm2StreamPtr;
|
||||
uint16_t dsm2Value;
|
||||
#else
|
||||
uint8_t dsm2Stream[64]; // Likely more than we need
|
||||
uint8_t *dsm2StreamPtr;
|
||||
@@ -47,17 +48,14 @@ uint8_t dsm2SerialBitCount;
|
||||
#endif
|
||||
|
||||
// DSM2 control bits
|
||||
#define DSM2_CHANS 6
|
||||
#define BIND_BIT 0x80
|
||||
#define RANGECHECK_BIT 0x20
|
||||
#define FRANCE_BIT 0x10
|
||||
#define DSMX_BIT 0x08
|
||||
#define BAD_DATA 0x47
|
||||
#define DSM2_CHANS 6
|
||||
#define FRANCE_BIT 0x10
|
||||
#define DSMX_BIT 0x08
|
||||
#define BAD_DATA 0x47
|
||||
|
||||
#define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit
|
||||
#define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
uint16_t dsm2Value;
|
||||
void _send_1(uint8_t v)
|
||||
{
|
||||
dsm2Value += v;
|
||||
@@ -74,16 +72,17 @@ void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1
|
||||
len += BITLEN_DSM2;
|
||||
}
|
||||
else {
|
||||
_send_1(len-1);
|
||||
_send_1(nlev ? len-5 : len+3);
|
||||
len = BITLEN_DSM2;
|
||||
lev = nlev;
|
||||
}
|
||||
b = (b>>1) | 0x80; //shift in stop bit
|
||||
}
|
||||
_send_1(len+BITLEN_DSM2-1); // 2 stop bits
|
||||
_send_1(len+BITLEN_DSM2+3); // 2 stop bits
|
||||
}
|
||||
void putDsm2Flush()
|
||||
{
|
||||
dsm2StreamPtr--; //remove last stopbits and
|
||||
*dsm2StreamPtr++ = 44010; // Past the 44000 of the ARR
|
||||
}
|
||||
#else
|
||||
@@ -134,29 +133,28 @@ void setupPulsesDSM2(unsigned int port)
|
||||
|
||||
dsm2StreamPtr = dsm2Stream;
|
||||
|
||||
// If more channels needed make sure the pulses union/array is large enough
|
||||
if (dsmDat[0] & BAD_DATA) //first time through, setup header
|
||||
{
|
||||
switch(s_current_protocol[port])
|
||||
{
|
||||
case PROTO_DSM2_LP45:
|
||||
dsmDat[0] = 0x80;
|
||||
break;
|
||||
case PROTO_DSM2_DSM2:
|
||||
dsmDat[0] = 0x90;
|
||||
break;
|
||||
default:
|
||||
dsmDat[0] = 0x98; //dsmx, bind mode
|
||||
break;
|
||||
}
|
||||
switch(s_current_protocol[port]) {
|
||||
case PROTO_DSM2_LP45:
|
||||
dsmDat[0] = 0x00;
|
||||
break;
|
||||
case PROTO_DSM2_DSM2:
|
||||
dsmDat[0] = 0x10;
|
||||
break;
|
||||
default: // DSMX
|
||||
dsmDat[0] = 0x18;
|
||||
break;
|
||||
}
|
||||
if ((dsmDat[0] & BIND_BIT) && (!switchState(SW_DSM2_BIND)))
|
||||
dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled
|
||||
if ((!(dsmDat[0] & BIND_BIT)) && s_rangecheck_mode)
|
||||
dsmDat[0] |= RANGECHECK_BIT; // range check function
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
if (s_bind_allowed) s_bind_allowed--;
|
||||
if (s_bind_allowed && switchState(SW_DSM2_BIND))
|
||||
dsm2Flag = DSM2_BIND_FLAG;
|
||||
else
|
||||
dsmDat[0] &= ~RANGECHECK_BIT;
|
||||
dsmDat[1] = g_model.header.modelId; //DSM2 Header second byte for model match
|
||||
dsm2Flag &= ~DSM2_BIND_FLAG;
|
||||
#endif
|
||||
|
||||
dsmDat[0] |= dsm2Flag;
|
||||
dsmDat[1] = g_model.header.modelId; // DSM2 Header second byte for model match
|
||||
|
||||
for (int i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, ((channelOutputs[g_model.moduleData[port].channelsStart+i]*13)>>5)+512, 1023);
|
||||
|
||||
@@ -63,6 +63,20 @@ void setupPulses(unsigned int port)
|
||||
#if defined(DSM2)
|
||||
case MODULE_TYPE_DSM2:
|
||||
required_protocol = limit<uint8_t>(DSM2_PROTO_LP45, PROTO_DSM2_LP45+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_DSMX);
|
||||
// The module is set to OFF during one second before BIND start
|
||||
{
|
||||
static tmr10ms_t bindStartTime = 0;
|
||||
if (dsm2Flag == DSM2_BIND_FLAG) {
|
||||
if (bindStartTime == 0) bindStartTime = get_tmr10ms();
|
||||
if ((tmr10ms_t)(get_tmr10ms() - bindStartTime) < 100) {
|
||||
required_protocol = PROTO_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bindStartTime = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
@@ -42,8 +42,6 @@ uint16_t nextMixerEndTime = 0;
|
||||
#if defined(DSM2)
|
||||
// DSM2 control bits
|
||||
#define DSM2_CHANS 6
|
||||
#define BIND_BIT 0x80
|
||||
#define RANGECHECK_BIT 0x20
|
||||
#define FRANCE_BIT 0x10
|
||||
#define DSMX_BIT 0x08
|
||||
#define BAD_DATA 0x47
|
||||
@@ -394,23 +392,17 @@ FORCEINLINE void setupPulsesDSM2()
|
||||
*ptr = 0x18;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_bind_allowed) s_bind_allowed--;
|
||||
if (s_bind_allowed && switchState(SW_DSM2_BIND))
|
||||
{
|
||||
s_bind_mode = true;
|
||||
*ptr |= BIND_BIT;
|
||||
}
|
||||
else if (s_rangecheck_mode)
|
||||
{
|
||||
*ptr |= RANGECHECK_BIT;
|
||||
}
|
||||
dsm2Flag = DSM2_BIND_FLAG;
|
||||
else
|
||||
s_bind_mode = false;
|
||||
++ptr;
|
||||
dsm2Flag &= ~DSM2_BIND_FLAG;
|
||||
|
||||
*ptr++ |= dsm2Flag;
|
||||
*ptr++ = g_model.header.modelId;
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++)
|
||||
{
|
||||
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, ((channelOutputs[i]*13)>>5)+512,1023);
|
||||
*ptr++ = (i<<2) | ((pulse>>8)&0x03); // encoded channel + upper 2 bits pulse width
|
||||
*ptr++ = pulse & 0xff; // low byte
|
||||
@@ -487,7 +479,7 @@ void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1
|
||||
// NOTE: This has now been tested as NOT required on the stock board, with the ATmega64A chip.
|
||||
_send_1(nlev ? len-5 : len+3);
|
||||
#else
|
||||
_send_1(len -1);
|
||||
_send_1(len-1);
|
||||
#endif
|
||||
len = BITLEN_DSM2;
|
||||
lev = nlev;
|
||||
@@ -510,33 +502,27 @@ void setupPulsesDSM2()
|
||||
pulses2MHzWPtr = pulses2MHz;
|
||||
|
||||
// If more channels needed make sure the pulses union/array is large enough
|
||||
switch (s_current_protocol[0])
|
||||
{
|
||||
switch (s_current_protocol[0]) {
|
||||
case PROTO_DSM2_LP45:
|
||||
dsmDat[0] = 0x00;
|
||||
break;
|
||||
case PROTO_DSM2_DSM2:
|
||||
dsmDat[0] = 0x10;
|
||||
break;
|
||||
default: // DSMX bind mode
|
||||
default: // DSMX
|
||||
dsmDat[0] = 0x18;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_bind_allowed) s_bind_allowed--;
|
||||
if (s_bind_allowed && switchState(SW_TRN))
|
||||
{
|
||||
s_bind_mode = true;
|
||||
dsmDat[0] |= BIND_BIT;
|
||||
}
|
||||
else if (s_rangecheck_mode)
|
||||
{
|
||||
dsmDat[0] |= RANGECHECK_BIT;
|
||||
}
|
||||
if (s_bind_allowed && switchState(SW_DSM2_BIND))
|
||||
dsm2Flag = DSM2_BIND_FLAG;
|
||||
else
|
||||
s_bind_mode = false;
|
||||
dsm2Flag &= ~DSM2_BIND_FLAG;
|
||||
|
||||
dsmDat[0] |= dsm2Flag;
|
||||
dsmDat[1] = g_model.header.modelId; // DSM2 Header second byte for model match
|
||||
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, ((channelOutputs[i]*13)>>5)+512, 1023);
|
||||
dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03); // encoded channel + upper 2 bits pulse width
|
||||
|
||||
Reference in New Issue
Block a user