mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 22:58:10 +00:00
Added Shenqi protocol and LT8910 emulation layer
This commit is contained in:
parent
795df2937e
commit
05fb8bc742
@ -146,7 +146,7 @@ void setup()
|
|||||||
// after this mode_select will be one of {0000, 0001, ..., 1111}
|
// after this mode_select will be one of {0000, 0001, ..., 1111}
|
||||||
mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0
|
mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0
|
||||||
//**********************************
|
//**********************************
|
||||||
//mode_select=14; // here to test PPM
|
//mode_select=1; // here to test PPM
|
||||||
//**********************************
|
//**********************************
|
||||||
|
|
||||||
// Update LED
|
// Update LED
|
||||||
@ -431,6 +431,12 @@ static void protocol_init()
|
|||||||
next_callback=initMJXQ();
|
next_callback=initMJXQ();
|
||||||
remote_callback = MJXQ_callback;
|
remote_callback = MJXQ_callback;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(SHENQI_NRF24L01_INO)
|
||||||
|
case MODE_SHENQI:
|
||||||
|
next_callback=initSHENQI();
|
||||||
|
remote_callback = SHENQI_callback;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +519,7 @@ static void module_reset()
|
|||||||
case MODE_DEVO:
|
case MODE_DEVO:
|
||||||
CYRF_Reset();
|
CYRF_Reset();
|
||||||
break;
|
break;
|
||||||
default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY, MODE_MT99XX, MODE_MJXQ
|
default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY, MODE_MT99XX, MODE_MJXQ, MODE_SHENQI
|
||||||
NRF24L01_Reset();
|
NRF24L01_Reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -409,3 +409,196 @@ void XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// End of XN297 emulation
|
// End of XN297 emulation
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// LT8910 emulation layer
|
||||||
|
uint8_t LT8910_buffer[64];
|
||||||
|
uint8_t LT8910_buffer_start;
|
||||||
|
uint16_t LT8910_buffer_overhead_bits;
|
||||||
|
uint8_t LT8910_addr[8];
|
||||||
|
uint8_t LT8910_addr_size;
|
||||||
|
uint8_t LT8910_Preamble_Len;
|
||||||
|
uint8_t LT8910_Tailer_Len;
|
||||||
|
uint8_t LT8910_CRC_Initial_Data;
|
||||||
|
uint8_t LT8910_Flags;
|
||||||
|
#define LT8910_CRC_ON 6
|
||||||
|
#define LT8910_SCRAMBLE_ON 5
|
||||||
|
#define LT8910_PACKET_LENGTH_EN 4
|
||||||
|
#define LT8910_DATA_PACKET_TYPE_1 3
|
||||||
|
#define LT8910_DATA_PACKET_TYPE_0 2
|
||||||
|
#define LT8910_FEC_TYPE_1 1
|
||||||
|
#define LT8910_FEC_TYPE_0 0
|
||||||
|
|
||||||
|
void LT8910_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uint8_t crc_init)
|
||||||
|
{
|
||||||
|
//Preamble 1 to 8 bytes
|
||||||
|
LT8910_Preamble_Len=preamble_len;
|
||||||
|
//Trailer 4 to 18 bits
|
||||||
|
LT8910_Tailer_Len=trailer_len;
|
||||||
|
//Flags
|
||||||
|
// CRC_ON: 1 on, 0 off
|
||||||
|
// SCRAMBLE_ON: 1 on, 0 off
|
||||||
|
// PACKET_LENGTH_EN: 1 1st byte of payload is payload size
|
||||||
|
// DATA_PACKET_TYPE: 00 NRZ, 01 Manchester, 10 8bit/10bit line code, 11 interleave data type
|
||||||
|
// FEC_TYPE: 00 No FEC, 01 FEC13, 10 FEC23, 11 reserved
|
||||||
|
LT8910_Flags=flags;
|
||||||
|
//CRC init constant
|
||||||
|
LT8910_CRC_Initial_Data=crc_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LT8910_SetChannel(uint8_t channel)
|
||||||
|
{
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, channel +2); //NRF24L01 is 2400+channel but LT8900 is 2402+channel
|
||||||
|
}
|
||||||
|
|
||||||
|
void LT8910_SetTxRxMode(enum TXRX_State mode)
|
||||||
|
{
|
||||||
|
if(mode == TX_EN)
|
||||||
|
{
|
||||||
|
//Switch to TX
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
//Disable CRC
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (mode == RX_EN)
|
||||||
|
{
|
||||||
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 32);
|
||||||
|
//Switch to RX
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
|
// Disable CRC
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP) | (1 << NRF24L01_00_PRIM_RX) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LT8910_BuildOverhead()
|
||||||
|
{
|
||||||
|
uint8_t pos;
|
||||||
|
|
||||||
|
//Build overhead
|
||||||
|
//preamble
|
||||||
|
memset(LT8910_buffer,LT8910_addr[0]&0x01?0xAA:0x55,LT8910_Preamble_Len-1);
|
||||||
|
pos=LT8910_Preamble_Len-1;
|
||||||
|
//address
|
||||||
|
for(uint8_t i=0;i<LT8910_addr_size;i++)
|
||||||
|
{
|
||||||
|
LT8910_buffer[pos]=bit_reverse(LT8910_addr[i]);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
//trailer
|
||||||
|
memset(LT8910_buffer+pos,(LT8910_buffer[pos-1]&0x01)==0?0xAA:0x55,3);
|
||||||
|
LT8910_buffer_overhead_bits=pos*8+LT8910_Tailer_Len;
|
||||||
|
//nrf address length max is 5
|
||||||
|
pos+=LT8910_Tailer_Len/8;
|
||||||
|
LT8910_buffer_start=pos>5?5:pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LT8910_SetAddress(uint8_t *address,uint8_t addr_size)
|
||||||
|
{
|
||||||
|
uint8_t addr[5];
|
||||||
|
|
||||||
|
//Address size (SyncWord) 2 to 8 bytes, 16/32/48/64 bits
|
||||||
|
LT8910_addr_size=addr_size;
|
||||||
|
memcpy(LT8910_addr,address,LT8910_addr_size);
|
||||||
|
|
||||||
|
//Build overhead
|
||||||
|
LT8910_BuildOverhead();
|
||||||
|
|
||||||
|
//Set NRF RX&TX address based on overhead content
|
||||||
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, LT8910_buffer_start-2);
|
||||||
|
for(uint8_t i=0;i<LT8910_buffer_start;i++) // reverse bytes order
|
||||||
|
addr[i]=LT8910_buffer[LT8910_buffer_start-i-1];
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, addr,LT8910_buffer_start);
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr,LT8910_buffer_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LT8910_ReadPayload(uint8_t* msg, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t i,pos=0,shift,end,buffer[32];
|
||||||
|
unsigned int crc=LT8910_CRC_Initial_Data,a;
|
||||||
|
pos=LT8910_buffer_overhead_bits/8-LT8910_buffer_start;
|
||||||
|
end=pos+len+(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN)?1:0)+(LT8910_Flags&_BV(LT8910_CRC_ON)?2:0);
|
||||||
|
//Read payload
|
||||||
|
NRF24L01_ReadPayload(buffer,end+1);
|
||||||
|
//Check address + trail
|
||||||
|
for(i=0;i<pos;i++)
|
||||||
|
if(LT8910_buffer[LT8910_buffer_start+i]!=buffer[i])
|
||||||
|
return 0; // wrong address...
|
||||||
|
//Shift buffer to remove trail bits
|
||||||
|
shift=LT8910_buffer_overhead_bits&0x7;
|
||||||
|
for(i=pos;i<end;i++)
|
||||||
|
{
|
||||||
|
a=(buffer[i]<<8)+buffer[i+1];
|
||||||
|
a<<=shift;
|
||||||
|
buffer[i]=(a>>8)&0xFF;
|
||||||
|
}
|
||||||
|
//Check len
|
||||||
|
if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN))
|
||||||
|
{
|
||||||
|
crc=crc16_update(crc,buffer[pos]);
|
||||||
|
if(bit_reverse(len)!=buffer[pos++])
|
||||||
|
return 0; // wrong len...
|
||||||
|
}
|
||||||
|
//Decode message
|
||||||
|
for(i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
crc=crc16_update(crc,buffer[pos]);
|
||||||
|
msg[i]=bit_reverse(buffer[pos++]);
|
||||||
|
}
|
||||||
|
//Check CRC
|
||||||
|
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
||||||
|
{
|
||||||
|
if(buffer[pos++]!=((crc>>8)&0xFF)) return 0; // wrong CRC...
|
||||||
|
if(buffer[pos]!=(crc&0xFF)) return 0; // wrong CRC...
|
||||||
|
}
|
||||||
|
//Everything ok
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LT8910_WritePayload(uint8_t* msg, uint8_t len)
|
||||||
|
{
|
||||||
|
unsigned int crc=LT8910_CRC_Initial_Data,a,mask;
|
||||||
|
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
||||||
|
//Add packet len
|
||||||
|
if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN))
|
||||||
|
{
|
||||||
|
tmp=bit_reverse(len);
|
||||||
|
buffer[pos++]=tmp;
|
||||||
|
crc=crc16_update(crc,tmp);
|
||||||
|
}
|
||||||
|
//Add payload
|
||||||
|
for(i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
tmp=bit_reverse(msg[i]);
|
||||||
|
buffer[pos++]=tmp;
|
||||||
|
crc=crc16_update(crc,tmp);
|
||||||
|
}
|
||||||
|
//Add CRC
|
||||||
|
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
||||||
|
{
|
||||||
|
buffer[pos++]=crc>>8;
|
||||||
|
buffer[pos++]=crc;
|
||||||
|
}
|
||||||
|
//Shift everything to fit behind the trailer (4 to 18 bits)
|
||||||
|
shift=LT8910_buffer_overhead_bits&0x7;
|
||||||
|
pos_final=LT8910_buffer_overhead_bits/8;
|
||||||
|
mask=~(0xFF<<(8-shift));
|
||||||
|
LT8910_buffer[pos_final+pos]=0xFF;
|
||||||
|
for(i=pos-1;i!=0xFF;i--)
|
||||||
|
{
|
||||||
|
a=buffer[i]<<(8-shift);
|
||||||
|
LT8910_buffer[pos_final+i]=(LT8910_buffer[pos_final+i]&mask>>8)|a>>8;
|
||||||
|
LT8910_buffer[pos_final+i+1]=(LT8910_buffer[pos_final+i+1]&mask)|a;
|
||||||
|
}
|
||||||
|
if(shift)
|
||||||
|
pos++;
|
||||||
|
//Send everything
|
||||||
|
NRF24L01_WritePayload(LT8910_buffer+LT8910_buffer_start,pos_final+pos-LT8910_buffer_start);
|
||||||
|
}
|
||||||
|
// End of LT8910 emulation
|
||||||
|
108
Multiprotocol/SHENQI_nrf24l01.ino
Normal file
108
Multiprotocol/SHENQI_nrf24l01.ino
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#if defined(SHENQI_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
const uint8_t PROGMEM SHENQI_Freq[] = {
|
||||||
|
50,50,20,60,30,40,
|
||||||
|
10,30,40,20,60,10,
|
||||||
|
50,20,50,40,10,60,
|
||||||
|
30,30,60,10,40,50,
|
||||||
|
20,10,60,20,50,30,
|
||||||
|
40,40,30,50,20,60,
|
||||||
|
10,10,20,30,40,50,
|
||||||
|
60,60,50,40,30,20,
|
||||||
|
10,60,10,50,30,40,
|
||||||
|
20,10,40,30,60,20 };
|
||||||
|
|
||||||
|
void SHENQI_init()
|
||||||
|
{
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
|
NRF24L01_SetPower();
|
||||||
|
|
||||||
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address
|
||||||
|
|
||||||
|
LT8910_Config(4, 8, _BV(LT8910_CRC_ON)|_BV(LT8910_PACKET_LENGTH_EN), 0xAA);
|
||||||
|
LT8910_SetChannel(2);
|
||||||
|
LT8910_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4);
|
||||||
|
LT8910_SetTxRxMode(RX_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHENQI_send_packet()
|
||||||
|
{
|
||||||
|
packet[0]=0x00;
|
||||||
|
if(packet_count==0)
|
||||||
|
{
|
||||||
|
uint8_t bind_addr[4];
|
||||||
|
bind_addr[0]=0x9A;
|
||||||
|
bind_addr[1]=0x9A;
|
||||||
|
bind_addr[2]=rx_tx_addr[2];
|
||||||
|
bind_addr[3]=rx_tx_addr[3];
|
||||||
|
LT8910_SetAddress(bind_addr,4);
|
||||||
|
LT8910_SetChannel(2);
|
||||||
|
packet[1]=rx_tx_addr[1];
|
||||||
|
packet[2]=rx_tx_addr[0];
|
||||||
|
packet_period=2508;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LT8910_SetAddress(rx_tx_addr,4);
|
||||||
|
packet[1]=255-convert_channel_8b(RUDDER);
|
||||||
|
packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0);
|
||||||
|
uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[1]&0x0F);
|
||||||
|
LT8910_SetChannel(freq);
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(hopping_frequency_no==60)
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
packet_period=1750;
|
||||||
|
}
|
||||||
|
// Send packet + 1 retransmit - not sure why but needed (not present on original TX...)
|
||||||
|
LT8910_WritePayload(packet,3);
|
||||||
|
while(NRF24L01_packet_ack()!=PKT_ACKED);
|
||||||
|
LT8910_WritePayload(packet,3);
|
||||||
|
|
||||||
|
packet_count++;
|
||||||
|
if(packet_count==7)
|
||||||
|
{
|
||||||
|
packet_count=0;
|
||||||
|
packet_period=3000;
|
||||||
|
}
|
||||||
|
// Set power
|
||||||
|
NRF24L01_SetPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SHENQI_callback()
|
||||||
|
{
|
||||||
|
if(IS_BIND_DONE_on)
|
||||||
|
SHENQI_send_packet();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
||||||
|
{
|
||||||
|
if(LT8910_ReadPayload(packet, 3))
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
rx_tx_addr[3]=packet[1];
|
||||||
|
rx_tx_addr[2]=packet[2];
|
||||||
|
LT8910_SetTxRxMode(TX_EN);
|
||||||
|
packet_period=14000;
|
||||||
|
}
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return packet_period;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initSHENQI()
|
||||||
|
{
|
||||||
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
|
SHENQI_init();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
packet_count=0;
|
||||||
|
packet_period=100;
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -56,6 +56,7 @@
|
|||||||
#define YD717_NRF24L01_INO
|
#define YD717_NRF24L01_INO
|
||||||
#define MT99XX_NRF24L01_INO
|
#define MT99XX_NRF24L01_INO
|
||||||
#define MJXQ_NRF24L01_INO
|
#define MJXQ_NRF24L01_INO
|
||||||
|
#define SHENQI_NRF24L01_INO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
|
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
|
||||||
@ -139,6 +140,8 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
X600
|
X600
|
||||||
X800
|
X800
|
||||||
H26D
|
H26D
|
||||||
|
MODE_SHENQI
|
||||||
|
NONE
|
||||||
|
|
||||||
RX_Num value between 0 and 15
|
RX_Num value between 0 and 15
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ enum PROTOCOLS
|
|||||||
MODE_FRSKYX = 15, // =>CC2500
|
MODE_FRSKYX = 15, // =>CC2500
|
||||||
MODE_ESKY = 16, // =>NRF24L01
|
MODE_ESKY = 16, // =>NRF24L01
|
||||||
MODE_MT99XX=17, // =>NRF24L01
|
MODE_MT99XX=17, // =>NRF24L01
|
||||||
MODE_MJXQ=18 // =>NRF24L01
|
MODE_MJXQ=18, // =>NRF24L01
|
||||||
|
MODE_SHENQI=19 // =>NRF24L01
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flysky
|
enum Flysky
|
||||||
@ -419,6 +420,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
ESky 16
|
ESky 16
|
||||||
MT99XX 17
|
MT99XX 17
|
||||||
MJXQ 18
|
MJXQ 18
|
||||||
|
SHENQI 19
|
||||||
BindBit=> 0x80 1=Bind/0=No
|
BindBit=> 0x80 1=Bind/0=No
|
||||||
AutoBindBit=> 0x40 1=Yes /0=No
|
AutoBindBit=> 0x40 1=Yes /0=No
|
||||||
RangeCheck=> 0x20 1=Yes /0=No
|
RangeCheck=> 0x20 1=Yes /0=No
|
||||||
|
Loading…
x
Reference in New Issue
Block a user