From 0955340a9361b251d5dbcc42ddddb97e6f9ab1fc Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Fri, 8 Jan 2021 21:16:07 +0100 Subject: [PATCH] New protocol: E010r5 --- Multiprotocol/E010R5_cyrf6936.ino | 213 ++++++++++++++++++++++++++++++ Multiprotocol/Multi_Names.ino | 4 + Multiprotocol/Multiprotocol.h | 4 +- Multiprotocol/Multiprotocol.ino | 9 +- Multiprotocol/Validate.h | 2 + Multiprotocol/_Config.h | 3 + Protocols_Details.md | 10 ++ 7 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 Multiprotocol/E010R5_cyrf6936.ino diff --git a/Multiprotocol/E010R5_cyrf6936.ino b/Multiprotocol/E010R5_cyrf6936.ino new file mode 100644 index 0000000..d66de85 --- /dev/null +++ b/Multiprotocol/E010R5_cyrf6936.ino @@ -0,0 +1,213 @@ +/* + 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(E010R5_CYRF6936_INO) + +#include "iface_cyrf6936.h" + +#define E010R5_FORCE_ID + +static uint8_t __attribute__((unused)) E010R5_BR(uint8_t byte) +{ + uint8_t result = 0; + for(uint8_t i=0;i<8;i++) + { + result = (result<<1) | (byte & 0x01); + byte >>= 1; + } + return result; +} + +static void __attribute__((unused)) E010R5_build_data_packet() +{ + uint8_t buf[16]; + + //Build the packet + buf[ 0] = 0x0D; // Packet length + buf[ 1] = convert_channel_8b(THROTTLE); + buf[ 2] = convert_channel_s8b(RUDDER); + buf[ 3] = convert_channel_s8b(ELEVATOR); + buf[ 4] = convert_channel_s8b(AILERON); + buf[ 5] = 0x20; // Trim Rudder + buf[ 6] = 0x20; // Trim Elevator + buf[ 7] = 0x20; // Trim Aileron + buf[ 8] = 0x01 // Flags: high=0x01, low=0x00 + | GET_FLAG(CH6_SW, 0x10) // headless=0x10 + | GET_FLAG(CH7_SW, 0x20); // one key return=0x20 + buf[ 9] = IS_BIND_IN_PROGRESS ? 0x80 : 0x00 // Flags: bind=0x80 + | GET_FLAG(CH5_SW, 0x01); // flip=0x01 + buf[10] = rx_tx_addr[0]; + buf[11] = rx_tx_addr[1]; + buf[12] = rx_tx_addr[2]; + buf[13] = 0x9D; // Check + for(uint8_t i=0;i<13;i++) + buf[13] += buf[i]; + + //Add CRC + crc=0x00; + for(uint8_t i=0;i<14;i++) + crc=crc16_update(crc,E010R5_BR(buf[i]),8); + buf[14] = E010R5_BR(crc>>8); + buf[15] = E010R5_BR(crc); + + #if 0 + debug("B:"); + for(uint8_t i=0; i<16; i++) + debug(" %02X",buf[i]); + debugln(""); + #endif + + //Build the payload + memcpy(packet,"\x0E\x54\x96\xEE\xC3\xC3",6); // 4 bytes of address followed by 5 FEC encoded + memset(&packet[6],0x00,70-6); + + //FEC encode + for(uint8_t i=0; i<16; i++) + { + for(uint8_t j=0;j<8;j++) + { + uint8_t offset=6 + (i<<2) + (j>>1); + packet[offset] <<= 4; + if( (buf[i]>>j) & 0x01 ) + packet[offset] |= 0x0C; + else + packet[offset] |= 0x03; + } + } + + #if 0 + debug("E:"); + for(uint8_t i=0; i<70; i++) + debug(" %02X",packet[i]); + debugln(""); + #endif + + //CYRF wants LSB first + for(uint8_t i=0;i<71;i++) + packet[i]=E010R5_BR(packet[i]); +} + +const uint8_t PROGMEM E010R5_init_vals[][2] = { + {CYRF_02_TX_CTRL, 0x00}, // transmit err & complete interrupts disabled + {CYRF_05_RX_CTRL, 0x00}, // receive err & complete interrupts disabled + {CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable, MUST be set + {CYRF_32_AUTO_CAL_TIME, 0x3c}, // must be set to 3C + {CYRF_35_AUTOCAL_OFFSET, 0x14}, // must be set to 14 + {CYRF_06_RX_CFG, 0x48}, // LNA manual control, Rx Fast Turn Mode Enable + {CYRF_1B_TX_OFFSET_LSB, 0x00}, // Tx frequency offset LSB + {CYRF_1C_TX_OFFSET_MSB, 0x00}, // Tx frequency offset MSB + {CYRF_0F_XACT_CFG, 0x24}, // Force End State, transaction end state = idle + {CYRF_03_TX_CFG, 0x00 | 7}, // GFSK mode, PA = +4 dBm + {CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN Code Correlator Threshold = 10 + {CYRF_0F_XACT_CFG, 0x04}, // Transaction End State = idle + {CYRF_39_ANALOG_CTRL, 0x01}, // synth setting time for all channels is the same as for slow channels + {CYRF_0F_XACT_CFG, 0x24}, //Force IDLE + {CYRF_29_RX_ABORT, 0x00}, //Clear RX abort + {CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold + {CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold + {CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort? + {CYRF_03_TX_CFG, 0x00 | 4}, // GFSK mode, set power (0-7) + {CYRF_10_FRAMING_CFG, 0x4a}, // 0b11000000 //set sop len and threshold + {CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC + {CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc + {CYRF_14_EOP_CTRL, 0x00}, //set EOP sync == 0 + {CYRF_01_TX_LENGTH, 70 }, // payload length +}; + +static void __attribute__((unused)) E010R5_cyrf_init() +{ + for(uint8_t i = 0; i < sizeof(E010R5_init_vals) / 2; i++) + CYRF_WriteRegister(pgm_read_byte_near(&E010R5_init_vals[i][0]), pgm_read_byte_near(&E010R5_init_vals[i][1])); + CYRF_WritePreamble(0xAAAA02); + CYRF_SetTxRxMode(TX_EN); +} + +uint16_t ReadE010R5() +{ + //Bind + if(bind_counter) + { + bind_counter--; + if(bind_counter==0) + BIND_DONE; + } + + //Send packet of 71 bytes... + uint8_t *buffer=packet; + CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40); + CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 16); + CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x80); + buffer+=16; + for(uint8_t i=0;i<6;i++) + { + while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); + CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 8); + buffer+=8; + } + while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); + CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 6); + + //Timing and hopping + packet_count++; + switch(packet_count) + { + case 1: + case 2: + case 4: + case 5: + return 1183; + default: + hopping_frequency_no++; + hopping_frequency_no &= 3; + if(IS_BIND_IN_PROGRESS) + rf_ch_num = 48 + (hopping_frequency_no<<3); + else + rf_ch_num = hopping_frequency[hopping_frequency_no]; + CYRF_ConfigRFChannel(rf_ch_num); + debugln("%d",hopping_frequency[hopping_frequency_no]); + packet_count = 0; + case 3: + E010R5_build_data_packet(); + return 3400; + } + return 0; +} + +uint16_t initE010R5() +{ + BIND_IN_PROGRESS; // autobind protocol + bind_counter = 2600; + + E010R5_cyrf_init(); + + #ifdef E010R5_FORCE_ID + hopping_frequency[0]=48; + hopping_frequency[1]=69; + hopping_frequency[2]=64; + hopping_frequency[3]=53; + rx_tx_addr[0]=0x00; + rx_tx_addr[1]=0x45; + rx_tx_addr[2]=0x46; + #endif + + E010R5_build_data_packet(); + CYRF_ConfigRFChannel(hopping_frequency[0]); + hopping_frequency_no=0; + packet_count=0; + + return 3400; +} + +#endif diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino index 14600e6..f74ba58 100644 --- a/Multiprotocol/Multi_Names.ino +++ b/Multiprotocol/Multi_Names.ino @@ -95,6 +95,7 @@ const char STR_MLINK[] ="M-Link"; const char STR_TEST[] ="Test"; const char STR_NANORF[] ="NanoRF"; const char STR_E016HV2[] ="E016Hv2"; +const char STR_E010R5[] ="E010r5"; const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20"; const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501"; @@ -213,6 +214,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(E010R5_CYRF6936_INO) + {PROTO_E010R5, STR_E010R5, 0, NO_SUBTYPE, OPTION_NONE }, + #endif #if defined(E016HV2_CC2500_INO) {PROTO_E016HV2, STR_E016HV2, 0, NO_SUBTYPE, OPTION_RFTUNE }, #endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index eabb09e..c8732d3 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 94 +#define VERSION_PATCH_LEVEL 96 //****************** // Protocols @@ -106,6 +106,7 @@ enum PROTOCOLS PROTO_MLINK = 78, // =>CYRF6936 PROTO_WFLY2 = 79, // =>A7105 PROTO_E016HV2 = 80, // =>CC2500 & NRF24L01 + PROTO_E010R5 = 81, // =>CYRF6936 PROTO_NANORF = 126, // =>NRF24L01 PROTO_TEST = 127, // =>CC2500 @@ -847,6 +848,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- MLINK 78 WFLY2 79 E016HV2 80 + E010R5 81 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 858b012..8fb6d3b 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -75,7 +75,7 @@ uint32_t blink=0,last_signal=0; // uint16_t counter; uint8_t channel; -#ifdef ESKY150V2_CC2500_INO +#if defined(ESKY150V2_CC2500_INO) || defined(E010R5_CYRF6936_INO) uint8_t packet[150]; #else uint8_t packet[50]; @@ -1360,6 +1360,13 @@ static void protocol_init() remote_callback = ReadMLINK; break; #endif + #if defined(E010R5_CYRF6936_INO) + case PROTO_E010R5: + PE2_on; //antenna RF4 + next_callback = initE010R5(); + remote_callback = ReadE010R5; + break; + #endif #if defined(DEVO_CYRF6936_INO) case PROTO_DEVO: #ifdef ENABLE_PPM diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index cf131c9..831f9f0 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -241,6 +241,7 @@ #undef DEVO_CYRF6936_INO #undef DSM_CYRF6936_INO #undef DSM_RX_CYRF6936_INO + #undef E010R5_CYRF6936_INO #undef J6PRO_CYRF6936_INO #undef MLINK_CYRF6936_INO #undef TRAXXAS_CYRF6936_INO @@ -310,6 +311,7 @@ #undef XK_NRF24L01_INO #undef YD717_NRF24L01_INO #undef ZSX_NRF24L01_INO + #undef E010R5_CYRF6936_INO // Use both CYRF and NRF code #endif #if not defined(STM32_BOARD) #undef SX1276_INSTALLED diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 5e37b89..c373d91 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -181,6 +181,7 @@ #define DEVO_CYRF6936_INO #define DSM_CYRF6936_INO #define DSM_RX_CYRF6936_INO +#define E010R5_CYRF6936_INO #define J6PRO_CYRF6936_INO #define TRAXXAS_CYRF6936_INO #define WFLY_CYRF6936_INO @@ -572,6 +573,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { DSMX_11 PROTO_DSM_RX NONE + PROTO_E010R5 + NONE PROTO_E016HV2 NONE PROTO_E01X diff --git a/Protocols_Details.md b/Protocols_Details.md index 68e8237..f550271 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| +[E010R5](Protocols_Details.md#E010R5---81)|81|E010r5||||||||CYRF6936/NRF24L01|unknown [E016HV2](Protocols_Details.md#E016HV2---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| @@ -832,6 +833,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 +## E010R5 - *81* +Models: E010 R5, JJRC H36 + +**Only 1 ID available** + +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- +A|E|T|R|FLIP|HEADLESS|RTH + ## J6Pro - *22* CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12