diff --git a/Lua_scripts/MultiChan.txt b/Lua_scripts/MultiChan.txt index fe35626..ac99315 100644 --- a/Lua_scripts/MultiChan.txt +++ b/Lua_scripts/MultiChan.txt @@ -232,3 +232,4 @@ 102,1,JIABAILE,Gyro,0,Speed,Light,Flash,ST_Tr 103,0,H36,Std,1,Flip,HLess,RTH 104,0,KAMTOM,Std,0,ST_Tr,TH_Tr,TH_DR +105,0,Shenqi2,Std,1 diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 815456c..1e82678 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -99,4 +99,5 @@ 100,YuXiang 102,JIABAILE,STD,GYRO 103,H36 -104,KAMTOM \ No newline at end of file +104,KAMTOM +105,Shenqi2 \ No newline at end of file diff --git a/Multiprotocol/Multi_Protos.ino b/Multiprotocol/Multi_Protos.ino index 371a9e6..62af875 100644 --- a/Multiprotocol/Multi_Protos.ino +++ b/Multiprotocol/Multi_Protos.ino @@ -36,6 +36,7 @@ const char STR_MT99XX[] ="MT99XX"; const char STR_MT99XX2[] ="MT99XX2"; const char STR_MJXQ[] ="MJXq"; const char STR_SHENQI[] ="Shenqi"; +const char STR_SHENQI2[] ="Shenqi2"; const char STR_FY326[] ="FY326"; const char STR_FUTABA[] ="Futaba"; const char STR_J6PRO[] ="J6 Pro"; @@ -476,6 +477,9 @@ const mm_protocol_definition multi_protocols[] = { #if defined(SHENQI_NRF24L01_INO) {PROTO_SHENQI, STR_SHENQI, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI_init, SHENQI_callback }, #endif + #if defined(SHENQI2_NRF24L01_INO) + {PROTO_SHENQI2, STR_SHENQI2, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI2_init, SHENQI2_callback }, + #endif #if defined(SKYARTEC_CC2500_INO) {PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback }, #endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 00bad2b..95b5cd0 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 4 -#define VERSION_PATCH_LEVEL 34 +#define VERSION_PATCH_LEVEL 35 #define MODE_SERIAL 0 @@ -132,6 +132,7 @@ enum PROTOCOLS PROTO_JIABAILE = 102, // =>NRF24L01 PROTO_H36 = 103, // =>NRF24L01 PROTO_KAMTOM = 104, // =>NRF24L01 + PROTO_SHENQI2 = 105, // =>NRF24L01 PROTO_NANORF = 126, // =>NRF24L01 PROTO_TEST = 127, // =>CC2500 diff --git a/Multiprotocol/SHENQI2_nrf24l01.ino b/Multiprotocol/SHENQI2_nrf24l01.ino new file mode 100644 index 0000000..9bf7b16 --- /dev/null +++ b/Multiprotocol/SHENQI2_nrf24l01.ino @@ -0,0 +1,232 @@ +/* + 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(SHENQI2_NRF24L01_INO) + +#include "iface_xn297.h" + +//#define FORCE_SHENQI2_ORIGINAL_ID + +#define SHENQI2_PAYLOAD_SIZE 8 +#define SHENQI2_RF_NUM_CHANNELS 16 +#define SHENQI2_BIND_COUNT 2000 +#define SHENQI2_WRITE_TIME 650 +#define SHENQI2_BIND_CHANNEL 44 +#define SHENQI2_PACKET_PERIOD 8210 + + +enum { + SHENQI2_BIND = 0, + SHENQI2_BIND_RX, + SHENQI2_DATA, +}; + +static void __attribute__((unused)) SHENQI2_send_packet() +{ + if(bind_counter) + { + bind_counter--; + if(!bind_counter) + BIND_DONE; + } + + memset(packet, 0x00, SHENQI2_PAYLOAD_SIZE); + + packet_count &= 0x0F; + packet[0] = packet_count; + + memcpy(&packet[1],rx_tx_addr,5); + + if(IS_BIND_DONE) + {//Normal + uint8_t val = convert_channel_8b(CH2); + if(val < 0x70) + val = 0x30; + else if(val < 0x80) + val = 0x00; + else + { + val &= 0x7F; + val >>= 2; + } + if(Channel_data[CH1] > 1024+50) + val |= 0x40; + else if(Channel_data[CH1] < 1024-50) + val |= 0x80; + packet[6] = val; + //packet[7] = 0x00; // ?? + } + else + packet[0] |= 0x30; + + // Send + XN297_SetPower(); + XN297_SetTxRxMode(TX_EN); + XN297_WriteEnhancedPayload(packet, SHENQI2_PAYLOAD_SIZE, false); + #ifdef DEBUG_SERIAL + for(uint8_t i=0; i < SHENQI2_PAYLOAD_SIZE; i++) + debug("%02X ", packet[i]); + debugln(); + #endif +} + +static void __attribute__((unused)) SHENQI2_initialize_txid() +{ + #ifdef FORCE_SHENQI2_ORIGINAL_ID + //TXID + rx_tx_addr[0] = 0x51; + rx_tx_addr[1] = 0x70; + rx_tx_addr[2] = 0x02; + //RXID + rx_tx_addr[3] = 0x46; + rx_tx_addr[4] = 0xBE; + #endif + rx_tx_addr[3] = 0x00; + rx_tx_addr[4] = 0x00; + //Freq + memcpy(hopping_frequency,(uint8_t*)"\x05\x09\x0E\x0F\x17\x1C\x21\x27\x2A\x2C\x33\x39\x3D\x42\x48\x4C",16); +} + +static void __attribute__((unused)) SHENQI2_RF_init() +{ + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); + //Address + XN297_SetTXAddr((uint8_t*)"\x74\xD1\x3A\xF5\x6C", 5); + XN297_SetRXAddr((uint8_t*)"\x74\xD1\x3A\xF5\x6C", SHENQI2_PAYLOAD_SIZE); + XN297_RFChannel(SHENQI2_BIND_CHANNEL); +} + +uint16_t SHENQI2_callback() +{ + static bool rx=false; + + switch(phase) + { + case SHENQI2_BIND: + rx = XN297_IsRX(); + XN297_SetTxRxMode(TXRX_OFF); + SHENQI2_send_packet(); + packet_count++; + if(rx) + { + uint8_t val=XN297_ReadEnhancedPayload(packet_in, SHENQI2_PAYLOAD_SIZE); + if(val == SHENQI2_PAYLOAD_SIZE) + { + if(memcmp(rx_tx_addr, packet_in, 3) == 0) + {//Good packet with our TXID + BIND_DONE; + rx_tx_addr[3] = packet_in[3]; + rx_tx_addr[4] = packet_in[4]; + packet_count = 0; + phase = SHENQI2_DATA; + } + #ifdef DEBUG_SERIAL + for(uint8_t i=0; i < SHENQI2_PAYLOAD_SIZE; i++) + debug(" %02X", packet_in[i]); + debugln(); + #endif + } + } + phase++; + return SHENQI2_WRITE_TIME; + case SHENQI2_BIND_RX: + XN297_SetTxRxMode(TXRX_OFF); + XN297_SetTxRxMode(RX_EN); + phase = SHENQI2_BIND; + return SHENQI2_PACKET_PERIOD - SHENQI2_WRITE_TIME; + default: //SHENQI2_DATA + //Since I don't know the order of the channels, I'm hopping on all the channels quickly + //Refresh rate from the motorcycle perspective is 32ms instead of 8ms... + XN297_Hopping(hopping_frequency_no); + hopping_frequency_no++; + hopping_frequency_no &= 0x0F; + SHENQI2_send_packet(); + if(hopping_frequency_no%4 == 0) + packet_count++; + return SHENQI2_PACKET_PERIOD/4; + } + return 0; +} + +void SHENQI2_init() +{ + BIND_IN_PROGRESS; + SHENQI2_initialize_txid(); + SHENQI2_RF_init(); + + bind_counter = SHENQI2_BIND_COUNT; + phase = SHENQI2_BIND; + hopping_frequency_no = 0; +} + +#endif +/* +XN297 1Mb Enhanced,Acked,Scrambled + +Bind +--- +RX on channel: 44, Time: 2890us P: 34 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1780us P: 34 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1773us P: 34 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1772us P: 34 51 70 02 00 00 00 00 +RX on channel: 44, Time: 2889us P: 35 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1769us P: 35 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1774us P: 35 51 70 02 00 00 00 00 +RX on channel: 44, Time: 1771us P: 35 51 70 02 00 00 00 00 +RX on channel: 44, Time: 2894us P: 36 51 70 02 00 00 00 00 + +A= 74 D1 3A F5 6C +RF:44 +Timing: 1772µs between the same 4 packets, 2892µs to the next packet, 8208µs between 2 packets +Request ack, if no ack repeat the packet 4 times + +P[0] = counter 00..0F | 30 bind +P[1] = TXID[0] +P[2] = TXID[1] +P[3] = TXID[2] +P[4] = RXID[0] +P[5] = RXID[1] +P[6] = TH 00..1F, Break 30, 40 ST_right, 80 ST_left +P[7] = 00? + +Answer from motorcycle: +P: 51 70 02 46 BE 00 00 00 +P[0] = TXID[0] +P[1] = TXID[1] +P[2] = TXID[2] +P[3] = RXID[0] +P[4] = RXID[1] +P[5] = 00 +P[6] = 00 +P[7] = 00 + +Normal packets +--- +A= 74 D1 3A F5 6C +RF:5,9,14,15,23,28,33,39,42,44,51,57,61,66,72,76 +RF:\x05\x09\x0E\x0F\x17\x1C\x21\x27\x2A\x2C\x33\x39\x3D\x42\x48\x4C +- order of the channels is unknown and vary over time +- send 16 times on each channel and switch (counter 00..0F) +Timing:1772µs between the same 4 packets, 2892µs to the next packet, 8208µs between 2 packets +Timing:8208 between packets if acked +P: 00 51 70 02 46 BE 00 00 +P[0] = counter 00..0F +P[1] = TXID[0] +P[2] = TXID[1] +P[3] = TXID[2] +P[4] = RXID[0] +P[5] = RXID[1] +P[6] = TH 00..1F, Break 30, 40 ST_right, 80 ST_left +P[7] = 00? +*/ \ No newline at end of file diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index ad0aed1..1843629 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -337,6 +337,7 @@ #undef REALACC_NRF24L01_INO #undef SGF22_NRF24L01_INO #undef SHENQI_NRF24L01_INO + #undef SHENQI2_NRF24L01_INO #undef SYMAX_NRF24L01_INO #undef V2X2_NRF24L01_INO #undef V761_NRF24L01_INO @@ -392,6 +393,7 @@ #undef KYOSHO3_CYRF6936_INO #undef MOULDKG_NRF24L01_INO #undef SHENQI_NRF24L01_INO + #undef SHENQI2_NRF24L01_INO #undef JIABAILE_NRF24L01_INO #undef UDIRC_CCNRF_INO #undef KAMTOM_NRF24L01_INO diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index c58c92a..1fb28ed 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -257,6 +257,7 @@ #define REALACC_NRF24L01_INO #define SGF22_NRF24L01_INO #define SHENQI_NRF24L01_INO +#define SHENQI2_NRF24L01_INO #define SYMAX_NRF24L01_INO #define V2X2_NRF24L01_INO #define V761_NRF24L01_INO @@ -835,6 +836,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { J20 PROTO_SHENQI NONE + PROTO_SHENQI2 + NONE PROTO_SKYARTEC NONE PROTO_SLT diff --git a/Protocols_Details.md b/Protocols_Details.md index 3f9879b..d4da285 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -144,6 +144,7 @@ CFlie|38|CFlie||||||||NRF24L01| [Scorpio](Protocols_Details.md#Scorpio---94)|94|||||||||CYRF6936| [SGF22](Protocols_Details.md#SGF22---97)|97|F22|F22S|J20||||||NRF24L01|XN297 [Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900 +[Shenqi2](Protocols_Details.md#Shenqi2---105)|105|Shenqi2||||||||NRF24L01|XN297 [Skyartec](Protocols_Details.md#Skyartec---68)|68|||||||||CC2500|CC2500 [SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100|V1_4CH|RF_SIM||NRF24L01|CC2500 [SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01| @@ -2161,6 +2162,15 @@ CH1|CH2|CH3|CH4 Throttle +100%=full forward,0%=stop,-100%=full backward. +## Shenqi2 - *105* +Autobind protocol + +Model: Shenqiwei 1/20 Mini Motorcycle + +CH1|CH2 +---|--- +ST|TH + ## Symax - *10* Autobind protocol