V911S protocol

Protocol number 46
No sub protocol
CH5: yaw calib
This commit is contained in:
Pascal Langer 2018-11-09 00:31:26 +01:00
parent 8bea5b125b
commit 903982afb7
7 changed files with 229 additions and 10 deletions

View File

@ -43,4 +43,5 @@
43,Traxxas
44,NCC1701
45,E01X,E012,E015
46,V911S
63,Test

View File

@ -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

View File

@ -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();

View File

@ -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<len; i++)
{
uint8_t b_in=buf[i];
if(xn297_scramble_enabled)
msg[i] ^= xn297_scramble[i+xn297_addr_len];
msg[i] = bit_reverse(msg[i]);
b_in ^= xn297_scramble[i+xn297_addr_len];
msg[i] = bit_reverse(b_in);
}
if (!xn297_crc)
return true; // No CRC so OK by default...
// Calculate CRC
uint16_t crc = 0xb5d2;
//process address
for (uint8_t i = 0; i < xn297_addr_len; ++i)
{
uint8_t b_in=xn297_tx_addr[xn297_addr_len-i-1];
if(xn297_scramble_enabled)
b_in ^= xn297_scramble[i];
crc = crc16_update(crc, b_in, 8);
}
//process payload
for (uint8_t i = 0; i < len; ++i)
crc = crc16_update(crc, buf[i], 8);
//xorout
if(xn297_scramble_enabled)
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
else
crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
//test
if( (crc >> 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)

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
// 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<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency[i]=0x10+i*5+offset;
if(!offset) hopping_frequency[0]++;
// channels order
rf_ch_num=random(0xfefefefe)&0x03; // 0-3
}
uint16_t V911S_callback()
{
if(IS_BIND_DONE)
V911S_send_packet(0);
else
{
if (bind_counter == 0)
{
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 5);
packet_period=V911S_PACKET_PERIOD;
}
else
{
V911S_send_packet(1);
bind_counter--;
if(bind_counter==100) // same as original TX...
packet_period=V911S_BIND_PACKET_PERIOD*3;
}
}
return packet_period;
}
uint16_t initV911S(void)
{
V911S_initialize_txid();
#ifdef V911S_ORIGINAL_ID
rx_tx_addr[0]=0xA5;
rx_tx_addr[1]=0xFF;
rx_tx_addr[2]=0x70;
rx_tx_addr[3]=0x8D;
rx_tx_addr[4]=0x76;
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency[i]=0x10+i*5;
hopping_frequency[0]++;
rf_ch_num=0;
#endif
V911S_init();
if(IS_BIND_IN_PROGRESS)
{
bind_counter = V911S_BIND_COUNT;
packet_period= V911S_BIND_PACKET_PERIOD;
}
else
{
XN297_SetTXAddr(rx_tx_addr, 5);
packet_period= V911S_PACKET_PERIOD;
}
hopping_frequency_no=0;
return V911S_INITIAL_WAIT;
}
#endif

View File

@ -184,6 +184,7 @@
#undef BUGSMINI_NRF24L01_INO
#undef NCC1701_NRF24L01_INO
#undef E01X_NRF24L01_INO
#undef V911S_NRF24L01_INO
#endif
//Make sure telemetry is selected correctly

View File

@ -178,6 +178,7 @@
#define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO //Include Q2X2 protocol
#define DM002_NRF24L01_INO
#define E01X_NRF24L01_INO
#define ESKY_NRF24L01_INO
#define ESKY150_NRF24L01_INO
#define FQ777_NRF24L01_INO
@ -195,8 +196,8 @@
#define SLT_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define V911S_NRF24L01_INO
#define YD717_NRF24L01_INO
#define E01X_NRF24L01_INO
/**************************/
/*** FAILSAFE SETTINGS ***/
@ -581,6 +582,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_E01X
E012
E015
PROTO_V911S
NONE
*/
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...