Compare commits

...

15 Commits

Author SHA1 Message Date
pascallanger
699e796a01 FX/BM26: new subprotocol
Missing files
2026-07-14 22:30:14 +02:00
pascallanger
93bade15d0 FX/BM26: new subprotocol 2026-07-14 22:29:07 +02:00
pascallanger
80d08c25e0 Update Protocols_Details.md 2026-07-14 19:52:07 +02:00
pascallanger
debb17a8fc Update Protocols_Details.md 2026-07-14 19:50:43 +02:00
pascallanger
174efa332b XK2/X4: Stunt flag for the Sky Viper Vector 2026-07-14 19:46:38 +02:00
pascallanger
e5f9f8c840 Hontai/XK170: Optical flag
CH11 enable/disable flow sensor for K270
2026-07-14 19:26:55 +02:00
pascallanger
a23716269b Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2026-07-14 18:55:06 +02:00
MRC3742
bfef3364fc Fix for DSM Clone
* fix for DSM clone not working
2026-07-14 18:54:36 +02:00
pascallanger
d62f2d0555 Update Protocols_Details.md 2026-07-14 18:52:32 +02:00
pascallanger
bb59582271 Update XN297Dump_nrf24l01.ino 2026-07-14 18:46:54 +02:00
pascallanger
c6c6fa442b Update WPL_nrf24l01.ino 2026-07-14 18:46:40 +02:00
pascallanger
d95012c30b TRAXXAS: attempt to describe TQi 2026-07-14 18:46:09 +02:00
pascallanger
f71768df39 E129 saving few bytes 2026-07-14 18:44:41 +02:00
pascallanger
7bde06ff50 AFHDS2A: Fix for CROSSOVER-RX
CROSSOVER-RX are sending end of telemetry data despite having sensors after...
2026-07-14 18:44:05 +02:00
pascallanger
51a01d1393 KF606 LED
Add LED channel for KF606 boards
2026-07-14 18:42:14 +02:00
17 changed files with 268 additions and 89 deletions

View File

@@ -86,11 +86,13 @@
55,1,FrSkyRX,CloneTX,0
55,2,FrSkyRX,EraseTX,0
55,3,FrSkyRX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
58,0,FX,816,1
58,1,FX,620,1
58,0,FX,FX816,1
58,1,FX,FX620,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
58,5,FX,BM26,1,FLIP,Gyro,LEDs,LED,CALIB
58,6,FX,FX818,1
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
@@ -110,7 +112,7 @@
26,1,Hontai,JJRCX1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,2,Hontai,X5C1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,3,Hontai,FQ777_951,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,4,Hontai,XKK170,1,Rate,Emerg,TakLan,Calib,TrimA,TrimE
26,4,Hontai,XKK170,1,Rate,Emerg,TakLan,Calib,TrimA,TrimE,Optic
57,0,HoTT,Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
57,1,HoTT,No_Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
2,0,Hubsan,H107,1,Flip,Light,Pict,Video,HLess
@@ -119,7 +121,7 @@
22,0,J6Pro,Std,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
71,0,JJRC345,JJRC345,1,Flip,HLess,RTH,LED,UNK1,UNK2,UNK3
71,1,JJRC345,SkyTmblr,1,Flip,HLess,RTH,LED,UNK1,UNK2,UNK3
49,0,KF606,KF606,1,Trim
49,0,KF606,KF606,1,Trim,LED
49,1,KF606,MIG320,1,Trim,LED
49,2,KF606,ZCZ50,1,Trim,UNK
9,0,KN,WLToys,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim,Rtrim,Hover
@@ -196,8 +198,8 @@
62,0,XK,X450,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video
62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
62,2,XK,Cars,0,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
99,0,XK2,X4,0,Rate,Mode,Hover,Light
99,1,XK2,P10,0,Rate,Mode,Hover,Light
99,0,XK2,X4,0,Rate,Mode,Hover,Light,Stunt
99,1,XK2,P10,0,Rate,Mode,Hover,Light,Stunt
8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess
8,1,YD717,SkyWlkr,1,Flip,Light,Pict,Video,HLess
8,2,YD717,Simax4,1,Flip,Light,Pict,Video,HLess
@@ -235,3 +237,4 @@
104,0,KAMTOM,Std,0,ST_Tr,TH_Tr,TH_DR
105,0,Shenqi2,Std,1
106,0,WL91x,Std,0
107,0,WPL,Std,0,Light,TH_DR,ST_DR

View File

@@ -93,6 +93,9 @@ static void AFHDS2A_update_telemetry()
if (option & 0x80)
{// forward 0xAA and 0xAC telemetry to TX, skip rx and tx id to save space
packet_in[0]= TX_RSSI;
//Fix for CROSSOVER-RX,
if(packet[17+8]==0xFF && packet[21+8]==0xFC && packet[25+8]==0xFF)
packet[17+8]=0xFE; // RX_ERR_RATE needed for TX to validate the telem
#if 0
debug("T(%02X)=",packet[0]);
for(uint8_t i=9;i < AFHDS2A_RXPACKET_SIZE; i++)

View File

@@ -599,6 +599,7 @@ void DSM_init()
uint16_t temp = DSM_CLONE_EEPROM_OFFSET;
for(uint8_t i=0;i<4;i++)
cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++);
cyrfmfg_id[3]^=RX_num; //Model match
#if DEBUG_BIND
debugln("Using cloned ID");
debug("Clone ID=")
@@ -619,8 +620,7 @@ void DSM_init()
{
//SUB_PROTO_VALID;
CYRF_GetMfgData(cyrfmfg_id);
//Model match
cyrfmfg_id[3]^=RX_num;
cyrfmfg_id[3]^=RX_num; //Model match
}
}

View File

@@ -44,9 +44,8 @@ static void __attribute__((unused)) E129_build_data_packet()
packet[ 1] = 0xA6; // Set to A5 every few packets??
//Flags
if(sub_protocol == E129_E129)
packet[ 2] = 0xF7; // High rate 0xF7, low 0xF4
else //C186
packet[ 2] = 0xF7; // E129 High rate 0xF7, low 0xF4
if(sub_protocol == E129_C186)
{
packet[ 2] = 0xFA; // High rate 0xFA, medium 0xF7, low 0xF4
packet[13] = bit_reverse(rx_tx_addr[2]);

View File

@@ -42,6 +42,9 @@ Multiprotocol is distributed in the hope that it will be useful,
#define FX_QF012_PACKET_PERIOD 12194
#define FX_QF012_RX_PAYLOAD_SIZE 3
#define FX_BM26_BIND_CHANNEL 40
#define FX_BM26_PACKET_PERIOD 14066
//#define FORCE_FX620_ID
//#define FORCE_FX9630_ID
//#define FORCE_QIDI_ID
@@ -85,11 +88,17 @@ static void __attribute__((unused)) FX_send_packet()
//Channels
uint8_t val;
if (sub_protocol >= FX9630)
{ // FX9630 & FX_Q560 & FX_QF012
{ // FX9630 & FX_Q560 & FX_QF012 & FX_BM26
packet[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_8b(AILERON);
packet[2] = 0xFF - convert_channel_8b(ELEVATOR);
packet[3] = convert_channel_8b(RUDDER);
if ( sub_protocol == FX_BM26 ) // BM26 Ail, Elev, Rud range between 0x00-0x3F-0x7F
{
packet[1] >>= 1;
packet[2] >>= 1;
packet[3] >>= 1;
}
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
@@ -99,10 +108,21 @@ static void __attribute__((unused)) FX_send_packet()
// 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
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
packet[5] |= GET_FLAG(CH7_SW, 0x40) // QF012 invert flight
| GET_FLAG(CH8_SW, 0x80); // QF012 Restore fine tunning midpoint
else if ( sub_protocol == FX_BM26 )
{
packet[5] &= 0xC0;
packet[5] += 0x40;
// BM26 P51=>0:beginner(6G), 1:mid(3D), 2:expert(Gyro off)
packet[5] |= (Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x08 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x0C : 0x0A));
packet[6] = GET_FLAG( CH5_SW, 0x20) // 6G Roll
| GET_FLAG(!CH7_SW, 0x08) // Light control switch, default on
| GET_FLAG(!CH8_SW, 0x10) // Turn signal switch, default on
| GET_FLAG( CH9_SW, 0x01); // Gyro Calibration
}
}
else // FX816 & FX620
{
@@ -142,7 +162,7 @@ static void __attribute__((unused)) FX_send_packet()
packet[5] = 0xAB; // Is it based on ID??
}
}
else // FX9630 & FX_Q560 & FX_QF012
else // FX9630 & FX_Q560 & FX_QF012 & FX_BM26
{
if(IS_BIND_IN_PROGRESS)
{
@@ -164,6 +184,8 @@ static void __attribute__((unused)) FX_send_packet()
val = val ^ 0xFF;
packet[last_packet_idx]=val;
if ( IS_BIND_IN_PROGRESS && sub_protocol == FX_BM26 ) packet[7] = packet[6];
//Debug
#if 0
for(uint8_t i=0;i<packet_length;i++)
@@ -194,6 +216,13 @@ static void __attribute__((unused)) FX_RF_init()
packet_period = FX620_BIND_PACKET_PERIOD;
packet_length = FX620_PAYLOAD_SIZE;
}
else if (sub_protocol == FX_BM26)
{
XN297_SetTXAddr((uint8_t *)"\x12\x34\x10\x10", 4);
XN297_RFChannel(FX_BM26_BIND_CHANNEL);
packet_period = FX_BM26_PACKET_PERIOD;
packet_length = FX9630_PAYLOAD_SIZE;
}
else // FX9630 & FX_Q560 & FX_QF012
{
XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4);
@@ -226,10 +255,10 @@ 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 & FX_QF012
else // FX9630 & FX_Q560 & FX_QF012 & FX_BM26
{
//??? Need to find out how the first RF channel is calculated ???
hopping_frequency[0] = 0x13;
hopping_frequency[0] = sub_protocol == FX_BM26? 0x0C : 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;
@@ -245,6 +274,7 @@ 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
// BM26 rx_tx_addr: "\x17\x03\x00\x00", hopping_frequency: 0x0C,0x30,0x43(12,48,67)
}
}
@@ -288,9 +318,11 @@ uint16_t FX_callback()
debug("RX");
if(XN297_ReadPayload(packet_in, FX_QF012_RX_PAYLOAD_SIZE))
{//Good CRC
//packets: A5 00 11 -> A5 01 11
telemetry_link = 1;
v_lipo1 = packet_in[1] ? 60:81; // low voltage 3.7V
if ( sub_protocol == FX_BM26 )
v_lipo1 = packet_in[0] < packet_in[2] ? 60:81; // packets: AA 00 55 -> 55 00 AA = low voltage 3.7V
else
v_lipo1 = packet_in[1] ? 60:81; // packets: A5 00 11 -> A5 01 11 = low voltage 3.7V
#if 0
for(uint8_t i=0; i < FX_QF012_RX_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);

View File

@@ -78,7 +78,8 @@ static void __attribute__((unused)) HONTAI_send_packet()
packet[i+3] = convert_channel_16b_limit(CH_TAER[i],0x28,0xD8);
packet[6] ^= 0xFF; //Reverse rudder
//flags
packet[1] = GET_FLAG(CH8_SW, 0x04); //Gyro calibration (momentary)
packet[1] = GET_FLAG(CH8_SW, 0x04) //Gyro calibration (momentary)
|GET_FLAG(CH11_SW, 0x10); //XK K270 optical flow switch
// |GET_FLAG(CH_SW, 0x08) //Unk long press second top right button (momentary)
// |GET_FLAG(CH_SW, 0x10) //Unk short press second top right button (toggle)
// |GET_FLAG(CH_SW, 0x40) //Unk short press second top left button (momentary)

View File

@@ -48,32 +48,19 @@ static void __attribute__((unused)) KF606_send_packet()
hopping_frequency_no ^= 1; // 2 RF channels
packet[0] = 0x55;
packet[1] = convert_channel_8b(THROTTLE); // 0..255
if(sub_protocol == KF606_ZCZ50) len--;
packet[len-3] = convert_channel_8b(THROTTLE); // 0..255
// Deadband is needed on aileron, 40 gives +-6%
switch(sub_protocol)
{
case KF606_KF606:
packet[2] = convert_channel_8b_limit_deadband(AILERON,0x20,0x80,0xE0,40); // Aileron: Max values:20..80..E0, Low rates:50..80..AF, High rates:3E..80..C1
packet[3] = convert_channel_16b_limit(CH5,0xC1,0xDF); // Aileron trim must be on a separated channel C1..D0..DF
break;
case KF606_MIG320:
packet[2] = convert_channel_8b_limit_deadband(AILERON,0x00,0x80,0xFF,40); // Aileron: High rate:2B..80..DA
packet[3] = convert_channel_16b_limit(CH5,0x01,0x1F); // Aileron trim must be on a separated channel 01..10..1F
packet[3] += (packet[2]-0x80)>>3; // Drive trims for more aileron authority
if(packet[3] > 0x80)
packet[3] = 0x01;
else if(packet[3] > 0x1F)
packet[3] = 0x1F;
packet[3] |= GET_FLAG(CH6_SW, 0xC0); // 0xC0 and 0xE0 are both turning the LED off, not sure if there is another hidden feature
break;
case KF606_ZCZ50:
len--; // uses only 3 bytes of payload
packet[0] = packet[1]; // Throttle: 0x00..0xFF
packet[1] = convert_channel_8b_limit_deadband(AILERON,0x20,0x80,0xE0,40); // Aileron: Max values:20..80..E0, low rate 0x52..0x80..0xB1, high rate: 0x41..0x80..0xC3.
packet[2] = convert_channel_16b_limit(CH5,0x01,0x1F); // Trim: 0x01..0x10..0x1F
packet[2] |= GET_FLAG(CH6_SW, 0xC0); // Unknown: 0x00 or 0xC0. Left top switch on original TX changes nothing on my plane. Maybe ON/OFF for main motor?
break;
}
packet[len-2] = convert_channel_8b_limit_deadband(AILERON,0x00,0x80,0xFF,40); // Aileron: High rate:2B..80..DA
uint8_t p3;
p3 = convert_channel_8b(CH5)>>3; // Aileron trim must be on a separated channel 01..10..1F
p3 += (packet[2]-0x80)>>3; // Drive trims for more aileron authority
if(p3 > 0x80)
p3 = 0x01;
else if(p3 > 0x1F)
p3 = 0x1F;
p3 |= GET_FLAG(CH6_SW, 0xC0); // 0xC0 and 0xE0 are both turning the LED off, not sure if there is another hidden feature
packet[len-1] = p3;
}
if(sub_protocol == KF606_MIG320)

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,QF012
58,FX,FX816,FX620,9630,Q560,QF012,BM26,FX818
59,Bayang_RX,Multi,CPPM
60,Pelikan,Pro,Lite,SCX24
61,EazyRC
@@ -102,3 +102,4 @@
104,KAMTOM
105,Shenqi2
106,WL91x
107,WPL

View File

@@ -188,7 +188,7 @@ const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
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[] = "\x05""816\0 ""620\0 ""9630\0""Q560\0""QF012";
const char STR_SUBTYPE_FX[] = "\x05""FX816""FX620""9630\0""Q560\0""QF012""BM26\0""FX818";
const char STR_SUBTYPE_SGF22[] = "\x04""F22\0""F22S""J20\0""CX10";
const char STR_SUBTYPE_JIABAILE[] = "\x04""Std\0""Gyro";
#define NO_SUBTYPE nullptr
@@ -345,7 +345,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, 5, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 7, 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 },

View File

@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 52
#define VERSION_PATCH_LEVEL 55
#define MODE_SERIAL 0
@@ -493,6 +493,8 @@ enum FX
FX9630 = 2,
FX_Q560 = 3,
FX_QF012 = 4,
FX_BM26 = 5,
FX818 = 6,
};
enum SGF22
{

View File

@@ -404,7 +404,7 @@ RX: 0x02 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0
TX: 0x02 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x00 0x00 0x01 0x01 0x06 0x05 0x00 0x00
Notes:
- RX cyrfmfg_id is 0x4A,0xA3,0x2D,0x1A,0x49,0xFE and TX cyrfmfg_id is 0x65,0xE2,0x5E,0x55,0x4D,0xFE
- P[7] changes from 0x06 to 0xEE but not needed to complete the bind -> doesn't care??
- P[7] = RX SOP code index, changes from 0x06 to 0xEE but not needed to complete the bind -> doesn't care??
- P[8] RF channel - 1 (on packets type 0x03)
- P[9] 0x00 unchanged??
- P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]??
@@ -474,4 +474,123 @@ Traxxas TQ 1st generation
-------------------------
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues/967#issuecomment-2079038576
*/
/*
Traxxas TQi
-------------------------
Unknown 3 first packets:
CHANNEL: 0x2B
SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91
CRC_SEED_LSB: 0x5A
CRC_SEED_MSB: 0x5A
RX: 0xA0 0x1F 0x60 0x58 0x34 0x44 0x1C 0x11 0xA5 0x72 0x8D 0x9D 0xEA 0x49 0x2B 0xE2
RX: 0xD3 0x53 0xD4 0x45 0x1B 0x6F 0x75 0x42 0xEF 0x8A 0xD2 0x24 0x8E 0xF0 0x05 0x6C
RX: 0xAA 0xD7 0xD7 0x43 0x0F 0x2F 0x02 0x8F 0x06 0x54 0x3A 0x35 0xF5 0xCF 0x0F 0x82
Packets 0x02: Bind learn TX/RX addresses same as TQ 2nd:
CHANNEL: 0x2B
SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91
CRC_SEED_LSB: 0x5A
CRC_SEED_MSB: 0x5A
RX: 0x02 0x5B 0xE9 0x7E 0x14 0xF1 0xFE 0x0D 0x00 0x00 0x02 0x02 0x00 0x26 0x00 0x00
TX: 0x02 0xE0 0xAC 0x7F 0x14 0xF1 0xFE 0x00 0x00 0x00 0x01 0x02 0x00 0x51 0x00 0x00
Notes:
- P[1..6] = RX cyrfmfg_id is 0x5B,0xE9,0x7E,0x14,0xF1,0xFE and TX cyrfmfg_id is 0xE0,0xAC,0x7F,0x14,0xF1,0xFE
- P[7] RX SOP code index, changes from 0x0D to 0x00 (but not needed to complete the bind -> doesn't care??)
- P[8] RF channel - 1 (on packets type 0x03)
- P[9] 0x00 unchanged??
- P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]??
- P[11] unchanged ?? (-> no bind if set to 0x00 or 0x81)
- P[12] unchanged ?? (-> no bind if set to 0x05 or 0x86)
- P[13] changes from 0x26 to 0x51 (but not needed to complete the bind -> doesn't care??)
- P[14..15]=0x00 unchanged??
Next steps:
Packets 0x08: ???
TX: 0x08 0x00 0x03 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00
TX: 0x08 0x00 0x02 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00
TX: 0x08 0x00 0x01 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00
RX: 0x08 0x00 0x03 0x14 0xFD 0x24 0x20 0xB8 0xCA 0x48 0x76 0x4E 0x00 0x26 0x00 0x00
RX: 0x08 0x00 0x01 0x14 0xFD 0x24 0x20 0xB8 0xCA 0x48 0x76 0x4E 0x00 0x26 0x00 0x00
P[1] index
P[2] sequence number
Packets 0x09: ???
TX: 0x09 0x00 0x03 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4
TX: 0x09 0x00 0x02 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4
TX: 0x09 0x00 0x01 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4
TX: 0x09 0x01 0x03 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
TX: 0x09 0x01 0x02 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
TX: 0x09 0x01 0x01 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
TX: 0x09 0x02 0x03 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
TX: 0x09 0x02 0x02 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
TX: 0x09 0x02 0x01 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E
RX: 0x09 0x00 0x03 0x90 0x24 0x93 0x08 0x41 0xC7 0x7F 0x59 0xB4 0xE3 0x25 0x77 0xB5
RX: 0x09 0x00 0x01 0x90 0x24 0x93 0x08 0x41 0xC7 0x7F 0x59 0xB4 0xE3 0x25 0x77 0xB5
RX: 0x09 0x01 0x02 0x88 0xFA 0x4D 0xFB 0x33 0xD4 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6
RX: 0x09 0x02 0x03 0x86 0xAF 0xD0 0x91 0xF6 0xDD 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6
RX: 0x09 0x02 0x01 0x86 0xAF 0xD0 0x91 0xF6 0xDD 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6
P[1] index
P[2] sequence number
Switch to normal mode:
SOP_CODE: 0xD2 0x8F 0xB1 0x2A 0xEF 0x64 0xB0 0x2A
CRC_SEED_LSB: 0x85
CRC_SEED_MSB: 0xC3
CHANNEL: 0x05
TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E
Normal content except P[14]&P[15] = 0x67&0x3E from previous packet sent
SOP_CODE: 0x97 0xE5 0x14 0x72 0x7F 0x1A 0x14 0x72
CRC_SEED_LSB: 0xA5
CRC_SEED_MSB: 0xA5
CHANNEL: 0x22
RX: 0x04 0x5B 0xE9 0x7E 0x14 0xF1 0xFE 0x0D 0xDD 0xFE 0x02 0x02 0x00 0x26 0x7A 0xE6
RX packets 0x04: RX identity ?
P[1..6] = RX cyrfmfg_id 0x5B,0xE9,0x7E,0x14,0xF1,0xFE
P[7] = SOP index
P[8] = unknown
P[9] = unknown
P[10] = same value as bind 0x02
P[11] = same value as bind 0x02
P[12] = same value as bind 0x00
P[13] = same value as bind 0x26
P[14] = unknown
P[15] = unknown
SOP_CODE: 0xD2 0x8F 0xB1 0x2A 0xEF 0x64 0xB0 0x2A
CRC_SEED_LSB: 0x85
CRC_SEED_MSB: 0xC3
CHANNEL: 0x05
TX: 0x14 0x00 0x03 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E
TX: 0x14 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E
TX: 0x14 0x00 0x01 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E
RX: 0x14 0x00 0x03 0x22 0xEC 0x42 0x9B 0xD7 0x99 0x3B 0xBB 0x85 0x17 0x41 0x67 0xA0
RX: 0x14 0x00 0x01 0x22 0xEC 0x42 0x9B 0xD7 0x99 0x3B 0xBB 0x85 0x17 0x41 0x67 0xA0
RX: 0x14 0x01 0x02 0x22 0xEF 0x42 0x9C 0xCA 0xFB 0x39 0xBB 0x85 0x17 0x41 0x67 0xA0
TX packets 0x14 same as packets 0x01 with a sequence number on P[2]
RX packets 0x14 unknown content
Packets 0x01 & 0x07: normal and telemetry request/answer
TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
RX: 0x07 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0
TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
RX: 0x07 0x01 0x00 0x00 0x00 0x11 0x49 0xC8 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0
TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00
RX: 0x07 0x01 0x00 0x00 0x00 0x12 0xDC 0x20 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0
TX packets 0x07: request for telemetry
RX packets 0x07: unknown
CRC calc same as TQ 2nd:
TX ID: 0xE0,0xAC,0x7F,0x14,0xF1,0xFE
RX ID: 0x5B,0xE9,0x7E,0x14,0xF1,0xFE CRC 0x85 0xC3 => CRC: E0-5B=85 AC-E9=C3
SOP index same as TQ 2nd:
SOP index=0x0D, SOP code= 0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A
*/
#endif

View File

@@ -887,7 +887,7 @@ void TelemetryUpdate()
t += TXBUFFER_SIZE - h ;
else
t -= h ;
if ( t < 32 )
if ( t < 48 ) //32 )
{
debugln("TEL_BUF_FULL %d",t);
return ;

View File

@@ -131,7 +131,7 @@ P[3..7] = Normal address
P[8] = 00 ??
P[9] = 08 ?? not bound?, Throttle and Steering rate low, Headlights on
P[10..14] = 00 ??
P[15] = sum(P[0..14])+66 why 66...
P[15] = sum(P[0..14])+66 why 66? 66=(94+16)^CC...
Normal packet
-----------
@@ -154,5 +154,5 @@ P[9] = 80 ?? bound?, Throttle and Steering rate low, Headlights off
|04 -> Throttle rate high
|08 -> Headlights on
P[10..14] = 00 ??
P[15] = sum(P[0..14])+66 why 66...
P[15] = sum(P[0..14])+66 why 66? 66=(94+16)^CC...
*/

View File

@@ -86,7 +86,8 @@ static void __attribute__((unused)) XK2_send_packet()
packet[5] |= 0x10; //Gyro off (senior mode)
else if(Channel_data[CH6] > CHANNEL_MIN_COMMAND)
packet[5] |= 0x08; //3D
//Requiest telemetry flag
packet[5] |= GET_FLAG(CH9_SW, 0x04); //Sky Viper Vector stunt flag
//Request telemetry flag
packet[6] = 0x01;
//RXID checksum
packet[7] = crc8; //Sum RX_ID[0..2]

View File

@@ -22,7 +22,9 @@
#include "iface_xn297.h"
// Parameters which can be modified
#define XN297DUMP_PERIOD_SCAN 50000 // 25000
#define XN297DUMP_PERIOD_FAST_SCAN 50000 // 50000
#define XN297DUMP_PERIOD_SLOW_SCAN 100000 // 75000
#define XN297DUMP_MAX_PACKET 50 // 20
#define XN297DUMP_MAX_RF_CHANNEL 84 // Default 84
// Do not touch from there
@@ -38,6 +40,7 @@ boolean ack;
uint8_t pid;
uint8_t bitrate;
uint8_t old_option;
uint32_t scan_counter;
static void __attribute__((unused)) XN297Dump_RF_init()
{
@@ -195,10 +198,10 @@ static uint16_t XN297Dump_callback()
{
if(sub_protocol<XN297DUMP_AUTO)
{
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
if(option==0xFF && scan_counter>XN297DUMP_PERIOD_SLOW_SCAN)
{ // Scan frequencies
hopping_frequency_no++;
bind_counter=0;
scan_counter=0;
}
if(hopping_frequency_no!=rf_ch_num)
{ // Channel has changed
@@ -294,10 +297,10 @@ static uint16_t XN297Dump_callback()
phase++;
break;
case 1:
if(bind_counter>XN297DUMP_PERIOD_SCAN)
if(scan_counter>XN297DUMP_PERIOD_FAST_SCAN)
{ // Scan frequencies
hopping_frequency_no++;
bind_counter=0;
scan_counter=0;
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
{
hopping_frequency_no=0;
@@ -367,7 +370,7 @@ static uint16_t XN297Dump_callback()
debugln("\r\n--------------------------------");
phase=2;
debugln("Identifying all RF channels in use.");
bind_counter=0;
scan_counter=0;
hopping_frequency_no=0;
rf_ch_num=0;
packet_count=0;
@@ -389,11 +392,11 @@ static uint16_t XN297Dump_callback()
}
break;
case 2:
if(bind_counter>XN297DUMP_PERIOD_SCAN)
if(scan_counter>XN297DUMP_PERIOD_SLOW_SCAN)
{ // Scan frequencies
hopping_frequency_no++;
bind_counter=0;
if(packet_count && packet_count<=20)
scan_counter=0;
if(packet_count && packet_count<=XN297DUMP_MAX_PACKET)
debug("\r\nTrying RF channel: ");
packet_count=0;
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
@@ -438,7 +441,7 @@ static uint16_t XN297Dump_callback()
hopping_frequency_no=0;
phase=3;
packet_count=0;
bind_counter=0;
scan_counter=0;
debugln("Time between CH:%d and CH:%d",hopping_frequency[compare_channel],hopping_frequency[hopping_frequency_no]);
time_rf[hopping_frequency_no]=0xFFFFFFFF;
XN297_RFChannel(hopping_frequency[compare_channel]);
@@ -495,9 +498,9 @@ static uint16_t XN297Dump_callback()
debug(" %02X",packet[i]);
packet_count++;
nbr_rf[rf_ch_num-1]=packet_count;
if(packet_count>20)
if(packet_count>XN297DUMP_MAX_PACKET)
{//change channel
bind_counter=XN297DUMP_PERIOD_SCAN+1;
scan_counter=XN297DUMP_PERIOD_SLOW_SCAN+1;
debug("\r\nTrying RF channel: ");
}
}
@@ -509,10 +512,10 @@ static uint16_t XN297Dump_callback()
XN297Dump_overflow();
break;
case 3:
if(bind_counter>XN297DUMP_PERIOD_SCAN)
if(scan_counter>XN297DUMP_PERIOD_SLOW_SCAN)
{ // Scan frequencies
hopping_frequency_no++;
bind_counter=0;
scan_counter=0;
if(hopping_frequency_no>=rf_ch_num)
{
uint8_t next=0;
@@ -596,7 +599,7 @@ static uint16_t XN297Dump_callback()
packet_count++;
if(packet_count>24)
{
bind_counter=XN297DUMP_PERIOD_SCAN+1;
scan_counter=XN297DUMP_PERIOD_SLOW_SCAN+1;
packet_count=0;
}
}
@@ -941,7 +944,7 @@ static uint16_t XN297Dump_callback()
}
}
}
bind_counter++;
scan_counter++;
if(IS_RX_FLAG_on) // Let the radio update the protocol
{
if(Update_All()) return 10000; // New protocol selected
@@ -967,7 +970,7 @@ void XN297Dump_init(void)
if(address_length<3||address_length>5)
address_length=5; //default
XN297Dump_RF_init();
bind_counter=0;
scan_counter=0;
rf_ch_num=0xFF;
prev_option=option^0x55;
phase=0; // init

View File

@@ -697,8 +697,10 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FX816
FX620
FX9630
Q560
QF012
FX_Q560
FX_QF012
FX_BM26
FX818
PROTO_FY326
FY326
FY319

View File

@@ -99,7 +99,7 @@ CFlie|AIR|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|QF012||||NRF24L01|
[FX](Protocols_Details.md#FX---58)||58|FX816|FX620|9630|Q560|QF012|BM26|FX818||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
@@ -1144,9 +1144,9 @@ New generation of GD models
### Sub_protocol KF606 - *0*
Model: KF606
CH1|CH2|CH3|CH4|CH5
---|---|---|---|---
A||T||TRIM
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A||T||TRIM|LED
### Sub_protocol MIG320 - *1*
Model: Zhiyang MIG-320
@@ -1574,21 +1574,25 @@ 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
---|---|---|---|---|---|---|---
A|E|T|R|Rate|Mode|Hover|Light
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|Rate|Mode|Hover|Light|Stunt
The plane does not need to be bound each time if it is powered on **after** the radio/protocol is on.
Telemetry is supported. The plane sends a battery status of good->empty which is visible in A1 (good=8.4V->empty=7.1V) and RSSI gets a dummy value of 100.
Telemetry is supported. The plane sends a battery status of good->empty which is visible in A1 (good=8.4V->empty=7.1V) and RSSI gets a dummy value of 100. For the Sky Viper Vector, the battery telemetry will still appear in A1 with good=8.4V->empty=7.1V despite being a 1S plane with a switch good/bad in reality at 3.3V.
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)
Stunt: Sky Viper Vector
### Sub_protocol X4 - *0*
Transmitter: XK X4-A160, X5S, model: XK A160S, XK A280, XK A300
Model: Sky Viper Vector
### Sub_protocol P10 - *1*
Model: Park10 J3-CUB
@@ -1839,7 +1843,7 @@ FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..1
## FX - *58*
FEI XIONG
### Sub_protocol 816 - *0*
### Sub_protocol FX816 - *0*
Model: FX816 P38, B17
Only 8 TX IDs available
@@ -1848,7 +1852,7 @@ CH1|CH2|CH3|CH4
---|---|---|---
A|-|T|-
### Sub_protocol 620 - *1*
### Sub_protocol FX620 - *1*
Model: FX620 SU35
CH1|CH2|CH3|CH4
@@ -1890,6 +1894,26 @@ Gyro: -100%=6G, 0%=3D+Gyro, +100%=3D
Reset: Restore fine tunning midpoint
### Sub_protocol BM26 - *5*
Model: BM26 P51
Telemetry supported. The plane sends a battery status of good->empty which is visible in A1 (good=4.2V->empty=3.1V) and RSSI gets a dummy value of 100.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|FLIP|GYRO|LEDs|Turning Light switch|Calib
Gyro: -100%=6G, 0%=3D+Gyro, +100%=3D
### Sub_protocol FX818 - *6*
Model: FX818/FX820/FX822/FX823
Telemetry supported. The plane sends a battery status of good->empty which is visible in A1 (good=4.2V->empty=3.1V) and RSSI gets a dummy value of 100.
CH1|CH2|CH3|CH4
---|---|---|---
A|-|T|-
## FY326 - *20*
### Sub_protocol FY326 - *0*
@@ -2003,14 +2027,16 @@ ARM|
### Sub_protocol XKK170 - *3*
Model: XK K170 UH-60L Black hawk
Model: XK K170 UH-60L Black hawk, XK K270 UH-60L
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|---
A|E|T|R|RATE|EMERGENCY|TAKE_OFF/LANDING|CALIB|TrimA|TrimE
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|RATE|EMERGENCY|TAKE_OFF/LANDING|CALIB|TrimA|TrimE|Optical
RATE: -100% Low, 0% Mid, +100% High
Optic: enable/disable the optical flow sensor for K270
## JIABAILE - *102*
### Sub_protocol Std - *0*