mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-12 17:57:53 +00:00
Ajout LUA + CX35 + Suivit + ...
This commit is contained in:
parent
bd92f5b1c0
commit
5572c47c79
@ -51,12 +51,14 @@ void ASSAN_init()
|
|||||||
void ASSAN_send_packet()
|
void ASSAN_send_packet()
|
||||||
{
|
{
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
for(uint8_t i=0;i<10;i++)
|
for(uint8_t i=0;i<8;i++)
|
||||||
{
|
{
|
||||||
temp=Servo_data[i]<<3;
|
temp=Servo_data[i]<<3;
|
||||||
packet[2*i]=temp>>8;
|
packet[2*i]=temp>>8;
|
||||||
packet[2*i+1]=temp;
|
packet[2*i+1]=temp;
|
||||||
}
|
}
|
||||||
|
for(uint8_t i=0;i<ASSAN_ADDRESS_LENGTH;i++)
|
||||||
|
packet[16+i]=packet[23-i];
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_WritePayload(packet, ASSAN_PACKET_SIZE);
|
NRF24L01_WritePayload(packet, ASSAN_PACKET_SIZE);
|
||||||
@ -87,7 +89,7 @@ uint16_t ASSAN_callback()
|
|||||||
//Prepare bind packet
|
//Prepare bind packet
|
||||||
memset(packet,0x05,ASSAN_PACKET_SIZE-5);
|
memset(packet,0x05,ASSAN_PACKET_SIZE-5);
|
||||||
packet[15]=0x99;
|
packet[15]=0x99;
|
||||||
for(uint8_t i=0;i<4;i++)
|
for(uint8_t i=0;i<ASSAN_ADDRESS_LENGTH;i++)
|
||||||
packet[16+i]=packet[23-i];
|
packet[16+i]=packet[23-i];
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
delayMilliseconds(260);
|
delayMilliseconds(260);
|
||||||
@ -143,7 +145,7 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
|
|||||||
uint8_t freq=0,freq2;
|
uint8_t freq=0,freq2;
|
||||||
for(uint8_t i=0;i<4;i++)
|
for(uint8_t i=0;i<4;i++)
|
||||||
{
|
{
|
||||||
uint8_t temp=rx_tx_addr[0];
|
uint8_t temp=rx_tx_addr[i];
|
||||||
packet[i+20]=temp;
|
packet[i+20]=temp;
|
||||||
packet[i+24]=temp+1;
|
packet[i+24]=temp+1;
|
||||||
freq+=temp;
|
freq+=temp;
|
||||||
@ -160,7 +162,7 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
|
|||||||
freq2+=freq*2-5;
|
freq2+=freq*2-5;
|
||||||
}
|
}
|
||||||
while( (freq2>118) || (freq2<freq+1) || (freq2==2*freq) );
|
while( (freq2>118) || (freq2<freq+1) || (freq2==2*freq) );
|
||||||
hopping_frequency[1]=freq2; // Add some random to the second channel
|
hopping_frequency[1]=freq2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initASSAN()
|
uint16_t initASSAN()
|
||||||
|
@ -11,10 +11,10 @@ if exist .dep (make clean)
|
|||||||
md .dep
|
md .dep
|
||||||
make
|
make
|
||||||
if exist MultiOrange.hex (
|
if exist MultiOrange.hex (
|
||||||
objcopy -I ihex MultiOrange.hex -O binary MultiOrange.bin
|
avr-objcopy -I ihex MultiOrange.hex -O binary MultiOrange.bin
|
||||||
echo.
|
echo.
|
||||||
echo Compilation OK.
|
echo Compilation OK.
|
||||||
echo Use MultiOrange.hex to program your OrangeTX module.
|
echo Use MultiOrange.hex or MultiOrange.bin to program your OrangeTX module.
|
||||||
echo.
|
echo.
|
||||||
)
|
)
|
||||||
pause
|
pause
|
||||||
|
@ -66,3 +66,18 @@ uint16_t limit_channel_100(uint8_t ch)
|
|||||||
return Servo_data[ch];
|
return Servo_data[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************/
|
||||||
|
/** FrSky D and X routines **/
|
||||||
|
/******************************/
|
||||||
|
void Frsky_init_hop(void)
|
||||||
|
{
|
||||||
|
uint8_t channel = rx_tx_addr[0]&0x07;
|
||||||
|
uint8_t channel_spacing = (rx_tx_addr[1]&0x7F)+64;
|
||||||
|
for(uint8_t i=0;i<50;i++)
|
||||||
|
{
|
||||||
|
hopping_frequency[i]=i>47?0:channel;
|
||||||
|
channel=(channel+channel_spacing) % 0xEB;
|
||||||
|
if((channel==0x00) || (channel==0x5A) || (channel==0xDC))
|
||||||
|
channel++;
|
||||||
|
}
|
||||||
|
}
|
@ -50,16 +50,6 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
|||||||
//#######END INIT########
|
//#######END INIT########
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t __attribute__((unused)) get_chan_num(uint16_t idx)
|
|
||||||
{
|
|
||||||
uint8_t ret = (idx * 0x1e) % 0xeb;
|
|
||||||
if(idx == 3 || idx == 23 || idx == 47)
|
|
||||||
ret++;
|
|
||||||
if(idx > 47)
|
|
||||||
return 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frsky2way_build_bind_packet()
|
static void __attribute__((unused)) frsky2way_build_bind_packet()
|
||||||
{
|
{
|
||||||
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
|
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
|
||||||
@ -71,11 +61,11 @@ static void __attribute__((unused)) frsky2way_build_bind_packet()
|
|||||||
packet[4] = rx_tx_addr[2];
|
packet[4] = rx_tx_addr[2];
|
||||||
uint16_t idx = ((state -FRSKY_BIND) % 10) * 5;
|
uint16_t idx = ((state -FRSKY_BIND) % 10) * 5;
|
||||||
packet[5] = idx;
|
packet[5] = idx;
|
||||||
packet[6] = get_chan_num(idx++);
|
packet[6] = hopping_frequency[idx++];
|
||||||
packet[7] = get_chan_num(idx++);
|
packet[7] = hopping_frequency[idx++];
|
||||||
packet[8] = get_chan_num(idx++);
|
packet[8] = hopping_frequency[idx++];
|
||||||
packet[9] = get_chan_num(idx++);
|
packet[9] = hopping_frequency[idx++];
|
||||||
packet[10] = get_chan_num(idx++);
|
packet[10] = hopping_frequency[idx++];
|
||||||
packet[11] = 0x00;
|
packet[11] = 0x00;
|
||||||
packet[12] = 0x00;
|
packet[12] = 0x00;
|
||||||
packet[13] = 0x00;
|
packet[13] = 0x00;
|
||||||
@ -124,6 +114,7 @@ static void __attribute__((unused)) frsky2way_data_frame()
|
|||||||
|
|
||||||
uint16_t initFrSky_2way()
|
uint16_t initFrSky_2way()
|
||||||
{
|
{
|
||||||
|
Frsky_init_hop();
|
||||||
if(IS_AUTOBIND_FLAG_on)
|
if(IS_AUTOBIND_FLAG_on)
|
||||||
{
|
{
|
||||||
frsky2way_init(1);
|
frsky2way_init(1);
|
||||||
@ -169,7 +160,7 @@ uint16_t ReadFrSky_2way()
|
|||||||
{ //telemetry receive
|
{ //telemetry receive
|
||||||
CC2500_SetTxRxMode(RX_EN);
|
CC2500_SetTxRxMode(RX_EN);
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
|
||||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||||
state++;
|
state++;
|
||||||
return 1300;
|
return 1300;
|
||||||
@ -191,7 +182,7 @@ uint16_t ReadFrSky_2way()
|
|||||||
CC2500_SetPower(); // Set tx_power
|
CC2500_SetPower(); // Set tx_power
|
||||||
}
|
}
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
|
||||||
if ( prev_option != option )
|
if ( prev_option != option )
|
||||||
{
|
{
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||||
|
@ -26,29 +26,11 @@ uint8_t ctr;
|
|||||||
uint8_t seq_last_sent;
|
uint8_t seq_last_sent;
|
||||||
uint8_t seq_last_rcvd;
|
uint8_t seq_last_rcvd;
|
||||||
|
|
||||||
const PROGMEM uint8_t hop_data[]={
|
|
||||||
0x02, 0xD4, 0xBB, 0xA2, 0x89,
|
|
||||||
0x70, 0x57, 0x3E, 0x25, 0x0C,
|
|
||||||
0xDE, 0xC5, 0xAC, 0x93, 0x7A,
|
|
||||||
0x61, 0x48, 0x2F, 0x16, 0xE8,
|
|
||||||
0xCF, 0xB6, 0x9D, 0x84, 0x6B,
|
|
||||||
0x52, 0x39, 0x20, 0x07, 0xD9,
|
|
||||||
0xC0, 0xA7, 0x8E, 0x75, 0x5C,
|
|
||||||
0x43, 0x2A, 0x11, 0xE3, 0xCA,
|
|
||||||
0xB1, 0x98, 0x7F, 0x66, 0x4D,
|
|
||||||
0x34, 0x1B, 0x00, 0x1D, 0x03
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t __attribute__((unused)) hop(uint8_t byte)
|
|
||||||
{
|
|
||||||
return pgm_read_byte_near(&hop_data[byte]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) set_start(uint8_t ch )
|
static void __attribute__((unused)) set_start(uint8_t ch )
|
||||||
{
|
{
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, ch==47? 0:hop(ch));
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) frskyX_init()
|
static void __attribute__((unused)) frskyX_init()
|
||||||
@ -87,19 +69,14 @@ static void __attribute__((unused)) frskyX_init()
|
|||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
//
|
//
|
||||||
for(uint8_t c=0;c < 47;c++)
|
for(uint8_t c=0;c < 48;c++)
|
||||||
{//calibrate hop channels
|
{//calibrate hop channels
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR,hop(c));
|
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
|
||||||
CC2500_Strobe(CC2500_SCAL);
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
delayMicroseconds(900);//
|
delayMicroseconds(900);//
|
||||||
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
}
|
}
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR,0x00);
|
|
||||||
CC2500_Strobe(CC2500_SCAL);
|
|
||||||
delayMicroseconds(900);
|
|
||||||
calData[47] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
|
||||||
//#######END INIT########
|
//#######END INIT########
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +125,11 @@ static void __attribute__((unused)) frskyX_build_bind_packet()
|
|||||||
packet[4] = rx_tx_addr[2];
|
packet[4] = rx_tx_addr[2];
|
||||||
int idx = ((state -FRSKY_BIND) % 10) * 5;
|
int idx = ((state -FRSKY_BIND) % 10) * 5;
|
||||||
packet[5] = idx;
|
packet[5] = idx;
|
||||||
packet[6] = hop(idx++);
|
packet[6] = hopping_frequency[idx++];
|
||||||
packet[7] = hop(idx++);
|
packet[7] = hopping_frequency[idx++];
|
||||||
packet[8] = hop(idx++);
|
packet[8] = hopping_frequency[idx++];
|
||||||
packet[9] = hop(idx++);
|
packet[9] = hopping_frequency[idx++];
|
||||||
packet[10] = hop(idx++);
|
packet[10] = hopping_frequency[idx++];
|
||||||
packet[11] = 0x02;
|
packet[11] = 0x02;
|
||||||
packet[12] = RX_num;
|
packet[12] = RX_num;
|
||||||
//
|
//
|
||||||
@ -307,16 +284,19 @@ uint16_t ReadFrSkyX()
|
|||||||
|
|
||||||
uint16_t initFrSkyX()
|
uint16_t initFrSkyX()
|
||||||
{
|
{
|
||||||
|
set_rx_tx_addr(MProtocol_id_master);
|
||||||
|
Frsky_init_hop();
|
||||||
while(!chanskip)
|
while(!chanskip)
|
||||||
chanskip=random(0xfefefefe)%47;
|
chanskip=random(0xfefefefe)%47;
|
||||||
while((chanskip-ctr)%4)
|
while((chanskip-ctr)%4)
|
||||||
ctr=(ctr+1)%4;
|
ctr=(ctr+1)%4;
|
||||||
|
|
||||||
counter_rst=(chanskip-ctr)>>2;
|
counter_rst=(chanskip-ctr)>>2;
|
||||||
|
|
||||||
//for test***************
|
//for test***************
|
||||||
//rx_tx_addr[3]=0xB3;
|
//rx_tx_addr[3]=0xB3;
|
||||||
//rx_tx_addr[2]=0xFD;
|
//rx_tx_addr[2]=0xFD;
|
||||||
//************************
|
//************************
|
||||||
|
hopping_frequency[47]=0;
|
||||||
frskyX_init();
|
frskyX_init();
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
//
|
//
|
||||||
|
@ -51,9 +51,9 @@ const uint8_t PROGMEM E010_map_txid[][2] = {
|
|||||||
{0xC0, 0x44},
|
{0xC0, 0x44},
|
||||||
{0x2A, 0xFE},
|
{0x2A, 0xFE},
|
||||||
{0xD7, 0x6E},
|
{0xD7, 0x6E},
|
||||||
{0x3C, 0xCD} // for this ID rx_tx_addr[2]=0x01
|
{0x3C, 0xCD}, // for this ID rx_tx_addr[2]=0x01
|
||||||
|
{0xF5, 0x2B} // for this ID rx_tx_addr[2]=0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t PROGMEM E010_map_rfchan[][2] = {
|
const uint8_t PROGMEM E010_map_rfchan[][2] = {
|
||||||
{0x3A, 0x35},
|
{0x3A, 0x35},
|
||||||
{0x2E, 0x36},
|
{0x2E, 0x36},
|
||||||
@ -65,11 +65,13 @@ const uint8_t PROGMEM E010_map_rfchan[][2] = {
|
|||||||
{0x34, 0x3E},
|
{0x34, 0x3E},
|
||||||
{0x34, 0x2F},
|
{0x34, 0x2F},
|
||||||
{0x39, 0x3E},
|
{0x39, 0x3E},
|
||||||
|
{0x2E, 0x38},
|
||||||
{0x2E, 0x36},
|
{0x2E, 0x36},
|
||||||
{0x2E, 0x36},
|
{0x2E, 0x38},
|
||||||
{0x2E, 0x36},
|
|
||||||
{0x3A, 0x41},
|
{0x3A, 0x41},
|
||||||
{0x32, 0x3E} };
|
{0x32, 0x3E},
|
||||||
|
{0x33, 0x3F}
|
||||||
|
};
|
||||||
|
|
||||||
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
||||||
#define MJXQ_PAN_DOWN 0x08
|
#define MJXQ_PAN_DOWN 0x08
|
||||||
@ -254,7 +256,7 @@ static void __attribute__((unused)) MJXQ_init2()
|
|||||||
case E010:
|
case E010:
|
||||||
for(uint8_t i=0;i<2;i++)
|
for(uint8_t i=0;i<2;i++)
|
||||||
{
|
{
|
||||||
hopping_frequency[i]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]%15][i] );
|
hopping_frequency[i]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]&0x0F][i] );
|
||||||
hopping_frequency[i+2]=hopping_frequency[i]+0x10;
|
hopping_frequency[i+2]=hopping_frequency[i]+0x10;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -277,8 +279,11 @@ static void __attribute__((unused)) MJXQ_initialize_txid()
|
|||||||
break;
|
break;
|
||||||
case E010:
|
case E010:
|
||||||
for(uint8_t i=0;i<2;i++)
|
for(uint8_t i=0;i<2;i++)
|
||||||
rx_tx_addr[i]=pgm_read_byte_near( &E010_map_txid[rx_tx_addr[3]%15][i] );
|
rx_tx_addr[i]=pgm_read_byte_near( &E010_map_txid[rx_tx_addr[3]&0x0F][i] );
|
||||||
rx_tx_addr[2]=(rx_tx_addr[3]%15 == 14)?1:0;
|
if((rx_tx_addr[3]&0x0E) == 0x0E)
|
||||||
|
rx_tx_addr[2]=(rx_tx_addr[3]&0x01)+1;
|
||||||
|
else
|
||||||
|
rx_tx_addr[2]=0;
|
||||||
break;
|
break;
|
||||||
case WLH08:
|
case WLH08:
|
||||||
rx_tx_addr[0]&=0xF8;
|
rx_tx_addr[0]&=0xF8;
|
||||||
|
29
Multiprotocol/Multi.txt
Normal file
29
Multiprotocol/Multi.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
1,Flysky,Flysky,V9x9,V6x6,V912,CX20
|
||||||
|
2,Hubsan
|
||||||
|
3,FrskyD
|
||||||
|
4,Hisky,Hisky,HK310
|
||||||
|
5,V2x2,V2x2,JXD506
|
||||||
|
6,DSM,DSM2-22,DSM2-11,DSMX-22,DSMX-11,AUTO
|
||||||
|
7,Devo
|
||||||
|
8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI
|
||||||
|
9,KN,WLTOYS,FEILUN
|
||||||
|
10,SymaX,SYMAX,SYMAX5C
|
||||||
|
11,SLT,SLT,VISTA
|
||||||
|
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
||||||
|
13,CG023,CG023,YD829,H8_3D
|
||||||
|
14,Bayang,Bayang,H8S3D
|
||||||
|
15,FrskyX,CH_16,CH_8
|
||||||
|
16,ESky
|
||||||
|
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||||
|
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH
|
||||||
|
19,Shenqi
|
||||||
|
20,FY326,FY326,FY319
|
||||||
|
21,SFHSS
|
||||||
|
22,J6PRO
|
||||||
|
23,FQ777
|
||||||
|
24,ASSAN
|
||||||
|
25,FrskyV
|
||||||
|
26,HONTAI,HONTAI,JJRCX1,X5C1,FQ777_951
|
||||||
|
27,OpnLrs
|
||||||
|
28,AFHD2SA,PWM_IBUS,PPM_IBUS,PWM_SBUS,PPM_SBUS
|
||||||
|
29,Q2X2,Q222,Q242,Q282
|
@ -80,7 +80,7 @@ uint16_t packet_period;
|
|||||||
uint8_t packet_count;
|
uint8_t packet_count;
|
||||||
uint8_t packet_sent;
|
uint8_t packet_sent;
|
||||||
uint8_t packet_length;
|
uint8_t packet_length;
|
||||||
uint8_t hopping_frequency[23];
|
uint8_t hopping_frequency[50];
|
||||||
uint8_t *hopping_frequency_ptr;
|
uint8_t *hopping_frequency_ptr;
|
||||||
uint8_t hopping_frequency_no=0;
|
uint8_t hopping_frequency_no=0;
|
||||||
uint8_t rf_ch_num;
|
uint8_t rf_ch_num;
|
||||||
@ -493,7 +493,9 @@ void Update_All()
|
|||||||
#endif //ENABLE_PPM
|
#endif //ENABLE_PPM
|
||||||
update_channels_aux();
|
update_channels_aux();
|
||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) )
|
#if !defined(MULTI_TELEMETRY)
|
||||||
|
if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) )
|
||||||
|
#endif
|
||||||
TelemetryUpdate();
|
TelemetryUpdate();
|
||||||
#endif
|
#endif
|
||||||
update_led_status();
|
update_led_status();
|
||||||
@ -1093,12 +1095,21 @@ void Mprotocol_serial_init()
|
|||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
void PPM_Telemetry_serial_init()
|
void PPM_Telemetry_serial_init()
|
||||||
{
|
{
|
||||||
if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) )
|
#ifdef MULTI_TELEMETRY
|
||||||
initTXSerial( SPEED_9600 ) ;
|
Mprotocol_serial_init();
|
||||||
if(protocol==MODE_FRSKYX)
|
#ifndef ORANGE_TX
|
||||||
initTXSerial( SPEED_57600 ) ;
|
#ifndef STM32_BOARD
|
||||||
if(protocol==MODE_DSM)
|
UCSR0B &= ~(_BV(RXEN0)|_BV(RXCIE0));//rx disable and interrupt
|
||||||
initTXSerial( SPEED_125K ) ;
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) )
|
||||||
|
initTXSerial( SPEED_9600 ) ;
|
||||||
|
if(protocol==MODE_FRSKYX)
|
||||||
|
initTXSerial( SPEED_57600 ) ;
|
||||||
|
if(protocol==MODE_DSM)
|
||||||
|
initTXSerial( SPEED_125K ) ;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -6,38 +6,28 @@
|
|||||||
|
|
||||||
#define Q303_PACKET_SIZE 10
|
#define Q303_PACKET_SIZE 10
|
||||||
#define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec
|
#define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec
|
||||||
|
#define CX35_PACKET_PERIOD 3000
|
||||||
#define Q303_INITIAL_WAIT 500
|
#define Q303_INITIAL_WAIT 500
|
||||||
#define Q303_RF_BIND_CHANNEL 0x02
|
#define Q303_RF_BIND_CHANNEL 0x02
|
||||||
#define Q303_NUM_RF_CHANNELS 4
|
#define Q303_NUM_RF_CHANNELS 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t tx_addr[5];
|
static uint8_t tx_addr[5];
|
||||||
static uint8_t current_chan;
|
static uint8_t current_chan;
|
||||||
/*
|
|
||||||
static const struct {
|
|
||||||
u8 txid[sizeof(txid)];
|
|
||||||
u8 rfchan[NUM_RF_CHANNELS];
|
|
||||||
} q303_tx_rf_map[] = {
|
|
||||||
{{0xb8, 0x69, 0x64, 0x67}, {0x48, 0x4a, 0x4c, 0x46}}, // tx2
|
|
||||||
{{0xAE, 0x89, 0x97, 0x87}, {0x4A, 0x4C, 0x4E, 0x48}}
|
|
||||||
}; // tx1
|
|
||||||
*/
|
|
||||||
uint8_t txid[4] = {0xAE, 0x89, 0x97, 0x87};
|
|
||||||
static uint8_t rf_chans[4] = {0x4A, 0x4C, 0x4E, 0x48};
|
|
||||||
|
|
||||||
// haven't figured out txid<-->rf channel mapping yet
|
|
||||||
// static const struct { uint8_t txid[sizeof(txid)]; uint8_t rfchan[Q303_NUM_RF_CHANNELS]; } q303_tx_rf_map[] = {{{0xAE, 0x89, 0x97, 0x87}, {0x4A, 0x4C, 0x4E, 0x48}}};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Q303_BIND,
|
Q303_BIND,
|
||||||
Q303_DATA
|
Q303_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
// flags going to packet[8]
|
|
||||||
|
// flags going to packet[8] (Q303)
|
||||||
#define Q303_FLAG_HIGHRATE 0x03
|
#define Q303_FLAG_HIGHRATE 0x03
|
||||||
#define Q303_FLAG_AHOLD 0x40
|
#define Q303_FLAG_AHOLD 0x40
|
||||||
#define Q303_FLAG_RTH 0x80
|
#define Q303_FLAG_RTH 0x80
|
||||||
|
|
||||||
// flags going to packet[9]
|
// flags going to packet[9] (Q303)
|
||||||
#define Q303_FLAG_GIMBAL_DN 0x04
|
#define Q303_FLAG_GIMBAL_DN 0x04
|
||||||
#define Q303_FLAG_GIMBAL_UP 0x20
|
#define Q303_FLAG_GIMBAL_UP 0x20
|
||||||
#define Q303_FLAG_HEADLESS 0x08
|
#define Q303_FLAG_HEADLESS 0x08
|
||||||
@ -45,6 +35,99 @@ enum {
|
|||||||
#define Q303_FLAG_SNAPSHOT 0x10
|
#define Q303_FLAG_SNAPSHOT 0x10
|
||||||
#define Q303_FLAG_VIDEO 0x01
|
#define Q303_FLAG_VIDEO 0x01
|
||||||
|
|
||||||
|
static u8 cx35_lastButton()
|
||||||
|
{
|
||||||
|
#define CX35_BTN_TAKEOFF 1
|
||||||
|
#define CX35_BTN_DESCEND 2
|
||||||
|
#define CX35_BTN_SNAPSHOT 4
|
||||||
|
#define CX35_BTN_VIDEO 8
|
||||||
|
#define CX35_BTN_RTH 16
|
||||||
|
|
||||||
|
#define CX35_CMD_RATE 0x09
|
||||||
|
#define CX35_CMD_TAKEOFF 0x0e
|
||||||
|
#define CX35_CMD_DESCEND 0x0f
|
||||||
|
#define CX35_CMD_SNAPSHOT 0x0b
|
||||||
|
#define CX35_CMD_VIDEO 0x0c
|
||||||
|
#define CX35_CMD_RTH 0x11
|
||||||
|
|
||||||
|
static uint8_t cx35_btn_state;
|
||||||
|
static uint8_t command;
|
||||||
|
// simulate 2 keypress on rate button just after bind
|
||||||
|
if(packet_counter < 50) {
|
||||||
|
cx35_btn_state = 0;
|
||||||
|
packet_counter++;
|
||||||
|
command = 0x00; // startup
|
||||||
|
}
|
||||||
|
else if(packet_counter < 150) {
|
||||||
|
packet_counter++;
|
||||||
|
command = CX35_CMD_RATE; // 1st keypress
|
||||||
|
}
|
||||||
|
else if(packet_counter < 250) {
|
||||||
|
packet_counter++;
|
||||||
|
command |= 0x20; // 2nd keypress
|
||||||
|
}
|
||||||
|
|
||||||
|
// descend
|
||||||
|
else if(!(GET_FLAG(CHANNEL_ARM, 1)) && !(cx35_btn_state & CX35_BTN_DESCEND)) {
|
||||||
|
cx35_btn_state |= CX35_BTN_DESCEND;
|
||||||
|
cx35_btn_state &= ~CX35_BTN_TAKEOFF;
|
||||||
|
command = CX35_CMD_DESCEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// take off
|
||||||
|
else if(GET_FLAG(CHANNEL_ARM,1) && !(cx35_btn_state & CX35_BTN_TAKEOFF)) {
|
||||||
|
cx35_btn_state |= CX35_BTN_TAKEOFF;
|
||||||
|
cx35_btn_state &= ~CX35_BTN_DESCEND;
|
||||||
|
command = CX35_CMD_TAKEOFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTH
|
||||||
|
else if(GET_FLAG(CHANNEL_RTH,1) && !(cx35_btn_state & CX35_BTN_RTH)) {
|
||||||
|
cx35_btn_state |= CX35_BTN_RTH;
|
||||||
|
if(command == CX35_CMD_RTH)
|
||||||
|
command |= 0x20;
|
||||||
|
else
|
||||||
|
command = CX35_CMD_RTH;
|
||||||
|
}
|
||||||
|
else if(!(GET_FLAG(CHANNEL_RTH,1)) && (cx35_btn_state & CX35_BTN_RTH)) {
|
||||||
|
cx35_btn_state &= ~CX35_BTN_RTH;
|
||||||
|
if(command == CX35_CMD_RTH)
|
||||||
|
command |= 0x20;
|
||||||
|
else
|
||||||
|
command = CX35_CMD_RTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// video
|
||||||
|
else if(GET_FLAG(CHANNEL_VIDEO,1) && !(cx35_btn_state & CX35_BTN_VIDEO)) {
|
||||||
|
cx35_btn_state |= CX35_BTN_VIDEO;
|
||||||
|
if(command == CX35_CMD_VIDEO)
|
||||||
|
command |= 0x20;
|
||||||
|
else
|
||||||
|
command = CX35_CMD_VIDEO;
|
||||||
|
}
|
||||||
|
else if(!(GET_FLAG(CHANNEL_VIDEO,1)) && (cx35_btn_state & CX35_BTN_VIDEO)) {
|
||||||
|
cx35_btn_state &= ~CX35_BTN_VIDEO;
|
||||||
|
if(command == CX35_CMD_VIDEO)
|
||||||
|
command |= 0x20;
|
||||||
|
else
|
||||||
|
command = CX35_CMD_VIDEO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// snapshot
|
||||||
|
else if(GET_FLAG(CHANNEL_SNAPSHOT,1) && !(cx35_btn_state & CX35_BTN_SNAPSHOT)) {
|
||||||
|
cx35_btn_state |= CX35_BTN_SNAPSHOT;
|
||||||
|
if(command == CX35_CMD_SNAPSHOT)
|
||||||
|
command |= 0x20;
|
||||||
|
else
|
||||||
|
command = CX35_CMD_SNAPSHOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(GET_FLAG(CHANNEL_SNAPSHOT,1)))
|
||||||
|
cx35_btn_state &= ~CX35_BTN_SNAPSHOT;
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_packet(uint8_t bind)
|
static void send_packet(uint8_t bind)
|
||||||
{
|
{
|
||||||
if(bind) {
|
if(bind) {
|
||||||
@ -53,10 +136,10 @@ static void send_packet(uint8_t bind)
|
|||||||
memset(&packet[5], 0, 5);
|
memset(&packet[5], 0, 5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
aileron = 1000 - map(Servo_data[AILERON], 1000, 2000, 0, 1000);
|
aileron = 1000 - map(Servo_data[AILERON], 1000, 2000, 1000, 0);
|
||||||
elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 0, 1000);
|
elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 1000, 0);
|
||||||
throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000);
|
throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000);
|
||||||
rudder = map(Servo_data[RUDDER], 1000, 2000, 0, 1000);
|
rudder = map(Servo_data[RUDDER], 1000, 2000, 0, 1000);
|
||||||
|
|
||||||
packet[0] = 0x55;
|
packet[0] = 0x55;
|
||||||
packet[1] = aileron >> 2 ; // 8 bits
|
packet[1] = aileron >> 2 ; // 8 bits
|
||||||
@ -67,40 +150,56 @@ static void send_packet(uint8_t bind)
|
|||||||
packet[4] = (throttle & 0x3f) << 2 // 6 bits
|
packet[4] = (throttle & 0x3f) << 2 // 6 bits
|
||||||
| (rudder >> 8); // 2 bits
|
| (rudder >> 8); // 2 bits
|
||||||
packet[5] = rudder & 0xff; // 8 bits
|
packet[5] = rudder & 0xff; // 8 bits
|
||||||
packet[6] = 0x10; // trim(s) ?
|
|
||||||
packet[7] = 0x10; // trim(s) ?
|
switch(sub_protocol) {
|
||||||
packet[8] = 0x03 // high rate (0-3)
|
case FORMAT_Q303:
|
||||||
| GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD)
|
packet[6] = 0x10; // trim(s) ?
|
||||||
| GET_FLAG(Servo_AUX6, Q303_FLAG_RTH);
|
packet[7] = 0x10; // trim(s) ?
|
||||||
packet[9] = 0x40 // always set
|
packet[8] = 0x03 // high rate (0-3)
|
||||||
| GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS)
|
| GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD)
|
||||||
| GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP)
|
| GET_FLAG(Servo_AUX6, Q303_FLAG_RTH);
|
||||||
| GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT)
|
packet[9] = 0x40 // always set
|
||||||
| GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO);
|
| GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS)
|
||||||
if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH))
|
| GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP)
|
||||||
packet[9] |= Q303_FLAG_GIMBAL_DN;
|
| GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT)
|
||||||
else if(Servo_data[AUX7] > PPM_SWITCH)
|
| GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO);
|
||||||
packet[9] |= Q303_FLAG_GIMBAL_UP;
|
if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH))
|
||||||
// set low rate for first packets
|
packet[9] |= Q303_FLAG_GIMBAL_DN;
|
||||||
if(bind_counter != 0) {
|
else if(Servo_data[AUX7] > PPM_SWITCH)
|
||||||
packet[8] &= ~0x03;
|
packet[9] |= Q303_FLAG_GIMBAL_UP;
|
||||||
bind_counter--;
|
break;
|
||||||
|
case FORMAT_CX35:
|
||||||
|
slider = map(Servo_data[AUX7], 1000, 2000, 731, 342); // GIMBAL
|
||||||
|
packet[6] = slider >> 2;
|
||||||
|
packet[7] = ((slider & 3) << 6)
|
||||||
|
| 0x3e; // ?? 6 bit left (always 111110 ?)
|
||||||
|
|
||||||
|
packet[8] = 0x80; // always set
|
||||||
|
packet[9] = cx35_lastButton();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power on, TX mode, CRC enabled
|
// Power on, TX mode, CRC enabled
|
||||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||||
if (bind) {
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, Q303_RF_BIND_CHANNEL);
|
|
||||||
} else {
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_chans[current_chan++]);
|
|
||||||
current_chan %= Q303_NUM_RF_CHANNELS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? Q303_RF_BIND_CHANNEL : hopping_frequency[current_chan++]);
|
||||||
NRF24L01_FlushTx();
|
current_chan %= Q303_NUM_RF_CHANNELS;
|
||||||
|
|
||||||
XN297_WritePayload(packet, Q303_PACKET_SIZE);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
|
NRF24L01_FlushTx();
|
||||||
|
|
||||||
|
XN297_WritePayload(packet, Q303_PACKET_SIZE);
|
||||||
|
|
||||||
|
// Check and adjust transmission power. We do this after
|
||||||
|
// transmission to not bother with timeout after power
|
||||||
|
// settings change - we have plenty of time until next
|
||||||
|
// packet.
|
||||||
|
if (tx_power != Model.tx_power) {
|
||||||
|
//Keep transmit power updated
|
||||||
|
tx_power = Model.tx_power;
|
||||||
|
NRF24L01_SetPower(tx_power);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t q303_callback()
|
static uint16_t q303_callback()
|
||||||
@ -112,7 +211,7 @@ static uint16_t q303_callback()
|
|||||||
memcpy(&tx_addr[1], txid, 4);
|
memcpy(&tx_addr[1], txid, 4);
|
||||||
XN297_SetTXAddr(tx_addr, 5);
|
XN297_SetTXAddr(tx_addr, 5);
|
||||||
phase = Q303_DATA;
|
phase = Q303_DATA;
|
||||||
bind_counter = Q303_BIND_COUNT;
|
packet_counter = 0;
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
} else {
|
} else {
|
||||||
send_packet(1);
|
send_packet(1);
|
||||||
@ -123,20 +222,34 @@ static uint16_t q303_callback()
|
|||||||
send_packet(0);
|
send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return Q303_PACKET_PERIOD;
|
return packet_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t q303_init()
|
static uint16_t q303_init()
|
||||||
{
|
{
|
||||||
// memcpy(txid, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].txid, sizeof(txid));
|
offset = txid[0] & 3;
|
||||||
// memcpy(rf_chans, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].rfchan, sizeof(rf_chans));
|
if(sub_protocol == FORMAT_CX35) {
|
||||||
|
for(i=0; i<Q303_NUM_RF_CHANNELS; i++)
|
||||||
|
hopping_frequency[i] = 0x14 + i*3 + offset;
|
||||||
|
}
|
||||||
|
else{ // Q303
|
||||||
|
for(i=0; i<Q303_NUM_RF_CHANNELS; i++)
|
||||||
|
hopping_frequency[i] = 0x46 + i*2 + offset;
|
||||||
|
}
|
||||||
|
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
if(sub_protocol == FORMAT_CX35) {
|
||||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||||
|
}
|
||||||
|
else { // Q303
|
||||||
|
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||||
|
}
|
||||||
XN297_SetTXAddr((uint8_t *) "\xCC\xCC\xCC\xCC\xCC", 5);
|
XN297_SetTXAddr((uint8_t *) "\xCC\xCC\xCC\xCC\xCC", 5);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
|
NRF24L01_FlushRx();
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
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_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
||||||
@ -149,12 +262,13 @@ static uint16_t q303_init()
|
|||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
|
|
||||||
NRF24L01_Activate(0x53); // switch bank back
|
|
||||||
|
|
||||||
BIND_IN_PROGRESS;
|
BIND_IN_PROGRESS;
|
||||||
bind_counter = Q303_BIND_COUNT;
|
bind_counter = Q303_BIND_COUNT;
|
||||||
|
if(Model.proto_opts[PROTOOPTS_FORMAT] == FORMAT_Q303)
|
||||||
|
packet_period = Q303_PACKET_PERIOD;
|
||||||
|
else if(Model.proto_opts[PROTOOPTS_FORMAT] == FORMAT_CX35)
|
||||||
|
packet_period = CX35_PACKET_PERIOD;
|
||||||
current_chan = 0;
|
current_chan = 0;
|
||||||
// PROTOCOL_SetBindState(Q303_BIND_COUNT * Q303_PACKET_PERIOD / 1000);
|
|
||||||
phase = Q303_BIND;
|
phase = Q303_BIND;
|
||||||
return Q303_INITIAL_WAIT;
|
return Q303_INITIAL_WAIT;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +263,14 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
|||||||
---|---|---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|AHOLD|FLIP|SNAPSHOT|VIDEO|HEADLESS|RTH|GIMBAL
|
A|E|T|R|AHOLD|FLIP|SNAPSHOT|VIDEO|HEADLESS|RTH|GIMBAL
|
||||||
|
|
||||||
|
####Sub_protocol CX35
|
||||||
|
|
||||||
|
Autobind
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
|
---|---|---|---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|ARM|FLIP|SNAPSHOT|VIDEO|HEADLESS|RTH| on Q303, full range on CX35
|
||||||
|
|
||||||
###UDI
|
###UDI
|
||||||
Modele: Known UDI 2.4GHz protocol variants, all using BK2421
|
Modele: Known UDI 2.4GHz protocol variants, all using BK2421
|
||||||
* UDI U819 coaxial 3ch helicoper
|
* UDI U819 coaxial 3ch helicoper
|
||||||
|
@ -17,8 +17,13 @@
|
|||||||
//**************************
|
//**************************
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
|
|
||||||
|
#if defined MULTI_TELEMETRY
|
||||||
|
#define MULTI_TIME 250 //in ms
|
||||||
|
uint32_t lastMulti = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SPORT_TELEMETRY
|
#if defined SPORT_TELEMETRY
|
||||||
#define SPORT_TIME 12000
|
#define SPORT_TIME 12000 //12ms
|
||||||
#define FRSKY_SPORT_PACKET_SIZE 8
|
#define FRSKY_SPORT_PACKET_SIZE 8
|
||||||
uint32_t last = 0;
|
uint32_t last = 0;
|
||||||
uint8_t sport_counter=0;
|
uint8_t sport_counter=0;
|
||||||
@ -52,22 +57,82 @@ uint8_t frame[18];
|
|||||||
} SerialControl ;
|
} SerialControl ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DSM_TELEMETRY
|
#ifdef MULTI_TELEMETRY
|
||||||
void DSM_frame()
|
static void multi_send_header(uint8_t type, uint8_t len)
|
||||||
{
|
{
|
||||||
Serial_write(0xAA); // Telemetry packet
|
Serial_write('M');
|
||||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
Serial_write('P');
|
||||||
Serial_write(pkt[i]);
|
Serial_write(type);
|
||||||
|
Serial_write(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void multi_send_frskyhub()
|
||||||
|
{
|
||||||
|
multi_send_header(MULTI_TELEMETRY_HUB, 9);
|
||||||
|
for (uint8_t i = 0; i < 9; i++)
|
||||||
|
Serial_write(frame[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void multi_send_status()
|
||||||
|
{
|
||||||
|
multi_send_header(MULTI_TELEMETRY_STATUS, 5);
|
||||||
|
|
||||||
|
// Build flags
|
||||||
|
uint8_t flags=0;
|
||||||
|
if (IS_INPUT_SIGNAL_on)
|
||||||
|
flags |= 0x01;
|
||||||
|
if (mode_select==MODE_SERIAL)
|
||||||
|
flags |= 0x02;
|
||||||
|
if (remote_callback != 0)
|
||||||
|
flags |= 0x04;
|
||||||
|
if (!IS_BIND_DONE_on)
|
||||||
|
flags |= 0x08;
|
||||||
|
Serial_write(flags);
|
||||||
|
|
||||||
|
// Version number example: 1.1.6.1
|
||||||
|
Serial_write(VERSION_MAJOR);
|
||||||
|
Serial_write(VERSION_MINOR);
|
||||||
|
Serial_write(VERSION_REVISION);
|
||||||
|
Serial_write(VERSION_PATCH_LEVEL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DSM_TELEMETRY
|
||||||
|
#ifdef MULTI_TELEMETRY
|
||||||
|
void DSM_frame()
|
||||||
|
{
|
||||||
|
if (pkt[0] == 0x80) {
|
||||||
|
multi_send_header(MULTI_TELEMETRY_DSMBIND, 10);
|
||||||
|
for (uint8_t i = 1; i < 11; i++) // 10 byte of DSM bind response
|
||||||
|
Serial_write(pkt[i]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
multi_send_header(MULTI_TELEMETRY_DSM, 17);
|
||||||
|
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||||
|
Serial_write(pkt[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void DSM_frame()
|
||||||
|
{
|
||||||
|
Serial_write(0xAA); // Telemetry packet
|
||||||
|
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||||
|
Serial_write(pkt[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AFHDS2A_FW_TELEMETRY
|
#ifdef AFHDS2A_FW_TELEMETRY
|
||||||
void AFHDSA_short_frame()
|
void AFHDSA_short_frame()
|
||||||
{
|
{
|
||||||
Serial_write(0xAA); // Telemetry packet
|
#if defined MULTI_TELEMETRY
|
||||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
multi_send_header(MULTI_TELEMETRY_AFHDS2A, 29);
|
||||||
Serial_write(pkt[i]);
|
#else
|
||||||
}
|
Serial_write(0xAA); // Telemetry packet
|
||||||
|
#endif
|
||||||
|
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||||
|
Serial_write(pkt[i]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void frskySendStuffed()
|
void frskySendStuffed()
|
||||||
@ -157,7 +222,11 @@ void frsky_link_frame()
|
|||||||
frame[4] = TX_RSSI;
|
frame[4] = TX_RSSI;
|
||||||
}
|
}
|
||||||
frame[5] = frame[6] = frame[7] = frame[8] = 0;
|
frame[5] = frame[6] = frame[7] = frame[8] = 0;
|
||||||
frskySendStuffed();
|
#if defined MULTI_TELEMETRY
|
||||||
|
multi_send_frskyhub();
|
||||||
|
#else
|
||||||
|
frskySendStuffed();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HUB_TELEMETRY
|
#if defined HUB_TELEMETRY
|
||||||
@ -223,7 +292,11 @@ void frsky_user_frame()
|
|||||||
if(!indx)
|
if(!indx)
|
||||||
return;
|
return;
|
||||||
frame[1] = indx;
|
frame[1] = indx;
|
||||||
frskySendStuffed();
|
#if defined MULTI_TELEMETRY
|
||||||
|
multi_send_frskyhub();
|
||||||
|
#else
|
||||||
|
frskySendStuffed();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pass=0;
|
pass=0;
|
||||||
@ -294,36 +367,60 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
|||||||
0x34 0x0A 0xC3 0x56 0xF3
|
0x34 0x0A 0xC3 0x56 0xF3
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void sportSend(uint8_t *p)
|
#ifdef MULTI_TELEMETRY
|
||||||
{
|
void sportSend(uint8_t *p)
|
||||||
uint16_t crc_s = 0;
|
|
||||||
Serial_write(START_STOP);//+9
|
|
||||||
Serial_write(p[0]) ;
|
|
||||||
for (uint8_t i = 1; i < 9; i++)
|
|
||||||
{
|
{
|
||||||
if (i == 8)
|
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
|
||||||
p[i] = 0xff - crc_s;
|
uint16_t crc_s = 0;
|
||||||
|
Serial_write(p[0]) ;
|
||||||
if ((p[i] == START_STOP) || (p[i] == BYTESTUFF))
|
for (uint8_t i = 1; i < 9; i++)
|
||||||
{
|
{
|
||||||
Serial_write(BYTESTUFF);//stuff again
|
if (i == 8)
|
||||||
Serial_write(STUFF_MASK ^ p[i]);
|
p[i] = 0xff - crc_s;
|
||||||
}
|
Serial_write(p[i]);
|
||||||
else
|
|
||||||
Serial_write(p[i]);
|
if (i>0)
|
||||||
|
{
|
||||||
if (i>0)
|
crc_s += p[i]; //0-1FF
|
||||||
{
|
crc_s += crc_s >> 8; //0-100
|
||||||
crc_s += p[i]; //0-1FF
|
crc_s &= 0x00ff;
|
||||||
crc_s += crc_s >> 8; //0-100
|
}
|
||||||
crc_s &= 0x00ff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#else
|
||||||
|
void sportSend(uint8_t *p)
|
||||||
|
{
|
||||||
|
uint16_t crc_s = 0;
|
||||||
|
Serial_write(START_STOP);//+9
|
||||||
|
Serial_write(p[0]) ;
|
||||||
|
for (uint8_t i = 1; i < 9; i++)
|
||||||
|
{
|
||||||
|
if (i == 8)
|
||||||
|
p[i] = 0xff - crc_s;
|
||||||
|
|
||||||
|
if ((p[i] == START_STOP) || (p[i] == BYTESTUFF))
|
||||||
|
{
|
||||||
|
Serial_write(BYTESTUFF);//stuff again
|
||||||
|
Serial_write(STUFF_MASK ^ p[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Serial_write(p[i]);
|
||||||
|
|
||||||
|
if (i>0)
|
||||||
|
{
|
||||||
|
crc_s += p[i]; //0-1FF
|
||||||
|
crc_s += crc_s >> 8; //0-100
|
||||||
|
crc_s &= 0x00ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void sportIdle()
|
void sportIdle()
|
||||||
{
|
{
|
||||||
Serial_write(START_STOP);
|
#if !defined MULTI_TELEMETRY
|
||||||
|
Serial_write(START_STOP);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void sportSendFrame()
|
void sportSendFrame()
|
||||||
@ -468,6 +565,16 @@ void TelemetryUpdate()
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined MULTI_TELEMETRY
|
||||||
|
{
|
||||||
|
uint32_t now = millis();
|
||||||
|
if ((now - lastMulti) > MULTI_TIME) {
|
||||||
|
multi_send_status();
|
||||||
|
lastMulti = now;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SPORT_TELEMETRY
|
#if defined SPORT_TELEMETRY
|
||||||
if (protocol==MODE_FRSKYX)
|
if (protocol==MODE_FRSKYX)
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#undef HUB_TELEMETRY
|
#undef HUB_TELEMETRY
|
||||||
#undef SPORT_TELEMETRY
|
#undef SPORT_TELEMETRY
|
||||||
#undef DSM_TELEMETRY
|
#undef DSM_TELEMETRY
|
||||||
|
#undef MULTI_TELEMETRY
|
||||||
#else
|
#else
|
||||||
#if not defined(BAYANG_NRF24L01_INO)
|
#if not defined(BAYANG_NRF24L01_INO)
|
||||||
#undef BAYANG_HUB_TELEMETRY
|
#undef BAYANG_HUB_TELEMETRY
|
||||||
|
@ -80,8 +80,8 @@
|
|||||||
//The protocols below need a CC2500 to be installed
|
//The protocols below need a CC2500 to be installed
|
||||||
#define SKYARTEC_CC2500_INO
|
#define SKYARTEC_CC2500_INO
|
||||||
|
|
||||||
#define FRSKYD_CC2500_INO
|
|
||||||
#define FRSKYV_CC2500_INO
|
#define FRSKYV_CC2500_INO
|
||||||
|
#define FRSKYD_CC2500_INO
|
||||||
#define FRSKYX_CC2500_INO
|
#define FRSKYX_CC2500_INO
|
||||||
#define SFHSS_CC2500_INO
|
#define SFHSS_CC2500_INO
|
||||||
|
|
||||||
@ -128,6 +128,10 @@
|
|||||||
//For ER9X and ERSKY9X it must be commented. For OpenTX it must be uncommented.
|
//For ER9X and ERSKY9X it must be commented. For OpenTX it must be uncommented.
|
||||||
//#define INVERT_TELEMETRY
|
//#define INVERT_TELEMETRY
|
||||||
|
|
||||||
|
//Uncomment to send also Multi status and wrap other telemetry to allow TX to autodetect the format
|
||||||
|
//Only for newest OpenTX version
|
||||||
|
//#define MULTI_TELEMETRY
|
||||||
|
|
||||||
//Comment a line to disable a protocol telemetry
|
//Comment a line to disable a protocol telemetry
|
||||||
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded
|
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded
|
||||||
#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
|
#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
|
||||||
@ -297,6 +301,7 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
X800
|
X800
|
||||||
H26D
|
H26D
|
||||||
E010
|
E010
|
||||||
|
H26WH
|
||||||
MODE_SHENQI
|
MODE_SHENQI
|
||||||
NONE
|
NONE
|
||||||
MODE_FY326
|
MODE_FY326
|
||||||
|
38
Multiprotocol/generate_hoptable.py
Normal file
38
Multiprotocol/generate_hoptable.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
# this will generate a random frsky compatible
|
||||||
|
# hop table and a random txid
|
||||||
|
#
|
||||||
|
import random
|
||||||
|
|
||||||
|
random.seed()
|
||||||
|
|
||||||
|
#get a random number for the txid
|
||||||
|
txid = random.randint(513, 65000)
|
||||||
|
|
||||||
|
#get random numbers for the hoptable calculation
|
||||||
|
channel_start = random.randint(0, 7)
|
||||||
|
channel_spacing = random.randint(64, 255-64)
|
||||||
|
|
||||||
|
#generate hoptable
|
||||||
|
hoptable = []
|
||||||
|
hop = channel_start
|
||||||
|
for i in range(47):
|
||||||
|
hoptable.append(hop)
|
||||||
|
hop = (hop + channel_spacing) % 235
|
||||||
|
if (hop == 0) or (hop == 0x5A) or (hop == 0xDC):
|
||||||
|
hop = hop + 1
|
||||||
|
|
||||||
|
hoptable_s = (",".join("0x{:02X} ".format(val) for val in hoptable))
|
||||||
|
|
||||||
|
print("#ifndef __HOPTABLE_H__")
|
||||||
|
print("#define __HOPTABLE_H__")
|
||||||
|
print("")
|
||||||
|
print("#define FRSKY_DEFAULT_FSCAL_VALUE 0x00")
|
||||||
|
print("")
|
||||||
|
print("#define FRSYK_TXID (0x%04X)" % (txid))
|
||||||
|
print("")
|
||||||
|
print("//hoptable was generated with start=%d, spacing=%d" % (channel_start, channel_spacing))
|
||||||
|
print("#define FRSKY_HOPTABLE { %s }" % (hoptable_s))
|
||||||
|
print("")
|
||||||
|
print("#endif // __HOPTABLE_H__")
|
1243
Multiprotocol/inter.lua
Normal file
1243
Multiprotocol/inter.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,19 +13,27 @@
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//******************
|
||||||
|
// Version
|
||||||
|
//******************
|
||||||
|
#define VERSION_MAJOR 1
|
||||||
|
#define VERSION_MINOR 1
|
||||||
|
#define VERSION_REVISION 6
|
||||||
|
#define VERSION_PATCH_LEVEL 3
|
||||||
|
|
||||||
//******************
|
//******************
|
||||||
// Protocols max 31 x2
|
// Protocols max 31 x2
|
||||||
//******************
|
//******************
|
||||||
enum PROTOCOLS
|
enum PROTOCOLS
|
||||||
{
|
{
|
||||||
MODE_JOYSWAY = 40, // =>A7105
|
MODE_JOYSWAY = 48, // =>A7105
|
||||||
MODE_WK2x01 = 41, // =>CYRF6936
|
MODE_WK2x01 = 49, // =>CYRF6936
|
||||||
MODE_SKYARTEC = 42, // =>CC2500
|
MODE_SKYARTEC = 50, // =>CC2500
|
||||||
|
|
||||||
MODE_UDI = 44, // =>NRF24L01
|
MODE_FBL100 = 59, // =>NRF24L01
|
||||||
MODE_FBL100 = 45, // =>NRF24L01
|
MODE_UDI = 60, // =>NRF24L01
|
||||||
|
|
||||||
MODE_HM830 = 50, // =>NRF24L01
|
MODE_HM830 = 40, // =>NRF24L01
|
||||||
MODE_CFLIE = 51, // =>NRF24L01
|
MODE_CFLIE = 51, // =>NRF24L01
|
||||||
MODE_H377 = 52, // =>NRF24L01
|
MODE_H377 = 52, // =>NRF24L01
|
||||||
MODE_ESKY150 = 53, // =>NRF24L01
|
MODE_ESKY150 = 53, // =>NRF24L01
|
||||||
@ -158,7 +166,7 @@ enum MJXQ
|
|||||||
X800 = 2,
|
X800 = 2,
|
||||||
H26D = 3,
|
H26D = 3,
|
||||||
E010 = 4,
|
E010 = 4,
|
||||||
H26WH = 5
|
H26WH = 5,
|
||||||
};
|
};
|
||||||
enum FRSKYX
|
enum FRSKYX
|
||||||
{
|
{
|
||||||
@ -177,6 +185,11 @@ enum V2X2
|
|||||||
V2X2 = 0,
|
V2X2 = 0,
|
||||||
JXD506 = 1,
|
JXD506 = 1,
|
||||||
};
|
};
|
||||||
|
enum FY326
|
||||||
|
{
|
||||||
|
FY326 = 0,
|
||||||
|
FY319 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
enum HUBSAN
|
enum HUBSAN
|
||||||
{
|
{
|
||||||
@ -184,15 +197,6 @@ enum HUBSAN
|
|||||||
H301 = 1,
|
H301 = 1,
|
||||||
H501 = 2
|
H501 = 2
|
||||||
};
|
};
|
||||||
enum FY326
|
|
||||||
{
|
|
||||||
FY326 = 0,
|
|
||||||
FY319 = 1
|
|
||||||
};
|
|
||||||
enum V2X2 {
|
|
||||||
FORMAT_V202 = 0,
|
|
||||||
FORMAT_JXD506 = 1,
|
|
||||||
};
|
|
||||||
enum WK2X01
|
enum WK2X01
|
||||||
{
|
{
|
||||||
WK2801 = 0,
|
WK2801 = 0,
|
||||||
@ -211,6 +215,11 @@ enum FBL100
|
|||||||
FBL100 = 0,
|
FBL100 = 0,
|
||||||
HP100 = 1
|
HP100 = 1
|
||||||
};
|
};
|
||||||
|
enum Q303
|
||||||
|
{
|
||||||
|
FORMAT_Q303 = 0,
|
||||||
|
FORMAT_CX35 = 1
|
||||||
|
};
|
||||||
|
|
||||||
#define NONE 0
|
#define NONE 0
|
||||||
#define P_HIGH 1
|
#define P_HIGH 1
|
||||||
@ -228,6 +237,18 @@ struct PPM_Parameters
|
|||||||
uint8_t option;
|
uint8_t option;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Telemetry
|
||||||
|
|
||||||
|
enum MultiPacketTypes {
|
||||||
|
MULTI_TELEMETRY_STATUS = 1,
|
||||||
|
MULTI_TELEMETRY_SPORT = 2,
|
||||||
|
MULTI_TELEMETRY_HUB = 3,
|
||||||
|
MULTI_TELEMETRY_DSM = 4,
|
||||||
|
MULTI_TELEMETRY_DSMBIND = 5,
|
||||||
|
MULTI_TELEMETRY_AFHDS2A = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Macros
|
// Macros
|
||||||
#define NOP() __asm__ __volatile__("nop")
|
#define NOP() __asm__ __volatile__("nop")
|
||||||
|
|
||||||
@ -538,6 +559,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
X800 2
|
X800 2
|
||||||
H26D 3
|
H26D 3
|
||||||
E010 4
|
E010 4
|
||||||
|
H26WH 5
|
||||||
sub_protocol==FRSKYX
|
sub_protocol==FRSKYX
|
||||||
CH_16 0
|
CH_16 0
|
||||||
CH_8 1
|
CH_8 1
|
||||||
@ -570,4 +592,63 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
2047 +125%
|
2047 +125%
|
||||||
Channels bits are concatenated to fit in 22 bytes like in SBUS protocol
|
Channels bits are concatenated to fit in 22 bytes like in SBUS protocol
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
Multiprotocol telemetry definition
|
||||||
|
|
||||||
|
Serial: 100000 Baud 8e2 (same as input)
|
||||||
|
|
||||||
|
TLV Protocol (type, length, value), allows a TX to ignore unknown messages
|
||||||
|
|
||||||
|
Format: header (4 byte) + data (variable)
|
||||||
|
|
||||||
|
[0] = 'M' (0x4d)
|
||||||
|
[1] = 'P' (0x50)
|
||||||
|
|
||||||
|
|
||||||
|
The first byte is deliberatly chosen to be different from other telemetry protocols
|
||||||
|
(e.g. 0xAA for DSM/Multi, 0xAA for FlySky and 0x7e for Frsky) to allow a TX to detect
|
||||||
|
the telemetry format of older versions
|
||||||
|
|
||||||
|
[2] Type (see below)
|
||||||
|
[3] Length (excluding the 4 header bytes)
|
||||||
|
|
||||||
|
[4-xx] data
|
||||||
|
|
||||||
|
|
||||||
|
Type = 0x01 Multimodule Status:
|
||||||
|
[4] Flags
|
||||||
|
0x01 = Input signal detected
|
||||||
|
0x02 = Serial mode enabled
|
||||||
|
0x04 = protocol is valid
|
||||||
|
0x08 = module is in binding mode
|
||||||
|
[5] major
|
||||||
|
[6] minor
|
||||||
|
[7-8] patchlevel
|
||||||
|
version of multi code, should be displayed as major.minor.patchlevel
|
||||||
|
|
||||||
|
|
||||||
|
more information can be added by specifing a longer length of the type, the TX will just ignore these bytes
|
||||||
|
|
||||||
|
|
||||||
|
Type 0x02 Frksy S.port telemetry
|
||||||
|
Type 0x03 Frsky Hub telemetry
|
||||||
|
|
||||||
|
*No* usual frsky byte stuffing and without start/stop byte (0x7e)
|
||||||
|
|
||||||
|
|
||||||
|
Type 0x04 Spektrum telemetry data
|
||||||
|
data[0] RSSI
|
||||||
|
data[1-15] telemetry data
|
||||||
|
|
||||||
|
Type 0x05 DSM bind data
|
||||||
|
data[0-16] DSM bind data
|
||||||
|
|
||||||
|
technically DSM bind data is only 10 bytes but multi send 16
|
||||||
|
like with telemtry, check length field)
|
||||||
|
|
||||||
|
Type 0x06 Flysky AFHDS2 telemetry data
|
||||||
|
length: 29
|
||||||
|
data[0] = RSSI value
|
||||||
|
data[1-28] telemetry data
|
||||||
|
|
||||||
|
*/
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user