Ajout LUA + CX35 + Suivit + ...

This commit is contained in:
tipouic 2016-12-31 08:15:48 +01:00
parent bd92f5b1c0
commit 5572c47c79
17 changed files with 1812 additions and 182 deletions

View File

@ -51,12 +51,14 @@ void ASSAN_init()
void ASSAN_send_packet()
{
uint16_t temp;
for(uint8_t i=0;i<10;i++)
for(uint8_t i=0;i<8;i++)
{
temp=Servo_data[i]<<3;
packet[2*i]=temp>>8;
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_FlushTx();
NRF24L01_WritePayload(packet, ASSAN_PACKET_SIZE);
@ -87,7 +89,7 @@ uint16_t ASSAN_callback()
//Prepare bind packet
memset(packet,0x05,ASSAN_PACKET_SIZE-5);
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_count=0;
delayMilliseconds(260);
@ -143,7 +145,7 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
uint8_t freq=0,freq2;
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+24]=temp+1;
freq+=temp;
@ -160,7 +162,7 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
freq2+=freq*2-5;
}
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()

View File

@ -11,10 +11,10 @@ if exist .dep (make clean)
md .dep
make
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 Compilation OK.
echo Use MultiOrange.hex to program your OrangeTX module.
echo Use MultiOrange.hex or MultiOrange.bin to program your OrangeTX module.
echo.
)
pause

View File

@ -66,3 +66,18 @@ uint16_t limit_channel_100(uint8_t 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++;
}
}

View File

@ -50,16 +50,6 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
//#######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()
{
//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];
uint16_t idx = ((state -FRSKY_BIND) % 10) * 5;
packet[5] = idx;
packet[6] = get_chan_num(idx++);
packet[7] = get_chan_num(idx++);
packet[8] = get_chan_num(idx++);
packet[9] = get_chan_num(idx++);
packet[10] = get_chan_num(idx++);
packet[6] = hopping_frequency[idx++];
packet[7] = hopping_frequency[idx++];
packet[8] = hopping_frequency[idx++];
packet[9] = hopping_frequency[idx++];
packet[10] = hopping_frequency[idx++];
packet[11] = 0x00;
packet[12] = 0x00;
packet[13] = 0x00;
@ -124,6 +114,7 @@ static void __attribute__((unused)) frsky2way_data_frame()
uint16_t initFrSky_2way()
{
Frsky_init_hop();
if(IS_AUTOBIND_FLAG_on)
{
frsky2way_init(1);
@ -169,7 +160,7 @@ uint16_t ReadFrSky_2way()
{ //telemetry receive
CC2500_SetTxRxMode(RX_EN);
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);
state++;
return 1300;
@ -191,7 +182,7 @@ uint16_t ReadFrSky_2way()
CC2500_SetPower(); // Set tx_power
}
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 )
{
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack

View File

@ -26,29 +26,11 @@ uint8_t ctr;
uint8_t seq_last_sent;
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 )
{
CC2500_Strobe(CC2500_SIDLE);
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()
@ -87,19 +69,14 @@ static void __attribute__((unused)) frskyX_init()
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_Strobe(CC2500_SIDLE);
//
for(uint8_t c=0;c < 47;c++)
for(uint8_t c=0;c < 48;c++)
{//calibrate hop channels
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_0A_CHANNR,hop(c));
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
CC2500_Strobe(CC2500_SCAL);
delayMicroseconds(900);//
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########
}
@ -148,11 +125,11 @@ static void __attribute__((unused)) frskyX_build_bind_packet()
packet[4] = rx_tx_addr[2];
int idx = ((state -FRSKY_BIND) % 10) * 5;
packet[5] = idx;
packet[6] = hop(idx++);
packet[7] = hop(idx++);
packet[8] = hop(idx++);
packet[9] = hop(idx++);
packet[10] = hop(idx++);
packet[6] = hopping_frequency[idx++];
packet[7] = hopping_frequency[idx++];
packet[8] = hopping_frequency[idx++];
packet[9] = hopping_frequency[idx++];
packet[10] = hopping_frequency[idx++];
packet[11] = 0x02;
packet[12] = RX_num;
//
@ -307,16 +284,19 @@ uint16_t ReadFrSkyX()
uint16_t initFrSkyX()
{
set_rx_tx_addr(MProtocol_id_master);
Frsky_init_hop();
while(!chanskip)
chanskip=random(0xfefefefe)%47;
while((chanskip-ctr)%4)
ctr=(ctr+1)%4;
counter_rst=(chanskip-ctr)>>2;
//for test***************
//rx_tx_addr[3]=0xB3;
//rx_tx_addr[2]=0xFD;
//************************
hopping_frequency[47]=0;
frskyX_init();
CC2500_SetTxRxMode(TX_EN);
//

View File

@ -51,9 +51,9 @@ const uint8_t PROGMEM E010_map_txid[][2] = {
{0xC0, 0x44},
{0x2A, 0xFE},
{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] = {
{0x3A, 0x35},
{0x2E, 0x36},
@ -65,11 +65,13 @@ const uint8_t PROGMEM E010_map_rfchan[][2] = {
{0x34, 0x3E},
{0x34, 0x2F},
{0x39, 0x3E},
{0x2E, 0x38},
{0x2E, 0x36},
{0x2E, 0x36},
{0x2E, 0x36},
{0x2E, 0x38},
{0x3A, 0x41},
{0x32, 0x3E} };
{0x32, 0x3E},
{0x33, 0x3F}
};
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
#define MJXQ_PAN_DOWN 0x08
@ -254,7 +256,7 @@ static void __attribute__((unused)) MJXQ_init2()
case E010:
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;
}
break;
@ -277,8 +279,11 @@ static void __attribute__((unused)) MJXQ_initialize_txid()
break;
case E010:
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[2]=(rx_tx_addr[3]%15 == 14)?1:0;
rx_tx_addr[i]=pgm_read_byte_near( &E010_map_txid[rx_tx_addr[3]&0x0F][i] );
if((rx_tx_addr[3]&0x0E) == 0x0E)
rx_tx_addr[2]=(rx_tx_addr[3]&0x01)+1;
else
rx_tx_addr[2]=0;
break;
case WLH08:
rx_tx_addr[0]&=0xF8;

29
Multiprotocol/Multi.txt Normal file
View 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

View File

@ -80,7 +80,7 @@ uint16_t packet_period;
uint8_t packet_count;
uint8_t packet_sent;
uint8_t packet_length;
uint8_t hopping_frequency[23];
uint8_t hopping_frequency[50];
uint8_t *hopping_frequency_ptr;
uint8_t hopping_frequency_no=0;
uint8_t rf_ch_num;
@ -493,7 +493,9 @@ void Update_All()
#endif //ENABLE_PPM
update_channels_aux();
#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();
#endif
update_led_status();
@ -1093,12 +1095,21 @@ void Mprotocol_serial_init()
#if defined(TELEMETRY)
void PPM_Telemetry_serial_init()
{
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 ) ;
#ifdef MULTI_TELEMETRY
Mprotocol_serial_init();
#ifndef ORANGE_TX
#ifndef STM32_BOARD
UCSR0B &= ~(_BV(RXEN0)|_BV(RXCIE0));//rx disable and interrupt
#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

View File

@ -6,38 +6,28 @@
#define Q303_PACKET_SIZE 10
#define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec
#define CX35_PACKET_PERIOD 3000
#define Q303_INITIAL_WAIT 500
#define Q303_RF_BIND_CHANNEL 0x02
#define Q303_NUM_RF_CHANNELS 4
static uint8_t tx_addr[5];
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 {
Q303_BIND,
Q303_DATA
};
// flags going to packet[8]
// flags going to packet[8] (Q303)
#define Q303_FLAG_HIGHRATE 0x03
#define Q303_FLAG_AHOLD 0x40
#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_UP 0x20
#define Q303_FLAG_HEADLESS 0x08
@ -45,6 +35,99 @@ enum {
#define Q303_FLAG_SNAPSHOT 0x10
#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)
{
if(bind) {
@ -53,10 +136,10 @@ static void send_packet(uint8_t bind)
memset(&packet[5], 0, 5);
}
else {
aileron = 1000 - map(Servo_data[AILERON], 1000, 2000, 0, 1000);
elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 0, 1000);
throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000);
rudder = map(Servo_data[RUDDER], 1000, 2000, 0, 1000);
aileron = 1000 - map(Servo_data[AILERON], 1000, 2000, 1000, 0);
elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 1000, 0);
throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000);
rudder = map(Servo_data[RUDDER], 1000, 2000, 0, 1000);
packet[0] = 0x55;
packet[1] = aileron >> 2 ; // 8 bits
@ -67,40 +150,56 @@ static void send_packet(uint8_t bind)
packet[4] = (throttle & 0x3f) << 2 // 6 bits
| (rudder >> 8); // 2 bits
packet[5] = rudder & 0xff; // 8 bits
packet[6] = 0x10; // trim(s) ?
packet[7] = 0x10; // trim(s) ?
packet[8] = 0x03 // high rate (0-3)
| GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD)
| GET_FLAG(Servo_AUX6, Q303_FLAG_RTH);
packet[9] = 0x40 // always set
| GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS)
| GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP)
| GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT)
| GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO);
if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH))
packet[9] |= Q303_FLAG_GIMBAL_DN;
else if(Servo_data[AUX7] > PPM_SWITCH)
packet[9] |= Q303_FLAG_GIMBAL_UP;
// set low rate for first packets
if(bind_counter != 0) {
packet[8] &= ~0x03;
bind_counter--;
switch(sub_protocol) {
case FORMAT_Q303:
packet[6] = 0x10; // trim(s) ?
packet[7] = 0x10; // trim(s) ?
packet[8] = 0x03 // high rate (0-3)
| GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD)
| GET_FLAG(Servo_AUX6, Q303_FLAG_RTH);
packet[9] = 0x40 // always set
| GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS)
| GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP)
| GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT)
| GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO);
if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH))
packet[9] |= Q303_FLAG_GIMBAL_DN;
else if(Servo_data[AUX7] > PPM_SWITCH)
packet[9] |= Q303_FLAG_GIMBAL_UP;
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
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;
}
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? Q303_RF_BIND_CHANNEL : hopping_frequency[current_chan++]);
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()
@ -112,7 +211,7 @@ static uint16_t q303_callback()
memcpy(&tx_addr[1], txid, 4);
XN297_SetTXAddr(tx_addr, 5);
phase = Q303_DATA;
bind_counter = Q303_BIND_COUNT;
packet_counter = 0;
BIND_DONE;
} else {
send_packet(1);
@ -123,20 +222,34 @@ static uint16_t q303_callback()
send_packet(0);
break;
}
return Q303_PACKET_PERIOD;
return packet_period;
}
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));
// memcpy(rf_chans, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].rfchan, sizeof(rf_chans));
offset = txid[0] & 3;
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_SetTxRxMode(TX_EN);
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
if(sub_protocol == FORMAT_CX35) {
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);
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);
@ -149,12 +262,13 @@ static uint16_t q303_init()
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
NRF24L01_Activate(0x73);
NRF24L01_Activate(0x53); // switch bank back
BIND_IN_PROGRESS;
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;
// PROTOCOL_SetBindState(Q303_BIND_COUNT * Q303_PACKET_PERIOD / 1000);
phase = Q303_BIND;
return Q303_INITIAL_WAIT;
}

View File

@ -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
####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
Modele: Known UDI 2.4GHz protocol variants, all using BK2421
* UDI U819 coaxial 3ch helicoper

View File

@ -17,8 +17,13 @@
//**************************
#if defined TELEMETRY
#if defined MULTI_TELEMETRY
#define MULTI_TIME 250 //in ms
uint32_t lastMulti = 0;
#endif
#if defined SPORT_TELEMETRY
#define SPORT_TIME 12000
#define SPORT_TIME 12000 //12ms
#define FRSKY_SPORT_PACKET_SIZE 8
uint32_t last = 0;
uint8_t sport_counter=0;
@ -52,22 +57,82 @@ uint8_t frame[18];
} SerialControl ;
#endif
#ifdef DSM_TELEMETRY
void DSM_frame()
#ifdef MULTI_TELEMETRY
static void multi_send_header(uint8_t type, uint8_t len)
{
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]);
Serial_write('M');
Serial_write('P');
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
#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
void AFHDSA_short_frame()
{
Serial_write(0xAA); // Telemetry packet
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
Serial_write(pkt[i]);
}
void AFHDSA_short_frame()
{
#if defined MULTI_TELEMETRY
multi_send_header(MULTI_TELEMETRY_AFHDS2A, 29);
#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
void frskySendStuffed()
@ -157,7 +222,11 @@ void frsky_link_frame()
frame[4] = TX_RSSI;
}
frame[5] = frame[6] = frame[7] = frame[8] = 0;
frskySendStuffed();
#if defined MULTI_TELEMETRY
multi_send_frskyhub();
#else
frskySendStuffed();
#endif
}
#if defined HUB_TELEMETRY
@ -223,7 +292,11 @@ void frsky_user_frame()
if(!indx)
return;
frame[1] = indx;
frskySendStuffed();
#if defined MULTI_TELEMETRY
multi_send_frskyhub();
#else
frskySendStuffed();
#endif
}
else
pass=0;
@ -294,36 +367,60 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
0x34 0x0A 0xC3 0x56 0xF3
*/
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++)
#ifdef MULTI_TELEMETRY
void sportSend(uint8_t *p)
{
if (i == 8)
p[i] = 0xff - crc_s;
if ((p[i] == START_STOP) || (p[i] == BYTESTUFF))
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
uint16_t crc_s = 0;
Serial_write(p[0]) ;
for (uint8_t i = 1; i < 9; i++)
{
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;
if (i == 8)
p[i] = 0xff - crc_s;
Serial_write(p[i]);
if (i>0)
{
crc_s += p[i]; //0-1FF
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()
{
Serial_write(START_STOP);
#if !defined MULTI_TELEMETRY
Serial_write(START_STOP);
#endif
}
void sportSendFrame()
@ -468,6 +565,16 @@ void TelemetryUpdate()
return ;
}
#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 (protocol==MODE_FRSKYX)

View File

@ -92,6 +92,7 @@
#undef HUB_TELEMETRY
#undef SPORT_TELEMETRY
#undef DSM_TELEMETRY
#undef MULTI_TELEMETRY
#else
#if not defined(BAYANG_NRF24L01_INO)
#undef BAYANG_HUB_TELEMETRY

View File

@ -80,8 +80,8 @@
//The protocols below need a CC2500 to be installed
#define SKYARTEC_CC2500_INO
#define FRSKYD_CC2500_INO
#define FRSKYV_CC2500_INO
#define FRSKYD_CC2500_INO
#define FRSKYX_CC2500_INO
#define SFHSS_CC2500_INO
@ -128,6 +128,10 @@
//For ER9X and ERSKY9X it must be commented. For OpenTX it must be uncommented.
//#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
#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
@ -297,6 +301,7 @@ const PPM_Parameters PPM_prot[15]= {
X800
H26D
E010
H26WH
MODE_SHENQI
NONE
MODE_FY326

View 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

File diff suppressed because it is too large Load Diff

View File

@ -13,19 +13,27 @@
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
//******************
enum PROTOCOLS
{
MODE_JOYSWAY = 40, // =>A7105
MODE_WK2x01 = 41, // =>CYRF6936
MODE_SKYARTEC = 42, // =>CC2500
MODE_JOYSWAY = 48, // =>A7105
MODE_WK2x01 = 49, // =>CYRF6936
MODE_SKYARTEC = 50, // =>CC2500
MODE_UDI = 44, // =>NRF24L01
MODE_FBL100 = 45, // =>NRF24L01
MODE_FBL100 = 59, // =>NRF24L01
MODE_UDI = 60, // =>NRF24L01
MODE_HM830 = 50, // =>NRF24L01
MODE_HM830 = 40, // =>NRF24L01
MODE_CFLIE = 51, // =>NRF24L01
MODE_H377 = 52, // =>NRF24L01
MODE_ESKY150 = 53, // =>NRF24L01
@ -158,7 +166,7 @@ enum MJXQ
X800 = 2,
H26D = 3,
E010 = 4,
H26WH = 5
H26WH = 5,
};
enum FRSKYX
{
@ -177,6 +185,11 @@ enum V2X2
V2X2 = 0,
JXD506 = 1,
};
enum FY326
{
FY326 = 0,
FY319 = 1,
};
enum HUBSAN
{
@ -184,15 +197,6 @@ enum HUBSAN
H301 = 1,
H501 = 2
};
enum FY326
{
FY326 = 0,
FY319 = 1
};
enum V2X2 {
FORMAT_V202 = 0,
FORMAT_JXD506 = 1,
};
enum WK2X01
{
WK2801 = 0,
@ -211,6 +215,11 @@ enum FBL100
FBL100 = 0,
HP100 = 1
};
enum Q303
{
FORMAT_Q303 = 0,
FORMAT_CX35 = 1
};
#define NONE 0
#define P_HIGH 1
@ -228,6 +237,18 @@ struct PPM_Parameters
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
#define NOP() __asm__ __volatile__("nop")
@ -538,6 +559,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
X800 2
H26D 3
E010 4
H26WH 5
sub_protocol==FRSKYX
CH_16 0
CH_8 1
@ -570,4 +592,63 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
2047 +125%
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.