Skip to content

Commit 02008a8

Browse files
author
Pascal Langer
committed
New protocol JJRC345: WIP
Work in progress
1 parent 5b82599 commit 02008a8

7 files changed

Lines changed: 195 additions & 1 deletion

File tree

Multiprotocol/JJRC345_nrf24l01.ino

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
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 JJRC345
16+
17+
#if defined(JJRC345_NRF24L01_INO)
18+
19+
#include "iface_nrf24l01.h"
20+
21+
#define JJRC345_FORCE_ID
22+
23+
#define JJRC345_PACKET_PERIOD 7450 // Timeout for callback in uSec
24+
#define JJRC345_INITIAL_WAIT 500
25+
#define JJRC345_PACKET_SIZE 16
26+
#define JJRC345_RF_BIND_CHANNEL 5
27+
#define JJRC345_BIND_COUNT 500
28+
#define JJRC345_NUM_CHANNELS 4
29+
30+
31+
enum JJRC345_FLAGS {
32+
// flags going to packet[8]
33+
//JJRC345_FLAG_FLIP = 0x80,
34+
JJRC345_FLAG_HEADLESS = 0x40,
35+
};
36+
37+
static uint8_t __attribute__((unused)) JJRC345_convert_channel(uint8_t num)
38+
{
39+
uint8_t val=convert_channel_8b(num);
40+
// 7F..01=left, 00=center, 80..FF=right
41+
if(val==0x80)
42+
val=0; // 0
43+
else
44+
if(val>0x80)
45+
val--; // 80..FE
46+
else
47+
{
48+
val=0x80-val; // 80..01
49+
if(val==0x80)
50+
val--; // 7F..01
51+
}
52+
return val;
53+
}
54+
55+
static void __attribute__((unused)) JJRC345_send_packet()
56+
{
57+
packet[0] = 0x00;
58+
packet[2] = 0x00;
59+
if (IS_BIND_IN_PROGRESS)
60+
{ //00 05 00 0A 46 4A 41 47 00 00 40 46 A5 4A F1 18
61+
packet[1] = JJRC345_RF_BIND_CHANNEL;
62+
packet[4] = hopping_frequency[0];
63+
packet[5] = hopping_frequency[1];
64+
packet[6] = hopping_frequency[2];
65+
packet[7] = hopping_frequency[3];
66+
packet[12] = 0xa5;
67+
}
68+
else
69+
{ //00 41 00 0A 00 80 80 80 00 00 40 46 00 49 F1 18
70+
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
71+
if (hopping_frequency_no >= JJRC345_NUM_CHANNELS)
72+
hopping_frequency_no = 0;
73+
packet[1] = hopping_frequency[hopping_frequency_no]; // next packet will be sent on this channel
74+
75+
packet[4] = convert_channel_8b(THROTTLE); // throttle: 00..FF
76+
packet[5] = JJRC345_convert_channel(RUDDER); // rudder: 70..60..41..01, 80 center, 81..C1..E0..F0
77+
packet[6] = JJRC345_convert_channel(ELEVATOR); // elevator: 70..60..41..01, 80 center, 81..C1..E0..F0
78+
packet[7] = JJRC345_convert_channel(AILERON); // aileron: 70..60..41..01, 80 center, 81..C1..E0..F0
79+
packet[12] = 0x02; // Rate: 00-01-02
80+
}
81+
packet[3] = (packet[4] >= 0xB7) ? 0x0e : 0x0a; // Some throttle flag. 0A when Thr <= B6, 0E when Thr >= B7, sometimes 06 when moving Ele/Ail
82+
83+
packet[8] = GET_FLAG(CH6_SW,JJRC345_FLAG_HEADLESS); // Headless mode: 00 normal, 40 headless. Rudder trim, 00 when not used, 01..1F when trimmed left, 20..3F
84+
packet[9] = 0; // Elevator trim, 00 when not used, 20..25 when trimmed up, 0..1F when trimmed down
85+
packet[10] = 0x40; // Aileron trim, 40 when not used, 40..5F when trimmed left, 61..7F when trimmed right
86+
87+
packet[11] = hopping_frequency[0]; // First hopping frequency
88+
89+
// Checksum
90+
packet[13] = 0xf8;
91+
for (uint8_t i = 0; i < 13; i++)
92+
packet[13] += packet[i];
93+
94+
// TX ID
95+
packet[14] = rx_tx_addr[2];
96+
packet[15] = rx_tx_addr[3];
97+
98+
// Power on, TX mode
99+
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
100+
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
101+
NRF24L01_FlushTx();
102+
XN297_WritePayload(packet, JJRC345_PACKET_SIZE);
103+
104+
NRF24L01_SetPower(); // Set tx_power
105+
}
106+
107+
static void __attribute__((unused)) JJRC345_init()
108+
{
109+
NRF24L01_Initialize();
110+
NRF24L01_SetTxRxMode(TX_EN);
111+
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
112+
NRF24L01_WriteReg(NRF24L01_05_RF_CH, JJRC345_RF_BIND_CHANNEL); // Bind channel
113+
NRF24L01_FlushTx();
114+
NRF24L01_FlushRx();
115+
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
116+
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
117+
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
118+
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1 Mbps
119+
NRF24L01_SetPower();
120+
}
121+
122+
uint16_t JJRC345_callback()
123+
{
124+
#ifdef MULTI_SYNC
125+
telemetry_set_input_sync(JJRC345_PACKET_PERIOD);
126+
#endif
127+
if(IS_BIND_IN_PROGRESS)
128+
{
129+
if (bind_counter)
130+
bind_counter--;
131+
else
132+
BIND_DONE;
133+
}
134+
JJRC345_send_packet();
135+
return JJRC345_PACKET_PERIOD;
136+
}
137+
138+
static void __attribute__((unused)) JJRC345_initialize_txid()
139+
{
140+
calc_fh_channels(4);
141+
142+
#ifdef JJRC345_FORCE_ID
143+
//TX 1
144+
rx_tx_addr[2]=0x1B;
145+
rx_tx_addr[3]=0x12;
146+
hopping_frequency[0] = 0x3f;
147+
hopping_frequency[1] = 0x49;
148+
hopping_frequency[2] = 0x47;
149+
hopping_frequency[3] = 0x47;
150+
//TX 2
151+
rx_tx_addr[2]=0xF1;
152+
rx_tx_addr[3]=0x18;
153+
hopping_frequency[0] = 0x46;
154+
hopping_frequency[1] = 0x4A;
155+
hopping_frequency[2] = 0x41;
156+
hopping_frequency[3] = 0x47;
157+
#endif
158+
}
159+
160+
uint16_t initJJRC345(void)
161+
{
162+
BIND_IN_PROGRESS; // autobind protocol
163+
bind_counter = JJRC345_BIND_COUNT;
164+
JJRC345_initialize_txid();
165+
JJRC345_init();
166+
return JJRC345_INITIAL_WAIT;
167+
}
168+
169+
#endif

Multiprotocol/Multi_Names.ino

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const char STR_SHENQI[] ="Shenqi";
4040
const char STR_FY326[] ="FY326";
4141
const char STR_SFHSS[] ="SFHSS";
4242
const char STR_J6PRO[] ="J6 Pro";
43+
const char STR_JJRC345[] ="JJRC345";
4344
const char STR_FQ777[] ="FQ777";
4445
const char STR_ASSAN[] ="Assan";
4546
const char STR_FRSKYV[] ="FrSky V";
@@ -273,6 +274,9 @@ const mm_protocol_definition multi_protocols[] = {
273274
#if defined(J6PRO_CYRF6936_INO)
274275
{PROTO_J6PRO, STR_J6PRO, 0, NO_SUBTYPE, OPTION_NONE },
275276
#endif
277+
#if defined(JJRC345_NRF24L01_INO)
278+
{PROTO_JJRC345, STR_JJRC345, 0, NO_SUBTYPE, OPTION_NONE },
279+
#endif
276280
#if defined(KF606_NRF24L01_INO)
277281
{PROTO_KF606, STR_KF606, 0, NO_SUBTYPE, OPTION_RFTUNE },
278282
#endif

Multiprotocol/Multiprotocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ enum PROTOCOLS
9797
PROTO_SKYARTEC = 68, // =>CC2500
9898
PROTO_ESKY150V2 = 69, // =>CC2500+NRF24L01
9999
PROTO_DSM_RX = 70, // =>CYRF6936
100+
PROTO_JJRC345 = 71, // =>NRF24L01
100101
};
101102

102103
enum Flysky
@@ -764,6 +765,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
764765
FRSKYL 67
765766
SKYARTEC 68
766767
ESKY150V2 69
768+
DSM_RX 70
769+
JJRC345 71
767770
BindBit=> 0x80 1=Bind/0=No
768771
AutoBindBit=> 0x40 1=Yes /0=No
769772
RangeCheck=> 0x20 1=Yes /0=No

Multiprotocol/Multiprotocol.ino

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,12 @@ static void protocol_init()
15421542
remote_callback = XN297Dump_callback;
15431543
break;
15441544
#endif
1545+
#if defined(JJRC345_NRF24L01_INO)
1546+
case PROTO_JJRC345:
1547+
next_callback=initJJRC345();
1548+
remote_callback = JJRC345_callback;
1549+
break;
1550+
#endif
15451551
#endif
15461552
#ifdef SX1276_INSTALLED
15471553
#if defined(FRSKYR9_SX1276_INO)

Multiprotocol/Validate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@
248248
#undef H8_3D_NRF24L01_INO
249249
#undef HISKY_NRF24L01_INO
250250
#undef HONTAI_NRF24L01_INO
251+
#undef JJRC345_NRF24L01_INO
251252
#undef KF606_NRF24L01_INO
252253
#undef KN_NRF24L01_INO
253254
#undef MJXQ_NRF24L01_INO

Multiprotocol/_Config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
#define HISKY_NRF24L01_INO
213213
#define HONTAI_NRF24L01_INO
214214
#define H8_3D_NRF24L01_INO
215+
#define JJRC345_NRF24L01_INO
215216
#define KF606_NRF24L01_INO
216217
#define KN_NRF24L01_INO
217218
#define MJXQ_NRF24L01_INO
@@ -635,6 +636,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
635636
H501
636637
PROTO_J6PRO
637638
NONE
639+
PROTO_JJRC345
640+
NONE
638641
PROTO_KF606
639642
NONE
640643
PROTO_KN

Protocols_Details.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ CFlie|38|CFlie||||||||NRF24L01|
106106
[Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|||||NRF24L01|XN297
107107
[HoTT](Protocols_Details.md#HoTT---57)|57|||||||||CC2500|
108108
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105|
109-
[J6Pro](Protocols_Details.md#J6Pro---22)|22|J6PRO||||||||CYRF6936|
109+
[J6Pro](Protocols_Details.md#J6Pro---22)|22|||||||||CYRF6936|
110+
[JJRC345](Protocols_Details.md#JJRC345---71)|71|||||||||NRF24L01|XN297
110111
[KF606](Protocols_Details.md#KF606---49)|49|KF606*||||||||NRF24L01|XN297
111112
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
112113
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
@@ -1097,6 +1098,13 @@ ARM|
10971098

10981099
### Sub_protocol FQ777_951 - *3*
10991100

1101+
## JJRC345 - *71*
1102+
Model: JJRC345
1103+
1104+
CH1|CH2|CH3|CH4|CH5|CH6
1105+
---|---|---|---|---|---
1106+
A|E|T|R||HEADLESS
1107+
11001108
## KF606 - *49*
11011109
Model: KF606
11021110

0 commit comments

Comments
 (0)