Skip to content

Commit 98d8d7f

Browse files
committed
FX/FX620 new protocol
1 parent ad0947b commit 98d8d7f

File tree

8 files changed

+196
-124
lines changed

8 files changed

+196
-124
lines changed

Lua_scripts/MultiChan.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@
8686
55,1,FrSkyRX,CloneTX,0
8787
55,2,FrSkyRX,EraseTX,0
8888
55,3,FrSkyRX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
89-
58,0,FX816,Std,1
89+
58,0,FX,816,1
90+
58,1,FX,620,1
9091
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
9192
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
9293
23,0,FY326,FY326,1,Flip,RTH,HLess,Expert

Multiprotocol/FX816_nrf24l01.ino

Lines changed: 0 additions & 100 deletions
This file was deleted.

Multiprotocol/FX_nrf24l01.ino

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
This project is free software: you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation, either version 3 of the License, or
5+
(at your option) any later version.
6+
7+
Multiprotocol is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
// Compatible with FEI XIONG P38 plane.
16+
17+
#if defined(FX_NRF24L01_INO)
18+
19+
#include "iface_xn297.h"
20+
21+
#define FX_INITIAL_WAIT 500
22+
#define FX_BIND_COUNT 300 //3sec
23+
#define FX_SWITCH 20
24+
25+
#define FX816_PACKET_PERIOD 10000
26+
#define FX816_BIND_CHANNEL 40
27+
#define FX816_NUM_CHANNELS 4
28+
#define FX816_PAYLOAD_SIZE 6
29+
30+
#define FX620_PACKET_PERIOD 3250
31+
#define FX620_BIND_CHANNEL 18
32+
#define FX620_PAYLOAD_SIZE 7
33+
#define FX620_NUM_CHANNELS 6
34+
35+
#define FORCE_FX620_ID
36+
37+
static void __attribute__((unused)) FX_send_packet()
38+
{
39+
//Hopp
40+
if(IS_BIND_DONE)
41+
{
42+
XN297_Hopping(hopping_frequency_no++);
43+
hopping_frequency_no %= sub_protocol == FX816 ? FX816_NUM_CHANNELS:FX620_NUM_CHANNELS;
44+
}
45+
46+
memset(packet,0x00,packet_length);
47+
48+
//Channels
49+
uint8_t offset=sub_protocol == FX816 ? 3:1;
50+
uint8_t val=convert_channel_8b(AILERON); // Can FX620 have a proportional value, the original radio does not but...
51+
if(val>127+FX_SWITCH)
52+
packet[offset] = sub_protocol == FX816 ? 1:0xFF;
53+
else if(val<127-FX_SWITCH)
54+
packet[offset] = sub_protocol == FX816 ? 2:0x00;
55+
else
56+
packet[offset] = sub_protocol == FX816 ? 0:0x7F;
57+
packet[offset+1] = convert_channel_16b_limit(THROTTLE,0,100);
58+
59+
//Bind and specifics
60+
if(sub_protocol == FX816)
61+
{
62+
if(IS_BIND_IN_PROGRESS)
63+
packet[0] = 0x55;
64+
else
65+
packet[0] = 0xAA;
66+
packet[1] = rx_tx_addr[0];
67+
packet[2] = rx_tx_addr[1];
68+
}
69+
else //FX620
70+
{
71+
if(IS_BIND_IN_PROGRESS)
72+
{
73+
memcpy(packet,rx_tx_addr,3);
74+
packet[3] = hopping_frequency[0];
75+
}
76+
else
77+
{
78+
packet[0] = 0x1F; // Is it based on ID??
79+
packet[5] = 0xAB; // Is it based on ID??
80+
}
81+
}
82+
83+
//Check
84+
val=0;
85+
for(uint8_t i=0;i<packet_length-1;i++)
86+
val+=packet[i];
87+
packet[packet_length-1]=val;
88+
89+
//Debug
90+
#if 1
91+
for(uint8_t i=0;i<packet_length;i++)
92+
debug("%02X ",packet[i]);
93+
debugln("");
94+
#endif
95+
96+
// Send
97+
XN297_SetPower();
98+
XN297_SetTxRxMode(TX_EN);
99+
XN297_WritePayload(packet, packet_length);
100+
}
101+
102+
static void __attribute__((unused)) FX_RF_init()
103+
{
104+
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
105+
if(sub_protocol == FX816)
106+
{
107+
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
108+
XN297_RFChannel(FX816_BIND_CHANNEL);
109+
}
110+
else //FX620
111+
{
112+
XN297_SetTXAddr((uint8_t *)"\xaa\xbb\xcc", 3);
113+
XN297_RFChannel(FX620_BIND_CHANNEL);
114+
}
115+
}
116+
117+
static void __attribute__((unused)) FX_initialize_txid()
118+
{
119+
if(sub_protocol == FX816)
120+
{
121+
//Only 8 IDs: the RX led does not indicate frame loss.
122+
//I didn't open the plane to find out if I could connect there so this is the best I came up with with few trial and errors...
123+
rx_tx_addr[0]=0x35+(rx_tx_addr[3]&0x07); //Original dump=0x35
124+
rx_tx_addr[1]=0x09; //Original dump=0x09
125+
memcpy(hopping_frequency,"\x09\x1B\x30\x42",FX816_NUM_CHANNELS); //Original dump=9=0x09,27=0x1B,48=0x30,66=0x42
126+
for(uint8_t i=0;i<FX816_NUM_CHANNELS;i++)
127+
hopping_frequency[i]+=rx_tx_addr[3]&0x07;
128+
129+
packet_length = FX816_PAYLOAD_SIZE;
130+
packet_period = FX816_PACKET_PERIOD;
131+
}
132+
else//FX620
133+
{
134+
rx_tx_addr[0] = rx_tx_addr[3];
135+
hopping_frequency[0] = 0x18 + rx_tx_addr[3]&0x07; // just to try something
136+
#ifdef FORCE_FX620_ID
137+
memcpy(rx_tx_addr,(uint8_t*)"\x34\xA9\x32",3);
138+
hopping_frequency[0] = 0x18; //on dump: 24 34 40 44 50 54
139+
#endif
140+
//no idea if this is true...
141+
hopping_frequency[1] = 10 + hopping_frequency[0];
142+
hopping_frequency[2] = 16 + hopping_frequency[0];
143+
hopping_frequency[3] = 20 + hopping_frequency[0];
144+
hopping_frequency[4] = 26 + hopping_frequency[0];
145+
hopping_frequency[5] = 30 + hopping_frequency[0];
146+
147+
packet_length = FX620_PAYLOAD_SIZE;
148+
packet_period = FX620_PACKET_PERIOD;
149+
}
150+
}
151+
152+
uint16_t FX_callback()
153+
{
154+
#ifdef MULTI_SYNC
155+
telemetry_set_input_sync(packet_period);
156+
#endif
157+
if(bind_counter)
158+
if(--bind_counter==0)
159+
{
160+
BIND_DONE;
161+
if(sub_protocol == FX620)
162+
XN297_SetTXAddr(rx_tx_addr, 3);
163+
}
164+
FX_send_packet();
165+
return packet_period;
166+
}
167+
168+
void FX_init()
169+
{
170+
BIND_IN_PROGRESS; // autobind protocol
171+
FX_initialize_txid();
172+
FX_RF_init();
173+
hopping_frequency_no = 0;
174+
bind_counter=FX_BIND_COUNT;
175+
}
176+
177+
#endif

Multiprotocol/Multi.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
5656
56,AFHDS2A_RX,Multi,CPPM
5757
57,HoTT,Sync,No_Sync
58-
58,FX816
58+
58,FX,816,620
5959
59,Bayang_RX,Multi,CPPM
6060
60,Pelikan,Pro,Lite,SCX24
6161
61,Tiger

Multiprotocol/Multi_Protos.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const char STR_SCANNER[] ="Scanner";
7878
const char STR_FRSKY_RX[] ="FrSkyRX";
7979
const char STR_AFHDS2A_RX[] ="FS2A_RX";
8080
const char STR_HOTT[] ="HoTT";
81-
const char STR_FX816[] ="FX816";
81+
const char STR_FX[] ="FX";
8282
const char STR_BAYANG_RX[] ="BayanRX";
8383
const char STR_PELIKAN[] ="Pelikan";
8484
const char STR_TIGER[] ="Tiger";
@@ -163,7 +163,7 @@ const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
163163
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
164164
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320";
165165
const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
166-
166+
const char STR_SUBTYPE_FX[] = "\x03""816""620";
167167
#define NO_SUBTYPE nullptr
168168

169169
#ifdef SEND_CPPM
@@ -304,8 +304,8 @@ const mm_protocol_definition multi_protocols[] = {
304304
#if defined(FUTABA_CC2500_INO)
305305
{PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
306306
#endif
307-
#if defined(FX816_NRF24L01_INO)
308-
{PROTO_FX816, STR_FX816, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, FX816_init, FX816_callback },
307+
#if defined(FX_NRF24L01_INO)
308+
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 2, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
309309
#endif
310310
#if defined(FY326_NRF24L01_INO)
311311
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },

0 commit comments

Comments
 (0)