mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 19:58:13 +00:00
Xerall protocol
This commit is contained in:
parent
a7b68dc2aa
commit
246e808cb4
@ -196,5 +196,6 @@
|
||||
85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH
|
||||
87,0,IKEA
|
||||
89,0,LOSI
|
||||
90,0,MouldKg,Analog
|
||||
90,1,MouldKg,Digit,E,F
|
||||
90,0,MouldKg,Analog,0
|
||||
90,1,MouldKg,Digit,0
|
||||
91,0,Xerall,Tank,0,FlGr,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA
|
||||
|
@ -87,4 +87,4 @@
|
||||
88,WILLIFM
|
||||
89,Losi
|
||||
90,MouldKg,Analog,Digit
|
||||
91,XERALL
|
||||
91,Xerall
|
@ -102,7 +102,7 @@ const char STR_IKEAANSLUTA[]="Ansluta";
|
||||
const char STR_CONFIG[] ="Config";
|
||||
const char STR_LOSI[] ="Losi";
|
||||
const char STR_MOULDKG[] ="MouldKg";
|
||||
const char STR_XERALL[] ="XERALL";
|
||||
const char STR_XERALL[] ="Xerall";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 2
|
||||
#define VERSION_PATCH_LEVEL 94
|
||||
#define VERSION_PATCH_LEVEL 95
|
||||
|
||||
#define MODE_SERIAL 0
|
||||
|
||||
|
283
Multiprotocol/XERALL_nrf24l01.ino
Normal file
283
Multiprotocol/XERALL_nrf24l01.ino
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
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 XERALL
|
||||
|
||||
#if defined(XERALL_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define XERALL_ORIGINAL_ID
|
||||
|
||||
#define XERALL_PACKET_PERIOD 2500 //2046
|
||||
#define XERALL_PACKET_SIZE 10
|
||||
#define XERALL_NUM_RF_CHANNELS 4
|
||||
#define XERALL_BIND_COUNT 15000 //about 30sec
|
||||
|
||||
// flags going to packet[6]
|
||||
#define XERALL_FLAG_VIDEO 0x80
|
||||
#define XERALL_FLAG_PHOTO 0x40
|
||||
// flags going to packet[7]
|
||||
#define XERALL_FLAG_RATE 0x80
|
||||
#define XERALL_FLAG_FLIGHT_GROUND 0x20
|
||||
#define XERALL_FLAG_HEADING_HOLD 0x04
|
||||
#define XERALL_FLAG_ONE_BUTTON 0x02
|
||||
|
||||
enum {
|
||||
XERALL_DATA,
|
||||
XERALL_RX,
|
||||
XERALL_CHECK,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) XERALL_send_packet()
|
||||
{
|
||||
if(bind_phase)
|
||||
bind_phase--;
|
||||
else
|
||||
{ // Hopping frequency
|
||||
if(packet_sent==0)
|
||||
{
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= (XERALL_NUM_RF_CHANNELS-1);
|
||||
}
|
||||
packet_sent++;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if(packet_sent > 24)
|
||||
packet_sent=0; // Hopp after 25 packets
|
||||
}
|
||||
else
|
||||
{
|
||||
if(packet_sent > 18)
|
||||
packet_sent = 0; // Hopp after 19 packets
|
||||
}
|
||||
|
||||
// Packet
|
||||
if(IS_BIND_IN_PROGRESS && (bind_counter&0x10)) // Alternate bind and normal packets
|
||||
{ // Bind packet: 01 56 06 23 00 13 20 40 02 00 and 01 F9 58 31 00 13 20 40 05 00
|
||||
if(packet[0] != 0x01)
|
||||
{
|
||||
XN297_SetTXAddr((uint8_t *)"\x01\x01\x01\x01\x09", 5); // Bind address
|
||||
XN297_SetRXAddr((uint8_t *)"\x01\x01\x01\x01\x09", XERALL_PACKET_SIZE);
|
||||
}
|
||||
packet[0] = 0x01;
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
packet[i+1] = rx_tx_addr[i];
|
||||
packet[9] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(packet[0] != 0x08)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
XN297_SetRXAddr(rx_tx_addr, XERALL_PACKET_SIZE);
|
||||
}
|
||||
// Normal packet: 08 32 7C 1C 20 20 20 40 0A 00
|
||||
packet[0] = 0x08;
|
||||
//Throttle
|
||||
packet[1] = convert_channel_16b_limit(THROTTLE ,0,0x32)<<1; //00..64 but only even values
|
||||
//Rudder
|
||||
packet[2] = (0xFF-convert_channel_8b(RUDDER))&0xF8; //F8..00 -> 5 bits
|
||||
//Elevator
|
||||
uint8_t ch = convert_channel_8b(ELEVATOR)>>3;
|
||||
packet[2] |= ch>>2; //00..07 -> 3 bits high
|
||||
packet[3] = ch<<6; //00,40,80,C0 -> 2 bits low
|
||||
//Aileron
|
||||
packet[3] |= ((0xFF-convert_channel_8b(AILERON))>>3)<<1; //5 bits
|
||||
|
||||
//Trim Rudder 0x00..0x20..0x3F
|
||||
packet[4] = convert_channel_8b(CH11)>>2;
|
||||
//Trim Elevator 0x00..0x20..0x3F
|
||||
packet[5] = convert_channel_8b(CH12)>>2;
|
||||
}
|
||||
}
|
||||
|
||||
// Flags + Trim Aileron
|
||||
//packet[6]
|
||||
// 0x20 -> 0x60 short press photo/video => |0x40 -> momentary
|
||||
// 0x20 -> 0xA0 long press photo/video => |0x80 -> toggle
|
||||
// 0xA0 -> 0xE0 short press photo/video => |0x40 -> momentary
|
||||
// 0x20 -> 0x00..0x20..0x3F Trim Aileron
|
||||
packet[6] = (convert_channel_8b(CH13)>>2)
|
||||
| GET_FLAG(CH9_SW,XERALL_FLAG_PHOTO)
|
||||
| GET_FLAG(CH10_SW,XERALL_FLAG_VIDEO);
|
||||
|
||||
// Flags
|
||||
// 0x40 -> 0x44 Heading hold mode => |0x04 -> toggle
|
||||
// 0x40 -> 0xC0 High/low speed => |0x80 -> toggle
|
||||
// 0x40 -> 0x42 One button takeoff/landing/emergency => |0x02 -> toggle
|
||||
// 0x40 -> 0x60 Flight/Ground => |0x20 -> toggle
|
||||
packet[7] = 0x40
|
||||
| GET_FLAG(CH5_SW,XERALL_FLAG_FLIGHT_GROUND)
|
||||
| GET_FLAG(CH6_SW,XERALL_FLAG_ONE_BUTTON)
|
||||
| GET_FLAG(CH7_SW,XERALL_FLAG_RATE)
|
||||
| GET_FLAG(CH8_SW,XERALL_FLAG_HEADING_HOLD);
|
||||
|
||||
// CRC
|
||||
uint8_t sum = 0;
|
||||
for(uint8_t i=1;i<8;i++)
|
||||
sum += packet[i];
|
||||
packet[8] = sum;
|
||||
|
||||
//0x00 -> 0x1A on first telemetry packet received
|
||||
//packet[9] = 0x00;
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WriteEnhancedPayload(packet, XERALL_PACKET_SIZE, 0);
|
||||
#if 0
|
||||
debug("H:%d,P:",hopping_frequency_no);
|
||||
for(uint8_t i=0; i<XERALL_PACKET_SIZE; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XERALL_RF_init()
|
||||
{
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XERALL_initialize_txid()
|
||||
{
|
||||
rx_tx_addr[0] = rx_tx_addr[3];
|
||||
#ifdef XERALL_ORIGINAL_ID
|
||||
// Pascal
|
||||
if(RX_num)
|
||||
{
|
||||
rx_tx_addr[0]=0x56;
|
||||
rx_tx_addr[1]=0x06;
|
||||
rx_tx_addr[2]=0x23;
|
||||
rx_tx_addr[3]=0x00;
|
||||
rx_tx_addr[4]=0x13;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alfons
|
||||
rx_tx_addr[0]=0xF9;
|
||||
rx_tx_addr[1]=0x58;
|
||||
rx_tx_addr[2]=0x31;
|
||||
rx_tx_addr[3]=0x00;
|
||||
rx_tx_addr[4]=0x13;
|
||||
}
|
||||
#endif
|
||||
rx_tx_addr[3] = 0x00;
|
||||
rx_tx_addr[4] = 0x13;
|
||||
hopping_frequency[0] = 56; // 0x38
|
||||
hopping_frequency[1] = 46; // 0x2E
|
||||
hopping_frequency[2] = 61; // 0x3D
|
||||
hopping_frequency[3] = 51; // 0x33
|
||||
}
|
||||
|
||||
#define XERALL_WRITE_WAIT 600
|
||||
#define XERALL_CHECK_WAIT 300
|
||||
uint16_t XERALL_callback()
|
||||
{
|
||||
static uint8_t wait = 0;
|
||||
switch(phase)
|
||||
{
|
||||
case XERALL_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(XERALL_PACKET_PERIOD);
|
||||
#endif
|
||||
if (bind_counter == 0)
|
||||
BIND_DONE;
|
||||
else
|
||||
bind_counter--;
|
||||
XERALL_send_packet();
|
||||
phase++;
|
||||
return XERALL_WRITE_WAIT;
|
||||
case XERALL_RX:
|
||||
// switch to RX mode
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase++;
|
||||
return XERALL_PACKET_PERIOD-XERALL_WRITE_WAIT-XERALL_CHECK_WAIT;
|
||||
case XERALL_CHECK:
|
||||
if( XN297_IsRX() )
|
||||
{ // RX fifo data ready
|
||||
uint8_t len = XN297_ReadEnhancedPayload(packet_in, XERALL_PACKET_SIZE);
|
||||
if(len != 255) // CRC OK
|
||||
{
|
||||
#if 0
|
||||
debug("RX(%d):",len);
|
||||
for(uint8_t i=0; i<len; i++)
|
||||
debug("%02X ", packet_in[i]);
|
||||
debugln();
|
||||
#endif
|
||||
if(len == XERALL_PACKET_SIZE && packet_in[0] == 0x11)
|
||||
{ // Request for ack packet
|
||||
// Ack the telem packet
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WriteEnhancedPayload(packet, 0, 0);
|
||||
|
||||
packet[9] = packet_in[9];
|
||||
if(packet[0] == 0x01) // Last packet sent was a bind packet
|
||||
{// Build bind response
|
||||
packet[0] = 0x02;
|
||||
for(uint8_t i=1; i<5; i++)
|
||||
packet[i] = packet_in[i]; // Tank ID???
|
||||
bind_phase = 14;
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
}
|
||||
wait = 0;
|
||||
phase = XERALL_DATA; // Resume data
|
||||
break;
|
||||
}
|
||||
if(len == XERALL_PACKET_SIZE && packet_in[0] == 0x12)
|
||||
{
|
||||
BIND_DONE;
|
||||
bind_phase = 0;
|
||||
wait = 0;
|
||||
phase = XERALL_DATA; // Resume data
|
||||
break;
|
||||
}
|
||||
if(len == 0)
|
||||
wait = 5; // The quad wants to talk let's pause sending data...
|
||||
}
|
||||
// switch to RX mode
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
}
|
||||
if(wait)
|
||||
{
|
||||
wait--;
|
||||
break;
|
||||
}
|
||||
phase = XERALL_DATA;
|
||||
return XERALL_CHECK_WAIT;
|
||||
}
|
||||
return XERALL_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
void XERALL_init(void)
|
||||
{
|
||||
XERALL_initialize_txid();
|
||||
|
||||
XERALL_RF_init();
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
bind_counter = XERALL_BIND_COUNT;
|
||||
hopping_frequency_no=0;
|
||||
packet_sent = 0;
|
||||
bind_phase = 0;
|
||||
memset(packet, 0, XERALL_PACKET_SIZE);
|
||||
phase = XERALL_DATA;
|
||||
}
|
||||
|
||||
#endif
|
@ -449,7 +449,7 @@ static uint8_t __attribute__((unused)) XN297_ReadEnhancedPayload(uint8_t* msg, u
|
||||
pcf_size = pcf_size >> 1;
|
||||
if(pcf_size>32)
|
||||
return 255; // Error
|
||||
for(int i=0; i< pcf_size; i++)
|
||||
for(uint8_t i=0; i< pcf_size; i++)
|
||||
{
|
||||
msg[i] = bit_reverse((buffer[i+1] << 2) | (buffer[i+2] >> 6));
|
||||
if(xn297_scramble_enabled)
|
||||
|
@ -248,6 +248,7 @@
|
||||
#define TIGER_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define V761_NRF24L01_INO
|
||||
#define XERALL_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
#define ZSX_NRF24L01_INO
|
||||
|
||||
|
@ -144,6 +144,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[WFLY](Protocols_Details.md#WFLY---40)|40|WFR0x||||||||CYRF6936|
|
||||
[WFLY2](Protocols_Details.md#WFLY2---79)|79|RF20x||||||||A7105|
|
||||
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
|
||||
[XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297
|
||||
[XK](Protocols_Details.md#XK---62)|62|X450|X420|||||||NRF24L01|XN297
|
||||
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
|
||||
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
|
||||
@ -1918,6 +1919,13 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|GYRO|CALIB|FLIP|RTN_ACT|RTN
|
||||
|
||||
## XERALL - *91*
|
||||
Model: Xerall TankCopter
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
||||
---|---|---|---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|Flight/Ground|Takeoff/Land/Emerg|RATE|HEADLESS|Photo|Video|TrimR|TrimE|TrimA
|
||||
|
||||
## YD717 - *8*
|
||||
Autobind protocol
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user