mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-12-14 03:23:15 +00:00
Tons of updates
This commit is contained in:
@@ -179,12 +179,26 @@ static void AFHDS2A_build_packet(uint8_t type)
|
||||
packet[0] = 0x56;
|
||||
for(uint8_t ch=0; ch<14; ch++)
|
||||
{
|
||||
/*if((Model.limits[ch].flags & CH_FAILSAFE_EN))
|
||||
#ifdef AFHDS2A_FAILSAFE
|
||||
int8_t failsafe = AFHDS2AFailsafe[ch];
|
||||
//
|
||||
if(failsafe != -1)
|
||||
{
|
||||
packet[9 + ch*2] = Servo_data[CH_AETR[ch]] & 0xff;
|
||||
packet[10+ ch*2] = (Servo_data[CH_AETR[ch]] >> 8) & 0xff;
|
||||
//
|
||||
if (failsafe > AFHDS2AFailsafeMAX)
|
||||
failsafe = AFHDS2AFailsafeMAX;
|
||||
//
|
||||
if (failsafe < AFHDS2AFailsafeMIN)
|
||||
failsafe = AFHDS2AFailsafeMIN;
|
||||
//
|
||||
double scale = (float)failsafe/(float)100;
|
||||
int16_t failsafeMicros = 1500 + ((float)512 * scale);
|
||||
//
|
||||
packet[9 + ch*2] = failsafeMicros & 0xff;
|
||||
packet[10+ ch*2] = ( failsafeMicros >> 8) & 0xff;
|
||||
}
|
||||
else*/
|
||||
else
|
||||
#endif
|
||||
{
|
||||
packet[9 + ch*2] = 0xff;
|
||||
packet[10+ ch*2] = 0xff;
|
||||
|
||||
@@ -25,19 +25,22 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
#define BAYANG_PACKET_SIZE 15
|
||||
#define BAYANG_RF_NUM_CHANNELS 4
|
||||
#define BAYANG_RF_BIND_CHANNEL 0
|
||||
#define BAYANG_RF_BIND_CHANNEL_X16_AH 10
|
||||
#define BAYANG_ADDRESS_LENGTH 5
|
||||
|
||||
enum BAYANG_FLAGS {
|
||||
// flags going to packet[2]
|
||||
BAYANG_FLAG_RTH = 0x01,
|
||||
BAYANG_FLAG_HEADLESS = 0x02,
|
||||
BAYANG_FLAG_FLIP = 0x08,
|
||||
BAYANG_FLAG_VIDEO = 0x10,
|
||||
BAYANG_FLAG_PICTURE = 0x20,
|
||||
// flags going to packet[3]
|
||||
BAYANG_FLAG_INVERTED = 0x80 // inverted flight on Floureon H101
|
||||
// flags going to packet[2]
|
||||
BAYANG_FLAG_RTH = 0x01,
|
||||
BAYANG_FLAG_HEADLESS = 0x02,
|
||||
BAYANG_FLAG_FLIP = 0x08,
|
||||
BAYANG_FLAG_VIDEO = 0x10,
|
||||
BAYANG_FLAG_PICTURE = 0x20,
|
||||
// flags going to packet[3]
|
||||
BAYANG_FLAG_INVERTED = 0x80, // inverted flight on Floureon H101
|
||||
BAYANG_FLAG_TAKE_OFF = 0x20, // take off / landing on X16 AH
|
||||
};
|
||||
|
||||
uint8_t bayang_bind_chan;
|
||||
static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
{
|
||||
uint8_t i;
|
||||
@@ -53,13 +56,29 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[i+1]=rx_tx_addr[i];
|
||||
for(i=0;i<4;i++)
|
||||
packet[i+6]=hopping_frequency[i];
|
||||
packet[10] = rx_tx_addr[0]; // txid[0]
|
||||
packet[11] = rx_tx_addr[1]; // txid[1]
|
||||
switch (sub_protocol)
|
||||
{
|
||||
case X16_AH:
|
||||
packet[10] = 0x00;
|
||||
packet[11] = 0x00;
|
||||
break;
|
||||
default:
|
||||
packet[10] = rx_tx_addr[0]; // txid[0]
|
||||
packet[11] = rx_tx_addr[1]; // txid[1]
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t val;
|
||||
packet[0] = 0xA5;
|
||||
switch (sub_protocol) {
|
||||
case X16_AH:
|
||||
packet[0] = 0xA6;
|
||||
break;
|
||||
default:
|
||||
packet[0] = 0xA5;
|
||||
break;
|
||||
}
|
||||
packet[1] = 0xFA; // normal mode is 0xf7, expert 0xfa
|
||||
|
||||
//Flags packet[2]
|
||||
@@ -78,7 +97,8 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[3] = 0x00;
|
||||
if(Servo_AUX6)
|
||||
packet[3] = BAYANG_FLAG_INVERTED;
|
||||
|
||||
if(Servo_AUX7)
|
||||
packet[3] |= BAYANG_FLAG_TAKE_OFF;
|
||||
//Aileron
|
||||
val = convert_channel_10b(AILERON);
|
||||
packet[4] = (val>>8) + ((val>>2) & 0xFC);
|
||||
@@ -96,13 +116,26 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[10] = (val>>8) + (val>>2 & 0xFC);
|
||||
packet[11] = val & 0xFF;
|
||||
}
|
||||
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||
packet[13] = sub_protocol==H8S3D?0x34:0x0A;
|
||||
switch (sub_protocol)
|
||||
{
|
||||
case H8S3D:
|
||||
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||
packet[13] = 0x34;
|
||||
break;
|
||||
case X16_AH:
|
||||
packet[12] = 0;
|
||||
packet[13] = 0;
|
||||
break;
|
||||
default:
|
||||
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||
packet[13] = 0x0A;
|
||||
break;
|
||||
}
|
||||
packet[14] = 0;
|
||||
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
||||
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
||||
packet[14] += packet[i];
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? BAYANG_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? bayang_bind_chan:hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
@@ -111,17 +144,17 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
|
||||
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
if (option)
|
||||
if (option)
|
||||
{ // switch radio to rx as soon as packet is sent
|
||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
||||
}
|
||||
#endif
|
||||
@@ -170,16 +203,16 @@ static void __attribute__((unused)) BAYANG_init()
|
||||
|
||||
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_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
uint16_t BAYANG_callback()
|
||||
@@ -250,10 +283,18 @@ uint16_t initBAYANG(void)
|
||||
BAYANG_initialize_txid();
|
||||
BAYANG_init();
|
||||
packet_count=0;
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
init_frskyd_link_telemetry();
|
||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
||||
#endif
|
||||
switch (sub_protocol) {
|
||||
case X16_AH:
|
||||
bayang_bind_chan = BAYANG_RF_BIND_CHANNEL_X16_AH;
|
||||
break;
|
||||
default:
|
||||
bayang_bind_chan = BAYANG_RF_BIND_CHANNEL;
|
||||
break;
|
||||
}
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
init_frskyd_link_telemetry();
|
||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
||||
#endif
|
||||
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
|
||||
302
Multiprotocol/FrSkyX_cc2500.ino
Normal file
302
Multiprotocol/FrSkyX_cc2500.ino
Normal file
@@ -0,0 +1,302 @@
|
||||
|
||||
/* **************************
|
||||
* By Midelic on RCGroups *
|
||||
**************************
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
uint8_t chanskip;
|
||||
//uint8_t seq_last_sent;
|
||||
//uint8_t seq_last_rcvd;
|
||||
|
||||
uint8_t FrX_send_seq ;
|
||||
uint8_t FrX_receive_seq ;
|
||||
|
||||
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, hopping_frequency[ch]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_init()
|
||||
{
|
||||
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
|
||||
//
|
||||
for(uint8_t c=0;c < 48;c++)
|
||||
{//calibrate hop channels
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);//
|
||||
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
//#######END INIT########
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) initialize_data(uint8_t adr)
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x8);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, adr ? 0x03 : rx_tx_addr[3]);
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1,0x05);
|
||||
}
|
||||
|
||||
//**CRC**
|
||||
const uint16_t PROGMEM CRC_Short[]={
|
||||
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
|
||||
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 };
|
||||
static uint16_t CRCTable(uint8_t val)
|
||||
{
|
||||
uint16_t word ;
|
||||
word = pgm_read_word(&CRC_Short[val&0x0F]) ;
|
||||
val /= 16 ;
|
||||
return word ^ (0x1081 * val) ;
|
||||
}
|
||||
static uint16_t __attribute__((unused)) crc_x(uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
for(uint8_t i=0; i < len; i++)
|
||||
crc = (crc<<8) ^ CRCTable((uint8_t)(crc>>8) ^ *data++);
|
||||
return crc;
|
||||
}
|
||||
|
||||
// 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182
|
||||
//64=860,1024=1500,1984=2140//Taranis 125%
|
||||
|
||||
static uint16_t __attribute__((unused)) scaleForPXX( uint8_t i )
|
||||
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
|
||||
return (uint16_t)(((Servo_data[i]-servo_min_125)*3)>>1)+64;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_build_bind_packet()
|
||||
{
|
||||
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
|
||||
packet[1] = 0x03;
|
||||
packet[2] = 0x01;
|
||||
//
|
||||
packet[3] = rx_tx_addr[3];
|
||||
packet[4] = rx_tx_addr[2];
|
||||
int idx = ((state -FRSKY_BIND) % 10) * 5;
|
||||
packet[5] = 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;
|
||||
//
|
||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||
memset(&packet[13], 0, limit - 13);
|
||||
uint16_t lcrc = crc_x(&packet[3], limit-3);
|
||||
//
|
||||
packet[limit++] = lcrc >> 8;
|
||||
packet[limit] = lcrc;
|
||||
//
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_data_frame()
|
||||
{
|
||||
//0x1D 0xB3 0xFD 0x02 0x56 0x07 0x15 0x00 0x00 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x96 0x12
|
||||
//
|
||||
static uint8_t lpass;
|
||||
uint16_t chan_0 ;
|
||||
uint16_t chan_1 ;
|
||||
uint8_t startChan = 0;
|
||||
//
|
||||
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
|
||||
packet[1] = rx_tx_addr[3];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = 0x02;
|
||||
//
|
||||
packet[4] = (chanskip<<6)|hopping_frequency_no;
|
||||
packet[5] = chanskip>>2;
|
||||
packet[6] = RX_num;
|
||||
//packet[7] = FLAGS 00 - standard packet
|
||||
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
||||
//20 - range check packet
|
||||
packet[7] = 0;
|
||||
packet[8] = 0;
|
||||
//
|
||||
if ( lpass & 1 )
|
||||
startChan += 8 ;
|
||||
|
||||
for(uint8_t i = 0; i <12 ; i+=3)
|
||||
{//12 bytes
|
||||
chan_0 = scaleForPXX(startChan);
|
||||
if(lpass & 1 )
|
||||
chan_0+=2048;
|
||||
startChan+=1;
|
||||
//
|
||||
chan_1 = scaleForPXX(startChan);
|
||||
if(lpass & 1 )
|
||||
chan_1+= 2048;
|
||||
startChan+=1;
|
||||
//
|
||||
packet[9+i] = lowByte(chan_0);//3 bytes*4
|
||||
packet[9+i+1]=(((chan_0>>8) & 0x0F)|(chan_1 << 4));
|
||||
packet[9+i+2]=chan_1>>4;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
|
||||
=======
|
||||
packet[21] = seq_last_sent << 4 | seq_last_rcvd;//8 at start
|
||||
if (seq_last_sent < 0x08 && seq_last_rcvd < 8)
|
||||
seq_last_sent = (seq_last_sent + 1) % 4;
|
||||
else if (seq_last_rcvd == 0x00)
|
||||
seq_last_sent = 1;
|
||||
else
|
||||
seq_last_rcvd = 8;
|
||||
>>>>>>> dd3f8b4717c03dc2f86701191dc8b265d4706751
|
||||
|
||||
if(sub_protocol & 1 )// in X8 mode send only 8ch every 9ms
|
||||
lpass = 0 ;
|
||||
else
|
||||
lpass += 1 ;
|
||||
|
||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||
for (uint8_t i=22;i<limit;i++)
|
||||
packet[i]=0;
|
||||
uint16_t lcrc = crc_x(&packet[3], limit-3);
|
||||
|
||||
packet[limit++]=lcrc>>8;//high byte
|
||||
packet[limit]=lcrc;//low byte
|
||||
}
|
||||
|
||||
uint16_t ReadFrSkyX()
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
default:
|
||||
set_start(47);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
//
|
||||
frskyX_build_bind_packet();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteData(packet, packet[0]+1);
|
||||
if(IS_BIND_DONE_on)
|
||||
state = FRSKY_BIND_DONE;
|
||||
else
|
||||
state++;
|
||||
return 9000;
|
||||
case FRSKY_BIND_DONE:
|
||||
initialize_data(0);
|
||||
hopping_frequency_no=0;
|
||||
BIND_DONE;
|
||||
state++;
|
||||
break;
|
||||
case FRSKY_DATA1:
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
set_start(hopping_frequency_no);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
hopping_frequency_no = (hopping_frequency_no+chanskip)%47;
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteData(packet, packet[0]+1);
|
||||
//
|
||||
// frskyX_data_frame();
|
||||
state++;
|
||||
return 5200;
|
||||
case FRSKY_DATA2:
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
state++;
|
||||
return 200;
|
||||
case FRSKY_DATA3:
|
||||
CC2500_Strobe(CC2500_SRX);
|
||||
state++;
|
||||
return 3100;
|
||||
case FRSKY_DATA4:
|
||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
||||
{
|
||||
packet_count=0;
|
||||
CC2500_ReadData(pkt, len);
|
||||
#if defined TELEMETRY
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
||||
//parse telemetry packets here
|
||||
//The same telemetry function used by FrSky(D8).
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_count++;
|
||||
// restart sequence on missed packet - might need count or timeout instead of one missed
|
||||
if(packet_count>100)
|
||||
{//~1sec
|
||||
// seq_last_sent = 0;
|
||||
// seq_last_rcvd = 8;
|
||||
FrX_send_seq = 0x08 ;
|
||||
// FrX_receive_seq = 0 ;
|
||||
packet_count=0;
|
||||
#if defined TELEMETRY
|
||||
telemetry_lost=1;
|
||||
#endif
|
||||
}
|
||||
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
|
||||
}
|
||||
frskyX_data_frame();
|
||||
if ( FrX_send_seq != 0x08 )
|
||||
{
|
||||
FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
|
||||
}
|
||||
state = FRSKY_DATA1;
|
||||
return 500;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t initFrSkyX()
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
Frsky_init_hop();
|
||||
packet_count=0;
|
||||
while(!chanskip)
|
||||
chanskip=random(0xfefefefe)%47;
|
||||
|
||||
//for test***************
|
||||
//rx_tx_addr[3]=0xB3;
|
||||
//rx_tx_addr[2]=0xFD;
|
||||
//************************
|
||||
frskyX_init();
|
||||
//
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
state = FRSKY_BIND;
|
||||
initialize_data(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FRSKY_DATA1;
|
||||
initialize_data(0);
|
||||
}
|
||||
// seq_last_sent = 0;
|
||||
// seq_last_rcvd = 8;
|
||||
FrX_send_seq = 0x08 ;
|
||||
FrX_receive_seq = 0 ;
|
||||
return 10000;
|
||||
}
|
||||
#endif
|
||||
@@ -11,7 +11,7 @@
|
||||
11,SLT,SLT,VISTA
|
||||
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
||||
13,CG023,CG023,YD829,H8_3D
|
||||
14,Bayang,Bayang,H8S3D
|
||||
14,Bayang,Bayang,H8S3D,X16_AH
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||
16,ESky
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 6
|
||||
#define VERSION_PATCH_LEVEL 21
|
||||
#define VERSION_PATCH_LEVEL 23
|
||||
//******************
|
||||
// Protocols
|
||||
//******************
|
||||
@@ -136,7 +136,8 @@ enum CG023
|
||||
enum BAYANG
|
||||
{
|
||||
BAYANG = 0,
|
||||
H8S3D = 1
|
||||
H8S3D = 1,
|
||||
X16_AH = 2,
|
||||
};
|
||||
enum MT99XX
|
||||
{
|
||||
@@ -393,7 +394,7 @@ enum CC2500_POWER
|
||||
CC2500_POWER_16 = 0xFE, // 0dbm
|
||||
CC2500_POWER_17 = 0xFF // +1dbm
|
||||
};
|
||||
#define CC2500_HIGH_POWER CC2500_POWER_16
|
||||
#define CC2500_HIGH_POWER CC2500_POWER_17
|
||||
#define CC2500_LOW_POWER CC2500_POWER_13
|
||||
#define CC2500_RANGE_POWER CC2500_POWER_1
|
||||
#define CC2500_BIND_POWER CC2500_POWER_1
|
||||
@@ -537,6 +538,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==BAYANG
|
||||
BAYANG 0
|
||||
H8S3D 1
|
||||
X16_AH 2
|
||||
sub_protocol==MT99XX
|
||||
MT99 0
|
||||
H7 1
|
||||
@@ -678,4 +680,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
data[0] = RSSI value
|
||||
data[1-28] telemetry data
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <avr/pgmspace.h>
|
||||
//#define DEBUG_TX
|
||||
//#define USE_MY_CONFIG
|
||||
#ifdef ARDUINO_AVR_XMEGA32D4
|
||||
#include "MultiOrange.h"
|
||||
#endif
|
||||
#include "Multiprotocol.h"
|
||||
|
||||
//Multiprotocol module configuration file
|
||||
@@ -106,6 +109,18 @@ uint8_t RX_num;
|
||||
uint8_t calData[48];
|
||||
#endif
|
||||
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
uint8_t BootTimer ;
|
||||
uint8_t BootState ;
|
||||
uint8_t NotBootChecking ;
|
||||
uint8_t BootCount ;
|
||||
|
||||
#define BOOT_WAIT_30_IDLE 0
|
||||
#define BOOT_WAIT_30_DATA 1
|
||||
#define BOOT_WAIT_20 2
|
||||
#define BOOT_READY 3
|
||||
#endif
|
||||
|
||||
//Channel mapping for protocols
|
||||
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10};
|
||||
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
|
||||
@@ -154,7 +169,7 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
||||
uint8_t pktt[MAX_PKT];//telemetry receiving packets
|
||||
#ifdef BASH_SERIAL
|
||||
// For bit-bashed serial output
|
||||
#define TXBUFFER_SIZE 128
|
||||
#define TXBUFFER_SIZE 192
|
||||
volatile struct t_serial_bash
|
||||
{
|
||||
uint8_t head ;
|
||||
@@ -164,7 +179,7 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
||||
uint8_t speed ;
|
||||
} SerialControl ;
|
||||
#else
|
||||
#define TXBUFFER_SIZE 64
|
||||
#define TXBUFFER_SIZE 96
|
||||
volatile uint8_t tx_buff[TXBUFFER_SIZE];
|
||||
volatile uint8_t tx_head=0;
|
||||
volatile uint8_t tx_tail=0;
|
||||
@@ -392,7 +407,11 @@ void setup()
|
||||
protocol=0;
|
||||
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
|
||||
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
|
||||
Mprotocol_serial_init(); // Configure serial and enable RX interrupt
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
Mprotocol_serial_init(1); // Configure serial and enable RX interrupt
|
||||
#else
|
||||
Mprotocol_serial_init(); // Configure serial and enable RX interrupt
|
||||
#endif
|
||||
#endif //ENABLE_SERIAL
|
||||
}
|
||||
servo_mid=servo_min_100+servo_max_100; //In fact 2* mid_value
|
||||
@@ -485,6 +504,11 @@ void loop()
|
||||
uint8_t Update_All()
|
||||
{
|
||||
#ifdef ENABLE_SERIAL
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
if ( (mode_select==MODE_SERIAL) && (NotBootChecking == 0) )
|
||||
pollBoot() ;
|
||||
else
|
||||
#endif
|
||||
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
|
||||
{
|
||||
update_serial_data(); // Update protocol and data
|
||||
@@ -1093,7 +1117,11 @@ void modules_reset()
|
||||
prev_power=0xFD; // unused power value
|
||||
}
|
||||
|
||||
void Mprotocol_serial_init()
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
void Mprotocol_serial_init( uint8_t boot )
|
||||
#else
|
||||
void Mprotocol_serial_init()
|
||||
#endif
|
||||
{
|
||||
#ifdef ORANGE_TX
|
||||
PORTC.OUTSET = 0x08 ;
|
||||
@@ -1103,18 +1131,41 @@ void Mprotocol_serial_init()
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCC) | 0x11 ;
|
||||
USARTC0.CTRLC = 0x2B ;
|
||||
UDR0 ;
|
||||
#ifdef INVERT_SERIAL
|
||||
PORTC.PIN3CTRL |= 0x40 ;
|
||||
#endif
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
if ( boot )
|
||||
{
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.BAUDCTRLA = 33 ; // 57600
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xC0) ;
|
||||
USARTC0.CTRLC = 0x03 ; // 8 bit, no parity, 1 stop
|
||||
USARTC0.CTRLB = 0x18 ; // Enable Tx and Rx
|
||||
PORTC.PIN3CTRL &= ~0x40 ;
|
||||
}
|
||||
#endif // CHECK_FOR_BOOTLOADER
|
||||
#elif defined STM32_BOARD
|
||||
usart2_begin(100000,SERIAL_8E2);
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
if ( boot )
|
||||
{
|
||||
usart2_begin(57600,SERIAL_8N1);
|
||||
USART2_BASE->CR1 &= ~USART_CR1_RXNEIE ;
|
||||
(void)UDR0 ;
|
||||
}
|
||||
else
|
||||
#endif // CHECK_FOR_BOOTLOADER
|
||||
{
|
||||
usart2_begin(100000,SERIAL_8E2);
|
||||
USART2_BASE->CR1 |= USART_CR1_PCE_BIT;
|
||||
}
|
||||
usart3_begin(100000,SERIAL_8E2);
|
||||
USART2_BASE->CR1 |= USART_CR1_PCE_BIT;
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE;//disable
|
||||
USART2_BASE->CR1 &= ~ USART_CR1_TE;//disable transmit
|
||||
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable
|
||||
USART2_BASE->CR1 &= ~ USART_CR1_TE; //disable transmit
|
||||
#else
|
||||
//ATMEGA328p
|
||||
#include <util/setbaud.h>
|
||||
@@ -1123,7 +1174,7 @@ void Mprotocol_serial_init()
|
||||
UCSR0A = 0 ; // Clear X2 bit
|
||||
//Set frame format to 8 data bits, even parity, 2 stop bits
|
||||
UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00);
|
||||
while ( UCSR0A & (1 << RXC0) )//flush receive buffer
|
||||
while ( UCSR0A & (1 << RXC0) ) //flush receive buffer
|
||||
UDR0;
|
||||
//enable reception and RC complete interrupt
|
||||
UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt
|
||||
@@ -1132,9 +1183,130 @@ void Mprotocol_serial_init()
|
||||
initTXSerial( SPEED_100K ) ;
|
||||
#endif //TELEMETRY
|
||||
#endif //DEBUG_TX
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
if ( boot )
|
||||
{
|
||||
UBRR0H = 0;
|
||||
UBRR0L = 33; // 57600
|
||||
UCSR0C &= ~_BV(UPM01); // No parity
|
||||
UCSR0B &= ~_BV(RXCIE0); // No rx interrupt
|
||||
UCSR0A |= _BV(U2X0); // Double speed mode USART0
|
||||
}
|
||||
#endif // CHECK_FOR_BOOTLOADER
|
||||
#endif //ORANGE_TX
|
||||
}
|
||||
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
void pollBoot()
|
||||
{
|
||||
uint8_t rxchar ;
|
||||
uint8_t lState = BootState ;
|
||||
uint8_t millisTime = millis(); // Call this once only
|
||||
|
||||
#ifdef ORANGE_TX
|
||||
if ( USARTC0.STATUS & USART_RXCIF_bm )
|
||||
#elif defined STM32_BOARD
|
||||
if ( USART2_BASE->SR & USART_SR_RXNE )
|
||||
#else
|
||||
if ( UCSR0A & ( 1 << RXC0 ) )
|
||||
#endif
|
||||
{
|
||||
rxchar = UDR0 ;
|
||||
BootCount += 1 ;
|
||||
if ( ( lState == BOOT_WAIT_30_IDLE ) || ( lState == BOOT_WAIT_30_DATA ) )
|
||||
{
|
||||
if ( lState == BOOT_WAIT_30_IDLE ) // Waiting for 0x30
|
||||
BootTimer = millisTime ; // Start timeout
|
||||
if ( rxchar == 0x30 )
|
||||
lState = BOOT_WAIT_20 ;
|
||||
else
|
||||
lState = BOOT_WAIT_30_DATA ;
|
||||
}
|
||||
else
|
||||
if ( lState == BOOT_WAIT_20 && rxchar == 0x20 ) // Waiting for 0x20
|
||||
lState = BOOT_READY ;
|
||||
}
|
||||
else // No byte received
|
||||
{
|
||||
if ( lState != BOOT_WAIT_30_IDLE ) // Something received
|
||||
{
|
||||
uint8_t time = millisTime - BootTimer ;
|
||||
if ( time > 5 )
|
||||
{
|
||||
#ifdef STM32_BOARD
|
||||
if ( BootCount > 4 )
|
||||
#else
|
||||
if ( BootCount > 2 )
|
||||
#endif
|
||||
{ // Run normally
|
||||
NotBootChecking = 0xFF ;
|
||||
Mprotocol_serial_init( 0 ) ;
|
||||
}
|
||||
else if ( lState == BOOT_READY )
|
||||
{
|
||||
#ifdef STM32_BOARD
|
||||
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
|
||||
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
|
||||
#define __I volatile /*!< defines 'read only' permissions */
|
||||
#define __IO volatile /*!< defines 'read / write' permissions */
|
||||
typedef struct
|
||||
{
|
||||
__I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
|
||||
__IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
|
||||
__IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */
|
||||
__IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
|
||||
__IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
|
||||
__IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
|
||||
__IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
|
||||
__IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
|
||||
__IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */
|
||||
__IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */
|
||||
__IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
|
||||
__IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */
|
||||
__IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */
|
||||
__IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */
|
||||
__I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */
|
||||
__I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */
|
||||
__I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */
|
||||
__I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */
|
||||
__I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */
|
||||
} SCB_Type;
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
|
||||
#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
// NVIC_SystemReset
|
||||
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
|
||||
asm("dsb");
|
||||
while(1); /* wait until reset */
|
||||
#else
|
||||
cli(); // Disable global int due to RW of 16 bits registers
|
||||
void (*p)();
|
||||
#ifndef ORANGE_TX
|
||||
p = (void (*)())0x3F00 ; // Word address (0x7E00 byte)
|
||||
#else
|
||||
p = (void (*)())0x4000 ; // Word address (0x8000 byte)
|
||||
#endif
|
||||
(*p)() ; // go to boot
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lState = BOOT_WAIT_30_IDLE ;
|
||||
BootCount = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BootState = lState ;
|
||||
}
|
||||
#endif //CHECK_FOR_BOOTLOADER
|
||||
|
||||
#if defined(TELEMETRY)
|
||||
void PPM_Telemetry_serial_init()
|
||||
{
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// compatible with Syma X5C-1, X11, X11C, X12 and for sub protocol X5C Syma X5C (original), X2
|
||||
// Last sync with hexfet new_protocols/cx10_nrf24l01.c dated 2015-09-28
|
||||
|
||||
#if defined(SYMAX_NRF24L01_INO)
|
||||
|
||||
@@ -30,6 +29,7 @@
|
||||
#define SYMAX_FLAG_VIDEO 0x02
|
||||
#define SYMAX_FLAG_PICTURE 0x04
|
||||
#define SYMAX_FLAG_HEADLESS 0x08
|
||||
#define SYMAX_XTRM_RATES 0x10
|
||||
|
||||
#define SYMAX_PAYLOADSIZE 10 // receive data pipes set to this size, but unused
|
||||
#define SYMAX_MAX_PACKET_LENGTH 16 // X11,X12,X5C-1 10-byte, X5C 16-byte
|
||||
@@ -58,6 +58,7 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
||||
{
|
||||
// Protocol is registered AETRF, that is
|
||||
// Aileron is channel 1, Elevator - 2, Throttle - 3, Rudder - 4, Flip control - 5
|
||||
// Extended (trim-added) Rates - 6, Photo - 7, Video - 8, Headless - 9
|
||||
aileron = convert_channel_s8b(AILERON);
|
||||
elevator = convert_channel_s8b(ELEVATOR);
|
||||
throttle = convert_channel_8b(THROTTLE);
|
||||
@@ -67,6 +68,9 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
||||
// Channel 5
|
||||
if (Servo_AUX1)
|
||||
flags = SYMAX_FLAG_FLIP;
|
||||
// Channel 6
|
||||
if (Servo_AUX2)
|
||||
flags |= SYMAX_XTRM_RATES;
|
||||
// Channel 7
|
||||
if (Servo_AUX3)
|
||||
flags |= SYMAX_FLAG_PICTURE;
|
||||
@@ -75,7 +79,10 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
||||
flags |= SYMAX_FLAG_VIDEO;
|
||||
// Channel 9
|
||||
if (Servo_AUX5)
|
||||
{
|
||||
flags |= SYMAX_FLAG_HEADLESS;
|
||||
flags &= ~SYMAX_XTRM_RATES; // Extended rates & headless incompatible
|
||||
}
|
||||
}
|
||||
|
||||
#define X5C_CHAN2TRIM(X) ((((X) & 0x80 ? 0xff - (X) : 0x80 + (X)) >> 2) + 0x20)
|
||||
@@ -98,9 +105,18 @@ static void __attribute__((unused)) SYMAX_build_packet_x5c(uint8_t bind)
|
||||
packet[1] = rudder;
|
||||
packet[2] = elevator ^ 0x80; // reversed from default
|
||||
packet[3] = aileron;
|
||||
packet[4] = X5C_CHAN2TRIM(rudder ^ 0x80);// drive trims for extra control range
|
||||
packet[5] = X5C_CHAN2TRIM(elevator);
|
||||
packet[6] = X5C_CHAN2TRIM(aileron ^ 0x80);
|
||||
if (flags & SYMAX_XTRM_RATES)
|
||||
{ // drive trims for extra control range
|
||||
packet[4] = X5C_CHAN2TRIM(rudder ^ 0x80);
|
||||
packet[5] = X5C_CHAN2TRIM(elevator);
|
||||
packet[6] = X5C_CHAN2TRIM(aileron ^ 0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[4] = 0x00;
|
||||
packet[5] = 0x00;
|
||||
packet[6] = 0x00;
|
||||
}
|
||||
packet[7] = 0xae;
|
||||
packet[8] = 0xa9;
|
||||
packet[9] = 0x00;
|
||||
@@ -138,9 +154,15 @@ static void __attribute__((unused)) SYMAX_build_packet(uint8_t bind)
|
||||
packet[2] = rudder;
|
||||
packet[3] = aileron;
|
||||
packet[4] = (flags & SYMAX_FLAG_VIDEO ? 0x80 : 0x00) | (flags & SYMAX_FLAG_PICTURE ? 0x40 : 0x00);
|
||||
packet[5] = (elevator >> 2) | 0xc0; //always high rates (bit 7 is rate control)
|
||||
packet[6] = (rudder >> 2) | (flags & SYMAX_FLAG_FLIP ? 0x40 : 0x00);
|
||||
packet[7] = (aileron >> 2) | (flags & SYMAX_FLAG_HEADLESS ? 0x80 : 0x00);
|
||||
packet[5] = 0xc0; //always high rates (bit 7 is rate control)
|
||||
packet[6] = flags & SYMAX_FLAG_FLIP ? 0x40 : 0x00;
|
||||
packet[7] = flags & SYMAX_FLAG_HEADLESS ? 0x80 : 0x00;
|
||||
if (flags & SYMAX_XTRM_RATES)
|
||||
{ // use trims to extend controls
|
||||
packet[5] |= elevator >> 2;
|
||||
packet[6] |= rudder >> 2;
|
||||
packet[7] |= aileron >> 2;
|
||||
}
|
||||
packet[8] = 0x00;
|
||||
}
|
||||
packet[9] = SYMAX_checksum(packet);
|
||||
|
||||
@@ -31,6 +31,34 @@ uint8_t RetrySequence ;
|
||||
uint8_t sport_counter=0;
|
||||
uint8_t RxBt = 0;
|
||||
uint8_t sport = 0;
|
||||
#define MAX_PKTX 10
|
||||
#define FX_BUFFERS 4
|
||||
uint8_t pktx[MAX_PKTX];
|
||||
uint8_t pktx1[FRSKY_SPORT_PACKET_SIZE*FX_BUFFERS];
|
||||
uint8_t indx;
|
||||
//struct t_fx_rx_packet
|
||||
//{
|
||||
// uint8_t validSequence ;
|
||||
// uint8_t count ;
|
||||
// uint8_t payload[6] ;
|
||||
//} ;
|
||||
|
||||
// Store for out of sequence packet
|
||||
//struct t_fx_rx_packet FrskyxRxTelemetry ;
|
||||
|
||||
uint8_t FrskyxRxTelemetryValidSequence ;
|
||||
|
||||
struct t_fx_rx_frame
|
||||
{
|
||||
uint8_t valid ;
|
||||
uint8_t count ;
|
||||
uint8_t payload[6] ;
|
||||
} ;
|
||||
|
||||
// Store for FrskyX telemetry
|
||||
struct t_fx_rx_frame FrskyxRxFrames[4] ;
|
||||
uint8_t NextFxFrameToForward ;
|
||||
|
||||
#endif
|
||||
#if defined HUB_TELEMETRY
|
||||
#define USER_MAX_BYTES 6
|
||||
@@ -40,10 +68,6 @@ uint8_t RetrySequence ;
|
||||
#define START_STOP 0x7e
|
||||
#define BYTESTUFF 0x7d
|
||||
#define STUFF_MASK 0x20
|
||||
#define MAX_PKTX 10
|
||||
uint8_t pktx[MAX_PKTX];
|
||||
uint8_t pktx1[MAX_PKTX];
|
||||
uint8_t indx;
|
||||
uint8_t frame[18];
|
||||
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
@@ -155,7 +179,8 @@ void frskySendStuffed()
|
||||
|
||||
void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
||||
{
|
||||
if(pkt[1] == rx_tx_addr[3] && pkt[2] == rx_tx_addr[2] && len ==(pkt[0] + 3))
|
||||
uint8_t clen = pkt[0] + 3 ;
|
||||
if(pkt[1] == rx_tx_addr[3] && pkt[2] == rx_tx_addr[2] && len == clen )
|
||||
{
|
||||
telemetry_link|=1; // Telemetry data is available
|
||||
/*previous version
|
||||
@@ -205,19 +230,144 @@ void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
||||
telemetry_lost=0;
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{
|
||||
if ((pktt[5] >> 4 & 0x0f) == 0x08)
|
||||
{
|
||||
seq_last_sent = 8;
|
||||
seq_last_rcvd = 0;
|
||||
pass=0;
|
||||
}
|
||||
else
|
||||
uint16_t lcrc = crc_x(&pkt[3], len-7 ) ;
|
||||
// if ( ( sub_protocol & 2 ) == 0 )
|
||||
// {
|
||||
// if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) )
|
||||
// {
|
||||
// lcrc = 0 ;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// lcrc = 1 ;
|
||||
// }
|
||||
// }
|
||||
// if ( lcrc == 0 )
|
||||
|
||||
if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) )
|
||||
{
|
||||
if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
|
||||
seq_last_rcvd = (seq_last_rcvd + 1) % 4;
|
||||
// Check if in sequence
|
||||
if ( (pkt[5] & 0x0F) == 0x08 )
|
||||
{
|
||||
FrX_receive_seq = 0x08 ;
|
||||
NextFxFrameToForward = 0 ;
|
||||
FrskyxRxFrames[0].valid = 0 ;
|
||||
FrskyxRxFrames[1].valid = 0 ;
|
||||
FrskyxRxFrames[2].valid = 0 ;
|
||||
FrskyxRxFrames[3].valid = 0 ;
|
||||
}
|
||||
else if ( (pkt[5] & 0x03) == (FrX_receive_seq & 0x03 ) )
|
||||
{
|
||||
// OK to process
|
||||
struct t_fx_rx_frame *p ;
|
||||
uint8_t count ;
|
||||
p = &FrskyxRxFrames[FrX_receive_seq & 3] ;
|
||||
count = pkt[6] ;
|
||||
if ( count <= 6 )
|
||||
{
|
||||
p->count = count ;
|
||||
for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||
{
|
||||
p->payload[i] = pkt[i+7] ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->count = 0 ;
|
||||
}
|
||||
p->valid = 1 ;
|
||||
|
||||
|
||||
|
||||
FrX_receive_seq = ( FrX_receive_seq + 1 ) & 0x03 ;
|
||||
|
||||
if ( FrskyxRxTelemetryValidSequence & 0x80 )
|
||||
{
|
||||
FrX_receive_seq = ( FrskyxRxTelemetryValidSequence + 1 ) & 3 ;
|
||||
FrskyxRxTelemetryValidSequence &= 0x7F ;
|
||||
}
|
||||
|
||||
// if ( FrskyxRxTelemetry.validSequence & 0x80 )
|
||||
// {
|
||||
// FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
|
||||
|
||||
// FrskyxRxTelemetry.validSequence &= 0x7F ;
|
||||
|
||||
// }
|
||||
}
|
||||
else
|
||||
pass=0;//reset if sequence wrong
|
||||
{
|
||||
// Save and request correct packet
|
||||
// struct t_fx_rx_packet *p ;
|
||||
struct t_fx_rx_frame *q ;
|
||||
uint8_t count ;
|
||||
// pkt[4] RSSI
|
||||
// pkt[5] sequence control
|
||||
// pkt[6] payload count
|
||||
// pkt[7-12] payload
|
||||
pktt[6] = 0 ; // Don't process
|
||||
if ( (pkt[5] & 0x03) == ( ( FrX_receive_seq +1 ) & 3 ) )
|
||||
{
|
||||
q = &FrskyxRxFrames[(pkt[5] & 0x03)] ;
|
||||
count = pkt[6] ;
|
||||
if ( count <= 6 )
|
||||
{
|
||||
q->count = count ;
|
||||
for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||
{
|
||||
q->payload[i] = pkt[i+7] ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
q->count = 0 ;
|
||||
}
|
||||
q->valid = 1 ;
|
||||
|
||||
FrskyxRxTelemetryValidSequence = 0x80 | ( pkt[5] & 0x03 ) ;
|
||||
}
|
||||
|
||||
|
||||
// p = &FrskyxRxTelemetry ;
|
||||
// count = pkt[6] ;
|
||||
// if ( count <= 6 )
|
||||
// {
|
||||
// p->count = count ;
|
||||
// for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||
// {
|
||||
// p->payload[i] = pkt[i+7] ;
|
||||
// }
|
||||
// p->validSequence = 0x80 | ( pkt[5] & 0x03 ) ;
|
||||
// }
|
||||
FrX_receive_seq = ( FrX_receive_seq & 0x03 ) | 0x04 ; // Request re-transmission
|
||||
}
|
||||
|
||||
if (((pktt[5] >> 4) & 0x0f) == 0x08)
|
||||
{
|
||||
FrX_send_seq = 0 ;
|
||||
// FrX_receive_seq = 0x08 ;
|
||||
}
|
||||
}
|
||||
|
||||
// packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
|
||||
// if ( FrX_send_seq != 0x08 )
|
||||
// {
|
||||
// FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
|
||||
// }
|
||||
|
||||
// if ((pktt[5] >> 4 & 0x0f) == 0x08)
|
||||
// {
|
||||
// seq_last_sent = 8;
|
||||
// seq_last_rcvd = 0;
|
||||
// pass=0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
|
||||
// seq_last_rcvd = (seq_last_rcvd + 1) % 4;
|
||||
// else
|
||||
// pass=0;//reset if sequence wrong
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -363,12 +513,25 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
0x34 0x0A 0xC3 0x56 0xF3
|
||||
|
||||
*/
|
||||
|
||||
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 } ;
|
||||
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
void sportSend(uint8_t *p)
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
|
||||
uint16_t crc_s = 0;
|
||||
Serial_write(p[0]) ;
|
||||
uint8_t x = p[0] ;
|
||||
if ( x <= 0x1B )
|
||||
{
|
||||
x = pgm_read_byte_near( &Indices[x] ) ;
|
||||
}
|
||||
Serial_write(x) ;
|
||||
for (uint8_t i = 1; i < 9; i++)
|
||||
{
|
||||
if (i == 8)
|
||||
@@ -462,7 +625,13 @@ void sportSendFrame()
|
||||
{
|
||||
for (i=0;i<FRSKY_SPORT_PACKET_SIZE;i++)
|
||||
frame[i]=pktx1[i];
|
||||
sport=0;
|
||||
sport -= 1 ;
|
||||
if ( sport )
|
||||
{
|
||||
uint8_t j = sport * FRSKY_SPORT_PACKET_SIZE ;
|
||||
for (i=0;i<j;i++)
|
||||
pktx1[i] = pktx1[i+FRSKY_SPORT_PACKET_SIZE] ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -506,19 +675,20 @@ void proces_sport_data(uint8_t data)
|
||||
} // end switch
|
||||
if (indx >= FRSKY_SPORT_PACKET_SIZE)
|
||||
{//8 bytes no crc
|
||||
if ( sport )
|
||||
{
|
||||
// overrun!
|
||||
}
|
||||
else
|
||||
if ( sport < FX_BUFFERS )
|
||||
{
|
||||
uint8_t dest = sport * FRSKY_SPORT_PACKET_SIZE ;
|
||||
uint8_t i ;
|
||||
for ( i = 0 ; i < FRSKY_SPORT_PACKET_SIZE ; i += 1 )
|
||||
{
|
||||
pktx1[i] = pktx[i] ; // Double buffer
|
||||
pktx1[dest++] = pktx[i] ; // Triple buffer
|
||||
}
|
||||
sport = 1;//ok to send
|
||||
sport += 1 ;//ok to send
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// // Overrun
|
||||
// }
|
||||
pass = 0;//reset
|
||||
}
|
||||
}
|
||||
@@ -534,11 +704,14 @@ void TelemetryUpdate()
|
||||
h = SerialControl.head ;
|
||||
t = SerialControl.tail ;
|
||||
if ( h >= t )
|
||||
t += 128 - h ;
|
||||
t += 192 - h ;
|
||||
else
|
||||
t -= h ;
|
||||
// if ( t < 32 )
|
||||
if ( t < 64 )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
#else
|
||||
uint8_t h ;
|
||||
uint8_t t ;
|
||||
@@ -549,7 +722,9 @@ void TelemetryUpdate()
|
||||
else
|
||||
t -= h ;
|
||||
if ( t < 32 )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
{
|
||||
@@ -566,15 +741,62 @@ void TelemetryUpdate()
|
||||
#if defined SPORT_TELEMETRY
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{ // FrSkyX
|
||||
// struct t_fx_rx_frame *p ;
|
||||
// uint8_t count ;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
struct t_fx_rx_frame *p ;
|
||||
uint8_t count ;
|
||||
p = &FrskyxRxFrames[NextFxFrameToForward] ;
|
||||
if ( p->valid )
|
||||
{
|
||||
count = p->count ;
|
||||
for (uint8_t i=0; i < count ; i++)
|
||||
proces_sport_data(p->payload[i]) ;
|
||||
p->valid = 0 ; // Sent on
|
||||
NextFxFrameToForward = ( NextFxFrameToForward + 1 ) & 3 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
// p = &FrskyxRxFrames[NextFxFrameToForward] ;
|
||||
// if ( p->valid )
|
||||
// {
|
||||
// count = p->count ;
|
||||
// for (uint8_t i=0; i < count ; i++)
|
||||
// proces_sport_data(p->payload[i]) ;
|
||||
// p->valid = 0 ; // Sent on
|
||||
// NextFxFrameToForward = ( NextFxFrameToForward + 1 ) & 3 ;
|
||||
// }
|
||||
|
||||
if(telemetry_link)
|
||||
{
|
||||
if(pktt[4] & 0x80)
|
||||
RX_RSSI=pktt[4] & 0x7F ;
|
||||
else
|
||||
RxBt = (pktt[4]<<1) + 1 ;
|
||||
if(pktt[6] && pktt[6]<=6)
|
||||
for (uint8_t i=0; i < pktt[6]; i++)
|
||||
proces_sport_data(pktt[7+i]);
|
||||
|
||||
// if(pktt[6] && pktt[6]<=6)
|
||||
// {
|
||||
// for (uint8_t i=0; i < pktt[6]; i++)
|
||||
// proces_sport_data(pktt[7+i]);
|
||||
// if ( FrskyxRxTelemetry.validSequence & 0x80 )
|
||||
// {
|
||||
// // Process out of sequence packet
|
||||
// for (uint8_t i=0; i < FrskyxRxTelemetry.count ; i++)
|
||||
// {
|
||||
// proces_sport_data( FrskyxRxTelemetry.payload[i] ) ;
|
||||
// }
|
||||
//// FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
|
||||
// FrskyxRxTelemetry.validSequence = 0 ;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
telemetry_link=0;
|
||||
}
|
||||
uint32_t now = micros();
|
||||
@@ -928,7 +1150,13 @@ ISR(TIMER0_COMPB_vect)
|
||||
{
|
||||
GPIOR0 = ptr->data[ptr->tail] ;
|
||||
GPIOR2 = ptr->data[ptr->tail+1] ;
|
||||
ptr->tail = ( ptr->tail + 2 ) & 0x7F ;
|
||||
uint8_t nextTail ;
|
||||
nextTail = ptr->tail + 2 ;
|
||||
if ( nextTail > 192 )
|
||||
{
|
||||
nextTail = 0 ;
|
||||
}
|
||||
ptr->tail = nextTail ;
|
||||
GPIOR1 = 8 ;
|
||||
OCR0A = OCR0B + 40 ;
|
||||
OCR0B = OCR0A + 8 * 20 ;
|
||||
|
||||
@@ -49,6 +49,13 @@
|
||||
//The goal is to prevent binding other people's model when powering up the TX, changing model or scanning through protocols.
|
||||
#define WAIT_FOR_BIND
|
||||
|
||||
/*************************/
|
||||
/*** BOOTLOADER USE ***/
|
||||
/*************************/
|
||||
//Allow flashing multimodule directly with TX(erky9x or opentx modified firmwares)
|
||||
//Check https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/BootLoaders
|
||||
//To enable this feature remove the "//" on the next line.
|
||||
//#define CHECK_FOR_BOOTLOADER
|
||||
|
||||
/****************/
|
||||
/*** RF CHIPS ***/
|
||||
@@ -87,7 +94,6 @@
|
||||
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
|
||||
//#define FORCE_CYRF_ID "\x12\x34\x56\x78\x9A\xBC"
|
||||
|
||||
|
||||
/****************************/
|
||||
/*** PROTOCOLS TO INCLUDE ***/
|
||||
/****************************/
|
||||
@@ -134,6 +140,42 @@
|
||||
#define GW008_NRF24L01_INO
|
||||
#define DM002_NRF24L01_INO
|
||||
|
||||
/**************************/
|
||||
/*** FAILSAFE SETTINGS ***/
|
||||
/**************************/
|
||||
#define AFHDS2A_FAILSAFE
|
||||
#ifdef AFHDS2A_FAILSAFE
|
||||
/*
|
||||
Failsafe Min/Max values 962 <-> 2038
|
||||
*/
|
||||
const int8_t AFHDS2AFailsafeMIN = -105;
|
||||
const int8_t AFHDS2AFailsafeMAX = 105;
|
||||
//
|
||||
const int8_t AFHDS2AFailsafe[14]= {
|
||||
/*
|
||||
Failsafe examples
|
||||
988 <-> 2012µs -100% = 988 = 1500 + (2012-988)/2 * (-100/100) = 1500 - 512 = 988
|
||||
988 <-> 2012µs 0% = 1500 = 1500 + (2012-988)/2 * ( 0/100) = 1500 + 0 = 1500
|
||||
988 <-> 2012µs 100% = 2012 = 1500 + (2012-988)/2 * ( 100/100) = 1500 + 512 = 2012
|
||||
988 <-> 2012µs -105% = 962 = 1500 + (2012-988)/2 * (-105/100) = 1500 - 538 = 962
|
||||
*/
|
||||
/* ch 1 */ -1,
|
||||
/* ch 2 */ -1,
|
||||
/* ch 3 */ -105,
|
||||
/* ch 4 */ -1,
|
||||
/* ch 5 */ -1,
|
||||
/* ch 6 */ -1,
|
||||
/* ch 7 */ -1,
|
||||
/* ch 8 */ -1,
|
||||
/* ch 9 */ -1,
|
||||
/* ch 10 */ -1,
|
||||
/* ch 11 */ -1,
|
||||
/* ch 12 */ -1,
|
||||
/* ch 13 */ -1,
|
||||
/* ch 14 */ -1
|
||||
};
|
||||
#endif
|
||||
|
||||
/**************************/
|
||||
/*** TELEMETRY SETTINGS ***/
|
||||
/**************************/
|
||||
@@ -178,7 +220,6 @@
|
||||
//If you do not plan to use the Serial mode comment this line using "//" to save Flash space
|
||||
#define ENABLE_SERIAL
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** PPM MODE SETTINGS ***/
|
||||
/*************************/
|
||||
@@ -305,6 +346,7 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
MODE_BAYANG
|
||||
BAYANG
|
||||
H8S3D
|
||||
X16_AH
|
||||
MODE_ESKY
|
||||
NONE
|
||||
MODE_MT99XX
|
||||
|
||||
Reference in New Issue
Block a user