New XK2/P10 sub protocol

This commit is contained in:
pascallanger 2025-02-09 12:01:28 +01:00
parent 2f520f2e91
commit 565aaed0c7
7 changed files with 103 additions and 16 deletions

View File

@ -195,6 +195,7 @@
62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light 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 62,2,XK,Cars,0,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
99,0,XK2,X4,0,Rate,Mode,Hover,Light 99,0,XK2,X4,0,Rate,Mode,Hover,Light
99,1,XK2,P10,0,Rate,Mode,Hover,Light
8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess 8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess
8,1,YD717,SkyWlkr,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 8,2,YD717,Simax4,1,Flip,Light,Pict,Video,HLess

View File

@ -95,7 +95,7 @@
96,BumbleB 96,BumbleB
97,SGF22,F22,F22S,J20 97,SGF22,F22,F22S,J20
98,Kyosho3 98,Kyosho3
99,XK2 99,XK2,X4,P10
100,YuXiang 100,YuXiang
102,JIABAILE,STD,GYRO 102,JIABAILE,STD,GYRO
103,H36 103,H36

View File

@ -165,6 +165,7 @@ const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2"; const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2";
const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0"; const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0";
const char STR_SUBTYPE_XK[] = "\x04""X450""X420""Cars"; const char STR_SUBTYPE_XK[] = "\x04""X450""X420""Cars";
const char STR_SUBTYPE_XK2[] = "\x03""X4\0""P10";
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0"; const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0";
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4"; const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z"; const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
@ -512,7 +513,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_XK, STR_XK, STR_SUBTYPE_XK, 3, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback }, {PROTO_XK, STR_XK, STR_SUBTYPE_XK, 3, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
#endif #endif
#if defined(XK2_CCNRF_INO) #if defined(XK2_CCNRF_INO)
{PROTO_XK2, STR_XK2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, XK2_init, XK2_callback }, {PROTO_XK2, STR_XK2, STR_SUBTYPE_XK2, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK2_init, XK2_callback },
#endif #endif
#if defined(XN297DUMP_NRF24L01_INO) #if defined(XN297DUMP_NRF24L01_INO)
{PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 7, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback }, {PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 7, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback },

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 4 #define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 30 #define VERSION_PATCH_LEVEL 31
#define MODE_SERIAL 0 #define MODE_SERIAL 0
@ -500,6 +500,11 @@ enum JIABAILE
JIABAILE_STD = 0, JIABAILE_STD = 0,
JIABAILE_GYRO = 1, JIABAILE_GYRO = 1,
}; };
enum XK2
{
XK2_X4 = 0,
XK2_P10 = 1,
};
#define NONE 0 #define NONE 0
#define P_HIGH 1 #define P_HIGH 1

View File

@ -19,8 +19,10 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_xn297.h" #include "iface_xn297.h"
//#define FORCE_XK2_ID //#define FORCE_XK2_ID
//#define FORCE_XK2_P10_ID
#define XK2_RF_BIND_CHANNEL 71 #define XK2_RF_BIND_CHANNEL 71
#define XK2_P10_RF_BIND_CHANNEL 69
#define XK2_PAYLOAD_SIZE 9 #define XK2_PAYLOAD_SIZE 9
#define XK2_PACKET_PERIOD 4911 #define XK2_PACKET_PERIOD 4911
#define XK2_RF_NUM_CHANNELS 4 #define XK2_RF_NUM_CHANNELS 4
@ -46,7 +48,7 @@ static void __attribute__((unused)) XK2_send_packet()
//Unknown //Unknown
packet[7] = 0x00; packet[7] = 0x00;
//Checksum seed //Checksum seed
packet[8] = 0xC0; //Constant? packet[8] = 0xC0;
} }
else else
{ {
@ -74,7 +76,7 @@ static void __attribute__((unused)) XK2_send_packet()
| GET_FLAG(CH8_SW, 0x40); //Light | GET_FLAG(CH8_SW, 0x40); //Light
//Telemetry not received=00, Telemetry received=01 but sometimes switch to 1 even if telemetry is not there... //Telemetry not received=00, Telemetry received=01 but sometimes switch to 1 even if telemetry is not there...
packet[6] = 0x00; packet[6] = 0x00;
//Unknown //RXID checksum
packet[7] = crc8; //Sum RX_ID[0..2] packet[7] = crc8; //Sum RX_ID[0..2]
//Checksum seed //Checksum seed
packet[8] = num_ch; //Based on TX ID packet[8] = num_ch; //Based on TX ID
@ -82,6 +84,8 @@ static void __attribute__((unused)) XK2_send_packet()
//Checksum //Checksum
for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++) for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++)
packet[8] += packet[i]; packet[8] += packet[i];
if(sub_protocol == XK2_P10)
packet[8] += 0x10;
// Send // Send
XN297_SetFreqOffset(); XN297_SetFreqOffset();
@ -104,11 +108,22 @@ static void __attribute__((unused)) XK2_RF_init()
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", XK2_PAYLOAD_SIZE); XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", XK2_PAYLOAD_SIZE);
XN297_HoppingCalib(XK2_RF_NUM_CHANNELS); XN297_HoppingCalib(XK2_RF_NUM_CHANNELS);
XN297_RFChannel(XK2_RF_BIND_CHANNEL); XN297_RFChannel(sub_protocol==XK2_X4?XK2_RF_BIND_CHANNEL:XK2_P10_RF_BIND_CHANNEL);
} }
static void __attribute__((unused)) XK2_initialize_txid() static void __attribute__((unused)) XK2_initialize_txid()
{ {
rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num
num_ch = 0x21 + rx_tx_addr[0] - rx_tx_addr[1] + rx_tx_addr[2];
//RF frequencies for X4: 65=0x41, 69=0x45, 73=0x49, 77=0x4D
//RF frequencies for P10: 67, unknown
uint8_t start = 65;
if(sub_protocol == XK2_P10) start += 2;
for(uint8_t i=0;i<XK2_RF_NUM_CHANNELS;i++)
hopping_frequency[i] = start + i*4;
#ifdef FORCE_XK2_ID #ifdef FORCE_XK2_ID
if(rx_tx_addr[3]&1) if(rx_tx_addr[3]&1)
{//Pascal {//Pascal
@ -127,13 +142,15 @@ static void __attribute__((unused)) XK2_initialize_txid()
//hopping frequencies 65=0x41, 69=0x45, 73=0x49, 77=0x4D //hopping frequencies 65=0x41, 69=0x45, 73=0x49, 77=0x4D
} }
#endif #endif
rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num #ifdef FORCE_XK2_P10_ID
rx_tx_addr[0] = 0xE8;
rx_tx_addr[1] = 0x25;
rx_tx_addr[2] = 0x3B;
num_ch = 0x1F;
//hopping frequencies 67=0x43, =0x, =0x, =0x
#endif
rx_tx_addr[3] = rx_tx_addr[4] = 0xCC; rx_tx_addr[3] = rx_tx_addr[4] = 0xCC;
num_ch = 0x21 + rx_tx_addr[0] - rx_tx_addr[1] + rx_tx_addr[2];
for(uint8_t i=0;i<XK2_RF_NUM_CHANNELS;i++) // Are these RF frequencies always the same? It looks like yes...
hopping_frequency[i] = 65 + i*4; //65=0x41, 69=0x45, 73=0x49, 77=0x4D
debugln("ID: %02X %02X %02X %02X %02X, OFFSET: %02X, HOP: %02X %02X %02X %02X",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],rx_tx_addr[4],num_ch,hopping_frequency[0],hopping_frequency[1],hopping_frequency[2],hopping_frequency[3]); debugln("ID: %02X %02X %02X %02X %02X, OFFSET: %02X, HOP: %02X %02X %02X %02X",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],rx_tx_addr[4],num_ch,hopping_frequency[0],hopping_frequency[1],hopping_frequency[2],hopping_frequency[3]);
} }
@ -160,6 +177,8 @@ uint16_t XK2_callback()
crc8 = 0xBF; crc8 = 0xBF;
for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++) for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++)
crc8 += packet[i]; crc8 += packet[i];
if(sub_protocol == XK2_P10)
crc8 += 0x10;
if(crc8 != packet[8]) if(crc8 != packet[8])
{ {
phase = XK2_BIND1; phase = XK2_BIND1;
@ -292,8 +311,8 @@ P[5] = flags
08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0 08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0
P[6] = 00 telemetry nok P[6] = 00 telemetry nok
01 telemetry ok but sometimes switch to 1 also when telemetry is nok... 01 telemetry ok but sometimes switch to 1 also when telemetry is nok...
P[7] = 5A -> ?? RX_ID checksum ?? => sum RX_ID[0..2] P[7] = 5A -> sum RX_ID[0..2]
P[8] = sum P[0..7] + 7F P[8] = sum P[0..7] + TX_ID[0] - TX_ID[1] + TX_ID[2] + 21
Telemetry Telemetry
RX on channel: 69, Time: 3408us P: 66 4F 47 00 00 00 00 00 C8 RX on channel: 69, Time: 3408us P: 66 4F 47 00 00 00 00 00 C8
@ -313,4 +332,49 @@ RF
2477 151753 5769 2477 151753 5769
2465 155330 3577 2465 155330 3577
*/
/* P10 Piper CUB
Bind
----
Phase 1
Plane sends these packets:
250K C=69 S=Y A= CC CC CC CC CC P(9)= 9C BB CC DD 84 24 20 00 97
P[0] = 9C bind phase 1
P[1] = Dummy TX_ID
P[2] = Dummy TX_ID
P[3] = Dummy TX_ID
P[4] = RX_ID[0]
P[5] = RX_ID[1]
P[6] = RX_ID[2]
P[7] = 00
P[8] = sum P[0..7] + BF + 10
Normal
------
TX sends
C=67 -> only one channel when telemetry is working
A= E8 25 3B CC CC P(9)= 32 32 00 32 A0 40 01 C8 6E
P[0] = A 00..32..64
P[1] = E 00..32..64
P[2] = T 00..64
P[3] = R 00..32..64
P[4] = alternates 20,60,A0,E0
trims
A 01..20..3F
E 41..60..7F
R 81..A0..BF
telemetry
E0 present when the telemetry works
6g/3d
C1 few times if P[6] flag 00->08
C0 few times if P[6] = flag 08->00
P[5] = flags
01=high rate
20=hover=long_press_left
40=light -> temporary
08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0
P[6] = 00 telemetry nok
01 telemetry ok but sometimes switch to 1 also when telemetry is nok...
P[7] = C8 -> sum RX_ID[0..2]
P[8] = sum P[0..7] + TX_ID[0] - TX_ID[1] + TX_ID[2] + 21 +10
*/ */

View File

@ -873,7 +873,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
X420 X420
XK_CARS XK_CARS
PROTO_XK2 PROTO_XK2
NONE XK2_X4
XK2_P10
PROTO_YD717 PROTO_YD717
YD717 YD717
SKYWLKR SKYWLKR

View File

@ -155,7 +155,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936| [WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
[XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297 [XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297
[XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L011&CC2500|XN297 [XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L011&CC2500|XN297
[XK2](Protocols_Details.md#XK2---99)|99|X4||||||||NRF24L01&CC2500|XN297 [XK2](Protocols_Details.md#XK2---99)|99|X4|P10|||||||NRF24L01&CC2500|XN297
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01| [YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
[YuXiang](Protocols_Details.md#YuXiang---100)|100|||||||||NRF24L01|XN297 [YuXiang](Protocols_Details.md#YuXiang---100)|100|||||||||NRF24L01|XN297
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297 [ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
@ -1535,6 +1535,21 @@ 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...). 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...).
### Sub_protocol P10 - *1*
Model: Park10 J3-CUB
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.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
A|E|T|R|Rate|Mode|Hover|Light
The plane does not need to be bound each time if it is powered on **after** the radio/protocol is on.
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...).
*** ***
# NRF24L01 RF Module # NRF24L01 RF Module