Compare commits

..

24 Commits

Author SHA1 Message Date
pascallanger
0fcb4b7f1a FX telemetry 2025-03-13 20:15:57 +01:00
pascallanger
432e2e08a4 FX small changes 2025-03-13 19:13:14 +01:00
pascallanger
77efe467ad MouldKg renamed subprotocols 2025-03-13 18:42:34 +01:00
pascallanger
b9c828c878 MouldKg multi 6 ports brick support 2025-03-13 18:29:56 +01:00
pascallanger
99cd4d34d4 MT99xx Trim channels 2025-03-12 17:20:54 +01:00
pascallanger
a9be2a8644 Update MouldKg_nrf24l01.ino 2025-03-12 14:05:53 +01:00
pascallanger
835facd2c3 XK2 Gyro off 2025-03-12 07:45:05 +01:00
pascallanger
9e20e47c5a FX/QF012 details 2 2025-03-12 07:34:47 +01:00
pascallanger
a916275f0d FX/QF012 details 2025-03-12 07:31:32 +01:00
rdba2k
9beade33de Add FX_QF012 subprotocol (#1091) 2025-03-12 07:17:08 +01:00
pascallanger
5ba70c3571 Update Protocols_Details.md 2025-03-10 17:40:46 +01:00
pascallanger
168aa89c57 New SFC protocol WL91x 2025-03-10 17:38:37 +01:00
pascallanger
fa055e991c ASF try 1 2025-02-27 16:56:58 +01:00
pascallanger
5437d88642 DSMR SR6200 test 1 2025-02-26 21:12:34 +01:00
pascallanger
d800f2c333 SLT2 final 2025-02-26 11:31:26 +01:00
pascallanger
78f6af6448 SLT2 last trial? 2025-02-26 00:00:49 +01:00
pascallanger
b04d4a54f7 SLT2 trial 3 2025-02-25 22:08:50 +01:00
pascallanger
ed65c81add SLT2 trial 2 2025-02-25 20:31:46 +01:00
pascallanger
9bdc24c42a SLT2 trial 2025-02-25 15:39:16 +01:00
pascallanger
7107d46d29 SHENQI2 new protocol 2025-02-24 17:04:07 +01:00
pascallanger
825f560cbb Update Protocols_Details.md 2025-02-22 11:51:55 +01:00
pascallanger
ccaec304d5 KAMTOM telemetry 2025-02-22 11:48:03 +01:00
pascallanger
22d45349cc Update Compiling.md (#1078) 2025-02-22 11:36:23 +01:00
pascallanger
5f26d624ad Update Compiling.md 2025-02-22 11:23:49 +01:00
17 changed files with 737 additions and 175 deletions

View File

@@ -91,6 +91,7 @@
58,1,FX,620,1
58,2,FX,9630,1,Rate,Gyro,TrimR,TrimA,TrimE
58,3,FX,Q560,1,FLIP,Gyro,LEDs
58,4,FX,QF012,1,FLIP,Gyro,Invert,Reset
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
23,0,FY326,FY326,1,Flip,RTH,HLess,Expert
@@ -133,14 +134,16 @@
18,4,MJXQ,E010,1,Flip,LED,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
18,5,MJXQ,H26WH,1,Flip,Arm,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
18,6,MJXQ,Phoenix,1,Flip,Arm,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
17,0,MT99XX,Std,1,Flip,LED,Pict,Video,HLess
17,1,MT99XX,H7,1,Flip,LED,Pict,Video,HLess
17,2,MT99XX,YZ,1,Flip,LED,Pict,Video,HLess
17,3,MT99XX,LS,1,Flip,Invert,Pict,Video,HLess
17,4,MT99XX,FY805,1,Flip,n-a,n-a,n-a,HLess
17,5,MT99XX,A180,0,3D_6G
17,6,MT99XX,Dragon,0,Mode,RTH
17,7,MT99XX,F949G,0,6G_3D,Light
17,0,MT99XX,Std,1,Flip,LED,Pict,Video,HLess,Atrim,Etrim
17,1,MT99XX,H7,1,Flip,LED,Pict,Video,HLess,Atrim,Etrim
17,2,MT99XX,YZ,1,Flip,LED,Pict,Video,HLess,Atrim,Etrim
17,3,MT99XX,LS,1,Flip,Invert,Pict,Video,HLess,Atrim,Etrim
17,4,MT99XX,FY805,1,Flip,n-a,n-a,n-a,HLess,Atrim,Etrim
17,5,MT99XX,A180,0,3D_6G,Rate,3D_6G,n-a,n-a,Atrim,Etrim
17,6,MT99XX,Dragon,0,Mode,RTH,n-a,n-a,n-a,Atrim,Etrim
17,7,MT99XX,F949G,0,6G_3D,Light,Rates,Unk1,Unk2,Atrim,Etrim
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH,n-a,n-a,Atrim,Etrim
92,1,MT99xx2,SU35,0,Mode,LED,LED_FH,Invert,Rate,Atrim,Etrim
44,0,NCC1701,Std,1,Warp
77,0,OMP,M2,0,THold,IdleUp,6G_3D
60,0,Pelikan,PRO_V4,0,CH5,CH6,CH7,CH8
@@ -213,11 +216,10 @@
85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH
87,0,IKEA
89,0,LOSI
90,0,MouldKg,Analog,0
90,1,MouldKg,Digit,0
90,0,MouldKg,A4444,0
90,1,MouldKg,D4444,0
90,2,MouldKg,A664,0
91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH
92,1,MT99xx2,SU35,0,Mode,LED,LED_FH,Invert,Rate
93,0,Kyosho2,KT-17,0
94,0,Scorpio
95,0,Bluefly,HP100,0,CH5,CH6,CH7,CH8
@@ -232,3 +234,5 @@
102,1,JIABAILE,Gyro,0,Speed,Light,Flash,ST_Tr
103,0,H36,Std,1,Flip,HLess,RTH
104,0,KAMTOM,Std,0,ST_Tr,TH_Tr,TH_DR
105,0,Shenqi2,Std,1
106,0,WL91x,Std,0

View File

@@ -462,7 +462,7 @@ uint16_t DSM_callback()
else
return DSM2_SFC_PERIOD - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY;
return 10900 - DSM_WRITE_DELAY - DSM_READ_DELAY; //Was 11000 but the SR6200A needs 10900 to report telemetry correctly
}
#endif
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
@@ -470,12 +470,15 @@ uint16_t DSM_callback()
case DSM_CH2_READ_B:
//Read telemetry
rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
debug("ST1:%02X ",rx_phase);
if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
debug("ST2:%02X ",rx_phase);
if((rx_phase & 0x07) == 0x02)
{ // good data (complete with no errors)
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
length=CYRF_ReadRegister(CYRF_09_RX_COUNT);
debug("RX(%d)",length);
if(length>TELEMETRY_BUFFER_SIZE-2)
length=TELEMETRY_BUFFER_SIZE-2;
CYRF_ReadDataPacketLen(packet_in+1, length);
@@ -489,8 +492,11 @@ uint16_t DSM_callback()
}
#endif
packet_in[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
//for(uint8_t i=0;i<length+1;i++)
// debug(" %02X", packet_in[i]);
telemetry_link=1;
}
debugln("");
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_1F || sub_protocol==DSMX_1F) && num_ch < 8) // 22ms mode
{

View File

@@ -38,11 +38,18 @@ Multiprotocol is distributed in the hope that it will be useful,
#define FX9630_BIND_CHANNEL 51
#define FX9630_PAYLOAD_SIZE 8
#define FX9630_NUM_CHANNELS 3
#define FX9630_WRITE_TIME 500
//#define FORCE_FX620_ID
//#define FORCE_FX9630_ID
//#define FORCE_QIDI_ID
enum
{
FX_DATA=0,
FX_RX,
};
static void __attribute__((unused)) FX_send_packet()
{
static uint8_t trim_ch = 0;
@@ -52,21 +59,20 @@ static void __attribute__((unused)) FX_send_packet()
{
XN297_Hopping(hopping_frequency_no++);
if(sub_protocol >= FX9630)
{ // FX9630 & FX_Q560
XN297_SetTXAddr(rx_tx_addr, 4);
{ // FX9630 & FX_Q560 & FX_QF012
if (hopping_frequency_no >= FX9630_NUM_CHANNELS)
{
hopping_frequency_no = 0;
if(sub_protocol == FX9630)
{
trim_ch++;
if(trim_ch > 3) trim_ch = 0;
trim_ch &= 3;
}
else // FX_Q560
else // FX_Q560 & FX_QF012
trim_ch = 0;
}
}
else // FX816 and FX620
else // FX816 & FX620
{
hopping_frequency_no &= 0x03;
}
@@ -85,12 +91,16 @@ static void __attribute__((unused)) FX_send_packet()
val = trim_ch==0 ? 0x20 : (convert_channel_8b(trim_ch + CH6) >> 2); // no trim on Throttle
packet[4] = val; // Trim for channel x 0C..20..34
packet[5] = (trim_ch << 4) // channel x << 4
| GET_FLAG(CH5_SW, 0x01) // DR toggle swich: 0 small throw, 1 large throw / Q560 acrobatic
| GET_FLAG(CH5_SW, (sub_protocol == FX_QF012 ? 0x08 : 0x01)) // DR toggle swich: 0 small throw, 1 large throw / Q560 acrobatic / QF012 Special effects
// FX9630 =>0:6G small throw, 1:6G large throw, 2:3D
// QIDI-550=>0:3D, 1:6G, 2:Torque
// QF012=>0:beginner(6G), 1:mid(3D), 2:expert(Gyro off)
| (Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x04 : 0x02));
if(sub_protocol == FX_Q560)
packet[5] |= GET_FLAG(CH7_SW, 0x18); // Q560 LED flag 0x10 conflicting with trim_ch... Corrected on new boards using 0x08 instead
else if (sub_protocol == FX_QF012)
packet[5] |= GET_FLAG(CH7_SW, 0x40) // QF012 invert flight
| GET_FLAG(CH8_SW, 0x80); // QF012 Restore fine tunning midpoint
}
else // FX816 and FX620
{
@@ -182,7 +192,7 @@ static void __attribute__((unused)) FX_RF_init()
packet_period = FX620_BIND_PACKET_PERIOD;
packet_length = FX620_PAYLOAD_SIZE;
}
else // FX9630 & FX_Q560
else // FX9630 & FX_Q560 & FX_QF012
{
XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4);
XN297_RFChannel(FX9630_BIND_CHANNEL);
@@ -214,15 +224,16 @@ static void __attribute__((unused)) FX_initialize_txid()
for(uint8_t i=1;i<FX_NUM_CHANNELS;i++)
hopping_frequency[i] = i*10 + hopping_frequency[0];
}
else // FX9630 & FX_Q560
else // FX9630 & FX_Q560 & FX_QF012
{
//??? Need to find out how the first RF channel is calculated ???
hopping_frequency[0] = 0x13;
//Other 2 RF channels are sent during the bind phase so they can be whatever
hopping_frequency[1] = RX_num & 0x0F + 0x1A;
hopping_frequency[2] = rx_tx_addr[3] & 0x0F + 0x38;
#ifdef FORCE_FX9630_ID
memcpy(rx_tx_addr,(uint8_t*)"\xCE\x31\x9B\x73", 4);
memcpy(hopping_frequency,"\x13\x1A\x38", FX9630_NUM_CHANNELS); //Original dump=>19=0x13,26=0x1A,56=0x38
#else
hopping_frequency[0] = 0x13; // constant???
hopping_frequency[1] = RX_num & 0x0F + 0x1A;
hopping_frequency[2] = rx_tx_addr[3] & 0x0F + 0x38;
#endif
#ifdef FORCE_QIDI_ID
memcpy(rx_tx_addr,(uint8_t*)"\x23\xDC\x76\xA2", 4);
@@ -232,26 +243,78 @@ static void __attribute__((unused)) FX_initialize_txid()
//memcpy(rx_tx_addr,(uint8_t*)"\x38\xC7\x6D\x8D", 4);
//memcpy(hopping_frequency,"\x0D\x20\x3A", FX9630_NUM_CHANNELS);
#endif
//??? Need to find out how the first RF channel is calculated ???
}
}
uint16_t FX_callback()
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(packet_period);
#endif
if(bind_counter)
if(--bind_counter==0)
#ifdef FX_HUB_TELEMETRY
bool rx=false;
switch(phase)
{
BIND_DONE;
if(sub_protocol == FX620)
{
XN297_SetTXAddr(rx_tx_addr, 3);
packet_period = FX620_PACKET_PERIOD;
}
case FX_DATA:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
#endif
#ifdef MULTI_SYNC
telemetry_set_input_sync(packet_period);
#endif
if(bind_counter)
if(--bind_counter==0)
{
BIND_DONE;
if(sub_protocol == FX620)
{
XN297_SetTXAddr(rx_tx_addr, 3);
packet_period = FX620_PACKET_PERIOD;
}
else if(sub_protocol >= FX9630)
{ // FX9630 & FX_Q560 & FX_QF012
XN297_SetTXAddr(rx_tx_addr, 4);
#ifdef FX_HUB_TELEMETRY
XN297_SetRXAddr(rx_tx_addr,packet_length);
#endif
}
}
FX_send_packet();
#ifdef FX_HUB_TELEMETRY
if(sub_protocol < FX9630)
break;
if(rx)
{
debug("RX");
if(XN297_ReadPayload(packet_in, packet_length))
{//Good CRC
telemetry_link = 1;
//v_lipo1 = packet_in[1] == 0x03 ? 0x00:0xFF; // low voltage
#if 1
for(uint8_t i=0; i < packet_length; i++)
debug(" %02X", packet_in[i]);
#endif
}
debugln();
}
phase++;
return FX9630_WRITE_TIME;
default: //FX_RX
/* { // Wait for packet to be sent before switching to receive mode
uint16_t start=(uint16_t)micros(), count=0;
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
{
if(XN297_IsPacketSent())
break;
count++;
}
debug("%d",count);
} */
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = FX_DATA;
return packet_period - FX9630_WRITE_TIME;
}
FX_send_packet();
#endif
return packet_period;
}
@@ -262,6 +325,10 @@ void FX_init()
FX_RF_init();
hopping_frequency_no = 0;
bind_counter=FX_BIND_COUNT;
#ifdef FX_HUB_TELEMETRY
RX_RSSI = 100; // Dummy value
phase = FX_DATA;
#endif
}
#endif

View File

@@ -136,10 +136,13 @@ uint16_t KAMTOM_callback()
{
BIND_DONE;
if(packet_in[0] == 0xA0 && packet_in[14] == rx_tx_addr[2] && packet_in[15] == rx_tx_addr[3])
{
{//Good packet with our TXID
rx_tx_addr[0] = packet_in[9];
rx_tx_addr[1] = packet_in[10];
//if(packet_in[1] == 0x03) // low voltage
#ifdef KAMTOM_HUB_TELEMETRY
v_lipo1 = packet_in[1] == 0x03 ? 0x00:0xFF; // low voltage
telemetry_link = 1;
#endif
}
#if 0
for(uint8_t i=0; i < KAMTOM_PAYLOAD_SIZE; i++)
@@ -174,6 +177,9 @@ void KAMTOM_init()
bind_counter = KAMTOM_BIND_COUNT;
phase = KAMTOM_DATA;
hopping_frequency_no = 0;
#ifdef KAMTOM_HUB_TELEMETRY
RX_RSSI = 100; // Dummy value
#endif
}
#endif

View File

@@ -112,7 +112,10 @@ void KYOSHO3_init()
debugln("RF CH: %02X",hopping_frequency[0]);
#endif
CYRF_ConfigRFChannel(hopping_frequency[0]);
if(IS_BIND_IN_PROGRESS)
CYRF_ConfigRFChannel(0x04);
else
CYRF_ConfigRFChannel(hopping_frequency[0]);
bind_counter = 8217;
phase = 0;

View File

@@ -189,8 +189,8 @@ static void __attribute__((unused)) MT99XX_send_packet()
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR,0x00,0xE1); // elevator
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
packet[4] = (convert_channel_8b(CH10) ^ 0xFF) >> 2; // aileron trim (3F..20..00)
packet[5] = convert_channel_8b(CH11) >> 2; // elevator trim (00..20..3F)
packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP );
if(sub_protocol != PA18+8)
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
@@ -337,7 +337,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
#if 0
#if 1
for(uint8_t i=0; i<MT99XX_PACKET_SIZE; i++)
debug(" %02X",packet[i]);
debugln();

View File

@@ -50,12 +50,19 @@ static void __attribute__((unused)) MOULDKG_send_packet()
else
{
uint8_t n = num_ch<<2;
if(sub_protocol == MOULDKG_ANALOG)
if(sub_protocol == MOULDKG_ANALOG4 || sub_protocol == MOULDKG_ANALOG6 )
{
packet[0] = 0x36;
uint8_t ch[]={ 1,0,2,3 };
for(uint8_t i=0;i<4;i++)
packet[i+4] = convert_channel_8b(ch[i]+n);
const uint8_t ch[]={ 1,0,2,3,4,5 };
if(sub_protocol == MOULDKG_ANALOG6)
n += num_ch<<1;
for(uint8_t i=0;i<6;i++)
{
if(i > 3 && (sub_protocol == MOULDKG_ANALOG4 || i + n > 15))
packet[i+4] = 0x80; //Centered channel
else
packet[i+4] = convert_channel_8b(ch[i]+n);
}
len = MOULDKG_PAYLOAD_SIZE_ANALOG;
}
else

View File

@@ -55,7 +55,7 @@
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
56,AFHDS2A_RX,Multi,CPPM
57,HoTT,Sync,No_Sync
58,FX,816,620,9630,Q560
58,FX,816,620,9630,Q560,QF012
59,Bayang_RX,Multi,CPPM
60,Pelikan,Pro,Lite,SCX24
61,EazyRC
@@ -86,7 +86,7 @@
87,IKEA
88,WILLIFM
89,Losi
90,MouldKg,Analog,Digit
90,MouldKg,A4444,D4444,A664
91,Xerall
92,MT99xx,PA18,SU35
93,Kyosho2,KT-17
@@ -99,4 +99,6 @@
100,YuXiang
102,JIABAILE,STD,GYRO
103,H36
104,KAMTOM
104,KAMTOM
105,Shenqi2
106,WL91x

View File

@@ -36,6 +36,7 @@ const char STR_MT99XX[] ="MT99XX";
const char STR_MT99XX2[] ="MT99XX2";
const char STR_MJXQ[] ="MJXq";
const char STR_SHENQI[] ="Shenqi";
const char STR_SHENQI2[] ="Shenqi2";
const char STR_FY326[] ="FY326";
const char STR_FUTABA[] ="Futaba";
const char STR_J6PRO[] ="J6 Pro";
@@ -116,6 +117,7 @@ const char STR_YUXIANG[] ="YuXiang";
const char STR_UDIRC[] ="UDIRC";
const char STR_JIABAILE[] ="JIABAILE";
const char STR_KAMTOM[] ="KAMTOM";
const char STR_WL91X[] ="WL91x";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -182,10 +184,10 @@ const char STR_SUBTYPE_KYOSHO2[] = "\x05""KT-17";
const char STR_SUBTYPE_KYOSHO3[] = "\x03""ASF";
const char STR_SUBTYPE_FUTABA[] = "\x05""SFHSS";
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
const char STR_SUBTYPE_MOULDKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_MOULDKG[] = "\x05""A4444""D4444""A664\0";
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0";
const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630""Q560";
const char STR_SUBTYPE_FX[] = "\x05""816\0 ""620\0 ""9630\0""Q560\0""QF012";
const char STR_SUBTYPE_SGF22[] = "\x04""F22\0""F22S""J20\0";
const char STR_SUBTYPE_JIABAILE[] = "\x04""Std\0""Gyro";
#define NO_SUBTYPE nullptr
@@ -342,7 +344,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
#endif
#if defined(FX_NRF24L01_INO)
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 4, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 5, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
#endif
#if defined(FY326_NRF24L01_INO)
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },
@@ -423,7 +425,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
#endif
#if defined(MOULDKG_NRF24L01_INO)
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULDKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULDKG, 3, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
#endif
#if defined(MT99XX_CCNRF_INO)
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
@@ -476,6 +478,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(SHENQI_NRF24L01_INO)
{PROTO_SHENQI, STR_SHENQI, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI_init, SHENQI_callback },
#endif
#if defined(SHENQI2_NRF24L01_INO)
{PROTO_SHENQI2, STR_SHENQI2, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI2_init, SHENQI2_callback },
#endif
#if defined(SKYARTEC_CC2500_INO)
{PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback },
#endif
@@ -500,9 +505,6 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(V911S_CCNRF_INO)
{PROTO_V911S, STR_V911S, STR_SUBTYPE_V911S, 2, OPTION_RFTUNE, 0, 0, SW_NRF, V911S_init, V911S_callback },
#endif
#if defined(WK2x01_CYRF6936_INO)
{PROTO_WK2x01, STR_WK2x01, STR_SUBTYPE_WK2x01, 6, OPTION_NONE, 1, 1, SW_CYRF, WK_init, WK_callback },
#endif
#if defined(WFLY_CYRF6936_INO)
{PROTO_WFLY, STR_WFLY, STR_SUBTYPE_WFLY, 1, OPTION_NONE, 1, 0, SW_CYRF, WFLY_init, WFLY_callback },
#endif
@@ -510,6 +512,13 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_OPTION, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },
// {PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_WBUS, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },// crash OpenTX...
#endif
#if defined(WK2x01_CYRF6936_INO)
{PROTO_WK2x01, STR_WK2x01, STR_SUBTYPE_WK2x01, 6, OPTION_NONE, 1, 1, SW_CYRF, WK_init, WK_callback },
#endif
#if defined(WL91X_CCNRF_INO)
{PROTO_WL91X, STR_WL91X, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, WL91X_init, WL91X_callback },
#endif
#if defined(XERALL_NRF24L01_INO)
{PROTO_XERALL, STR_XERALL, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, XERALL_init, XERALL_callback },
#endif

View File

@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 34
#define VERSION_PATCH_LEVEL 46
#define MODE_SERIAL 0
@@ -132,6 +132,8 @@ enum PROTOCOLS
PROTO_JIABAILE = 102, // =>NRF24L01
PROTO_H36 = 103, // =>NRF24L01
PROTO_KAMTOM = 104, // =>NRF24L01
PROTO_SHENQI2 = 105, // =>NRF24L01
PROTO_WL91X = 106, // =>CC2500 & NRF24L01
PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500
@@ -469,8 +471,9 @@ enum RLINK
};
enum MOULDKG
{
MOULDKG_ANALOG = 0,
MOULDKG_DIGIT = 1,
MOULDKG_ANALOG4 = 0,
MOULDKG_DIGIT4 = 1,
MOULDKG_ANALOG6 = 2,
};
enum KF606
{
@@ -489,6 +492,7 @@ enum FX
FX620 = 1,
FX9630 = 2,
FX_Q560 = 3,
FX_QF012 = 4,
};
enum SGF22
{

View File

@@ -0,0 +1,232 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol 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.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(SHENQI2_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_SHENQI2_ORIGINAL_ID
#define SHENQI2_PAYLOAD_SIZE 8
#define SHENQI2_RF_NUM_CHANNELS 16
#define SHENQI2_BIND_COUNT 2000
#define SHENQI2_WRITE_TIME 650
#define SHENQI2_BIND_CHANNEL 44
#define SHENQI2_PACKET_PERIOD 8210
enum {
SHENQI2_BIND = 0,
SHENQI2_BIND_RX,
SHENQI2_DATA,
};
static void __attribute__((unused)) SHENQI2_send_packet()
{
if(bind_counter)
{
bind_counter--;
if(!bind_counter)
BIND_DONE;
}
memset(packet, 0x00, SHENQI2_PAYLOAD_SIZE);
packet_count &= 0x0F;
packet[0] = packet_count;
memcpy(&packet[1],rx_tx_addr,5);
if(IS_BIND_DONE)
{//Normal
uint8_t val = convert_channel_8b(CH2);
if(val < 0x70)
val = 0x30;
else if(val < 0x80)
val = 0x00;
else
{
val &= 0x7F;
val >>= 2;
}
if(Channel_data[CH1] > 1024+50)
val |= 0x40;
else if(Channel_data[CH1] < 1024-50)
val |= 0x80;
packet[6] = val;
//packet[7] = 0x00; // ??
}
else
packet[0] |= 0x30;
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, SHENQI2_PAYLOAD_SIZE, false);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < SHENQI2_PAYLOAD_SIZE; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) SHENQI2_initialize_txid()
{
#ifdef FORCE_SHENQI2_ORIGINAL_ID
//TXID
rx_tx_addr[0] = 0x51;
rx_tx_addr[1] = 0x70;
rx_tx_addr[2] = 0x02;
//RXID
rx_tx_addr[3] = 0x46;
rx_tx_addr[4] = 0xBE;
#endif
rx_tx_addr[3] = 0x00;
rx_tx_addr[4] = 0x00;
//Freq
memcpy(hopping_frequency,(uint8_t*)"\x05\x09\x0E\x0F\x17\x1C\x21\x27\x2A\x2C\x33\x39\x3D\x42\x48\x4C",16);
}
static void __attribute__((unused)) SHENQI2_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//Address
XN297_SetTXAddr((uint8_t*)"\x74\xD1\x3A\xF5\x6C", 5);
XN297_SetRXAddr((uint8_t*)"\x74\xD1\x3A\xF5\x6C", SHENQI2_PAYLOAD_SIZE);
XN297_RFChannel(SHENQI2_BIND_CHANNEL);
}
uint16_t SHENQI2_callback()
{
static bool rx=false;
switch(phase)
{
case SHENQI2_BIND:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
SHENQI2_send_packet();
packet_count++;
if(rx)
{
uint8_t val=XN297_ReadEnhancedPayload(packet_in, SHENQI2_PAYLOAD_SIZE);
if(val == SHENQI2_PAYLOAD_SIZE)
{
if(memcmp(rx_tx_addr, packet_in, 3) == 0)
{//Good packet with our TXID
BIND_DONE;
rx_tx_addr[3] = packet_in[3];
rx_tx_addr[4] = packet_in[4];
packet_count = 0;
phase = SHENQI2_DATA;
}
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < SHENQI2_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
}
}
phase++;
return SHENQI2_WRITE_TIME;
case SHENQI2_BIND_RX:
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = SHENQI2_BIND;
return SHENQI2_PACKET_PERIOD - SHENQI2_WRITE_TIME;
default: //SHENQI2_DATA
//Since I don't know the order of the channels, I'm hopping on all the channels quickly
//Refresh rate from the motorcycle perspective is 32ms instead of 8ms...
XN297_Hopping(hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= 0x0F;
SHENQI2_send_packet();
if(hopping_frequency_no%4 == 0)
packet_count++;
return SHENQI2_PACKET_PERIOD/4;
}
return 0;
}
void SHENQI2_init()
{
BIND_IN_PROGRESS;
SHENQI2_initialize_txid();
SHENQI2_RF_init();
bind_counter = SHENQI2_BIND_COUNT;
phase = SHENQI2_BIND;
hopping_frequency_no = 0;
}
#endif
/*
XN297 1Mb Enhanced,Acked,Scrambled
Bind
---
RX on channel: 44, Time: 2890us P: 34 51 70 02 00 00 00 00
RX on channel: 44, Time: 1780us P: 34 51 70 02 00 00 00 00
RX on channel: 44, Time: 1773us P: 34 51 70 02 00 00 00 00
RX on channel: 44, Time: 1772us P: 34 51 70 02 00 00 00 00
RX on channel: 44, Time: 2889us P: 35 51 70 02 00 00 00 00
RX on channel: 44, Time: 1769us P: 35 51 70 02 00 00 00 00
RX on channel: 44, Time: 1774us P: 35 51 70 02 00 00 00 00
RX on channel: 44, Time: 1771us P: 35 51 70 02 00 00 00 00
RX on channel: 44, Time: 2894us P: 36 51 70 02 00 00 00 00
A= 74 D1 3A F5 6C
RF:44
Timing: 1772µs between the same 4 packets, 2892µs to the next packet, 8208µs between 2 packets
Request ack, if no ack repeat the packet 4 times
P[0] = counter 00..0F | 30 bind
P[1] = TXID[0]
P[2] = TXID[1]
P[3] = TXID[2]
P[4] = RXID[0]
P[5] = RXID[1]
P[6] = TH 00..1F, Break 30, 40 ST_right, 80 ST_left
P[7] = 00?
Answer from motorcycle:
P: 51 70 02 46 BE 00 00 00
P[0] = TXID[0]
P[1] = TXID[1]
P[2] = TXID[2]
P[3] = RXID[0]
P[4] = RXID[1]
P[5] = 00
P[6] = 00
P[7] = 00
Normal packets
---
A= 74 D1 3A F5 6C
RF:5,9,14,15,23,28,33,39,42,44,51,57,61,66,72,76
RF:\x05\x09\x0E\x0F\x17\x1C\x21\x27\x2A\x2C\x33\x39\x3D\x42\x48\x4C
- order of the channels is unknown and vary over time
- send 16 times on each channel and switch (counter 00..0F)
Timing:1772µs between the same 4 packets, 2892µs to the next packet, 8208µs between 2 packets
Timing:8208 between packets if acked
P: 00 51 70 02 46 BE 00 00
P[0] = counter 00..0F
P[1] = TXID[0]
P[2] = TXID[1]
P[3] = TXID[2]
P[4] = RXID[0]
P[5] = RXID[1]
P[6] = TH 00..1F, Break 30, 40 ST_right, 80 ST_left
P[7] = 00?
*/

View File

@@ -19,6 +19,7 @@
#include "iface_nrf250k.h"
//#define SLT_Q200_FORCE_ID
//#define SLT_V1_4_FORCE_ID
// For code readability
#define SLT_PAYLOADSIZE_V1 7
@@ -73,12 +74,12 @@ static void __attribute__((unused)) SLT_set_freq(void)
}
// Unique freq
uint8_t max_freq=0x50; //V1 and V2
if(sub_protocol==Q200)
uint8_t max_freq = 0x50; //V1 and V2
if(sub_protocol == Q200)
max_freq=45;
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
{
if(sub_protocol==Q200 && hopping_frequency[i] >= max_freq)
if(sub_protocol == Q200 && hopping_frequency[i] >= max_freq)
hopping_frequency[i] = hopping_frequency[i] - max_freq + 0x03;
uint8_t done = 0;
while (!done)
@@ -94,15 +95,15 @@ static void __attribute__((unused)) SLT_set_freq(void)
}
}
}
#if 0
#ifdef DEBUG_SERIAL
debug("CH:");
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
debug(" %02X", hopping_frequency[i]);
debug(" %02X(%d)", hopping_frequency[i], hopping_frequency[i]);
debugln();
#endif
//Bind channel
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
hopping_frequency[SLT_NFREQCHANNELS] = SLT_BIND_CHANNEL;
//Calib all channels
NRF250K_HoppingCalib(SLT_NFREQCHANNELS+1);
@@ -153,35 +154,38 @@ static void __attribute__((unused)) SLT_build_packet()
//->V1 stops here
if(sub_protocol==Q200)
if(sub_protocol == Q200)
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
else if(sub_protocol==MR100 || sub_protocol==Q100)
else if(sub_protocol == MR100 || sub_protocol == Q100)
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
packet[7]=convert_channel_8b(CH7);
packet[8]=convert_channel_8b(CH8);
if(sub_protocol==RF_SIM) {
packet[9]=convert_channel_8b(CH9);
packet[10]=convert_channel_8b(CH10);
} else {
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
}
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
{//Calibrate
packet[9]=0x77; //enter calibration
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
packet[10]=0x20; //launch calibration
calib_counter++;
if(calib_counter>250) calib_counter=250;
packet[7] = convert_channel_8b(CH7);
packet[8] = convert_channel_8b(CH8);
if(sub_protocol == RF_SIM)
{
packet[9] = convert_channel_8b(CH9);
packet[10] = convert_channel_8b(CH10);
}
else
calib_counter=0;
{
packet[9] = 0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
packet[10] = 0x00; //normal mode for Q100/Q200, unknown for V2/MR100
}
if((sub_protocol == Q100 || sub_protocol == Q200) && CH13_SW)
{//Calibrate
packet[9] = 0x77; //enter calibration
if(calib_counter >= 20 && calib_counter <= 25) // 7 packets for Q100 / 3 packets for Q200
packet[10] = 0x20; //launch calibration
calib_counter++;
if(calib_counter > 250) calib_counter = 250;
}
else
calib_counter = 0;
}
static void __attribute__((unused)) SLT_send_bind_packet()
@@ -192,8 +196,8 @@ static void __attribute__((unused)) SLT_send_bind_packet()
NRF250K_SetPower();
BIND_DONE;
NRF250K_SetTXAddr((uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
if(phase==SLT_BIND2)
memcpy((void*)packet, (void*)rx_tx_addr, SLT_TXID_SIZE);
if(phase == SLT_BIND2)
SLT_send_packet(SLT_TXID_SIZE);
else // SLT_BIND1
SLT_send_packet(SLT_PAYLOADSIZE_V2);
@@ -224,9 +228,9 @@ uint16_t SLT_callback()
case SLT_DATA2:
phase++;
SLT_send_packet(packet_length);
if(sub_protocol==SLT_V1)
if(sub_protocol == SLT_V1)
return SLT_V1_TIMING_PACKET;
if(sub_protocol==SLT_V1_4)
if(sub_protocol == SLT_V1_4)
{
phase++; //Packets are sent two times only
return SLT_V1_4_TIMING_PACKET;
@@ -238,24 +242,24 @@ uint16_t SLT_callback()
if (++packet_count >= 100)
{// Send bind packet
packet_count = 0;
if(sub_protocol==SLT_V1||sub_protocol==SLT_V1_4)
if(sub_protocol == SLT_V1 || sub_protocol == SLT_V1_4)
{
phase=SLT_BIND2;
phase = SLT_BIND2;
return SLT_V1_TIMING_BIND2;
}
//V2
phase=SLT_BIND1;
phase = SLT_BIND1;
return SLT_V2_TIMING_BIND1;
}
else
{// Continue to send normal packets
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD;
if(sub_protocol == SLT_V1)
return 20000 - SLT_TIMING_BUILD;
if(sub_protocol==SLT_V1_4)
return 18000-SLT_TIMING_BUILD-SLT_V1_4_TIMING_PACKET;
return 18000 - SLT_TIMING_BUILD - SLT_V1_4_TIMING_PACKET;
//V2
return 13730-SLT_TIMING_BUILD;
return 13730 - SLT_TIMING_BUILD;
}
case SLT_BIND1:
SLT_send_bind_packet();
@@ -264,12 +268,12 @@ uint16_t SLT_callback()
case SLT_BIND2:
SLT_send_bind_packet();
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2;
if(sub_protocol==SLT_V1_4)
return 18000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2-SLT_V1_4_TIMING_PACKET;
if(sub_protocol == SLT_V1)
return 20000 - SLT_TIMING_BUILD - SLT_V1_TIMING_BIND2;
if(sub_protocol == SLT_V1_4)
return 18000 - SLT_TIMING_BUILD - SLT_V1_TIMING_BIND2 - SLT_V1_4_TIMING_PACKET;
//V2
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2;
return 13730 - SLT_TIMING_BUILD - SLT_V2_TIMING_BIND1 - SLT_V2_TIMING_BIND2;
}
return 19000;
}
@@ -280,35 +284,26 @@ void SLT_init()
packet_count = 0;
packet_sent = 0;
hopping_frequency_no = 0;
if(sub_protocol==Q200)
{ //Q200: Force high part of the ID otherwise it won't bind
rx_tx_addr[0]=0x01;
rx_tx_addr[1]=0x02;
#ifdef SLT_Q200_FORCE_ID // ID taken from TX dumps
rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x6A;rx_tx_addr[3]=0x31;
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
#endif
}
SLT_RF_init();
SLT_set_freq();
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
if(sub_protocol == SLT_V1)
{
packet_length = SLT_PAYLOADSIZE_V1;
#ifdef MULTI_SYNC
packet_period = 20000+2*SLT_V1_TIMING_PACKET; //22ms
#endif
}
else if(sub_protocol==SLT_V1_4)
else if(sub_protocol == SLT_V1_4)
{
packet_length = SLT_PAYLOADSIZE_V1_4;
#ifdef MULTI_SYNC
packet_period = 18000; //18ms
#endif
//Test IDs
MProtocol_id = MProtocol_id_master ^ (1<<RX_num);
set_rx_tx_addr(MProtocol_id);
debugln("Try ID: %lx", MProtocol_id);
//Force high part of the ID otherwise the RF frequencies do not match, only tested the 2 last bytes...
rx_tx_addr[0]=0xF4;
rx_tx_addr[1]=0x71;
#ifdef SLT_V1_4_FORCE_ID // ID taken from TX dumps
memcpy(rx_tx_addr,"\xF4\x71\x8D\x01",SLT_TXID_SIZE);
#endif
}
else //V2
{
@@ -317,6 +312,21 @@ void SLT_init()
packet_period = 13730+2*SLT_V2_TIMING_PACKET; //~18ms
#endif
}
if(sub_protocol == Q200)
{ //Q200: Force high part of the ID otherwise it won't bind
rx_tx_addr[0]=0x01;
rx_tx_addr[1]=0x02;
#ifdef SLT_Q200_FORCE_ID // ID taken from TX dumps
rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x6A;rx_tx_addr[3]=0x31;
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
#endif
}
SLT_RF_init();
SLT_set_freq();
phase = SLT_BUILD;
}
#endif

View File

@@ -337,6 +337,7 @@
#undef REALACC_NRF24L01_INO
#undef SGF22_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef SHENQI2_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
#undef V2X2_NRF24L01_INO
#undef V761_NRF24L01_INO
@@ -358,6 +359,7 @@
#undef SLT_CCNRF_INO
#undef UDIRC_CCNRF_INO
#undef V911S_CCNRF_INO
#undef WL91X_CCNRF_INO
#undef XK_CCNRF_INO
#undef XK2_CCNRF_INO
#endif
@@ -392,9 +394,11 @@
#undef KYOSHO3_CYRF6936_INO
#undef MOULDKG_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef SHENQI2_NRF24L01_INO
#undef JIABAILE_NRF24L01_INO
#undef UDIRC_CCNRF_INO
#undef KAMTOM_NRF24L01_INO
#undef WL91X_CCNRF_INO
#endif
#ifdef MULTI_SURFACE
@@ -490,6 +494,8 @@
#undef PROPEL_HUB_TELEMETRY
#undef OMP_HUB_TELEMETRY
#undef V761_HUB_TELEMETRY
#undef FX_HUB_TELEMETRY
#undef KAMTOM_HUB_TELEMETRY
#undef YUXIANG_HUB_TELEMETRY
#undef RLINK_HUB_TELEMETRY
#undef DSM_RX_CYRF6936_INO
@@ -529,6 +535,12 @@
#if not defined(V761_NRF24L01_INO)
#undef V761_HUB_TELEMETRY
#endif
#if not defined(FX_NRF24L01_INO)
#undef FX_HUB_TELEMETRY
#endif
#if not defined(KAMTOM_NRF24L01_INO)
#undef KAMTOM_HUB_TELEMETRY
#endif
#if not defined(YUXIANG_NRF24L01_INO)
#undef YUXIANG_HUB_TELEMETRY
#endif
@@ -589,7 +601,7 @@
//protocols using FRSKYD user frames
#undef HUB_TELEMETRY
#endif
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY) && not defined(OMP_HUB_TELEMETRY) && not defined(V761_HUB_TELEMETRY) && not defined(YUXIANG_HUB_TELEMETRY) && not defined(WFLY2_HUB_TELEMETRY) && not defined(LOLI_HUB_TELEMETRY) && not defined(MLINK_HUB_TELEMETRY) && not defined(MLINK_FW_TELEMETRY) && not defined(MT99XX_HUB_TELEMETRY) && not defined(MULTI_CONFIG_INO)
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY) && not defined(OMP_HUB_TELEMETRY) && not defined(V761_HUB_TELEMETRY) && not defined(FX_HUB_TELEMETRY) && not defined(KAMTOM_HUB_TELEMETRY) && not defined(YUXIANG_HUB_TELEMETRY) && not defined(WFLY2_HUB_TELEMETRY) && not defined(LOLI_HUB_TELEMETRY) && not defined(MLINK_HUB_TELEMETRY) && not defined(MLINK_FW_TELEMETRY) && not defined(MT99XX_HUB_TELEMETRY) && not defined(MULTI_CONFIG_INO)
#undef TELEMETRY
#undef INVERT_TELEMETRY
#undef MULTI_TELEMETRY

View File

@@ -0,0 +1,96 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol 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.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(WL91X_CCNRF_INO)
#include "iface_xn297.h"
//#define FORCE_WL91X_ORIGINAL_ID
#define WL91X_PAYLOAD_SIZE 9
#define WL91X_RF_NUM_CHANNELS 3
#define WL91X_PACKET_PERIOD 2594
static void __attribute__((unused)) WL91X_send_packet()
{
uint8_t val;
//RF freq
XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no %= WL91X_RF_NUM_CHANNELS;
//Sticks
val = convert_channel_16b_limit(CH2,0x21,0xE0); //THR forward 00..5F, backward 80..DF
if(val < 128) val = 127 - val;
packet[0] = val - 0x80;
val = convert_channel_s8b(CH1); //ST right 00..7F, left 80..FF
packet[1] = val - 0x80;
//Trims
val = convert_channel_s8b(CH3); //ST_Trim centered=80, increment/decrement=4, right 04..7C, left 84..FC
packet[2] = val - 0x80;
packet[3] = convert_channel_16b_limit(CH4,0x00,0x70); //TH_Trim increment/decrement=3, 00..39..6F
//TX_ID
memcpy(&packet[4], rx_tx_addr, 4);
//Checksum
val = 0;
for(uint8_t i=0; i<WL91X_PAYLOAD_SIZE-1; i++)
val += packet[i];
packet[8] = val;
//Send
XN297_SetPower();
XN297_SetFreqOffset();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, WL91X_PAYLOAD_SIZE);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < WL91X_PAYLOAD_SIZE; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) WL91X_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K);
XN297_HoppingCalib(WL91X_RF_NUM_CHANNELS);
XN297_SetTXAddr((uint8_t*)"\x46\x14\x7B\x08", 4);
}
static void __attribute__((unused)) WL91X_initialize_txid()
{
#ifdef FORCE_WL91X_ORIGINAL_ID
memcpy(rx_tx_addr, (uint8_t*)"\x00\x1E\x33\x02",4);
#endif
memcpy(hopping_frequency, (uint8_t*)"\x1A\x3B\x3B",3); //26,59,59
}
uint16_t WL91X_callback()
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(WL91X_PACKET_PERIOD);
#endif
WL91X_send_packet();
return WL91X_PACKET_PERIOD;
}
void WL91X_init()
{
BIND_DONE; //No bind for this protocol
WL91X_initialize_txid();
WL91X_RF_init();
hopping_frequency_no = 0;
}
#endif

View File

@@ -71,9 +71,13 @@ static void __attribute__((unused)) XK2_send_packet()
}
//Flags
packet[5] = GET_FLAG(CH5_SW, 0x01) //Rate
| GET_FLAG(CH6_SW, 0x08) //Mode
| GET_FLAG(CH7_SW, 0x20) //Hover
| GET_FLAG(CH8_SW, 0x40); //Light
if(CH6_SW)
packet[5] |= 0x10; //Gyro off (senior mode)
else if(Channel_data[CH6] > CHANNEL_MIN_COMMAND)
packet[5] |= 0x08; //3D
//Telemetry not received=00, Telemetry received=01 but sometimes switch to 1 even if telemetry is not there...
packet[6] = 0x00;
//RXID checksum
@@ -200,7 +204,7 @@ uint16_t XK2_callback()
}
return 1000;
case XK2_DATA_PREP:
crc8=eeprom_read_byte((EE_ADDR)(XK2_EEPROM_OFFSET+RX_num));
crc8 = eeprom_read_byte((EE_ADDR)(XK2_EEPROM_OFFSET+RX_num));
debugln("R:RX_ID=%02X",crc8);
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(TX_EN);

View File

@@ -257,6 +257,7 @@
#define REALACC_NRF24L01_INO
#define SGF22_NRF24L01_INO
#define SHENQI_NRF24L01_INO
#define SHENQI2_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define V761_NRF24L01_INO
@@ -276,6 +277,7 @@
#define SLT_CCNRF_INO
#define UDIRC_CCNRF_INO
#define V911S_CCNRF_INO
#define WL91X_CCNRF_INO
#define XK_CCNRF_INO
#define XK2_CCNRF_INO
@@ -351,14 +353,16 @@
#define NCC1701_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define OMP_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define V761_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define YUXIANG_HUB_TELEMETRY
#define KAMTOM_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define FX_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define YUXIANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define PROPEL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define RLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define WFLY2_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define LOLI_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define MT99XX_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define MLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define MLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define MLINK_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by erskyTX and OpenTX
//#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, erskyTX and OpenTX
#define HITEC_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX
@@ -697,6 +701,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FX620
FX9630
Q560
QF012
PROTO_FY326
FY326
FY319
@@ -777,8 +782,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_MLINK
NONE
PROTO_MOULDKG
MOULDKG_ANALOG
MOULDKG_DIGIT
MOULDKG_ANALOG4
MOULDKG_DIGIT4
MOULDKG_ANALOG6
PROTO_MT99XX
MT99
H7
@@ -834,6 +840,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
J20
PROTO_SHENQI
NONE
PROTO_SHENQI2
NONE
PROTO_SKYARTEC
NONE
PROTO_SLT

View File

@@ -99,7 +99,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[FrskyX2](Protocols_Details.md#FRSKYX2---64)|64|CH_16|CH_8|EU_16|EU_8|Cloned|Cloned_8|||CC2500|
[Frsky_RX](Protocols_Details.md#FRSKY_RX---55)|55|Multi|CloneTX|EraseTX|CPPM|||||CC2500|
[Futaba/SFHSS](Protocols_Details.md#Futaba---21)|21|SFHSS||||||||CC2500|
[FX](Protocols_Details.md#FX---58)|28|816|620|9630|Q560|||||NRF24L01|
[FX](Protocols_Details.md#FX---58)|28|816|620|9630|Q560|QF012||||NRF24L01|
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L
[GW008](Protocols_Details.md#GW008---32)|32|||||||||NRF24L01|XN297
@@ -115,6 +115,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[JIABAILE](Protocols_Details.md#JIABAILE---102)|102|Std|Gyro|||||||NRF24L01|XN297
[JJRC345](Protocols_Details.md#JJRC345---71)|71|JJRC345|SkyTmblr|||||||NRF24L01|XN297
[JOYSWAY](Protocols_Details.md#JOYSWAY---84)|84|||||||||NRF24L01|XN297
[KAMTOM](Protocols_Details.md#KAMTOM---104)|104|||||||||NRF24L01|XN297
[KF606](Protocols_Details.md#KF606---49)|49|KF606|MIG320|ZCZ50||||||NRF24L01|XN297
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
[Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105|
@@ -124,7 +125,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[Losi](Protocols_Details.md#Losi---89)|89|||||||||CYRF6936|
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
[MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936|
[MouldKg](Protocols_Details.md#mouldkg---90)|90|Analog|Digit|||||||NRF24L01|XN297
[MouldKg](Protocols_Details.md#mouldkg---90)|90|A4444|D4444|A664||||||NRF24L01|XN297
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805|A180|DRAGON|F949G|NRF24L01|XN297
[MT99xx2](Protocols_Details.md#MT99XX2---92)|92|PA18|SU35|||||||NRF24L01|XN297
[NCC1701](Protocols_Details.md#NCC1701---44)|44|||||||||NRF24L01|
@@ -143,6 +144,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[Scorpio](Protocols_Details.md#Scorpio---94)|94|||||||||CYRF6936|
[SGF22](Protocols_Details.md#SGF22---97)|97|F22|F22S|J20||||||NRF24L01|XN297
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
[Shenqi2](Protocols_Details.md#Shenqi2---105)|105|Shenqi2||||||||NRF24L01|XN297
[Skyartec](Protocols_Details.md#Skyartec---68)|68|||||||||CC2500|CC2500
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100|V1_4CH|RF_SIM||NRF24L01|CC2500
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
@@ -153,6 +155,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[WFLY](Protocols_Details.md#WFLY---40)|40|WFR0x||||||||CYRF6936|
[WFLY2](Protocols_Details.md#WFLY2---79)|79|RF20x||||||||A7105|
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
[WL91X](Protocols_Details.md#WL91X---106)|106|||||||||NRF24L011&CC2500|XN297
[XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297
[XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L011&CC2500|XN297
[XK2](Protocols_Details.md#XK2---99)|99|X4|P10|||||||NRF24L01&CC2500|XN297
@@ -1182,16 +1185,22 @@ If only a NRF24L01 is installed then this sub protocol might be problematic beca
## MT99XX - *17*
Autobind protocol
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS
CC2500: only YZ is supported.
CC2500: only YZ and F949G are supported.
### Sub_protocol MT99 - *0*
Models: MT99xx
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|ATrim|ETrim
### Sub_protocol H7 - *1*
Models: Eachine H7, Cheerson CX023
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|ATrim|ETrim
### Sub_protocol YZ - *2*
Model: Yi Zhan i6S
@@ -1201,63 +1210,71 @@ If a CC2500 is installed it will be used for this sub protocol. Option in this c
If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|ATrim|ETrim
### Sub_protocol LS - *3*
Models: LS114, 124, 215
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS|ATrim|ETrim
### Sub_protocol FY805 - *4*
Model: FY805
**Only 1 ID available**
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP||||HEADLESS
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP||||HEADLESS|ATrim|ETrim
### Sub_protocol A180 - *5*
Model: XK A180, A120, F949S, F959
A180:
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|E|T|R|3D6G|RATE
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|3D6G|RATE||||ATrim|ETrim
A120:
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|E|T|R|RATE|LED
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|RATE|LED||||ATrim|ETrim
F949S:
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|RATE|RXLED|3D6G
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|RATE|RXLED|3D6G|||ATrim|ETrim
### Sub_protocol DRAGON - *6*
Model: Eachine Mini Wing Dragon, Eachine Mini Cessna
Telemetry is supported: A1 = battery voltage with a Ratio of 25.5, A2=battery low flag (0=off,>0=on) and RSSI = dummy value of 100
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|E|T|R|MODE|RTH
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|RTH||||ATrim|ETrim
MODE: -100%=Beginner, 0%=Intermediate, +100%=Advanced
### Sub_protocol F949G - *7*
If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
Model: F949G
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|E|T|R|6G3D|Light
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|6G3D|Light||||ATrim|ETrim
Model: KFPLAN Z-Series like Z61 BF109, Z54 A380,...
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|-|Rate|Light|Unk1|Unk2
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R||Rate|Light|Unk1|Unk2|ATrim|ETrim
Unk1&2: long press right/left
@@ -1266,20 +1283,18 @@ Unk1&2: long press right/left
### Sub_protocol PA18 - *0*
Model: PA18 mini
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|MODE|FLIP|RTH
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|FLIP|RTH|||ATrim|ETrim
MODE: -100% beginner, 0% intermediate, +100% Expert
### Sub_protocol SU35 - *1*
Model: QF009 SU35
CH6 - LED, CH7 - LED Flash, CH8 - Invert, CH9 - Rate
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|LED|LED_FLASH|INVERT|RATE
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|LED|LED_FLASH|INVERT|RATE|ATrim|ETrim
MODE: -100% 6G, +100% 3D
@@ -1439,11 +1454,14 @@ FLIP: sets model into flip mode for approx 5 seconds at each throw of switch (re
MODE: -100% level, +100% acro
### Sub_protocol V1_4CH - *5*
Transmitters: SLT2 and SLT2 DLC, Receivers: SPMXSE2825RX, SPMXSBER1025G, SPMXSE4510RX, ...
CH1|CH2|CH3|CH4
---|---|---|---
CH1|CH2|CH3|CH4
CH4 is used for DSC settings: -35% off to +15% full
### Sub_protocol RF_SIM - *6*
Models: the SLT-dongle included in RealFlight 7.5
@@ -1481,6 +1499,14 @@ A|E|T|R|CALIB|RATE|6G_3D|6GSENIOR|LIGHT
A280 -> 6GSENIOR: -100% - 6G, +100% - Senior mode (turn off gyro), LIGHT: cycle the light through on-flash-off when the CH9 value is changed from -100% to 100%
## WL91X - *106*
Models: WLtoys WL911, WL913, WL915 and may be others...
CH1|CH2|CH3|CH4
---|---|---|---
ST|TH|ST_TR|TH_TR
## XK - *62*
CC2500: only X450 is supported.
@@ -1532,6 +1558,8 @@ The plane does not need to be bound each time if it is powered on **after** the
The rudder trim is driven from the rudder channel to increase the range (Original TX rudder has no range once the motor has been turned on...).
Mode: -100%=6G, 0%=3D, +100%=Gyro off (Senior mode)
### Sub_protocol X4 - *0*
Transmitter: XK X4-A160, X5S, model: XK A160S, XK A280, XK A300
@@ -1785,18 +1813,22 @@ FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..1
## FX - *58*
FEI XIONG
CH1|CH2|CH3|CH4
---|---|---|---
A|-|T|-
### Sub_protocol 816 - *0*
Model: FX816 P38, B17
Only 8 TX IDs available
CH1|CH2|CH3|CH4
---|---|---|---
A|-|T|-
### Sub_protocol 620 - *1*
Model: FX620 SU35
CH1|CH2|CH3|CH4
---|---|---|---
A|-|T|-
### Sub_protocol 9630 - *2*
Model: FX9630, FX9603, QIDI-550
@@ -1819,6 +1851,19 @@ FLIP is a toggle channel meaning that -100% to +100% is a command and +100% to -
Gyro: -100%=6G, 0%=3D+Gyro, +100%=3D
### Sub_protocol QF012 - *4*
Model: QF012 SBD Dauntless
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
A|E|T|R|FLIP|GYRO|Invert|Reset
FLIP is a toggle channel meaning that -100% to +100% is a command and +100% to -100% is also a command
Gyro: -100%=6G, 0%=3D+Gyro, +100%=3D
Reset: Restore fine tunning midpoint
## FY326 - *20*
### Sub_protocol FY326 - *0*
@@ -1982,13 +2027,13 @@ Model: DF-Models SkyTumbler
RTH not supported
## KAMTOM - *104*
Models: KAMTOM KM24xx (KM32xx?), Pinecone SG-24xx
Models: KAMTOM RC Racing KM24xx (KM32xx?), Pinecone SG-24xx
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
ST|TH|UNK1|UNK2|ST_TR|TH_TR|TH_DR
Low batt telemetry is not yet added.
Low battery telemetry in A1 with 0 = low batt
## KYOSHO2 - *93*
Model: TX KT-17, Minium Edge 540, Minium Citabria
@@ -2026,6 +2071,9 @@ CH16| CH8 | -100% | 0% | - | - | -
## MouldKg - *90*
Mould King 2.4GHz TX: Technic Brick models
### Sub_protocol A4444 - *0*
Model: 4 analog ports brick
Up to 4 bricks can be controlled at the same time.
Option field | Value
@@ -2041,17 +2089,52 @@ To associate a brick to a RX number (RX_num above), set this RX number under the
Example: I want to control 2 bricks. I select RX number 1, set option to 1 and launch a bind on the first brick. I select RX number 2, set option to 1 and launch a bind on the second brick. Now to control both bricks I set RX number to 1 and option to 2. Therefore brick1 will react to channels CH1 to CH4 and brick2 to channel CH5 to CH8.
On another model I can control 4 other bricks, bind each brick to RX number 3 to 6 and then finaly set RX number to 3 and option to 4 to contol the 4 bricks with CH1 to CH16.
### Sub_protocol Analog - *0*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick3_A|Brick3_B|Brick3_C|Brick3_D|Brick4_A|Brick4_B|Brick4_C|Brick4_D
### Sub_protocol D4444 - *1*
Model: 4 digital ports brick
Up to 4 bricks can be controlled at the same time.
Option field | Value
-------------|------
0|The module will act like the original radio which will bind every time and attach to the first brick in bind mode
1|The module will control the brick number RX_num
2|The module will control the brick number RX_num and RX_num+1
3|The module will control the brick number RX_num, RX_num+1 and RX_num+2
4|The module will control the brick number RX_num, RX_num+1, RX_num+2 and RX_num+3
To associate a brick to a RX number (RX_num above), set this RX number under the protocol, set option to 1, launch a bind and power on the brick you want to control. Repeat this for every brick using a different RX number each time and then indicate the number of bricks to be controlled using the Option field.
Example: I want to control 2 bricks. I select RX number 1, set option to 1 and launch a bind on the first brick. I select RX number 2, set option to 1 and launch a bind on the second brick. Now to control both bricks I set RX number to 1 and option to 2. Therefore brick1 will react to channels CH1 to CH4 and brick2 to channel CH5 to CH8.
On another model I can control 4 other bricks, bind each brick to RX number 3 to 6 and then finaly set RX number to 3 and option to 4 to contol the 4 bricks with CH1 to CH16.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick3_A|Brick3_B|Brick3_C|Brick3_D|Brick4_A|Brick4_B|Brick4_C|Brick4_D
### Sub_protocol Digit - *1*
### Sub_protocol A664 - *2*
Model: 4/6 analog ports brick
Up to 3 bricks can be controlled at the same time. The bricks can be either 4 or 6 ports but only the 2 first bricks will be sent 6 channels, the last brick will only be sent 4 channels.
Option field | Value
-------------|------
0|The module will act like the original radio which will bind every time and attach to the first brick in bind mode
1|The module will control the brick number RX_num
2|The module will control the brick number RX_num and RX_num+1
3|The module will control the brick number RX_num, RX_num+1 and RX_num+2
To associate a brick to a RX number (RX_num above), set this RX number under the protocol, set option to 1, launch a bind and power on the brick you want to control. Repeat this for every brick using a different RX number each time and then indicate the number of bricks to be controlled using the Option field.
Example: I want to control 2 bricks. I select RX number 1, set option to 1 and launch a bind on the first brick. I select RX number 2, set option to 1 and launch a bind on the second brick. Now to control both bricks I set RX number to 1 and option to 2. Therefore brick1 will react to channels CH1 to CH4 and brick2 to channel CH5 to CH8.
On another model I can control 3 other bricks, bind each brick to RX number 3 to 5 and then finaly set RX number to 3 and option to 3 to contol the 4 bricks with CH1 to CH16.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick3_A|Brick3_B|Brick3_C|Brick3_D|Brick4_A|Brick4_B|Brick4_C|Brick4_D
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick1_E|Brick1_F|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick2_E|Brick2_F|Brick3_A|Brick3_B|Brick3_C|Brick3_D
## NCC1701 - *44*
Model: Air Hogs Star Trek USS Enterprise NCC-1701-A
@@ -2160,6 +2243,15 @@ CH1|CH2|CH3|CH4
Throttle +100%=full forward,0%=stop,-100%=full backward.
## Shenqi2 - *105*
Autobind protocol
Model: Shenqiwei 1/20 Mini Motorcycle
CH1|CH2
---|---
ST|TH
## Symax - *10*
Autobind protocol