diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 8363a4c..2dd2b2e 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -43,4 +43,5 @@ 43,Traxxas 44,NCC1701 45,E01X,E012,E015 +46,V911S 63,Test diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 4c855a1..10bc929 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 10 +#define VERSION_PATCH_LEVEL 11 //****************** // Protocols @@ -72,6 +72,7 @@ enum PROTOCOLS PROTO_TRAXXAS = 43, // =>CYRF6936 PROTO_NCC1701 = 44, // =>NRF24L01 PROTO_E01X = 45, // =>NRF24L01 + PROTO_V911S = 46, // =>NRF24L01 PROTO_TEST = 63, // =>NRF24L01 }; @@ -369,12 +370,13 @@ enum MultiPacketTypes //******************** #if defined(STM32_BOARD) && defined (DEBUG_SERIAL) uint16_t debug_time=0; - #define debug(msg, ...) {char buf[64]; sprintf(buf, msg, ##__VA_ARGS__); Serial.write(buf);} - #define debugln(msg, ...) {char buf[64]; sprintf(buf, msg "\r\n", ##__VA_ARGS__); Serial.write(buf);} + #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; } #else #define debug(...) { } #define debugln(...) { } + #define debug_time(...) { } #undef DEBUG_SERIAL #endif @@ -592,6 +594,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- TRAXXAS 43 NCC1701 44 E01X 45 + V911S 46 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 a336ae0..1a34ab6 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -1206,6 +1206,12 @@ static void protocol_init() remote_callback = E01X_callback; break; #endif + #if defined(V911S_NRF24L01_INO) + case PROTO_V911S: + next_callback=initV911S(); + remote_callback = V911S_callback; + break; + #endif #if defined(TEST_NRF24L01_INO) case PROTO_TEST: next_callback=initTest(); diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino index 7e71858..22c64a0 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -457,16 +457,46 @@ void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack, uint16 pid=0; } -void XN297_ReadPayload(uint8_t* msg, uint8_t len) -{ - // TODO: if xn297_crc==1, check CRC before filling *msg - NRF24L01_ReadPayload(msg, len); +boolean XN297_ReadPayload(uint8_t* msg, uint8_t len) +{ //!!! Don't forget if using CRC to do a +2 on any of the used NRF24L01_11_RX_PW_Px !!! + uint8_t buf[32]; + if (xn297_crc) + NRF24L01_ReadPayload(buf, len+2); // Read payload + CRC + else + NRF24L01_ReadPayload(buf, len); + // Decode payload for(uint8_t i=0; i> 8) == buf[len] && (crc & 0xff) == buf[len+1]) + return true; // CRC OK + return false; // CRC NOK } uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len) diff --git a/Multiprotocol/V911S_nrf24l01.ino b/Multiprotocol/V911S_nrf24l01.ino new file mode 100644 index 0000000..9ca917b --- /dev/null +++ b/Multiprotocol/V911S_nrf24l01.ino @@ -0,0 +1,175 @@ +/* + 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 V911S + +#if defined(V911S_NRF24L01_INO) + +#include "iface_nrf24l01.h" + +//#define V911S_ORIGINAL_ID + +#define V911S_PACKET_PERIOD 5000 +#define V911S_BIND_PACKET_PERIOD 3300 +#define V911S_INITIAL_WAIT 500 +#define V911S_PACKET_SIZE 16 +#define V911S_RF_BIND_CHANNEL 35 +#define V911S_NUM_RF_CHANNELS 8 +#define V911S_BIND_COUNT 200 + +// flags going to packet[1] +#define V911S_FLAG_EXPERT 0x04 +// flags going to packet[2] +#define V911S_FLAG_CALIB 0x01 + +static void __attribute__((unused)) V911S_send_packet(uint8_t bind) +{ + if(bind) + { + packet[0] = 0x42; + packet[1] = 0x4E; + packet[2] = 0x44; + for(uint8_t i=0;i<5;i++) + packet[i+3] = rx_tx_addr[i]; + for(uint8_t i=0;i<8;i++) + packet[i+8] = hopping_frequency[i]; + } + else + { + uint8_t channel=hopping_frequency_no; + if(rf_ch_num&1) + { + if((hopping_frequency_no&1)==0) + channel+=8; + channel>>=1; + } + if(rf_ch_num&2) + channel=7-channel; + packet[ 0]=(rf_ch_num<<3)|channel; + packet[ 1]=V911S_FLAG_EXPERT; // short press on left button + packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button + memset(packet+3,0x00,14); + //packet[3..6]=trims TAER signed + uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF); + packet[ 7] = ch; + packet[ 8] = ch>>8; + ch=convert_channel_16b_limit(AILERON ,0,0x7FF); + packet[ 8]|= ch<<3; + packet[ 9] = ch>>5; + ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF); + packet[10] = ch; + packet[11] = ch>>8; + ch=convert_channel_16b_limit(RUDDER ,0,0x7FF); + packet[11]|= ch<<3; + packet[12] = ch>>5; + } + + // Power on, TX mode, 2byte CRC + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + if (!bind) + { + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[channel]); + hopping_frequency_no++; + hopping_frequency_no&=7; // 8 RF channels + } + // clear packet status bits and TX FIFO + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + XN297_WritePayload(packet, V911S_PACKET_SIZE); + + NRF24L01_SetPower(); // Set tx_power +} + +static void __attribute__((unused)) V911S_init() +{ + NRF24L01_Initialize(); + NRF24L01_SetTxRxMode(TX_EN); + XN297_SetTXAddr((uint8_t *)"\x4B\x4E\x42\x4E\x44", 5); // Bind address + NRF24L01_WriteReg(NRF24L01_05_RF_CH, V911S_RF_BIND_CHANNEL); // Bind channel + 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_250K); // 250Kbps + NRF24L01_SetPower(); +} + +static void __attribute__((unused)) V911S_initialize_txid() +{ + //channels + uint8_t offset=rx_tx_addr[3]%5; // 0-4 + for(uint8_t i=0;i