diff --git a/Multiprotocol/A7105_SPI.ino b/Multiprotocol/A7105_SPI.ino
index 6483886..ae58415 100644
--- a/Multiprotocol/A7105_SPI.ino
+++ b/Multiprotocol/A7105_SPI.ino
@@ -183,8 +183,8 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
#endif
break;
case PROTO_BUGS:
- #ifdef FORCE_HUBSAN_TUNING
- offset=(int16_t)FORCE_HUBSAN_TUNING;
+ #ifdef FORCE_BUGS_TUNING
+ offset=(int16_t)FORCE_BUGS_TUNING;
#endif
break;
case PROTO_FLYSKY:
@@ -192,6 +192,11 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
offset=(int16_t)FORCE_FLYSKY_TUNING;
#endif
break;
+ case PROTO_FLYZONE:
+ #ifdef FORCE_FLYZONE_TUNING
+ offset=(int16_t)FORCE_FLYZONE_TUNING;
+ #endif
+ break;
case PROTO_AFHDS2A:
#ifdef FORCE_AFHDS2A_TUNING
offset=(int16_t)FORCE_AFHDS2A_TUNING;
@@ -247,22 +252,6 @@ static void __attribute__((unused)) A7105_SetVCOBand(uint8_t vb1, uint8_t vb2)
A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb2 | 0x08);
}
-#ifdef HUBSAN_A7105_INO
-const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
- 0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF, // 00 - 0f
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07, // 10 - 1f
- 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20 - 2f
- 0xFF, 0xFF // 30 - 31
-};
-#endif
-#ifdef FLYSKY_A7105_INO
-const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
- 0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, // 00 - 0f
- 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
- 0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
- 0x01, 0x0f // 30 - 31
-};
-#endif
#ifdef AFHDS2A_A7105_INO
const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f
@@ -279,6 +268,30 @@ const uint8_t PROGMEM BUGS_A7105_regs[] = {
0x01, 0x0f // 30 - 31
};
#endif
+#ifdef FLYSKY_A7105_INO
+const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
+ 0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, // 00 - 0f
+ 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
+ 0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
+ 0x01, 0x0f // 30 - 31
+};
+#endif
+#ifdef FLYZONE_A7105_INO
+const uint8_t PROGMEM FLYZONE_A7105_regs[] = {
+ 0xff, 0x42, 0x00, 0x07, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x01, 0x50, // 00 - 0f
+ 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x1f, // 10 - 1f
+ 0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3a, 0x00, 0x3f, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
+ 0x01, 0x0f // 30 - 31
+};
+#endif
+#ifdef HUBSAN_A7105_INO
+const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
+ 0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF, // 00 - 0f
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07, // 10 - 1f
+ 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20 - 2f
+ 0xFF, 0xFF // 30 - 31
+};
+#endif
#define ID_NORMAL 0x55201041
#define ID_PLUS 0xAA201041
@@ -287,6 +300,14 @@ void A7105_Init(void)
uint8_t *A7105_Regs=0;
uint8_t vco_calibration0, vco_calibration1;
+ #ifdef FLYZONE_A7105_INO
+ if(protocol==PROTO_FLYZONE)
+ {
+ A7105_Regs=(uint8_t*)FLYZONE_A7105_regs;
+ A7105_WriteID(0x25A53C45);
+ }
+ else
+ #endif
#ifdef BUGS_A7105_INO
if(protocol==PROTO_BUGS)
A7105_Regs=(uint8_t*)BUGS_A7105_regs;
@@ -360,7 +381,21 @@ void A7105_Init(void)
A7105_SetVCOBand(vco_calibration0 & 0x07, vco_calibration1 & 0x07); // Set calibration band value to best match
else
if(protocol!=PROTO_HUBSAN)
- A7105_WriteReg(A7105_25_VCO_SBCAL_I,protocol==PROTO_FLYSKY?0x08:0x0A); //Reset VCO Band calibration
+ {
+ switch(protocol)
+ {
+ case PROTO_FLYSKY:
+ vco_calibration1=0x08;
+ break;
+ case PROTO_FLYZONE:
+ vco_calibration1=0x02;
+ break;
+ default:
+ vco_calibration1=0x0A;
+ break;
+ }
+ A7105_WriteReg(A7105_25_VCO_SBCAL_I,vco_calibration1); //Reset VCO Band calibration
+ }
A7105_SetTxRxMode(TX_EN);
A7105_SetPower();
diff --git a/Multiprotocol/CYRF6936_SPI.ino b/Multiprotocol/CYRF6936_SPI.ino
index 20136b8..63f4502 100644
--- a/Multiprotocol/CYRF6936_SPI.ino
+++ b/Multiprotocol/CYRF6936_SPI.ino
@@ -152,6 +152,17 @@ void CYRF_SetPower(uint8_t val)
CYRF_WriteRegister(CYRF_03_TX_CFG,power);
prev_power=power;
}
+
+ #ifdef USE_CYRF6936_CH15_TUNING
+ static uint16_t Channel15=1024;
+ if(Channel15!=Channel_data[CH15])
+ { // adjust frequency
+ Channel15=Channel_data[CH15]+0x155; // default value is 0x555 = 0x400 + 0x155
+ CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, Channel15&0xFF);
+ CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, Channel15>>8);
+ Channel15-=0x155;
+ }
+ #endif
}
/*
diff --git a/Multiprotocol/Common.ino b/Multiprotocol/Common.ino
index c5525a1..5b0c6d9 100644
--- a/Multiprotocol/Common.ino
+++ b/Multiprotocol/Common.ino
@@ -70,7 +70,7 @@ uint8_t convert_channel_8b_limit_deadband(uint8_t num,uint8_t min,uint8_t mid, u
return val;
}
-// Revert a channel and store it
+// Reverse a channel and store it
void reverse_channel(uint8_t num)
{
uint16_t val=2048-Channel_data[num];
diff --git a/Multiprotocol/DSM_cyrf6936.ino b/Multiprotocol/DSM_cyrf6936.ino
index 759e703..faea637 100644
--- a/Multiprotocol/DSM_cyrf6936.ino
+++ b/Multiprotocol/DSM_cyrf6936.ino
@@ -375,9 +375,13 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
uint16_t ReadDsm()
{
-#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
-#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. Was 400 but 600 seems what the 328p needs to read a packet
+ #define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
+ #ifdef STM32_BOARD
+ #define DSM_WRITE_DELAY 1500 // Time after write to verify write complete
+ #else
+ #define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
+ #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
uint8_t rx_phase;
uint8_t len;
@@ -464,6 +468,7 @@ uint16_t ReadDsm()
while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 100) // Wait max 100µs, max I've seen is 50µs
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
break;
+
if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B)
{
#if defined DSM_TELEMETRY
diff --git a/Multiprotocol/Flyzone_a7105.ino b/Multiprotocol/Flyzone_a7105.ino
new file mode 100644
index 0000000..24c69ee
--- /dev/null
+++ b/Multiprotocol/Flyzone_a7105.ino
@@ -0,0 +1,103 @@
+/*
+ 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 .
+ */
+// Compatible with FZ-410 TX
+
+#if defined(FLYZONE_A7105_INO)
+
+#include "iface_a7105.h"
+
+//#define FLYZONE_FORCEID
+
+#define FLYZONE_BIND_COUNT 220 // 5 sec
+#define FLYZONE_BIND_CH 0x18 // TX, RX for bind end is 0x17
+
+static void __attribute__((unused)) flyzone_build_packet()
+{
+ packet[0] = 0xA5;
+ packet[1] = rx_tx_addr[2];
+ packet[2] = rx_tx_addr[3];
+ packet[3] = convert_channel_8b(AILERON); //00..80..FF
+ packet[4] = convert_channel_8b(ELEVATOR); //00..80..FF
+ packet[5] = convert_channel_8b(THROTTLE); //00..FF
+ packet[6] = convert_channel_8b(RUDDER); //00..80..FF
+ packet[7] = 0xFF;
+}
+
+uint16_t ReadFlyzone()
+{
+ #ifndef FORCE_FLYZONE_TUNING
+ A7105_AdjustLOBaseFreq(1);
+ #endif
+ if(IS_BIND_IN_PROGRESS)
+ {
+ packet[0] = 0x1B;
+ packet[1] = rx_tx_addr[2];
+ packet[2] = rx_tx_addr[3];
+ A7105_WriteData(3, FLYZONE_BIND_CH);
+ if (bind_counter--==0)
+ BIND_DONE;
+ return 22700;
+ }
+ else
+ {
+ if(phase>19)
+ {
+ phase=0;
+ flyzone_build_packet();
+ A7105_WriteData(8, hopping_frequency[0]);
+ A7105_SetPower();
+ }
+ else
+ {
+ A7105_WriteReg(A7105_0F_PLL_I, hopping_frequency[(phase&0x02)>>1]);
+ A7105_Strobe(A7105_TX);
+ }
+ phase++;
+ }
+ return 1500;
+}
+
+uint16_t initFlyzone()
+{
+ A7105_Init();
+
+ hopping_frequency[0]=((random(0xfefefefe) & 0x0F)+2)<<2;
+ hopping_frequency[1]=hopping_frequency[0]+0x50;
+
+ #ifdef FLYZONE_FORCEID
+ rx_tx_addr[2]=0x35;
+ rx_tx_addr[3]=0xD0;
+ hopping_frequency[0]=0x18;
+ hopping_frequency[1]=0x68;
+ #endif
+
+ phase=255;
+ bind_counter = FLYZONE_BIND_COUNT;
+ return 2400;
+}
+#endif
+// Normal packet is 8 bytes: 0xA5 0xAF 0x59 0x84 0x7A 0x00 0x80 0xFF
+// Protocol is using AETR channel order, 1 byte per channel 00..80..FF including trim. Channels are in packet [3,4,5,6].
+// packet[0,1,2,7] values are constant in normal mode.
+// packet[0]=0xA5 -> normal mode
+// packet[1,2] ->ID
+// packet[7]=0xFF -> ???
+// Channel values are updated every 30ms which is quite slow, slower than PPM...
+// Packets are sent every 1500µs on 2 different channels. 2 times on first channel, 2 times on second channel and restart. The channels are changing between the files 0x08, 0x58 and 0x18, 0x68.
+//
+// Bind is sending 3 bytes on channel 0x18: 0x1B 0x35 0xD0 every 22.7ms
+// packet[0]=0x1B -> bind mode
+// packet[1,2] ->ID
+// It listens for the model on channel 0x17 and recieves 0x1B 0x35 0xD0 when the plane accepts bind.
\ No newline at end of file
diff --git a/Multiprotocol/GW008_nrf24l01.ino b/Multiprotocol/GW008_nrf24l01.ino
index 1499c6c..3bcae2e 100644
--- a/Multiprotocol/GW008_nrf24l01.ino
+++ b/Multiprotocol/GW008_nrf24l01.ino
@@ -47,7 +47,7 @@ static void __attribute__((unused)) GW008_send_packet(uint8_t bind)
}
else
{
- packet[1] = 0x01 | GET_FLAG(CH5, 0x40); // flip
+ packet[1] = 0x01 | GET_FLAG(CH5_SW, 0x40); // flip
packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator
packet[4] = convert_channel_16b_limit(RUDDER , 200, 0); // rudder
@@ -125,7 +125,7 @@ uint16_t GW008_callback()
NRF24L01_SetTxRxMode(TX_EN);
GW008_send_packet(1);
phase = GW008_BIND2;
- return 300;
+ return 850; // minimum value 750 for STM32
}
break;
case GW008_BIND2:
diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt
index 7c58e99..0eb0d6c 100644
--- a/Multiprotocol/Multi.txt
+++ b/Multiprotocol/Multi.txt
@@ -40,13 +40,15 @@
40,WFLY
41,BUGS
42,BUGSMINI,BUGSMINI,BUGS3H
-43,Traxxas
+43,Traxxas,RX6519
44,NCC1701
45,E01X,E012,E015,E016H
46,V911S
47,GD00X,GD_V1,GD_V2
48,V761
49,KF606
-50,REDPINE,FAST,SLOW
-51,POTENSIC,A20
+50,Redpine,Fast,Slow
+51,Potensic,A20
+52,ZSX,280
+53,Flyzone,FZ-410
63,XN_DUMP,250K,1M,2M
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index 338ad2a..f6977d7 100644
--- a/Multiprotocol/Multiprotocol.h
+++ b/Multiprotocol/Multiprotocol.h
@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 1
-#define VERSION_PATCH_LEVEL 67
+#define VERSION_PATCH_LEVEL 74
//******************
// Protocols
@@ -78,6 +78,8 @@ enum PROTOCOLS
PROTO_KF606 = 49, // =>NRF24L01
PROTO_REDPINE = 50, // =>CC2500
PROTO_POTENSIC = 51, // =>NRF24L01
+ PROTO_ZSX = 52, // =>NRF24L01
+ PROTO_FLYZONE = 53, // =>A7105
PROTO_SCANNER = 54, // =>CYRF6936
PROTO_XN297DUMP = 63, // =>NRF24L01
};
@@ -90,6 +92,10 @@ enum Flysky
V912 = 3,
CX20 = 4,
};
+enum Flyzone
+{
+ FZ410 = 0,
+};
enum Hubsan
{
H107 = 0,
@@ -278,6 +284,11 @@ enum REDPINE
RED_FAST= 0,
RED_SLOW= 1,
};
+enum TRAXXAS
+{
+ RX6519 = 0,
+};
+
#define NONE 0
#define P_HIGH 1
#define P_LOW 0
@@ -397,10 +408,11 @@ enum MultiPacketTypes
#define debug(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg, ##__VA_ARGS__); Serial.write(debug_buf);}
#define debugln(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg "\r\n", ##__VA_ARGS__); Serial.write(debug_buf);}
#define debug_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u", debug_time>>1); debug_time=debug_time_TCNT1; }
+ #define debugln_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u\r\n", debug_time>>1); debug_time=debug_time_TCNT1; }
#else
#define debug(...) { }
#define debugln(...) { }
- #define debug_time(...) { }
+ #define debugln_time(...) { }
#undef DEBUG_SERIAL
#endif
@@ -624,6 +636,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
KF606 49
REDPINE 50
POTENSIC 51
+ ZSX 52
+ FLYZONE 53
+ SCANNER 54
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
@@ -763,6 +778,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
sub_protocol==REDPINE
RED_FAST 0
RED_SLOW 1
+ sub_protocol==TRAXXAS
+ RX6519 0
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index 8d204d6..6e4ac06 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -398,7 +398,7 @@ void setup()
#endif
// Read or create protocol id
- MProtocol_id_master=random_id(10,false);
+ MProtocol_id_master=random_id(EEPROM_ID_OFFSET,false);
debugln("Module Id: %lx", MProtocol_id_master);
@@ -933,6 +933,13 @@ static void protocol_init()
remote_callback = ReadBUGS;
break;
#endif
+ #if defined(FLYZONE_A7105_INO)
+ case PROTO_FLYZONE:
+ PE1_off; //antenna RF1
+ next_callback = initFlyzone();
+ remote_callback = ReadFlyzone;
+ break;
+ #endif
#endif
#ifdef CC2500_INSTALLED
#if defined(FRSKYD_CC2500_INO)
@@ -1058,6 +1065,13 @@ static void protocol_init()
remote_callback = ReadJ6Pro;
break;
#endif
+ #if defined(TRAXXAS_CYRF6936_INO)
+ case PROTO_TRAXXAS:
+ PE2_on; //antenna RF4
+ next_callback = initTRAXXAS();
+ remote_callback = ReadTRAXXAS;
+ break;
+ #endif
#if defined(SCANNER_CYRF6936_INO)
case PROTO_SCANNER:
PE2_on; //antenna RF4
@@ -1261,6 +1275,12 @@ static void protocol_init()
remote_callback = POTENSIC_callback;
break;
#endif
+ #if defined(ZSX_NRF24L01_INO)
+ case PROTO_ZSX:
+ next_callback=initZSX();
+ remote_callback = ZSX_callback;
+ break;
+ #endif
#if defined(XN297DUMP_NRF24L01_INO)
case PROTO_XN297DUMP:
next_callback=initXN297Dump();
diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino
index abe20cc..adee414 100644
--- a/Multiprotocol/NRF24l01_SPI.ino
+++ b/Multiprotocol/NRF24l01_SPI.ino
@@ -286,7 +286,7 @@ const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[] = {
// unscrambled enhanced mode crc xorout table
// unused so far
-/*
+#ifdef XN297DUMP_NRF24L01_INO
const uint16_t xn297_crc_xorout_enhanced[] = {
0x0000, 0x8BE6, 0xD8EC, 0xB87A, 0x42DC, 0xAA89,
0x83AF, 0x10E4, 0xE83E, 0x5C29, 0xAC76, 0x1C69,
@@ -294,7 +294,7 @@ const uint16_t xn297_crc_xorout_enhanced[] = {
0x7CDB, 0x7A14, 0xD5D2, 0x57D7, 0xE31D, 0xCE42,
0x648D, 0xBF2D, 0x653B, 0x190C, 0x9117, 0x9A97,
0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 };
-*/
+#endif
static uint8_t bit_reverse(uint8_t b_in)
{
diff --git a/Multiprotocol/TRAXXAS_cyrf6936.ino b/Multiprotocol/TRAXXAS_cyrf6936.ino
new file mode 100644
index 0000000..4de89c6
--- /dev/null
+++ b/Multiprotocol/TRAXXAS_cyrf6936.ino
@@ -0,0 +1,235 @@
+/*
+ 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 .
+
+ Works with Traxxas 6519 receivers https://traxxas.com/sites/default/files/24CompGuide-2016.jpg .
+ */
+
+#if defined(TRAXXAS_CYRF6936_INO)
+
+#include "iface_cyrf6936.h"
+
+//#define TRAXXAS_FORCE_ID
+
+#define TRAXXAS_CHANNEL 0x05
+#define TRAXXAS_BIND_CHANNEL 0x2B
+#define TRAXXAS_PACKET_SIZE 16
+
+enum {
+ TRAXXAS_BIND_PREP_RX=0,
+ TRAXXAS_BIND_RX,
+ TRAXXAS_BIND_TX1,
+ TRAXXAS_PREP_DATA,
+ TRAXXAS_DATA,
+};
+
+const uint8_t PROGMEM TRAXXAS_sop_bind[] ={ 0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91 };
+const uint8_t PROGMEM TRAXXAS_sop_data[] ={ 0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C };
+//const uint8_t PROGMEM TRAXXAS_sop_check[]={ 0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72 };
+
+const uint8_t PROGMEM TRAXXAS_init_vals[][2] = {
+ //Init from dump
+ {CYRF_0B_PWR_CTRL, 0x00}, // PMU
+ {CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
+ {CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
+ {CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
+ {CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
+ {CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable
+ {CYRF_06_RX_CFG, 0x88 | 0x02}, // AGC enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX
+ {CYRF_1E_RX_OVERRIDE, 0x08}, // Reject packets with 0 seed
+ {CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes
+};
+
+static void __attribute__((unused)) TRAXXAS_cyrf_bind_config()
+{
+ CYRF_PROGMEM_ConfigSOPCode(TRAXXAS_sop_bind);
+ CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x5A);
+ CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x5A);
+ CYRF_ConfigRFChannel(TRAXXAS_BIND_CHANNEL);
+}
+
+static void __attribute__((unused)) TRAXXAS_cyrf_data_config()
+{
+ CYRF_PROGMEM_ConfigSOPCode(TRAXXAS_sop_data);
+ #ifdef TRAXXAS_FORCE_ID // data taken from TX dump
+ CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x1B);
+ CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x3F);
+ #else
+ CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0]+0xB6);
+ CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1]+0x5D);
+ #endif
+ CYRF_ConfigRFChannel(TRAXXAS_CHANNEL);
+ CYRF_SetTxRxMode(TX_EN);
+}
+
+static void __attribute__((unused)) TRAXXAS_send_data_packet()
+{
+ packet[0] = 0x01;
+ memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
+ //Steering
+ uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000);
+ packet[2]=ch>>8;
+ packet[3]=ch;
+ //Throttle
+ ch = convert_channel_16b_nolimit(THROTTLE,500,1000);
+ packet[4]=ch>>8;
+ packet[5]=ch;
+ //AUX3
+ ch = convert_channel_16b_nolimit(AILERON,500,1000);
+ packet[6]=ch>>8;
+ packet[7]=ch;
+ //AUX4???
+ ch = convert_channel_16b_nolimit(ELEVATOR,500,1000);
+ packet[12]=ch>>8;
+ packet[13]=ch;
+
+ CYRF_SetPower(0x08);
+ CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
+}
+
+uint16_t ReadTRAXXAS()
+{
+ uint8_t status;
+
+ switch(phase)
+ {
+ case TRAXXAS_BIND_PREP_RX:
+ TRAXXAS_cyrf_bind_config();
+ CYRF_SetTxRxMode(RX_EN); //Receive mode
+ CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); //Prepare to receive
+ packet_count=100; //Timeout for RX
+ phase=TRAXXAS_BIND_RX;
+ return 700;
+ case TRAXXAS_BIND_RX:
+ //Read data from RX
+ status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
+ if((status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
+ status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
+ debugln("s=%02X",status);
+ CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
+ if((status & 0x07) == 0x02)
+ { // Data received with no errors
+ len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
+ debugln("L=%02X",len)
+ if(len==TRAXXAS_PACKET_SIZE)
+ {
+ CYRF_ReadDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
+ debug("RX=");
+ for(uint8_t i=0;i 127 )
+ #error "The CORONA forced frequency tuning value is outside of the range -127..127."
+ #endif
+#endif
#ifdef FORCE_FRSKYD_TUNING
#if ( FORCE_FRSKYD_TUNING < -127 ) || ( FORCE_FRSKYD_TUNING > 127 )
#error "The FrSkyD forced frequency tuning value is outside of the range -127..127."
@@ -77,14 +84,9 @@
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
#endif
#endif
-#ifdef FORCE_SFHSS_TUNING
- #if ( FORCE_SFHSS_TUNING < -127 ) || ( FORCE_SFHSS_TUNING > 127 )
- #error "The SFHSS forced frequency tuning value is outside of the range -127..127."
- #endif
-#endif
-#ifdef FORCE_CORONA_TUNING
- #if ( FORCE_CORONA_TUNING < -127 ) || ( FORCE_CORONA_TUNING > 127 )
- #error "The CORONA forced frequency tuning value is outside of the range -127..127."
+#ifdef FORCE_HITEC_TUNING
+ #if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
+ #error "The HITEC forced frequency tuning value is outside of the range -127..127."
#endif
#endif
#ifdef FORCE_REDPINE_TUNING
@@ -92,9 +94,20 @@
#error "The REDPINE forced frequency tuning value is outside of the range -127..127."
#endif
#endif
-#ifdef FORCE_HITEC_TUNING
- #if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
- #error "The HITEC forced frequency tuning value is outside of the range -127..127."
+#ifdef FORCE_SFHSS_TUNING
+ #if ( FORCE_SFHSS_TUNING < -127 ) || ( FORCE_SFHSS_TUNING > 127 )
+ #error "The SFHSS forced frequency tuning value is outside of the range -127..127."
+ #endif
+#endif
+//A7105
+#ifdef FORCE_AFHDS2A_TUNING
+ #if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
+ #error "The AFHDS2A forced frequency tuning value is outside of the range -300..300."
+ #endif
+#endif
+#ifdef FORCE_BUGS_TUNING
+ #if ( FORCE_BUGS_TUNING < -300 ) || ( FORCE_BUGS_TUNING > 300 )
+ #error "The BUGS forced frequency tuning value is outside of the range -300..300."
#endif
#endif
#ifdef FORCE_FLYSKY_TUNING
@@ -102,20 +115,27 @@
#error "The Flysky forced frequency tuning value is outside of the range -300..300."
#endif
#endif
+#ifdef FORCE_FLYZONE_TUNING
+ #if ( FORCE_FLYZONE_TUNING < -300 ) || ( FORCE_FLYZONE_TUNING > 300 )
+ #error "The Flyzone forced frequency tuning value is outside of the range -300..300."
+ #endif
+#endif
#ifdef FORCE_HUBSAN_TUNING
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
#endif
#endif
-#ifdef FORCE_AFHDS2A_TUNING
- #if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
- #error "The AFHDS2A forced frequency tuning value is outside of the range -300..300."
- #endif
-#endif
+
#ifndef USE_A7105_CH15_TUNING
+ #ifndef FORCE_BUGS_TUNING
+ #define FORCE_BUGS_TUNING 0
+ #endif
#ifndef FORCE_FLYSKY_TUNING
#define FORCE_FLYSKY_TUNING 0
#endif
+ #ifndef FORCE_FLYZONE_TUNING
+ #define FORCE_FLYZONE_TUNING 0
+ #endif
#ifndef FORCE_HUBSAN_TUNING
#define FORCE_HUBSAN_TUNING 0
#endif
@@ -124,6 +144,10 @@
#endif
#endif
+#if defined (USE_CYRF6936_CH15_TUNING) && (DSM_THROTTLE_KILL_CH == 15)
+ #error "Error Channel 15 conflict between the CYRF6936 freq tuning and the DSM throttle kill feature."
+#endif
+
//Change/Force configuration if OrangeTX
#ifdef ORANGE_TX
#undef ENABLE_PPM // Disable PPM for OrangeTX module
@@ -144,6 +168,7 @@
#undef HUBSAN_A7105_INO
#undef AFHDS2A_A7105_INO
#undef BUGS_A7105_INO
+ #undef FLYZONE_A7105_INO
#endif
#ifndef CYRF6936_INSTALLED
#undef DEVO_CYRF6936_INO
@@ -198,6 +223,7 @@
#undef V911S_NRF24L01_INO
#undef XN297L_CC2500_EMU
#undef POTENSIC_NRF24L01_INO
+ #undef ZSX_NRF24L01_INO
#endif
//Make sure telemetry is selected correctly
diff --git a/Multiprotocol/WFLY_cyrf6936.ino b/Multiprotocol/WFLY_cyrf6936.ino
index e62102c..baacbcd 100644
--- a/Multiprotocol/WFLY_cyrf6936.ino
+++ b/Multiprotocol/WFLY_cyrf6936.ino
@@ -80,9 +80,6 @@ static void __attribute__((unused)) WFLY_cyrf_data_config()
static uint16_t __attribute__((unused)) WFLY_send_data_packet()
{
- #ifdef USE_CYRF6936_CH15_TUNING
- static uint16_t Channel15=1024;
- #endif
packet_count++;
packet[0] = rx_tx_addr[2];
packet[1] = rx_tx_addr[3];
@@ -137,16 +134,6 @@ static uint16_t __attribute__((unused)) WFLY_send_data_packet()
sum += packet[i];
packet[len] = sum;
- #ifdef USE_CYRF6936_CH15_TUNING
- if(Channel15!=Channel_data[CH15])
- { // adjust frequency
- Channel15=Channel_data[CH15]+0x155; // default value is 0x555 = 0x400 + 0x155
- CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, Channel15&0xFF);
- CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, Channel15>>8);
- Channel15-=0x155;
- }
- #endif
-
CYRF_ConfigRFChannel(hopping_frequency[(packet_count)%4]);
CYRF_SetPower(0x08);
CYRF_WriteDataPacketLen(packet, len+1);
diff --git a/Multiprotocol/XN297Dump_nrf24l01.ino b/Multiprotocol/XN297Dump_nrf24l01.ino
index 85a8875..2ff6033 100644
--- a/Multiprotocol/XN297Dump_nrf24l01.ino
+++ b/Multiprotocol/XN297Dump_nrf24l01.ino
@@ -76,10 +76,10 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
{
uint16_t crcxored;
uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN];
-
// init crc
crc = 0xb5d2;
+ //Try normal payload
// address
for (uint8_t i = 0; i < address_length; i++)
{
@@ -112,6 +112,56 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
return true;
}
}
+
+ //Try enhanced payload
+ crc = 0xb5d2;
+ packet_length=0;
+ uint16_t crc_enh;
+ for (uint8_t i = 0; i < XN297DUMP_MAX_PACKET_LEN-XN297DUMP_CRC_LENGTH; i++)
+ {
+ packet_sc[i]=packet[i]^xn297_scramble[i];
+ crc = crc16_update(crc, packet[i], 8);
+ crc_enh = crc16_update(crc, packet[i+1] & 0xC0, 2);
+ crcxored=(packet[i+1]<<10)|(packet[i+2]<<2)|(packet[i+3]>>6) ;
+ if((crc_enh ^ pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[i - 3])) == crcxored)
+ { // Found a valid CRC for the enhanced payload mode
+ packet_length=i;
+ scramble=true;
+ i++;
+ packet_sc[i]=packet[i]^xn297_scramble[i];
+ memcpy(packet_un,packet_sc,packet_length+2); // unscramble packet
+ break;
+ }
+ if((crc_enh ^ pgm_read_word(&xn297_crc_xorout_enhanced[i - 3])) == crcxored)
+ { // Found a valid CRC for the enhanced payload mode
+ packet_length=i;
+ scramble=false;
+ memcpy(packet_un,packet,packet_length+2); // packet is unscrambled
+ break;
+ }
+ }
+ if(packet_length!=0)
+ { // Found a valid CRC for the enhanced payload mode
+ debug("Enhanced ");
+ //check selected address length
+ if((packet_un[address_length]>>1)!=packet_length-address_length)
+ {
+ for(uint8_t i=3;i<=5;i++)
+ if((packet_un[i]>>1)==packet_length-i)
+ address_length=i;
+ debug("Wrong address length selected using %d ", address_length )
+ }
+ debug("pid=%d ",((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7));
+ debug("ack=%d ",(packet_un[address_length+1]>>6)&0x01);
+ // address
+ for (uint8_t i = 0; i < address_length; i++)
+ packet[address_length-1-i]=packet_un[i];
+ // payload
+ for (uint8_t i = address_length; i < packet_length; i++)
+ packet[i] = bit_reverse((packet_un[i+1]<<2)|(packet_un[i+2]>>6));
+ return true;
+ }
+
return false;
}
diff --git a/Multiprotocol/ZSX_nrf24l01.ino b/Multiprotocol/ZSX_nrf24l01.ino
new file mode 100644
index 0000000..3e8f6be
--- /dev/null
+++ b/Multiprotocol/ZSX_nrf24l01.ino
@@ -0,0 +1,117 @@
+/*
+ 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 .
+ */
+// Compatible with JJRC ZSX-280 plane.
+
+#if defined(ZSX_NRF24L01_INO)
+
+#include "iface_xn297l.h"
+
+//#define FORCE_ZSX_ORIGINAL_ID
+
+#define ZSX_INITIAL_WAIT 500
+#define ZSX_PACKET_PERIOD 10093
+#define ZSX_RF_BIND_CHANNEL 7
+#define ZSX_PAYLOAD_SIZE 6
+#define ZSX_BIND_COUNT 50
+#define ZSX_RF_NUM_CHANNELS 1
+
+static void __attribute__((unused)) ZSX_send_packet()
+{
+ memcpy(&packet[1],rx_tx_addr,3);
+ if(IS_BIND_IN_PROGRESS)
+ {
+ packet[0] = 0xAA;
+ packet[4] = 0x00;
+ packet[5] = 0x00;
+ }
+ else
+ {
+ packet[0]= 0x55;
+ packet[4]= 0xFF-convert_channel_8b(RUDDER); // FF..80..01
+ packet[5]= convert_channel_8b(THROTTLE)>>1 // 0..7F
+ | GET_FLAG(CH5_SW, 0x80); // Light
+ }
+
+ XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
+ NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
+ NRF24L01_FlushTx();
+ XN297_WritePayload(packet, ZSX_PAYLOAD_SIZE);
+
+ NRF24L01_SetPower(); // Set tx_power
+}
+
+static void __attribute__((unused)) ZSX_initialize_txid()
+{
+ rx_tx_addr[0]=rx_tx_addr[3]; // Use RX_num;
+ #ifdef FORCE_ZSX_ORIGINAL_ID
+ //TX1
+ rx_tx_addr[0]=0x03;
+ rx_tx_addr[1]=0x01;
+ rx_tx_addr[2]=0xC3;
+ #endif
+}
+
+static void __attribute__((unused)) ZSX_init()
+{
+ NRF24L01_Initialize();
+ NRF24L01_SetTxRxMode(TX_EN);
+ NRF24L01_FlushTx();
+ NRF24L01_FlushRx();
+ NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
+ NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
+ NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
+ NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
+ NRF24L01_SetPower();
+ XN297_SetTXAddr((uint8_t*)"\xc1\xc2\xc3", 3);
+ NRF24L01_WriteReg(NRF24L01_05_RF_CH, ZSX_RF_BIND_CHANNEL); // Set bind channel
+}
+
+uint16_t ZSX_callback()
+{
+ if(IS_BIND_IN_PROGRESS)
+ if(--bind_counter==0)
+ {
+ BIND_DONE;
+ XN297_SetTXAddr(rx_tx_addr, 3);
+ NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x00);
+ }
+ ZSX_send_packet();
+ return ZSX_PACKET_PERIOD;
+}
+
+uint16_t initZSX()
+{
+ BIND_IN_PROGRESS; // autobind protocol
+ ZSX_initialize_txid();
+ ZSX_init();
+ bind_counter=ZSX_BIND_COUNT;
+ return ZSX_INITIAL_WAIT;
+}
+
+#endif
+
+// XN297 spped 1Mb, scrambled
+// Bind
+// channel 7
+// address: C1 C2 C3
+// P(6)= AA 03 01 C3 00 00
+// 03 01 C3 <- normal address
+// Normal
+// channel 0 and seems to be fixed
+// address: 03 01 C3
+// P(6)= 55 03 01 C3 80 00
+// 03 01 C3 <- normal address
+// 80 <- rudder FF..80..01
+// 00 <- throttle 00..7F, light flag 0x80
\ No newline at end of file
diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h
index dd445be..a7d4695 100644
--- a/Multiprotocol/_Config.h
+++ b/Multiprotocol/_Config.h
@@ -31,8 +31,8 @@
/*************************/
//Allow flashing multimodule directly with TX(erky9x or opentx maintenance mode)
//Instructions:https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Flash_from_Tx.md
-//To enable this feature remove the "//" on the next line. Requires a compatible bootloader or upload method to be selected when you use the Multi 4-in-1 Boards Manager definitions.
-//#define CHECK_FOR_BOOTLOADER
+//To disable this feature add "//" at the begining of the next line. Requires a compatible bootloader or upload method to be selected when you use the Multi 4-in-1 Boards Manager definitions.
+#define CHECK_FOR_BOOTLOADER
/*******************/
@@ -108,10 +108,11 @@
//Once a good tuning value is found it can be set here and will override the frequency tuning for a specific protocol.
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -300 to +300 and default is 0.
-//#define FORCE_FLYSKY_TUNING 0
-//#define FORCE_HUBSAN_TUNING 0
//#define FORCE_AFHDS2A_TUNING 0
-//#define FORCE_BUGS_TUNING 0
+//#define FORCE_BUGS_TUNING 0
+//#define FORCE_FLYSKY_TUNING 0
+//#define FORCE_FLYZONE_TUNING 0
+//#define FORCE_HUBSAN_TUNING 0
/** CYRF6936 Fine Frequency Tuning **/
//This is required in rare cases where some CYRF6936 modules and/or RXs have an inaccurate crystal oscillator.
@@ -155,20 +156,20 @@
//The protocols below need an A7105 to be installed
#define AFHDS2A_A7105_INO
-#define FLYSKY_A7105_INO
-#define HUBSAN_A7105_INO
#define BUGS_A7105_INO
+#define FLYSKY_A7105_INO
+#define FLYZONE_A7105_INO
+#define HUBSAN_A7105_INO
//The protocols below need a CYRF6936 to be installed
#define DEVO_CYRF6936_INO
#define DSM_CYRF6936_INO
#define J6PRO_CYRF6936_INO
+#define TRAXXAS_CYRF6936_INO
#define WFLY_CYRF6936_INO
#define WK2x01_CYRF6936_INO
#define SCANNER_CYRF6936_INO
-//#define TRAXXAS_CYRF6936_INO
-
//The protocols below need a CC2500 to be installed
#define CORONA_CC2500_INO
#define FRSKYD_CC2500_INO
@@ -211,6 +212,7 @@
#define V761_NRF24L01_INO
#define V911S_NRF24L01_INO
#define YD717_NRF24L01_INO
+#define ZSX_NRF24L01_INO
/***************************/
@@ -223,10 +225,10 @@
// For more throw, 1024..1976us @100% and 904..2096us @125%, remove the "//" on the line below. Be aware that too much throw can damage some UMX servos. To achieve standard throw in this mode use a channel weight of 84%.
//#define DSM_MAX_THROW
//Some models (X-Vert, Blade 230S...) require a special value to instant stop the motor(s).
-// You can disable this feature by adding "//" on the line below. You have to specify which channel (15 by default) will be used to kill the throttle channel.
-// If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
+// You can disable this feature by adding "//" on the line below. You have to specify which channel (14 by default) will be used to kill the throttle channel.
+// If the channel 14 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
// For example, a value of -80% applied on channel 15 will instantly kill the motors on the X-Vert.
-#define DSM_THROTTLE_KILL_CH 15
+#define DSM_THROTTLE_KILL_CH 14
//AFHDS2A specific settings
//-------------------------
@@ -274,11 +276,11 @@
//Comment if you don't want to send Multi status telemetry frames (Protocol available, Bind in progress, version...)
//Use with er9x/erksy9x, for OpenTX MULTI_TELEMETRY below is preferred instead
-#define MULTI_STATUS
+//#define MULTI_STATUS
//Uncomment to send Multi status and allow OpenTX to autodetect the telemetry format
//Supported by OpenTX version 2.2 RC9 and newer. NOT supported by er9x/ersky9x use MULTI_STATUS instead.
-//#define MULTI_TELEMETRY
+#define MULTI_TELEMETRY
//Comment a line to disable a specific protocol telemetry
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, ersky9x and OpenTX
@@ -532,6 +534,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
V6X6
V912
CX20
+ PROTO_FLYZONE
+ FZ410
PROTO_FQ777
NONE
PROTO_FRSKYD
@@ -625,7 +629,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
SYMAX
SYMAX5C
PROTO_TRAXXAS
- NONE
+ RX6519
PROTO_V2X2
V2X2
JXD506
@@ -648,4 +652,6 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
SYMAX4
XINXUN
NIHUI
+ PROTO_ZSX
+ NONE
*/
diff --git a/Protocols_Details.md b/Protocols_Details.md
index 6892ddd..6a4e617 100644
--- a/Protocols_Details.md
+++ b/Protocols_Details.md
@@ -84,6 +84,7 @@ CFlie|38|CFlie||||||||NRF24L01
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01
[Flysky](Protocols_Details.md#FLYSKY---1)|1|Flysky|V9x9|V6x6|V912|CX20||||A7105
[Flysky AFHDS2A](Protocols_Details.md#FLYSKY-AFHDS2A---28)|28|PWM_IBUS|PPM_IBUS|PWM_SBUS|PPM_SBUS|||||A7105
+[Flyzone](Protocols_Details.md#FLYZONE---53)|53|Flyzone|FZ410|||||||A7105
[FQ777](Protocols_Details.md#FQ777---23)|23|FQ777||||||||NRF24L01
[FrskyD](Protocols_Details.md#FRSKYD---3)|3|FrskyD||||||||CC2500
[FrskyV](Protocols_Details.md#FRSKYV---25)|25|FrskyV||||||||CC2500
@@ -111,18 +112,21 @@ CFlie|38|CFlie||||||||NRF24L01
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01
-Traxxas|43|Traxxas||||||||NRF24L01
+[Traxxas](Protocols_Details.md#Traxxas---43)|43|Traxxas|RX6519|||||||CYRF6936
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|||||||NRF24L01
[V761](Protocols_Details.md#V761---48)|48|V761||||||||NRF24L01
[V911S](Protocols_Details.md#V911S---46)|46|V911S*||||||||NRF24L01
[WFly](Protocols_Details.md#WFLY---40)|40|WFLY||||||||CYRF6936
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01
+[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01
* "*" Sub Protocols designated by * suffix will use the NRF24L01 module by default to emulate the XN297L RF chip.
* If a CC2500 module is installed it will be used instead as it is proving to be a better option for the XN297L@250kbps. Each specific sub protocol has a more detailed explanation.
# A7105 RF Module
+If USE_A7105_CH15_TUNING is enabled, the value of channel 15 is used by all A7105 protocols for tuning the frequency. This is required in rare cases where some A7105 modules and/or RXs have an inaccurate crystal oscillator.
+
## FLYSKY - *1*
Extended limits supported
@@ -183,6 +187,15 @@ Note that the RX ouput will be AETR whatever the input channel order is.
### Sub_protocol PWM_SBUS - *2*
### Sub_protocol PPM_SBUS - *3*
+## FLYZONE - *53*
+Models using the Flyzone FZ-410 TX: Fokker D.VII Micro EP RTF
+
+Models using the old ARES TX (prior to Hitec RED): Tiger Moth
+
+CH1|CH2|CH3|CH4
+---|---|---|---
+A|E|T|R
+
## HUBSAN - *2*
Telemetry enabled for battery voltage and TX RSSI
@@ -372,12 +385,14 @@ A|E|T|R|CH5|CH6|CH7|CH8
***
# CYRF6936 RF Module
+If USE_CYRF6936_CH15_TUNING is enabled, the value of channel 15 is used by all CYRF6936 protocols for tuning the frequency. This is required in rare cases where some CYRF6936 modules and/or RXs have an inaccurate crystal oscillator.
+
## DEVO - *7*
Extended limits and failsafe supported
-CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
----|---|---|---|---|---|---|---
-A|E|T|R|CH5|CH6|CH7|CH8
+CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
+---|---|---|---|---|---|---|---|---|---|---|---
+A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
Note that the RX ouput will be EATR.
@@ -483,16 +498,16 @@ Telemetry enabled for TSSI and plugins
option=number of channels from 4 to 12. An invalid option value will end up with 6 channels.
-CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|----|CH15
----|---|---|---|---|---|---|---|---|----|----|----|----|----|----
-A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|----|TH_KILL
+CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|CH14
+---|---|---|---|---|---|---|---|---|----|----|----|----|----
+A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|TH_KILL
Notes:
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
- RX output will match the Spektrum standard TAER independently of the input configuration AETR, RETA...
- RX output will match the Spektrum standard throw (1500µs +/- 400µs -> 1100..1900µs) for a 100% input. This is true for both Serial and PPM input. For PPM, make sure the end points PPM_MIN_100 and PPM_MAX_100 in _config.h are matching your TX ouput. The maximum ouput is 1000..2000µs based on an input of 125%.
- If you want to override the above and get maximum throw (old way) uncomment in _config.h the line #define DSM_MAX_THROW . In this mode to achieve standard throw use a channel weight of 84%.
- - TH_KILL is a feature which is enabled on channel 15 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 15 will instantly kill the motors on the X-Vert.
+ - TH_KILL is a feature which is enabled on channel 14 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
### Sub_protocol DSM2_22 - *0*
DSM2, Resolution 1024, refresh rate 22ms
@@ -515,6 +530,15 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
---|---|---|---|---|---|---|---|---|----|----|----
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
+## Traxxas - *43*
+Receiver 6519
+
+Extended limits supported
+
+CH1|CH2|CH3|CH4
+---|---|---|---
+AUX3|AUX4|THROTTLE|STEERING
+
## WFLY - *40*
Receivers: WFR04S, WFR07S, WFR09S
@@ -1180,6 +1204,15 @@ A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
### Sub_protocol NIHUI - *4*
Same channels assignement as above.
+## ZSX - *52*
+Model: JJRC ZSX-280
+
+Autobind protocol
+
+CH1|CH2|CH3|CH4|CH5
+---|---|---|---|---
+||T|R|LIGHT
+
# OpenLRS module
## OpenLRS - *27*
diff --git a/docs/Advanced_Debug.md b/docs/Advanced_Debug.md
new file mode 100644
index 0000000..be39c3b
--- /dev/null
+++ b/docs/Advanced_Debug.md
@@ -0,0 +1,21 @@
+# Enable the STM32 module serial debug feature
+
+To enable serial debug on your module you must know how to buid the firmware from the source code available on this GitHub. To do so follow this page: [Compiling and programming the STM32 module](Compiling_STM32.md).
+
+Procedure to use serial debug:
+1. Edit the file [Multiprotocol.ino](../Multiprotocol/Multiprotocol.ino#L26)
+1. Modify at the begining of the file the line: `//#define DEBUG_SERIAL` by removing the // leaving only: `#define DEBUG_SERIAL`
+1. Save the file
+1. Upload the firmware to the module:
+
+iRangeX+, Banggood and old Jumper 4in1 modules|Recent Jumper 4in1 modules with built-in CP2102|FTDI
+----------------------------------------------|-----------------------------------------------|----
+Use the Upload method:"Upload via USB"|Use the Upload method: "Upload via Serial (FTDI)|Use the Upload method: "Upload via Serial (FTDI)
+Do not disconnect the USB cable. In case you have to do it, you have to connect the module, close and reopen the Serial Monitor to get the module working otherwise it will be stuck with the status LED off.|Do not disconnect the USB cable. In case you have to do it, you have to power first the TX and then connect the USB cable to the module and relaunch the Serial monitor.|No restrictions apart from relaunching the Serial monitor if you disconnect the FTDI from the PC
+
+5. Power on the TX
+1. Open in the Arduino IDE the Serial Monitor: Tools->Serial Monitor or Ctrl+Shift+M
+1. Make sure the settings at the bottom of the Serial Monitor window are the same as the picture above especially the baud rate set to 115200 baud
+1. The Serial Monitor window should show the module booting, selection of a different protocol and more depending on the protocol currently loaded
+1. At this stage you can test whatever is needed or have been instructed to do. You can easily select text in the window to copy and paste it on the forum or in a text file.
+1. **Important: to use your module normally and before flying you must reupload the firmware as you usually do with the debug line commented: `//#define DEBUG_SERIAL` **
diff --git a/docs/Advanced_Topics.md b/docs/Advanced_Topics.md
index edd1523..97bded3 100644
--- a/docs/Advanced_Topics.md
+++ b/docs/Advanced_Topics.md
@@ -1,11 +1,17 @@
-# Advanced Topics {This page is currently a proof of concept}
+# Advanced Topics
Warning: the topics on this page are not for the fainthearted. It is strongly recommended that you have some experience in getting up and runnning with your module before you dive in there. On the other hand what is described on this page are some very useful options that could greatly increase the value and the enjoyment of your Multiprotocol module.
+# Enable STM32 module serial debug
+This document describes how to enable serial debug for STM32 MULTI-modules. This can be useful in case of issues with a protocol or to reverse a protocol based on the XN297L RF component. See the [MULTI-Module Serial Debug](Advanced_Debug.md) page for more details.
+
+# XN297L dump feature
+This document describes how to dump packets sent from a TX using a XN297L RF compatible component over the air on a STM32 MULTI-modules. This can be useful to get details on a protocol or even fully reverse a protocol as used in many remote controls lately. See the [MULTI-Module XN297L Dump](Advanced_XN297Ldump.md) page for more details.
+
+# EEPROM Backup and Restore
+This document describes how to back up and restore the EEPROM for both Atmega328p and STM32 MULTI-modules. This can be useful if cloning a module, or to preserve settings. See the [MULTI-Module EEPROM](EEPROM.md) page for more details.
+
# Telemetry in PPM mode
It is possible to access the telemetry stream coming from the receiver through the MULTI-module. This document describes a simple bluetooth module to stream telemetry information to a mobile device like an Android smartphone or tablet. The method may be generalized to feed telemetry to the transmitter if the transmitter has the capabilities to process the information. This is very useful with modules used in the PPM mode with transmitters that do not support telemetry. See the [Advanced Bluetooth Telemetry](Advanced_Bluetooth_Telemetry.md) page for more details.
# Manually setting fuses on ATmega328
This document describes a relatively simple process to set the fuses on ATmega328. See the [Advanced Manually Setting ATmega328 Fuses](Advanced_Manually_Setting_ATmega328_Fuses.md) page for more details.
-
-# EEPROM Backup and Restore
-This document describes how to back up and restore the EEPROM for both Atmega328p and STM32 MULTI-modules. This can be useful if cloning a module, or to preserve settings. See the [MULTI-Module EEPROM](EEPROM.md) page for more details.
diff --git a/docs/Advanced_XN297Ldump.md b/docs/Advanced_XN297Ldump.md
new file mode 100644
index 0000000..2512e23
--- /dev/null
+++ b/docs/Advanced_XN297Ldump.md
@@ -0,0 +1,16 @@
+# XN297L dump feature
+
+To get the XN297L dump feature working on your module you must know:
+1. How to buid the firmware from the source code available on this GitHub. To do so follow this page: [Compiling and programming the STM32 module](Compiling_STM32.md).
+1. How to enable serial debug [MULTI-Module Serial Debug](Advanced_Debug.md).
+
+Procedure to use the XN297L dump feature:
+1. Start the Multi module in serial debug mode with the Arduion IDE Serial Monitor open
+1. Select the protocol 63 or "Custom 63" to enable the XN297L Dump protocol
+1. This protocol parameters are:
+ * sub_protocol or type or the second number after "Custom 63" is used to set the transmission speed: 0=250Kbps, 1=1Mbps and 2=2Mbps. Any other value will default to 1Mbps.
+ * RX_num or Receiver number sets the address length 3, 4 or 5 bytes. Any other value will default to an address length of 5 bytes.
+ * option sets the RF channel number used to receive packets between 0..84 . A value of -1 will automatically scan all channels one by one. Any other value will default to the RF channel 0.
+
+Examples:
+TBC
\ No newline at end of file
diff --git a/docs/images/Serial_Monitor_1.png b/docs/images/Serial_Monitor_1.png
new file mode 100644
index 0000000..6ea902f
Binary files /dev/null and b/docs/images/Serial_Monitor_1.png differ
diff --git a/docs/images/Serial_Monitor_2.png b/docs/images/Serial_Monitor_2.png
new file mode 100644
index 0000000..ce0f435
Binary files /dev/null and b/docs/images/Serial_Monitor_2.png differ