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()
@ -77,20 +79,23 @@ static void __attribute__((unused)) DSM_build_bind_packet()
packet[8] = sum >> 8; packet[8] = sum >> 8;
packet[9] = sum & 0xff; packet[9] = sum & 0xff;
packet[10] = 0x01; // ??? packet[10] = 0x01; // ???
if(sub_protocol==DSM_AUTO)
packet[11] = 12;
else
packet[11] = num_ch; 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++)
@ -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,12 +138,12 @@ 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)
@ -152,7 +155,9 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
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
@ -249,10 +254,14 @@ uint16_t ReadDsm()
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
} }