Compare commits

...

49 Commits

Author SHA1 Message Date
pascallanger
54ae77ed7f FX/Q560 new sub protocol 2024-05-17 11:01:54 +02:00
pascallanger
2bdbd7088c Traxxas TQ 1st gen: try 5 2024-05-04 11:36:14 +02:00
pascallanger
1d3ed78622 J6Pro update 2024-05-04 11:34:59 +02:00
pascallanger
79b1c54007 Traxxas TQ 1st gen: try 4 2024-05-03 00:15:03 +02:00
pascallanger
81eb5dc6bc Traxxas TQ 1st gen: try 2 2024-04-29 19:43:24 +02:00
pascallanger
85a0e4bde8 Traxxas TQ 1st gen: try 2 2024-04-27 11:23:19 +02:00
pascallanger
63dfa316e8 Traxxas TQ 1st gen: try 1 2024-04-26 19:25:23 +02:00
pascallanger
9d383432a5 Update SGF22_nrf24l01.ino 2024-04-24 07:00:44 +02:00
pascallanger
6b181db629 SLT try 1e 2024-04-18 10:40:37 +02:00
pascallanger
873279dbe9 SLT new sub_protocol V1_4CH 2024-04-15 14:13:37 +02:00
pascallanger
f35be2984a SLT try 1d 2024-04-14 13:29:28 +02:00
pascallanger
7ddeb31e95 SLT try 1c 2024-04-14 13:23:50 +02:00
pascallanger
7444c44b48 SLT try 1b 2024-04-13 10:22:39 +02:00
pascallanger
08d1dcbed2 SLT try 1a 2024-04-12 18:24:50 +02:00
pascallanger
3e4f4e36c1 SLT try 1 2024-04-12 18:20:01 +02:00
pascallanger
902419dd3d Update Protocols_Details.md 2024-04-08 18:36:42 +02:00
pascallanger
038b3b9225 Update Protocols_Details.md 2024-04-04 17:13:35 +02:00
pascallanger
45f0154f4b Update Protocols_Details.md 2024-04-04 16:15:27 +02:00
pascallanger
e03864e35f Traxxas TQ 6 channels 2024-04-04 16:13:35 +02:00
pascallanger
de35ee09f5 Realacc doc update 2024-04-02 16:42:19 +02:00
pascallanger
c88952c35e REALACC: IDs
Any ID
2024-04-02 12:34:04 +02:00
pascallanger
ffae7dda1d Update SGF22_nrf24l01.ino 2024-03-29 16:24:25 +01:00
pascallanger
4f17f76b39 SGF22: new flag 2024-03-29 16:19:20 +01:00
pascallanger
31ef090508 ASF try 4 2024-03-29 15:55:54 +01:00
pascallanger
04d4e39b87 Update _Config.h 2024-03-27 19:34:28 +01:00
pascallanger
b3537ea75a DSM2_SFC try 3 2024-03-26 16:18:34 +01:00
pascallanger
bccc050165 DSM2_SFC try 2 2024-03-26 14:41:19 +01:00
pascallanger
0f0df176de DSM2_SFC try 1
Servo refresh rate -> frame rate 16.5/11ms
2024-03-26 14:37:26 +01:00
pascallanger
5542e7005d ASF try 3 2024-03-26 11:43:42 +01:00
pascallanger
eb35fefd3e ASF try 2 2024-03-25 15:17:51 +01:00
pascallanger
5acc3a8d01 CYRF6936: Findbestchannels flag addition 2024-03-25 15:11:31 +01:00
pascallanger
9e9c3958c6 ASF: try 1 2024-03-23 11:23:42 +01:00
pascallanger
7f3a93ca4c Kyosho3: increase bind time to 2.5s 2024-03-22 18:24:31 +01:00
pascallanger
debc9de11a New protocol Kyosho3/ASF
Only 1 ID and 1 frequency for now
2024-03-22 18:17:21 +01:00
pascallanger
f117105124 SGF22: Fix none working IDs 2024-03-21 16:33:16 +01:00
pascallanger
2e3520acad DSM2SFC timing update 2024-03-19 20:52:50 +01:00
pascallanger
91af921d98 Update Protocols_Details.md 2024-03-19 15:47:56 +01:00
pascallanger
ab45ec6d1c Update Validate.h 2024-03-19 15:44:29 +01:00
pascallanger
26b0b6bd20 Update DSM_cyrf6936.ino 2024-03-19 15:44:21 +01:00
pascallanger
1b9ce32e89 Update DSM_cyrf6936.ino 2024-03-19 14:11:40 +01:00
pascallanger
332e55831c Update Protocols_Details.md 2024-03-18 17:11:23 +01:00
pascallanger
7051438e5d Update Protocols_Details.md 2024-03-18 17:00:40 +01:00
pascallanger
28467fac57 DSM/DSM2SFC new subprotocol 2024-03-18 16:57:54 +01:00
pascallanger
c7513abad8 Update Multiprotocol.h 2024-03-18 09:02:55 +01:00
pascallanger
e6e13c0fdd Docs update 2024-03-17 15:52:42 +01:00
pascallanger
9579a667fc Update REALACC_nrf24l01.ino 2024-03-17 15:28:33 +01:00
pascallanger
cbedda2471 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2024-03-14 20:23:04 +01:00
pascallanger
f8695befe2 REALACC multi IDs 2024-03-14 20:23:02 +01:00
pascallanger
e951e3146b Update Protocols_Details.md (#955) 2024-03-14 20:22:00 +01:00
22 changed files with 732 additions and 283 deletions

View File

@@ -35,6 +35,7 @@
6,3,DSM,X_2F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill 6,3,DSM,X_2F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
6,4,DSM,AUTO,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill 6,4,DSM,AUTO,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
6,5,DSM,R_1F,0,AUX3,AUX4,AUX5 6,5,DSM,R_1F,0,AUX3,AUX4,AUX5
6,6,DSM,2SFC,0
70,0,DSM_RX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12 70,0,DSM_RX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12 70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
45,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH 45,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH
@@ -89,6 +90,7 @@
58,0,FX,816,1 58,0,FX,816,1
58,1,FX,620,1 58,1,FX,620,1
58,2,FX,9630,1,Rate,Gyro,TrimR,TrimA,TrimE 58,2,FX,9630,1,Rate,Gyro,TrimR,TrimA,TrimE
58,3,FX,Q560,1,FLIP,Gyro,LEDs
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib 20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
20,1,FY326,FY319,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 23,0,FY326,FY326,1,Flip,RTH,HLess,Expert
@@ -157,7 +159,7 @@
74,1,RadioLink,Air,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8 74,1,RadioLink,Air,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
74,2,RadioLink,DumboRC,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8 74,2,RadioLink,DumboRC,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
74,3,RadioLink,RC4G,0,CH5,FS_CH1,FS_CH2,FS_CH3,FS_CH4 74,3,RadioLink,RC4G,0,CH5,FS_CH1,FS_CH2,FS_CH3,FS_CH4
76,0,Realacc,R11,1,Flip,Light,Calib,HLess,RTH,UNK 76,0,Realacc,Std,1,Flip,Light,Calib,HLess,RTH,ThCut,Rotat
50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16 50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16 50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
21,0,Futaba,SFHSS,0,CH5,CH6,CH7,CH8 21,0,Futaba,SFHSS,0,CH5,CH6,CH7,CH8
@@ -168,6 +170,7 @@
11,2,SLT,Q100,0,Rates,n-a,CH7,CH8,Mode,Flip,n-a,n-a,Calib 11,2,SLT,Q100,0,Rates,n-a,CH7,CH8,Mode,Flip,n-a,n-a,Calib
11,3,SLT,Q200,0,Rates,n-a,CH7,CH8,Mode,VidOn,VidOff,Calib 11,3,SLT,Q200,0,Rates,n-a,CH7,CH8,Mode,VidOn,VidOff,Calib
11,4,SLT,MR100,0,Rates,n-a,CH7,CH8,Mode,Flip,Video,Pict 11,4,SLT,MR100,0,Rates,n-a,CH7,CH8,Mode,Flip,Video,Pict
11,5,SLT,V1_4CH,0
10,0,Symax,Std,1,Flip,Rates,Pict,Video,HLess 10,0,Symax,Std,1,Flip,Rates,Pict,Video,HLess
10,1,Symax,X5C,1,Flip,Rates,Pict,Video,HLess 10,1,Symax,X5C,1,Flip,Rates,Pict,Video,HLess
43,0,Traxxas,TQ,0 43,0,Traxxas,TQ,0
@@ -213,5 +216,6 @@
94,0,Scorpio 94,0,Scorpio
95,0,Bluefly,HP100,0,CH5,CH6,CH7,CH8 95,0,Bluefly,HP100,0,CH5,CH6,CH7,CH8
96,0,BumbleB 96,0,BumbleB
97,0,SGF22,Std,1,Mode,Flip,LED,Pict,Video 97,0,SGF22,Std,1,Mode,Flip,LED,Pict,Video,TrRes
61,1,EazyRC 61,1,EazyRC
98,0,Kyosho3,ASF,0

View File

@@ -249,7 +249,7 @@ void CYRF_WriteDataPacket(const uint8_t dpbuffer[])
} }
*/ */
//NOTE: This routine will reset the CRC Seed //NOTE: This routine will reset the CRC Seed
void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uint8_t min, uint8_t max) void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uint8_t min, uint8_t max, uint8_t forced)
{ {
#define NUM_FREQ 80 #define NUM_FREQ 80
#define FREQ_OFFSET 4 #define FREQ_OFFSET 4
@@ -269,7 +269,12 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
delayMilliseconds(1); delayMilliseconds(1);
for(i = 0; i < NUM_FREQ; i++) for(i = 0; i < NUM_FREQ; i++)
{ {
CYRF_ConfigRFChannel(protocol==PROTO_LOSI?i|1:i); if(((i&1) && forced == FIND_CHANNEL_EVEN) || (!(i&1) && forced == FIND_CHANNEL_ODD))
{
rssi[i] = 0xFF;
continue;
}
CYRF_ConfigRFChannel(i); //protocol==PROTO_LOSI?i|1:i);
delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle
if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) { if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) {
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive
@@ -321,9 +326,7 @@ const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
{0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46}, {0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46},
{0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C}, {0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C},
{0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74}, {0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74},
#endif {0x62, 0xDF, 0xC1, 0x49, 0xDF, 0xB1, 0xC0, 0x49}, //j6pro bind
#if defined(TRAXXAS_CYRF6936_INO)
{0x62, 0xDF, 0xC1, 0x49, 0xDF, 0xB1, 0xC0, 0x49},
#endif #endif
}; };
#endif #endif

View File

@@ -267,6 +267,7 @@ uint16_t DSM_RX_callback()
0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8 0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8
0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7 0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7
0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels 0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels
0x23 => DX3R DSM2 2 surface packets
0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8 0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8
0xB2 => 11ms 2048 DSMX => can be any number of channels 0xB2 => 11ms 2048 DSMX => can be any number of channels
(0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms (0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms

View File

@@ -19,11 +19,10 @@
//#define DSM_DEBUG_FWD_PGM //#define DSM_DEBUG_FWD_PGM
//#define DEBUG_BIND 1 //#define DEBUG_BIND 1
//#define DSM_GR300
#define CLONE_BIT_MASK 0x20 #define CLONE_BIT_MASK 0x20
#define DSM_BIND_CHANNEL 0x0D //13 This can be any odd channel
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel #define DSM2_SFC_PERIOD 16500
//During binding we will send BIND_COUNT packets //During binding we will send BIND_COUNT packets
//One packet each 10msec //One packet each 10msec
@@ -32,8 +31,8 @@
// Lemon-RX G2s seems to have a timeout waiting for the channel to get quiet after the // Lemon-RX G2s seems to have a timeout waiting for the channel to get quiet after the
// first good BIND packet.. If using 3s (300), Lemon-RX will not transmit the BIND-Response packet. // first good BIND packet.. If using 3s (300), Lemon-RX will not transmit the BIND-Response packet.
#define DSM_BIND_COUNT 180 // About 1.8s #define DSM_BIND_COUNT 180 // About 1.8s
#define DSM_BIND_COUNT_READ 600 // About 4.2s of waiting for Response #define DSM_BIND_COUNT_READ 600 // About 4.2s of waiting for Response
enum { enum {
DSM_BIND_WRITE=0, DSM_BIND_WRITE=0,
@@ -95,9 +94,12 @@ static void __attribute__((unused)) DSM_build_bind_packet()
packet[11] = 12; packet[11] = 12;
else else
packet[11] = num_ch; // DX5 DSMR sends 0x48... packet[11] = num_ch; // DX5 DSMR sends 0x48...
//packet[11] = 3; // DX3R
if (sub_protocol==DSMR) if (sub_protocol==DSMR)
packet[12] = 0xa2; packet[12] = 0xa2;
else if (sub_protocol==DSM2_SFC)
packet[12] = 0x23; // DX3R
else if (sub_protocol==DSM2_1F) else if (sub_protocol==DSM2_1F)
packet[12] = num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels packet[12] = num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
else if(sub_protocol==DSM2_2F) else if(sub_protocol==DSM2_2F)
@@ -110,7 +112,6 @@ static void __attribute__((unused)) DSM_build_bind_packet()
#endif #endif
else // DSMX_2F && DSM_AUTO else // DSMX_2F && DSM_AUTO
packet[12] = 0xb2; // DSMX/2048 2 packets packet[12] = 0xb2; // DSMX/2048 2 packets
packet[13] = 0x00; //??? packet[13] = 0x00; //???
for(i = 8; i < 14; i++) for(i = 8; i < 14; i++)
@@ -137,8 +138,13 @@ static void __attribute__((unused)) DSM_update_channels()
if(num_ch<3 || num_ch>12) if(num_ch<3 || num_ch>12)
num_ch=6; // Default to 6 channels if invalid choice... num_ch=6; // Default to 6 channels if invalid choice...
if(sub_protocol==DSMR && num_ch>7) #ifndef MULTI_AIR
num_ch=7; // Max 7 channels in DSMR if(sub_protocol==DSMR && num_ch>7)
num_ch=7; // Max 7 channels in DSMR
if(sub_protocol==DSM2_SFC && num_ch>5)
num_ch=5; // Max 5 channels in DSM2_SFC
#endif
// Create channel map based on number of channels and refresh rate // Create channel map based on number of channels and refresh rate
uint8_t idx=num_ch-3; uint8_t idx=num_ch-3;
@@ -175,13 +181,17 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
} }
#ifndef MULTI_AIR #ifndef MULTI_AIR
if(sub_protocol == DSMR) if(sub_protocol == DSMR || sub_protocol == DSM2_SFC)
{ { // 12 bits, full range, no reassignment
for (uint8_t i = 0; i < 7; i++) for (uint8_t i = 0; i < 7; i++)
{ {
uint16_t value = 0x0000; uint16_t value = 0x0000;
if(i < num_ch) if(i < num_ch)
{
value=Channel_data[i]<<1; value=Channel_data[i]<<1;
if(sub_protocol == DSM2_SFC)
value |= i<<12;
}
packet[i*2+2] = (value >> 8) & 0xff; packet[i*2+2] = (value >> 8) & 0xff;
packet[i*2+3] = (value >> 0) & 0xff; packet[i*2+3] = (value >> 0) & 0xff;
} }
@@ -266,12 +276,18 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
uint16_t DSM_callback() uint16_t DSM_callback()
{ {
#if defined MULTI_EU #if defined MULTI_EU
if(sub_protocol == DSM2_1F || sub_protocol == DSM2_2F) if(sub_protocol == DSM2_1F || sub_protocol == DSM2_2F || sub_protocol == DSM2_SFC)
{
SUB_PROTO_INVALID;
return 11000; return 11000;
}
#endif #endif
#if defined MULTI_AIR #if defined MULTI_AIR
if(sub_protocol == DSMR) if(sub_protocol == DSMR || sub_protocol == DSM2_SFC)
{
SUB_PROTO_INVALID;
return 11000; return 11000;
}
#endif #endif
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2 #define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
#ifdef STM32_BOARD #ifdef STM32_BOARD
@@ -285,12 +301,7 @@ uint16_t DSM_callback()
uint8_t len; uint8_t len;
#endif #endif
uint8_t start; uint8_t start;
//debugln("P=%d",phase);
#ifdef DSM_GR300
uint16_t timing=5000+(convert_channel_8b(CH13)*100);
debugln("T=%u",timing);
#endif
switch(phase) switch(phase)
{ {
case DSM_BIND_WRITE: case DSM_BIND_WRITE:
@@ -304,11 +315,11 @@ uint16_t DSM_callback()
return 10000; return 10000;
#if defined DSM_TELEMETRY #if defined DSM_TELEMETRY
case DSM_BIND_CHECK: case DSM_BIND_CHECK:
#if DEBUG_BIND #if DEBUG_BIND
debugln("Bind Check"); debugln("Bind Check");
#endif #endif
//64 SDR Mode is configured so only the 8 first values are needed //64 SDR Mode is configured so only the 8 first values are needed
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84"); CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84");
CYRF_SetTxRxMode(RX_EN); //Receive mode CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive
bind_counter=DSM_BIND_COUNT_READ; //Timeout of 4.2s if no packet received bind_counter=DSM_BIND_COUNT_READ; //Timeout of 4.2s if no packet received
@@ -371,25 +382,38 @@ uint16_t DSM_callback()
CYRF_SetTxRxMode(TX_EN); CYRF_SetTxRxMode(TX_EN);
hopping_frequency_no = 0; hopping_frequency_no = 0;
phase = DSM_CH1_WRITE_A; // in fact phase++ phase = DSM_CH1_WRITE_A; // in fact phase++
#ifndef MULTI_AIR
if(sub_protocol == DSMR) if(sub_protocol == DSMR)
DSM_set_sop_data_crc(false, true); DSM_set_sop_data_crc(false, true);
else else
#endif
DSM_set_sop_data_crc(true, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F); //prep CH1 DSM_set_sop_data_crc(true, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F); //prep CH1
return 10000; return 10000;
case DSM_CH1_WRITE_A: case DSM_CH1_WRITE_A:
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode if(sub_protocol!=DSM2_SFC || option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
else
telemetry_set_input_sync(DSM2_SFC_PERIOD);
#endif #endif
#ifndef MULTI_AIR
if(sub_protocol == DSMR) if(sub_protocol == DSMR)
CYRF_SetPower(0x08); //Keep transmit power in sync CYRF_SetPower(0x08); //Keep transmit power in sync
else else
#endif
CYRF_SetPower(0x28); //Keep transmit power in sync CYRF_SetPower(0x28); //Keep transmit power in sync
case DSM_CH1_WRITE_B: case DSM_CH1_WRITE_B:
DSM_build_data_packet(phase == DSM_CH1_WRITE_B); // build lower or upper channels DSM_build_data_packet(phase == DSM_CH1_WRITE_B); // build lower or upper channels
case DSM_CH2_WRITE_A: case DSM_CH2_WRITE_A:
case DSM_CH2_WRITE_B: case DSM_CH2_WRITE_B:
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
CYRF_WriteDataPacket(packet); //debugln_time("");
#ifndef MULTI_AIR
if(sub_protocol==DSM2_SFC)
CYRF_WriteDataPacketLen(packet,2*(num_ch+1));
else
#endif
CYRF_WriteDataPacket(packet);
#if 0 #if 0
for(uint8_t i=0;i<16;i++) for(uint8_t i=0;i<16;i++)
debug(" %02X", packet[i]); debug(" %02X", packet[i]);
@@ -426,14 +450,19 @@ uint16_t DSM_callback()
phase++; // change from CH2_CHECK to CH2_READ phase++; // change from CH2_CHECK to CH2_READ
CYRF_SetTxRxMode(RX_EN); //Receive mode CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
if(sub_protocol==DSMR) #ifndef MULTI_AIR
{ if(sub_protocol==DSMR || sub_protocol == DSM2_SFC)
phase = DSM_CH2_READ_B; {
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY; phase = DSM_CH2_READ_B;
} if(sub_protocol == DSM2_SFC)
#ifdef DSM_GR300 {
if(num_ch==3) if(option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY; return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
else
return DSM2_SFC_PERIOD - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
#endif #endif
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY; return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
case DSM_CH2_READ_A: case DSM_CH2_READ_A:
@@ -468,10 +497,6 @@ uint16_t DSM_callback()
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
phase = DSM_CH2_READ_B; phase = DSM_CH2_READ_B;
#ifdef DSM_GR300
if(num_ch==3)
return timing;
#endif
return 11000; return 11000;
} }
if (phase == DSM_CH2_READ_A) if (phase == DSM_CH2_READ_A)
@@ -492,19 +517,20 @@ uint16_t DSM_callback()
else else
{ //Normal mode 22ms { //Normal mode 22ms
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
#ifdef DSM_GR300 #ifndef MULTI_AIR
if(num_ch==3) if(sub_protocol==DSM2_SFC)
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ; {
if(option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
else
return DSM2_SFC_PERIOD - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
}
#endif #endif
return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ; return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
} }
} }
else else
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)
#ifdef DSM_GR300
if(num_ch==3)
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
#endif
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
#endif #endif
} }
@@ -547,15 +573,13 @@ void DSM_init()
SUB_PROTO_INVALID; SUB_PROTO_INVALID;
else else
{ {
SUB_PROTO_VALID; //SUB_PROTO_VALID;
uint8_t row = rx_tx_addr[3]%22; uint8_t row = rx_tx_addr[3]%22;
for(uint8_t i=0; i< 4; i++) for(uint8_t i=0; i< 4; i++)
cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]); cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]);
for(uint8_t i=0; i< 23; i++) for(uint8_t i=0; i< 23; i++)
hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]); hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]);
} }
#else
SUB_PROTO_INVALID;
#endif #endif
} }
else else
@@ -568,25 +592,25 @@ void DSM_init()
uint16_t temp = DSM_CLONE_EEPROM_OFFSET; uint16_t temp = DSM_CLONE_EEPROM_OFFSET;
for(uint8_t i=0;i<4;i++) for(uint8_t i=0;i<4;i++)
cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++); cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++);
#if DEBUG_BIND #if DEBUG_BIND
debugln("Using cloned ID"); debugln("Using cloned ID");
debug("Clone ID=") debug("Clone ID=")
for(uint8_t i=0;i<4;i++) for(uint8_t i=0;i<4;i++)
debug("%02x ", cyrfmfg_id[i]); debug("%02x ", cyrfmfg_id[i]);
debugln(""); debugln("");
#endif #endif
} }
else else
{ {
SUB_PROTO_INVALID; SUB_PROTO_INVALID;
#if DEBUG_BIND #if DEBUG_BIND
debugln("No valid cloned ID"); debugln("No valid cloned ID");
#endif #endif
} }
} }
else else
{ {
SUB_PROTO_VALID; //SUB_PROTO_VALID;
CYRF_GetMfgData(cyrfmfg_id); CYRF_GetMfgData(cyrfmfg_id);
} }
} }
@@ -602,8 +626,8 @@ void DSM_init()
//Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8" //Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8"
if(sop_col==0 && sub_protocol != DSMR) if(sop_col==0 && sub_protocol != DSMR)
{ {
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0 cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07; sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
} }
} }
@@ -616,7 +640,7 @@ void DSM_init()
else if(sub_protocol != DSMR) else if(sub_protocol != DSMR)
{ {
uint8_t tmpch[10]; uint8_t tmpch[10];
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75); CYRF_FindBestChannels(tmpch, 10, 5, 3, 75, FIND_CHANNEL_ANY);
// //
uint8_t idx = random(0xfefefefe) % 10; uint8_t idx = random(0xfefefefe) % 10;
hopping_frequency[0] = tmpch[idx]; hopping_frequency[0] = tmpch[idx];
@@ -639,10 +663,10 @@ void DSM_init()
{ {
DSM_initialize_bind_phase(); DSM_initialize_bind_phase();
phase = DSM_BIND_WRITE; phase = DSM_BIND_WRITE;
bind_counter=DSM_BIND_COUNT; bind_counter=DSM_BIND_COUNT;
#if DEBUG_BIND #if DEBUG_BIND
debugln("Bind Started: write count=%d",bind_counter); debugln("Bind Started: write count=%d",bind_counter);
#endif #endif
} }
else else
phase = DSM_CHANSEL; phase = DSM_CHANSEL;

View File

@@ -365,7 +365,7 @@ static void __attribute__((unused)) DEVO_cyrf_init()
static void __attribute__((unused)) DEVO_set_radio_channels() static void __attribute__((unused)) DEVO_set_radio_channels()
{ {
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80); CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80, FIND_CHANNEL_ANY);
hopping_frequency[3] = hopping_frequency[0]; hopping_frequency[3] = hopping_frequency[0];
hopping_frequency[4] = hopping_frequency[1]; hopping_frequency[4] = hopping_frequency[1];
} }

View File

@@ -33,7 +33,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#define FX620_PAYLOAD_SIZE 7 #define FX620_PAYLOAD_SIZE 7
#define FX620_CH_OFFSET 1 #define FX620_CH_OFFSET 1
#define FX9630_PACKET_PERIOD 8124 #define FX9630_PACKET_PERIOD 8124 //8156 on QIDI-560
#define FX9630_BIND_PACKET_PERIOD 8124 #define FX9630_BIND_PACKET_PERIOD 8124
#define FX9630_BIND_CHANNEL 51 #define FX9630_BIND_CHANNEL 51
#define FX9630_PAYLOAD_SIZE 8 #define FX9630_PAYLOAD_SIZE 8
@@ -51,14 +51,19 @@ static void __attribute__((unused)) FX_send_packet()
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {
XN297_Hopping(hopping_frequency_no++); XN297_Hopping(hopping_frequency_no++);
if(sub_protocol == FX9630) if(sub_protocol >= FX9630)
{ { // FX9630 & FX_Q560
XN297_SetTXAddr(rx_tx_addr, 4); XN297_SetTXAddr(rx_tx_addr, 4);
if (hopping_frequency_no >= FX9630_NUM_CHANNELS) if (hopping_frequency_no >= FX9630_NUM_CHANNELS)
{ {
hopping_frequency_no = 0; hopping_frequency_no = 0;
trim_ch++; if(sub_protocol == FX9630)
if(trim_ch > 3) trim_ch = 0; {
trim_ch++;
if(trim_ch > 3) trim_ch = 0;
}
else // FX_Q560
trim_ch = 0;
} }
} }
else // FX816 and FX620 else // FX816 and FX620
@@ -71,8 +76,8 @@ static void __attribute__((unused)) FX_send_packet()
//Channels //Channels
uint8_t val; uint8_t val;
if (sub_protocol == FX9630) if (sub_protocol >= FX9630)
{ { // FX9630 & FX_Q560
packet[0] = convert_channel_8b(THROTTLE); packet[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_8b(AILERON); packet[1] = convert_channel_8b(AILERON);
packet[2] = 0xFF - convert_channel_8b(ELEVATOR); packet[2] = 0xFF - convert_channel_8b(ELEVATOR);
@@ -83,7 +88,9 @@ static void __attribute__((unused)) FX_send_packet()
| GET_FLAG(CH5_SW, 0x01) // DR toggle swich: 0 small throw, 1 large throw | GET_FLAG(CH5_SW, 0x01) // DR toggle swich: 0 small throw, 1 large throw
// FX9630 =>0:6G small throw, 1:6G large throw, 2:3D // FX9630 =>0:6G small throw, 1:6G large throw, 2:3D
// QIDI-550=>0:3D, 1:6G, 2:Torque // QIDI-550=>0:3D, 1:6G, 2:Torque
| ((Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x02 : 0x01)) << 1); | (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, 0x10);
} }
else // FX816 and FX620 else // FX816 and FX620
{ {
@@ -123,7 +130,7 @@ static void __attribute__((unused)) FX_send_packet()
packet[5] = 0xAB; // Is it based on ID?? packet[5] = 0xAB; // Is it based on ID??
} }
} }
else // FX9630 else // FX9630 & FX_Q560
{ {
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
@@ -175,7 +182,7 @@ static void __attribute__((unused)) FX_RF_init()
packet_period = FX620_BIND_PACKET_PERIOD; packet_period = FX620_BIND_PACKET_PERIOD;
packet_length = FX620_PAYLOAD_SIZE; packet_length = FX620_PAYLOAD_SIZE;
} }
else // FX9630 else // FX9630 & FX_Q560
{ {
XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4); XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4);
XN297_RFChannel(FX9630_BIND_CHANNEL); XN297_RFChannel(FX9630_BIND_CHANNEL);
@@ -207,7 +214,7 @@ static void __attribute__((unused)) FX_initialize_txid()
for(uint8_t i=1;i<FX_NUM_CHANNELS;i++) for(uint8_t i=1;i<FX_NUM_CHANNELS;i++)
hopping_frequency[i] = i*10 + hopping_frequency[0]; hopping_frequency[i] = i*10 + hopping_frequency[0];
} }
else // FX9630 else // FX9630 & FX_Q560
{ {
#ifdef FORCE_FX9630_ID #ifdef FORCE_FX9630_ID
memcpy(rx_tx_addr,(uint8_t*)"\xCE\x31\x9B\x73", 4); memcpy(rx_tx_addr,(uint8_t*)"\xCE\x31\x9B\x73", 4);
@@ -220,6 +227,10 @@ static void __attribute__((unused)) FX_initialize_txid()
#ifdef FORCE_QIDI_ID #ifdef FORCE_QIDI_ID
memcpy(rx_tx_addr,(uint8_t*)"\x23\xDC\x76\xA2", 4); memcpy(rx_tx_addr,(uint8_t*)"\x23\xDC\x76\xA2", 4);
memcpy(hopping_frequency,"\x08\x25\x33", FX9630_NUM_CHANNELS); //Original dump=>08=0x08,37=0x25,51=0x33 memcpy(hopping_frequency,"\x08\x25\x33", FX9630_NUM_CHANNELS); //Original dump=>08=0x08,37=0x25,51=0x33
//QIDI-560 #1
//memcpy(rx_tx_addr,(uint8_t*)"\x38\xC7\x6D\x8D", 4);
//memcpy(hopping_frequency,"\x0D\x20\x3A", FX9630_NUM_CHANNELS);
#endif #endif
//??? Need to find out how the first RF channel is calculated ??? //??? Need to find out how the first RF channel is calculated ???
} }

View File

@@ -35,7 +35,6 @@ enum PktState {
J6PRO_CHAN_4, J6PRO_CHAN_4,
}; };
const uint8_t PROGMEM j6pro_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; // unneeded since this is the default table after a reset const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; // unneeded since this is the default table after a reset
static void __attribute__((unused)) j6pro_build_bind_packet() static void __attribute__((unused)) j6pro_build_bind_packet()
@@ -99,7 +98,7 @@ static void __attribute__((unused)) cyrf_bindinit()
/* Use when binding */ /* Use when binding */
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power... CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
//CYRF_ConfigRFChannel(0x52); //CYRF_ConfigRFChannel(0x52);
CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code); CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[19]);
CYRF_ConfigCRCSeed(0x0000); CYRF_ConfigCRCSeed(0x0000);
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); //CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
//CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
@@ -124,7 +123,7 @@ static void __attribute__((unused)) j6pro_set_radio_channels()
{ {
//FIXME: Query free channels //FIXME: Query free channels
//lowest channel is 0x08, upper channel is 0x4d? //lowest channel is 0x08, upper channel is 0x4d?
CYRF_FindBestChannels(hopping_frequency, 3, 5, 8, 77); CYRF_FindBestChannels(hopping_frequency, 3, 5, 8, 77, FIND_CHANNEL_ANY);
hopping_frequency[3] = hopping_frequency[0]; hopping_frequency[3] = hopping_frequency[0];
} }

View File

@@ -0,0 +1,121 @@
/*
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(KYOSHO3_CYRF6936_INO)
#include "iface_cyrf6936.h"
//#define KYOSHO3_FORCE_ID
//#define KYOSHO3_DEBUG
#define KYOSHO3_BIND_PACKET_SIZE 4
#define KYOSHO3_PACKET_SIZE 9
const uint8_t PROGMEM KYOSHO3_init_vals[][2] = {
//Init from dump
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
{CYRF_03_TX_CFG, 0x28 | CYRF_BIND_POWER}, // 8DR Mode, 64 chip codes
{CYRF_10_FRAMING_CFG, 0xA4}, // SOP and LEN enable
{CYRF_1F_TX_OVERRIDE, 0x05}, // Disable CRC, Data invert
{CYRF_1E_RX_OVERRIDE, 0x04}, // CRC check disabled
//{CYRF_11_DATA32_THOLD, 0x04}, // ???Using 64 chip...
{CYRF_12_DATA64_THOLD, 0x0E}, // Default
{CYRF_06_RX_CFG, 0x52}, // AGC disabled, LNA enabled, override enabled
};
static uint16_t __attribute__((unused)) KYOSHO3_send_packet()
{
CYRF_SetPower(0x28);
if(IS_BIND_IN_PROGRESS)
{
if(--bind_counter==0)
BIND_DONE;
packet[0] = 0xAA;
//ID
memcpy(&packet[1],&rx_tx_addr[1],3);
CYRF_WriteDataPacketLen(packet, KYOSHO3_BIND_PACKET_SIZE);
#ifdef KYOSHO3_DEBUG
debug("P:");
for(uint8_t i=0;i<KYOSHO3_BIND_PACKET_SIZE;i++)
debug(" %02X",packet[i]);
debugln("");
#endif
return 2434;
}
else
{
//ID
memcpy(packet,&rx_tx_addr[1],3);
//Channels
for(uint8_t i=0;i<4;i++)
{
packet[3] >>= 2;
packet[3] |= Channel_data[i]<<6;
packet[4+i] = Channel_data[i]>>3;
}
//Checksum
packet[8] = packet[3];
for(uint8_t i=4;i<8;i++)
packet[8] += packet[i];
//Timing
phase ^= 0x01;
CYRF_WriteDataPacketLen(packet, KYOSHO3_PACKET_SIZE);
#ifdef KYOSHO3_DEBUG
debug("P:");
for(uint8_t i=0;i<KYOSHO3_PACKET_SIZE;i++)
debug(" %02X",packet[i]);
debugln("");
#endif
if(phase)
return 9047;
}
return 6957;
}
uint16_t KYOSHO3_callback()
{
return KYOSHO3_send_packet();
}
void KYOSHO3_init()
{
//Config CYRF registers
for(uint8_t i = 0; i < sizeof(KYOSHO3_init_vals) / 2; i++)
CYRF_WriteRegister(pgm_read_byte_near(&KYOSHO3_init_vals[i][0]), pgm_read_byte_near(&KYOSHO3_init_vals[i][1]));
CYRF_WritePreamble(0x333304);
//Find a free even channel
CYRF_FindBestChannels(hopping_frequency,1,1,0x04,0x50, FIND_CHANNEL_EVEN);
#ifdef KYOSHO3_FORCE_ID // data taken from TX dump
rx_tx_addr[1] = 0x01;
rx_tx_addr[2] = 0xAB;
rx_tx_addr[3] = 0x31;
hopping_frequency[0] = 0x04;
#endif
#ifdef KYOSHO3_DEBUG
debugln("ID: %02X %02X %02X",rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3]);
debugln("RF CH: %02X",hopping_frequency[0]);
#endif
CYRF_ConfigRFChannel(hopping_frequency[0]);
bind_counter = 8217;
phase = 0;
}
#endif

View File

@@ -169,8 +169,7 @@ void LOSI_init()
{ {
LOSI_cyrf_init(); LOSI_cyrf_init();
CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x07, 0x4F); // 0x07 and 0x4F are unknown limits, this routine resets the CRC Seed to 0 CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x07, 0x4F, FIND_CHANNEL_ODD); // 0x07 and 0x4F are unknown limits, this routine resets the CRC Seed to 0
hopping_frequency[0] |= 1; // Only odd channels are used, integrated in CYRF code...
crc8 = 0; crc8 = 0;
crc8 = (uint16_t)LOSI_check(((rx_tx_addr[2]&0x0F) << 8) + rx_tx_addr[3]) >> 12; crc8 = (uint16_t)LOSI_check(((rx_tx_addr[2]&0x0F) << 8) + rx_tx_addr[3]) >> 12;

View File

@@ -3,12 +3,12 @@
3,FrskyD,D8,Cloned 3,FrskyD,D8,Cloned
4,Hisky,Hisky,HK310 4,Hisky,Hisky,HK310
5,V2x2,V2x2,JXD506,MR101 5,V2x2,V2x2,JXD506,MR101
6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO,DSMR_1F 6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO,DSMR_1F,DSMR,DSM2_SFC
7,Devo,8CH,10CH,12CH,6CH,7CH 7,Devo,8CH,10CH,12CH,6CH,7CH
8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI 8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI
9,KN,WLTOYS,FEILUN 9,KN,WLTOYS,FEILUN
10,SymaX,SYMAX,SYMAX5C 10,SymaX,SYMAX,SYMAX5C
11,SLT,SLT_V1,SLT_V2,Q100,Q200,MR100 11,SLT,SLT_V1,SLT_V2,Q100,Q200,MR100,V1_4CH
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041 12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
13,CG023,CG023,YD829 13,CG023,CG023,YD829
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4,QX100 14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4,QX100
@@ -55,7 +55,7 @@
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM 55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
56,AFHDS2A_RX,Multi,CPPM 56,AFHDS2A_RX,Multi,CPPM
57,HoTT,Sync,No_Sync 57,HoTT,Sync,No_Sync
58,FX,816,620,9630 58,FX,816,620,9630,Q560
59,Bayang_RX,Multi,CPPM 59,Bayang_RX,Multi,CPPM
60,Pelikan,Pro,Lite,SCX24 60,Pelikan,Pro,Lite,SCX24
61,EazyRC 61,EazyRC
@@ -73,7 +73,7 @@
73,Kyosho,FHSS,Hype 73,Kyosho,FHSS,Hype
74,RadioLink,Surface,Air,DumboRC,RC4G 74,RadioLink,Surface,Air,DumboRC,RC4G
75,--- 75,---
76,Realacc,R11 76,Realacc
77,OMP 77,OMP
78,M-Link 78,M-Link
79,WFLY,RF20x 79,WFLY,RF20x
@@ -94,3 +94,4 @@
95,BlueFly 95,BlueFly
96,BumbleB 96,BumbleB
97,SGF22 97,SGF22
98,Kyosho3

View File

@@ -109,6 +109,7 @@ const char STR_BLUEFLY[] ="BlueFly";
const char STR_BUMBLEB[] ="BumbleB"; const char STR_BUMBLEB[] ="BumbleB";
const char STR_SGF22[] ="SGF22"; const char STR_SGF22[] ="SGF22";
const char STR_EAZYRC[] ="EazyRC"; const char STR_EAZYRC[] ="EazyRC";
const char STR_KYOSHO3[] ="Kyosho3";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20"; const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501"; const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -121,15 +122,15 @@ const char STR_SUBTYPE_FRSKYD[] = "\x06""D8\0 ""Cloned";
const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310"; const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310";
const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506""MR101\0"; const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506""MR101\0";
#ifndef MULTI_EU #ifndef MULTI_EU
const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F"; const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F""2SFC";
#else #else
const char STR_SUBTYPE_DSM[] = "\x04""--->""--->""X 1F""X 2F""Auto""R 1F"; const char STR_SUBTYPE_DSM[] = "\x04""--->""--->""X 1F""X 2F""Auto""R 1F""----";
#endif #endif
const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0"; const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0";
const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 "; const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 ";
const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun"; const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun";
const char STR_SUBTYPE_SYMAX[] = "\x03""Std""X5C"; const char STR_SUBTYPE_SYMAX[] = "\x03""Std""X5C";
const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0"; const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0""V1_4ch";
const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041"; const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829"; const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829";
const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 "; const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
@@ -147,7 +148,7 @@ const char STR_SUBTYPE_H83D[] = "\x07""Std\0 ""H20H\0 ""H20Mini""H30Min
const char STR_SUBTYPE_CORONA[] = "\x05""V1\0 ""V2\0 ""FD V3"; const char STR_SUBTYPE_CORONA[] = "\x05""V1\0 ""V2\0 ""FD V3";
const char STR_SUBTYPE_HITEC[] = "\x07""Optima\0""Opt Hub""Minima\0"; const char STR_SUBTYPE_HITEC[] = "\x07""Optima\0""Opt Hub""Minima\0";
const char STR_SUBTYPE_BUGS_MINI[] = "\x06""Std\0 ""Bugs3H"; const char STR_SUBTYPE_BUGS_MINI[] = "\x06""Std\0 ""Bugs3H";
const char STR_SUBTYPE_TRAXXAS[] = "\x02""TQ"; const char STR_SUBTYPE_TRAXXAS[] = "\x03""TQ2""TQ1";
const char STR_SUBTYPE_E01X[] = "\x05""E012\0""E015\0"; const char STR_SUBTYPE_E01X[] = "\x05""E012\0""E015\0";
const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2"; const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2";
const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow"; const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow";
@@ -169,15 +170,15 @@ const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
const char STR_SUBTYPE_PELIKAN[] = "\x05""Pro\0 ""Lite\0""SCX24"; const char STR_SUBTYPE_PELIKAN[] = "\x05""Pro\0 ""Lite\0""SCX24";
const char STR_SUBTYPE_V761[] = "\x05""3ch\0 ""4ch\0 ""TOPRC"; const char STR_SUBTYPE_V761[] = "\x05""3ch\0 ""4ch\0 ""TOPRC";
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC""RC4G\0 "; const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC""RC4G\0 ";
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype"; const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype";
const char STR_SUBTYPE_KYOSHO2[] = "\x05""KT-17"; 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_FUTABA[] = "\x05""SFHSS";
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr"; const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
const char STR_SUBTYPE_MOULDKG[] = "\x06""Analog""Digit\0"; const char STR_SUBTYPE_MOULDKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0"; const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0";
const char STR_SUBTYPE_E129[] = "\x04""E129""C186"; const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630"; const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630""Q560";
#define NO_SUBTYPE nullptr #define NO_SUBTYPE nullptr
#ifdef SEND_CPPM #ifdef SEND_CPPM
@@ -259,7 +260,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_DM002, STR_DM002, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, DM002_init, DM002_callback }, {PROTO_DM002, STR_DM002, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, DM002_init, DM002_callback },
#endif #endif
#if defined(DSM_CYRF6936_INO) #if defined(DSM_CYRF6936_INO)
{PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 6, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback }, {PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 7, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback },
#endif #endif
#if defined(DSM_RX_CYRF6936_INO) #if defined(DSM_RX_CYRF6936_INO)
{PROTO_DSM_RX, STR_DSM_RX, STR_SUB_DSM_RX, DSMCPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback }, {PROTO_DSM_RX, STR_DSM_RX, STR_SUB_DSM_RX, DSMCPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback },
@@ -332,7 +333,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 }, {PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
#endif #endif
#if defined(FX_NRF24L01_INO) #if defined(FX_NRF24L01_INO)
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 3, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback }, {PROTO_FX, STR_FX, STR_SUBTYPE_FX, 4, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
#endif #endif
#if defined(FY326_NRF24L01_INO) #if defined(FY326_NRF24L01_INO)
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback }, {PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },
@@ -388,6 +389,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(KYOSHO2_NRF24L01_INO) #if defined(KYOSHO2_NRF24L01_INO)
{PROTO_KYOSHO2, STR_KYOSHO2, STR_SUBTYPE_KYOSHO2, 1, OPTION_NONE, 0, 0, SW_NRF, KYOSHO2_init, KYOSHO2_callback }, {PROTO_KYOSHO2, STR_KYOSHO2, STR_SUBTYPE_KYOSHO2, 1, OPTION_NONE, 0, 0, SW_NRF, KYOSHO2_init, KYOSHO2_callback },
#endif #endif
#if defined(KYOSHO3_CYRF6936_INO)
{PROTO_KYOSHO3, STR_KYOSHO3, STR_SUBTYPE_KYOSHO3, 1, OPTION_NONE, 0, 0, SW_CYRF, KYOSHO3_init, KYOSHO3_callback },
#endif
#if defined(LOLI_NRF24L01_INO) #if defined(LOLI_NRF24L01_INO)
{PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback }, {PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback },
#endif #endif
@@ -437,7 +441,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 4, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback }, {PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 4, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback },
#endif #endif
#if defined(REALACC_NRF24L01_INO) #if defined(REALACC_NRF24L01_INO)
{PROTO_REALACC, STR_REALACC, STR_SUBTYPE_REALACC, 1, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback }, {PROTO_REALACC, STR_REALACC, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback },
#endif #endif
#if defined(REDPINE_CC2500_INO) #if defined(REDPINE_CC2500_INO)
{PROTO_REDPINE, STR_REDPINE, STR_SUBTYPE_REDPINE, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, REDPINE_init, REDPINE_callback }, {PROTO_REDPINE, STR_REDPINE, STR_SUBTYPE_REDPINE, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, REDPINE_init, REDPINE_callback },
@@ -458,13 +462,13 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback }, {PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback },
#endif #endif
#if defined(SLT_CCNRF_INO) #if defined(SLT_CCNRF_INO)
{PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 5, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback }, {PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 6, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback },
#endif #endif
#if defined(SYMAX_NRF24L01_INO) #if defined(SYMAX_NRF24L01_INO)
{PROTO_SYMAX, STR_SYMAX, STR_SUBTYPE_SYMAX, 2, OPTION_NONE, 0, 0, SW_NRF, SYMAX_init, SYMAX_callback }, {PROTO_SYMAX, STR_SYMAX, STR_SUBTYPE_SYMAX, 2, OPTION_NONE, 0, 0, SW_NRF, SYMAX_init, SYMAX_callback },
#endif #endif
#if defined(TRAXXAS_CYRF6936_INO) #if defined(TRAXXAS_CYRF6936_INO)
{PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 1, OPTION_NONE, 0, 0, SW_CYRF, TRAXXAS_init, TRAXXAS_callback }, {PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 2, OPTION_NONE, 0, 0, SW_CYRF, TRAXXAS_init, TRAXXAS_callback },
#endif #endif
#if defined(V2X2_NRF24L01_INO) #if defined(V2X2_NRF24L01_INO)
{PROTO_V2X2, STR_V2X2, STR_SUBTYPE_V2X2, 3, OPTION_NONE, 0, 0, SW_NRF, V2X2_init, V2X2_callback }, {PROTO_V2X2, STR_V2X2, STR_SUBTYPE_V2X2, 3, OPTION_NONE, 0, 0, SW_NRF, V2X2_init, V2X2_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 00 #define VERSION_PATCH_LEVEL 9
#define MODE_SERIAL 0 #define MODE_SERIAL 0
@@ -125,6 +125,7 @@ enum PROTOCOLS
PROTO_BLUEFLY = 95, // =>CC2500 & NRF24L01 PROTO_BLUEFLY = 95, // =>CC2500 & NRF24L01
PROTO_BUMBLEB = 96, // =>CC2500 & NRF24L01 PROTO_BUMBLEB = 96, // =>CC2500 & NRF24L01
PROTO_SGF22 = 97, // =>NRF24L01 PROTO_SGF22 = 97, // =>NRF24L01
PROTO_KYOSHO3 = 98, // =>CYRF6936
PROTO_NANORF = 126, // =>NRF24L01 PROTO_NANORF = 126, // =>NRF24L01
@@ -173,6 +174,7 @@ enum DSM
DSMX_2F = 3, DSMX_2F = 3,
DSM_AUTO = 4, DSM_AUTO = 4,
DSMR = 5, DSMR = 5,
DSM2_SFC = 6,
}; };
enum DSM_RX enum DSM_RX
{ {
@@ -200,11 +202,12 @@ enum SYMAX
}; };
enum SLT enum SLT
{ {
SLT_V1 = 0, SLT_V1 = 0,
SLT_V2 = 1, SLT_V2 = 1,
Q100 = 2, Q100 = 2,
Q200 = 3, Q200 = 3,
MR100 = 4, MR100 = 4,
SLT_V1_4 = 5,
}; };
enum CX10 enum CX10
{ {
@@ -360,7 +363,8 @@ enum REDPINE
}; };
enum TRAXXAS enum TRAXXAS
{ {
TRAXXAS_TQ = 0, TRAXXAS_TQ2 = 0,
TRAXXAS_TQ1 = 1,
}; };
enum ESKY150 enum ESKY150
{ {
@@ -475,6 +479,7 @@ enum FX
FX816 = 0, FX816 = 0,
FX620 = 1, FX620 = 1,
FX9630 = 2, FX9630 = 2,
FX_Q560 = 3,
}; };
#define NONE 0 #define NONE 0

View File

@@ -18,7 +18,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_xn297.h" #include "iface_xn297.h"
#define FORCE_REALACC_ORIGINAL_ID //#define FORCE_REALACC_ORIGINAL_ID
#define REALACC_INITIAL_WAIT 500 #define REALACC_INITIAL_WAIT 500
#define REALACC_PACKET_PERIOD 2268 #define REALACC_PACKET_PERIOD 2268
@@ -30,7 +30,7 @@ Multiprotocol is distributed in the hope that it will be useful,
static void __attribute__((unused)) REALACC_send_packet() static void __attribute__((unused)) REALACC_send_packet()
{ {
packet[ 0]= 0xDC; packet[ 0]= 0xDC; // DC/D6/DE
packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF
packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF
packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF
@@ -39,16 +39,17 @@ static void __attribute__((unused)) REALACC_send_packet()
packet[ 6]= 0x20; // Trim packet[ 6]= 0x20; // Trim
packet[ 7]= 0x20; // Trim packet[ 7]= 0x20; // Trim
packet[ 8]= 0x20; // Trim packet[ 8]= 0x20; // Trim
packet[ 9]= num_ch; // Change at each power up packet[ 9]= 0x88; // Change at each power up: C5 A2 77 F0 84 58, fixed for the E017 = 88
packet[10]= 0x04 // Flag1 packet[10]= 0x04 // Flag1: R11=04, E017=0C
| 0x02 // Rate1=0, Rate2=1, Rate3=2 | 0x02 // Rate1=0, Rate2=1, Rate3=2
| GET_FLAG(CH8_SW, 0x20); // Headless | GET_FLAG(CH8_SW, 0x20); // Headless
packet[11]= 0x00 // Flag2 packet[11]= 0x00 // Flag2
| GET_FLAG(CH7_SW, 0x01) // Calib | GET_FLAG(CH7_SW, 0x01) // Calib
| GET_FLAG(CH9_SW, 0x20) // Return | GET_FLAG(CH9_SW, 0x20) // Return
| GET_FLAG(CH10_SW,0x80); // Unknown | GET_FLAG(CH10_SW,0x80); // Throttle cut
packet[12]= 0x00 // Flag3 packet[12]= 0x00 // Flag3
| GET_FLAG(CH5_SW, 0x01) // Flip | GET_FLAG(CH5_SW, 0x01) // Flip
| GET_FLAG(CH11_SW,0x02) // Rotating
| GET_FLAG(CH6_SW, 0x80); // Light | GET_FLAG(CH6_SW, 0x80); // Light
XN297_Hopping(hopping_frequency_no); XN297_Hopping(hopping_frequency_no);
@@ -59,31 +60,50 @@ static void __attribute__((unused)) REALACC_send_packet()
static void __attribute__((unused)) REALACC_send_bind_packet() static void __attribute__((unused)) REALACC_send_bind_packet()
{ {
packet[0] = 0xB1; packet[0] = 0xB1; // B0/B1
memcpy(&packet[1],rx_tx_addr,4); memcpy(&packet[1],rx_tx_addr,4); // Address
memcpy(&packet[5],hopping_frequency,5); memcpy(&packet[5],hopping_frequency,5); // RF frequencies
XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1); XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1);
} }
static void __attribute__((unused)) REALACC_initialize_txid() static void __attribute__((unused)) REALACC_initialize_txid()
{ {
rx_tx_addr[3] &= 0x3F;
calc_fh_channels(REALACC_RF_NUM_CHANNELS); calc_fh_channels(REALACC_RF_NUM_CHANNELS);
num_ch=random(0xfefefefe); // 00..FF
#ifdef FORCE_REALACC_ORIGINAL_ID #ifdef FORCE_REALACC_ORIGINAL_ID
//Dump if(RX_num==0)
rx_tx_addr[0]=0x99; {//TX1
rx_tx_addr[1]=0x06; rx_tx_addr[0]=0x99;
rx_tx_addr[2]=0x00; rx_tx_addr[1]=0x06;
rx_tx_addr[3]=0x00; rx_tx_addr[2]=0x00;
hopping_frequency[0]=0x55; rx_tx_addr[3]=0x00; // 00..3F:OK, 40..:NOK
hopping_frequency[1]=0x59; hopping_frequency[0]=0x55;
hopping_frequency[2]=0x5A; hopping_frequency[1]=0x59;
hopping_frequency[3]=0x5A; hopping_frequency[2]=0x5A;
hopping_frequency[4]=0x62; hopping_frequency[3]=0x5A;
num_ch=0xC5; // Value in dumps: C5 A2 77 F0 84 58 hopping_frequency[4]=0x62;
}
else
{//TX2
rx_tx_addr[0]=0x4F;
rx_tx_addr[1]=0xB9;
rx_tx_addr[2]=0xA1;
rx_tx_addr[3]=0x17;
hopping_frequency[0]=0x45;
hopping_frequency[1]=0x38;
hopping_frequency[2]=0x3C;
hopping_frequency[3]=0x41;
hopping_frequency[4]=0x3F;
}
#endif #endif
#if 0
debug("ID: %02X %02X %02X %02X, C: ",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3]);
for(uint8_t i=0; i<REALACC_RF_NUM_CHANNELS; i++)
debug(" %02X",hopping_frequency[i]);
debugln("");
#endif
} }
static void __attribute__((unused)) REALACC_RF_init() static void __attribute__((unused)) REALACC_RF_init()
@@ -129,18 +149,39 @@ void REALACC_init()
// Bind // Bind
// Address = 4D 41 49 4E = 'MAIN' // Address = 4D 41 49 4E = 'MAIN'
// Channel = 80 (most likely from dump) // Channel = 80 (most likely from dump)
// P(10) = B1 99 06 00 00 55 59 5A 5A 62 // TX1
// B1 indicates bind packet // ---
// P(10) = B1 99 06 00 00 55 59 5A 5A 62
// Bx indicates bind packet, why x=1?
// 99 06 00 00 = ID = address of normal packets // 99 06 00 00 = ID = address of normal packets
// 55 59 5A 5A 62 = 85, 89, 90, 90, 98 = RF channels to be used (kind of match previous dumps)// Normal // 55 59 5A 5A 62 = 85, 89, 90, 90, 98 = RF channels to be used (kind of match previous dumps)
// TX2
// ---
// P(10) = B0 4F B9 A1 17 45 38 3C 41 3F
// Bx indicates bind packet, why x=0?
// 4F B9 A1 17 = ID = address of normal packets
// 45 38 3C 41 3F = 69, 56, 60, 65, 63 = RF channels to be used
// Normal // Normal
// Address = 99 06 00 00 // TX1
// Channels = 84, 89, 90, 90, 98 (guess from bind) // ---
// P(13)= DC 80 80 32 80 20 20 20 20 58 04 00 00 // Address = 99 06 00 00
// DC = normal packet // Channels = 84, 89, 90, 90, 98 (guess from bind)
// 80 80 32 80 : AETR 00..80..FF // P(13)= DC 80 80 32 80 20 20 20 20 58 04 00 00
// 20 20 20 20 : Trims // Dx = normal packet, why C ?
// 58 : changing every time the TX restart // 80 80 32 80 : AETR 00..80..FF
// 04 : |0x20=headless, |0x01=rate2, |0x02=rate3 // 20 20 20 20 : Trims
// 00 : |0x01=calib, |0x20=return, |0x80=unknown // 58 : changing every time the TX restart
// 00 : |0x80=light, |0x01=flip // 04 : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip
// TX2
// ---
// Address = 4F B9 A1 17
// P(13)= D6/DE 80 80 80 80 20 20 20 20 88 0C 00 00
// Dx = normal packet, why 6/E ?
// 80 80 32 80 : AETR 00..80..FF
// 20 20 20 20 : Trims
// 88 : not changing unknown
// 0C : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip, |0x02=Rotating

View File

@@ -35,6 +35,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#define SGF22_FLAG_VERTICAL 0xC0 #define SGF22_FLAG_VERTICAL 0xC0
//packet[9] //packet[9]
#define SGF22_FLAG_PHOTO 0x40 #define SGF22_FLAG_PHOTO 0x40
#define SGF22_FLAG_TRIMRESET 0x04
static void __attribute__((unused)) SGF22_send_packet() static void __attribute__((unused)) SGF22_send_packet()
{ {
@@ -66,7 +67,8 @@ static void __attribute__((unused)) SGF22_send_packet()
packet[8] |= SGF22_FLAG_6G; // mode 1 - 6g packet[8] |= SGF22_FLAG_6G; // mode 1 - 6g
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND) if(Channel_data[CH5] > CHANNEL_MAX_COMMAND)
packet[8] |= SGF22_FLAG_VERTICAL; // mode 0 - vertical packet[8] |= SGF22_FLAG_VERTICAL; // mode 0 - vertical
packet[9] = GET_FLAG(CH8_SW, SGF22_FLAG_PHOTO); // press in throttle trim for photo packet[9] = GET_FLAG(CH8_SW, SGF22_FLAG_PHOTO) // press in throttle trim for photo
| GET_FLAG(CH10_SW, SGF22_FLAG_TRIMRESET); // Both sticks down inwards
packet[10] = 0x42; // no fine tune packet[10] = 0x42; // no fine tune
packet[11] = 0x10; // no fine tune packet[11] = 0x10; // no fine tune
} }
@@ -91,7 +93,10 @@ static void __attribute__((unused)) SGF22_send_packet()
static void __attribute__((unused)) SGF22_initialize_txid() static void __attribute__((unused)) SGF22_initialize_txid()
{ {
uint8_t val = (( (uint16_t) rx_tx_addr[2] << 8 ) | rx_tx_addr[3])%5; uint16_t val = ( rx_tx_addr[2] << 8 ) | rx_tx_addr[3];
if ( rx_tx_addr[2] > ( 0xFF - rx_tx_addr[3]) )
val--;
val %= 5;
const uint8_t hop[5][4] = const uint8_t hop[5][4] =
{ { 0x0C, 0x2A, 0x1B, 0x39 }, { { 0x0C, 0x2A, 0x1B, 0x39 },
@@ -100,7 +105,7 @@ static void __attribute__((unused)) SGF22_initialize_txid()
{ 0x15, 0x34, 0x24, 0x44 }, { 0x15, 0x34, 0x24, 0x44 },
{ 0x18, 0x37, 0x27, 0x47 } }; { 0x18, 0x37, 0x27, 0x47 } };
memcpy(hopping_frequency, &hop[val], SGF22_RF_NUM_CHANNELS); memcpy(hopping_frequency, &hop[val], SGF22_RF_NUM_CHANNELS);
/*//Same code sze... /*//Same code sze...
hopping_frequency[0] = 0x0C + 3 * val; hopping_frequency[0] = 0x0C + 3 * val;
hopping_frequency[1] = hopping_frequency[0] + 0x1E; hopping_frequency[1] = hopping_frequency[0] + 0x1E;
@@ -110,8 +115,8 @@ static void __attribute__((unused)) SGF22_initialize_txid()
if(val ) hopping_frequency[3]++;*/ if(val ) hopping_frequency[3]++;*/
#ifdef FORCE_SGF22_ORIGINAL_ID #ifdef FORCE_SGF22_ORIGINAL_ID
rx_tx_addr[2] = 0x1F; rx_tx_addr[2] = 0x1F; // TX2:27 TX3:2B
rx_tx_addr[3] = 0x61; rx_tx_addr[3] = 0x61; // TX2:51 TX3:0C
memcpy(hopping_frequency,"\x15\x34\x24\x44", SGF22_RF_NUM_CHANNELS); //Original dump=>21=0x15,52=0x34,36=0x24,68=0x44 memcpy(hopping_frequency,"\x15\x34\x24\x44", SGF22_RF_NUM_CHANNELS); //Original dump=>21=0x15,52=0x34,36=0x24,68=0x44
#endif #endif
#if 0 #if 0
@@ -163,7 +168,7 @@ void SGF22_init()
SGF22_initialize_txid(); SGF22_initialize_txid();
SGF22_RF_init(); SGF22_RF_init();
bind_counter=SGF22_BIND_COUNT; bind_counter=SGF22_BIND_COUNT;
packet_sent = packet_count = 0x26; packet_sent = packet_count = 0x26; // TX2:26 TX3:26
phase = 0; phase = 0;
} }

View File

@@ -21,11 +21,12 @@
//#define SLT_Q200_FORCE_ID //#define SLT_Q200_FORCE_ID
// For code readability // For code readability
#define SLT_PAYLOADSIZE_V1 7 #define SLT_PAYLOADSIZE_V1 7
#define SLT_PAYLOADSIZE_V2 11 #define SLT_PAYLOADSIZE_V1_4 5
#define SLT_NFREQCHANNELS 15 #define SLT_PAYLOADSIZE_V2 11
#define SLT_TXID_SIZE 4 #define SLT_NFREQCHANNELS 15
#define SLT_BIND_CHANNEL 0x50 #define SLT_TXID_SIZE 4
#define SLT_BIND_CHANNEL 0x50
enum{ enum{
// flags going to packet[6] (Q200) // flags going to packet[6] (Q200)
@@ -93,6 +94,12 @@ static void __attribute__((unused)) SLT_set_freq(void)
} }
} }
} }
#if 0
debug("CH:");
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
debug(" %02X", hopping_frequency[i]);
debugln();
#endif
//Bind channel //Bind channel
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL; hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
@@ -129,44 +136,47 @@ static void __attribute__((unused)) SLT_build_packet()
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
for (uint8_t i = 0; i < 4; ++i) for (uint8_t i = 0; i < 4; ++i)
{ {
uint16_t v = convert_channel_10b(CH_AETR[i], false); uint16_t v = convert_channel_10b(sub_protocol != SLT_V1_4 ? CH_AETR[i] : i, false);
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) ) if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) && sub_protocol != SLT_V1_4)
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
packet[i] = v; packet[i] = v;
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0); e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
} }
// Extra bits for AETR // Extra bits for AETR
packet[4] = e; packet[4] = e;
//->V1_4CH stops here
// 8-bit channels // 8-bit channels
packet[5] = convert_channel_8b(CH5); packet[5] = convert_channel_8b(CH5);
packet[6] = convert_channel_8b(CH6); packet[6] = convert_channel_8b(CH6);
if(sub_protocol!=SLT_V1)
{ //->V1 stops here
if(sub_protocol==Q200)
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE) if(sub_protocol==Q200)
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP) packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON) |GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF); |GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
else if(sub_protocol==MR100 || sub_protocol==Q100) |GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE) else if(sub_protocol==MR100 || sub_protocol==Q100)
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP) packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but... |GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but... |GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
packet[7]=convert_channel_8b(CH7); |GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
packet[8]=convert_channel_8b(CH8); packet[7]=convert_channel_8b(CH7);
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100 packet[8]=convert_channel_8b(CH8);
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100 packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW) packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
{//Calibrate if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
packet[9]=0x77; //enter calibration {//Calibrate
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200 packet[9]=0x77; //enter calibration
packet[10]=0x20; //launch calibration if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
calib_counter++; packet[10]=0x20; //launch calibration
if(calib_counter>250) calib_counter=250; calib_counter++;
} if(calib_counter>250) calib_counter=250;
else
calib_counter=0;
} }
else
calib_counter=0;
} }
static void __attribute__((unused)) SLT_send_bind_packet() static void __attribute__((unused)) SLT_send_bind_packet()
@@ -186,6 +196,7 @@ static void __attribute__((unused)) SLT_send_bind_packet()
#define SLT_TIMING_BUILD 1000 #define SLT_TIMING_BUILD 1000
#define SLT_V1_TIMING_PACKET 1000 #define SLT_V1_TIMING_PACKET 1000
#define SLT_V1_4_TIMING_PACKET 1643
#define SLT_V2_TIMING_PACKET 2042 #define SLT_V2_TIMING_PACKET 2042
#define SLT_V1_TIMING_BIND2 1000 #define SLT_V1_TIMING_BIND2 1000
#define SLT_V2_TIMING_BIND1 6507 #define SLT_V2_TIMING_BIND1 6507
@@ -195,8 +206,9 @@ uint16_t SLT_callback()
switch (phase) switch (phase)
{ {
case SLT_BUILD: case SLT_BUILD:
//debugln_time("b ");
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730); telemetry_set_input_sync(packet_period);
#endif #endif
SLT_build_packet(); SLT_build_packet();
NRF250K_SetPower(); //Change power level NRF250K_SetPower(); //Change power level
@@ -206,42 +218,39 @@ uint16_t SLT_callback()
case SLT_DATA1: case SLT_DATA1:
case SLT_DATA2: case SLT_DATA2:
phase++; phase++;
SLT_send_packet(packet_length);
if(sub_protocol==SLT_V1) if(sub_protocol==SLT_V1)
{
SLT_send_packet(SLT_PAYLOADSIZE_V1);
return SLT_V1_TIMING_PACKET; return SLT_V1_TIMING_PACKET;
} if(sub_protocol==SLT_V1_4)
else //V2
{ {
SLT_send_packet(SLT_PAYLOADSIZE_V2); phase++; //Packets are sent two times only
return SLT_V2_TIMING_PACKET; return SLT_V1_4_TIMING_PACKET;
} }
//V2
return SLT_V2_TIMING_PACKET;
case SLT_DATA3: case SLT_DATA3:
if(sub_protocol==SLT_V1) SLT_send_packet(packet_length);
SLT_send_packet(SLT_PAYLOADSIZE_V1);
else //V2
SLT_send_packet(SLT_PAYLOADSIZE_V2);
if (++packet_count >= 100) if (++packet_count >= 100)
{// Send bind packet {// Send bind packet
packet_count = 0; packet_count = 0;
if(sub_protocol==SLT_V1) if(sub_protocol==SLT_V1||sub_protocol==SLT_V1_4)
{ {
phase=SLT_BIND2; phase=SLT_BIND2;
return SLT_V1_TIMING_BIND2; return SLT_V1_TIMING_BIND2;
} }
else //V2 //V2
{ phase=SLT_BIND1;
phase=SLT_BIND1; return SLT_V2_TIMING_BIND1;
return SLT_V2_TIMING_BIND1;
}
} }
else else
{// Continue to send normal packets {// Continue to send normal packets
phase = SLT_BUILD; phase = SLT_BUILD;
if(sub_protocol==SLT_V1) if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD; return 20000-SLT_TIMING_BUILD;
else //V2 if(sub_protocol==SLT_V1_4)
return 13730-SLT_TIMING_BUILD; return 18000-SLT_TIMING_BUILD-SLT_V1_4_TIMING_PACKET;
//V2
return 13730-SLT_TIMING_BUILD;
} }
case SLT_BIND1: case SLT_BIND1:
SLT_send_bind_packet(); SLT_send_bind_packet();
@@ -252,8 +261,10 @@ uint16_t SLT_callback()
phase = SLT_BUILD; phase = SLT_BUILD;
if(sub_protocol==SLT_V1) if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2; return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2;
else //V2 if(sub_protocol==SLT_V1_4)
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2; 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 19000; return 19000;
} }
@@ -276,6 +287,33 @@ void SLT_init()
SLT_RF_init(); SLT_RF_init();
SLT_set_freq(); SLT_set_freq();
phase = SLT_BUILD; phase = SLT_BUILD;
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)
{
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);
}
else //V2
{
packet_length = SLT_PAYLOADSIZE_V2;
#ifdef MULTI_SYNC
packet_period = 13730+2*SLT_V2_TIMING_PACKET; //~18ms
#endif
}
} }
#endif #endif
//SLT v1_4ch timing
//268363 + 1643 / 15 = 18000

View File

@@ -19,12 +19,16 @@
#include "iface_cyrf6936.h" #include "iface_cyrf6936.h"
//#define TRAXXAS_FORCE_ID #define TRAXXAS_TQ1_FORCE_ID
//#define TRAXXAS_DEBUG //#define TRAXXAS_TQ2_FORCE_ID
#define TRAXXAS_DEBUG
#define TRAXXAS_BIND_CHANNEL 0x2B #define TRAXXAS_BIND_CHANNEL 0x2B
#define TRAXXAS_CHECK_CHANNEL 0x22 #define TRAXXAS_CHECK_CHANNEL 0x22
#define TRAXXAS_PACKET_SIZE 16 #define TRAXXAS_PACKET_SIZE 16
#define TRAXXAS_TQ1_BIND_CHANNEL 0x04
#define TRAXXAS_TQ1_CHECK_CHANNEL 0x34
enum { enum {
TRAXXAS_BIND_PREP_RX=0, TRAXXAS_BIND_PREP_RX=0,
@@ -34,19 +38,22 @@ enum {
TRAXXAS_RX, TRAXXAS_RX,
TRAXXAS_PREP_DATA, TRAXXAS_PREP_DATA,
TRAXXAS_DATA, TRAXXAS_DATA,
TRAXXAS_TQ1_BIND,
TRAXXAS_TQ1_DATA1,
TRAXXAS_TQ1_DATA2,
}; };
const uint8_t PROGMEM TRAXXAS_init_vals[][2] = { const uint8_t PROGMEM TRAXXAS_init_vals[][2] = {
//Init from dump //Init from dump
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value {CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value {CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
{CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value {CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
{CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value {CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
{CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable {CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable
{CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_06_RX_CFG, 0x88 | 0x02}, // AGC enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX {CYRF_06_RX_CFG, 0x88 | 0x02}, // AGC enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX
{CYRF_1E_RX_OVERRIDE, 0x08}, // Reject packets with 0 seed {CYRF_1E_RX_OVERRIDE, 0x08}, // Reject packets with 0 seed
{CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes
}; };
static void __attribute__((unused)) TRAXXAS_cyrf_bind_config() static void __attribute__((unused)) TRAXXAS_cyrf_bind_config()
@@ -87,25 +94,58 @@ static void __attribute__((unused)) TRAXXAS_send_data_packet()
memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1); memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
//Next RF channel ? 0x00 -> keep current, 0x0E change to F=15 //Next RF channel ? 0x00 -> keep current, 0x0E change to F=15
//packet[1] = hopping_frequency[0] - 1; //packet[1] = hopping_frequency[0] - 1;
//Steering
uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000,false); //6 channels
packet[2]=ch>>8; uint16_t ch;
packet[3]=ch; for(uint8_t i=0; i<6; i++)
//Throttle {
ch = convert_channel_16b_nolimit(THROTTLE,500,1000,false); ch = convert_channel_16b_nolimit(i,500,1000,false);
packet[4]=ch>>8; packet[2+i*2]=ch>>8;
packet[5]=ch; packet[3+i*2]=ch;
//AUX3 }
ch = convert_channel_16b_nolimit(AILERON,500,1000,false);
packet[6]=ch>>8;
packet[7]=ch;
//AUX4???
ch = convert_channel_16b_nolimit(ELEVATOR,500,1000,false);
packet[12]=ch>>8;
packet[13]=ch;
CYRF_SetPower(0x08); CYRF_SetPower(0x08);
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE); CYRF_WriteDataPacket(packet);
}
static void __attribute__((unused)) TRAXXAS_TQ1_send_data_packet()
{
memcpy(&packet[1], cyrfmfg_id, 4);
if(IS_BIND_IN_PROGRESS)
{
packet_length = 8;
packet[0] = 0x2A; // Bind packet
packet[5] = 0xA0; // Bind phase 0
packet[6] = TRAXXAS_TQ1_BIND_CHANNEL-1; // Not sure...
}
else
{
packet_length = 16;
packet[0] = 0x02; // Normal packet
packet[5] = 0xA2; // Bind phase 2 = completed?
//4 channels
uint16_t ch;
for(uint8_t i=0; i<4; i++)
{
ch = convert_channel_ppm(i);
packet[6+i*2]=ch;
packet[7+i*2]=ch>>8;
}
packet[14] = hopping_frequency[0]-1; // Not sure...
}
uint8_t xor_value=0;
for(uint8_t i=0; i<packet_length-1; i++)
xor_value ^= packet[i];
packet[packet_length-1] = xor_value;
CYRF_SetPower(0x08);
CYRF_WriteDataPacketLen(packet, packet_length);
#ifdef TRAXXAS_DEBUG
debug("P:");
for(uint8_t i=0; i<packet_length; i++)
debug(" %02X",packet[i]);
debugln("");
#endif
} }
uint16_t TRAXXAS_callback() uint16_t TRAXXAS_callback()
@@ -114,6 +154,7 @@ uint16_t TRAXXAS_callback()
switch(phase) switch(phase)
{ {
//TQ2
case TRAXXAS_BIND_PREP_RX: case TRAXXAS_BIND_PREP_RX:
case TRAXXAS_PREP_RX: case TRAXXAS_PREP_RX:
//debugln("PREP_RX"); //debugln("PREP_RX");
@@ -228,6 +269,33 @@ uint16_t TRAXXAS_callback()
TRAXXAS_send_data_packet(); TRAXXAS_send_data_packet();
phase = TRAXXAS_PREP_RX; phase = TRAXXAS_PREP_RX;
return 1000; return 1000;
//TQ1
case TRAXXAS_TQ1_BIND:
if(bind_counter)
{
CYRF_ConfigRFChannel(TRAXXAS_TQ1_BIND_CHANNEL);
TRAXXAS_TQ1_send_data_packet();
bind_counter--;
if(bind_counter == 0)
{
BIND_DONE;
phase++;
}
}
return 10000;
case TRAXXAS_TQ1_DATA1:
#ifdef MULTI_SYNC
telemetry_set_input_sync(19900);
#endif
CYRF_ConfigRFChannel(TRAXXAS_TQ1_CHECK_CHANNEL);
TRAXXAS_TQ1_send_data_packet();
phase++;
return 7100;
case TRAXXAS_TQ1_DATA2:
CYRF_ConfigRFChannel(hopping_frequency[0]);
TRAXXAS_TQ1_send_data_packet();
phase = TRAXXAS_TQ1_DATA1;
return 12800;
} }
return 10000; return 10000;
} }
@@ -235,35 +303,87 @@ uint16_t TRAXXAS_callback()
void TRAXXAS_init() void TRAXXAS_init()
{ {
//Config CYRF registers //Config CYRF registers
for(uint8_t i = 0; i < sizeof(TRAXXAS_init_vals) / 2; i++) uint8_t init;
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1])); if(sub_protocol == TRAXXAS_TQ1)
{
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x48 | 0x02);
//CYRF_WriteRegister(CYRF_26_XTAL_CFG, 0x08);
init = 5;
}
else //TQ2
{
init = sizeof(TRAXXAS_init_vals) / 2;
for(uint8_t i = 0; i < init; i++)
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1]));
}
//Read CYRF ID //Read CYRF ID
CYRF_GetMfgData(cyrfmfg_id); CYRF_GetMfgData(cyrfmfg_id);
//cyrfmfg_id[0]+=RX_num; // Not needed since the TX and RX have to match //Find a free channel
CYRF_FindBestChannels(hopping_frequency,1,1,0x02,0x21); if(sub_protocol == TRAXXAS_TQ1)
#ifdef TRAXXAS_FORCE_ID // data taken from TX dump {
cyrfmfg_id[0]=0x65; // CYRF MFG ID cyrfmfg_id[3]+=RX_num; // Not needed for TQ2 since the TX and RX have to match
cyrfmfg_id[1]=0xE2; //CYRF_FindBestChannels(hopping_frequency,1,1,0x0B,0x30, FIND_CHANNEL_ANY); // Complete guess
cyrfmfg_id[2]=0x5E; }
cyrfmfg_id[3]=0x55; else //TRAXXAS_TQ2
cyrfmfg_id[4]=0x4D; CYRF_FindBestChannels(hopping_frequency,1,1,0x02,0x21, FIND_CHANNEL_ANY);
cyrfmfg_id[5]=0xFE;
hopping_frequency[0] = 0x05; // seen 05 and 0F #ifdef TRAXXAS_TQ1_FORCE_ID // data taken from TX dump
if(sub_protocol == TRAXXAS_TQ1)
{
cyrfmfg_id[0]=0xD8; // CYRF MFG ID
cyrfmfg_id[1]=0xAA;
cyrfmfg_id[2]=0x59;
cyrfmfg_id[3]=0xE6;
//cyrfmfg_id[4]=0x44; // Unused
//cyrfmfg_id[5]=0xFB; // Unused
hopping_frequency[0] = 0x0B;
}
#endif
#ifdef TRAXXAS_TQ2_FORCE_ID // data taken from TX dump
if(sub_protocol == TRAXXAS_TQ2)
{
cyrfmfg_id[0]=0x65; // CYRF MFG ID
cyrfmfg_id[1]=0xE2;
cyrfmfg_id[2]=0x5E;
cyrfmfg_id[3]=0x55;
cyrfmfg_id[4]=0x4D;
cyrfmfg_id[5]=0xFE;
hopping_frequency[0] = 0x05; // seen 05 and 0F
}
#endif #endif
#ifdef TRAXXAS_DEBUG #ifdef TRAXXAS_DEBUG
debugln("ID: %02X %02X %02X %02X %02X %02X",cyrfmfg_id[0],cyrfmfg_id[1],cyrfmfg_id[2],cyrfmfg_id[3],cyrfmfg_id[4],cyrfmfg_id[5]); debugln("ID: %02X %02X %02X %02X %02X %02X",cyrfmfg_id[0],cyrfmfg_id[1],cyrfmfg_id[2],cyrfmfg_id[3],cyrfmfg_id[4],cyrfmfg_id[5]);
debugln("RF CH: %02X",hopping_frequency[0]); debugln("RF CH: %02X",hopping_frequency[0]);
#endif #endif
if(IS_BIND_IN_PROGRESS) bind_counter=100;
if(sub_protocol == TRAXXAS_TQ1)
{ {
bind_counter=100; CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
phase = TRAXXAS_BIND_PREP_RX; CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
CYRF_WriteRegister(CYRF_26_XTAL_CFG, 0x08);
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x48);
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x21);
CYRF_WriteRegister(CYRF_03_TX_CFG, 0x0C);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]);
CYRF_SetTxRxMode(TX_EN);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x21);
if(IS_BIND_IN_PROGRESS)
phase = TRAXXAS_TQ1_BIND;
else
phase = TRAXXAS_TQ1_DATA1;
} }
else else
phase = TRAXXAS_PREP_DATA; {//TRAXXAS_TQ2
if(IS_BIND_IN_PROGRESS)
phase = TRAXXAS_BIND_PREP_RX;
else
phase = TRAXXAS_PREP_DATA;
}
// //
// phase = TRAXXAS_BIND_TX1; // phase = TRAXXAS_BIND_TX1;
// TRAXXAS_cyrf_bind_config(); // TRAXXAS_cyrf_bind_config();
@@ -273,6 +393,8 @@ void TRAXXAS_init()
} }
/* /*
Traxxas TQ 2nd generation
-------------------------
Packets 0x02: Bind learn TX/RX addresses Packets 0x02: Bind learn TX/RX addresses
CHANNEL: 0x2B CHANNEL: 0x2B
SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91 SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91
@@ -317,8 +439,8 @@ RX ID: \x4B\xA3\x2D\x1A\x49\xFE CRC 0x1A 0x3F => CRC: 65-4B=1A E2-A3=3F
RX ID: \x00\x00\x2D\x1A\x49\xFE CRC 0x65 0xE2 => CRC: 65-00=65 E2-00=E2 RX ID: \x00\x00\x2D\x1A\x49\xFE CRC 0x65 0xE2 => CRC: 65-00=65 E2-00=E2
RX ID: \x00\xFF\x2D\x1A\x49\xFE CRC 0x65 0xE3 => CRC: 65-00=65 E2-FF=E3 RX ID: \x00\xFF\x2D\x1A\x49\xFE CRC 0x65 0xE3 => CRC: 65-00=65 E2-FF=E3
RX ID: \xFF\x00\x2D\x1A\x49\xFE CRC 0x66 0xE2 => CRC: 65-FF=66 E2-00=E2 RX ID: \xFF\x00\x2D\x1A\x49\xFE CRC 0x66 0xE2 => CRC: 65-FF=66 E2-00=E2
*/
/* SOP Codes:
RX1: 02 4A A3 2D 1A 49 FE 06 00 00 02 01 06 06 00 00 RX1: 02 4A A3 2D 1A 49 FE 06 00 00 02 01 06 06 00 00
SOP: A1 78 DC 3C 9E 82 DC 3C SOP: A1 78 DC 3C 9E 82 DC 3C
RX2: 02 49 AC 4F 55 4D FE 05 00 00 02 01 06 06 00 00 RX2: 02 49 AC 4F 55 4D FE 05 00 00 02 01 06 06 00 00
@@ -347,4 +469,9 @@ Dump of SOP Codes:
20: 00 00 00 33 DE AD BA BE ??over?? 20: 00 00 00 33 DE AD BA BE ??over??
*/ */
/*
Traxxas TQ 1st generation
-------------------------
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues/967#issuecomment-2079038576
*/
#endif #endif

View File

@@ -266,6 +266,7 @@
#undef E01X_CYRF6936_INO #undef E01X_CYRF6936_INO
#undef E129_CYRF6936_INO #undef E129_CYRF6936_INO
#undef J6PRO_CYRF6936_INO #undef J6PRO_CYRF6936_INO
#undef KYOSHO3_CYRF6936_INO
#undef LOSI_CYRF6936_INO #undef LOSI_CYRF6936_INO
#undef MLINK_CYRF6936_INO #undef MLINK_CYRF6936_INO
#undef TRAXXAS_CYRF6936_INO #undef TRAXXAS_CYRF6936_INO
@@ -377,6 +378,7 @@
#undef TRAXXAS_CYRF6936_INO #undef TRAXXAS_CYRF6936_INO
#undef EAZYRC_NRF24L01_INO #undef EAZYRC_NRF24L01_INO
#undef KYOSHO2_NRF24L01_INO #undef KYOSHO2_NRF24L01_INO
#undef KYOSHO3_CYRF6936_INO
#undef MOULDKG_NRF24L01_INO #undef MOULDKG_NRF24L01_INO
#undef SHENQI_NRF24L01_INO #undef SHENQI_NRF24L01_INO
#endif #endif
@@ -432,7 +434,6 @@
#undef OMP_CCNRF_INO #undef OMP_CCNRF_INO
#undef Q303_CCNRF_INO #undef Q303_CCNRF_INO
#undef Q90C_CCNRF_INO #undef Q90C_CCNRF_INO
#undef SLT_CCNRF_INO
#undef V911S_CCNRF_INO #undef V911S_CCNRF_INO
#endif #endif

View File

@@ -487,7 +487,7 @@ void WK_init()
CYRF_SetTxRxMode(TX_EN); CYRF_SetTxRxMode(TX_EN);
hopping_frequency_no=0; hopping_frequency_no=0;
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80); CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80, FIND_CHANNEL_ANY);
CYRF_ConfigRFChannel(hopping_frequency[0]); CYRF_ConfigRFChannel(hopping_frequency[0]);
packet_count = 0; packet_count = 0;

View File

@@ -37,6 +37,7 @@ boolean enhanced;
boolean ack; boolean ack;
uint8_t pid; uint8_t pid;
uint8_t bitrate; uint8_t bitrate;
uint8_t old_option;
static void __attribute__((unused)) XN297Dump_RF_init() static void __attribute__((unused)) XN297Dump_RF_init()
{ {
@@ -609,12 +610,11 @@ static uint16_t XN297Dump_callback()
{ {
if(phase==0) if(phase==0)
{ {
address_length=3; address_length=4;
memcpy(rx_tx_addr, (uint8_t *)"\xBD\x54\x78", address_length); //"\x62\xE6\xBD\x54\x78" memcpy(rx_tx_addr, (uint8_t *)"\xF4\x71\x8D\x01", address_length); // bind \x7E\xB8\x63\xA9
bitrate=XN297DUMP_250K;
bitrate=XN297DUMP_1M;
packet_length=7; packet_length=7;
hopping_frequency_no=40; //bind ?, normal 40 hopping_frequency_no=0x50; //bind 0x50, normal ??
NRF24L01_Initialize(); NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
@@ -623,8 +623,9 @@ static uint16_t XN297Dump_callback()
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0 NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no); NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
old_option = option;
debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,hopping_frequency_no,address_length);
debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,option,address_length); //hopping_frequency_no,address_length);
switch(bitrate) switch(bitrate)
{ {
case XN297DUMP_250K: case XN297DUMP_250K:
@@ -643,6 +644,7 @@ static uint16_t XN297Dump_callback()
} }
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); //_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); //_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
phase++; phase++;
time=0;
} }
else else
{ {
@@ -650,13 +652,23 @@ static uint16_t XN297Dump_callback()
{ // RX fifo data ready { // RX fifo data ready
if(NRF24L01_ReadReg(NRF24L01_09_CD)) if(NRF24L01_ReadReg(NRF24L01_09_CD))
{ {
XN297Dump_overflow();
uint16_t timeL=TCNT1;
if(TIMER2_BASE->SR & TIMER_SR_UIF)
{//timer just rolled over...
XN297Dump_overflow();
timeL=0;
}
time=(timeH<<16)+timeL-time;
debug("RX: %5luus ", time>>1);
time=(timeH<<16)+timeL;
NRF24L01_ReadPayload(packet, packet_length); NRF24L01_ReadPayload(packet, packet_length);
//bool ok=true; //bool ok=true;
uint8_t buffer[40]; uint8_t buffer[40];
memcpy(buffer,packet,packet_length); memcpy(buffer,packet,packet_length);
//if(memcmp(&packet_in[0],&packet[0],packet_length)) //if(memcmp(&packet_in[0],&packet[0],packet_length))
{ {
debug("P:"); debug("C: %02X P:", option);
for(uint8_t i=0;i<packet_length;i++) for(uint8_t i=0;i<packet_length;i++)
debug(" %02X",packet[i]); debug(" %02X",packet[i]);
debugln(""); debugln("");
@@ -718,7 +730,12 @@ static uint16_t XN297Dump_callback()
NRF24L01_FlushRx(); NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
} }
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no); XN297Dump_overflow();
if(old_option != option)
{
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
old_option = option;
}
} }
} }
else if(sub_protocol == XN297DUMP_CC2500) else if(sub_protocol == XN297DUMP_CC2500)

View File

@@ -165,9 +165,14 @@
/*** PROTOCOLS TO INCLUDE ***/ /*** PROTOCOLS TO INCLUDE ***/
/****************************/ /****************************/
//In this section select the protocols you want to be accessible when using the module. //In this section select the protocols you want to be accessible when using the module.
//All the protocols will not fit in the Atmega328p module so you need to pick and choose. //All the protocols will not fit in the STM32 or Atmega328p modules so you need to pick and choose.
//Comment the protocols you are not using with "//" to save Flash space. //Comment the protocols you are not using with "//" to save Flash space.
//Already defined protocols selection
//#define MULTI_AIR //Only Air protocols will be available, all the others are disabled
//#define MULTI_SURFACE //Only Surface protocols will be available, all the others are disabled
//#define MULTI_EU //Only LBT/EU protocols will be available, all the others are disabled
//Protocol for module configuration //Protocol for module configuration
#define MULTI_CONFIG_INO #define MULTI_CONFIG_INO
@@ -191,6 +196,7 @@
#define E01X_CYRF6936_INO #define E01X_CYRF6936_INO
#define E129_CYRF6936_INO #define E129_CYRF6936_INO
#define J6PRO_CYRF6936_INO #define J6PRO_CYRF6936_INO
#define KYOSHO3_CYRF6936_INO
#define LOSI_CYRF6936_INO //Need DSM to be enabled #define LOSI_CYRF6936_INO //Need DSM to be enabled
#define MLINK_CYRF6936_INO #define MLINK_CYRF6936_INO
#define SCORPIO_CYRF6936_INO #define SCORPIO_CYRF6936_INO
@@ -606,6 +612,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
DSMX_1F DSMX_1F
DSMX_2F DSMX_2F
DSMR DSMR
DSM2_SFC
PROTO_DSM_RX PROTO_DSM_RX
DSM_RX DSM_RX
DSM_CLONE DSM_CLONE
@@ -682,6 +689,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FX816 FX816
FX620 FX620
FX9630 FX9630
Q560
PROTO_FY326 PROTO_FY326
FY326 FY326
FY319 FY319
@@ -738,6 +746,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
KYOSHO_HYPE KYOSHO_HYPE
PROTO_KYOSHO2 PROTO_KYOSHO2
NONE NONE
PROTO_KYOSHO3
NONE
PROTO_LOLI PROTO_LOLI
NONE NONE
PROTO_LOSI PROTO_LOSI

View File

@@ -71,7 +71,11 @@ enum CYRF_PWR {
CYRF_PWR_DEFAULT, CYRF_PWR_DEFAULT,
}; };
enum FIND_CHANNEL {
FIND_CHANNEL_ANY = 0,
FIND_CHANNEL_EVEN = 1,
FIND_CHANNEL_ODD = 2,
};
/* SPI CYRF6936 */ /* SPI CYRF6936 */
/* /*

View File

@@ -75,7 +75,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[CX10](Protocols_Details.md#CX10---12)|12|GREEN|BLUE|DM007|-|J3015_1|J3015_2|MK33041||NRF24L01|XN297 [CX10](Protocols_Details.md#CX10---12)|12|GREEN|BLUE|DM007|-|J3015_1|J3015_2|MK33041||NRF24L01|XN297
[Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936| [Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936|
[DM002](Protocols_Details.md#DM002---33)|33|||||||||NRF24L01|XN297 [DM002](Protocols_Details.md#DM002---33)|33|||||||||NRF24L01|XN297
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|||CYRF6936| [DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|DSM2SFC||CYRF6936|
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936| [DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936|
[E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936|RF2500 [E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936|RF2500
[E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297 [E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297
@@ -116,6 +116,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01| [KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
[Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105| [Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105|
[Kyosho2](Protocols_Details.md#Kyosho2---93)|93|KT-17||||||||NRF24L01| [Kyosho2](Protocols_Details.md#Kyosho2---93)|93|KT-17||||||||NRF24L01|
[Kyosho3](Protocols_Details.md#Kyosho3---98)|98|ASF||||||||CYRF6936|
[LOLI](Protocols_Details.md#LOLI---82)|82|||||||||NRF24L01| [LOLI](Protocols_Details.md#LOLI---82)|82|||||||||NRF24L01|
[Losi](Protocols_Details.md#Losi---89)|89|||||||||CYRF6936| [Losi](Protocols_Details.md#Losi---89)|89|||||||||CYRF6936|
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297 [MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
@@ -140,7 +141,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[SGF22](Protocols_Details.md#SGF22---97)|97|SGF22||||||||NRF24L01|XN297 [SGF22](Protocols_Details.md#SGF22---97)|97|SGF22||||||||NRF24L01|XN297
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900 [Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
[Skyartec](Protocols_Details.md#Skyartec---68)|68|||||||||CC2500|CC2500 [Skyartec](Protocols_Details.md#Skyartec---68)|68|||||||||CC2500|CC2500
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01|CC2500 [SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100|V1_4CH|||NRF24L01|CC2500
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01| [SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
[Traxxas](Protocols_Details.md#Traxxas---43)|43|TQ||||||||CYRF6936| [Traxxas](Protocols_Details.md#Traxxas---43)|43|TQ||||||||CYRF6936|
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01| [V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01|
@@ -368,8 +369,6 @@ TX: Axial AX-4 2.4GHz transmitter, HPI TF-41 and Panda Hobby 3CH Smart Radio 2.4
Models: Axial SCX24: Deadbolt, Jeep Wranger Rubicon, Chevrolet 1967 C10, B-17 Betty, HPI RF-50 and Panda Hobby: Tetra K1, X1, X2 Models: Axial SCX24: Deadbolt, Jeep Wranger Rubicon, Chevrolet 1967 C10, B-17 Betty, HPI RF-50 and Panda Hobby: Tetra K1, X1, X2
**Only 4 frequency hopping tables**
Extended limits supported Extended limits supported
CH1|CH2|CH3 CH1|CH2|CH3
@@ -542,12 +541,23 @@ Surface DSMR receivers
**Only 22 IDs available**, use RX num to cycle through them. **Only 22 IDs available**, use RX num to cycle through them.
Telemetry enabled, extended limits available. Telemetry enabled, extended limits available and no channel mapping. Do not use DSM/AUTO to bind but DSM/R_1F instead.
CH1|CH2|CH3|CH4|CH5|CH6|CH7 CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|--- ---|---|---|---|---|---|---
STR|THR|AUX1|AUX2|AUX3|AUX4|AUX5 STR|THR|AUX1|AUX2|AUX3|AUX4|AUX5
### Sub_protocol DSM2SFC - *6*
Surface DSM2 receivers, tested with a SR3100
Extended limits available and no channel mapping. Do not use DSM/AUTO to bind but DSM/2SFC instead.
Servo refresh rate 22/11ms is repurposed to the frame rates 16.5ms(22) and 11ms(11).
CH1|CH2|CH3
---|---|---
STR|THR|AUX1
## DSM_RX - *70* ## DSM_RX - *70*
The DSM receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,... The DSM receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
@@ -622,7 +632,7 @@ Calib is the same as the original radio with both sticks down and to the left in
Models: Eachine E129/E130 and Twister Ninja 250 Models: Eachine E129/E130 and Twister Ninja 250
### Sub_protocol C186 - *1* ### Sub_protocol C186 - *1*
Models: C186/E120, C127/E110, K127, C159, C189, C129v2 Models: RC ERA C186/E120, C127/E110, K127, C159, C189, C129v2
The FC of the heli seems to store the trims Trim A/E/R=CH7..9. If you use these trims, make sure to center them after powering off the heli or they will be added to the previous trims and over correct. The FC of the heli seems to store the trims Trim A/E/R=CH7..9. If you use these trims, make sure to center them after powering off the heli or they will be added to the previous trims and over correct.
@@ -640,6 +650,17 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
---|---|---|---|---|---|---|---|---|----|----|---- ---|---|---|---|---|---|---|---|---|----|----|----
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
## Kyosho3 - *98*
### Sub_protocol ASF - *0*
Surface protocol ASF. Models: Mini-Z.
Extended limits supported
CH1|CH2|CH3|CH4
---|---|---|---
STEERING|THROTTLE|CH3|CH4
## Losi - *89* ## Losi - *89*
TX: LSR-3000 TX: LSR-3000
@@ -672,13 +693,15 @@ CH1|CH2|CH3|CH4
A|E|T|R A|E|T|R
## Traxxas - *43* ## Traxxas - *43*
Transmitter TQ, Receivers: 6519, ECM-2.5 Transmitter TQ, Receivers: 6519, 2218(X), ECM-2.5
Extended limits supported Extended limits supported
CH1|CH2|CH3|CH4 CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|--- ---|---|---|---|---|---
AUX3|AUX4|THROTTLE|STEERING CH1|CH2|CH3|CH4|CH5|CH6
Warning from v1.3.4.7 channels order have changed
## WFLY - *40* ## WFLY - *40*
Receivers: WFR04S, WFR07S, WFR09S Receivers: WFR04S, WFR07S, WFR09S
@@ -1390,6 +1413,12 @@ FLIP: sets model into flip mode for approx 5 seconds at each throw of switch (re
MODE: -100% level, +100% acro MODE: -100% level, +100% acro
### Sub_protocol V1_4CH - *5*
CH1|CH2|CH3|CH4
---|---|---|---
CH1|CH2|CH3|CH4
## V911S - *46* ## V911S - *46*
CH1|CH2|CH3|CH4|CH5|CH6 CH1|CH2|CH3|CH4|CH5|CH6
@@ -1706,7 +1735,7 @@ Only 8 TX IDs available
Model: FX620 SU35 Model: FX620 SU35
### Sub_protocol 9630 - *2* ### Sub_protocol 9630 - *2*
Model: FX9630, FX9603 and QIDI-550 Model: FX9630, FX9603, QIDI-550
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---
@@ -1716,6 +1745,15 @@ FX9630 and FX9603 Gyro: -100%=6G small throw, 0%=6G large throw, +100%=3D
QIDI-550 Gyro: -100%=3D, 0%=6G, +100%=Torque QIDI-550 Gyro: -100%=3D, 0%=6G, +100%=Torque
### Sub_protocol Q560 - *2*
Model: QIDI-560
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|FLIP|GYRO|LEDs
FLIP and LEDs are toggle channels meaning that -100% to +100% is a command and +100% to -100% is also a command
## FY326 - *20* ## FY326 - *20*
### Sub_protocol FY326 - *0* ### Sub_protocol FY326 - *0*
@@ -1951,17 +1989,13 @@ A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
Model: JXD 509 is using Q282 with CH12=Start/Stop motors Model: JXD 509 is using Q282 with CH12=Start/Stop motors
## Realacc - *76* ## Realacc - *76*
Model: Realacc R11 Model: Realacc R11, Eachine E017
Untested protocol, let me know if it works.
Autobind protocol Autobind protocol
### Sub_protocol R11 - *0* CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|----|----
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|THR_CUT|ROTATE
---|---|---|---|---|---|---|---|---|----
A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|UNK
## Redpine - *50* ## Redpine - *50*
[Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol) [Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol)
@@ -1974,9 +2008,9 @@ Autobind protocol
Model: SGF22 Model: SGF22
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|FLIP|LIGHT|PHOTO|VIDEO A|E|T|R|MODE|FLIP|LIGHT|PHOTO|VIDEO|TRIMRESET
## Shenqi - *19* ## Shenqi - *19*
Autobind protocol Autobind protocol