Compare commits

...

44 Commits

Author SHA1 Message Date
pascallanger
7327265e55 Update Compiling.md 2025-02-22 11:23:15 +01:00
pascallanger
496c07943f KAMTOM new surface protocol
Missing low batt telem
2025-02-21 21:46:18 +01:00
pascallanger
af87b0f6d1 Update UDIRC_ccnrf.ino 2025-02-19 17:16:04 +01:00
pascallanger
2918e63fb4 XN297Emu add ReSendPayload 2025-02-19 11:54:29 +01:00
pascallanger
ed63ef7efe Update UDIRC_ccnrf.ino 2025-02-19 11:33:17 +01:00
pascallanger
36d25c7773 Update UDIRC_ccnrf.ino 2025-02-19 11:21:26 +01:00
pascallanger
a3ef2b94d4 Update MultiChan.txt 2025-02-18 19:32:19 +01:00
pascallanger
ad8b45773d UDIRC new protocol / WIP 2025-02-18 11:18:13 +01:00
pascallanger
b2dec9b331 Update Protocols_Details.md 2025-02-12 11:57:04 +01:00
pascallanger
565aaed0c7 New XK2/P10 sub protocol 2025-02-09 12:01:28 +01:00
pascallanger
2f520f2e91 Update Protocols_Details.md 2025-02-06 12:03:15 +01:00
pascallanger
f1470a80dd Update Protocols_Details.md 2025-02-06 12:00:07 +01:00
pascallanger
b6f78e93a0 Yuxiang multi IDs/Freqs 2025-02-06 11:57:40 +01:00
pascallanger
58bfd3b8b0 New JIABAILE/Gyro subprotocol 2025-02-06 11:56:24 +01:00
pascallanger
9e5e907f4a Hontai/XKK170 new subprotocol 2025-01-30 23:14:15 +01:00
pascallanger
4b68443c8f Update Multiprotocol.h 2025-01-30 10:37:53 +01:00
pascallanger
f092e137c7 Improve DSM telemetry stability? 2025-01-30 10:28:57 +01:00
pascallanger
7b9941e537 Fix DSMR 2025-01-29 19:48:18 +01:00
pascallanger
d03a8787d1 Update Protocols_Details.md 2025-01-29 10:05:23 +01:00
pascallanger
75f79095ae JIABAILE RX ID in EEPROM
Not an autobind protocol anymore.
2025-01-29 09:42:16 +01:00
pascallanger
b901bedad6 Update H36_nrf24l01.ino 2025-01-28 17:51:06 +01:00
pascallanger
dbbef9181a Update H36_nrf24l01.ino 2025-01-28 14:05:45 +01:00
pascallanger
98a54300e0 New H36 protocol - 1 ID 2025-01-28 14:00:38 +01:00
pascallanger
56fa7e788b Update Protocols_Details.md 2025-01-27 17:54:26 +01:00
pascallanger
7af23017ff Update JIABAILE_nrf24l01.ino 2025-01-27 17:37:00 +01:00
pascallanger
a07c23b25f New car protocol JIABAILE 2025-01-27 16:12:21 +01:00
pascallanger
b5b2dc37d4 SGF22 FX922 flags 2025-01-25 17:49:22 +01:00
pascallanger
756af87ec1 SGF22 Flags trial 2025-01-25 11:31:21 +01:00
pascallanger
e5810a2978 QIDI560 new light flag? 2025-01-23 15:49:35 +01:00
pascallanger
eaf71c2f49 XK2 details 2025-01-21 17:06:21 +01:00
pascallanger
546a962d96 XK2 multi IDs 2025-01-20 19:19:31 +01:00
pascallanger
fd150fa109 XK2 2nd ID 2025-01-20 16:28:48 +01:00
pascallanger
9b66711052 MT99X2/SU35 2025-01-19 16:07:45 +01:00
pascallanger
550754c7f9 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2025-01-19 15:59:42 +01:00
rdba2k
729fdd4719 Add MT99xx2/SU35 protocol (#1033)
* Update Multi.txt

* Update Multi_Protos.ino

* Update _Config.h

* Update Multiprotocol.h

* Update MT99xx_ccnrf.ino
2025-01-19 15:59:13 +01:00
pascallanger
2713b18099 Update Protocols_Details.md 2025-01-19 14:57:51 +01:00
pascallanger
5b5e95066a Traxxas TQ2&TQ1 2025-01-19 14:25:41 +01:00
pascallanger
b1f8560509 Update Yuxiang_nrf24l01.ino 2025-01-19 14:25:21 +01:00
Paul
50c18311c9 Update readme and protocol detals with surface/air info (#1034)
* Update readme and protocol detals with surface/air info

* Update Protocols_Details.md

* Update README.md

---------

Co-authored-by: pascallanger <pascal_langer@yahoo.fr>
2025-01-19 14:18:20 +01:00
Arild Langseid
95746f80a1 Add RF_SIM sub-protocol to SLT-protocol (#1061)
* Added sub-protocol RF_SIM to the SLT protocol

* fixed typo

---------

Co-authored-by: Arild Langseid <arild@langseid.no>
2025-01-19 14:14:32 +01:00
pascallanger
bb7685e7a5 Update Yuxiang_nrf24l01.ino 2025-01-18 12:24:26 +01:00
pascallanger
a44126583e Yuxiang telemetry
Offset=7, Ratio=3.5
2025-01-18 12:19:33 +01:00
pascallanger
7fbca99bf3 Yuxiang bind ok 2025-01-18 00:36:33 +01:00
pascallanger
8db90fb6fc Yuxiang remove CH8 2025-01-16 11:34:07 +01:00
23 changed files with 1599 additions and 229 deletions

View File

@@ -110,6 +110,7 @@
26,1,Hontai,JJRCX1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib 26,1,Hontai,JJRCX1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,2,Hontai,X5C1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib 26,2,Hontai,X5C1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,3,Hontai,FQ777_951,1,Flip,Arm,Pict,Video,HLess,RTH,Calib 26,3,Hontai,FQ777_951,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
26,4,Hontai,XKK170,1,Rate,Emerg,TakLan,Calib,TrimA,TrimE
57,0,HoTT,Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16 57,0,HoTT,Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
57,1,HoTT,No_Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16 57,1,HoTT,No_Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
2,0,Hubsan,H107,1,Flip,Light,Pict,Video,HLess 2,0,Hubsan,H107,1,Flip,Light,Pict,Video,HLess
@@ -171,9 +172,11 @@
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 11,5,SLT,V1_4CH,0
11,6,SLT,RF_SIM,0,CH5,CH6,CH7,CH8,CH9,CH10
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,TQ2,0
43,1,Traxxas,TQ1,0
5,0,V2x2,Std,1,Flip,Light,Pict,Video,HLess,CalX,CalY 5,0,V2x2,Std,1,Flip,Light,Pict,Video,HLess,CalX,CalY
5,1,V2x2,JXD506,1,Flip,Light,Pict,Video,HLess,StaSto,Emerg,Cam_UD 5,1,V2x2,JXD506,1,Flip,Light,Pict,Video,HLess,StaSto,Emerg,Cam_UD
48,0,V761,3CH,0,Gyro,Calib,Flip,RtnAct,Rtn,Beep 48,0,V761,3CH,0,Gyro,Calib,Flip,RtnAct,Rtn,Beep
@@ -191,7 +194,8 @@
62,0,XK,X450,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video 62,0,XK,X450,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video
62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light 62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
62,2,XK,Cars,0,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light 62,2,XK,Cars,0,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
99,0,XK2,X4,0,Rate,Mode,Hover 99,0,XK2,X4,0,Rate,Mode,Hover,Light
99,1,XK2,P10,0,Rate,Mode,Hover,Light
8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess 8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess
8,1,YD717,SkyWlkr,1,Flip,Light,Pict,Video,HLess 8,1,YD717,SkyWlkr,1,Flip,Light,Pict,Video,HLess
8,2,YD717,Simax4,1,Flip,Light,Pict,Video,HLess 8,2,YD717,Simax4,1,Flip,Light,Pict,Video,HLess
@@ -213,12 +217,18 @@
90,1,MouldKg,Digit,0 90,1,MouldKg,Digit,0
91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA 91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH 92,0,MT99xx2,PA18,0,MODE,FLIP,RTH
92,1,MT99xx2,SU35,0,Mode,LED,LED_FH,Invert,Rate
93,0,Kyosho2,KT-17,0 93,0,Kyosho2,KT-17,0
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,F22,1,Mode,Flip,LED,Pict,Video,TrRes 97,0,SGF22,F22,1,Mode,Flip,LED,Pict,Video,TrRes,Bal,HiBal
97,1,SGF22,F22S,1,Mode,Flip,LED,Pict,Video,TrRes 97,1,SGF22,F22S,1,Mode,Flip,LED,Pict,Video,TrRes
97,2,SGF22,J20,1,Mode,Flip,LED,Pict,Video
61,0,EazyRC 61,0,EazyRC
98,0,Kyosho3,ASF,0 98,0,Kyosho3,ASF,0
100,0,YuXiang,Std,0,Lock,Rate,Land,AltHol,Manual,Flip,Mode,Pitch 100,0,YuXiang,Std,0,Lock,Rate,Land,Manual,Flip,Mode,Pitch
102,0,JIABAILE,Std,0,Speed,Light,Flash
102,1,JIABAILE,Gyro,0,Speed,Light,Flash,ST_Tr
103,0,H36,Std,1,Flip,HLess,RTH
104,0,KAMTOM,Std,0,ST_Tr,TH_Tr,TH_DR

View File

@@ -292,13 +292,14 @@ uint16_t DSM_callback()
#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
#define DSM_WRITE_DELAY 1600 // Time after write to verify write complete #define DSM_WRITE_DELAY 1600 // Time after write to verify write complete
#define DSM_READ_DELAY 400 // Time before write to check read phase, and switch channels.
#else #else
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete #define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels.
#endif #endif
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet
#if defined DSM_TELEMETRY #if defined DSM_TELEMETRY
uint8_t rx_phase; uint8_t rx_phase;
uint8_t len; uint8_t length;
#endif #endif
uint8_t start; uint8_t start;
//debugln("P=%d",phase); //debugln("P=%d",phase);
@@ -474,15 +475,15 @@ uint16_t DSM_callback()
if((rx_phase & 0x07) == 0x02) if((rx_phase & 0x07) == 0x02)
{ // good data (complete with no errors) { // good data (complete with no errors)
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
len=CYRF_ReadRegister(CYRF_09_RX_COUNT); length=CYRF_ReadRegister(CYRF_09_RX_COUNT);
if(len>TELEMETRY_BUFFER_SIZE-2) if(length>TELEMETRY_BUFFER_SIZE-2)
len=TELEMETRY_BUFFER_SIZE-2; length=TELEMETRY_BUFFER_SIZE-2;
CYRF_ReadDataPacketLen(packet_in+1, len); CYRF_ReadDataPacketLen(packet_in+1, length);
#ifdef DSM_DEBUG_FWD_PGM #ifdef DSM_DEBUG_FWD_PGM
//debug(" %02X", packet_in[1]); //debug(" %02X", packet_in[1]);
if(packet_in[1]==9) if(packet_in[1]==9)
{ {
for(uint8_t i=0;i<len;i++) for(uint8_t i=0;i<length;i++)
debug(" %02X", packet_in[i+1]); debug(" %02X", packet_in[i+1]);
debugln(""); debugln("");
} }
@@ -612,10 +613,10 @@ void DSM_init()
{ {
//SUB_PROTO_VALID; //SUB_PROTO_VALID;
CYRF_GetMfgData(cyrfmfg_id); CYRF_GetMfgData(cyrfmfg_id);
}
}
//Model match //Model match
cyrfmfg_id[3]^=RX_num; cyrfmfg_id[3]^=RX_num;
}
}
//Calc sop_col //Calc sop_col
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;

View File

@@ -90,7 +90,7 @@ static void __attribute__((unused)) FX_send_packet()
// 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 ? 0x04 : 0x02)); | (Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x04 : 0x02));
if(sub_protocol == FX_Q560) if(sub_protocol == FX_Q560)
packet[5] |= GET_FLAG(CH7_SW, 0x10); // Q560 LED flag conflicting with trim_ch... packet[5] |= GET_FLAG(CH7_SW, 0x18); // Q560 LED flag 0x10 conflicting with trim_ch... Corrected on new boards using 0x08 instead
} }
else // FX816 and FX620 else // FX816 and FX620
{ {

View File

@@ -0,0 +1,132 @@
/*
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(H36_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_H36_ORIGINAL_ID
#define H36_PAYLOAD_SIZE 13
#define H36_RF_NUM_CHANNELS 4
#define H36_BIND_PACKET_PERIOD 10285
#define H36_BIND_COUNT 648 //3sec
enum {
H36_DATA1=0,
H36_DATA2,
H36_DATA3,
H36_DATA4,
};
static void __attribute__((unused)) H36_send_packet()
{
if(IS_BIND_DONE && phase == H36_DATA1)
{
hopping_frequency_no++;
hopping_frequency_no&=3;
XN297_Hopping(hopping_frequency_no);
}
packet[0] = 0x2E; // constant?
memcpy(&packet[2],rx_tx_addr,3);
if(IS_BIND_IN_PROGRESS)
{//Bind
memcpy(&packet[5],hopping_frequency,4);
memset(&packet[9], 0x00, 3);
packet[12] = 0xED; // constant?
bind_counter--;
if(bind_counter == 0)
BIND_DONE;
}
else
{//Normal
packet[5] = convert_channel_8b(THROTTLE);
packet[6] = convert_channel_8b(RUDDER);
packet[7] = convert_channel_8b(ELEVATOR);
packet[8] = convert_channel_8b(AILERON);
packet[9] = GET_FLAG(CH6_SW, 0x02) //Headless
|GET_FLAG(CH7_SW, 0x04); //RTH(temporary)
packet[10] = 0x20; //Trim A centered(0x20)
packet[11] = CH5_SW?0x60:0x20; //Flip(0x40)|Trim E centered(0x20)
packet[12] = 0xA0; //High(0x80)/Low(0x40) rates|Trim R centered(0x20)?
}
//crc
packet[1]=0xAA;
for(uint8_t i=5;i<12;i++)
packet[1] ^= packet[i];
//Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, H36_PAYLOAD_SIZE);
#ifdef DEBUG_SERIAL
debug("H%d P",hopping_frequency_no);
for(uint8_t i=0; i < H36_PAYLOAD_SIZE; i++)
debug(" %02X", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) H36_initialize_txid()
{
rx_tx_addr[0] = rx_tx_addr[3];
calc_fh_channels(4);
#ifdef FORCE_H36_ORIGINAL_ID
if(!RX_num)
{
memcpy(rx_tx_addr,(uint8_t *)"\x00\x11\x00",3);
memcpy(hopping_frequency,(uint8_t *)"\x36\x3A\x31\x2B",4); //54, 58, 49, 43
}
#endif
}
static void __attribute__((unused)) H36_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t*)"\xCC\x6C\x47\x90\x53", 5);
XN297_RFChannel(50); //Bind channel
}
uint16_t H36_callback()
{
H36_send_packet();
switch(phase)
{
case H36_DATA1:
phase++;
return 1830;
case H36_DATA2:
case H36_DATA3:
phase++;
return 3085;
default://DATA4
#ifdef MULTI_SYNC
telemetry_set_input_sync(18500);
#endif
phase = H36_DATA1;
break;
}
return 10500;
}
void H36_init()
{
BIND_IN_PROGRESS; // Autobind protocol
H36_initialize_txid();
H36_RF_init();
phase = H36_DATA1;
hopping_frequency_no = 0;
bind_counter = H36_BIND_COUNT;
}
#endif

View File

@@ -24,6 +24,10 @@
#define HONTAI_BIND_PACKET_SIZE 10 #define HONTAI_BIND_PACKET_SIZE 10
#define HONTAI_PACKET_SIZE 12 #define HONTAI_PACKET_SIZE 12
#define HONTAI_RF_BIND_CHANNEL 0 #define HONTAI_RF_BIND_CHANNEL 0
#define HONTAI_XKK170_RF_BIND_CHANNEL 20
#define HONTAI_XKK170_PACKET_PERIOD 8085
//#define FORCE_HONTAI_XKK170_ORIGINAL_ID
enum{ enum{
HONTAI_FLAG_FLIP = 0x01, HONTAI_FLAG_FLIP = 0x01,
@@ -40,6 +44,8 @@ static void __attribute__((unused)) HONTAI_send_packet()
{ {
memcpy(packet, rx_tx_addr, 5); memcpy(packet, rx_tx_addr, 5);
memset(&packet[5], 0, 3); memset(&packet[5], 0, 3);
//if(sub_protocol == HONTAI_XKK170)
// packet[6] = 0xD2;
packet_length = HONTAI_BIND_PACKET_SIZE; packet_length = HONTAI_BIND_PACKET_SIZE;
} }
else else
@@ -50,19 +56,46 @@ static void __attribute__((unused)) HONTAI_send_packet()
XN297_Hopping(hopping_frequency_no++); XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no %= 3; hopping_frequency_no %= 3;
memset(packet,0,HONTAI_PACKET_SIZE); memset(packet,0,HONTAI_PACKET_SIZE);
packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle for(uint8_t i=0; i<4; i++)
packet[4] = convert_channel_16b_limit(AILERON, 63, 0); // Aileron packet[i+3] = convert_channel_8b(CH_TAER[i]);
packet[5] = convert_channel_16b_limit(ELEVATOR, 0, 63); // Elevator if(sub_protocol != HONTAI_XKK170)
packet[6] = convert_channel_16b_limit(RUDDER, 0, 63); // Rudder {
if(sub_protocol == X5C1) //Drive trims
packet[7] = convert_channel_16b_limit(AILERON, 0, 63)-31; // Aileron trim packet[7] = (packet[4]>>3)-16;
packet[8] = (packet[6]>>3)-16;
packet[9] = (packet[5]>>3)-16;
//Reverse aileron
packet[4] ^= 0xFF;
//Limit range
for(uint8_t i=3; i<7; i++)
packet[i] >>= 2; //00..63
}
else else
packet[7] = convert_channel_16b_limit(AILERON, 0, 32)-16; // Aileron trim {//K170
packet[8] = convert_channel_16b_limit(RUDDER, 0, 32)-16; // Rudder trim //packet[2] = 0xAB; //This value keeps changing when touching any button... Left over from debug?
if (sub_protocol == X5C1) //Sticks
packet[9] = convert_channel_16b_limit(ELEVATOR, 0, 63)-31; // Elevator trim for(uint8_t i=1; i<4; i++)
else packet[i+3] = convert_channel_16b_limit(CH_TAER[i],0x28,0xD8);
packet[9] = convert_channel_16b_limit(ELEVATOR, 0, 32)-16; // Elevator trim packet[6] ^= 0xFF; //Reverse rudder
//flags
packet[1] = GET_FLAG(CH8_SW, 0x04); //Gyro calibration (momentary)
// |GET_FLAG(CH_SW, 0x08) //Unk long press second top right button (momentary)
// |GET_FLAG(CH_SW, 0x10) //Unk short press second top right button (toggle)
// |GET_FLAG(CH_SW, 0x40) //Unk short press second top left button (momentary)
// |GET_FLAG(CH_SW, 0x80); //Unk long press second top left button (momentary)
uint8_t rate = 0x80; //Mid rate
if(CH5_SW)
rate = 0xC0; //High rate
else if(Channel_data[CH5] < CHANNEL_MIN_COMMAND)
rate = 0x40; //Low rate
packet[8] = rate
|GET_FLAG(CH7_SW, 0x04) //Take-off/Landing (momentary)
|GET_FLAG(CH6_SW, 0x10); //Emergency (momentary)
//Trims
packet[7] = ((convert_channel_8b(CH9)^0xFF)>>2)-31; // Trim Aileron
packet[9] = ( convert_channel_8b(CH10) >>2)-32; // Trim Elevator
}
switch(sub_protocol) switch(sub_protocol)
{ {
case HONTAI: case HONTAI:
@@ -93,9 +126,11 @@ static void __attribute__((unused)) HONTAI_send_packet()
packet[5] |= GET_FLAG(CH11_SW, 0x80) // Calibrate packet[5] |= GET_FLAG(CH11_SW, 0x80) // Calibrate
| GET_FLAG(CH5_SW, 0x40); // Flip | GET_FLAG(CH5_SW, 0x40); // Flip
packet[6] |= GET_FLAG(CH8_SW, 0x80); // Video packet[6] |= GET_FLAG(CH8_SW, 0x80); // Video
packet[7] <<= 1; // Aileron trim
packet[8] = 0xC0 // high rate, no rudder trim packet[8] = 0xC0 // high rate, no rudder trim
| GET_FLAG(CH10_SW, 0x02) // RTH | GET_FLAG(CH10_SW, 0x02) // RTH
| GET_FLAG(CH9_SW, 0x01); // Headless | GET_FLAG(CH9_SW, 0x01); // Headless
packet[9] <<= 1; // Elevator trim
break; break;
case FQ777_951: case FQ777_951:
packet[0] = GET_FLAG(CH7_SW, 0x01) // Picture packet[0] = GET_FLAG(CH7_SW, 0x01) // Picture
@@ -109,6 +144,8 @@ static void __attribute__((unused)) HONTAI_send_packet()
packet_length = HONTAI_PACKET_SIZE; packet_length = HONTAI_PACKET_SIZE;
} }
if(sub_protocol != HONTAI_XKK170)
{
// CRC 16 bits reflected in and out // CRC 16 bits reflected in and out
crc=0xFFFF; crc=0xFFFF;
for(uint8_t i=0; i< packet_length-2; i++) for(uint8_t i=0; i< packet_length-2; i++)
@@ -116,6 +153,9 @@ static void __attribute__((unused)) HONTAI_send_packet()
crc ^= 0xFFFF; crc ^= 0xFFFF;
packet[packet_length-2]=bit_reverse(crc>>8); packet[packet_length-2]=bit_reverse(crc>>8);
packet[packet_length-1]=bit_reverse(crc); packet[packet_length-1]=bit_reverse(crc);
}
else
memset(&packet[packet_length-2], 0xAA, 2);
// Power on, TX mode, 2byte CRC // Power on, TX mode, 2byte CRC
/*if(sub_protocol == JJRCX1) /*if(sub_protocol == JJRCX1)
@@ -135,6 +175,11 @@ static void __attribute__((unused)) HONTAI_send_packet()
NRF24L01_WritePayload(packet, packet_length); NRF24L01_WritePayload(packet, packet_length);
else else
XN297_WritePayload(packet, packet_length); XN297_WritePayload(packet, packet_length);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < packet_length; i++)
debug("%02X ", packet[i]);
debugln();
#endif
} }
static void __attribute__((unused)) HONTAI_RF_init() static void __attribute__((unused)) HONTAI_RF_init()
@@ -152,15 +197,16 @@ static void __attribute__((unused)) HONTAI_RF_init()
} }
else else
{ {
XN297_SetTXAddr((const uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5); memcpy(rx_id,(const uint8_t*)"\xD2\xB5\x99\xB3\x41",5);
if(sub_protocol == HONTAI_XKK170)
rx_id[4] = 0x4A;
XN297_SetTXAddr(rx_id, 5);
//XN297_HoppingCalib(3); //XN297_HoppingCalib(3);
} }
XN297_RFChannel(HONTAI_RF_BIND_CHANNEL); XN297_RFChannel(sub_protocol==HONTAI_XKK170?HONTAI_XKK170_RF_BIND_CHANNEL:HONTAI_RF_BIND_CHANNEL);
} }
const uint8_t PROGMEM HONTAI_hopping_frequency_nonels[][3] = { const uint8_t PROGMEM HONTAI_hopping_frequency[3] = { 0x05, 0x19, 0x28 };
{0x05, 0x19, 0x28}, // Hontai
{0x0a, 0x1e, 0x2d}}; // JJRC X1
const uint8_t PROGMEM HONTAI_addr_vals[4][16] = { const uint8_t PROGMEM HONTAI_addr_vals[4][16] = {
{0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a}, {0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a},
@@ -178,32 +224,69 @@ static void __attribute__((unused)) HONTAI_init2()
data_tx_addr[2] = pgm_read_byte_near( &HONTAI_addr_vals[2][ rx_tx_addr[4] & 0x0f]); data_tx_addr[2] = pgm_read_byte_near( &HONTAI_addr_vals[2][ rx_tx_addr[4] & 0x0f]);
data_tx_addr[3] = pgm_read_byte_near( &HONTAI_addr_vals[3][(rx_tx_addr[4] >> 4) & 0x0f]); data_tx_addr[3] = pgm_read_byte_near( &HONTAI_addr_vals[3][(rx_tx_addr[4] >> 4) & 0x0f]);
data_tx_addr[4] = 0x24; data_tx_addr[4] = 0x24;
#ifdef DEBUG_SERIAL
debug("A N");
for(uint8_t i=0; i < 5; i++)
debug(" %02X", data_tx_addr[i]);
debugln();
#endif
if(sub_protocol == JJRCX1) if(sub_protocol == JJRCX1)
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, 5);
else else
XN297_SetTXAddr(data_tx_addr, 5); XN297_SetTXAddr(data_tx_addr, 5);
//Hopping frequency table //Hopping frequency table
uint8_t val;
for(uint8_t i=0;i<3;i++) for(uint8_t i=0;i<3;i++)
hopping_frequency[i]=pgm_read_byte_near( &HONTAI_hopping_frequency_nonels[sub_protocol == JJRCX1?1:0][i] ); {
if(sub_protocol==HONTAI_XKK170)
val = 60+10*i;
else
{
val = pgm_read_byte_near( &HONTAI_hopping_frequency[i] );
if(sub_protocol == JJRCX1)
val += 5;
}
hopping_frequency[i] = val;
}
hopping_frequency_no=0; hopping_frequency_no=0;
#ifdef DEBUG_SERIAL
debug("H");
for(uint8_t i=0; i < 3; i++)
debug(" %d(%02X)", hopping_frequency[i], hopping_frequency[i]);
debugln();
#endif
} }
static void __attribute__((unused)) HONTAI_initialize_txid() static void __attribute__((unused)) HONTAI_initialize_txid()
{ {
rx_tx_addr[4] = rx_tx_addr[2]; rx_tx_addr[4] = rx_tx_addr[2];
if(sub_protocol == HONTAI || sub_protocol == FQ777_951) // First three bytes some kind of model id? - set same as stock tx
{ if(sub_protocol == JJRCX1 || sub_protocol == X5C1)
rx_tx_addr[0] = 0x4c; // first three bytes some kind of model id? - set same as stock tx {//JJRCX1 & X5C1
rx_tx_addr[1] = 0x4b; rx_tx_addr[0] = 0x4B;
rx_tx_addr[2] = 0x3a; rx_tx_addr[1] = 0x59;
rx_tx_addr[2] = 0x3A;
} }
else else
{//HONTAI, FQ777_951, HONTAI_XKK170
rx_tx_addr[0] = 0x4C;
rx_tx_addr[1] = 0x4B;
rx_tx_addr[2] = 0x3A;
#ifdef FORCE_HONTAI_XKK170_ORIGINAL_ID
if(sub_protocol == HONTAI_XKK170)
{ {
rx_tx_addr[0] = 0x4b; // JJRC X1 rx_tx_addr[3] = 0x5A;
rx_tx_addr[1] = 0x59; rx_tx_addr[4] = 0x06;
rx_tx_addr[2] = 0x3a;
} }
#endif
}
#ifdef DEBUG_SERIAL
debug("A B");
for(uint8_t i=0; i < 5; i++)
debug(" %02X", rx_tx_addr[i]);
debugln();
#endif
} }
uint16_t HONTAI_callback() uint16_t HONTAI_callback()
@@ -228,8 +311,14 @@ void HONTAI_init()
{ {
BIND_IN_PROGRESS; // autobind protocol BIND_IN_PROGRESS; // autobind protocol
bind_counter = HONTAI_BIND_COUNT; bind_counter = HONTAI_BIND_COUNT;
HONTAI_initialize_txid();
HONTAI_RF_init(); HONTAI_RF_init();
packet_period = sub_protocol == FQ777_951 ? FQ777_951_PACKET_PERIOD : HONTAI_PACKET_PERIOD; HONTAI_initialize_txid();
if(sub_protocol == FQ777_951)
packet_period = FQ777_951_PACKET_PERIOD;
else if(sub_protocol == HONTAI_XKK170)
packet_period = HONTAI_XKK170_PACKET_PERIOD;
else
packet_period = HONTAI_PACKET_PERIOD;
} }
#endif #endif

View File

@@ -0,0 +1,450 @@
/*
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(JIABAILE_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_JIABAILE_ORIGINAL_ID
//#define FORCE_JIABAILE_GYRO_ORIGINAL_ID
#define JIABAILE_PAYLOAD_SIZE 8
#define JIABAILE_RX_PAYLOAD_SIZE 7
#define JIABAILE_RF_NUM_CHANNELS 3
#define JIABAILE_BIND_PACKET_PERIOD 12700
#define JIABAILE_PACKET_PERIOD 2408
#define JIABAILE_GYRO_PACKET_PERIOD 8205
#define JIABAILE_BIND_COUNT 160 //2 sec
#define JIABAILE_WRITE_TIME 1000
enum {
JIABAILE_BIND=0,
JIABAILE_RX,
JIABAILE_PREP_DATA,
JIABAILE_DATA,
};
static uint8_t __attribute__((unused)) JIABAILE_channel(uint8_t num)
{
uint8_t val=convert_channel_16b_limit(num,0,100);
if(val > 50+num)
{
packet[3] |= 0x01;
return val-50;
}
if(val < 50-num)
{
packet[3] |= 0x02;
return 50-val;
}
return 0;
}
static void __attribute__((unused)) JIABAILE_send_packet()
{
if(!(sub_protocol == JIABAILE_GYRO && IS_BIND_IN_PROGRESS))
{
hopping_frequency_no++;
if(hopping_frequency_no > 2)
hopping_frequency_no = 0;
XN297_Hopping(hopping_frequency_no);
}
if(sub_protocol == JIABAILE_STD)
{//Std
memcpy(packet,rx_tx_addr,3);
memset(&packet[3], 0x00, 4);
if(IS_BIND_DONE)
{//Normal
packet[4] = convert_channel_16b_limit(RUDDER,0,50)-25; //ST Trim
packet[6] = JIABAILE_channel(AILERON); //ST
packet[3] ^= 0x03; //Reverse ST channel
packet[3] <<= 2; //Move ST channel where it should be
packet[5] = JIABAILE_channel(ELEVATOR); //TH
packet[3] |= GET_FLAG(CH5_SW, 0x20) //Low speed
|GET_FLAG(CH7_SW, 0x40) //Flash light
|GET_FLAG(!CH6_SW, 0x80); //Light
if(!CH5_SW && Channel_data[CH5] > CHANNEL_MIN_COMMAND)
packet[3] |= 0x10; //Mid speed
}
else
{
bind_counter--;
if(!bind_counter)
{
BIND_DONE;
phase = JIABAILE_PREP_DATA;
}
}
packet[7] = 0x55 + hopping_frequency[hopping_frequency_no];
for(uint8_t i=0;i<JIABAILE_PAYLOAD_SIZE-1;i++)
packet[7] += packet[i];
}
else
{//Gyro
if(bind_counter)
{
bind_counter--;
if(!bind_counter)
{
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 4);
}
}
uint8_t crc_pos;
if(IS_BIND_IN_PROGRESS)
{
memcpy(packet,rx_tx_addr,4);
packet[4] = hopping_frequency[1];
packet[5] = hopping_frequency[2];
crc_pos = 6;
packet[7] = 0x55;
}
else
{
packet[0] = convert_channel_16b_limit(CH2,0x60,0xA0); //Throttle
packet[1] = convert_channel_16b_limit(CH1,0x40,0xC0); //Steering
if(Channel_data[CH5] < CHANNEL_MIN_COMMAND)
packet[2] = 0x02; //High speed
else if(CH5_SW)
packet[2] = 0x00; //Low speed
else
packet[2] = 0x01; //Mid speed
packet[3] = convert_channel_8b(CH3) ^0xFF; //Gyro
uint8_t val = GET_FLAG(CH6_SW, 0x04) //Light
|GET_FLAG(CH7_SW, 0x08); //Flash
if(Channel_data[CH4] > CHANNEL_MAX_COMMAND)
val |= 0x01; //Trim right
else if(Channel_data[CH4] < CHANNEL_MIN_COMMAND)
val |= 0x02; //Trim left
packet[4] = val;
packet[5] = packet[6] = 0x00; //?
crc_pos = 7;
}
uint8_t sum=0;
for(uint8_t i=0; i<crc_pos; i++)
sum += packet[i];
sum ^= 0xFF;
packet[crc_pos] = sum;
}
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, JIABAILE_PAYLOAD_SIZE);
#if 0
debug("B%d ",bind_counter);
debug("H%d RF%d",hopping_frequency_no,hopping_frequency[hopping_frequency_no]);
for(uint8_t i=0; i < JIABAILE_PAYLOAD_SIZE; i++)
debug(" %02X", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) JIABAILE_initialize_txid()
{
if(sub_protocol == JIABAILE_STD)
{//Std
rx_tx_addr[0] = rx_tx_addr[3];
#ifdef FORCE_JIABAILE_ORIGINAL_ID
memcpy(rx_tx_addr,(uint8_t *)"\xCB\x03\xA5",3);
//memcpy(rx_tx_addr,(uint8_t *)"\x3D\x08\xA2",3);
//Normal frequencies are calculated from the car ID...
//memcpy(&hopping_frequency[3],(uint8_t *)"\x23\x2D\x4B",3); //35,45,75
memcpy(&hopping_frequency[3],(uint8_t *)"\x24\x43\x4C",3); //36,67,76
#endif
//Bind frequencies
memcpy(hopping_frequency,(uint8_t *)"\x07\x27\x45",3); //7,39,69
}
else
{//Gyro
rx_tx_addr[0] += RX_num;
uint8_t val = (rx_tx_addr[0] & 0x0F) + 5; //5..20
for(uint8_t i=0; i<3; i++)
hopping_frequency[i] = val+ 20*i; //hopping_frequency[1,2] could be whatever but...
#ifdef FORCE_JIABAILE_GYRO_ORIGINAL_ID
if(RX_num)
{
memcpy(rx_tx_addr,(uint8_t *)"\x7D\x82\x28\xC2",4);
memcpy(hopping_frequency,(uint8_t *)"\x12\x1B\x35",3); //18,27,53
}
else
{
memcpy(rx_tx_addr,(uint8_t *)"\x0C\xF3\x59\xB3",4);
memcpy(hopping_frequency,(uint8_t *)"\x11\x1C\x36",3); //17,28,54
}
#endif
debugln("ID: %02X %02X %02X %02X, HOP: %2d %2d %2d",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],hopping_frequency[0],hopping_frequency[1],hopping_frequency[2]);
}
}
static void __attribute__((unused)) JIABAILE_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//Bind address
if(sub_protocol == JIABAILE_STD)
{//Std
memcpy(rx_id,(uint8_t*)"\xA7\x07\x57\xA7\x26", 5);
XN297_SetTXAddr(rx_id, 5);
XN297_SetRXAddr(rx_id, JIABAILE_RX_PAYLOAD_SIZE);
}
else
{//Gyro
XN297_SetTXAddr((uint8_t*)"\x14\x41\x11\x13", 4);
XN297_RFChannel(0x29); //41
}
}
uint16_t JIABAILE_callback()
{
uint8_t sum;
uint16_t addr;
switch(phase)
{
case JIABAILE_BIND:
phase++; // JIABAILE_RX but is overwritten if RX or bind timeout
if(XN297_IsRX())
{
if(XN297_ReadPayload(packet_in, JIABAILE_RX_PAYLOAD_SIZE))
{//CRC OK
#ifdef DEBUG_SERIAL
debug("RX");
for(uint8_t i=0; i < JIABAILE_RX_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
//RX: CB 03 A5 9D 05 A2 68
if(memcmp(packet_in,rx_tx_addr,3)==0)
{//TX ID match
//Check packet
sum=0xAA + hopping_frequency[hopping_frequency_no];
for(uint8_t i=0; i < JIABAILE_RX_PAYLOAD_SIZE-1; i++)
sum+=packet_in[i];
if(sum==packet_in[6])
{
//Write the RXID
#ifdef DEBUG_SERIAL
debug("RXID ");
for(uint8_t i=0; i < 3; i++)
debug(" %02X", packet_in[3+i]);
debugln();
#endif
addr=JIABAILE_EEPROM_OFFSET+RX_num*3;
for(uint8_t i=0;i<3;i++)
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[3+i]);
//Switch to normal mode
BIND_DONE;
phase = JIABAILE_PREP_DATA;
}
#ifdef DEBUG_SERIAL
else
debug("Wrong Sum");
}
else
debug("Wrong TX ID");
}
else
debug("Bad CRC");
debugln("");
#else
}
}
#endif
}
XN297_SetTxRxMode(TXRX_OFF);
JIABAILE_send_packet();
return JIABAILE_WRITE_TIME;
case JIABAILE_RX:
//Wait for the packet transmission to finish
while(XN297_IsPacketSent()==false);
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = JIABAILE_BIND;
return JIABAILE_BIND_PACKET_PERIOD - JIABAILE_WRITE_TIME;
case JIABAILE_PREP_DATA:
//Read the RXID
addr=JIABAILE_EEPROM_OFFSET+RX_num*3;
for(uint8_t i=0;i<3;i++)
rx_id[i+1] = eeprom_read_byte((EE_ADDR)(addr+i));
#ifdef DEBUG_SERIAL
debug("RXID ");
for(uint8_t i=0; i < 3; i++)
debug(" %02X", rx_id[i+1]);
#endif
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTXAddr(rx_id, 5);
//Set the normal frequencies
sum=rx_id[1]&0x07;
hopping_frequency[0] = (sum>4?30:8) + sum;
if(sum==4 || sum ==7)
hopping_frequency[0]++;
hopping_frequency[1] = 40 + sum;
if((sum & 0x06) == 0x06)
hopping_frequency[1] += 21;
hopping_frequency[2] = 70 + sum;
#ifdef DEBUG_SERIAL
debug(" RF");
for(uint8_t i=0; i < 3; i++)
debug(" %d", hopping_frequency[i]);
debugln();
#endif
phase++;
default: //JIABAILE_DATA
#ifdef MULTI_SYNC
telemetry_set_input_sync(packet_period);
#endif
JIABAILE_send_packet();
break;
}
return packet_period;
}
void JIABAILE_init()
{
JIABAILE_initialize_txid();
JIABAILE_RF_init();
if(sub_protocol == JIABAILE_STD)
{//Std
if(IS_BIND_IN_PROGRESS)
{
phase = JIABAILE_BIND;
bind_counter = JIABAILE_BIND_COUNT;
}
else
phase = JIABAILE_PREP_DATA;
packet_period = JIABAILE_PACKET_PERIOD;
}
else
{//Gyro
phase = JIABAILE_DATA;
bind_counter = IS_BIND_IN_PROGRESS?JIABAILE_BIND_COUNT>>2:1;
packet_period = JIABAILE_GYRO_PACKET_PERIOD;
}
hopping_frequency_no = 0;
}
#endif
/*
// CAR RX debug code
static void __attribute__((unused)) JIABAILE_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//Bind address
memcpy(rx_id,(uint8_t*)"\xA7\x07\x57\xA7\x26", 5);
XN297_SetTXAddr(rx_id, 5);
XN297_SetRXAddr(rx_id, JIABAILE_PAYLOAD_SIZE);
XN297_RFChannel(7);
rx_tx_addr[0] = 0x00;
rx_tx_addr[1] = RX_num;
rx_tx_addr[2] = 0x00;
}
uint16_t JIABAILE_callback()
{
switch(phase)
{
case JIABAILE_BIND:
if(XN297_IsRX())
{
if(XN297_ReadPayload(packet_in, JIABAILE_PAYLOAD_SIZE))
{//CRC OK
XN297_SetTxRxMode(TXRX_OFF);
#ifdef DEBUG_SERIAL
debug("RX Bind");
for(uint8_t i=0; i < JIABAILE_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
memcpy(packet,packet_in,3);
memcpy(&packet[3],rx_tx_addr,3);
packet[6]=0xAA + 7;
for(uint8_t i=0; i < JIABAILE_RX_PAYLOAD_SIZE-1; i++)
packet[6]+=packet[i];
XN297_SetTxRxMode(TX_EN);
memcpy(&rx_id[1],rx_tx_addr,3);
bind_counter = 10;
phase = JIABAILE_RX;
}
}
return JIABAILE_WRITE_TIME;
case JIABAILE_RX:
if(bind_counter)
{
bind_counter--;
XN297_WritePayload(packet, JIABAILE_RX_PAYLOAD_SIZE);
#ifdef DEBUG_SERIAL
debug("TX Bind");
for(uint8_t i=0; i < JIABAILE_RX_PAYLOAD_SIZE; i++)
debug(" %02X", packet[i]);
debugln();
#endif
return JIABAILE_PACKET_PERIOD;
}
//Wait for the packet transmission to finish
//while(XN297_IsPacketSent()==false);
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetRXAddr(rx_id, JIABAILE_PAYLOAD_SIZE);
hopping_frequency_no++;
if(hopping_frequency_no>84)
hopping_frequency_no = 0;
debug(".");
XN297_RFChannel(hopping_frequency_no);
XN297_SetTxRxMode(RX_EN);
phase = JIABAILE_DATA;
return JIABAILE_BIND_PACKET_PERIOD;
case JIABAILE_DATA:
if(XN297_IsRX())
{
debugln("");
if(XN297_ReadPayload(packet_in, JIABAILE_PAYLOAD_SIZE))
{//CRC OK
#ifdef DEBUG_SERIAL
debug("CH=%d=%02X P:",hopping_frequency_no,hopping_frequency_no);
for(uint8_t i=0; i < JIABAILE_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
#endif
//Check packet
uint8_t sum=0x55 + hopping_frequency_no;
for(uint8_t i=0; i < JIABAILE_PAYLOAD_SIZE-1; i++)
sum+=packet_in[i];
if(sum==packet_in[7])
{
debug("Good channel");
}
else
debug("Wrong Sum");
}
else
debug("Bad CRC");
debugln("");
}
phase = JIABAILE_RX;
break;
}
return JIABAILE_PACKET_PERIOD;
}
void JIABAILE_init()
{
JIABAILE_RF_init();
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = JIABAILE_BIND;
hopping_frequency_no = 7;
}
*/

View File

@@ -0,0 +1,179 @@
/*
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(KAMTOM_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_KAMTOM_ORIGINAL_ID
#define KAMTOM_PAYLOAD_SIZE 16
#define KAMTOM_RF_NUM_CHANNELS 4
#define KAMTOM_BIND_COUNT 2000
#define KAMTOM_WRITE_TIME 650
#define KAMTOM_BIND_CHANNEL 0x28 //40
#define KAMTOM_PACKET_PERIOD 3585
enum {
KAMTOM_DATA,
KAMTOM_RX,
};
static void __attribute__((unused)) KAMTOM_send_packet()
{
if(bind_counter)
{
bind_counter--;
if(!bind_counter)
BIND_DONE;
}
memset(packet, 0x00, 16);
if(IS_BIND_DONE)
{//Normal
XN297_Hopping(hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= 3;
//RXID
packet[0] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1];
//Next RF channel
packet[1] = hopping_frequency[hopping_frequency_no];
//Channels and trims
for(uint8_t i=0; i<6; i++)
{
packet[4+i] = convert_channel_s8b(CH_TAER[i]);
if(i>3) //ST_TR and TH_TR
packet[4+i] >>= 2;
}
//packet[11] = 0x00; //??
//TH_DR
packet[12] = convert_channel_16b_limit(CH7,0x25,0x64);
}
else
{
packet[1] = KAMTOM_BIND_CHANNEL;
memcpy(&packet[4],hopping_frequency,4);
packet[12] = 0xA5;
}
packet[10] = 0x40; //??
//Checksum
uint16_t sum = packet[1];
for(uint8_t i=4;i<13;i++)
sum += packet[i];
packet[13] = sum;
packet[3] = (sum>>6) & 0xFC;
//TXID
packet[14] = rx_tx_addr[2];
packet[15] = rx_tx_addr[3];
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, KAMTOM_PAYLOAD_SIZE,false);
#if 0
//def DEBUG_SERIAL
for(uint8_t i=0; i < KAMTOM_PAYLOAD_SIZE; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) KAMTOM_initialize_txid()
{
calc_fh_channels(4);
#ifdef FORCE_KAMTOM_ORIGINAL_ID
rx_tx_addr[0] = 0xC7;
rx_tx_addr[1] = 0x78;
rx_tx_addr[2] = 0x2C;
rx_tx_addr[3] = 0x25;
hopping_frequency[0] = 59;
hopping_frequency[1] = 59;
hopping_frequency[2] = 71;
hopping_frequency[3] = 65;
#endif
}
static void __attribute__((unused)) KAMTOM_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//Address
XN297_SetTXAddr((uint8_t*)"\xCC\xDD\xEE\xDD", 4);
XN297_SetRXAddr((uint8_t*)"\xCC\xDD\xEE\xDD", KAMTOM_PAYLOAD_SIZE);
XN297_RFChannel(KAMTOM_BIND_CHANNEL);
}
uint16_t KAMTOM_callback()
{
static bool rx=false;
switch(phase)
{
case KAMTOM_DATA:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
#ifdef MULTI_SYNC
telemetry_set_input_sync(KAMTOM_PACKET_PERIOD);
#endif
KAMTOM_send_packet();
if(rx)
{
uint8_t val=XN297_ReadEnhancedPayload(packet_in, KAMTOM_PAYLOAD_SIZE);
if(val==KAMTOM_PAYLOAD_SIZE)
{
BIND_DONE;
if(packet_in[0] == 0xA0 && packet_in[14] == rx_tx_addr[2] && packet_in[15] == rx_tx_addr[3])
{
rx_tx_addr[0] = packet_in[9];
rx_tx_addr[1] = packet_in[10];
//if(packet_in[1] == 0x03) // low voltage
}
#if 0
for(uint8_t i=0; i < KAMTOM_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
}
}
phase++;
return KAMTOM_WRITE_TIME;
default: //KAMTOM_RX
//{ // Wait for packet to be sent before switching to receive mode
// uint16_t start=(uint16_t)micros();
// while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
// if(XN297_IsPacketSent())
// break;
//}
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = KAMTOM_DATA;
return KAMTOM_PACKET_PERIOD - KAMTOM_WRITE_TIME;
}
return 0;
}
void KAMTOM_init()
{
KAMTOM_initialize_txid();
KAMTOM_RF_init();
bind_counter = KAMTOM_BIND_COUNT;
phase = KAMTOM_DATA;
hopping_frequency_no = 0;
}
#endif

View File

@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124 // compatible with MT99xx, Eachine H7, Yi Zhan i6S, LS114/124, QF009 Su35
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29 // Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
#if defined(MT99XX_CCNRF_INO) #if defined(MT99XX_CCNRF_INO)
@@ -96,6 +96,16 @@ enum{
FLAG_PA18_FLIP = 0x80, FLAG_PA18_FLIP = 0x80,
}; };
enum{
// flags going to packet[6] (QF009 Su35)
FLAG_SU35_6G = 0x00,
FLAG_SU35_3D = 0x40,
FLAG_SU35_HIRATE = 0x01,
FLAG_SU35_LED = 0x02,
FLAG_SU35_FLASH = 0x04,
FLAG_SU35_INVERT = 0x08,
};
const uint8_t h7_mys_byte[] = { const uint8_t h7_mys_byte[] = {
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10 0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
@@ -271,6 +281,14 @@ static void __attribute__((unused)) MT99XX_send_packet()
if(hopping_frequency_no == 0) if(hopping_frequency_no == 0)
packet[7] ^= 0x40; packet[7] ^= 0x40;
break; break;
case SU35+8:
packet[6] = FLAG_SU35_6G
| GET_FLAG( CH5_SW, FLAG_SU35_3D )
| GET_FLAG( !CH6_SW, FLAG_SU35_LED )
| GET_FLAG( CH7_SW, FLAG_SU35_FLASH )
| GET_FLAG( CH8_SW, FLAG_SU35_INVERT )
| GET_FLAG( CH9_SW, FLAG_SU35_HIRATE );
break;
} }
uint8_t result=crc8; uint8_t result=crc8;
for(uint8_t i=0; i<8; i++) for(uint8_t i=0; i<8; i++)

View File

@@ -8,7 +8,7 @@
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,V1_4CH 11,SLT,SLT_V1,SLT_V2,Q100,Q200,MR100,V1_4CH,RF_SIM
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
@@ -23,7 +23,7 @@
23,FQ777 23,FQ777
24,ASSAN 24,ASSAN
25,FrskyV 25,FrskyV
26,HONTAI,HONTAI,JJRCX1,X5C1,FQ777_951 26,HONTAI,HONTAI,JJRCX1,X5C1,FQ777_951,XKK170
27,OpnLrs 27,OpnLrs
28,AFHDS2A,PWM_IBUS,PPM_IBUS,PWM_SBUS,PPM_SBUS,PWM_IB16,PPM_IB16,PWM_SB16,PPM_SB16 28,AFHDS2A,PWM_IBUS,PPM_IBUS,PWM_SBUS,PPM_SBUS,PWM_IB16,PPM_IB16,PWM_SB16,PPM_SB16
29,Q2X2,Q222,Q242,Q282 29,Q2X2,Q222,Q242,Q282
@@ -88,12 +88,15 @@
89,Losi 89,Losi
90,MouldKg,Analog,Digit 90,MouldKg,Analog,Digit
91,Xerall 91,Xerall
92,MT99xx,PA18 92,MT99xx,PA18,SU35
93,Kyosho2,KT-17 93,Kyosho2,KT-17
94,Scorpio 94,Scorpio
95,BlueFly 95,BlueFly
96,BumbleB 96,BumbleB
97,SGF22,F22,F22S,J20 97,SGF22,F22,F22S,J20
98,Kyosho3 98,Kyosho3
99,XK2 99,XK2,X4,P10
100,YuXiang 100,YuXiang
102,JIABAILE,STD,GYRO
103,H36
104,KAMTOM

View File

@@ -55,6 +55,7 @@ const char STR_DM002[] ="DM002";
const char STR_CABELL[] ="Cabell"; const char STR_CABELL[] ="Cabell";
const char STR_ESKY150[] ="Esky150"; const char STR_ESKY150[] ="Esky150";
const char STR_ESKY150V2[] ="EskyV2"; const char STR_ESKY150V2[] ="EskyV2";
const char STR_H36[] ="H36";
const char STR_H8_3D[] ="H8 3D"; const char STR_H8_3D[] ="H8 3D";
const char STR_CORONA[] ="Corona"; const char STR_CORONA[] ="Corona";
const char STR_CFLIE[] ="CFlie"; const char STR_CFLIE[] ="CFlie";
@@ -112,6 +113,9 @@ const char STR_SGF22[] ="SGF22";
const char STR_EAZYRC[] ="EazyRC"; const char STR_EAZYRC[] ="EazyRC";
const char STR_KYOSHO3[] ="Kyosho3"; const char STR_KYOSHO3[] ="Kyosho3";
const char STR_YUXIANG[] ="YuXiang"; const char STR_YUXIANG[] ="YuXiang";
const char STR_UDIRC[] ="UDIRC";
const char STR_JIABAILE[] ="JIABAILE";
const char STR_KAMTOM[] ="KAMTOM";
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";
@@ -132,15 +136,15 @@ 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""V1_4ch"; const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0""V1_4ch""RF_SIM";
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 ";
const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805\0""A180\0 ""Dragon""F949G\0"; const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805\0""A180\0 ""Dragon""F949G\0";
const char STR_SUBTYPE_MT992[] = "\x04""PA18"; const char STR_SUBTYPE_MT992[] = "\x04""PA18""SU35";
const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix"; const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319"; const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319";
const char STR_SUBTYPE_HONTAI[] = "\x07""Std\0 ""JJRC X1""X5C1\0 ""FQ_951"; const char STR_SUBTYPE_HONTAI[] = "\x06""Std\0 ""JJRCX1""X5C1\0 ""FQ_951""XKK170";
const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16""PWM,SB16""PPM,SB16"; const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16""PWM,SB16""PPM,SB16";
const char STR_SUBTYPE_Q2X2[] = "\x04""Q222""Q242""Q282"; const char STR_SUBTYPE_Q2X2[] = "\x04""Q222""Q242""Q282";
const char STR_SUBTYPE_WK2x01[] = "\x06""WK2801""WK2401""W6_5_1""W6_6_1""W6_HeL""W6_HeI"; const char STR_SUBTYPE_WK2x01[] = "\x06""WK2801""WK2401""W6_5_1""W6_6_1""W6_HeL""W6_HeI";
@@ -162,6 +166,7 @@ const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2"; const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2";
const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0"; const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0";
const char STR_SUBTYPE_XK[] = "\x04""X450""X420""Cars"; const char STR_SUBTYPE_XK[] = "\x04""X450""X420""Cars";
const char STR_SUBTYPE_XK2[] = "\x03""X4\0""P10";
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0"; const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0";
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4"; const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z"; const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
@@ -182,6 +187,7 @@ 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""Q560"; const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630""Q560";
const char STR_SUBTYPE_SGF22[] = "\x04""F22\0""F22S""J20\0"; const char STR_SUBTYPE_SGF22[] = "\x04""F22\0""F22S""J20\0";
const char STR_SUBTYPE_JIABAILE[] = "\x04""Std\0""Gyro";
#define NO_SUBTYPE nullptr #define NO_SUBTYPE nullptr
#ifdef SEND_CPPM #ifdef SEND_CPPM
@@ -347,6 +353,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(GW008_NRF24L01_INO) #if defined(GW008_NRF24L01_INO)
{PROTO_GW008, STR_GW008, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, GW008_init, GW008_callback }, {PROTO_GW008, STR_GW008, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, GW008_init, GW008_callback },
#endif #endif
#if defined(H36_NRF24L01_INO)
{PROTO_H36, STR_H36, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, H36_init, H36_callback },
#endif
#if defined(H8_3D_NRF24L01_INO) #if defined(H8_3D_NRF24L01_INO)
{PROTO_H8_3D, STR_H8_3D, STR_SUBTYPE_H83D, 4, OPTION_NONE, 0, 0, SW_NRF, H8_3D_init, H8_3D_callback }, {PROTO_H8_3D, STR_H8_3D, STR_SUBTYPE_H83D, 4, OPTION_NONE, 0, 0, SW_NRF, H8_3D_init, H8_3D_callback },
#endif #endif
@@ -360,7 +369,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_HITEC, STR_HITEC, STR_SUBTYPE_HITEC, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, HITEC_init, HITEC_callback }, {PROTO_HITEC, STR_HITEC, STR_SUBTYPE_HITEC, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, HITEC_init, HITEC_callback },
#endif #endif
#if defined(HONTAI_NRF24L01_INO) #if defined(HONTAI_NRF24L01_INO)
{PROTO_HONTAI, STR_HONTAI, STR_SUBTYPE_HONTAI, 4, OPTION_NONE, 0, 0, SW_NRF, HONTAI_init, HONTAI_callback }, {PROTO_HONTAI, STR_HONTAI, STR_SUBTYPE_HONTAI, 5, OPTION_NONE, 0, 0, SW_NRF, HONTAI_init, HONTAI_callback },
#endif #endif
#if defined(HOTT_CC2500_INO) #if defined(HOTT_CC2500_INO)
{PROTO_HOTT, STR_HOTT, STR_SUBTYPE_HOTT, 2, OPTION_RFTUNE, 1, 0, SW_CC2500, HOTT_init, HOTT_callback }, {PROTO_HOTT, STR_HOTT, STR_SUBTYPE_HOTT, 2, OPTION_RFTUNE, 1, 0, SW_CC2500, HOTT_init, HOTT_callback },
@@ -374,12 +383,18 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(J6PRO_CYRF6936_INO) #if defined(J6PRO_CYRF6936_INO)
{PROTO_J6PRO, STR_J6PRO, NO_SUBTYPE, 0, OPTION_NONE, 0, 1, SW_CYRF, J6PRO_init, J6PRO_callback }, {PROTO_J6PRO, STR_J6PRO, NO_SUBTYPE, 0, OPTION_NONE, 0, 1, SW_CYRF, J6PRO_init, J6PRO_callback },
#endif #endif
#if defined(JIABAILE_NRF24L01_INO)
{PROTO_JIABAILE, STR_JIABAILE, STR_SUBTYPE_JIABAILE, 2, OPTION_NONE, 0, 0, SW_NRF, JIABAILE_init, JIABAILE_callback },
#endif
#if defined(JJRC345_NRF24L01_INO) #if defined(JJRC345_NRF24L01_INO)
{PROTO_JJRC345, STR_JJRC345, STR_SUBTYPE_JJRC345, 2, OPTION_NONE, 0, 0, SW_NRF, JJRC345_init, JJRC345_callback }, {PROTO_JJRC345, STR_JJRC345, STR_SUBTYPE_JJRC345, 2, OPTION_NONE, 0, 0, SW_NRF, JJRC345_init, JJRC345_callback },
#endif #endif
#if defined(JOYSWAY_A7105_INO) #if defined(JOYSWAY_A7105_INO)
{PROTO_JOYSWAY, STR_JOYSWAY, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, JOYSWAY_init, JOYSWAY_callback }, {PROTO_JOYSWAY, STR_JOYSWAY, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, JOYSWAY_init, JOYSWAY_callback },
#endif #endif
#if defined(KAMTOM_NRF24L01_INO)
{PROTO_KAMTOM, STR_KAMTOM, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, KAMTOM_init, KAMTOM_callback },
#endif
#if defined(KF606_CCNRF_INO) #if defined(KF606_CCNRF_INO)
{PROTO_KF606, STR_KF606, STR_SUBTYPE_KF606, 3, OPTION_RFTUNE, 0, 0, SW_NRF, KF606_init, KF606_callback }, {PROTO_KF606, STR_KF606, STR_SUBTYPE_KF606, 3, OPTION_RFTUNE, 0, 0, SW_NRF, KF606_init, KF606_callback },
#endif #endif
@@ -414,7 +429,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback }, {PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
#endif #endif
#if defined(MT99XX_CCNRF_INO) #if defined(MT99XX_CCNRF_INO)
{PROTO_MT99XX2, STR_MT99XX2, STR_SUBTYPE_MT992, 1, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback }, {PROTO_MT99XX2, STR_MT99XX2, STR_SUBTYPE_MT992, 2, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
#endif #endif
#if defined(NCC1701_NRF24L01_INO) #if defined(NCC1701_NRF24L01_INO)
{PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback }, {PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback },
@@ -465,7 +480,7 @@ 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, 6, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback }, {PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 7, 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 },
@@ -473,6 +488,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(TRAXXAS_CYRF6936_INO) #if defined(TRAXXAS_CYRF6936_INO)
{PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 2, 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(UDIRC_CCNRF_INO)
{PROTO_UDIRC, STR_UDIRC, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, UDIRC_init, UDIRC_callback },
#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 },
#endif #endif
@@ -499,7 +517,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_XK, STR_XK, STR_SUBTYPE_XK, 3, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback }, {PROTO_XK, STR_XK, STR_SUBTYPE_XK, 3, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
#endif #endif
#if defined(XK2_CCNRF_INO) #if defined(XK2_CCNRF_INO)
{PROTO_XK2, STR_XK2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, XK2_init, XK2_callback }, {PROTO_XK2, STR_XK2, STR_SUBTYPE_XK2, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK2_init, XK2_callback },
#endif #endif
#if defined(XN297DUMP_NRF24L01_INO) #if defined(XN297DUMP_NRF24L01_INO)
{PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 7, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback }, {PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 7, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback },

View File

@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_REVISION 4 #define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 15 #define VERSION_PATCH_LEVEL 34
#define MODE_SERIAL 0 #define MODE_SERIAL 0
@@ -75,7 +75,7 @@ enum PROTOCOLS
PROTO_NCC1701 = 44, // =>NRF24L01 PROTO_NCC1701 = 44, // =>NRF24L01
PROTO_E01X = 45, // =>CYRF6936 PROTO_E01X = 45, // =>CYRF6936
PROTO_V911S = 46, // =>NRF24L01 PROTO_V911S = 46, // =>NRF24L01
PROTO_GD00X = 47, // =>NRF24L01 PROTO_GD00X = 47, // =>CC2500 & NRF24L01
PROTO_V761 = 48, // =>NRF24L01 PROTO_V761 = 48, // =>NRF24L01
PROTO_KF606 = 49, // =>NRF24L01 PROTO_KF606 = 49, // =>NRF24L01
PROTO_REDPINE = 50, // =>CC2500 PROTO_REDPINE = 50, // =>CC2500
@@ -128,6 +128,10 @@ enum PROTOCOLS
PROTO_KYOSHO3 = 98, // =>CYRF6936 PROTO_KYOSHO3 = 98, // =>CYRF6936
PROTO_XK2 = 99, // =>CC2500 & NRF24L01 PROTO_XK2 = 99, // =>CC2500 & NRF24L01
PROTO_YUXIANG = 100, // =>NRF24L01 PROTO_YUXIANG = 100, // =>NRF24L01
PROTO_UDIRC = 101, // =>CC2500 & NRF24L01
PROTO_JIABAILE = 102, // =>NRF24L01
PROTO_H36 = 103, // =>NRF24L01
PROTO_KAMTOM = 104, // =>NRF24L01
PROTO_NANORF = 126, // =>NRF24L01 PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500 PROTO_TEST = 127, // =>CC2500
@@ -209,6 +213,7 @@ enum SLT
Q200 = 3, Q200 = 3,
MR100 = 4, MR100 = 4,
SLT_V1_4 = 5, SLT_V1_4 = 5,
RF_SIM = 6,
}; };
enum CX10 enum CX10
{ {
@@ -256,6 +261,7 @@ enum MT99XX
enum MT99XX2 enum MT99XX2
{ {
PA18 = 0, PA18 = 0,
SU35 = 1,
}; };
enum MJXQ enum MJXQ
{ {
@@ -286,7 +292,8 @@ enum HONTAI
HONTAI = 0, HONTAI = 0,
JJRCX1 = 1, JJRCX1 = 1,
X5C1 = 2, X5C1 = 2,
FQ777_951 =3, FQ777_951 = 3,
HONTAI_XKK170 = 4,
}; };
enum V2X2 enum V2X2
{ {
@@ -489,6 +496,16 @@ enum SGF22
SGF22_F22S = 1, SGF22_F22S = 1,
SGF22_J20 = 2, SGF22_J20 = 2,
}; };
enum JIABAILE
{
JIABAILE_STD = 0,
JIABAILE_GYRO = 1,
};
enum XK2
{
XK2_X4 = 0,
XK2_P10 = 1,
};
#define NONE 0 #define NONE 0
#define P_HIGH 1 #define P_HIGH 1
@@ -851,7 +868,8 @@ enum {
#define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079 #define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079
#define TRAXXAS_EEPROM_OFFSET 1079 // RX ID and SOP index, 3 bytes per model id, end is 1079+192=1271 #define TRAXXAS_EEPROM_OFFSET 1079 // RX ID and SOP index, 3 bytes per model id, end is 1079+192=1271
#define XK2_EEPROM_OFFSET 1271 // RX ID checksum, 1 byte per model, end is 1271+64=1335 #define XK2_EEPROM_OFFSET 1271 // RX ID checksum, 1 byte per model, end is 1271+64=1335
//#define CONFIG_EEPROM_OFFSET 1335 // Current configuration of the multimodule #define JIABAILE_EEPROM_OFFSET 1335 // RX ID, 3 bytes per model, end is 1335+64*3=1527
//#define CONFIG_EEPROM_OFFSET 1527 // Current configuration of the multimodule
/* STM32 Flash Size */ /* STM32 Flash Size */
#ifndef DISABLE_FLASH_SIZE_CHECK #ifndef DISABLE_FLASH_SIZE_CHECK
@@ -1110,6 +1128,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Q100 2 Q100 2
Q200 3 Q200 3
MR100 4 MR100 4
SLT_V1_4CH 5
RF_SIM 6
sub_protocol==E01X sub_protocol==E01X
E012 0 E012 0
E015 1 E015 1

View File

@@ -30,8 +30,8 @@ Multiprotocol is distributed in the hope that it will be useful,
//packet[8] //packet[8]
#define SGF22_FLAG_3D 0x00 #define SGF22_FLAG_3D 0x00
#define SGF22_FLAG_ROLL 0x08
#define SGF22_FLAG_LIGHT 0x04 #define SGF22_FLAG_LIGHT 0x04
#define SGF22_FLAG_ROLL 0x08
#define SGF22_FLAG_VIDEO 0x10 #define SGF22_FLAG_VIDEO 0x10
#define SGF22_FLAG_6G 0x40 #define SGF22_FLAG_6G 0x40
#define SGF22_FLAG_VERTICAL 0xC0 #define SGF22_FLAG_VERTICAL 0xC0
@@ -39,9 +39,13 @@ Multiprotocol is distributed in the hope that it will be useful,
#define SGF22_J20_FLAG_HORIZONTAL 0x80 #define SGF22_J20_FLAG_HORIZONTAL 0x80
//#define SGF22_J20_FLAG_SPEED 0x01 // Up/Down trim, not implemented //#define SGF22_J20_FLAG_SPEED 0x01 // Up/Down trim, not implemented
#define SGF22_FX922_FLAG_BALANCEHIGH 0x01
#define SGF22_FX922_FLAG_BALANCE 0x02
//packet[9] //packet[9]
#define SGF22_FLAG_PHOTO 0x40 // #define SGF22_J20_FLAG_INVERT 0x40
#define SGF22_FLAG_TRIMRESET 0x04 #define SGF22_FLAG_TRIMRESET 0x04
#define SGF22_FLAG_PHOTO 0x40 // #define SGF22_J20_FLAG_INVERT 0x40
#define SGF22_J20_FLAG_FIXHEIGHT 0x80 #define SGF22_J20_FLAG_FIXHEIGHT 0x80
static void __attribute__((unused)) SGF22_send_packet() static void __attribute__((unused)) SGF22_send_packet()
@@ -69,7 +73,9 @@ static void __attribute__((unused)) SGF22_send_packet()
packet[8] = SGF22_FLAG_3D // CH5 -100%, F22 & F22S - 3D mode, J20 - Gyro off packet[8] = SGF22_FLAG_3D // CH5 -100%, F22 & F22S - 3D mode, J20 - Gyro off
| GET_FLAG(CH6_SW, SGF22_FLAG_ROLL) // roll | GET_FLAG(CH6_SW, SGF22_FLAG_ROLL) // roll
| GET_FLAG(CH7_SW, SGF22_FLAG_LIGHT) // push up throttle trim for light in the stock TX | GET_FLAG(CH7_SW, SGF22_FLAG_LIGHT) // push up throttle trim for light in the stock TX
| GET_FLAG(CH9_SW, SGF22_FLAG_VIDEO); // push down throttle trim for video in the stock TX | GET_FLAG(CH9_SW, SGF22_FLAG_VIDEO) // push down throttle trim for video in the stock TX
| GET_FLAG(CH11_SW, SGF22_FX922_FLAG_BALANCE)
| GET_FLAG(CH12_SW, SGF22_FX922_FLAG_BALANCEHIGH);
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND) if(Channel_data[CH5] > CHANNEL_MAX_COMMAND)
packet[8] |= SGF22_FLAG_VERTICAL; // CH5 100%, vertical mode (torque) packet[8] |= SGF22_FLAG_VERTICAL; // CH5 100%, vertical mode (torque)
else if(Channel_data[CH5] > CHANNEL_MIN_COMMAND ) else if(Channel_data[CH5] > CHANNEL_MIN_COMMAND )
@@ -163,7 +169,7 @@ uint16_t SGF22_callback()
} }
else else
{//send 3 times in total the same packet {//send 3 times in total the same packet
NRF24L01_Strobe(REUSE_TX_PL); XN297_ReSendPayload();
phase++; phase++;
if(phase > 2) if(phase > 2)
{ {

View File

@@ -137,7 +137,7 @@ static void __attribute__((unused)) SLT_build_packet()
for (uint8_t i = 0; i < 4; ++i) for (uint8_t i = 0; i < 4; ++i)
{ {
uint16_t v = convert_channel_10b(sub_protocol != SLT_V1_4 ? CH_AETR[i] : 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) && sub_protocol != SLT_V1_4) if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) && sub_protocol != SLT_V1_4 && sub_protocol != RF_SIM)
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);
@@ -165,8 +165,13 @@ static void __attribute__((unused)) SLT_build_packet()
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but... |GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
packet[7]=convert_channel_8b(CH7); packet[7]=convert_channel_8b(CH7);
packet[8]=convert_channel_8b(CH8); packet[8]=convert_channel_8b(CH8);
if(sub_protocol==RF_SIM) {
packet[9]=convert_channel_8b(CH9);
packet[10]=convert_channel_8b(CH10);
} else {
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100 packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100 packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
}
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW) if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
{//Calibrate {//Calibrate
packet[9]=0x77; //enter calibration packet[9]=0x77; //enter calibration

View File

@@ -0,0 +1,184 @@
/*
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/>.
*/
//Models: UDIRC UD160x(PRO), Pinecone Models SG-160x, Eachine EAT15
#if defined(UDIRC_CCNRF_INO)
#include "iface_xn297.h"
#define FORCE_UDIRC_ORIGINAL_ID
#define UDIRC_PAYLOAD_SIZE 15
#define UDIRC_RF_NUM_CHANNELS 4
#define UDIRC_PACKET_PERIOD 21000
#define UDIRC_BIND_COUNT 2000
#define UDIRC_P1_P2_TIME 5000
#define UDIRC_WRITE_TIME 1500
enum {
UDIRC_DATA1=0,
UDIRC_DATA2,
UDIRC_DATA3,
UDIRC_RX,
};
static void __attribute__((unused)) UDIRC_send_packet()
{
if(rf_ch_num==0)
{
XN297_Hopping(hopping_frequency_no);
debug("H %d ",hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= 3;
}
memset(&packet[3], 0x00, 12);
if(bind_counter)
{//Bind in progress
bind_counter--;
if(bind_counter)
{//Bind
packet[0] = 0x01;
memcpy(&packet[1],rx_tx_addr,5);
}
else
{//Switch to normal
rf_ch_num = 1;
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, UDIRC_PAYLOAD_SIZE);
}
}
if(!bind_counter)
{//Normal
packet[0] = 0x08;
//Channels SG-16xx: ST/TH/CH4 /CH3 /UNK/UNK/UNK/UNK/GYRO/ST_TRIM/ST_DR
//Channels EAT15 : ST/TH/RATE/LIGHT/UNK/UNK/UNK/UNK/GYRO/ST_TRIM/ST_DR
for(uint8_t i=0; i<12; i++)
packet[i+1] = convert_channel_16b_limit(i,0,200);
//Just for now let's set the additional channels to 0
packet[5] = packet[6] = packet[7] = packet[8] = 0;
}
packet[12] = GET_FLAG(CH12_SW, 0x40) //TH.REV
|GET_FLAG(CH13_SW, 0x80); //ST.REV
//packet[13] = 00; //Unknown, future flags?
for(uint8_t i=0;i<UDIRC_PAYLOAD_SIZE-1;i++)
packet[14] += packet[i];
// Send
XN297_SetFreqOffset();
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, UDIRC_PAYLOAD_SIZE,false);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < UDIRC_PAYLOAD_SIZE; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) UDIRC_initialize_txid()
{
#ifdef FORCE_UDIRC_ORIGINAL_ID
if(RX_num)
{
rx_tx_addr[0] = 0xD0;
rx_tx_addr[1] = 0x06;
rx_tx_addr[2] = 0x00;
rx_tx_addr[3] = 0x00;
rx_tx_addr[4] = 0x81;
}
else
{
rx_tx_addr[0] = 0xF6;
rx_tx_addr[1] = 0x96;
rx_tx_addr[2] = 0x01;
rx_tx_addr[3] = 0x00;
rx_tx_addr[4] = 0x81;
}
hopping_frequency[0] = 45;
hopping_frequency[1] = 59;
hopping_frequency[2] = 52;
hopping_frequency[3] = 67;
#endif
}
static void __attribute__((unused)) UDIRC_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
//Bind address
XN297_SetTXAddr((uint8_t*)"\x01\x03\x05\x07\x09", 5);
XN297_SetRXAddr((uint8_t*)"\x01\x03\x05\x07\x09", UDIRC_PAYLOAD_SIZE);
XN297_HoppingCalib(UDIRC_RF_NUM_CHANNELS);
}
uint16_t UDIRC_callback()
{
bool rx;
switch(phase)
{
case UDIRC_DATA1:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
#ifdef MULTI_SYNC
telemetry_set_input_sync(UDIRC_PACKET_PERIOD);
#endif
UDIRC_send_packet();
if(rx)
{
uint8_t val=XN297_ReadEnhancedPayload(packet_in, UDIRC_PAYLOAD_SIZE);
debug("RX(%d):",val);
if(val != 255)
{
rf_ch_num = 1;
if(bind_counter)
bind_counter=1;
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < UDIRC_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
#endif
}
debugln("");
}
phase++;
return UDIRC_P1_P2_TIME;
case UDIRC_DATA2:
//Resend packet
XN297_ReSendPayload();
phase++;
return UDIRC_WRITE_TIME;
default: //UDIRC_RX
//Wait for the packet transmission to finish
while(XN297_IsPacketSent()==false);
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = UDIRC_DATA1;
return UDIRC_PACKET_PERIOD - UDIRC_P1_P2_TIME - UDIRC_WRITE_TIME;
}
return 0;
}
void UDIRC_init()
{
UDIRC_initialize_txid();
UDIRC_RF_init();
bind_counter = IS_BIND_IN_PROGRESS ? UDIRC_BIND_COUNT : 1;
phase = UDIRC_DATA1;
hopping_frequency_no = 0;
rf_ch_num = 0;
}
#endif

View File

@@ -321,9 +321,12 @@
#undef FY326_NRF24L01_INO #undef FY326_NRF24L01_INO
#undef GW008_NRF24L01_INO #undef GW008_NRF24L01_INO
#undef H8_3D_NRF24L01_INO #undef H8_3D_NRF24L01_INO
#undef H36_NRF24L01_INO
#undef HISKY_NRF24L01_INO #undef HISKY_NRF24L01_INO
#undef HONTAI_NRF24L01_INO #undef HONTAI_NRF24L01_INO
#undef JIABAILE_NRF24L01_INO
#undef JJRC345_NRF24L01_INO #undef JJRC345_NRF24L01_INO
#undef KAMTOM_NRF24L01_INO
#undef KN_NRF24L01_INO #undef KN_NRF24L01_INO
#undef KYOSHO2_NRF24L01_INO #undef KYOSHO2_NRF24L01_INO
#undef LOLI_NRF24L01_INO #undef LOLI_NRF24L01_INO
@@ -353,6 +356,7 @@
#undef Q303_CCNRF_INO #undef Q303_CCNRF_INO
#undef Q90C_CCNRF_INO #undef Q90C_CCNRF_INO
#undef SLT_CCNRF_INO #undef SLT_CCNRF_INO
#undef UDIRC_CCNRF_INO
#undef V911S_CCNRF_INO #undef V911S_CCNRF_INO
#undef XK_CCNRF_INO #undef XK_CCNRF_INO
#undef XK2_CCNRF_INO #undef XK2_CCNRF_INO
@@ -388,6 +392,9 @@
#undef KYOSHO3_CYRF6936_INO #undef KYOSHO3_CYRF6936_INO
#undef MOULDKG_NRF24L01_INO #undef MOULDKG_NRF24L01_INO
#undef SHENQI_NRF24L01_INO #undef SHENQI_NRF24L01_INO
#undef JIABAILE_NRF24L01_INO
#undef UDIRC_CCNRF_INO
#undef KAMTOM_NRF24L01_INO
#endif #endif
#ifdef MULTI_SURFACE #ifdef MULTI_SURFACE
@@ -421,6 +428,7 @@
#undef GW008_NRF24L01_INO #undef GW008_NRF24L01_INO
#undef HONTAI_NRF24L01_INO #undef HONTAI_NRF24L01_INO
#undef H8_3D_NRF24L01_INO #undef H8_3D_NRF24L01_INO
#undef H36_NRF24L01_INO
#undef JJRC345_NRF24L01_INO #undef JJRC345_NRF24L01_INO
#undef KN_NRF24L01_INO #undef KN_NRF24L01_INO
#undef LOLI_NRF24L01_INO #undef LOLI_NRF24L01_INO

View File

@@ -18,9 +18,11 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_xn297.h" #include "iface_xn297.h"
#define FORCE_XK2_ID //#define FORCE_XK2_ID
//#define FORCE_XK2_P10_ID
#define XK2_RF_BIND_CHANNEL 71 #define XK2_RF_BIND_CHANNEL 71
#define XK2_P10_RF_BIND_CHANNEL 69
#define XK2_PAYLOAD_SIZE 9 #define XK2_PAYLOAD_SIZE 9
#define XK2_PACKET_PERIOD 4911 #define XK2_PACKET_PERIOD 4911
#define XK2_RF_NUM_CHANNELS 4 #define XK2_RF_NUM_CHANNELS 4
@@ -46,7 +48,7 @@ static void __attribute__((unused)) XK2_send_packet()
//Unknown //Unknown
packet[7] = 0x00; packet[7] = 0x00;
//Checksum seed //Checksum seed
packet[8] = 0xC0; //Constant? packet[8] = 0xC0;
} }
else else
{ {
@@ -70,19 +72,23 @@ static void __attribute__((unused)) XK2_send_packet()
//Flags //Flags
packet[5] = GET_FLAG(CH5_SW, 0x01) //Rate packet[5] = GET_FLAG(CH5_SW, 0x01) //Rate
| GET_FLAG(CH6_SW, 0x08) //Mode | GET_FLAG(CH6_SW, 0x08) //Mode
| GET_FLAG(CH7_SW, 0x20); //Hover | GET_FLAG(CH7_SW, 0x20) //Hover
| GET_FLAG(CH8_SW, 0x40); //Light
//Telemetry not received=00, Telemetry received=01 but sometimes switch to 1 even if telemetry is not there... //Telemetry not received=00, Telemetry received=01 but sometimes switch to 1 even if telemetry is not there...
packet[6] = 0x00; packet[6] = 0x00;
//Unknown //RXID checksum
packet[7] = crc8; //?? RX_ID checksum ?? => sum RX_ID[0..2] packet[7] = crc8; //Sum RX_ID[0..2]
//Checksum seed //Checksum seed
packet[8] = 0x7F; //Constant? packet[8] = num_ch; //Based on TX ID
} }
//Checksum //Checksum
for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++) for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++)
packet[8] += packet[i]; packet[8] += packet[i];
if(sub_protocol == XK2_P10)
packet[8] += 0x10;
// Send // Send
XN297_SetFreqOffset();
XN297_SetPower(); XN297_SetPower();
XN297_SetTxRxMode(TX_EN); XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, XK2_PAYLOAD_SIZE); XN297_WritePayload(packet, XK2_PAYLOAD_SIZE);
@@ -102,20 +108,50 @@ static void __attribute__((unused)) XK2_RF_init()
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", XK2_PAYLOAD_SIZE); XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", XK2_PAYLOAD_SIZE);
XN297_HoppingCalib(XK2_RF_NUM_CHANNELS); XN297_HoppingCalib(XK2_RF_NUM_CHANNELS);
XN297_RFChannel(XK2_RF_BIND_CHANNEL); XN297_RFChannel(sub_protocol==XK2_X4?XK2_RF_BIND_CHANNEL:XK2_P10_RF_BIND_CHANNEL);
} }
static void __attribute__((unused)) XK2_initialize_txid() static void __attribute__((unused)) XK2_initialize_txid()
{ {
rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num
num_ch = 0x21 + rx_tx_addr[0] - rx_tx_addr[1] + rx_tx_addr[2];
//RF frequencies for X4: 65=0x41, 69=0x45, 73=0x49, 77=0x4D
//RF frequencies for P10: 67, unknown
uint8_t start = 65;
if(sub_protocol == XK2_P10) start += 2;
for(uint8_t i=0;i<XK2_RF_NUM_CHANNELS;i++)
hopping_frequency[i] = start + i*4;
#ifdef FORCE_XK2_ID #ifdef FORCE_XK2_ID
if(rx_tx_addr[3]&1)
{//Pascal
rx_tx_addr[0] = 0x66; rx_tx_addr[0] = 0x66;
rx_tx_addr[1] = 0x4F; rx_tx_addr[1] = 0x4F;
rx_tx_addr[2] = 0x47; rx_tx_addr[2] = 0x47;
for(uint8_t i=0;i<XK2_RF_NUM_CHANNELS;i++) num_ch = 0x7F;
hopping_frequency[i] = 65 + i*4; //65=0x41, 69=0x45, 73=0x49, 77=0x4D //hopping frequencies 65=0x41, 69=0x45, 73=0x49, 77=0x4D
}
else
{//Marc
rx_tx_addr[0] = 0x36;
rx_tx_addr[1] = 0x49;
rx_tx_addr[2] = 0x6B;
num_ch = 0x79;
//hopping frequencies 65=0x41, 69=0x45, 73=0x49, 77=0x4D
}
#endif #endif
rx_tx_addr[3] = 0xCC; #ifdef FORCE_XK2_P10_ID
rx_tx_addr[4] = 0xCC; rx_tx_addr[0] = 0xE8;
rx_tx_addr[1] = 0x25;
rx_tx_addr[2] = 0x3B;
num_ch = 0x1F;
//hopping frequencies 67=0x43, =0x, =0x, =0x
#endif
rx_tx_addr[3] = rx_tx_addr[4] = 0xCC;
debugln("ID: %02X %02X %02X %02X %02X, OFFSET: %02X, HOP: %02X %02X %02X %02X",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],rx_tx_addr[4],num_ch,hopping_frequency[0],hopping_frequency[1],hopping_frequency[2],hopping_frequency[3]);
} }
uint16_t XK2_callback() uint16_t XK2_callback()
@@ -138,11 +174,11 @@ uint16_t XK2_callback()
debug(" %02X",packet[i]); debug(" %02X",packet[i]);
debugln(""); debugln("");
#endif #endif
//phase = XK2_BIND1;
//return 500;
crc8 = 0xBF; crc8 = 0xBF;
for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++) for(uint8_t i=0; i<XK2_PAYLOAD_SIZE-1; i++)
crc8 += packet[i]; crc8 += packet[i];
if(sub_protocol == XK2_P10)
crc8 += 0x10;
if(crc8 != packet[8]) if(crc8 != packet[8])
{ {
phase = XK2_BIND1; phase = XK2_BIND1;
@@ -271,11 +307,12 @@ P[4] = alternates 20,60,A0,E0
P[5] = flags P[5] = flags
01=high rate 01=high rate
20=hover=long_press_left 20=hover=long_press_left
40=light -> temporary
08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0 08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0
P[6] = 00 telemetry nok P[6] = 00 telemetry nok
01 telemetry ok but sometimes switch to 1 also when telemetry is nok... 01 telemetry ok but sometimes switch to 1 also when telemetry is nok...
P[7] = 5A -> ?? RX_ID checksum ?? => sum RX_ID[0..2] P[7] = 5A -> sum RX_ID[0..2]
P[8] = sum P[0..7] + 7F P[8] = sum P[0..7] + TX_ID[0] - TX_ID[1] + TX_ID[2] + 21
Telemetry Telemetry
RX on channel: 69, Time: 3408us P: 66 4F 47 00 00 00 00 00 C8 RX on channel: 69, Time: 3408us P: 66 4F 47 00 00 00 00 00 C8
@@ -296,3 +333,48 @@ RF
2465 155330 3577 2465 155330 3577
*/ */
/* P10 Piper CUB
Bind
----
Phase 1
Plane sends these packets:
250K C=69 S=Y A= CC CC CC CC CC P(9)= 9C BB CC DD 84 24 20 00 97
P[0] = 9C bind phase 1
P[1] = Dummy TX_ID
P[2] = Dummy TX_ID
P[3] = Dummy TX_ID
P[4] = RX_ID[0]
P[5] = RX_ID[1]
P[6] = RX_ID[2]
P[7] = 00
P[8] = sum P[0..7] + BF + 10
Normal
------
TX sends
C=67 -> only one channel when telemetry is working
A= E8 25 3B CC CC P(9)= 32 32 00 32 A0 40 01 C8 6E
P[0] = A 00..32..64
P[1] = E 00..32..64
P[2] = T 00..64
P[3] = R 00..32..64
P[4] = alternates 20,60,A0,E0
trims
A 01..20..3F
E 41..60..7F
R 81..A0..BF
telemetry
E0 present when the telemetry works
6g/3d
C1 few times if P[6] flag 00->08
C0 few times if P[6] = flag 08->00
P[5] = flags
01=high rate
20=hover=long_press_left
40=light -> temporary
08=6g/3d=short_press_right sequece also switches for a few packets to C1 if 8 C0 if 0
P[6] = 00 telemetry nok
01 telemetry ok but sometimes switch to 1 also when telemetry is nok...
P[7] = C8 -> sum RX_ID[0..2]
P[8] = sum P[0..7] + TX_ID[0] - TX_ID[1] + TX_ID[2] + 21 +10
*/

View File

@@ -207,6 +207,27 @@ static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State mode)
#endif #endif
} }
#ifdef CC2500_INSTALLED
uint8_t XN297_Buffer[32];
uint8_t XN297_Buffer_Len = 0;
static void __attribute__((unused)) XN297_SendCC2500Payload()
{
// stop TX/RX
CC2500_Strobe(CC2500_SIDLE);
// flush tx FIFO
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_06_PKTLEN, XN297_Buffer_Len + 4); // Packet len, fix packet len
// xn297L preamble
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4);
// xn297 packet
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, XN297_Buffer, XN297_Buffer_Len);
// transmit
CC2500_Strobe(CC2500_STX);
}
#endif
static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len) static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len)
{ {
#ifdef NRF24L01_INSTALLED #ifdef NRF24L01_INSTALLED
@@ -220,22 +241,25 @@ static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len)
#ifdef CC2500_INSTALLED #ifdef CC2500_INSTALLED
if(xn297_rf == XN297_CC2500) if(xn297_rf == XN297_CC2500)
{ {
// stop TX/RX memcpy(XN297_Buffer, msg, len);
CC2500_Strobe(CC2500_SIDLE); XN297_Buffer_Len = len;
// flush tx FIFO XN297_SendCC2500Payload();
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_06_PKTLEN, len + 4); // Packet len, fix packet len
// xn297L preamble
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4);
// xn297 packet
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, msg, len);
// transmit
CC2500_Strobe(CC2500_STX);
} }
#endif #endif
} }
static void __attribute__((unused)) XN297_ReSendPayload()
{
#ifdef NRF24L01_INSTALLED
if(xn297_rf == XN297_NRF)
NRF24L01_Strobe(NRF24L01_E3_REUSE_TX_PL);
#endif
#ifdef CC2500_INSTALLED
if(xn297_rf == XN297_CC2500)
XN297_SendCC2500Payload();
#endif
}
static void __attribute__((unused)) XN297_WritePayload(uint8_t* msg, uint8_t len) static void __attribute__((unused)) XN297_WritePayload(uint8_t* msg, uint8_t len)
{ {
uint8_t buf[32]; uint8_t buf[32];
@@ -329,9 +353,9 @@ static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uin
last++; last++;
buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
}
if(xn297_scramble_enabled) if(xn297_scramble_enabled)
buf[last] ^= xn297_scramble[scramble_index++] & 0xc0; buf[last] ^= xn297_scramble[scramble_index++] & 0xc0;
}
// crc // crc
if (xn297_crc) if (xn297_crc)
@@ -351,8 +375,7 @@ static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uin
buf[last++] = (crc & 0xff) << 6; buf[last++] = (crc & 0xff) << 6;
} }
pid++; pid++;
if(pid>3) pid &= 0x03;
pid=0;
// send packet // send packet
XN297_SendPayload(buf, last); XN297_SendPayload(buf, last);
@@ -440,7 +463,6 @@ static uint8_t __attribute__((unused)) XN297_ReadEnhancedPayload(uint8_t* msg, u
// Read payload // Read payload
XN297_ReceivePayload(buffer, len+2); // Read pcf + payload + CRC XN297_ReceivePayload(buffer, len+2); // Read pcf + payload + CRC
// Decode payload // Decode payload
pcf_size = buffer[0]; pcf_size = buffer[0];
if(xn297_scramble_enabled) if(xn297_scramble_enabled)

View File

@@ -17,16 +17,16 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_xn297.h" #include "iface_xn297.h"
#define YUXIANG_FORCE_ID //#define YUXIANG_FORCE_ID
#define YUXIANG_PACKET_PERIOD 12430 #define YUXIANG_PACKET_PERIOD 12422
#define YUXIANG_PACKET_SIZE 9 #define YUXIANG_PACKET_SIZE 9
#define YUXIANG_BIND_COUNT 20000 #define YUXIANG_BIND_COUNT 150
#define YUXIANG_BIND_FREQ 0x30 #define YUXIANG_BIND_FREQ 0x30 //48
#define YUXIANG_RF_NUM_CHANNELS 4 #define YUXIANG_RF_NUM_CHANNELS 4
#define YUXIANG_WRITE_TIME 1000 #define YUXIANG_WRITE_TIME 1000
#define YUXIANG_TELEM_DEBUG //#define YUXIANG_TELEM_DEBUG
enum enum
{ {
@@ -36,42 +36,47 @@ enum
static void __attribute__((unused)) YUXIANG_send_packet() static void __attribute__((unused)) YUXIANG_send_packet()
{ {
static bool bind_state = false; if(bind_counter && packet_sent < 5 && (hopping_frequency_no & 0x07) == 0)
if(bind_counter && (hopping_frequency_no & 0x0E) == 0)
{ {
bind_counter--; bind_counter--;
if(!bind_counter) if(!bind_counter)
BIND_DONE; BIND_DONE;
XN297_Hopping(YUXIANG_BIND_FREQ); #if 0
debug("B C:%d, ",YUXIANG_BIND_FREQ);
#endif
XN297_RFChannel(YUXIANG_BIND_FREQ);
XN297_SetTXAddr((uint8_t*)"\x00\x00\x00\x00\x00", 5); XN297_SetTXAddr((uint8_t*)"\x00\x00\x00\x00\x00", 5);
XN297_SetRXAddr((uint8_t*)"\x00\x00\x00\x00\x00", YUXIANG_PACKET_SIZE); bind_phase = 1;
bind_state = true; packet_sent++;
} }
else else
{ {//Normal operation
XN297_Hopping(hopping_frequency_no & 0x03); XN297_Hopping(hopping_frequency_no & 0x03);
if(bind_state) #if 0
debug("C:%d, ",hopping_frequency[hopping_frequency_no & 0x03]);
#endif
hopping_frequency_no++;
if(bind_phase)
{ {
XN297_SetTXAddr(rx_tx_addr, 5); XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, YUXIANG_PACKET_SIZE); XN297_SetRXAddr(rx_tx_addr, YUXIANG_PACKET_SIZE);
bind_state = false; bind_phase = 0;
packet_sent = 0;
} }
} }
hopping_frequency_no++;
packet[0] = GET_FLAG(!bind_state, 0x80) // Bind packet packet[0] = GET_FLAG(!bind_phase, 0x80) // Bind packet
| GET_FLAG(telemetry_lost, 0x20) // No telem | GET_FLAG(telemetry_lost, 0x20) // No telem
| GET_FLAG(!CH5_SW, 0x10) // Lock | GET_FLAG(!CH5_SW, 0x10) // Lock
| GET_FLAG(CH6_SW, 0x08) // High | GET_FLAG(CH6_SW, 0x08) // High
| GET_FLAG(CH12_SW, 0x01); // Screw pitch -> temporary | GET_FLAG(CH11_SW, 0x01); // Screw pitch -> temporary
packet[1] = GET_FLAG(CH7_SW, 0x08) // Land only when unlock packet[1] = GET_FLAG(CH7_SW, 0x08) // Land only when unlock
| GET_FLAG(CH11_SW, 0x20); // Mode | GET_FLAG(CH10_SW, 0x20); // Mode
packet[2] = GET_FLAG(CH8_SW, 0x02) // Altitude hold packet[2] = GET_FLAG(CH5_SW, 0x02) // Altitude hold set when unlock
| GET_FLAG(CH9_SW, 0x03) // Manual | GET_FLAG(CH8_SW, 0x01) // Manual
| GET_FLAG(CH10_SW, 0x40); // Flip | GET_FLAG(CH9_SW, 0x40); // Flip
uint16_t value = convert_channel_16b_limit(AILERON,0,1000); uint16_t value = convert_channel_16b_limit(AILERON,0,1000);
packet[3] = value; packet[3] = value;
@@ -86,17 +91,15 @@ static void __attribute__((unused)) YUXIANG_send_packet()
packet[6] = value; packet[6] = value;
packet[7] |= (value >> 2) & 0xC0; packet[7] |= (value >> 2) & 0xC0;
if(bind_state && (hopping_frequency_no&1)) if(bind_phase)
memcpy(&packet[3], rx_tx_addr, 4); memcpy(&packet[3], rx_tx_addr, 4);
else
packet[0] |= 0x80;
uint8_t checksum = 0; uint8_t checksum = 0;
for(uint8_t i=0; i<YUXIANG_PACKET_SIZE-1; i++) for(uint8_t i=0; i<YUXIANG_PACKET_SIZE-1; i++)
checksum += packet[i]; checksum += packet[i];
packet[8] = checksum; packet[8] = checksum;
#if 1 #if 0
debug("P:"); debug("P:");
for(uint8_t i=0;i<YUXIANG_PACKET_SIZE;i++) for(uint8_t i=0;i<YUXIANG_PACKET_SIZE;i++)
debug(" %02X",packet[i]); debug(" %02X",packet[i]);
@@ -111,34 +114,52 @@ static void __attribute__((unused)) YUXIANG_send_packet()
static void __attribute__((unused)) YUXIANG_RF_init() static void __attribute__((unused)) YUXIANG_RF_init()
{ {
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, YUXIANG_PACKET_SIZE);
} }
static void __attribute__((unused)) YUXIANG_initialize_txid() static void __attribute__((unused)) YUXIANG_initialize_txid()
{ {
#ifdef YUXIANG_FORCE_ID //Modify address to influence hop
if(RX_num==0) rx_tx_addr[0] += RX_num;
{//TX1 //Calc hop
memcpy(rx_tx_addr,(uint8_t *)"\xB3\x13\x36\xDD",4); //rx_tx_addr[4]=0xD9 uint8_t val;
memcpy(hopping_frequency,(uint8_t *)"\x49\x32\x35\x42",4); for(uint8_t i=0; i<4; i++)
{
val = i*0x06;
if(i) val |= 0x01;
val += rx_tx_addr[0];
val &= 0x1F;
val += 47;
if(val < 50)
val = 50;
if(val > 62 && val < 66)
val = 62;
hopping_frequency[i] = val;
} }
else
{//TX2 #ifdef YUXIANG_FORCE_ID
switch(RX_num)
{
case 0://TX1
memcpy(rx_tx_addr,(uint8_t *)"\xB3\x13\x36\xDD",4); //rx_tx_addr[4]=0xD9
memcpy(hopping_frequency,(uint8_t *)"\x42\x49\x32\x35",4); //66,73,50,53
break;
case 1://TX2
memcpy(rx_tx_addr,(uint8_t *)"\xEB\x13\x36\xAC",4); //rx_tx_addr[4]=0xE0 memcpy(rx_tx_addr,(uint8_t *)"\xEB\x13\x36\xAC",4); //rx_tx_addr[4]=0xE0
memcpy(hopping_frequency,(uint8_t *)"\x4D\x3A\x3E\x47",4); memcpy(hopping_frequency,(uint8_t *)"\x47\x4D\x3A\x3E",4); //58,62,71,77
break;
} }
#endif #endif
uint8_t sum=0; uint8_t sum=0;
for(uint8_t i=0; i<4; i++) for(uint8_t i=0; i<4; i++)
sum += rx_tx_addr[i]; sum += rx_tx_addr[i];
rx_tx_addr[4] = sum; rx_tx_addr[4] = sum;
debugln("ID: %02X %02X %02X %02X %02X , HOP: %02X %02X %02X %02X",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],rx_tx_addr[4],hopping_frequency[0],hopping_frequency[1],hopping_frequency[2],hopping_frequency[3]); debugln("ID: %02X %02X %02X %02X %02X , HOP: %2d %2d %2d %2d",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],rx_tx_addr[4],hopping_frequency[0],hopping_frequency[1],hopping_frequency[2],hopping_frequency[3]);
} }
uint16_t YUXIANG_callback() uint16_t YUXIANG_callback()
{ {
static bool rx = false; bool rx = false;
switch(phase) switch(phase)
{ {
@@ -152,7 +173,7 @@ uint16_t YUXIANG_callback()
packet_count++; packet_count++;
#endif #endif
#ifdef MULTI_SYNC #ifdef MULTI_SYNC
telemetry_set_input_sync(packet_period); telemetry_set_input_sync(YUXIANG_PACKET_PERIOD);
#endif #endif
YUXIANG_send_packet(); YUXIANG_send_packet();
if(rx) if(rx)
@@ -162,18 +183,22 @@ uint16_t YUXIANG_callback()
#endif #endif
if(XN297_ReadPayload(packet_in, YUXIANG_PACKET_SIZE)) if(XN297_ReadPayload(packet_in, YUXIANG_PACKET_SIZE))
{ // packet with good CRC and length { // packet with good CRC and length
#ifdef YUXIANG_TELEM_DEBUG
debug("OK:");
for(uint8_t i=0;i<YUXIANG_PACKET_SIZE;i++)
debug(" %02X",packet_in[i]);
#endif
uint8_t checksum = 0; uint8_t checksum = 0;
for(uint8_t i=0; i<YUXIANG_PACKET_SIZE-1; i++) for(uint8_t i=0; i<YUXIANG_PACKET_SIZE-1; i++)
checksum += packet_in[i]; checksum += packet_in[i];
if(packet_in[8] == checksum) if(packet_in[8] == checksum)
{ {
#ifdef YUXIANG_HUB_TELEMETRY #ifdef YUXIANG_HUB_TELEMETRY
if(packet_in[0]==0x78)
{
#ifdef YUXIANG_TELEM_DEBUG
debug("OK:");
for(uint8_t i=0;i<YUXIANG_PACKET_SIZE;i++)
debug(" %02X",packet_in[i]);
#endif
v_lipo1 = packet_in[4]; v_lipo1 = packet_in[4];
v_lipo2 = packet_in[6];
}
telemetry_link = 1; telemetry_link = 1;
#endif #endif
telemetry_lost = 0; telemetry_lost = 0;
@@ -195,18 +220,21 @@ uint16_t YUXIANG_callback()
} }
phase++; phase++;
return YUXIANG_WRITE_TIME; return YUXIANG_WRITE_TIME;
case YUXIANG_RX: default:
// RX
{ // Wait for packet to be sent before switching to receive mode { // Wait for packet to be sent before switching to receive mode
uint16_t start=(uint16_t)micros(); uint16_t start=(uint16_t)micros();
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500) while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
if(XN297_IsPacketSent()) if(XN297_IsPacketSent())
break; break;
} }
//if(bind_phase)
// XN297_Hopping(3);
XN297_SetTxRxMode(RX_EN); XN297_SetTxRxMode(RX_EN);
phase = YUXIANG_DATA; phase = YUXIANG_DATA;
return YUXIANG_PACKET_PERIOD - YUXIANG_WRITE_TIME; return YUXIANG_PACKET_PERIOD - YUXIANG_WRITE_TIME;
} }
return YUXIANG_PACKET_PERIOD; return 0;
} }
void YUXIANG_init(void) void YUXIANG_init(void)
@@ -221,6 +249,8 @@ void YUXIANG_init(void)
phase = YUXIANG_DATA; phase = YUXIANG_DATA;
hopping_frequency_no = 0; hopping_frequency_no = 0;
bind_phase = 1;
packet_sent = 8;
#ifdef YUXIANG_HUB_TELEMETRY #ifdef YUXIANG_HUB_TELEMETRY
packet_count = 0; packet_count = 0;
telemetry_lost = 1; telemetry_lost = 1;

View File

@@ -240,10 +240,13 @@
#define FX_NRF24L01_INO #define FX_NRF24L01_INO
#define FY326_NRF24L01_INO #define FY326_NRF24L01_INO
#define GW008_NRF24L01_INO #define GW008_NRF24L01_INO
#define H36_NRF24L01_INO
#define H8_3D_NRF24L01_INO
#define HISKY_NRF24L01_INO #define HISKY_NRF24L01_INO
#define HONTAI_NRF24L01_INO #define HONTAI_NRF24L01_INO
#define H8_3D_NRF24L01_INO #define JIABAILE_NRF24L01_INO
#define JJRC345_NRF24L01_INO #define JJRC345_NRF24L01_INO
#define KAMTOM_NRF24L01_INO
#define KN_NRF24L01_INO #define KN_NRF24L01_INO
#define KYOSHO2_NRF24L01_INO #define KYOSHO2_NRF24L01_INO
#define LOLI_NRF24L01_INO #define LOLI_NRF24L01_INO
@@ -271,6 +274,7 @@
#define Q303_CCNRF_INO #define Q303_CCNRF_INO
#define Q90C_CCNRF_INO #define Q90C_CCNRF_INO
#define SLT_CCNRF_INO #define SLT_CCNRF_INO
#define UDIRC_CCNRF_INO
#define V911S_CCNRF_INO #define V911S_CCNRF_INO
#define XK_CCNRF_INO #define XK_CCNRF_INO
#define XK2_CCNRF_INO #define XK2_CCNRF_INO
@@ -701,6 +705,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
GD_V2 GD_V2
PROTO_GW008 PROTO_GW008
NONE NONE
PROTO_H36
PROTO_H8_3D PROTO_H8_3D
H8_3D H8_3D
H20H H20H
@@ -721,6 +726,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
JJRCX1 JJRCX1
X5C1 X5C1
FQ777_951 FQ777_951
HONTAI_XKK170
PROTO_HOTT PROTO_HOTT
HOTT_SYNC HOTT_SYNC
HOTT_NO_SYNC HOTT_NO_SYNC
@@ -732,11 +738,16 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
NONE NONE
PROTO_J6PRO PROTO_J6PRO
NONE NONE
PROTO_JIABAILE
JIABAILE_STD
JIABAILE_GYRO
PROTO_JJRC345 PROTO_JJRC345
JJRC345 JJRC345
SKYTMBLR SKYTMBLR
PROTO_JOYSWAY PROTO_JOYSWAY
NONE NONE
PROTO_KAMTOM
NONE
PROTO_KF606 PROTO_KF606
KF606_KF606 KF606_KF606
KF606_MIG320 KF606_MIG320
@@ -779,6 +790,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
F949G F949G
PROTO_MT99XX2 PROTO_MT99XX2
PA18 PA18
SU35
PROTO_NCC1701 PROTO_NCC1701
NONE NONE
PROTO_OMP PROTO_OMP
@@ -830,11 +842,15 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
Q100 Q100
Q200 Q200
MR100 MR100
V1_4CH
RF_SIM
PROTO_SYMAX PROTO_SYMAX
SYMAX SYMAX
SYMAX5C SYMAX5C
PROTO_TRAXXAS PROTO_TRAXXAS
NONE NONE
PROTO_UDIRC
NONE
PROTO_V2X2 PROTO_V2X2
V2X2 V2X2
JXD506 JXD506
@@ -863,7 +879,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
X420 X420
XK_CARS XK_CARS
PROTO_XK2 PROTO_XK2
NONE XK2_X4
XK2_P10
PROTO_YD717 PROTO_YD717
YD717 YD717
SKYWLKR SKYWLKR

View File

@@ -28,6 +28,7 @@ static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t*, uint8_t); static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State); static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State);
static void __attribute__((unused)) XN297_SendPayload(uint8_t*, uint8_t); static void __attribute__((unused)) XN297_SendPayload(uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_ReSendPayload();
static void __attribute__((unused)) XN297_WritePayload(uint8_t*, uint8_t); static void __attribute__((unused)) XN297_WritePayload(uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t); static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t);
static bool __attribute__((unused)) XN297_IsRX(); static bool __attribute__((unused)) XN297_IsRX();

View File

@@ -6,6 +6,7 @@ Here are detailed descriptions of every supported protocols (sorted by RF module
The Deviation project (on which this project was based) have a useful list of models and protocols [here](http://www.deviationtx.com/wiki/supported_models). The Deviation project (on which this project was based) have a useful list of models and protocols [here](http://www.deviationtx.com/wiki/supported_models).
## Useful notes and definitions ## Useful notes and definitions
- **Surface and air protocols** - As the list of supported protocols grows even the STM32 ARM microcontroller cannot hold all of the protocols. Firmware available from the [Multi-Module](https://downloads.multi-module.org) website has been split into two groups, surface "SFC" and air "AIR". You can check which protocols are included in each of these groups in the [Validate.h](Multiprotocol/Validate.h) source file.
- **Channel Order** - The channel order assumed in all the documentation is AETR. You can change this in the compilation settings or by using a precompiled firmware. The module will take whatever input channel order you have choosen and will rearrange them to match the output channel order required by the selected protocol. - **Channel Order** - The channel order assumed in all the documentation is AETR. You can change this in the compilation settings or by using a precompiled firmware. The module will take whatever input channel order you have choosen and will rearrange them to match the output channel order required by the selected protocol.
- **Channel ranges** - A radio output of -100%..0%..+100% will match on the selected protocol -100%,0%,+100%. No convertion needs to be done. - **Channel ranges** - A radio output of -100%..0%..+100% will match on the selected protocol -100%,0%,+100%. No convertion needs to be done.
- **Extended limits supported** - A channel range of -125%..+125% will be transmitted. Otherwise it will be truncated to -100%..+100%. - **Extended limits supported** - A channel range of -125%..+125% will be transmitted. Otherwise it will be truncated to -100%..+100%.
@@ -102,14 +103,16 @@ CFlie|38|CFlie||||||||NRF24L01|
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01| [FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L [GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L
[GW008](Protocols_Details.md#GW008---32)|32|||||||||NRF24L01|XN297 [GW008](Protocols_Details.md#GW008---32)|32|||||||||NRF24L01|XN297
[H36](Protocols_Details.md#H36---103)|H36|||||||||NRF24L01|XN297
[H8_3D](Protocols_Details.md#H8_3D---36)|36|H8_3D|H20H|H20Mini|H30Mini|||||NRF24L01|XN297 [H8_3D](Protocols_Details.md#H8_3D---36)|36|H8_3D|H20H|H20Mini|H30Mini|||||NRF24L01|XN297
[Height](Protocols_Details.md#HEIGHT---53)|53|5ch|8ch|||||||A7105| [Height](Protocols_Details.md#HEIGHT---53)|53|5ch|8ch|||||||A7105|
[Hisky](Protocols_Details.md#HISKY---4)|4|Hisky|HK310|||||||NRF24L01| [Hisky](Protocols_Details.md#HISKY---4)|4|Hisky|HK310|||||||NRF24L01|
[Hitec](Protocols_Details.md#HITEC---39)|39|OPT_FW|OPT_HUB|MINIMA||||||CC2500| [Hitec](Protocols_Details.md#HITEC---39)|39|OPT_FW|OPT_HUB|MINIMA||||||CC2500|
[Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|||||NRF24L01|XN297 [Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|XKK170||||NRF24L01|XN297
[HoTT](Protocols_Details.md#HoTT---57)|57|Sync|No_Sync|||||||CC2500| [HoTT](Protocols_Details.md#HoTT---57)|57|Sync|No_Sync|||||||CC2500|
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105| [Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105|
[J6Pro](Protocols_Details.md#J6Pro---22)|22|||||||||CYRF6936| [J6Pro](Protocols_Details.md#J6Pro---22)|22|||||||||CYRF6936|
[JIABAILE](Protocols_Details.md#JIABAILE---102)|102|Std|Gyro|||||||NRF24L01|XN297
[JJRC345](Protocols_Details.md#JJRC345---71)|71|JJRC345|SkyTmblr|||||||NRF24L01|XN297 [JJRC345](Protocols_Details.md#JJRC345---71)|71|JJRC345|SkyTmblr|||||||NRF24L01|XN297
[JOYSWAY](Protocols_Details.md#JOYSWAY---84)|84|||||||||NRF24L01|XN297 [JOYSWAY](Protocols_Details.md#JOYSWAY---84)|84|||||||||NRF24L01|XN297
[KF606](Protocols_Details.md#KF606---49)|49|KF606|MIG320|ZCZ50||||||NRF24L01|XN297 [KF606](Protocols_Details.md#KF606---49)|49|KF606|MIG320|ZCZ50||||||NRF24L01|XN297
@@ -123,7 +126,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936| [MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936|
[MouldKg](Protocols_Details.md#mouldkg---90)|90|Analog|Digit|||||||NRF24L01|XN297 [MouldKg](Protocols_Details.md#mouldkg---90)|90|Analog|Digit|||||||NRF24L01|XN297
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805|A180|DRAGON|F949G|NRF24L01|XN297 [MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805|A180|DRAGON|F949G|NRF24L01|XN297
[MT99xx2](Protocols_Details.md#MT99XX2---92)|92|PA18||||||||NRF24L01|XN297 [MT99xx2](Protocols_Details.md#MT99XX2---92)|92|PA18|SU35|||||||NRF24L01|XN297
[NCC1701](Protocols_Details.md#NCC1701---44)|44|||||||||NRF24L01| [NCC1701](Protocols_Details.md#NCC1701---44)|44|||||||||NRF24L01|
[OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L [OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None| [OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
@@ -141,9 +144,9 @@ CFlie|38|CFlie||||||||NRF24L01|
[SGF22](Protocols_Details.md#SGF22---97)|97|F22|F22S|J20||||||NRF24L01|XN297 [SGF22](Protocols_Details.md#SGF22---97)|97|F22|F22S|J20||||||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|V1_4CH|||NRF24L01|CC2500 [SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100|V1_4CH|RF_SIM||NRF24L01|CC2500
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01| [SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
[Traxxas](Protocols_Details.md#Traxxas---43)|43|TQ1|TQ2|||||||CYRF6936| [Traxxas](Protocols_Details.md#Traxxas---43)|43|TQ2|TQ1|||||||CYRF6936|
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01| [V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01|
[V761](Protocols_Details.md#V761---48)|48|3CH|4CH|TOPRC||||||NRF24L01|XN297 [V761](Protocols_Details.md#V761---48)|48|3CH|4CH|TOPRC||||||NRF24L01|XN297
[V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297 [V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297
@@ -152,7 +155,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936| [WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
[XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297 [XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297
[XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L011&CC2500|XN297 [XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L011&CC2500|XN297
[XK2](Protocols_Details.md#XK2---99)|99|X4||||||||NRF24L01&CC2500|XN297 [XK2](Protocols_Details.md#XK2---99)|99|X4|P10|||||||NRF24L01&CC2500|XN297
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01| [YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
[YuXiang](Protocols_Details.md#YuXiang---100)|100|||||||||NRF24L01|XN297 [YuXiang](Protocols_Details.md#YuXiang---100)|100|||||||||NRF24L01|XN297
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297 [ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
@@ -698,12 +701,9 @@ A|E|T|R
## Traxxas - *43* ## Traxxas - *43*
### Sub_protocol TQ1 - *0* You must assign a different RX number for each receiver/car. Otherwise the new receiver/car ID will overwrite the previous one.
Transmitter 2228 TX and a 2217 RX
Under dev ### Sub_protocol TQ2 - *0*
### Sub_protocol TQ2 - *1*
Transmitter TQ, Receivers: 6519, 2218(X), ECM-2.5 Transmitter TQ, Receivers: 6519, 2218(X), ECM-2.5
Extended limits supported Extended limits supported
@@ -714,6 +714,9 @@ CH1|CH2|CH3|CH4|CH5|CH6
Warning from v1.3.4.7 channels order have changed Warning from v1.3.4.7 channels order have changed
### Sub_protocol TQ1 - *1*
Transmitter 2228 TX and a 2217 RX
## WFLY - *40* ## WFLY - *40*
Receivers: WFR04S, WFR07S, WFR09S Receivers: WFR04S, WFR07S, WFR09S
@@ -1260,7 +1263,7 @@ Unk1&2: long press right/left
## MT99XX2 - *92* ## MT99XX2 - *92*
### Sub_protocol PA18 - *92* ### Sub_protocol PA18 - *0*
Model: PA18 mini Model: PA18 mini
CH1|CH2|CH3|CH4|CH5|CH6|CH7 CH1|CH2|CH3|CH4|CH5|CH6|CH7
@@ -1269,6 +1272,17 @@ A|E|T|R|MODE|FLIP|RTH
MODE: -100% beginner, 0% intermediate, +100% Expert MODE: -100% beginner, 0% intermediate, +100% Expert
### Sub_protocol SU35 - *1*
Model: QF009 SU35
CH6 - LED, CH7 - LED Flash, CH8 - Invert, CH9 - Rate
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|LED|LED_FLASH|INVERT|RATE
MODE: -100% 6G, +100% 3D
## OMP - *77* ## OMP - *77*
Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider
@@ -1430,6 +1444,23 @@ CH1|CH2|CH3|CH4
---|---|---|--- ---|---|---|---
CH1|CH2|CH3|CH4 CH1|CH2|CH3|CH4
### Sub_protocol RF_SIM - *6*
Models: the SLT-dongle included in RealFlight 7.5
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10
Output 10 channels to use with RealFlight simulator.
The RealFlight "reset" button found on the RealFlight USB-transmitter, can now be CH9 or CH10.
RealFlight 8 crashes when trying to save file with reset-button defined.
Please save radio-profile with a new name without setting reset-button in RF8. Then edit the radio-profile definition in ~\Documents\RealFlight8\RadioProfiles\ in an ordinary fileeditor.
Find the [Reset21] section and change Input=INT:-1 to Input=INT:9
## V911S - *46* ## V911S - *46*
CH1|CH2|CH3|CH4|CH5|CH6 CH1|CH2|CH3|CH4|CH5|CH6
@@ -1487,23 +1518,26 @@ Models: WLtoys cars 284131/284161/284010/124016/124017/144010 and Eachine EAT14
## XK2 - *99* ## XK2 - *99*
### Sub_protocol X4 - *0* You must assign a different RX number for each receiver/plane. Otherwise the new receiver/plane ID will overwrite the previous one.
Transmitter: XK X4-A160, model: XK A160S
**Only 1 ID and might only work with my plane**
If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md). If a CC2500 is installed it will be used for this sub protocol. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components. If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
CH1|CH2|CH3|CH4|CH5|CH6|CH7 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---
A|E|T|R|Rate|Mode|Hover A|E|T|R|Rate|Mode|Hover|Light
The plane does not need to be bound each time if it is powered on **after** the radio/protocol is on. The plane does not need to be bound each time if it is powered on **after** the radio/protocol is on.
The rudder trim is driven from the rudder channel to increase the range (Original TX rudder has no range once the motor has been turned on...). The rudder trim is driven from the rudder channel to increase the range (Original TX rudder has no range once the motor has been turned on...).
### Sub_protocol X4 - *0*
Transmitter: XK X4-A160, X5S, model: XK A160S, XK A280, XK A300
### Sub_protocol P10 - *1*
Model: Park10 J3-CUB
*** ***
# NRF24L01 RF Module # NRF24L01 RF Module
@@ -1813,15 +1847,24 @@ CH1|CH2|CH3|CH4|CH5
---|---|---|---|--- ---|---|---|---|---
A|E|T|R|FLIP A|E|T|R|FLIP
## H36 - *103*
Autobind protocol
Model: JJRC H36 (JR-NH010R9 board)
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|FLIP|HEADLESS|RTH
## H8_3D - *36* ## H8_3D - *36*
Autobind protocol Autobind protocol
### Sub_protocol H8_3D - *0* ### Sub_protocol H8_3D - *0*
Models: Eachine H8 mini 3D,Eachine E10, JJRC H20/H22/H11D Models: Eachine H8 mini 3D,Eachine E10, JJRC H20/H22/H11D
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---|---|---|---|---
FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL A|E|T|R|FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL
JJRC H20: OPT1=Headless, OPT2=RTH JJRC H20: OPT1=Headless, OPT2=RTH
@@ -1887,6 +1930,43 @@ ARM|
### Sub_protocol FQ777_951 - *3* ### Sub_protocol FQ777_951 - *3*
### Sub_protocol XKK170 - *3*
Model: XK K170 UH-60L Black hawk
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|---
A|E|T|R|RATE|EMERGENCY|TAKE_OFF/LANDING|CALIB|TrimA|TrimE
RATE: -100% Low, 0% Mid, +100% High
## JIABAILE - *102*
### Sub_protocol Std - *0*
Models: JBL-430x 1:43 car without gyro
You must assign a different RX number for each car. Otherwise the new car ID will overwrite the previous one.
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
ST|TH|-|ST_TRIM|SPEED|LIGHT|FLASH
- Extended Steering comparing to original
- SPEED: -100% High, 0% Mid, +100% Low
- ST_TRIM: value between -100% and +100% but using the radio steering trim looks better
### Sub_protocol Gyro - *1*
Models: JBL-430x 1:43 car with gyro
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
ST|TH|GYRO|ST_TRIM|SPEED|LIGHT|FLASH
- Extended Steering comparing to original
- SPEED: -100% High, 0% Mid, +100% Low
- GYRO: -100% Off..+100% Max
- ST_TRIM: momentary switch, -100% Trim left, 0% Idle, +100% Trim right. Configure the radio steering trim has buttons (ST- and ST+) and assign them to that channel. Don't forget to disable the steering trim in the driving modes.
## JJRC345 - *71* ## JJRC345 - *71*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
@@ -1901,6 +1981,15 @@ Model: DF-Models SkyTumbler
RTH not supported RTH not supported
## KAMTOM - *104*
Models: KAMTOM KM24xx (KM32xx?), Pinecone SG-24xx
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
ST|TH|UNK1|UNK2|ST_TR|TH_TR|TH_DR
Low batt telemetry is not yet added.
## KYOSHO2 - *93* ## KYOSHO2 - *93*
Model: TX KT-17, Minium Edge 540, Minium Citabria Model: TX KT-17, Minium Edge 540, Minium Citabria
@@ -2037,14 +2126,18 @@ A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|THR_CUT|ROTATE
## SGF22 - *97* ## SGF22 - *97*
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|CH12
---|---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|FLIP|LIGHT|PHOTO|VIDEO|TRIMRESET A|E|T|R|MODE|FLIP|LIGHT|PHOTO|VIDEO|TRIMRESET|BAL|BALHIG
### Sub_protocol F22 ### Sub_protocol F22
Model: SG F22 Model: SG F22
SGF22: Mode -100% = 3D, 0% = 6G, 100% = Vertical Mode: -100% = 3D, 0% = 6G, 100% = Vertical
Model: FlyBear FX922
Manual CH11=-100% & CH12=-100%, Balance CH11=+100% & CH12=-100%, Large Angle Balance CH11=-100% & CH12=+100%
### Sub_protocol F22S ### Sub_protocol F22S
Model: ParkTen F22S Model: ParkTen F22S
@@ -2190,11 +2283,13 @@ Same channels assignement as above.
## YuXiang - *100* ## YuXiang - *100*
**Only 1 TX ID**. Bind might not work... Telemetry is received but content unknown yet. Models: E190 F07 UH-1D, E186 F08 Bell-206
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 Telemetry A1=Batt voltage with a Ratio 3.5 and Offset 7, A2=Low batt with 0=OK, everything else=BAD
---|---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|LOCK|RATE|LAND|ALTHOL|MANUAL|FLIP|MODE|PITCH CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|---|---
A|E|T|R|LOCK|RATE|LAND|MANUAL|FLIP|MODE|PITCH
## ZSX - *52* ## ZSX - *52*
Model: JJRC ZSX-280 Model: JJRC ZSX-280

View File

@@ -100,9 +100,9 @@ For example, if you have no interest in binding your Tx to an model with and FrS
## **Choice 3:** Which protocols to upload to the MULTI-Module ## **Choice 3:** Which protocols to upload to the MULTI-Module
In the case of the ATmega328, the memory required by all the possible protocols exceeds the 32KB flash limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page. As the list of supported protocols grows even the STM32 ARM microcontroller cannot hold all of the protocols. You can select the protocols you need and complie your own firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page. You can also download firmware from the [Multi-Module](https://downloads.multi-module.org) website. These firmware files have been split into two groups, surface "SFC" and air "AIR". You can check which protocols are included in each of these groups in the [Validate.h](Multiprotocol/Validate.h) source file.
An alternative is to use a STM32 ARM microcontroller based module which can hold all the protocols. In the case of the ATmega328, the memory required by all the possible protocols exceeds the 32KB flash limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware.
## **Choice 4:** Choosing the type of interface between the MULTI-Module and your radio (PPM or Serial) ## **Choice 4:** Choosing the type of interface between the MULTI-Module and your radio (PPM or Serial)

View File

@@ -108,7 +108,7 @@ The images below indicate the pin layout and the location of the ground pin on t
|:---:|:---:|:---:| |:---:|:---:|:---:|
<img src="images/V2b_ISP.jpeg" width="189" height="200" /> | <img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" /> | <img src="images/ProMini_ISP.png" width="195" height="200" /> | <img src="images/V2b_ISP.jpeg" width="189" height="200" /> | <img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" /> | <img src="images/ProMini_ISP.png" width="195" height="200" /> |
You are now ready to plug in the USB programmer to the computer. If you are looking for a good working USBasp Windows driver, [use this one](http://www.protostack.com/download/USBasp-win-driver-x86-x64-v3.0.7.zip). You are now ready to plug in the USB programmer to the computer. If you are looking for a good working USBasp Windows driver, [use this one](https://protostack.com.au/download/USBasp-win-driver-x86-x64-v3.0.7.zip).
### Burn bootloader and set fuses ### Burn bootloader and set fuses
The bootloader only needs to be burned once, unless you decide to switch from one option to the other (or it is accidentally erased). If you have already burned the bootloader / set the fuses you can skip this step. The bootloader only needs to be burned once, unless you decide to switch from one option to the other (or it is accidentally erased). If you have already burned the bootloader / set the fuses you can skip this step.