diff --git a/Lua_scripts/MultiChan.txt b/Lua_scripts/MultiChan.txt
index bb4c934..fa1f291 100644
--- a/Lua_scripts/MultiChan.txt
+++ b/Lua_scripts/MultiChan.txt
@@ -177,3 +177,4 @@
52,0,ZSX,280,1,Light
78,0,M-Link,Std,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
79,0,WFLY2,RF20x,0,CH5,CH6,CH7,CH8,CH9,CH10
+80,0,E016H,E016Hv2,1,TakLan,EmStop,Flip,HLess,RTH
diff --git a/Multiprotocol/E016H_cc2500.ino b/Multiprotocol/E016H_cc2500.ino
new file mode 100644
index 0000000..481e504
--- /dev/null
+++ b/Multiprotocol/E016H_cc2500.ino
@@ -0,0 +1,146 @@
+/*
+ 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 .
+ */
+
+#if defined(E016H_CC2500_INO)
+
+#include "iface_nrf250k.h"
+
+#define FORCE_E016H_ORIGINAL_ID
+
+#define E016H_INITIAL_WAIT 500
+#define E016H_PACKET_PERIOD 10000
+#define E016H_RF_BIND_CHANNEL 5
+#define E016H_PAYLOAD_SIZE 11
+#define E016H_BIND_COUNT 300 //3sec
+
+static void __attribute__((unused)) E016H_send_packet()
+{
+ packet[0 ] = rx_tx_addr[0];
+ if(IS_BIND_IN_PROGRESS)
+ {
+ packet[1 ] = 0x02;
+ if(bind_counter)
+ bind_counter--;
+ else
+ {
+ BIND_DONE;
+ XN297L_RFChannel(hopping_frequency_no); // Set main channel
+ }
+ }
+ else
+ packet[1 ] = 0x20;
+ packet[2 ] = rx_tx_addr[2];
+ packet[3 ] = rx_tx_addr[3];
+
+ //channels TREA
+ uint8_t channel;
+ if(IS_BIND_IN_PROGRESS)
+ channel=0x64; // Throttle must be centered during bind
+ else
+ channel=convert_channel_8b_limit_deadband(THROTTLE,0x00,0x64,0xC8, 160);
+ packet[4 ] = channel;
+ channel=convert_channel_16b_limit(RUDDER,0x00,0xC8);
+ packet[5 ] = channel;
+ channel=convert_channel_16b_limit(ELEVATOR,0x00,0xC8);
+ packet[6 ] = channel;
+ channel=convert_channel_16b_limit(AILERON,0x00,0xC8);
+ packet[7 ] = channel;
+
+ //flags
+ packet[8 ] = GET_FLAG(CH7_SW, 0x01) // 0x01=Flip
+ | GET_FLAG(CH8_SW, 0x02) // 0x02=Headless
+ | GET_FLAG(CH9_SW, 0x04); // 0x04=One Key Return
+
+ packet[9 ] = 0x02; // Speed control 0x00:low, 0x01:medium, 0x02:high
+
+ packet[10] = GET_FLAG(CH5_SW, 0x01) // 0x01=TakeOff/Land (momentary switch)
+ | GET_FLAG(CH6_SW, 0x04); // 0x04=Emergeny Stop (momentary switch)
+
+ if(option==0)
+ option=1; // Select the CC2500
+ XN297L_SetPower(); // Set tx_power
+ XN297L_SetFreqOffset(); // Set frequency offset
+
+ //Build real packet and send it
+ static uint8_t pid=0;
+ crc=0;
+
+ // stop TX/RX
+ CC2500_Strobe(CC2500_SIDLE);
+ // flush tx FIFO
+ CC2500_Strobe(CC2500_SFTX);
+ // packet length
+ CC2500_WriteReg(CC2500_3F_TXFIFO, 6 + 4 + 1 + 11 + 2); // preamble + address + packet_control + payload + crc
+
+ // preamble+address
+ CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\xAA\xAA\xAA\xAA\xAA\xAA\xE7\xE7\xE7\xE7", 10);
+
+ // packet control
+ CC2500_WriteReg(CC2500_3F_TXFIFO, 0x50+(pid<<2));
+ pid++;
+
+ // payload
+ debug("P:")
+ for (uint8_t i = 0; i < E016H_PAYLOAD_SIZE; ++i)
+ {
+ uint8_t byte = (bit_reverse(packet[i])<<1) | (packet[i+1]&0x01);
+ debug(" %02X",byte)
+ CC2500_WriteReg(CC2500_3F_TXFIFO,byte);
+ crc=crc16_update(crc, byte, 8);
+ }
+
+ // crc
+ CC2500_WriteReg(CC2500_3F_TXFIFO,crc >> 8);
+ CC2500_WriteReg(CC2500_3F_TXFIFO,crc);
+ debugln(" %04X",crc)
+
+ // transmit
+ CC2500_Strobe(CC2500_STX);
+}
+
+uint16_t E016H_callback()
+{
+ E016H_send_packet();
+ return E016H_PACKET_PERIOD;
+}
+
+static void __attribute__((unused)) E016H_initialize_txid()
+{
+ //need to figure out ID&Freq
+ #ifdef FORCE_E016H_ORIGINAL_ID
+ rx_tx_addr[0]=0x0A;
+ rx_tx_addr[1]=0x02; // not used in the code
+ rx_tx_addr[2]=0x27;
+ rx_tx_addr[3]=0x1B;
+ hopping_frequency_no = 44;
+ #endif
+}
+
+uint16_t initE016H()
+{
+ //Config CC2500
+ if(option==0)
+ option=1; // Select the CC2500
+ XN297L_Init();
+ XN297L_RFChannel(E016H_RF_BIND_CHANNEL); // Set bind channel
+
+ E016H_initialize_txid();
+
+ bind_counter = E016H_BIND_COUNT;
+ BIND_IN_PROGRESS; // Autobind protocol
+ return E016H_INITIAL_WAIT;
+}
+
+#endif
diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino
index 98a9516..328cc62 100644
--- a/Multiprotocol/Multi_Names.ino
+++ b/Multiprotocol/Multi_Names.ino
@@ -94,6 +94,7 @@ const char STR_OMP[] ="OMP";
const char STR_MLINK[] ="M-Link";
const char STR_TEST[] ="Test";
const char STR_NANORF[] ="NanoRF";
+const char STR_E016H[] ="E016Hv2";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -212,6 +213,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(DSM_RX_CYRF6936_INO)
{PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE },
#endif
+ #if defined(E016H_CC2500_INO)
+ {PROTO_E016H, STR_E016H, 0, NO_SUBTYPE, OPTION_RFTUNE },
+ #endif
#if defined(E01X_NRF24L01_INO)
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
#endif
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index fd06bbe..9cd72a7 100644
--- a/Multiprotocol/Multiprotocol.h
+++ b/Multiprotocol/Multiprotocol.h
@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 1
-#define VERSION_PATCH_LEVEL 86
+#define VERSION_PATCH_LEVEL 87
//******************
// Protocols
@@ -105,6 +105,7 @@ enum PROTOCOLS
PROTO_OMP = 77, // =>CC2500 & NRF24L01
PROTO_MLINK = 78, // =>CYRF6936
PROTO_WFLY2 = 79, // =>A7105
+ PROTO_E016H = 80, // =>CC2500 & NRF24L01
PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500
@@ -838,6 +839,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
OMP 77
MLINK 78
WFLY2 79
+ E016H 80
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index c1294de..69ae1c0 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -1322,6 +1322,14 @@ static void protocol_init()
remote_callback = RLINK_callback;
break;
#endif
+ #if defined(E016H_CC2500_INO)
+ case PROTO_E016H:
+ PE1_off;
+ PE2_on; //antenna RF2
+ next_callback = initE016H();
+ remote_callback = E016H_callback;
+ break;
+ #endif
#endif
#ifdef CYRF6936_INSTALLED
#if defined(DSM_CYRF6936_INO)
diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h
index 1b04ce4..594c96c 100644
--- a/Multiprotocol/Validate.h
+++ b/Multiprotocol/Validate.h
@@ -263,6 +263,7 @@
#undef SCANNER_CC2500_INO
#undef FUTABA_CC2500_INO
#undef SKYARTEC_CC2500_INO
+ #undef E016H_CC2500_INO
#endif
#ifndef NRF24L01_INSTALLED
#undef ASSAN_NRF24L01_INO
@@ -274,6 +275,7 @@
#undef CG023_NRF24L01_INO
#undef CX10_NRF24L01_INO
#undef DM002_NRF24L01_INO
+ #undef E016H_CC2500_INO // Use both CC2500 and NRF code
#undef E01X_NRF24L01_INO
#undef ESKY_NRF24L01_INO
#undef ESKY150_NRF24L01_INO
@@ -292,7 +294,7 @@
#undef MJXQ_NRF24L01_INO
#undef MT99XX_NRF24L01_INO
#undef NCC1701_NRF24L01_INO
- #undef OMP_CC2500_INO
+ #undef OMP_CC2500_INO // Use both CC2500 and NRF code
#undef POTENSIC_NRF24L01_INO
#undef PROPEL_NRF24L01_INO
#undef Q303_NRF24L01_INO
diff --git a/Multiprotocol/XN297Dump_nrf24l01.ino b/Multiprotocol/XN297Dump_nrf24l01.ino
index 89ebfdb..95a42b0 100644
--- a/Multiprotocol/XN297Dump_nrf24l01.ino
+++ b/Multiprotocol/XN297Dump_nrf24l01.ino
@@ -628,11 +628,11 @@ static uint16_t XN297Dump_callback()
{
if(phase==0)
{
- address_length=5;
- memcpy(rx_tx_addr, (uint8_t *)"\xC9\x59\xD2\x65\x34", 5);
+ address_length=4;
+ memcpy(rx_tx_addr, (uint8_t *)"\xE7\xE7\xE7\xE7", 4);
bitrate=XN297DUMP_250K;
- packet_length=16;
- hopping_frequency_no=0x03;
+ packet_length=14;
+ hopping_frequency_no=5; //bind 5, normal 44
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TXRX_OFF);
@@ -669,7 +669,7 @@ static uint16_t XN297Dump_callback()
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
NRF24L01_Activate(0x73);
NRF24L01_SetPower();
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
+ NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); //_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
phase++;
}
else
@@ -679,21 +679,30 @@ static uint16_t XN297Dump_callback()
if(NRF24L01_ReadReg(NRF24L01_09_CD))
{
NRF24L01_ReadPayload(packet, packet_length);
- if(memcmp(packet_in,packet,packet_length))
- {
- debug("P:");
- for(uint8_t i=0;i>8)&0xFF) && packet[13]==(crc&0xFF))
+ if(memcmp(&packet_in[1],&packet[1],packet_length-1))
+ {
+ /*debug("P:");
+ for(uint8_t i=0;i>7))&0xFF);
+ debugln("");
+ memcpy(packet_in,packet,packet_length);
+ }
}
// restart RX mode
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(RX_EN);
NRF24L01_FlushRx();
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
+ NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
}
}
}
diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h
index 1daf636..7a303bf 100644
--- a/Multiprotocol/_Config.h
+++ b/Multiprotocol/_Config.h
@@ -188,6 +188,7 @@
//The protocols below need a CC2500 to be installed
#define CORONA_CC2500_INO
+#define E016H_CC2500_INO
#define ESKY150V2_CC2500_INO //Need both CC2500 and NRF
#define FRSKYL_CC2500_INO
#define FRSKYD_CC2500_INO
@@ -571,6 +572,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
DSMX_11
PROTO_DSM_RX
NONE
+ PROTO_E016H
+ NONE
PROTO_E01X
E012
E015
diff --git a/Protocols_Details.md b/Protocols_Details.md
index c0a0ec0..ed795aa 100644
--- a/Protocols_Details.md
+++ b/Protocols_Details.md
@@ -76,6 +76,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO||||CYRF6936|
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|RX||||||||CYRF6936|
+[E016H](Protocols_Details.md#E016H---80)|80|E016Hv2||||||||CC2500/NRF24L01|unknown
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01|
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
@@ -371,6 +372,22 @@ To bind V2 RXs you must follow the below procedure (original):
### Sub_protocol FD_V3 - *2*
FlyDream RXs like IS-4R and IS-4R0
+## E016H - *80*
+Models: E016H v2
+
+**Only 1 ID available**
+
+Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
+Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
+
+CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
+---|---|---|---|---|---|---|---
+A|E|T|R|TAKE_OFF/LANDING|EMERGENCY|FLIP|HEADLESS|RTH
+
+TAKE_OFF/LANDING: this is a momentary switch to arm the motors or land the quad. This switch is not really needed as you can start the quad with throttle low then increase throttle until the motor arms and continue to increase to lift off; To land just bring throttle all the way down, the quad will just stops when touching the ground.
+
+EMERGENCY: Can be used along with the throttle cut switch: Throttle cut=set throttle at -100% and set EMERGENCY to 100%
+
## FRSKYV - *25*
Models: FrSky receivers V8R4, V8R7 and V8FR.
- FrSkyV = FrSky 1 way