E129/C186 protocol

C186/E120 models
This commit is contained in:
pascallanger 2022-06-27 16:59:48 +02:00
parent 4f580a4286
commit 0a0463652b
9 changed files with 89 additions and 31 deletions

View File

@ -18,15 +18,17 @@
#include "iface_rf2500.h" #include "iface_rf2500.h"
//#define E129_FORCE_ID //#define E129_FORCE_ID
//#define C186_FORCE_ID
#define E129_BIND_CH 0x2D //45 #define E129_BIND_CH 0x2D //45
#define E129_PAYLOAD_SIZE 16 #define E129_PAYLOAD_SIZE 16
#define C186_PAYLOAD_SIZE 19
static void __attribute__((unused)) E129_build_data_packet() static void __attribute__((unused)) E129_build_data_packet()
{ {
//Build the packet //Build the packet
memset(packet,0,E129_PAYLOAD_SIZE); memset(packet,0,packet_length);
packet[ 0] = 0x0F; // Packet length packet[ 0] = packet_length - 1; // Packet length
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
packet[ 1] = 0xA4; packet[ 1] = 0xA4;
@ -40,11 +42,22 @@ static void __attribute__((unused)) E129_build_data_packet()
else else
{ {
packet[ 1] = 0xA6; packet[ 1] = 0xA6;
packet[ 2] = 0xF7; // High rate 0xF7, low rate 0xF4 //Flags
//packet[ 3] = 0x00; // Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->... if(sub_protocol == E129_E129)
packet[ 2] = 0xF7; // High rate 0xF7, low 0xF4
else //C186
{
packet[ 2] = 0xFA; // High rate 0xFA, medium 0xF7, low 0xF4
packet[13] = bit_reverse(rx_tx_addr[2]);
packet[14] = bit_reverse(rx_tx_addr[3]);
packet[15] = bit_reverse(rx_tx_addr[0]);
packet[16] = bit_reverse(rx_tx_addr[1]);
}
//packet[ 3] = 0x00; // E129 Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->... => C186 throttle trim is doing the same:up=short press and down=long press
packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20 packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20
| GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04 | GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04
//Channels and trims
uint16_t val = convert_channel_10b(AILERON,false); uint16_t val = convert_channel_10b(AILERON,false);
uint8_t trim = convert_channel_8b(CH7) & 0xFC; uint8_t trim = convert_channel_8b(CH7) & 0xFC;
packet[ 5] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8 packet[ 5] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
@ -67,9 +80,13 @@ static void __attribute__((unused)) E129_build_data_packet()
packet[11] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8 packet[11] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
packet[12] = val; // channel (0x000...0x200...0x3FF) packet[12] = val; // channel (0x000...0x200...0x3FF)
} }
packet[14] = 0x00; // Check //Check
for(uint8_t i=0;i<14;i++) if(sub_protocol == E129_E129)
packet[14] += packet[i]; packet[packet_length-2] = packet[0] + packet[1];
else
packet[packet_length-2] = 0x24 + packet[0] + (packet[1]&0x03); // ??
for(uint8_t i=2;i<packet_length-2;i++)
packet[packet_length-2] += packet[i];
RF2500_BuildPayload(packet); RF2500_BuildPayload(packet);
} }
@ -83,7 +100,7 @@ uint16_t E129_callback()
//Send packet //Send packet
RF2500_SendPayload(); RF2500_SendPayload();
//Send twice on same channel //E129 sends twice on same channel, not the C186 but there is a bug somewhere if I don't send the packets back to back
if(phase==0) if(phase==0)
{ {
phase++; phase++;
@ -109,7 +126,9 @@ uint16_t E129_callback()
hopping_frequency_no &= 3; hopping_frequency_no &= 3;
phase=0; phase=0;
return 5200-1260; if(sub_protocol==E129_E129)
return 5200-1260;
return 5500-1260; //E129_C186
} }
void E129_init() void E129_init()
@ -117,8 +136,9 @@ void E129_init()
BIND_IN_PROGRESS; // Autobind protocol BIND_IN_PROGRESS; // Autobind protocol
bind_counter = 384; // ~2sec bind_counter = 384; // ~2sec
//RF2500 emu init //RF2500 emu init
RF2500_Init(E129_PAYLOAD_SIZE, true); // 16 bytes, Scrambled packet_length = sub_protocol == E129_E129?E129_PAYLOAD_SIZE:C186_PAYLOAD_SIZE;
RF2500_Init(packet_length, true); // 16/19 bytes, Scrambled
//Freq hopping //Freq hopping
calc_fh_channels(4); calc_fh_channels(4);
@ -136,6 +156,16 @@ void E129_init()
hopping_frequency[2]=0x4B; //75 hopping_frequency[2]=0x4B; //75
hopping_frequency[3]=0x41; //65 hopping_frequency[3]=0x41; //65
#endif #endif
#ifdef C186_FORCE_ID
rx_tx_addr[0]=0x91;
rx_tx_addr[1]=0x02;
rx_tx_addr[2]=0x5D;
rx_tx_addr[3]=0x33;
hopping_frequency[0]=0x44 + 2;
hopping_frequency[1]=0x41 + 2;
hopping_frequency[2]=0x43 + 2;
hopping_frequency[3]=0x49 + 2;
#endif
RF2500_SetTXAddr((uint8_t*)"\xE2\x32\xE0\xC8"); // 4 bytes of bind address RF2500_SetTXAddr((uint8_t*)"\xE2\x32\xE0\xC8"); // 4 bytes of bind address

View File

@ -80,7 +80,7 @@
80,E016H,E016Hv2 80,E016H,E016Hv2
81,E010r5 81,E010r5
82,LOLI 82,LOLI
83,E129 83,E129,E129,C186
84,JOYSWAY 84,JOYSWAY
85,E016H 85,E016H
87,IKEA 87,IKEA

View File

@ -163,6 +163,7 @@ const char STR_SUBTYPE_FUTABA[] = "\x05""SFHSS";
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr"; const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0"; const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320"; const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320";
const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
#define NO_SUBTYPE nullptr #define NO_SUBTYPE nullptr
@ -253,7 +254,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_E01X, STR_E01X, STR_SUBTYPE_E01X, 2, OPTION_NONE, 0, 0, SW_CYRF, E01X_init, E01X_callback }, {PROTO_E01X, STR_E01X, STR_SUBTYPE_E01X, 2, OPTION_NONE, 0, 0, SW_CYRF, E01X_init, E01X_callback },
#endif #endif
#if defined(E129_CYRF6936_INO) #if defined(E129_CYRF6936_INO)
{PROTO_E129, STR_E129, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E129_init, E129_callback }, {PROTO_E129, STR_E129, STR_SUBTYPE_E129, 2, OPTION_NONE, 0, 0, SW_CYRF, E129_init, E129_callback },
#endif #endif
#if defined(ESKY_NRF24L01_INO) #if defined(ESKY_NRF24L01_INO)
{PROTO_ESKY, STR_ESKY, STR_SUBTYPE_ESKY, 2, OPTION_NONE, 0, 1, SW_NRF, ESKY_init, ESKY_callback }, {PROTO_ESKY, STR_ESKY, STR_SUBTYPE_ESKY, 2, OPTION_NONE, 0, 1, SW_NRF, ESKY_init, ESKY_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 3 #define VERSION_REVISION 3
#define VERSION_PATCH_LEVEL 12 #define VERSION_PATCH_LEVEL 13
#define MODE_SERIAL 0 #define MODE_SERIAL 0
@ -461,6 +461,12 @@ enum KF606
KF606_MIG320 = 1, KF606_MIG320 = 1,
}; };
enum E129
{
E129_E129 = 0,
E129_C186 = 1,
};
#define NONE 0 #define NONE 0
#define P_HIGH 1 #define P_HIGH 1
#define P_LOW 0 #define P_LOW 0

View File

@ -179,7 +179,7 @@ uint8_t option;
uint8_t cur_protocol[3]; uint8_t cur_protocol[3];
uint8_t prev_option; uint8_t prev_option;
uint8_t prev_power=0xFD; // unused power value uint8_t prev_power=0xFD; // unused power value
uint8_t RX_num; uint8_t RX_num;
//Serial RX variables //Serial RX variables
#define BAUD 100000 #define BAUD 100000

View File

@ -17,7 +17,7 @@
#define RF2500_ADDR_LENGTH 4 #define RF2500_ADDR_LENGTH 4
uint8_t RF2500_payload_length, RF2500_tx_addr[RF2500_ADDR_LENGTH], RF2500_buf[80]; uint8_t RF2500_payload_length, RF2500_tx_addr[RF2500_ADDR_LENGTH], RF2500_buf[100];
bool RF2500_scramble_enabled; bool RF2500_scramble_enabled;
static void __attribute__((unused)) RF2500_Init(uint8_t payload_length, bool scramble) static void __attribute__((unused)) RF2500_Init(uint8_t payload_length, bool scramble)
@ -35,9 +35,17 @@ static void __attribute__((unused)) RF2500_SetTXAddr(const uint8_t* addr)
static void __attribute__((unused)) RF2500_BuildPayload(uint8_t* buffer) static void __attribute__((unused)) RF2500_BuildPayload(uint8_t* buffer)
{ {
const uint8_t RF2500_scramble[] = { 0xD0, 0x9E, 0x53, 0x33, 0xD8, 0xBA, 0x98, 0x08, 0x24, 0xCB, 0x3B, 0xFC, 0x71, 0xA3, 0xF4, 0x55 }; const uint8_t RF2500_scramble[] = { 0xD0, 0x9E, 0x53, 0x33, 0xD8, 0xBA, 0x98, 0x08, 0x24, 0xCB, 0x3B, 0xFC, 0x71, 0xA3, 0xF4, 0x55, 0x68, 0x4F, 0xA9 }; //0x4F: unsure
const uint16_t RF2500_crc_xorout_scramble = 0xAEE4; uint16_t RF2500_crc_xorout_scramble;
if(RF2500_payload_length == 16)
RF2500_crc_xorout_scramble = 0xAEE4;
else //19
RF2500_crc_xorout_scramble = 0xE7C5;
#if 0
for(uint8_t i=0; i<RF2500_payload_length; i++)
debug("%02X ", buffer[i]);
#endif
//Scramble the incoming buffer //Scramble the incoming buffer
if(RF2500_scramble_enabled) if(RF2500_scramble_enabled)
for(uint8_t i=0; i<RF2500_payload_length; i++) for(uint8_t i=0; i<RF2500_payload_length; i++)
@ -50,6 +58,10 @@ static void __attribute__((unused)) RF2500_BuildPayload(uint8_t* buffer)
buffer[RF2500_payload_length ] = bit_reverse(crc>>8); buffer[RF2500_payload_length ] = bit_reverse(crc>>8);
buffer[RF2500_payload_length+1] = bit_reverse(crc); buffer[RF2500_payload_length+1] = bit_reverse(crc);
#if 0
debugln("C:%02X %02X",buffer[RF2500_payload_length ], buffer[RF2500_payload_length+1]);
#endif
if(RF2500_scramble_enabled) if(RF2500_scramble_enabled)
{ {
buffer[RF2500_payload_length ] ^= RF2500_crc_xorout_scramble>>8; buffer[RF2500_payload_length ] ^= RF2500_crc_xorout_scramble>>8;

View File

@ -609,12 +609,12 @@ static uint16_t XN297Dump_callback()
{ {
if(phase==0) if(phase==0)
{ {
address_length=5; address_length=3;
memcpy(rx_tx_addr, (uint8_t *)"\x61\x94\x17\x27\xED", address_length); //"\xA3\x05\x22\xC1""\x5A\x20\x12\xAC" memcpy(rx_tx_addr, (uint8_t *)"\xBD\x54\x78", address_length); //"\x62\xE6\xBD\x54\x78"
bitrate=XN297DUMP_250K; bitrate=XN297DUMP_1M;
packet_length=32; packet_length=7;
hopping_frequency_no=54; //bind ?, normal 60 hopping_frequency_no=40; //bind ?, normal 40
NRF24L01_Initialize(); NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);
@ -622,7 +622,7 @@ static uint16_t XN297Dump_callback()
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, address_length-2); // RX/TX address length NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, address_length-2); // RX/TX address length
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0 NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,hopping_frequency_no,address_length); debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,hopping_frequency_no,address_length);
switch(bitrate) switch(bitrate)
@ -718,6 +718,7 @@ static uint16_t XN297Dump_callback()
NRF24L01_FlushRx(); NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
} }
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
} }
} }
else if(sub_protocol == XN297DUMP_CC2500) else if(sub_protocol == XN297DUMP_CC2500)

View File

@ -612,7 +612,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
E012 E012
E015 E015
PROTO_E129 PROTO_E129
NONE E129_E129
E129_C186
PROTO_ESKY PROTO_ESKY
ESKY_STD ESKY_STD
ESKY_ET4 ESKY_ET4

View File

@ -76,11 +76,11 @@ CFlie|38|CFlie||||||||NRF24L01|
[DM002](Protocols_Details.md#DM002---33)|33|||||||||NRF24L01|XN297 [DM002](Protocols_Details.md#DM002---33)|33|||||||||NRF24L01|XN297
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|||CYRF6936| [DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|||CYRF6936|
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936| [DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936|
[E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936/NRF24L01|RF2500 [E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936|RF2500
[E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297 [E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297
[E016HV2](Protocols_Details.md#E016HV2---80)|80|||||||||CC2500/NRF24L01|unknown [E016HV2](Protocols_Details.md#E016HV2---80)|80|||||||||CC2500/NRF24L01|unknown
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|||||||CYRF6936|HS6200 [E01X](Protocols_Details.md#E01X---45)|45|E012|E015|||||||CYRF6936|HS6200
[E129](Protocols_Details.md#E129---83)|83|||||||||CYRF6936/NRF24L01|RF2500 [E129](Protocols_Details.md#E129---83)|83|E129|C186|||||||CYRF6936|RF2500
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01| [ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01|
[ESky150](Protocols_Details.md#ESKY150---35)|35|||||||||NRF24L01| [ESky150](Protocols_Details.md#ESKY150---35)|35|||||||||NRF24L01|
[ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|||||||||CC2500|NRF51822 [ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|||||||||CC2500|NRF51822
@ -597,9 +597,8 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
A|E|T|R|ARM|FLIP|LED|HEADLESS|RTH A|E|T|R|ARM|FLIP|LED|HEADLESS|RTH
## E129 - *83* ## E129 - *83*
Models: Eachine E129/E130 and Twister Ninja 250
Not supported by Atmega328p modules. **Not supported by Atmega328p modules.**
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|--- ---|---|---|---|---|---|---|---|---
@ -611,6 +610,14 @@ Take off with a none spring throttle is easier by putting both sticks down outwa
Calib is the same as the original radio with both sticks down and to the left in Mode 1/2, not sure about other modes. Calib is the same as the original radio with both sticks down and to the left in Mode 1/2, not sure about other modes.
### Sub_protocol E129 - *0*
Models: Eachine E129/E130 and Twister Ninja 250
### Sub_protocol C186 - *1*
Models: C186, E120
The FC of the heli seems to store the trims Trim A/E/R=CH7..9. If you use these trims, make sure to center them after powering off the heli or they will be added to the previous trims.
## J6Pro - *22* ## J6Pro - *22*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12