Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new

This commit is contained in:
Ben Lye
2017-12-01 17:21:41 +00:00
16 changed files with 522 additions and 119 deletions

View File

@@ -294,6 +294,8 @@ void A7105_Init(void)
A7105_SetTxRxMode(TX_EN);
A7105_SetPower();
A7105_AdjustLOBaseFreq(A7105_FREQ_OFFSET);
A7105_Strobe(A7105_STANDBY);
}
#endif

View File

@@ -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)

View File

@@ -439,4 +439,4 @@ uint16_t initCABELL(void)
return packet_period;
}
#endif
#endif

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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