mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-12-14 03:23:15 +00:00
Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new
This commit is contained in:
@@ -294,6 +294,8 @@ void A7105_Init(void)
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_SetPower();
|
||||
|
||||
A7105_AdjustLOBaseFreq(A7105_FREQ_OFFSET);
|
||||
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
}
|
||||
#endif
|
||||
@@ -75,7 +75,9 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
else
|
||||
{
|
||||
uint16_t val;
|
||||
switch (sub_protocol) {
|
||||
uint8_t dyntrim = 1;
|
||||
switch (sub_protocol)
|
||||
{
|
||||
case X16_AH:
|
||||
case IRDRONE:
|
||||
packet[0] = 0xA6;
|
||||
@@ -97,22 +99,27 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
if(Servo_AUX4)
|
||||
packet[2] |= BAYANG_FLAG_VIDEO;
|
||||
if(Servo_AUX5)
|
||||
{
|
||||
packet[2] |= BAYANG_FLAG_HEADLESS;
|
||||
dyntrim = 0;
|
||||
}
|
||||
//Flags packet[3]
|
||||
packet[3] = 0x00;
|
||||
if(Servo_AUX6)
|
||||
packet[3] = BAYANG_FLAG_INVERTED;
|
||||
if(Servo_AUX7)
|
||||
packet[3] |= BAYANG_FLAG_TAKE_OFF;
|
||||
dyntrim = 0;
|
||||
if(Servo_AUX8)
|
||||
packet[3] |= BAYANG_FLAG_TAKE_OFF;
|
||||
if(Servo_AUX9)
|
||||
packet[3] |= BAYANG_FLAG_EMG_STOP;
|
||||
//Aileron
|
||||
val = convert_channel_10b(AILERON);
|
||||
packet[4] = (val>>8) + ((val>>2) & 0xFC);
|
||||
packet[4] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[5] = val & 0xFF;
|
||||
//Elevator
|
||||
val = convert_channel_10b(ELEVATOR);
|
||||
packet[6] = (val>>8) + ((val>>2) & 0xFC);
|
||||
packet[6] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[7] = val & 0xFF;
|
||||
//Throttle
|
||||
val = convert_channel_10b(THROTTLE);
|
||||
@@ -120,7 +127,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[9] = val & 0xFF;
|
||||
//Rudder
|
||||
val = convert_channel_10b(RUDDER);
|
||||
packet[10] = (val>>8) + (val>>2 & 0xFC);
|
||||
packet[10] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[11] = val & 0xFF;
|
||||
}
|
||||
switch (sub_protocol)
|
||||
|
||||
@@ -439,4 +439,4 @@ uint16_t initCABELL(void)
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/* **************************
|
||||
* By Midelic on RCGroups *
|
||||
**************************
|
||||
@@ -164,6 +163,30 @@ static void __attribute__((unused)) frskyX_data_frame()
|
||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||
for (uint8_t i=22;i<limit;i++)
|
||||
packet[i]=0;
|
||||
#if defined SPORT_POLLING
|
||||
uint8_t idxs=0;
|
||||
if(ok_to_send)
|
||||
for (uint8_t i=23;i<limit;i++)
|
||||
{//
|
||||
if(sport_index==sport_idx)
|
||||
{//no new data
|
||||
ok_to_send=false;
|
||||
break;
|
||||
}
|
||||
packet[i]=SportData[sport_index];
|
||||
sport_index= (sport_index+1)& (MAX_SPORT_BUFFER-1);
|
||||
idxs++;
|
||||
}
|
||||
packet[22]= idxs;
|
||||
#ifdef SERIAL_DEBUG
|
||||
for(uint8_t i=0;i<idxs;i++)
|
||||
{
|
||||
Serial.print(packet[23+i],HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println(" ");
|
||||
#endif
|
||||
#endif // SPORT_POLLING
|
||||
uint16_t lcrc = crc_x(&packet[3], limit-3);
|
||||
|
||||
packet[limit++]=lcrc>>8;//high byte
|
||||
|
||||
@@ -20,24 +20,48 @@
|
||||
#include "iface_a7105.h"
|
||||
|
||||
enum{
|
||||
// flags going to packet[9] (Normal)
|
||||
HUBSAN_FLAG_VIDEO= 0x01, // record video
|
||||
HUBSAN_FLAG_FLIP = 0x08, // enable flips
|
||||
HUBSAN_FLAG_LED = 0x04 // enable LEDs
|
||||
// flags going to packet[9] (H107)
|
||||
HUBSAN_FLAG_VIDEO= 0x01, // record video
|
||||
HUBSAN_FLAG_FLIP = 0x08, // enable flips
|
||||
HUBSAN_FLAG_LED = 0x04 // enable LEDs
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[9] (Plus series)
|
||||
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
|
||||
// flags going to packet[9] (H107 Plus series)
|
||||
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[13] (Plus series)
|
||||
HUBSAN_FLAG_SNAPSHOT = 0x01,
|
||||
HUBSAN_FLAG_FLIP_PLUS = 0x80,
|
||||
// flags going to packet[9] (H301)
|
||||
FLAG_H301_VIDEO = 0x01,
|
||||
FLAG_H301_STAB = 0x02,
|
||||
FLAG_H301_LED = 0x10,
|
||||
FLAG_H301_RTH = 0x40,
|
||||
};
|
||||
|
||||
uint32_t sessionid,id_data;
|
||||
enum{
|
||||
// flags going to packet[13] (H107 Plus series)
|
||||
HUBSAN_FLAG_SNAPSHOT = 0x01,
|
||||
HUBSAN_FLAG_FLIP_PLUS = 0x80,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[9] (H501S)
|
||||
FLAG_H501_VIDEO = 0x01,
|
||||
FLAG_H501_LED = 0x04,
|
||||
FLAG_H501_RTH = 0x20,
|
||||
FLAG_H501_HEADLESS1 = 0x40,
|
||||
FLAG_H501_GPS_HOLD = 0x80,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[13] (H501S)
|
||||
FLAG_H501_SNAPSHOT = 0x01,
|
||||
FLAG_H501_HEADLESS2 = 0x02,
|
||||
FLAG_H501_ALT_HOLD = 0x08,
|
||||
};
|
||||
|
||||
uint32_t hubsan_id_data;
|
||||
|
||||
enum {
|
||||
BIND_1,
|
||||
@@ -54,7 +78,7 @@ enum {
|
||||
DATA_4,
|
||||
DATA_5,
|
||||
};
|
||||
#define WAIT_WRITE 0x80
|
||||
#define HUBSAN_WAIT_WRITE 0x80
|
||||
|
||||
static void __attribute__((unused)) hubsan_update_crc()
|
||||
{
|
||||
@@ -72,11 +96,11 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
||||
memset(packet, 0, 16);
|
||||
packet[0] = bind_state;
|
||||
packet[1] = channel;
|
||||
packet[2] = (sessionid >> 24) & 0xFF;
|
||||
packet[3] = (sessionid >> 16) & 0xFF;
|
||||
packet[4] = (sessionid >> 8) & 0xFF;
|
||||
packet[5] = (sessionid >> 0) & 0xFF;
|
||||
if(id_data == ID_NORMAL)
|
||||
packet[2] = (MProtocol_id >> 24) & 0xFF;
|
||||
packet[3] = (MProtocol_id >> 16) & 0xFF;
|
||||
packet[4] = (MProtocol_id >> 8) & 0xFF;
|
||||
packet[5] = (MProtocol_id >> 0) & 0xFF;
|
||||
if(hubsan_id_data == ID_NORMAL && sub_protocol != H501)
|
||||
{
|
||||
packet[6] = 0x08;
|
||||
packet[7] = 0xe4;
|
||||
@@ -108,7 +132,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
||||
//ii : aileron observed range: 0x45 - 0xc3 (smaller is right)69-195-50%
|
||||
static void __attribute__((unused)) hubsan_build_packet()
|
||||
{
|
||||
static uint8_t vtx_freq = 0;
|
||||
static uint8_t vtx_freq = 0, h501_packet = 0;
|
||||
memset(packet, 0, 16);
|
||||
if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D)
|
||||
{
|
||||
@@ -127,8 +151,8 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
packet[4] = 0xFF - convert_channel_8b(RUDDER); //Rudder is reversed
|
||||
packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed
|
||||
packet[8] = convert_channel_8b(AILERON); //Aileron
|
||||
if(id_data == ID_NORMAL)
|
||||
{
|
||||
if(hubsan_id_data == ID_NORMAL && sub_protocol==H107)
|
||||
{// H107/L/C/D, H102D
|
||||
if( packet_count < 100)
|
||||
{
|
||||
packet[9] = 0x02 | HUBSAN_FLAG_LED | HUBSAN_FLAG_FLIP; // sends default value for the 100 first packets
|
||||
@@ -150,22 +174,56 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
packet[12] = 0x04;
|
||||
packet[13] = 0x26;
|
||||
packet[14] = 0x79;
|
||||
} else if(sub_protocol==H301)
|
||||
{// H301
|
||||
if( packet_count < 100)
|
||||
{
|
||||
packet[9] = FLAG_H301_STAB; // sends default value for the 100 first packets
|
||||
packet_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[9] = GET_FLAG(Servo_AUX2, FLAG_H301_LED)
|
||||
| GET_FLAG(Servo_AUX3, FLAG_H301_STAB)
|
||||
| GET_FLAG(Servo_AUX4, FLAG_H301_VIDEO)
|
||||
| GET_FLAG(Servo_AUX1, FLAG_H301_RTH);
|
||||
}
|
||||
packet[10] = 0x18; // ?
|
||||
packet[12] = 0x5c; // ?
|
||||
packet[14] = 0xf6; // ?
|
||||
}
|
||||
else
|
||||
{ //ID_PLUS
|
||||
packet[3] = 0x64;
|
||||
packet[5] = 0x64;
|
||||
packet[7] = 0x64;
|
||||
packet[9] = 0x06;
|
||||
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
|
||||
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
|
||||
packet[10]= 0x19;
|
||||
packet[12]= 0x5C; // ghost channel ?
|
||||
packet[13] = 0;
|
||||
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
|
||||
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
|
||||
packet[14]= 0x49; // ghost channel ?
|
||||
{ //ID_PLUS && H501
|
||||
packet[3] = sub_protocol==H501 ? 0x00:0x64;
|
||||
packet[5] = sub_protocol==H501 ? 0x00:0x64;
|
||||
packet[7] = sub_protocol==H501 ? 0x00:0x64;
|
||||
|
||||
if(sub_protocol==H501)
|
||||
{ // H501S
|
||||
packet[9] = 0x02
|
||||
| GET_FLAG(Servo_AUX2, FLAG_H501_LED)
|
||||
| GET_FLAG(Servo_AUX4, FLAG_H501_VIDEO)
|
||||
| GET_FLAG(Servo_AUX1, FLAG_H501_RTH)
|
||||
| GET_FLAG(Servo_AUX7, FLAG_H501_GPS_HOLD)
|
||||
| GET_FLAG(Servo_AUX5, FLAG_H501_HEADLESS1);
|
||||
//packet[10]= 0x1A;
|
||||
packet[13] = GET_FLAG(Servo_AUX6, FLAG_H501_HEADLESS2)
|
||||
| GET_FLAG(Servo_AUX8, FLAG_H501_ALT_HOLD)
|
||||
| GET_FLAG(Servo_AUX3, FLAG_H501_SNAPSHOT);
|
||||
}
|
||||
else
|
||||
{ // H107P/C+/D+
|
||||
packet[9] = 0x06;
|
||||
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
|
||||
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
|
||||
packet[10]= 0x19;
|
||||
packet[12]= 0x5C; // ghost channel ?
|
||||
packet[13] = 0;
|
||||
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
|
||||
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
|
||||
packet[14]= 0x49; // ghost channel ?
|
||||
}
|
||||
if(packet_count < 100)
|
||||
{ // set channels to neutral for first 100 packets
|
||||
packet[2] = 0x80; // throttle neutral is at mid stick on plus series
|
||||
@@ -176,6 +234,21 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
packet[13]= 0x00;
|
||||
packet_count++;
|
||||
}
|
||||
if(sub_protocol==H501)
|
||||
{ // H501S
|
||||
h501_packet++;
|
||||
if(h501_packet == 10)
|
||||
{
|
||||
memset(packet, 0, 16);
|
||||
packet[0] = 0xe8;
|
||||
}
|
||||
else if(h501_packet == 20)
|
||||
{
|
||||
memset(packet, 0, 16);
|
||||
packet[0] = 0xe9;
|
||||
}
|
||||
if(h501_packet >= 20) h501_packet = 0;
|
||||
}
|
||||
}
|
||||
hubsan_update_crc();
|
||||
}
|
||||
@@ -198,41 +271,42 @@ uint16_t ReadHubsan()
|
||||
static uint8_t rfMode=0;
|
||||
#endif
|
||||
static uint8_t txState=0;
|
||||
static uint8_t bind_count=0;
|
||||
uint16_t delay;
|
||||
uint8_t i;
|
||||
|
||||
switch(phase) {
|
||||
switch(phase)
|
||||
{
|
||||
case BIND_1:
|
||||
bind_count++;
|
||||
if(bind_count >= 20)
|
||||
bind_phase++;
|
||||
if(bind_phase >= 20 && sub_protocol != H501)
|
||||
{
|
||||
if(id_data == ID_NORMAL)
|
||||
id_data = ID_PLUS;
|
||||
if(hubsan_id_data == ID_NORMAL)
|
||||
hubsan_id_data = ID_PLUS;
|
||||
else
|
||||
id_data = ID_NORMAL;
|
||||
A7105_WriteID(id_data);
|
||||
bind_count = 0;
|
||||
hubsan_id_data = ID_NORMAL;
|
||||
A7105_WriteID(hubsan_id_data);
|
||||
bind_phase = 0;
|
||||
}
|
||||
case BIND_3:
|
||||
case BIND_5:
|
||||
case BIND_7:
|
||||
hubsan_build_bind_packet(phase == BIND_7 ? 9 : (phase == BIND_5 ? 1 : phase + 1 - BIND_1));
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteData(16, channel);
|
||||
phase |= WAIT_WRITE;
|
||||
phase |= HUBSAN_WAIT_WRITE;
|
||||
return 3000;
|
||||
case BIND_1 | WAIT_WRITE:
|
||||
case BIND_3 | WAIT_WRITE:
|
||||
case BIND_5 | WAIT_WRITE:
|
||||
case BIND_7 | WAIT_WRITE:
|
||||
case BIND_1 | HUBSAN_WAIT_WRITE:
|
||||
case BIND_3 | HUBSAN_WAIT_WRITE:
|
||||
case BIND_5 | HUBSAN_WAIT_WRITE:
|
||||
case BIND_7 | HUBSAN_WAIT_WRITE:
|
||||
//wait for completion
|
||||
for(i = 0; i< 20; i++)
|
||||
if(! (A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_Strobe(A7105_RX);
|
||||
phase &= ~WAIT_WRITE;
|
||||
if(id_data == ID_PLUS)
|
||||
phase &= ~HUBSAN_WAIT_WRITE;
|
||||
if(hubsan_id_data == ID_PLUS)
|
||||
{
|
||||
if(phase == BIND_7 && packet[2] == 9)
|
||||
{
|
||||
@@ -264,7 +338,7 @@ uint16_t ReadHubsan()
|
||||
return 15000; //22.5msec elapsed since last write
|
||||
}
|
||||
A7105_ReadData(16);
|
||||
if(packet[1] == 9 && id_data == ID_NORMAL) {
|
||||
if(packet[1] == 9 && hubsan_id_data == ID_NORMAL) {
|
||||
phase = DATA_1;
|
||||
A7105_WriteReg(A7105_1F_CODE_I, 0x0F);
|
||||
BIND_DONE;
|
||||
@@ -285,7 +359,13 @@ uint16_t ReadHubsan()
|
||||
if( phase == DATA_1)
|
||||
A7105_SetPower(); //Keep transmit power in sync
|
||||
hubsan_build_packet();
|
||||
A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel);
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
uint8_t ch;
|
||||
if((phase == DATA_5 && hubsan_id_data == ID_NORMAL) && sub_protocol == H107)
|
||||
ch = channel + 0x23;
|
||||
else
|
||||
ch = channel;
|
||||
A7105_WriteData(16, ch);
|
||||
if (phase == DATA_5)
|
||||
phase = DATA_1;
|
||||
else
|
||||
@@ -340,20 +420,30 @@ uint16_t ReadHubsan()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initHubsan() {
|
||||
uint16_t initHubsan()
|
||||
{
|
||||
const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82};
|
||||
A7105_Init();
|
||||
|
||||
sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)];
|
||||
channel = allowed_ch[MProtocol_id % sizeof(allowed_ch)];
|
||||
hubsan_id_data=ID_NORMAL;
|
||||
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
phase = BIND_1;
|
||||
if(IS_AUTOBIND_FLAG_on || sub_protocol==H107)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
phase = BIND_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
phase = DATA_1;
|
||||
A7105_WriteID(MProtocol_id);
|
||||
A7105_WriteReg(A7105_1F_CODE_I, 0x0F);
|
||||
}
|
||||
packet_count=0;
|
||||
id_data=ID_NORMAL;
|
||||
#ifdef HUBSAN_HUB_TELEMETRY
|
||||
init_frskyd_link_telemetry();
|
||||
#endif
|
||||
bind_phase=0;
|
||||
#ifdef HUBSAN_HUB_TELEMETRY
|
||||
init_frskyd_link_telemetry();
|
||||
#endif
|
||||
return 10000;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,9 +105,9 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
packet[1] = convert_channel_s8b(RUDDER);
|
||||
packet[4] = 0x40; // rudder does not work well with dyntrim
|
||||
packet[2] = 0x80 ^ convert_channel_s8b(ELEVATOR);
|
||||
packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||
packet[5] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||
packet[3] = convert_channel_s8b(AILERON);
|
||||
packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
||||
packet[6] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
||||
packet[7] = rx_tx_addr[0];
|
||||
packet[8] = rx_tx_addr[1];
|
||||
packet[9] = rx_tx_addr[2];
|
||||
@@ -128,6 +128,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
// Servo_AUX7 AUTOFLIP // X800, X600
|
||||
// Servo_AUX8 PAN
|
||||
// Servo_AUX9 TILT
|
||||
// Servo_AUX10 XTRM // Dyntrim, don't use if high.
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case H26WH:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
1,Flysky,Flysky,V9x9,V6x6,V912,CX20
|
||||
2,Hubsan
|
||||
2,Hubsan,H107,H301,H501
|
||||
3,FrskyD
|
||||
4,Hisky,Hisky,HK310
|
||||
5,V2x2,V2x2,JXD506
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 6
|
||||
#define VERSION_PATCH_LEVEL 35
|
||||
#define VERSION_PATCH_LEVEL 38
|
||||
//******************
|
||||
// Protocols
|
||||
//******************
|
||||
@@ -72,6 +72,12 @@ enum Flysky
|
||||
V912 = 3,
|
||||
CX20 = 4
|
||||
};
|
||||
enum Hubsan
|
||||
{
|
||||
H107 = 0,
|
||||
H301 = 1,
|
||||
H501 = 2,
|
||||
};
|
||||
enum AFHDS2A
|
||||
{
|
||||
PWM_IBUS = 0,
|
||||
@@ -372,6 +378,8 @@ enum FailSafeMode {
|
||||
#define Servo_AUX6 (Servo_AUX & _BV(5))
|
||||
#define Servo_AUX7 (Servo_AUX & _BV(6))
|
||||
#define Servo_AUX8 (Servo_AUX & _BV(7))
|
||||
#define Servo_AUX9 (Servo_data[AUX9 ]>PPM_SWITCH)
|
||||
#define Servo_AUX10 (Servo_data[AUX10]>PPM_SWITCH)
|
||||
|
||||
//************************
|
||||
//*** Power settings ***
|
||||
@@ -555,6 +563,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
V6x6 2
|
||||
V912 3
|
||||
CX20 4
|
||||
sub_protocol==Hubsan
|
||||
H107 0
|
||||
H301 1
|
||||
H501 2
|
||||
sub_protocol==Hisky
|
||||
Hisky 0
|
||||
HK310 1
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
#include "_Config.h"
|
||||
|
||||
//Personal config file
|
||||
#if __has_include("_MyConfig.h")
|
||||
#include "_MyConfig.h"
|
||||
#if __has_include("_MyConfig.h") || defined(USE_MY_CONFIG)
|
||||
#include "_MyConfig.h"
|
||||
#endif
|
||||
|
||||
#include "Pins.h"
|
||||
@@ -194,6 +194,13 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
||||
uint8_t telemetry_link=0;
|
||||
uint8_t telemetry_counter=0;
|
||||
uint8_t telemetry_lost;
|
||||
#ifdef SPORT_POLLING
|
||||
#define MAX_SPORT_BUFFER 64
|
||||
uint8_t SportData[MAX_SPORT_BUFFER];
|
||||
bool ok_to_send = false;
|
||||
uint8_t sport_idx = 0;
|
||||
uint8_t sport_index = 0;
|
||||
#endif
|
||||
#endif // TELEMETRY
|
||||
|
||||
// Callback
|
||||
@@ -670,7 +677,9 @@ inline void tx_resume()
|
||||
{
|
||||
#ifdef TELEMETRY
|
||||
// Resume telemetry by enabling transmitter interrupt
|
||||
#ifndef SPORT_POLLING
|
||||
if(!IS_TX_PAUSE_on)
|
||||
#endif
|
||||
{
|
||||
#ifdef ORANGE_TX
|
||||
cli() ;
|
||||
@@ -1195,8 +1204,9 @@ void modules_reset()
|
||||
USART2_BASE->CR1 |= USART_CR1_PCE_BIT;
|
||||
}
|
||||
usart3_begin(100000,SERIAL_8E2);
|
||||
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable
|
||||
#ifndef SPORT_POLLING
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable
|
||||
#endif
|
||||
USART2_BASE->CR1 &= ~ USART_CR1_TE; //disable transmit
|
||||
#else
|
||||
//ATMEGA328p
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
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/>.
|
||||
*/
|
||||
@@ -338,4 +336,4 @@
|
||||
#define eeprom_read_byte EEPROM.read
|
||||
#else
|
||||
#define EE_ADDR uint8_t*
|
||||
#endif
|
||||
#endif
|
||||
@@ -48,6 +48,18 @@ uint8_t RetrySequence ;
|
||||
// Store for FrskyX telemetry
|
||||
struct t_fx_rx_frame FrskyxRxFrames[4] ;
|
||||
uint8_t NextFxFrameToForward ;
|
||||
#ifdef SPORT_POLLING
|
||||
uint8_t sport_rx_index[28] ;
|
||||
uint8_t ukindex ;
|
||||
uint8_t kindex ;
|
||||
uint8_t TxData[2];
|
||||
uint8_t SportIndexPolling;
|
||||
uint8_t RxData[16] ;
|
||||
volatile uint8_t RxIndex=0 ;
|
||||
uint8_t sport_bytes=0;
|
||||
uint8_t skipped_id;
|
||||
uint8_t rx_counter=0;
|
||||
#endif
|
||||
#endif // SPORT_TELEMETRY
|
||||
|
||||
#if defined HUB_TELEMETRY
|
||||
@@ -433,13 +445,15 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
0x34 0x0A 0xC3 0x56 0xF3
|
||||
|
||||
*/
|
||||
#if defined SPORT_POLLING || defined MULTI_TELEMETRY
|
||||
const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45,
|
||||
0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB,
|
||||
0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71,
|
||||
0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7,
|
||||
0x98, 0x39, 0xBA, 0x1B } ;
|
||||
#endif
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45,
|
||||
0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB,
|
||||
0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71,
|
||||
0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7,
|
||||
0x98, 0x39, 0xBA, 0x1B } ;
|
||||
void sportSend(uint8_t *p)
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
|
||||
@@ -489,8 +503,158 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined SPORT_POLLING
|
||||
uint8_t nextID()
|
||||
{
|
||||
uint8_t i ;
|
||||
uint8_t poll_idx ;
|
||||
if (phase)
|
||||
{
|
||||
poll_idx = 99 ;
|
||||
for ( i = 0 ; i < 28 ; i++ )
|
||||
{
|
||||
if ( sport_rx_index[kindex] )
|
||||
{
|
||||
poll_idx = kindex ;
|
||||
}
|
||||
kindex++ ;
|
||||
if ( kindex>= 28 )
|
||||
{
|
||||
kindex = 0 ;
|
||||
phase = 0 ;
|
||||
break ;
|
||||
}
|
||||
if ( poll_idx != 99 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( poll_idx != 99 )
|
||||
{
|
||||
return poll_idx ;
|
||||
}
|
||||
}
|
||||
if ( phase == 0 )
|
||||
{
|
||||
for ( i = 0 ; i < 28 ; i++ )
|
||||
{
|
||||
if ( sport_rx_index[ukindex] == 0 )
|
||||
{
|
||||
poll_idx = ukindex ;
|
||||
phase = 1 ;
|
||||
}
|
||||
ukindex++;
|
||||
if (ukindex >= 28 )
|
||||
{
|
||||
ukindex = 0 ;
|
||||
}
|
||||
if ( poll_idx != 99 )
|
||||
{
|
||||
return poll_idx ;
|
||||
}
|
||||
}
|
||||
if ( poll_idx == 99 )
|
||||
{
|
||||
phase = 1 ;
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
return poll_idx ;
|
||||
}
|
||||
|
||||
void pollSport()
|
||||
{
|
||||
uint8_t pindex = nextID() ;
|
||||
TxData[0] = START_STOP;
|
||||
TxData[1] = pgm_read_byte_near(&Indices[pindex]) ;
|
||||
if(!telemetry_lost && ((TxData[1] &0x1F)== skipped_id ||TxData[1]==0x98))
|
||||
{//98 ID(RSSI/RxBat and SWR ) and ID's from sport telemetry
|
||||
pindex = nextID() ;
|
||||
TxData[1] = pgm_read_byte_near(&Indices[pindex]);
|
||||
}
|
||||
SportIndexPolling = pindex ;
|
||||
RxIndex = 0;
|
||||
Serial_write(TxData[0]);
|
||||
Serial_write(TxData[1]);
|
||||
}
|
||||
|
||||
bool checkSportPacket()
|
||||
{
|
||||
uint8_t *packet = RxData ;
|
||||
uint16_t crc = 0 ;
|
||||
if ( RxIndex < 8 )
|
||||
return 0 ;
|
||||
for ( uint8_t i = 0 ; i<8 ; i += 1 )
|
||||
{
|
||||
crc += packet[i];
|
||||
crc += crc >> 8;
|
||||
crc &= 0x00ff;
|
||||
}
|
||||
return (crc == 0x00ff) ;
|
||||
}
|
||||
|
||||
uint8_t unstuff()
|
||||
{
|
||||
uint8_t i ;
|
||||
uint8_t j ;
|
||||
j = 0 ;
|
||||
for ( i = 0 ; i < RxIndex ; i += 1 )
|
||||
{
|
||||
if ( RxData[i] == BYTESTUFF )
|
||||
{
|
||||
i += 1 ;
|
||||
RxData[j] = RxData[i] ^ STUFF_MASK ; ;
|
||||
}
|
||||
else
|
||||
RxData[j] = RxData[i] ;
|
||||
j += 1 ;
|
||||
}
|
||||
return j ;
|
||||
}
|
||||
|
||||
void processSportData(uint8_t *p)
|
||||
{
|
||||
|
||||
RxIndex = unstuff() ;
|
||||
uint8_t x=checkSportPacket() ;
|
||||
if (x)
|
||||
{
|
||||
SportData[sport_idx]=0x7E;
|
||||
sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1);
|
||||
SportData[sport_idx]=TxData[1]&0x1F;
|
||||
sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1);
|
||||
|
||||
for(uint8_t i=0;i<(RxIndex-1);i++)
|
||||
{//no crc
|
||||
if(p[i]==START_STOP || p[i]==BYTESTUFF)
|
||||
{//stuff back
|
||||
SportData[sport_idx]=BYTESTUFF;
|
||||
sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1);
|
||||
SportData[sport_idx]=p[i]^STUFF_MASK;
|
||||
}
|
||||
else
|
||||
SportData[sport_idx]=p[i];
|
||||
sport_idx =(sport_idx+1) & (MAX_SPORT_BUFFER-1);
|
||||
}
|
||||
sport_rx_index[SportIndexPolling] = 1 ;
|
||||
ok_to_send=true;
|
||||
RxIndex =0 ;
|
||||
}
|
||||
}
|
||||
|
||||
inline void rx_pause()
|
||||
{
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RXNEIE; //disable rx interrupt on USART3
|
||||
}
|
||||
inline void rx_resume()
|
||||
{
|
||||
USART3_BASE->CR1 |= USART_CR1_RXNEIE; //enable rx interrupt on USART3
|
||||
}
|
||||
#endif//end SPORT_POLLING
|
||||
|
||||
void sportIdle()
|
||||
{
|
||||
#if !defined MULTI_TELEMETRY
|
||||
@@ -500,11 +664,18 @@ void sportIdle()
|
||||
|
||||
void sportSendFrame()
|
||||
{
|
||||
#if defined SPORT_POLLING
|
||||
rx_pause();
|
||||
#endif
|
||||
uint8_t i;
|
||||
sport_counter = (sport_counter + 1) %36;
|
||||
if(telemetry_lost)
|
||||
{
|
||||
sportIdle();
|
||||
#ifdef SPORT_POLLING
|
||||
pollSport();
|
||||
#else
|
||||
sportIdle();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if(sport_counter<6)
|
||||
@@ -542,6 +713,9 @@ void sportSendFrame()
|
||||
for (i=0;i<FRSKY_SPORT_PACKET_SIZE;i++)
|
||||
frame[i]=pktx1[i];
|
||||
sport -= 1 ;
|
||||
#ifdef SPORT_POLLING
|
||||
skipped_id=frame[0];
|
||||
#endif
|
||||
if ( sport )
|
||||
{
|
||||
uint8_t j = sport * FRSKY_SPORT_PACKET_SIZE ;
|
||||
@@ -552,7 +726,11 @@ void sportSendFrame()
|
||||
}
|
||||
else
|
||||
{
|
||||
sportIdle();
|
||||
#ifdef SPORT_POLLING
|
||||
pollSport();
|
||||
#else
|
||||
sportIdle();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -684,6 +862,9 @@ void TelemetryUpdate()
|
||||
uint32_t now = micros();
|
||||
if ((now - last) > SPORT_TIME)
|
||||
{
|
||||
#if defined SPORT_POLLING
|
||||
processSportData(RxData); //process arrived data before polling
|
||||
#endif
|
||||
sportSendFrame();
|
||||
#ifdef STM32_BOARD
|
||||
last=now;
|
||||
@@ -831,21 +1012,39 @@ void TelemetryUpdate()
|
||||
#endif
|
||||
{ // Transmit interrupt
|
||||
#ifdef STM32_BOARD
|
||||
#ifdef SPORT_POLLING
|
||||
if(USART3_BASE->SR & USART_SR_RXNE)
|
||||
{
|
||||
USART3_BASE->SR &= ~USART_SR_RXNE;
|
||||
if (RxIndex < 16 )
|
||||
{
|
||||
if(RxData[0]==TxData[0] && RxData[1]==TxData[1])
|
||||
RxIndex=0;
|
||||
RxData[RxIndex++] = USART3_BASE->DR & 0xFF ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(USART3_BASE->SR & USART_SR_TXE)
|
||||
{
|
||||
USART3_BASE->SR &= ~USART_SR_TXE;
|
||||
#endif
|
||||
if(tx_head!=tx_tail)
|
||||
{
|
||||
if(++tx_tail>=TXBUFFER_SIZE)//head
|
||||
tx_tail=0;
|
||||
#ifdef STM32_BOARD
|
||||
USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit
|
||||
#else
|
||||
UDR0=tx_buff[tx_tail];
|
||||
#endif
|
||||
}
|
||||
if (tx_tail == tx_head)
|
||||
tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
|
||||
if(tx_head!=tx_tail)
|
||||
{
|
||||
if(++tx_tail>=TXBUFFER_SIZE)//head
|
||||
tx_tail=0;
|
||||
#ifdef STM32_BOARD
|
||||
USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit
|
||||
#else
|
||||
UDR0=tx_buff[tx_tail];
|
||||
#endif
|
||||
}
|
||||
if (tx_tail == tx_head)
|
||||
{
|
||||
tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
|
||||
#ifdef SPORT_POLLING
|
||||
rx_resume();
|
||||
#endif
|
||||
}
|
||||
#ifdef STM32_BOARD
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if not defined (SPORT_TELEMETRY) || not defined (STM32_BOARD)
|
||||
#undef SPORT_POLLING
|
||||
#endif
|
||||
|
||||
//Make sure TX is defined correctly
|
||||
#ifndef AILERON
|
||||
#error You must select a correct channel order.
|
||||
@@ -165,4 +169,4 @@
|
||||
#endif
|
||||
#if MAX_PPM_CHANNELS>16
|
||||
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
|
||||
#endif
|
||||
#endif
|
||||
@@ -17,6 +17,14 @@
|
||||
/** Multiprotocol module configuration file ***/
|
||||
/**********************************************/
|
||||
|
||||
/********************/
|
||||
/*** LOCAL CONFIG ***/
|
||||
/********************/
|
||||
//If you know parameters you want for sure to be enabled or disabled which survives in future, you can use a file named "_MyConfig.h".
|
||||
//An example is given within the file named "_MyConfig.h.example" which needs to be renamed if you want to use it.
|
||||
//To enable this config file remove the // from the line below. It's automatically loaded if the file exists for the AVR platform but not STM32...
|
||||
//#define USE_MY_CONFIG
|
||||
|
||||
/*******************/
|
||||
/*** TX SETTINGS ***/
|
||||
/*******************/
|
||||
@@ -77,6 +85,10 @@
|
||||
//#define CC2500_ENABLE_LOW_POWER
|
||||
//#define NRF24L01_ENABLE_LOW_POWER
|
||||
|
||||
//Fine tune of the A7105 LO base frequency
|
||||
// This is required for some A7105 modules and/or RXs with inaccurate crystal oscillator.
|
||||
// The offset is in +/-kHz. Default value is 0.
|
||||
#define A7105_FREQ_OFFSET 0
|
||||
|
||||
/*****************/
|
||||
/*** GLOBAL ID ***/
|
||||
@@ -217,6 +229,12 @@ const int8_t AFHDS2AFailsafe[14]= {
|
||||
//#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
//#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
|
||||
//SPORT_POLLING is an implementation of the same polling routine as XJT module for sport telemetry bidirectional communication.
|
||||
//This is useful for passing sport control frames from Tx to rx(ex: changing Betaflight PID or VTX channels on the fly using LUA scripts with OpentX).
|
||||
//Using this feature on turnigy 9XR_PRO requires uncomment INVERT_TELEMETRY as this TX output on telemetry pin only inverted signal.
|
||||
//!This is a work in progress!
|
||||
//#define SPORT_POLLING
|
||||
|
||||
/****************************/
|
||||
/*** SERIAL MODE SETTINGS ***/
|
||||
/****************************/
|
||||
@@ -272,7 +290,7 @@ const int8_t AFHDS2AFailsafe[14]= {
|
||||
const PPM_Parameters PPM_prot[15]= {
|
||||
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option
|
||||
/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 2 */ {MODE_HUBSAN, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
||||
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
@@ -295,7 +313,9 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
V912
|
||||
CX20
|
||||
MODE_HUBSAN
|
||||
NONE
|
||||
H107
|
||||
H301
|
||||
H501
|
||||
MODE_FRSKYV
|
||||
NONE
|
||||
MODE_FRSKYD
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
/*
|
||||
This file is meant to keep your settings after an upgrade of the multi source.
|
||||
If you know parameters you want for sure to be enabled or disabled in future
|
||||
then just force their values here.
|
||||
To enable a setting use #define <setting name>
|
||||
To disable a setting use #undef <setting name>
|
||||
*/
|
||||
|
||||
//#define FORCE_GLOBAL_ID 0x12345678
|
||||
|
||||
//Force bootloader
|
||||
#define CHECK_FOR_BOOTLOADER
|
||||
|
||||
#if not defined STM32_BOARD
|
||||
// Atmega328p board list of unwanted protocols to fit in flash
|
||||
// Everything here will only apply to Multi Atmega328p boards
|
||||
// Add or remove unwanted protocols to fit in flash
|
||||
#undef AFHDS2A_A7105_INO
|
||||
|
||||
#undef DEVO_CYRF6936_INO
|
||||
|
||||
Reference in New Issue
Block a user