DSM: selectable refresh rate 22/11ms when supported

This commit is contained in:
Pascal Langer 2020-06-12 00:25:09 +02:00
parent 944ec62f49
commit f52f96d44e
6 changed files with 66 additions and 44 deletions

View File

@ -238,11 +238,11 @@ uint16_t DSM_Rx_callback()
if(num_ch>12) num_ch=12; if(num_ch>12) num_ch=12;
//check DSM_rx_type //check DSM_rx_type
/*packet[12] 1 byte -> max DSM type allowed: /*packet[12] 1 byte -> max DSM type allowed:
0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8 and no telemetry 0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8
0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7 or telemetry enable RX 0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7
0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels with/without telemetry 0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels
0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8 and no telemetry 0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8
0xB2 => 11ms 2048 DSMX => can be any number of channels with/without telemetry 0xB2 => 11ms 2048 DSMX => can be any number of channels
(0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms (0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms
&0x80 => false=DSM2, true=DSMX &0x80 => false=DSM2, true=DSMX
&0xF0 => false=1024, true=2048 */ &0xF0 => false=1024, true=2048 */

View File

@ -43,21 +43,23 @@ enum {
// //
uint8_t ch_map[14]; uint8_t ch_map[14];
const uint8_t PROGMEM DSM_ch_map_progmem[][14] = { const uint8_t PROGMEM DSM_ch_map_progmem[][14] = {
//22+11ms for 4..7 channels //22+11ms for 3..7 channels
{1, 0, 2, 0xff, 0xff, 0xff, 0xff, 1, 0, 2, 0xff, 0xff, 0xff, 0xff}, //3ch - Guess
{1, 0, 2, 3, 0xff, 0xff, 0xff, 1, 0, 2, 3, 0xff, 0xff, 0xff}, //4ch - Guess {1, 0, 2, 3, 0xff, 0xff, 0xff, 1, 0, 2, 3, 0xff, 0xff, 0xff}, //4ch - Guess
{1, 0, 2, 3, 4, 0xff, 0xff, 1, 0, 2, 3, 4, 0xff, 0xff}, //5ch - Guess {1, 0, 2, 3, 4, 0xff, 0xff, 1, 0, 2, 3, 4, 0xff, 0xff}, //5ch - Guess
{1, 5, 2, 3, 0, 4, 0xff, 1, 5, 2, 3, 0, 4, 0xff}, //6ch - HP6DSM {1, 5, 2, 3, 0, 4, 0xff, 1, 5, 2, 3, 0, 4, 0xff}, //6ch - HP6DSM
{1, 5, 2, 4, 3, 6, 0, 1, 5, 2, 4, 3, 6, 0xff}, //7ch - DX6i -> removed channel 0 on second packet to prevent some RXs to switch to 11ms {1, 5, 2, 4, 3, 6, 0, 1, 5, 2, 4, 3, 6, 0 }, //7ch - DX6i
//22ms for 8..12 channels //22ms for 8..12 channels
{1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 0xff, 0xff, 0xff, 0xff}, //8ch - DX8/DX7 {1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 0xff, 0xff, 0xff, 0xff}, //8ch - DX8/DX7
{1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 8, 0xff, 0xff, 0xff}, //9ch - Guess {1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 8, 0xff, 0xff, 0xff}, //9ch - Guess
{1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 8, 9, 0xff, 0xff}, //10ch - Guess {1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 8, 9, 0xff, 0xff}, //10ch - Guess
{1, 5, 2, 3, 6, 10, 0xff, 4, 0, 7, 8, 9, 0xff, 0xff}, //11ch - Guess {1, 5, 2, 3, 6, 10, 0xff, 4, 0, 7, 8, 9, 0xff, 0xff}, //11ch - Guess
{1, 5, 2, 4, 6, 10, 0xff, 0, 7, 3, 8, 9 , 11 , 0xff}, //12ch - DX18 {1, 5, 2, 4, 6, 10, 0xff, 0, 7, 3, 8, 9 , 11 , 0xff}, //12ch - DX18
//11ms for 8..12 channels //11ms for 8..11 channels
{1, 5, 2, 3, 6, 7, 0xff, 1, 5, 2, 4, 0, 0xff, 0xff}, //8ch - DX7 {1, 5, 2, 3, 6, 7, 0xff, 1, 5, 2, 4, 0, 0xff, 0xff}, //8ch - DX7
{1, 5, 2, 3, 6, 7, 0xff, 1, 5, 2, 4, 0, 8, 0xff}, //9ch - Guess {1, 5, 2, 3, 6, 7, 0xff, 1, 5, 2, 4, 0, 8, 0xff}, //9ch - Guess
{1, 5, 2, 3, 4, 8, 9, 1, 5, 2, 3, 0, 7, 6 }, //10ch - DX18 {1, 5, 2, 3, 4, 8, 9, 1, 5, 2, 3, 0, 7, 6 }, //10ch - DX18
{1, 5, 2, 3, 4, 8, 9, 1, 10, 2, 3, 0, 7, 6 }, //11ch - Guess
}; };
static void __attribute__((unused)) DSM_build_bind_packet() static void __attribute__((unused)) DSM_build_bind_packet()
@ -76,23 +78,26 @@ static void __attribute__((unused)) DSM_build_bind_packet()
sum += packet[i]; sum += packet[i];
packet[8] = sum >> 8; packet[8] = sum >> 8;
packet[9] = sum & 0xff; packet[9] = sum & 0xff;
packet[10] = 0x01; //??? packet[10] = 0x01; // ???
packet[11] = num_ch; if(sub_protocol==DSM_AUTO)
packet[11] = 12;
else
packet[11] = num_ch;
if (sub_protocol==DSM2_22) if (sub_protocol==DSM2_22)
packet[12]=num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels packet[12]=num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
if(sub_protocol==DSM2_11) else if(sub_protocol==DSM2_11)
packet[12]=0x12; // DSM2/2048 2 packets packet[12]=0x12; // DSM2/2048 2 packets
if(sub_protocol==DSMX_22) else if(sub_protocol==DSMX_22)
#if defined DSM_TELEMETRY #if defined DSM_TELEMETRY
packet[12] = 0xb2; // DSMX/2048 2 packets packet[12] = 0xb2; // DSMX/2048 2 packets
#else #else
packet[12] = num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels packet[12] = num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels
#endif #endif
if(sub_protocol==DSMX_11 || sub_protocol==DSM_AUTO) // Force DSMX/1024 in mode Auto else // DSMX_11 && DSM_AUTO
packet[12]=0xb2; // DSMX/1024 2 packets packet[12]=0xb2; // DSMX/2048 2 packets
packet[13] = 0x00; //??? packet[13] = 0x00; //???
for(i = 8; i < 14; i++) for(i = 8; i < 14; i++)
sum += packet[i]; sum += packet[i];
packet[14] = sum >> 8; packet[14] = sum >> 8;
@ -112,17 +117,15 @@ static void __attribute__((unused)) DSM_initialize_bind_phase()
static void __attribute__((unused)) DSM_update_channels() static void __attribute__((unused)) DSM_update_channels()
{ {
prev_option=option; prev_option=option;
if(sub_protocol==DSM_AUTO) num_ch=option & 0x0F; // Remove flags 0x80=max_throw, 0x40=11ms
num_ch=12; // Force 12 channels in mode Auto
else if(num_ch<3 || num_ch>12)
num_ch=option & 0x7F; // Remove the Max Throw flag
if(num_ch<4 || num_ch>12)
num_ch=6; // Default to 6 channels if invalid choice... num_ch=6; // Default to 6 channels if invalid choice...
// Create channel map based on number of channels and refresh rate // Create channel map based on number of channels and refresh rate
uint8_t idx=num_ch-4; uint8_t idx=num_ch-3;
if(num_ch>7 && num_ch<11 && (sub_protocol==DSM2_11 || sub_protocol==DSMX_11)) if((option & 0x40) && num_ch>7 && num_ch<12)
idx+=5; // In 11ms mode change index only for channels 8..10 idx+=5; // In 11ms mode change index only for channels 8..11
for(uint8_t i=0;i<14;i++) for(uint8_t i=0;i<14;i++)
ch_map[i]=pgm_read_byte_near(&DSM_ch_map_progmem[idx][i]); ch_map[i]=pgm_read_byte_near(&DSM_ch_map_progmem[idx][i]);
} }
@ -135,24 +138,26 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
DSM_update_channels(); DSM_update_channels();
if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 ) if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 )
{ {//DSMX
packet[0] = cyrfmfg_id[2]; packet[0] = cyrfmfg_id[2];
packet[1] = cyrfmfg_id[3]; packet[1] = cyrfmfg_id[3];
} }
else else
{ {//DSM2
packet[0] = (0xff ^ cyrfmfg_id[2]); packet[0] = (0xff ^ cyrfmfg_id[2]);
packet[1] = (0xff ^ cyrfmfg_id[3]); packet[1] = (0xff ^ cyrfmfg_id[3]);
if(sub_protocol==DSM2_22) if(sub_protocol==DSM2_22)
bits=10; // Only DSM2_22 is using a resolution of 1024 bits=10; // Only DSM2_22 is using a resolution of 1024
} }
#ifdef DSM_THROTTLE_KILL_CH #ifdef DSM_THROTTLE_KILL_CH
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1]; uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
#endif #endif
for (uint8_t i = 0; i < 7; i++) for (uint8_t i = 0; i < 7; i++)
{ {
uint8_t idx = ch_map[(upper?7:0) + i];//1,5,2,3,0,4 uint8_t idx = ch_map[(upper?7:0) + i]; // 1,5,2,3,0,4
uint16_t value = 0xffff;; uint16_t value = 0xffff;
if((option&0x40) == 0 && num_ch < 8 && upper)
idx=0xff; // in 22ms do not transmit upper channels if <8, is it the right method???
if (idx != 0xff) if (idx != 0xff)
{ {
/* Spektrum own remotes transmit normal values during bind and actually use this (e.g. Nano CP X) to /* Spektrum own remotes transmit normal values during bind and actually use this (e.g. Nano CP X) to
@ -160,7 +165,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
#ifdef DSM_THROTTLE_KILL_CH #ifdef DSM_THROTTLE_KILL_CH
if(idx==CH1 && kill_ch<=604) if(idx==CH1 && kill_ch<=604)
{//Activate throttle kill only if channel is throttle and DSM_THROTTLE_KILL_CH below -50% {//Activate throttle kill only if channel is throttle and DSM_THROTTLE_KILL_CH below -50%
if(kill_ch<CHANNEL_MIN_100) // restrict val to 0...400 if(kill_ch<CHANNEL_MIN_100) // restrict val to 0...400
kill_ch=0; kill_ch=0;
else else
kill_ch-=CHANNEL_MIN_100; kill_ch-=CHANNEL_MIN_100;
@ -221,9 +226,9 @@ uint16_t ReadDsm()
case DSM_BIND_WRITE: case DSM_BIND_WRITE:
if(bind_counter--==0) if(bind_counter--==0)
#if defined DSM_TELEMETRY #if defined DSM_TELEMETRY
phase=DSM_BIND_CHECK; //Check RX answer phase=DSM_BIND_CHECK; //Check RX answer
#else #else
phase=DSM_CHANSEL; //Switch to normal mode phase=DSM_CHANSEL; //Switch to normal mode
#endif #endif
CYRF_WriteDataPacket(packet); CYRF_WriteDataPacket(packet);
return 10000; return 10000;
@ -231,28 +236,32 @@ uint16_t ReadDsm()
case DSM_BIND_CHECK: case DSM_BIND_CHECK:
//64 SDR Mode is configured so only the 8 first values are needed but we need to write 16 values... //64 SDR Mode is configured so only the 8 first values are needed but we need to write 16 values...
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84", 16); CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84", 16);
CYRF_SetTxRxMode(RX_EN); //Receive mode CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive
bind_counter=2*DSM_BIND_COUNT; //Timeout of 4.2s if no packet received bind_counter=2*DSM_BIND_COUNT; //Timeout of 4.2s if no packet received
phase++; // change from BIND_CHECK to BIND_READ phase++; // change from BIND_CHECK to BIND_READ
return 2000; return 2000;
case DSM_BIND_READ: case DSM_BIND_READ:
//Read data from RX //Read data from RX
rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing) if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if((rx_phase & 0x07) == 0x02) if((rx_phase & 0x07) == 0x02)
{ // data received with no errors { // data received with no errors
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // Need to set RXOW before data read CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80);// Need to set RXOW before data read
if(CYRF_ReadRegister(CYRF_09_RX_COUNT)==10) // Len if(CYRF_ReadRegister(CYRF_09_RX_COUNT)==10) // Len
{ {
CYRF_ReadDataPacketLen(packet_in+1, 10); CYRF_ReadDataPacketLen(packet_in+1, 10);
if(DSM_Check_RX_packet()) if(DSM_Check_RX_packet())
{ {
debug("Bind");
for(uint8_t i=0;i<10;i++)
debug(" %02X",packet_in[i+1]);
debugln("");
packet_in[0]=0x80; packet_in[0]=0x80;
packet_in[6]&=0x0F; // It looks like there is a flag 0x40 being added by some receivers packet_in[6]&=0x0F; // It looks like there is a flag 0x40 being added by some receivers
if(packet_in[6]>12) packet_in[6]=12; if(packet_in[6]>12) packet_in[6]=12;
else if(packet_in[6]<4) packet_in[6]=6; else if(packet_in[6]<3) packet_in[6]=6;
telemetry_link=1; // Send received data on serial telemetry_link=1; // Send received data on serial
phase++; phase++;
return 2000; return 2000;
@ -296,6 +305,11 @@ uint16_t ReadDsm()
DSM_build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels DSM_build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
CYRF_WriteDataPacket(packet); CYRF_WriteDataPacket(packet);
#if 0
for(uint8_t i=0;i<16;i++)
debug(" %02X", packet[i]);
debugln("");
#endif
phase++; // change from WRITE to CHECK mode phase++; // change from WRITE to CHECK mode
return DSM_WRITE_DELAY; return DSM_WRITE_DELAY;
case DSM_CH1_CHECK_A: case DSM_CH1_CHECK_A:
@ -329,6 +343,8 @@ uint16_t ReadDsm()
phase++; // change from CH2_CHECK to CH2_READ phase++; // change from CH2_CHECK to CH2_READ
CYRF_SetTxRxMode(RX_EN); //Receive mode CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
if(num_ch==3)
return 8250 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY; return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
case DSM_CH2_READ_A: case DSM_CH2_READ_A:
case DSM_CH2_READ_B: case DSM_CH2_READ_B:
@ -353,6 +369,8 @@ uint16_t ReadDsm()
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
phase = DSM_CH2_READ_B; phase = DSM_CH2_READ_B;
if(num_ch==3)
return 8250;
return 11000; return 11000;
} }
if (phase == DSM_CH2_READ_A) if (phase == DSM_CH2_READ_A)
@ -373,11 +391,15 @@ uint16_t ReadDsm()
else else
{ //Normal mode 22ms { //Normal mode 22ms
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
if(num_ch==3)
return 16500 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ; return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
} }
} }
else else
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)
if(num_ch==3)
return 8250 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
#endif #endif
} }

View File

@ -3,7 +3,7 @@
3,FrskyD,D8,Cloned 3,FrskyD,D8,Cloned
4,Hisky,Hisky,HK310 4,Hisky,Hisky,HK310
5,V2x2,V2x2,JXD506 5,V2x2,V2x2,JXD506
6,DSM,DSM2-22,DSM2-11,DSMX-22,DSMX-11,AUTO 6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO
7,Devo,8CH,10CH,12CH,6CH,7CH 7,Devo,8CH,10CH,12CH,6CH,7CH
8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI 8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI
9,KN,WLTOYS,FEILUN 9,KN,WLTOYS,FEILUN

View File

@ -94,7 +94,7 @@ const char STR_SUBTYPE_FRSKYD[] = "\x06""D8\0 ""Cloned";
const char STR_SUBTYPE_FRSKYX[] = "\x07""D16\0 ""D16 8ch""LBT(EU)""LBT 8ch""Cloned\0"; const char STR_SUBTYPE_FRSKYX[] = "\x07""D16\0 ""D16 8ch""LBT(EU)""LBT 8ch""Cloned\0";
const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310"; const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310";
const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506"; const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506";
const char STR_SUBTYPE_DSM[] = "\x06""2 22ms""2 11ms""X 22ms""X 11ms"; const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto";
const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0"; const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0";
const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 "; const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 ";
const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun"; const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun";
@ -193,7 +193,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_DM002, STR_DM002, 0, NO_SUBTYPE, OPTION_NONE }, {PROTO_DM002, STR_DM002, 0, NO_SUBTYPE, OPTION_NONE },
#endif #endif
#if defined(DSM_CYRF6936_INO) #if defined(DSM_CYRF6936_INO)
{PROTO_DSM, STR_DSM, 4, STR_SUBTYPE_DSM, OPTION_MAXTHR }, {PROTO_DSM, STR_DSM, 5, STR_SUBTYPE_DSM, OPTION_MAXTHR },
#endif #endif
#if defined(DSM_RX_CYRF6936_INO) #if defined(DSM_RX_CYRF6936_INO)
{PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE }, {PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE },

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_REVISION 1 #define VERSION_REVISION 1
#define VERSION_PATCH_LEVEL 16 #define VERSION_PATCH_LEVEL 17
//****************** //******************
// Protocols // Protocols

View File

@ -148,7 +148,7 @@ static void multi_send_status()
else if(sub_protocol&0x07) else if(sub_protocol&0x07)
{ {
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto; uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol //if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol
if((sub_protocol&0x07)>=nbr) if((sub_protocol&0x07)>=nbr)
flags &= ~0x04; //Invalid sub protocol flags &= ~0x04; //Invalid sub protocol
} }