Compare commits

..

42 Commits

Author SHA1 Message Date
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
21 changed files with 691 additions and 258 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
@@ -157,7 +158,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,Std,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 +169,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 +215,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

@@ -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
@@ -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";
@@ -171,6 +172,7 @@ 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_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";
@@ -258,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 },
@@ -387,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
@@ -457,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 0 #define VERSION_PATCH_LEVEL 8
#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
{ {

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
@@ -738,6 +745,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|
@@ -540,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,...
@@ -638,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
@@ -670,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
@@ -1388,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
@@ -1704,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 and QIDI-560
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---
@@ -1953,9 +1984,9 @@ Model: Realacc R11, Eachine E017
Autobind protocol Autobind protocol
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---- ---|---|---|---|---|---|---|---|---|----|----
A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|UNK A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|THR_CUT|ROTATE
## 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)
@@ -1968,9 +1999,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