mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-12-16 12:53:17 +00:00
Merge remote-tracking branch 'refs/remotes/pascallanger/master'
This commit is contained in:
@@ -146,7 +146,11 @@ void A7105_SetPower()
|
||||
{
|
||||
uint8_t power=A7105_BIND_POWER;
|
||||
if(IS_BIND_DONE_on)
|
||||
power=IS_POWER_FLAG_on?A7105_HIGH_POWER:A7105_LOW_POWER;
|
||||
#ifdef A7105_ENABLE_LOW_POWER
|
||||
power=IS_POWER_FLAG_on?A7105_HIGH_POWER:A7105_LOW_POWER;
|
||||
#else
|
||||
power=A7105_HIGH_POWER;
|
||||
#endif
|
||||
if(IS_RANGE_FLAG_on)
|
||||
power=A7105_RANGE_POWER;
|
||||
if(prev_power != power)
|
||||
|
||||
@@ -110,11 +110,11 @@ static void AFHDS2A_update_telemetry()
|
||||
v_lipo1 = packet[index+2];
|
||||
telemetry_link=1;
|
||||
break;
|
||||
/*case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||
// packet[index+2];
|
||||
break;*/
|
||||
case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||
RX_LQI=packet[index+2];
|
||||
break;
|
||||
case AFHDS2A_SENSOR_RX_RSSI:
|
||||
RSSI_dBm = -packet[index+2];
|
||||
RX_RSSI = -packet[index+2];
|
||||
break;
|
||||
case 0xff:
|
||||
return;
|
||||
@@ -260,7 +260,7 @@ uint16_t ReadAFHDS2A()
|
||||
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_SetTxRxMode(TXRX_OFF); // Turn LNA off since we are in near range and we want to prevent swamping
|
||||
A7105_Strobe(A7105_RX);
|
||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||
phase++;
|
||||
@@ -352,7 +352,7 @@ uint16_t initAFHDS2A()
|
||||
}
|
||||
hopping_frequency_no = 0;
|
||||
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
||||
init_hub_telemetry();
|
||||
init_frskyd_link_telemetry();
|
||||
#endif
|
||||
return 50000;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
|
||||
packet[20]=0x53; */
|
||||
// Using packet[20..23] to store the ID1 and packet[24..27] to store the ID2
|
||||
uint8_t freq=0,freq2;
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
for(uint8_t i=0;i<ASSAN_ADDRESS_LENGTH;i++)
|
||||
{
|
||||
uint8_t temp=rx_tx_addr[i];
|
||||
packet[i+20]=temp;
|
||||
|
||||
@@ -150,7 +150,7 @@ static void __attribute__((unused)) check_rx(void)
|
||||
// compensated battery volts*100/2
|
||||
v_lipo2 = (packet[5]<<7) + (packet[6]>>2);
|
||||
// reception in packets / sec
|
||||
RSSI_dBm = packet[7];
|
||||
RX_RSSI = packet[7];
|
||||
//Flags
|
||||
//uint8_t flags = packet[3] >> 3;
|
||||
// battery low: flags & 1
|
||||
@@ -252,7 +252,7 @@ uint16_t initBAYANG(void)
|
||||
BAYANG_init();
|
||||
packet_count=0;
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
init_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;
|
||||
|
||||
@@ -145,7 +145,11 @@ void CC2500_SetPower()
|
||||
{
|
||||
uint8_t power=CC2500_BIND_POWER;
|
||||
if(IS_BIND_DONE_on)
|
||||
power=IS_POWER_FLAG_on?CC2500_HIGH_POWER:CC2500_LOW_POWER;
|
||||
#ifdef CC2500_ENABLE_LOW_POWER
|
||||
power=IS_POWER_FLAG_on?CC2500_HIGH_POWER:CC2500_LOW_POWER;
|
||||
#else
|
||||
power=CC2500_HIGH_POWER;
|
||||
#endif
|
||||
if(IS_RANGE_FLAG_on)
|
||||
power=CC2500_RANGE_POWER;
|
||||
if(prev_power != power)
|
||||
|
||||
@@ -133,7 +133,11 @@ void CYRF_SetPower(uint8_t val)
|
||||
{
|
||||
uint8_t power=CYRF_BIND_POWER;
|
||||
if(IS_BIND_DONE_on)
|
||||
power=IS_POWER_FLAG_on?CYRF_HIGH_POWER:CYRF_LOW_POWER;
|
||||
#ifdef CYRF6936_ENABLE_LOW_POWER
|
||||
power=IS_POWER_FLAG_on?CYRF_HIGH_POWER:CYRF_LOW_POWER;
|
||||
#else
|
||||
power=CYRF_HIGH_POWER;
|
||||
#endif
|
||||
if(IS_RANGE_FLAG_on)
|
||||
power=CYRF_RANGE_POWER;
|
||||
power|=val;
|
||||
|
||||
271
Multiprotocol/Common.ino
Normal file
271
Multiprotocol/Common.ino
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
/************************/
|
||||
/** Convert routines **/
|
||||
/************************/
|
||||
// Channel value is converted to 8bit values full scale
|
||||
uint8_t convert_channel_8b(uint8_t num)
|
||||
{
|
||||
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,0,255));
|
||||
}
|
||||
|
||||
// Channel value is converted to 8bit values to provided values scale
|
||||
uint8_t convert_channel_8b_scale(uint8_t num,uint8_t min,uint8_t max)
|
||||
{
|
||||
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,min,max));
|
||||
}
|
||||
|
||||
// Channel value is converted sign + magnitude 8bit values
|
||||
uint8_t convert_channel_s8b(uint8_t num)
|
||||
{
|
||||
uint8_t ch;
|
||||
ch = convert_channel_8b(num);
|
||||
return (ch < 128 ? 127-ch : ch);
|
||||
}
|
||||
|
||||
// Channel value is converted to 10bit values
|
||||
uint16_t convert_channel_10b(uint8_t num)
|
||||
{
|
||||
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,1,1023));
|
||||
}
|
||||
|
||||
// Channel value is multiplied by 1.5
|
||||
uint16_t convert_channel_frsky(uint8_t num)
|
||||
{
|
||||
return Servo_data[num] + Servo_data[num]/2;
|
||||
}
|
||||
|
||||
// Channel value is converted for HK310
|
||||
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
||||
{
|
||||
uint16_t temp=0xFFFF-(4*Servo_data[num])/3;
|
||||
*low=(uint8_t)(temp&0xFF);
|
||||
*high=(uint8_t)(temp>>8);
|
||||
}
|
||||
|
||||
// Channel value is converted to 16bit values
|
||||
uint16_t convert_channel_16b(uint8_t num, int16_t out_min, int16_t out_max)
|
||||
{
|
||||
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,out_min,out_max));
|
||||
}
|
||||
|
||||
// Channel value is converted to 16bit values with no limit
|
||||
uint16_t convert_channel_16b_nolim(uint8_t num, int16_t out_min, int16_t out_max)
|
||||
{
|
||||
return (uint16_t) (map(Servo_data[num],servo_min_100,servo_max_100,out_min,out_max));
|
||||
}
|
||||
|
||||
// Channel value is limited to PPM_100
|
||||
uint16_t limit_channel_100(uint8_t ch)
|
||||
{
|
||||
if(Servo_data[ch]>servo_max_100)
|
||||
return servo_max_100;
|
||||
else
|
||||
if (Servo_data[ch]<servo_min_100)
|
||||
return servo_min_100;
|
||||
return Servo_data[ch];
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/** FrSky D and X routines **/
|
||||
/******************************/
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
|
||||
enum {
|
||||
FRSKY_BIND = 0,
|
||||
FRSKY_BIND_DONE = 1000,
|
||||
FRSKY_DATA1,
|
||||
FRSKY_DATA2,
|
||||
FRSKY_DATA3,
|
||||
FRSKY_DATA4,
|
||||
FRSKY_DATA5
|
||||
};
|
||||
|
||||
void Frsky_init_hop(void)
|
||||
{
|
||||
uint8_t val;
|
||||
uint8_t channel = rx_tx_addr[0]&0x07;
|
||||
uint8_t channel_spacing = rx_tx_addr[1];
|
||||
//Filter bad tables
|
||||
if(channel_spacing<0x02) channel_spacing+=0x02;
|
||||
if(channel_spacing>0xE9) channel_spacing-=0xE7;
|
||||
if(channel_spacing%0x2F==0) channel_spacing++;
|
||||
|
||||
hopping_frequency[0]=channel;
|
||||
for(uint8_t i=1;i<50;i++)
|
||||
{
|
||||
channel=(channel+channel_spacing) % 0xEB;
|
||||
val=channel;
|
||||
if((val==0x00) || (val==0x5A) || (val==0xDC))
|
||||
val++;
|
||||
hopping_frequency[i]=i>46?0:val;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/******************************/
|
||||
/** FrSky V, D and X routines **/
|
||||
/******************************/
|
||||
#if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
|
||||
const PROGMEM uint8_t FRSKY_common_startreg_cc2500_conf[]= {
|
||||
CC2500_02_IOCFG0 ,
|
||||
CC2500_00_IOCFG2 ,
|
||||
CC2500_17_MCSM1 ,
|
||||
CC2500_18_MCSM0 ,
|
||||
CC2500_06_PKTLEN ,
|
||||
CC2500_07_PKTCTRL1 ,
|
||||
CC2500_08_PKTCTRL0 ,
|
||||
CC2500_3E_PATABLE ,
|
||||
CC2500_0B_FSCTRL1 ,
|
||||
CC2500_0C_FSCTRL0 , // replaced by option value
|
||||
CC2500_0D_FREQ2 ,
|
||||
CC2500_0E_FREQ1 ,
|
||||
CC2500_0F_FREQ0 ,
|
||||
CC2500_10_MDMCFG4 ,
|
||||
CC2500_11_MDMCFG3 ,
|
||||
CC2500_12_MDMCFG2 ,
|
||||
CC2500_13_MDMCFG1 ,
|
||||
CC2500_14_MDMCFG0 ,
|
||||
CC2500_15_DEVIATN };
|
||||
|
||||
#if defined(FRSKYV_CC2500_INO)
|
||||
const PROGMEM uint8_t FRSKYV_cc2500_conf[]= {
|
||||
/*02_IOCFG0*/ 0x06 ,
|
||||
/*00_IOCFG2*/ 0x06 ,
|
||||
/*17_MCSM1*/ 0x0c ,
|
||||
/*18_MCSM0*/ 0x18 ,
|
||||
/*06_PKTLEN*/ 0xff ,
|
||||
/*07_PKTCTRL1*/ 0x04 ,
|
||||
/*08_PKTCTRL0*/ 0x05 ,
|
||||
/*3E_PATABLE*/ 0xfe ,
|
||||
/*0B_FSCTRL1*/ 0x08 ,
|
||||
/*0C_FSCTRL0*/ 0x00 ,
|
||||
/*0D_FREQ2*/ 0x5c ,
|
||||
/*0E_FREQ1*/ 0x58 ,
|
||||
/*0F_FREQ0*/ 0x9d ,
|
||||
/*10_MDMCFG4*/ 0xAA ,
|
||||
/*11_MDMCFG3*/ 0x10 ,
|
||||
/*12_MDMCFG2*/ 0x93 ,
|
||||
/*13_MDMCFG1*/ 0x23 ,
|
||||
/*14_MDMCFG0*/ 0x7a ,
|
||||
/*15_DEVIATN*/ 0x41 };
|
||||
#endif
|
||||
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
const PROGMEM uint8_t FRSKYD_cc2500_conf[]= {
|
||||
/*02_IOCFG0*/ 0x06 ,
|
||||
/*00_IOCFG2*/ 0x06 ,
|
||||
/*17_MCSM1*/ 0x0c ,
|
||||
/*18_MCSM0*/ 0x18 ,
|
||||
/*06_PKTLEN*/ 0x19 ,
|
||||
/*07_PKTCTRL1*/ 0x04 ,
|
||||
/*08_PKTCTRL0*/ 0x05 ,
|
||||
/*3E_PATABLE*/ 0xff ,
|
||||
/*0B_FSCTRL1*/ 0x08 ,
|
||||
/*0C_FSCTRL0*/ 0x00 ,
|
||||
/*0D_FREQ2*/ 0x5c ,
|
||||
/*0E_FREQ1*/ 0x76 ,
|
||||
/*0F_FREQ0*/ 0x27 ,
|
||||
/*10_MDMCFG4*/ 0xAA ,
|
||||
/*11_MDMCFG3*/ 0x39 ,
|
||||
/*12_MDMCFG2*/ 0x11 ,
|
||||
/*13_MDMCFG1*/ 0x23 ,
|
||||
/*14_MDMCFG0*/ 0x7a ,
|
||||
/*15_DEVIATN*/ 0x42 };
|
||||
#endif
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
const PROGMEM uint8_t FRSKYX_cc2500_conf[]= {
|
||||
//FRSKYX
|
||||
/*02_IOCFG0*/ 0x06 ,
|
||||
/*00_IOCFG2*/ 0x06 ,
|
||||
/*17_MCSM1*/ 0x0c ,
|
||||
/*18_MCSM0*/ 0x18 ,
|
||||
/*06_PKTLEN*/ 0x1E ,
|
||||
/*07_PKTCTRL1*/ 0x04 ,
|
||||
/*08_PKTCTRL0*/ 0x01 ,
|
||||
/*3E_PATABLE*/ 0xff ,
|
||||
/*0B_FSCTRL1*/ 0x0A ,
|
||||
/*0C_FSCTRL0*/ 0x00 ,
|
||||
/*0D_FREQ2*/ 0x5c ,
|
||||
/*0E_FREQ1*/ 0x76 ,
|
||||
/*0F_FREQ0*/ 0x27 ,
|
||||
/*10_MDMCFG4*/ 0x7B ,
|
||||
/*11_MDMCFG3*/ 0x61 ,
|
||||
/*12_MDMCFG2*/ 0x13 ,
|
||||
/*13_MDMCFG1*/ 0x23 ,
|
||||
/*14_MDMCFG0*/ 0x7a ,
|
||||
/*15_DEVIATN*/ 0x51 };
|
||||
const PROGMEM uint8_t FRSKYXEU_cc2500_conf[]= {
|
||||
/*02_IOCFG0*/ 0x06 ,
|
||||
/*00_IOCFG2*/ 0x06 ,
|
||||
/*17_MCSM1*/ 0x0E ,
|
||||
/*18_MCSM0*/ 0x18 ,
|
||||
/*06_PKTLEN*/ 0x23 ,
|
||||
/*07_PKTCTRL1*/ 0x04 ,
|
||||
/*08_PKTCTRL0*/ 0x01 ,
|
||||
/*3E_PATABLE*/ 0xff ,
|
||||
/*0B_FSCTRL1*/ 0x08 ,
|
||||
/*0C_FSCTRL0*/ 0x00 ,
|
||||
/*0D_FREQ2*/ 0x5c ,
|
||||
/*0E_FREQ1*/ 0x80 ,
|
||||
/*0F_FREQ0*/ 0x00 ,
|
||||
/*10_MDMCFG4*/ 0x7B ,
|
||||
/*11_MDMCFG3*/ 0xF8 ,
|
||||
/*12_MDMCFG2*/ 0x03 ,
|
||||
/*13_MDMCFG1*/ 0x23 ,
|
||||
/*14_MDMCFG0*/ 0x7a ,
|
||||
/*15_DEVIATN*/ 0x53 };
|
||||
#endif
|
||||
|
||||
const PROGMEM uint8_t FRSKY_common_end_cc2500_conf[][2]= {
|
||||
{ CC2500_19_FOCCFG, 0x16 },
|
||||
{ CC2500_1A_BSCFG, 0x6c },
|
||||
{ CC2500_1B_AGCCTRL2, 0x43 },
|
||||
{ CC2500_1C_AGCCTRL1, 0x40 },
|
||||
{ CC2500_1D_AGCCTRL0, 0x91 },
|
||||
{ CC2500_21_FREND1, 0x56 },
|
||||
{ CC2500_22_FREND0, 0x10 },
|
||||
{ CC2500_23_FSCAL3, 0xa9 },
|
||||
{ CC2500_24_FSCAL2, 0x0A },
|
||||
{ CC2500_25_FSCAL1, 0x00 },
|
||||
{ CC2500_26_FSCAL0, 0x11 },
|
||||
{ CC2500_29_FSTEST, 0x59 },
|
||||
{ CC2500_2C_TEST2, 0x88 },
|
||||
{ CC2500_2D_TEST1, 0x31 },
|
||||
{ CC2500_2E_TEST0, 0x0B },
|
||||
{ CC2500_03_FIFOTHR, 0x07 },
|
||||
{ CC2500_09_ADDR, 0x00 } };
|
||||
|
||||
void FRSKY_init_cc2500(const uint8_t *ptr)
|
||||
{
|
||||
for(uint8_t i=0;i<19;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&FRSKY_common_startreg_cc2500_conf[i]);
|
||||
uint8_t val=pgm_read_byte_near(&ptr[i]);
|
||||
if(reg==CC2500_0C_FSCTRL0)
|
||||
val=option;
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
prev_option = option ; // Save option to monitor FSCTRL0 change
|
||||
for(uint8_t i=0;i<17;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][0]);
|
||||
uint8_t val=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][1]);
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||
}
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
/************************/
|
||||
/** Convert routines **/
|
||||
/************************/
|
||||
// Channel value is converted to 8bit values full scale
|
||||
uint8_t convert_channel_8b(uint8_t num)
|
||||
{
|
||||
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,0,255));
|
||||
}
|
||||
|
||||
// Channel value is converted to 8bit values to provided values scale
|
||||
uint8_t convert_channel_8b_scale(uint8_t num,uint8_t min,uint8_t max)
|
||||
{
|
||||
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,min,max));
|
||||
}
|
||||
|
||||
// Channel value is converted sign + magnitude 8bit values
|
||||
uint8_t convert_channel_s8b(uint8_t num)
|
||||
{
|
||||
uint8_t ch;
|
||||
ch = convert_channel_8b(num);
|
||||
return (ch < 128 ? 127-ch : ch);
|
||||
}
|
||||
|
||||
// Channel value is converted to 10bit values
|
||||
uint16_t convert_channel_10b(uint8_t num)
|
||||
{
|
||||
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,1,1023));
|
||||
}
|
||||
|
||||
// Channel value is multiplied by 1.5
|
||||
uint16_t convert_channel_frsky(uint8_t num)
|
||||
{
|
||||
return Servo_data[num] + Servo_data[num]/2;
|
||||
}
|
||||
|
||||
// Channel value is converted for HK310
|
||||
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
||||
{
|
||||
uint16_t temp=0xFFFF-(4*Servo_data[num])/3;
|
||||
*low=(uint8_t)(temp&0xFF);
|
||||
*high=(uint8_t)(temp>>8);
|
||||
}
|
||||
|
||||
// Channel value is limited to PPM_100
|
||||
uint16_t limit_channel_100(uint8_t ch)
|
||||
{
|
||||
if(Servo_data[ch]>servo_max_100)
|
||||
return servo_max_100;
|
||||
else
|
||||
if (Servo_data[ch]<servo_min_100)
|
||||
return servo_min_100;
|
||||
return Servo_data[ch];
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ const uint8_t PROGMEM data_vals[][2] = {
|
||||
{CYRF_1E_RX_OVERRIDE, 0x00}, // CRC16 enabled, no ACK
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) cyrf_config()
|
||||
static void __attribute__((unused)) DSM_cyrf_config()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&init_vals[i][0]), pgm_read_byte_near(&init_vals[i][1]));
|
||||
@@ -172,7 +172,7 @@ static void __attribute__((unused)) cyrf_config()
|
||||
CYRF_ConfigRFChannel(0x61);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) build_bind_packet()
|
||||
static void __attribute__((unused)) DSM_build_bind_packet()
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t sum = 384 - 0x10;//
|
||||
@@ -211,21 +211,21 @@ static void __attribute__((unused)) build_bind_packet()
|
||||
packet[15] = sum & 0xff;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) initialize_bind_phase()
|
||||
static void __attribute__((unused)) DSM_initialize_bind_phase()
|
||||
{
|
||||
CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random?
|
||||
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
||||
CYRF_ConfigDataCode((const uint8_t*)"\xD7\xA1\x54\xB1\x5E\x89\xAE\x86\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 16);
|
||||
build_bind_packet();
|
||||
DSM_build_bind_packet();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) cyrf_configdata()
|
||||
static void __attribute__((unused)) DSM_cyrf_configdata()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(data_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&data_vals[i][0]), pgm_read_byte_near(&data_vals[i][1]));
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) update_channels()
|
||||
static void __attribute__((unused)) DSM_update_channels()
|
||||
{
|
||||
prev_option=option;
|
||||
if(sub_protocol==DSM_AUTO)
|
||||
@@ -243,13 +243,13 @@ static void __attribute__((unused)) update_channels()
|
||||
ch_map[i]=pgm_read_byte_near(&ch_map_progmem[idx][i]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) build_data_packet(uint8_t upper)
|
||||
static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
{
|
||||
uint16_t max = 2047;
|
||||
uint8_t bits = 11;
|
||||
|
||||
if(prev_option!=option)
|
||||
update_channels();
|
||||
DSM_update_channels();
|
||||
|
||||
if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 )
|
||||
{
|
||||
@@ -288,7 +288,7 @@ static void __attribute__((unused)) build_data_packet(uint8_t upper)
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) set_sop_data_crc()
|
||||
static void __attribute__((unused)) DSM_set_sop_data_crc()
|
||||
{
|
||||
//The crc for channel '1' is NOT(mfgid[0] << 8 + mfgid[1])
|
||||
//The crc for channel '2' is (mfgid[0] << 8 + mfgid[1])
|
||||
@@ -314,7 +314,7 @@ static void __attribute__((unused)) set_sop_data_crc()
|
||||
hopping_frequency_no %=2;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) calc_dsmx_channel()
|
||||
static void __attribute__((unused)) DSM_calc_dsmx_channel()
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint32_t id = ~(((uint32_t)cyrfmfg_id[0] << 24) | ((uint32_t)cyrfmfg_id[1] << 16) | ((uint32_t)cyrfmfg_id[2] << 8) | (cyrfmfg_id[3] << 0));
|
||||
@@ -433,17 +433,17 @@ uint16_t ReadDsm()
|
||||
#endif
|
||||
case DSM_CHANSEL:
|
||||
BIND_DONE;
|
||||
cyrf_configdata();
|
||||
DSM_cyrf_configdata();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
hopping_frequency_no = 0;
|
||||
phase = DSM_CH1_WRITE_A; // in fact phase++
|
||||
set_sop_data_crc();
|
||||
DSM_set_sop_data_crc();
|
||||
return 10000;
|
||||
case DSM_CH1_WRITE_A:
|
||||
case DSM_CH1_WRITE_B:
|
||||
case DSM_CH2_WRITE_A:
|
||||
case DSM_CH2_WRITE_B:
|
||||
build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
|
||||
DSM_build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
|
||||
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
|
||||
CYRF_WriteDataPacket(packet);
|
||||
phase++; // change from WRITE to CHECK mode
|
||||
@@ -463,12 +463,12 @@ uint16_t ReadDsm()
|
||||
if (((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x22) == 0x20) || (CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80))
|
||||
{
|
||||
CYRF_Reset();
|
||||
cyrf_config();
|
||||
cyrf_configdata();
|
||||
DSM_cyrf_config();
|
||||
DSM_cyrf_configdata();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
#endif
|
||||
set_sop_data_crc();
|
||||
DSM_set_sop_data_crc();
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||
}
|
||||
@@ -510,11 +510,11 @@ uint16_t ReadDsm()
|
||||
phase = DSM_CH1_WRITE_A; //Transmit lower
|
||||
CYRF_SetTxRxMode(TX_EN); //TX mode
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); //Clear abort RX operation
|
||||
set_sop_data_crc();
|
||||
DSM_set_sop_data_crc();
|
||||
return DSM_READ_DELAY;
|
||||
#else
|
||||
// No telemetry
|
||||
set_sop_data_crc();
|
||||
DSM_set_sop_data_crc();
|
||||
if (phase == DSM_CH2_CHECK_A)
|
||||
{
|
||||
if(DSM_num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||
@@ -548,7 +548,7 @@ uint16_t initDsm()
|
||||
}
|
||||
//Hopping frequencies
|
||||
if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
||||
calc_dsmx_channel();
|
||||
DSM_calc_dsmx_channel();
|
||||
else
|
||||
{
|
||||
uint8_t tmpch[10];
|
||||
@@ -565,15 +565,15 @@ uint16_t initDsm()
|
||||
hopping_frequency[1] = tmpch[idx];
|
||||
}
|
||||
//
|
||||
cyrf_config();
|
||||
DSM_cyrf_config();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
//
|
||||
update_channels();
|
||||
DSM_update_channels();
|
||||
//
|
||||
if(IS_AUTOBIND_FLAG_on )
|
||||
{
|
||||
BIND_IN_PROGRESS;
|
||||
initialize_bind_phase();
|
||||
DSM_initialize_bind_phase();
|
||||
phase = DSM_BIND_WRITE;
|
||||
bind_counter=DSM_BIND_COUNT;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
uint8_t sign = 0x0b;
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value=map(Servo_data[CH_EATR[ch_idx * 4 + i]],servo_min_125,servo_max_125,-1600,1600);//range -1600..+1600
|
||||
int16_t value=map(Servo_data[CH_EATR[ch_idx * 4 + i]],servo_min_100,servo_max_100,-1600,1600);//range -1600..+1600
|
||||
if(value < 0)
|
||||
{
|
||||
value = -value;
|
||||
|
||||
@@ -60,9 +60,9 @@ static void __attribute__((unused)) ssv_pack_dpl(uint8_t addr[], uint8_t pid, ui
|
||||
|
||||
crc.val=0x3c18;
|
||||
for (i = 0; i < 7; ++i)
|
||||
crc.val=crc16_update(crc.val,header[i]);
|
||||
crc.val=crc16_update(crc.val,header[i],8);
|
||||
for (i = 0; i < *len; ++i)
|
||||
crc.val=crc16_update(crc.val,payload[i]);
|
||||
crc.val=crc16_update(crc.val,payload[i],8);
|
||||
|
||||
// encode payload and crc
|
||||
// xor with this:
|
||||
|
||||
@@ -19,26 +19,7 @@
|
||||
|
||||
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||
{
|
||||
// Configure cc2500 for tx mode
|
||||
//
|
||||
for(uint8_t i=0;i<36;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]);
|
||||
uint8_t val=pgm_read_byte_near(&cc2500_conf[i][1]);
|
||||
|
||||
if(reg==CC2500_0C_FSCTRL0)
|
||||
val=option;
|
||||
else
|
||||
if(reg==CC2500_1B_AGCCTRL2)
|
||||
val=bind ? 0x43 : 0x03;
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
prev_option = option ;
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
FRSKY_init_cc2500(FRSKYD_cc2500_conf);
|
||||
|
||||
CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
@@ -50,16 +31,6 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||
//#######END INIT########
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) get_chan_num(uint16_t idx)
|
||||
{
|
||||
uint8_t ret = (idx * 0x1e) % 0xeb;
|
||||
if(idx == 3 || idx == 23 || idx == 47)
|
||||
ret++;
|
||||
if(idx > 47)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky2way_build_bind_packet()
|
||||
{
|
||||
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
|
||||
@@ -71,11 +42,11 @@ static void __attribute__((unused)) frsky2way_build_bind_packet()
|
||||
packet[4] = rx_tx_addr[2];
|
||||
uint16_t idx = ((state -FRSKY_BIND) % 10) * 5;
|
||||
packet[5] = idx;
|
||||
packet[6] = get_chan_num(idx++);
|
||||
packet[7] = get_chan_num(idx++);
|
||||
packet[8] = get_chan_num(idx++);
|
||||
packet[9] = get_chan_num(idx++);
|
||||
packet[10] = get_chan_num(idx++);
|
||||
packet[6] = hopping_frequency[idx++];
|
||||
packet[7] = hopping_frequency[idx++];
|
||||
packet[8] = hopping_frequency[idx++];
|
||||
packet[9] = hopping_frequency[idx++];
|
||||
packet[10] = hopping_frequency[idx++];
|
||||
packet[11] = 0x00;
|
||||
packet[12] = 0x00;
|
||||
packet[13] = 0x00;
|
||||
@@ -124,6 +95,11 @@ static void __attribute__((unused)) frsky2way_data_frame()
|
||||
|
||||
uint16_t initFrSky_2way()
|
||||
{
|
||||
Frsky_init_hop();
|
||||
packet_count=0;
|
||||
#if defined TELEMETRY
|
||||
init_frskyd_link_telemetry();
|
||||
#endif
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
frsky2way_init(1);
|
||||
@@ -131,8 +107,7 @@ uint16_t initFrSky_2way()
|
||||
}
|
||||
else
|
||||
{
|
||||
frsky2way_init(0);
|
||||
state = FRSKY_DATA2;
|
||||
state = FRSKY_BIND_DONE;
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
@@ -147,7 +122,10 @@ uint16_t ReadFrSky_2way()
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
CC2500_Strobe(CC2500_SFRX);//0x3A
|
||||
CC2500_WriteData(packet, packet[0]+1);
|
||||
state++;
|
||||
if(IS_BIND_DONE_on)
|
||||
state = FRSKY_BIND_DONE;
|
||||
else
|
||||
state++;
|
||||
return 9000;
|
||||
}
|
||||
if (state == FRSKY_BIND_DONE)
|
||||
@@ -169,7 +147,7 @@ uint16_t ReadFrSky_2way()
|
||||
{ //telemetry receive
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
state++;
|
||||
return 1300;
|
||||
@@ -179,19 +157,35 @@ uint16_t ReadFrSky_2way()
|
||||
if (state == FRSKY_DATA1)
|
||||
{
|
||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len && len<=MAX_PKT)//27 bytes
|
||||
{
|
||||
CC2500_ReadData(pkt, len); //received telemetry packets
|
||||
if (len && len<=(0x11+3))// 20bytes
|
||||
{
|
||||
CC2500_ReadData(pkt, len); //received telemetry packets
|
||||
#if defined(TELEMETRY)
|
||||
//parse telemetry packet here
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets and buffer them.
|
||||
#endif
|
||||
}
|
||||
if(pkt[len-1] & 0x80)
|
||||
{//with valid crc
|
||||
packet_count=0;
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets and buffer them.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_count++;
|
||||
// restart sequence on missed packet - might need count or timeout instead of one missed
|
||||
if(packet_count>100)
|
||||
{//~1sec
|
||||
packet_count=0;
|
||||
#if defined TELEMETRY
|
||||
telemetry_link=0;//no link frames
|
||||
pkt[6]=0;//no user frames.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower(); // Set tx_power
|
||||
}
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||
|
||||
@@ -27,50 +27,6 @@ enum {
|
||||
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
const PROGMEM uint8_t FRSKYV_cc2500_conf[][2]={
|
||||
{ CC2500_17_MCSM1, 0x0c },
|
||||
{ CC2500_18_MCSM0, 0x18 },
|
||||
{ CC2500_06_PKTLEN, 0xff },
|
||||
{ CC2500_07_PKTCTRL1, 0x04 },
|
||||
{ CC2500_08_PKTCTRL0, 0x05 },
|
||||
{ CC2500_3E_PATABLE, 0xfe },
|
||||
{ CC2500_0B_FSCTRL1, 0x08 },
|
||||
{ CC2500_0C_FSCTRL0, 0x00 },
|
||||
{ CC2500_0D_FREQ2, 0x5c },
|
||||
{ CC2500_0E_FREQ1, 0x58 },
|
||||
{ CC2500_0F_FREQ0, 0x9d },
|
||||
{ CC2500_10_MDMCFG4, 0xaa },
|
||||
{ CC2500_11_MDMCFG3, 0x10 },
|
||||
{ CC2500_12_MDMCFG2, 0x93 },
|
||||
{ CC2500_13_MDMCFG1, 0x23 },
|
||||
{ CC2500_14_MDMCFG0, 0x7a },
|
||||
{ CC2500_15_DEVIATN, 0x41 }
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) FRSKYV_init()
|
||||
{
|
||||
for(uint8_t i=0;i<17;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&FRSKYV_cc2500_conf[i][0]);
|
||||
uint8_t val=pgm_read_byte_near(&FRSKYV_cc2500_conf[i][1]);
|
||||
if(reg==CC2500_0C_FSCTRL0)
|
||||
val=option;
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
prev_option = option ;
|
||||
for(uint8_t i=19;i<36;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]);
|
||||
uint8_t val=pgm_read_byte_near(&cc2500_conf[i][1]);
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
|
||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) FRSKYV_crc8(uint8_t result, uint8_t *data, uint8_t len)
|
||||
{
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
@@ -199,7 +155,7 @@ uint16_t initFRSKYV()
|
||||
rx_tx_addr[2]&=0x7F;
|
||||
crc8 = FRSKYV_crc8_le(rx_tx_addr+2, 2);
|
||||
|
||||
FRSKYV_init();
|
||||
FRSKY_init_cc2500(FRSKYV_cc2500_conf);
|
||||
seed = 1;
|
||||
binding_idx=0;
|
||||
phase = FRSKYV_DATA1;
|
||||
|
||||
@@ -21,85 +21,28 @@
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
uint8_t chanskip;
|
||||
uint8_t counter_rst;
|
||||
uint8_t ctr;
|
||||
uint8_t seq_last_sent;
|
||||
uint8_t seq_last_rcvd;
|
||||
|
||||
const PROGMEM uint8_t hop_data[]={
|
||||
0x02, 0xD4, 0xBB, 0xA2, 0x89,
|
||||
0x70, 0x57, 0x3E, 0x25, 0x0C,
|
||||
0xDE, 0xC5, 0xAC, 0x93, 0x7A,
|
||||
0x61, 0x48, 0x2F, 0x16, 0xE8,
|
||||
0xCF, 0xB6, 0x9D, 0x84, 0x6B,
|
||||
0x52, 0x39, 0x20, 0x07, 0xD9,
|
||||
0xC0, 0xA7, 0x8E, 0x75, 0x5C,
|
||||
0x43, 0x2A, 0x11, 0xE3, 0xCA,
|
||||
0xB1, 0x98, 0x7F, 0x66, 0x4D,
|
||||
0x34, 0x1B, 0x00, 0x1D, 0x03
|
||||
};
|
||||
|
||||
static uint8_t __attribute__((unused)) hop(uint8_t byte)
|
||||
{
|
||||
return pgm_read_byte_near(&hop_data[byte]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) set_start(uint8_t ch )
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, ch==47? 0:hop(ch));
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_init()
|
||||
{
|
||||
for(uint8_t i=0;i<36;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]);
|
||||
uint8_t val=pgm_read_byte_near(&cc2500_conf[i][1]);
|
||||
|
||||
if(reg==CC2500_06_PKTLEN)
|
||||
val=0x1E;
|
||||
else
|
||||
if(reg==CC2500_08_PKTCTRL0)
|
||||
val=0x01;
|
||||
else
|
||||
if(reg==CC2500_0B_FSCTRL1)
|
||||
val=0x0A;
|
||||
else
|
||||
if(reg==CC2500_10_MDMCFG4)
|
||||
val=0x7B;
|
||||
else
|
||||
if(reg==CC2500_11_MDMCFG3)
|
||||
val=0x61;
|
||||
else
|
||||
if(reg==CC2500_12_MDMCFG2)
|
||||
val=0x13;
|
||||
else
|
||||
if(reg==CC2500_15_DEVIATN)
|
||||
val=0x51;
|
||||
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x04);
|
||||
prev_option = option ;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
|
||||
//
|
||||
for(uint8_t c=0;c < 47;c++)
|
||||
for(uint8_t c=0;c < 48;c++)
|
||||
{//calibrate hop channels
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR,hop(c));
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);//
|
||||
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR,0x00);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
calData[47] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
//#######END INIT########
|
||||
}
|
||||
|
||||
@@ -140,27 +83,28 @@ static uint16_t __attribute__((unused)) scaleForPXX( uint8_t i )
|
||||
|
||||
static void __attribute__((unused)) frskyX_build_bind_packet()
|
||||
{
|
||||
packet[0] = 0x1D;
|
||||
packet[1] = 0x03;
|
||||
packet[2] = 0x01;
|
||||
//
|
||||
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] = hop(idx++);
|
||||
packet[7] = hop(idx++);
|
||||
packet[8] = hop(idx++);
|
||||
packet[9] = hop(idx++);
|
||||
packet[10] = hop(idx++);
|
||||
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;
|
||||
//
|
||||
memset(&packet[13], 0, 15);
|
||||
uint16_t lcrc = crc_x(&packet[3], 25);
|
||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||
memset(&packet[13], 0, limit - 13);
|
||||
uint16_t lcrc = crc_x(&packet[3], limit-3);
|
||||
//
|
||||
packet[28] = lcrc >> 8;
|
||||
packet[29] = lcrc;
|
||||
packet[limit++] = lcrc >> 8;
|
||||
packet[limit] = lcrc;
|
||||
//
|
||||
}
|
||||
|
||||
@@ -173,13 +117,13 @@ static void __attribute__((unused)) frskyX_data_frame()
|
||||
uint16_t chan_1 ;
|
||||
uint8_t startChan = 0;
|
||||
//
|
||||
packet[0] = 0x1D;
|
||||
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] = (ctr<<6)+hopping_frequency_no;
|
||||
packet[5] = counter_rst;
|
||||
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
|
||||
@@ -213,17 +157,18 @@ static void __attribute__((unused)) frskyX_data_frame()
|
||||
else if (seq_last_rcvd == 0x00)
|
||||
seq_last_sent = 1;
|
||||
|
||||
if(sub_protocol== CH_8 )// in X8 mode send only 8ch every 9ms
|
||||
if(sub_protocol & 1 )// in X8 mode send only 8ch every 9ms
|
||||
lpass = 0 ;
|
||||
else
|
||||
lpass += 1 ;
|
||||
|
||||
for (uint8_t i=22;i<28;i++)
|
||||
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], 25);
|
||||
uint16_t lcrc = crc_x(&packet[3], limit-3);
|
||||
|
||||
packet[28]=lcrc>>8;//high byte
|
||||
packet[29]=lcrc;//low byte
|
||||
packet[limit++]=lcrc>>8;//high byte
|
||||
packet[limit]=lcrc;//low byte
|
||||
}
|
||||
|
||||
uint16_t ReadFrSkyX()
|
||||
@@ -238,7 +183,10 @@ uint16_t ReadFrSkyX()
|
||||
frskyX_build_bind_packet();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteData(packet, packet[0]+1);
|
||||
state++;
|
||||
if(IS_BIND_DONE_on)
|
||||
state = FRSKY_BIND_DONE;
|
||||
else
|
||||
state++;
|
||||
return 9000;
|
||||
case FRSKY_BIND_DONE:
|
||||
initialize_data(0);
|
||||
@@ -276,7 +224,7 @@ uint16_t ReadFrSkyX()
|
||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
||||
{
|
||||
counter=0;
|
||||
packet_count=0;
|
||||
CC2500_ReadData(pkt, len);
|
||||
#if defined TELEMETRY
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
||||
@@ -286,13 +234,13 @@ uint16_t ReadFrSkyX()
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
packet_count++;
|
||||
// restart sequence on missed packet - might need count or timeout instead of one missed
|
||||
if(counter>100)
|
||||
if(packet_count>100)
|
||||
{//~1sec
|
||||
seq_last_sent = 0;
|
||||
seq_last_rcvd = 8;
|
||||
counter=0;
|
||||
packet_count=0;
|
||||
#if defined TELEMETRY
|
||||
telemetry_lost=1;
|
||||
#endif
|
||||
@@ -307,18 +255,17 @@ uint16_t ReadFrSkyX()
|
||||
|
||||
uint16_t initFrSkyX()
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
Frsky_init_hop();
|
||||
packet_count=0;
|
||||
while(!chanskip)
|
||||
chanskip=random(0xfefefefe)%47;
|
||||
while((chanskip-ctr)%4)
|
||||
ctr=(ctr+1)%4;
|
||||
|
||||
counter_rst=(chanskip-ctr)>>2;
|
||||
|
||||
//for test***************
|
||||
//rx_tx_addr[3]=0xB3;
|
||||
//rx_tx_addr[2]=0xFD;
|
||||
//************************
|
||||
frskyX_init();
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
//
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
|
||||
158
Multiprotocol/GW008_nrf24l01.ino
Normal file
158
Multiprotocol/GW008_nrf24l01.ino
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
// Compatible with Global Drone GW008 protocol.
|
||||
// There are 3 versions of this small quad, this protocol is for the one with a XNS104 IC in the stock Tx and PAN159CY IC in the quad (SOCs with built-in xn297 compatible RF).
|
||||
// The xn297 version is compatible with the CX10 protocol (green pcb).
|
||||
// The LT8910 version is not supported yet.
|
||||
|
||||
#if defined(GW008_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define GW008_INITIAL_WAIT 500
|
||||
#define GW008_PACKET_PERIOD 2400
|
||||
#define GW008_RF_BIND_CHANNEL 2
|
||||
#define GW008_PAYLOAD_SIZE 15
|
||||
|
||||
enum {
|
||||
GW008_BIND1,
|
||||
GW008_BIND2,
|
||||
GW008_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) send_packet(uint8_t bind)
|
||||
{
|
||||
packet[0] = rx_tx_addr[0];
|
||||
if(bind)
|
||||
{
|
||||
packet[1] = 0x55;
|
||||
packet[2] = hopping_frequency[0];
|
||||
packet[3] = hopping_frequency[1];
|
||||
packet[4] = hopping_frequency[2];
|
||||
packet[5] = hopping_frequency[3];
|
||||
memset(&packet[6], 0, 7);
|
||||
packet[13] = 0xaa;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[1] = 0x01 | GET_FLAG(AUX1, 0x40); // flip
|
||||
packet[2] = convert_channel_8b_scale(AILERON , 200, 0); // aileron
|
||||
packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
|
||||
packet[4] = convert_channel_8b_scale(RUDDER , 200, 0); // rudder
|
||||
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
|
||||
packet[6] = 0xaa;
|
||||
packet[7] = 0x02; // max rate
|
||||
packet[8] = 0x00;
|
||||
packet[9] = 0x00;
|
||||
packet[10]= 0x00;
|
||||
packet[11]= 0x00;
|
||||
packet[12]= 0x00;
|
||||
packet[13]= rx_tx_addr[2];
|
||||
}
|
||||
packet[14] = rx_tx_addr[1];
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? GW008_RF_BIND_CHANNEL : hopping_frequency[(hopping_frequency_no++)/2]);
|
||||
hopping_frequency_no %= 8;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0, 0x3c7d);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GW008_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, GW008_PAYLOAD_SIZE+2); // payload + 2 bytes for pcf
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
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); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GW008_initialize_txid()
|
||||
{
|
||||
uint32_t lfsr = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
hopping_frequency[i] = 0x10 + ((lfsr >> (i*8)) % 0x37);
|
||||
}
|
||||
|
||||
uint16_t GW008_callback()
|
||||
{
|
||||
switch(phase)
|
||||
{
|
||||
case GW008_BIND1:
|
||||
if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) && // RX fifo data ready
|
||||
XN297_ReadEnhancedPayload(packet, GW008_PAYLOAD_SIZE) == GW008_PAYLOAD_SIZE && // check payload size
|
||||
packet[0] == rx_tx_addr[0] && packet[14] == rx_tx_addr[1]) // check tx id
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
rx_tx_addr[2] = packet[13];
|
||||
BIND_DONE;
|
||||
phase = GW008_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
send_packet(1);
|
||||
phase = GW008_BIND2;
|
||||
return 300;
|
||||
}
|
||||
break;
|
||||
case GW008_BIND2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
||||
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
phase = GW008_BIND1;
|
||||
return 5000;
|
||||
break;
|
||||
case GW008_DATA:
|
||||
send_packet(0);
|
||||
break;
|
||||
}
|
||||
return GW008_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initGW008()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
GW008_initialize_txid();
|
||||
phase = GW008_BIND1;
|
||||
GW008_init();
|
||||
hopping_frequency_no = 0;
|
||||
return GW008_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -352,7 +352,7 @@ uint16_t initHubsan() {
|
||||
packet_count=0;
|
||||
id_data=ID_NORMAL;
|
||||
#ifdef HUBSAN_HUB_TELEMETRY
|
||||
init_hub_telemetry();
|
||||
init_frskyd_link_telemetry();
|
||||
#endif
|
||||
return 10000;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,8 @@ uint16_t initMT99XX(void)
|
||||
bind_counter = MT99XX_BIND_COUNT;
|
||||
|
||||
memcpy(hopping_frequency,"\x02\x48\x0C\x3e\x16\x34\x20\x2A\x2A\x20\x34\x16\x3e\x0c\x48\x02",16);
|
||||
|
||||
hopping_frequency_no=0;
|
||||
|
||||
MT99XX_initialize_txid();
|
||||
MT99XX_init();
|
||||
|
||||
|
||||
@@ -598,7 +598,7 @@ clean_list :
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
$(REMOVE) $(CPPSRC:%.cpp=%.o)
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
||||
13,CG023,CG023,YD829,H8_3D
|
||||
14,Bayang,Bayang,H8S3D
|
||||
15,FrskyX,CH_16,CH_8
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||
16,ESky
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH
|
||||
@@ -26,4 +26,7 @@
|
||||
26,HONTAI,HONTAI,JJRCX1,X5C1,FQ777_951
|
||||
27,OpnLrs
|
||||
28,AFHD2SA,PWM_IBUS,PPM_IBUS,PWM_SBUS,PPM_SBUS
|
||||
29,Q2X2,Q242,Q282
|
||||
29,Q2X2,Q222,Q242,Q282
|
||||
30,WK2x01,WK2801,WK2401,W6_5_1,W6_6_1,W6_HEL,W6_HEL_I
|
||||
31,Q303,Q303,CX35,CX10D,CX10WD
|
||||
32,GW008
|
||||
@@ -34,6 +34,8 @@ extern uint16_t DevoInit(void) ;
|
||||
extern uint16_t devo_callback(void) ;
|
||||
extern uint16_t initJ6Pro(void) ;
|
||||
extern uint16_t ReadJ6Pro(void) ;
|
||||
extern uint16_t WK_setup(void) ;
|
||||
extern uint16_t WK_cb(void) ;
|
||||
|
||||
extern void randomSeed(unsigned int seed) ;
|
||||
extern long random(long howbig) ;
|
||||
@@ -46,7 +48,7 @@ extern void delayMilliseconds(unsigned long ms) ;
|
||||
extern void init(void) ;
|
||||
|
||||
extern void modules_reset() ;
|
||||
extern void Update_All() ;
|
||||
extern uint8_t Update_All() ;
|
||||
extern void tx_pause() ;
|
||||
extern void tx_resume() ;
|
||||
extern void TelemetryUpdate() ;
|
||||
@@ -139,13 +141,14 @@ void init()
|
||||
|
||||
#include "Multiprotocol.ino"
|
||||
#include "SPI.ino"
|
||||
#include "Convert.ino"
|
||||
#include "Common.ino"
|
||||
#include "Arduino.ino"
|
||||
|
||||
#include "cyrf6936_SPI.ino"
|
||||
#include "DSM_cyrf6936.ino"
|
||||
#include "Devo_cyrf6936.ino"
|
||||
#include "J6Pro_cyrf6936.ino"
|
||||
#include "WK2x01_cyrf6936.ino"
|
||||
|
||||
#include "Telemetry.ino"
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
// Version
|
||||
//******************
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 16
|
||||
#define VERSION_PATCH_LEVEL 1
|
||||
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 6
|
||||
#define VERSION_PATCH_LEVEL 20
|
||||
//******************
|
||||
// Protocols
|
||||
//******************
|
||||
@@ -55,6 +55,9 @@ enum PROTOCOLS
|
||||
MODE_OPENLRS = 27, // =>OpenLRS hardware
|
||||
MODE_AFHDS2A = 28, // =>A7105
|
||||
MODE_Q2X2 = 29, // =>NRF24L01, extension of CX-10 protocol
|
||||
MODE_WK2x01 = 30, // =>CYRF6936
|
||||
MODE_Q303 = 31, // =>NRF24L01
|
||||
MODE_GW008 = 32, // =>NRF24L01
|
||||
MODE_CABELL = 33, // =>NRF24L01
|
||||
};
|
||||
|
||||
@@ -156,6 +159,8 @@ enum FRSKYX
|
||||
{
|
||||
CH_16 = 0,
|
||||
CH_8 = 1,
|
||||
EU_16 = 2,
|
||||
EU_8 = 3,
|
||||
};
|
||||
enum HONTAI
|
||||
{
|
||||
@@ -174,6 +179,22 @@ enum FY326
|
||||
FY326 = 0,
|
||||
FY319 = 1,
|
||||
};
|
||||
enum WK2x01
|
||||
{
|
||||
WK2801 = 0,
|
||||
WK2401 = 1,
|
||||
W6_5_1 = 2,
|
||||
W6_6_1 = 3,
|
||||
W6_HEL = 4,
|
||||
W6_HEL_I= 5,
|
||||
};
|
||||
enum Q303
|
||||
{
|
||||
Q303 = 0,
|
||||
CX35 = 1,
|
||||
CX10D = 2,
|
||||
CX10WD = 3,
|
||||
};
|
||||
enum CABELL
|
||||
{
|
||||
CABELL_V3 = 0,
|
||||
@@ -271,6 +292,17 @@ enum MultiPacketTypes {
|
||||
#define INPUT_SIGNAL_on protocol_flags2 |= _BV(5)
|
||||
#define IS_INPUT_SIGNAL_on ( ( protocol_flags2 & _BV(5) ) !=0 )
|
||||
#define IS_INPUT_SIGNAL_off ( ( protocol_flags2 & _BV(5) ) ==0 )
|
||||
//Bind from channel
|
||||
#define BIND_CH_PREV_off protocol_flags2 &= ~_BV(6)
|
||||
#define BIND_CH_PREV_on protocol_flags2 |= _BV(6)
|
||||
#define IS_BIND_CH_PREV_on ( ( protocol_flags2 & _BV(6) ) !=0 )
|
||||
#define IS_BIND_CH_PREV_off ( ( protocol_flags2 & _BV(6) ) ==0 )
|
||||
//Wait for bind
|
||||
#define WAIT_BIND_off protocol_flags2 &= ~_BV(7)
|
||||
#define WAIT_BIND_on protocol_flags2 |= _BV(7)
|
||||
#define IS_WAIT_BIND_on ( ( protocol_flags2 & _BV(7) ) !=0 )
|
||||
#define IS_WAIT_BIND_off ( ( protocol_flags2 & _BV(7) ) ==0 )
|
||||
|
||||
|
||||
//********************
|
||||
//*** Blink timing ***
|
||||
@@ -278,8 +310,11 @@ enum MultiPacketTypes {
|
||||
#define BLINK_BIND_TIME 100
|
||||
#define BLINK_SERIAL_TIME 500
|
||||
#define BLINK_PPM_TIME 1000
|
||||
#define BLINK_BAD_PROTO_TIME_LOW 1000
|
||||
#define BLINK_BAD_PROTO_TIME_HIGH 50
|
||||
#define BLINK_BAD_PROTO_TIME_LOW 1000
|
||||
#define BLINK_WAIT_BIND_TIME_HIGH 1000
|
||||
#define BLINK_WAIT_BIND_TIME_LOW 100
|
||||
|
||||
|
||||
//*******************
|
||||
//*** AUX flags ***
|
||||
@@ -449,6 +484,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
OpenLRS 27
|
||||
AFHDS2A 28
|
||||
Q2X2 29
|
||||
WK2x01 30
|
||||
Q303 31
|
||||
GW008 32
|
||||
CABELL 33
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
@@ -521,6 +559,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==FRSKYX
|
||||
CH_16 0
|
||||
CH_8 1
|
||||
EU_16 2
|
||||
EU_8 3
|
||||
sub_protocol==HONTAI
|
||||
FORMAT_HONTAI 0
|
||||
FORMAT_JJRCX1 1
|
||||
@@ -537,6 +577,18 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==FY326
|
||||
FY326 0
|
||||
FY319 1
|
||||
sub_protocol==WK2x01
|
||||
WK2801 0
|
||||
WK2401 1
|
||||
W6_5_1 2
|
||||
W6_6_1 3
|
||||
W6_HEL 4
|
||||
W6_HEL_I 5
|
||||
sub_protocol==Q303
|
||||
Q303 0
|
||||
CX35 1
|
||||
CX10D 2
|
||||
CX10WD 3
|
||||
sub_protocol==CABELL
|
||||
CABELL_V3 0,
|
||||
CABELL_SET_FAIL_SAFE 6,
|
||||
@@ -544,7 +596,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
|
||||
Power value => 0x80 0=High/1=Low
|
||||
Stream[3] = option_protocol;
|
||||
option_protocol value is -127..127
|
||||
option_protocol value is -128..127
|
||||
Stream[4] to [25] = Channels
|
||||
16 Channels on 11 bits (0..2047)
|
||||
0 -125%
|
||||
@@ -555,18 +607,41 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
Channels bits are concatenated to fit in 22 bytes like in SBUS protocol
|
||||
*/
|
||||
/*
|
||||
Multiprotocol telemetry definition
|
||||
Multimodule Status
|
||||
Based on #define MULTI_STATUS
|
||||
|
||||
Serial: 100000 Baud 8e2 (same as input)
|
||||
|
||||
Format: header (2 bytes) + data (variable)
|
||||
[0] = 'M' (0x4d)
|
||||
[1] Length (excluding the 2 header bytes)
|
||||
[2-xx] data
|
||||
|
||||
Type = 0x01 Multimodule Status:
|
||||
[2] Flags
|
||||
0x01 = Input signal detected
|
||||
0x02 = Serial mode enabled
|
||||
0x04 = protocol is valid
|
||||
0x08 = module is in binding mode
|
||||
0x10 = module waits a bind event to load the protocol
|
||||
[3] major
|
||||
[4] minor
|
||||
[5] revision
|
||||
[6] patchlevel,
|
||||
version of multi code, should be displayed as major.minor.revision.patchlevel
|
||||
*/
|
||||
/*
|
||||
Multiprotocol telemetry definition for OpenTX
|
||||
Based on #define MULTI_TELEMETRY enables OpenTX to get the multimodule status and select the correct telemetry type automatically.
|
||||
|
||||
Serial: 100000 Baud 8e2 (same as input)
|
||||
|
||||
TLV Protocol (type, length, value), allows a TX to ignore unknown messages
|
||||
|
||||
Format: header (4 byte) + data (variable)
|
||||
|
||||
[0] = 'M' (0x4d)
|
||||
[1] = 'P' (0x50)
|
||||
|
||||
|
||||
The first byte is deliberatly chosen to be different from other telemetry protocols
|
||||
(e.g. 0xAA for DSM/Multi, 0xAA for FlySky and 0x7e for Frsky) to allow a TX to detect
|
||||
the telemetry format of older versions
|
||||
@@ -576,41 +651,41 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
|
||||
[4-xx] data
|
||||
|
||||
|
||||
Type = 0x01 Multimodule Status:
|
||||
Type = 0x01 Multimodule Status:
|
||||
[4] Flags
|
||||
0x01 = Input signal detected
|
||||
0x02 = Serial mode enabled
|
||||
0x04 = protocol is valid
|
||||
0x08 = module is in binding mode
|
||||
0x10 = module waits a bind event to load the protocol
|
||||
[5] major
|
||||
[6] minor
|
||||
[7-8] patchlevel
|
||||
version of multi code, should be displayed as major.minor.patchlevel
|
||||
|
||||
[7] revision
|
||||
[8] patchlevel,
|
||||
version of multi code, should be displayed as major.minor.revision.patchlevel
|
||||
|
||||
more information can be added by specifing a longer length of the type, the TX will just ignore these bytes
|
||||
|
||||
|
||||
Type 0x02 Frksy S.port telemetry
|
||||
Type 0x03 Frsky Hub telemetry
|
||||
Type 0x02 Frksy S.port telemetry
|
||||
Type 0x03 Frsky Hub telemetry
|
||||
|
||||
*No* usual frsky byte stuffing and without start/stop byte (0x7e)
|
||||
|
||||
|
||||
Type 0x04 Spektrum telemetry data
|
||||
Type 0x04 Spektrum telemetry data
|
||||
data[0] RSSI
|
||||
data[1-15] telemetry data
|
||||
|
||||
Type 0x05 DSM bind data
|
||||
Type 0x05 DSM bind data
|
||||
data[0-16] DSM bind data
|
||||
|
||||
technically DSM bind data is only 10 bytes but multi send 16
|
||||
like with telemtry, check length field)
|
||||
|
||||
Type 0x06 Flysky AFHDS2 telemetry data
|
||||
Type 0x06 Flysky AFHDS2 telemetry data
|
||||
length: 29
|
||||
data[0] = RSSI value
|
||||
data[1-28] telemetry data
|
||||
|
||||
*/
|
||||
*/
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
//Multiprotocol module configuration file
|
||||
#include "_Config.h"
|
||||
#ifdef __arm__
|
||||
#define STM32_BOARD // Let's automatically select this board if arm is selected since this is the only one for now...
|
||||
#endif
|
||||
#include "Pins.h"
|
||||
#include "TX_Def.h"
|
||||
#include "Validate.h"
|
||||
@@ -76,7 +79,7 @@ uint16_t packet_period;
|
||||
uint8_t packet_count;
|
||||
uint8_t packet_sent;
|
||||
uint8_t packet_length;
|
||||
uint8_t hopping_frequency[23];
|
||||
uint8_t hopping_frequency[50];
|
||||
uint8_t *hopping_frequency_ptr;
|
||||
uint8_t hopping_frequency_no=0;
|
||||
uint8_t rf_ch_num;
|
||||
@@ -140,16 +143,29 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
||||
#endif
|
||||
uint8_t pass = 0;
|
||||
uint8_t pktt[MAX_PKT];//telemetry receiving packets
|
||||
#ifndef BASH_SERIAL
|
||||
#define TXBUFFER_SIZE 32
|
||||
#ifdef BASH_SERIAL
|
||||
// For bit-bashed serial output
|
||||
#define TXBUFFER_SIZE 128
|
||||
volatile struct t_serial_bash
|
||||
{
|
||||
uint8_t head ;
|
||||
uint8_t tail ;
|
||||
uint8_t data[TXBUFFER_SIZE] ;
|
||||
uint8_t busy ;
|
||||
uint8_t speed ;
|
||||
} SerialControl ;
|
||||
#else
|
||||
#define TXBUFFER_SIZE 64
|
||||
volatile uint8_t tx_buff[TXBUFFER_SIZE];
|
||||
volatile uint8_t tx_head=0;
|
||||
volatile uint8_t tx_tail=0;
|
||||
#endif // BASH_SERIAL
|
||||
uint8_t v_lipo1;
|
||||
uint8_t v_lipo2;
|
||||
int16_t RSSI_dBm;
|
||||
uint8_t RX_RSSI;
|
||||
uint8_t TX_RSSI;
|
||||
uint8_t RX_LQI;
|
||||
uint8_t TX_LQI;
|
||||
uint8_t telemetry_link=0;
|
||||
uint8_t telemetry_counter=0;
|
||||
uint8_t telemetry_lost;
|
||||
@@ -219,17 +235,17 @@ void setup()
|
||||
// outputs
|
||||
SDI_output;
|
||||
SCLK_output;
|
||||
#ifdef A7105_INSTALLED
|
||||
#ifdef A7105_CSN_pin
|
||||
A7105_CSN_output;
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#ifdef CC25_CSN_pin
|
||||
CC25_CSN_output;
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#ifdef CYRF_CSN_pin
|
||||
CYRF_RST_output;
|
||||
CYRF_CSN_output;
|
||||
#endif
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#ifdef NRF_CSN_pin
|
||||
NRF_CSN_output;
|
||||
#endif
|
||||
PE1_output;
|
||||
@@ -252,16 +268,16 @@ void setup()
|
||||
#endif
|
||||
|
||||
// Set Chip selects
|
||||
#ifdef A7105_INSTALLED
|
||||
#ifdef A7105_CSN_pin
|
||||
A7105_CSN_on;
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#ifdef CC25_CSN_pin
|
||||
CC25_CSN_on;
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#ifdef CYRF_CSN_pin
|
||||
CYRF_CSN_on;
|
||||
#endif
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#ifdef NRF_CSN_pin
|
||||
NRF_CSN_on;
|
||||
#endif
|
||||
// Set SPI lines
|
||||
@@ -380,13 +396,13 @@ void loop()
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(remote_callback==0 || diff>2*200)
|
||||
if(remote_callback==0 || IS_WAIT_BIND_on || diff>2*200)
|
||||
{
|
||||
do
|
||||
{
|
||||
Update_All();
|
||||
}
|
||||
while(remote_callback==0);
|
||||
while(remote_callback==0 || IS_WAIT_BIND_on);
|
||||
}
|
||||
#ifndef STM32_BOARD
|
||||
if( (TIFR1 & OCF1A_bm) != 0)
|
||||
@@ -411,7 +427,7 @@ void loop()
|
||||
{
|
||||
TX_MAIN_PAUSE_on;
|
||||
tx_pause();
|
||||
if(IS_INPUT_SIGNAL_on)
|
||||
if(IS_INPUT_SIGNAL_on && remote_callback!=0)
|
||||
next_callback=remote_callback();
|
||||
else
|
||||
next_callback=2000; // No PPM/serial signal check again in 2ms...
|
||||
@@ -428,9 +444,11 @@ void loop()
|
||||
TIMER2_BASE->SR &= ~TIMER_SR_CC1IF; //clear compare Flag
|
||||
#endif
|
||||
sei(); // enable global int
|
||||
Update_All();
|
||||
if(IS_CHANGE_PROTOCOL_FLAG_on)
|
||||
break; // Protocol has been changed
|
||||
if(Update_All()) // Protocol changed?
|
||||
{
|
||||
next_callback=0; // Launch new protocol ASAP
|
||||
break;
|
||||
}
|
||||
#ifndef STM32_BOARD
|
||||
while((TIFR1 & OCF1A_bm) == 0); // wait 2ms...
|
||||
#else
|
||||
@@ -454,18 +472,13 @@ void loop()
|
||||
}
|
||||
}
|
||||
|
||||
void Update_All()
|
||||
uint8_t Update_All()
|
||||
{
|
||||
#ifdef ENABLE_SERIAL
|
||||
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
|
||||
{
|
||||
update_serial_data(); // Update protocol and data
|
||||
if(IS_CHANGE_PROTOCOL_FLAG_on)
|
||||
{ // Protocol needs to be changed
|
||||
LED_off; //led off during protocol init
|
||||
modules_reset(); //reset all modules
|
||||
protocol_init(); //init new protocol
|
||||
}
|
||||
update_channels_aux();
|
||||
INPUT_SIGNAL_on; //valid signal received
|
||||
last_signal=millis();
|
||||
}
|
||||
@@ -473,7 +486,7 @@ void Update_All()
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
|
||||
{
|
||||
for(uint8_t i=0;i<NUM_CHN;i++)
|
||||
for(uint8_t i=0;i<MAX_PPM_CHANNELS;i++)
|
||||
{ // update servo data without interrupts to prevent bad read in protocols
|
||||
uint16_t temp_ppm ;
|
||||
cli(); // disable global int
|
||||
@@ -484,18 +497,42 @@ void Update_All()
|
||||
Servo_data[i]= temp_ppm ;
|
||||
}
|
||||
PPM_FLAG_off; // wait for next frame before update
|
||||
update_channels_aux();
|
||||
INPUT_SIGNAL_on; //valid signal received
|
||||
last_signal=millis();
|
||||
}
|
||||
#endif //ENABLE_PPM
|
||||
update_channels_aux();
|
||||
update_led_status();
|
||||
#if defined(TELEMETRY)
|
||||
#if !defined(MULTI_TELEMETRY)
|
||||
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
||||
if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) )
|
||||
#endif
|
||||
TelemetryUpdate();
|
||||
TelemetryUpdate();
|
||||
#endif
|
||||
update_led_status();
|
||||
#ifdef ENABLE_BIND_CH
|
||||
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && Servo_data[BIND_CH-1]>PPM_MAX_COMMAND && Servo_data[THROTTLE]<(servo_min_100+25))
|
||||
{ // Autobind is on and BIND_CH went up and Throttle is low
|
||||
CHANGE_PROTOCOL_FLAG_on; //reload protocol to rebind
|
||||
BIND_CH_PREV_on;
|
||||
}
|
||||
if(IS_BIND_CH_PREV_on && Servo_data[BIND_CH-1]<PPM_MIN_COMMAND)
|
||||
{
|
||||
BIND_CH_PREV_off;
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO)
|
||||
if(protocol==MODE_FRSKYD || protocol==MODE_FRSKYX || protocol==MODE_FRSKYV)
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
if(bind_counter>2)
|
||||
bind_counter=2;
|
||||
}
|
||||
#endif //ENABLE_BIND_CH
|
||||
if(IS_CHANGE_PROTOCOL_FLAG_on)
|
||||
{ // Protocol needs to be changed or relaunched for bind
|
||||
protocol_init(); //init new protocol
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update channels direction and Servo_AUX flags based on servo AUX positions
|
||||
@@ -546,9 +583,19 @@ static void update_led_status(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IS_BIND_DONE_on)
|
||||
LED_off; //bind completed force led on
|
||||
blink+=BLINK_BIND_TIME; //blink fastly during binding
|
||||
if(IS_WAIT_BIND_on)
|
||||
{
|
||||
if(IS_LED_on) //flash to indicate WAIT_BIND
|
||||
blink+=BLINK_WAIT_BIND_TIME_LOW;
|
||||
else
|
||||
blink+=BLINK_WAIT_BIND_TIME_HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IS_BIND_DONE_on)
|
||||
LED_off; //bind completed force led on
|
||||
blink+=BLINK_BIND_TIME; //blink fastly during binding
|
||||
}
|
||||
}
|
||||
LED_toggle;
|
||||
}
|
||||
@@ -615,252 +662,312 @@ void start_timer2()
|
||||
// Protocol start
|
||||
static void protocol_init()
|
||||
{
|
||||
uint16_t next_callback=0; // Default is immediate call back
|
||||
remote_callback = 0;
|
||||
|
||||
// reset telemetry
|
||||
#ifdef TELEMETRY
|
||||
tx_pause();
|
||||
pass=0;
|
||||
telemetry_link=0;
|
||||
telemetry_lost=1;
|
||||
#ifndef BASH_SERIAL
|
||||
tx_tail=0;
|
||||
tx_head=0;
|
||||
#endif
|
||||
TX_RX_PAUSE_off;
|
||||
TX_MAIN_PAUSE_off;
|
||||
#endif
|
||||
|
||||
//Set global ID and rx_tx_addr
|
||||
MProtocol_id = RX_num + MProtocol_id_master;
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
|
||||
blink=millis();
|
||||
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
AUTOBIND_FLAG_on;
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
BIND_IN_PROGRESS; // Indicates bind in progress for blinking bind led
|
||||
else
|
||||
BIND_DONE;
|
||||
|
||||
PE1_on; //NRF24L01 antenna RF3 by default
|
||||
PE2_off; //NRF24L01 antenna RF3 by default
|
||||
|
||||
switch(protocol) // Init the requested protocol
|
||||
static uint16_t next_callback;
|
||||
if(IS_WAIT_BIND_off)
|
||||
{
|
||||
#ifdef A7105_INSTALLED
|
||||
#if defined(FLYSKY_A7105_INO)
|
||||
case MODE_FLYSKY:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initFlySky();
|
||||
remote_callback = ReadFlySky;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO)
|
||||
case MODE_AFHDS2A:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initAFHDS2A();
|
||||
remote_callback = ReadAFHDS2A;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HUBSAN_A7105_INO)
|
||||
case MODE_HUBSAN:
|
||||
PE1_off; //antenna RF1
|
||||
if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed.
|
||||
next_callback = initHubsan();
|
||||
remote_callback = ReadHubsan;
|
||||
break;
|
||||
remote_callback = 0; // No protocol
|
||||
next_callback=0; // Default is immediate call back
|
||||
LED_off; // Led off during protocol init
|
||||
modules_reset(); // Reset all modules
|
||||
|
||||
// reset telemetry
|
||||
#ifdef TELEMETRY
|
||||
tx_pause();
|
||||
pass=0;
|
||||
telemetry_link=0;
|
||||
telemetry_lost=1;
|
||||
#ifdef BASH_SERIAL
|
||||
TIMSK0 = 0 ; // Stop all timer 0 interrupts
|
||||
#ifdef INVERT_SERIAL
|
||||
SERIAL_TX_off;
|
||||
#else
|
||||
SERIAL_TX_on;
|
||||
#endif
|
||||
SerialControl.tail=0;
|
||||
SerialControl.head=0;
|
||||
SerialControl.busy=0;
|
||||
#else
|
||||
tx_tail=0;
|
||||
tx_head=0;
|
||||
#endif
|
||||
TX_RX_PAUSE_off;
|
||||
TX_MAIN_PAUSE_off;
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
case MODE_FRSKYD:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFrSky_2way();
|
||||
remote_callback = ReadFrSky_2way;
|
||||
break;
|
||||
|
||||
//Set global ID and rx_tx_addr
|
||||
MProtocol_id = RX_num + MProtocol_id_master;
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
|
||||
blink=millis();
|
||||
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
AUTOBIND_FLAG_on;
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
BIND_IN_PROGRESS; // Indicates bind in progress for blinking bind led
|
||||
else
|
||||
BIND_DONE;
|
||||
|
||||
PE1_on; //NRF24L01 antenna RF3 by default
|
||||
PE2_off; //NRF24L01 antenna RF3 by default
|
||||
|
||||
switch(protocol) // Init the requested protocol
|
||||
{
|
||||
#ifdef A7105_INSTALLED
|
||||
#if defined(FLYSKY_A7105_INO)
|
||||
case MODE_FLYSKY:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initFlySky();
|
||||
remote_callback = ReadFlySky;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO)
|
||||
case MODE_AFHDS2A:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initAFHDS2A();
|
||||
remote_callback = ReadAFHDS2A;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HUBSAN_A7105_INO)
|
||||
case MODE_HUBSAN:
|
||||
PE1_off; //antenna RF1
|
||||
if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed.
|
||||
next_callback = initHubsan();
|
||||
remote_callback = ReadHubsan;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(FRSKYV_CC2500_INO)
|
||||
case MODE_FRSKYV:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFRSKYV();
|
||||
remote_callback = ReadFRSKYV;
|
||||
break;
|
||||
#ifdef CC2500_INSTALLED
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
case MODE_FRSKYD:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFrSky_2way();
|
||||
remote_callback = ReadFrSky_2way;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FRSKYV_CC2500_INO)
|
||||
case MODE_FRSKYV:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFRSKYV();
|
||||
remote_callback = ReadFRSKYV;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
case MODE_FRSKYX:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFrSkyX();
|
||||
remote_callback = ReadFrSkyX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
case MODE_SFHSS:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initSFHSS();
|
||||
remote_callback = ReadSFHSS;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
case MODE_FRSKYX:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFrSkyX();
|
||||
remote_callback = ReadFrSkyX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
case MODE_SFHSS:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initSFHSS();
|
||||
remote_callback = ReadSFHSS;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#if defined(DSM_CYRF6936_INO)
|
||||
case MODE_DSM:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initDsm();
|
||||
//Servo_data[2]=1500;//before binding
|
||||
remote_callback = ReadDsm;
|
||||
break;
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
case MODE_DEVO:
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select) //PPM mode
|
||||
{
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#if defined(DSM_CYRF6936_INO)
|
||||
case MODE_DSM:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initDsm();
|
||||
//Servo_data[2]=1500;//before binding
|
||||
remote_callback = ReadDsm;
|
||||
break;
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
case MODE_DEVO:
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select) //PPM mode
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)(30+mode_select),0x00); // reset to autobind mode for the current model
|
||||
option=0;
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)(30+mode_select),0x00); // reset to autobind mode for the current model
|
||||
option=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
option=eeprom_read_byte((EE_ADDR)(30+mode_select)); // load previous mode: autobind or fixed id
|
||||
if(option!=1) option=0; // if not fixed id mode then it should be autobind
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
option=eeprom_read_byte((EE_ADDR)(30+mode_select)); // load previous mode: autobind or fixed id
|
||||
if(option!=1) option=0; // if not fixed id mode then it should be autobind
|
||||
#endif //ENABLE_PPM
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = DevoInit();
|
||||
remote_callback = devo_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WK2x01_CYRF6936_INO)
|
||||
case MODE_WK2x01:
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select) //PPM mode
|
||||
{
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)(30+mode_select),0x00); // reset to autobind mode for the current model
|
||||
option=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
option=eeprom_read_byte((EE_ADDR)(30+mode_select)); // load previous mode: autobind or fixed id
|
||||
if(option!=1) option=0; // if not fixed id mode then it should be autobind
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //ENABLE_PPM
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = DevoInit();
|
||||
remote_callback = devo_callback;
|
||||
break;
|
||||
#endif //ENABLE_PPM
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = WK_setup();
|
||||
remote_callback = WK_cb;
|
||||
break;
|
||||
#endif
|
||||
#if defined(J6PRO_CYRF6936_INO)
|
||||
case MODE_J6PRO:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initJ6Pro();
|
||||
remote_callback = ReadJ6Pro;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(J6PRO_CYRF6936_INO)
|
||||
case MODE_J6PRO:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initJ6Pro();
|
||||
remote_callback = ReadJ6Pro;
|
||||
break;
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
case MODE_HISKY:
|
||||
next_callback=initHiSky();
|
||||
remote_callback = hisky_cb;
|
||||
break;
|
||||
#endif
|
||||
#if defined(V2X2_NRF24L01_INO)
|
||||
case MODE_V2X2:
|
||||
next_callback = initV2x2();
|
||||
remote_callback = ReadV2x2;
|
||||
break;
|
||||
#endif
|
||||
#if defined(YD717_NRF24L01_INO)
|
||||
case MODE_YD717:
|
||||
next_callback=initYD717();
|
||||
remote_callback = yd717_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(KN_NRF24L01_INO)
|
||||
case MODE_KN:
|
||||
next_callback = initKN();
|
||||
remote_callback = kn_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SYMAX_NRF24L01_INO)
|
||||
case MODE_SYMAX:
|
||||
next_callback = initSymax();
|
||||
remote_callback = symax_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
case MODE_SLT:
|
||||
next_callback=initSLT();
|
||||
remote_callback = SLT_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
case MODE_Q2X2:
|
||||
sub_protocol|=0x08; // Increase the number of sub_protocols for CX-10
|
||||
case MODE_CX10:
|
||||
next_callback=initCX10();
|
||||
remote_callback = CX10_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CG023_NRF24L01_INO)
|
||||
case MODE_CG023:
|
||||
next_callback=initCG023();
|
||||
remote_callback = CG023_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(BAYANG_NRF24L01_INO)
|
||||
case MODE_BAYANG:
|
||||
next_callback=initBAYANG();
|
||||
remote_callback = BAYANG_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
case MODE_ESKY:
|
||||
next_callback=initESKY();
|
||||
remote_callback = ESKY_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
case MODE_MT99XX:
|
||||
next_callback=initMT99XX();
|
||||
remote_callback = MT99XX_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
case MODE_MJXQ:
|
||||
next_callback=initMJXQ();
|
||||
remote_callback = MJXQ_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
case MODE_SHENQI:
|
||||
next_callback=initSHENQI();
|
||||
remote_callback = SHENQI_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FY326_NRF24L01_INO)
|
||||
case MODE_FY326:
|
||||
next_callback=initFY326();
|
||||
remote_callback = FY326_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FQ777_NRF24L01_INO)
|
||||
case MODE_FQ777:
|
||||
next_callback=initFQ777();
|
||||
remote_callback = FQ777_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(ASSAN_NRF24L01_INO)
|
||||
case MODE_ASSAN:
|
||||
next_callback=initASSAN();
|
||||
remote_callback = ASSAN_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HONTAI_NRF24L01_INO)
|
||||
case MODE_HONTAI:
|
||||
next_callback=initHONTAI();
|
||||
remote_callback = HONTAI_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(Q303_NRF24L01_INO)
|
||||
case MODE_Q303:
|
||||
next_callback=initQ303();
|
||||
remote_callback = Q303_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(GW008_NRF24L01_INO)
|
||||
case MODE_GW008:
|
||||
next_callback=initGW008();
|
||||
remote_callback = GW008_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CABELL_NRF24L01_INO)
|
||||
case MODE_CABELL:
|
||||
next_callback=initCABELL();
|
||||
remote_callback = CABELL_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
case MODE_HISKY:
|
||||
next_callback=initHiSky();
|
||||
remote_callback = hisky_cb;
|
||||
break;
|
||||
#endif
|
||||
#if defined(V2X2_NRF24L01_INO)
|
||||
case MODE_V2X2:
|
||||
next_callback = initV2x2();
|
||||
remote_callback = ReadV2x2;
|
||||
break;
|
||||
#endif
|
||||
#if defined(YD717_NRF24L01_INO)
|
||||
case MODE_YD717:
|
||||
next_callback=initYD717();
|
||||
remote_callback = yd717_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(KN_NRF24L01_INO)
|
||||
case MODE_KN:
|
||||
next_callback = initKN();
|
||||
remote_callback = kn_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SYMAX_NRF24L01_INO)
|
||||
case MODE_SYMAX:
|
||||
next_callback = initSymax();
|
||||
remote_callback = symax_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
case MODE_SLT:
|
||||
next_callback=initSLT();
|
||||
remote_callback = SLT_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
case MODE_Q2X2:
|
||||
sub_protocol|=0x08; // Increase the number of sub_protocols for CX-10
|
||||
case MODE_CX10:
|
||||
next_callback=initCX10();
|
||||
remote_callback = CX10_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CG023_NRF24L01_INO)
|
||||
case MODE_CG023:
|
||||
next_callback=initCG023();
|
||||
remote_callback = CG023_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(BAYANG_NRF24L01_INO)
|
||||
case MODE_BAYANG:
|
||||
next_callback=initBAYANG();
|
||||
remote_callback = BAYANG_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
case MODE_ESKY:
|
||||
next_callback=initESKY();
|
||||
remote_callback = ESKY_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
case MODE_MT99XX:
|
||||
next_callback=initMT99XX();
|
||||
remote_callback = MT99XX_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
case MODE_MJXQ:
|
||||
next_callback=initMJXQ();
|
||||
remote_callback = MJXQ_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
case MODE_SHENQI:
|
||||
next_callback=initSHENQI();
|
||||
remote_callback = SHENQI_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FY326_NRF24L01_INO)
|
||||
case MODE_FY326:
|
||||
next_callback=initFY326();
|
||||
remote_callback = FY326_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FQ777_NRF24L01_INO)
|
||||
case MODE_FQ777:
|
||||
next_callback=initFQ777();
|
||||
remote_callback = FQ777_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(ASSAN_NRF24L01_INO)
|
||||
case MODE_ASSAN:
|
||||
next_callback=initASSAN();
|
||||
remote_callback = ASSAN_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HONTAI_NRF24L01_INO)
|
||||
case MODE_HONTAI:
|
||||
next_callback=initHONTAI();
|
||||
remote_callback = HONTAI_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CABELL_NRF24L01_INO)
|
||||
case MODE_CABELL:
|
||||
next_callback=initCABELL();
|
||||
remote_callback = CABELL_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WAIT_FOR_BIND) && defined(ENABLE_BIND_CH)
|
||||
if( IS_AUTOBIND_FLAG_on && ! ( IS_BIND_CH_PREV_on || IS_BIND_BUTTON_FLAG_on || (cur_protocol[1]&0x80)!=0 ) )
|
||||
{
|
||||
WAIT_BIND_on;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
WAIT_BIND_off;
|
||||
CHANGE_PROTOCOL_FLAG_off;
|
||||
|
||||
if(next_callback>32000)
|
||||
{ // next_callback should not be more than 32767 so we will wait here...
|
||||
uint16_t temp=(next_callback>>10)-2;
|
||||
@@ -900,15 +1007,26 @@ void update_serial_data()
|
||||
if( (rx_ok_buff[0] != cur_protocol[0]) || ((rx_ok_buff[1]&0x5F) != (cur_protocol[1]&0x5F)) || ( (rx_ok_buff[2]&0x7F) != (cur_protocol[2]&0x7F) ) )
|
||||
{ // New model has been selected
|
||||
CHANGE_PROTOCOL_FLAG_on; //change protocol
|
||||
WAIT_BIND_off;
|
||||
protocol=(rx_ok_buff[0]==0x55?0:32) + (rx_ok_buff[1]&0x1F); //protocol no (0-63) bits 4-6 of buff[1] and bit 0 of buf[0]
|
||||
sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6
|
||||
RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0---3
|
||||
}
|
||||
else
|
||||
if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set
|
||||
if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set
|
||||
CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind
|
||||
else
|
||||
CHANGE_PROTOCOL_FLAG_off; //no need to restart
|
||||
if( ((rx_ok_buff[1]&0x80)==0) && ((cur_protocol[1]&0x80)!=0) ) // Bind flag has been reset
|
||||
{
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO)
|
||||
if(protocol==MODE_FRSKYD || protocol==MODE_FRSKYX || protocol==MODE_FRSKYV)
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
if(bind_counter>2)
|
||||
bind_counter=2;
|
||||
}
|
||||
|
||||
//store current protocol values
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
cur_protocol[i] = rx_ok_buff[i];
|
||||
@@ -1010,21 +1128,12 @@ void Mprotocol_serial_init()
|
||||
#if defined(TELEMETRY)
|
||||
void PPM_Telemetry_serial_init()
|
||||
{
|
||||
#ifdef MULTI_TELEMETRY
|
||||
Mprotocol_serial_init();
|
||||
#ifndef ORANGE_TX
|
||||
#ifndef STM32_BOARD
|
||||
UCSR0B &= ~(_BV(RXEN0)|_BV(RXCIE0));//rx disable and interrupt
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) )
|
||||
initTXSerial( SPEED_9600 ) ;
|
||||
if(protocol==MODE_FRSKYX)
|
||||
initTXSerial( SPEED_57600 ) ;
|
||||
if(protocol==MODE_DSM)
|
||||
initTXSerial( SPEED_125K ) ;
|
||||
#endif
|
||||
if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) )
|
||||
initTXSerial( SPEED_9600 ) ;
|
||||
if(protocol==MODE_FRSKYX)
|
||||
initTXSerial( SPEED_57600 ) ;
|
||||
if(protocol==MODE_DSM)
|
||||
initTXSerial( SPEED_125K ) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1070,7 +1179,13 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new)
|
||||
return id;
|
||||
}
|
||||
// Generate a random ID
|
||||
id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
#if defined STM32_BOARD
|
||||
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
|
||||
if (!create_new)
|
||||
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
|
||||
#else
|
||||
id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
#endif
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)adress+i,id);
|
||||
@@ -1114,7 +1229,7 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new)
|
||||
else
|
||||
if(Cur_TCNT1>4840)
|
||||
{ //start of frame
|
||||
if(chan>3)
|
||||
if(chan>=MIN_PPM_CHANNELS)
|
||||
PPM_FLAG_on; // good frame received if at least 4 channels have been seen
|
||||
chan=0; // reset channel counter
|
||||
bad_frame=0;
|
||||
@@ -1123,7 +1238,7 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new)
|
||||
if(bad_frame==0) // need to wait for start of frame
|
||||
{ //servo values between 500us and 2420us will end up here
|
||||
PPM_data[chan]= Cur_TCNT1>>1;;
|
||||
if(chan++>=NUM_CHN)
|
||||
if(chan++>=MAX_PPM_CHANNELS)
|
||||
bad_frame=1; // don't accept any new channels
|
||||
}
|
||||
Prev_TCNT1+=Cur_TCNT1;
|
||||
|
||||
@@ -160,7 +160,11 @@ void NRF24L01_SetPower()
|
||||
{
|
||||
uint8_t power=NRF_BIND_POWER;
|
||||
if(IS_BIND_DONE_on)
|
||||
power=IS_POWER_FLAG_on?NRF_HIGH_POWER:NRF_LOW_POWER;
|
||||
#ifdef NRF24L01_ENABLE_LOW_POWER
|
||||
power=IS_POWER_FLAG_on?NRF_HIGH_POWER:NRF_LOW_POWER;
|
||||
#else
|
||||
power=NRF_HIGH_POWER;
|
||||
#endif
|
||||
if(IS_RANGE_FLAG_on)
|
||||
power=NRF_POWER_0;
|
||||
rf_setup = (rf_setup & 0xF9) | (power << 1);
|
||||
@@ -278,10 +282,10 @@ static uint8_t bit_reverse(uint8_t b_in)
|
||||
}
|
||||
|
||||
static const uint16_t polynomial = 0x1021;
|
||||
static uint16_t crc16_update(uint16_t crc, uint8_t a)
|
||||
static uint16_t crc16_update(uint16_t crc, uint8_t a, uint8_t bits)
|
||||
{
|
||||
crc ^= a << 8;
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
while(bits--)
|
||||
if (crc & 0x8000)
|
||||
crc = (crc << 1) ^ polynomial;
|
||||
else
|
||||
@@ -370,7 +374,7 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
uint16_t crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc = crc16_update(crc, buf[i]);
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
@@ -381,6 +385,76 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
NRF24L01_WritePayload(buf, last);
|
||||
}
|
||||
|
||||
|
||||
void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack, uint16_t crc_xorout)
|
||||
{
|
||||
uint8_t packet[32];
|
||||
uint8_t scramble_index=0;
|
||||
uint8_t last = 0;
|
||||
static uint8_t pid=0;
|
||||
|
||||
// address
|
||||
if (xn297_addr_len < 4)
|
||||
{
|
||||
// If address length (which is defined by receive address length)
|
||||
// is less than 4 the TX address can't fit the preamble, so the last
|
||||
// byte goes here
|
||||
packet[last++] = 0x55;
|
||||
}
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
packet[last] = xn297_tx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
}
|
||||
|
||||
// pcf
|
||||
packet[last] = (len << 1) | (pid>>1);
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
packet[last] = (pid << 7) | (noack << 6);
|
||||
|
||||
// payload
|
||||
packet[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
|
||||
for (uint8_t i = 0; i < len-1; ++i)
|
||||
{
|
||||
last++;
|
||||
packet[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2);
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
}
|
||||
|
||||
last++;
|
||||
packet[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++] & 0xc0;
|
||||
|
||||
// crc
|
||||
if (xn297_crc)
|
||||
{
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
uint16_t crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc = crc16_update(crc, packet[last] & 0xc0, 2);
|
||||
crc ^= crc_xorout;
|
||||
|
||||
packet[last++] |= (crc >> 8) >> 2;
|
||||
packet[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
|
||||
packet[last++] = (crc & 0xff) << 6;
|
||||
}
|
||||
NRF24L01_WritePayload(packet, last);
|
||||
|
||||
pid++;
|
||||
if(pid>3)
|
||||
pid=0;
|
||||
}
|
||||
|
||||
void XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
// TODO: if xn297_crc==1, check CRC before filling *msg
|
||||
@@ -393,7 +467,26 @@ void XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
}
|
||||
}
|
||||
|
||||
// End of XN297 emulation
|
||||
uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
uint8_t pcf_size; // pcf payload size
|
||||
NRF24L01_ReadPayload(buffer, len+2); // pcf + payload
|
||||
pcf_size = buffer[0];
|
||||
if(xn297_scramble_enabled)
|
||||
pcf_size ^= xn297_scramble[xn297_addr_len];
|
||||
pcf_size = pcf_size >> 1;
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
msg[i] = bit_reverse((buffer[i+1] << 2) | (buffer[i+2] >> 6));
|
||||
if(xn297_scramble_enabled)
|
||||
msg[i] ^= bit_reverse((xn297_scramble[xn297_addr_len+i+1] << 2) |
|
||||
(xn297_scramble[xn297_addr_len+i+2] >> 6));
|
||||
}
|
||||
return pcf_size;
|
||||
}
|
||||
|
||||
// End of XN297 emulation
|
||||
|
||||
///////////////
|
||||
// LT8900 emulation layer
|
||||
@@ -527,14 +620,14 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
//Check len
|
||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||
{
|
||||
crc=crc16_update(crc,buffer[pos]);
|
||||
crc=crc16_update(crc,buffer[pos],8);
|
||||
if(bit_reverse(len)!=buffer[pos++])
|
||||
return 0; // wrong len...
|
||||
}
|
||||
//Decode message
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
crc=crc16_update(crc,buffer[pos]);
|
||||
crc=crc16_update(crc,buffer[pos],8);
|
||||
msg[i]=bit_reverse(buffer[pos++]);
|
||||
}
|
||||
//Check CRC
|
||||
@@ -556,14 +649,14 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
tmp=bit_reverse(len);
|
||||
buffer[pos++]=tmp;
|
||||
crc=crc16_update(crc,tmp);
|
||||
crc=crc16_update(crc,tmp,8);
|
||||
}
|
||||
//Add payload
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
tmp=bit_reverse(msg[i]);
|
||||
buffer[pos++]=tmp;
|
||||
crc=crc16_update(crc,tmp);
|
||||
crc=crc16_update(crc,tmp,8);
|
||||
}
|
||||
//Add CRC
|
||||
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
||||
|
||||
409
Multiprotocol/Q303_nrf24l01.ino
Normal file
409
Multiprotocol/Q303_nrf24l01.ino
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
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(Q303_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define Q303_BIND_COUNT 1500
|
||||
#define Q303_INITIAL_WAIT 500
|
||||
#define Q303_RF_BIND_CHANNEL 0x02
|
||||
|
||||
#define Q303_BTN_TAKEOFF 1
|
||||
#define Q303_BTN_DESCEND 2
|
||||
#define Q303_BTN_SNAPSHOT 4
|
||||
#define Q303_BTN_VIDEO 8
|
||||
#define Q303_BTN_RTH 16
|
||||
#define Q303_BTN_VTX 32
|
||||
|
||||
static uint8_t __attribute__((unused)) cx10wd_getButtons()
|
||||
{
|
||||
#define CX10WD_FLAG_LAND 0x20
|
||||
#define CX10D_FLAG_LAND 0x80
|
||||
#define CX10WD_FLAG_TAKEOFF 0x40
|
||||
|
||||
static uint8_t BTN_state;
|
||||
static uint8_t command;
|
||||
|
||||
// startup
|
||||
if(packet_count < 50)
|
||||
{
|
||||
BTN_state = 0;
|
||||
command = 0;
|
||||
packet_count++;
|
||||
}
|
||||
// auto land
|
||||
else if((Servo_data[AUX1] < PPM_MIN_COMMAND) && !(BTN_state & Q303_BTN_DESCEND))
|
||||
{
|
||||
BTN_state |= Q303_BTN_DESCEND;
|
||||
BTN_state &= ~Q303_BTN_TAKEOFF;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case CX10WD:
|
||||
command ^= CX10WD_FLAG_LAND;
|
||||
break;
|
||||
case CX10D:
|
||||
command ^= CX10D_FLAG_LAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// auto take off
|
||||
else if(Servo_AUX1 && !(BTN_state & Q303_BTN_TAKEOFF))
|
||||
{
|
||||
BTN_state |= Q303_BTN_TAKEOFF;
|
||||
BTN_state &= ~Q303_BTN_DESCEND;
|
||||
command ^= CX10WD_FLAG_TAKEOFF;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) cx35_lastButton()
|
||||
{
|
||||
#define CX35_CMD_RATE 0x09
|
||||
#define CX35_CMD_TAKEOFF 0x0e
|
||||
#define CX35_CMD_DESCEND 0x0f
|
||||
#define CX35_CMD_SNAPSHOT 0x0b
|
||||
#define CX35_CMD_VIDEO 0x0c
|
||||
#define CX35_CMD_RTH 0x11
|
||||
#define CX35_CMD_VTX 0x10
|
||||
|
||||
static uint8_t BTN_state;
|
||||
static uint8_t command;
|
||||
// simulate 2 keypress on rate button just after bind
|
||||
if(packet_count < 50)
|
||||
{
|
||||
BTN_state = 0;
|
||||
packet_count++;
|
||||
command = 0x00; // startup
|
||||
}
|
||||
else if(packet_count < 150)
|
||||
{
|
||||
packet_count++;
|
||||
command = CX35_CMD_RATE; // 1st keypress
|
||||
}
|
||||
else if(packet_count < 250)
|
||||
{
|
||||
packet_count++;
|
||||
command |= 0x20; // 2nd keypress
|
||||
}
|
||||
// descend
|
||||
else if(!(GET_FLAG(Servo_AUX1, 1)) && !(BTN_state & Q303_BTN_DESCEND))
|
||||
{
|
||||
BTN_state |= Q303_BTN_DESCEND;
|
||||
BTN_state &= ~Q303_BTN_TAKEOFF;
|
||||
command = CX35_CMD_DESCEND;
|
||||
}
|
||||
// take off
|
||||
else if(GET_FLAG(Servo_AUX1,1) && !(BTN_state & Q303_BTN_TAKEOFF))
|
||||
{
|
||||
BTN_state |= Q303_BTN_TAKEOFF;
|
||||
BTN_state &= ~Q303_BTN_DESCEND;
|
||||
command = CX35_CMD_TAKEOFF;
|
||||
}
|
||||
// RTH
|
||||
else if(GET_FLAG(Servo_AUX6,1) && !(BTN_state & Q303_BTN_RTH))
|
||||
{
|
||||
BTN_state |= Q303_BTN_RTH;
|
||||
if(command == CX35_CMD_RTH)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_RTH;
|
||||
}
|
||||
else if(!(GET_FLAG(Servo_AUX6,1)) && (BTN_state & Q303_BTN_RTH))
|
||||
{
|
||||
BTN_state &= ~Q303_BTN_RTH;
|
||||
if(command == CX35_CMD_RTH)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_RTH;
|
||||
}
|
||||
// video
|
||||
else if(GET_FLAG(Servo_AUX4,1) && !(BTN_state & Q303_BTN_VIDEO))
|
||||
{
|
||||
BTN_state |= Q303_BTN_VIDEO;
|
||||
if(command == CX35_CMD_VIDEO)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_VIDEO;
|
||||
}
|
||||
else if(!(GET_FLAG(Servo_AUX4,1)) && (BTN_state & Q303_BTN_VIDEO))
|
||||
{
|
||||
BTN_state &= ~Q303_BTN_VIDEO;
|
||||
if(command == CX35_CMD_VIDEO)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_VIDEO;
|
||||
}
|
||||
// snapshot
|
||||
else if(GET_FLAG(Servo_AUX3,1) && !(BTN_state & Q303_BTN_SNAPSHOT))
|
||||
{
|
||||
BTN_state |= Q303_BTN_SNAPSHOT;
|
||||
if(command == CX35_CMD_SNAPSHOT)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_SNAPSHOT;
|
||||
}
|
||||
// vtx channel
|
||||
else if(GET_FLAG(Servo_AUX2,1) && !(BTN_state & Q303_BTN_VTX))
|
||||
{
|
||||
BTN_state |= Q303_BTN_VTX;
|
||||
if(command == CX35_CMD_VTX)
|
||||
command |= 0x20;
|
||||
else
|
||||
command = CX35_CMD_VTX;
|
||||
}
|
||||
|
||||
if(!(GET_FLAG(Servo_AUX3,1)))
|
||||
BTN_state &= ~Q303_BTN_SNAPSHOT;
|
||||
if(!(GET_FLAG(Servo_AUX2,1)))
|
||||
BTN_state &= ~Q303_BTN_VTX;
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
|
||||
{
|
||||
uint16_t aileron, elevator, throttle, rudder, slider;
|
||||
if(bind)
|
||||
{
|
||||
packet[0] = 0xaa;
|
||||
memcpy(&packet[1], rx_tx_addr + 1, 4);
|
||||
memset(&packet[5], 0, packet_length-5);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = 0x55;
|
||||
// sticks
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case Q303:
|
||||
case CX35:
|
||||
aileron = convert_channel_16b(AILERON, 0, 1000);
|
||||
elevator = convert_channel_16b(ELEVATOR, 1000, 0);
|
||||
throttle = convert_channel_16b(THROTTLE, 0, 1000);
|
||||
rudder = convert_channel_16b(RUDDER, 1000, 0);
|
||||
if(sub_protocol == CX35)
|
||||
aileron = 1000 - aileron;
|
||||
packet[1] = aileron >> 2; // 8 bits
|
||||
packet[2] = (aileron & 0x03) << 6 // 2 bits
|
||||
| (elevator >> 4); // 6 bits
|
||||
packet[3] = (elevator & 0x0f) << 4 // 4 bits
|
||||
| (throttle >> 6); // 4 bits
|
||||
packet[4] = (throttle & 0x3f) << 2 // 6 bits
|
||||
| (rudder >> 8); // 2 bits
|
||||
packet[5] = rudder & 0xff; // 8 bits
|
||||
break;
|
||||
case CX10D:
|
||||
case CX10WD:
|
||||
aileron = convert_channel_16b(AILERON, 2000, 1000);
|
||||
elevator = convert_channel_16b(ELEVATOR, 2000, 1000);
|
||||
throttle = convert_channel_16b(THROTTLE, 1000, 2000);
|
||||
rudder = convert_channel_16b(RUDDER, 1000, 2000);
|
||||
packet[1] = aileron & 0xff;
|
||||
packet[2] = aileron >> 8;
|
||||
packet[3] = elevator & 0xff;
|
||||
packet[4] = elevator >> 8;
|
||||
packet[5] = throttle & 0xff;
|
||||
packet[6] = throttle >> 8;
|
||||
packet[7] = rudder & 0xff;
|
||||
packet[8] = rudder >> 8;
|
||||
break;
|
||||
}
|
||||
|
||||
// buttons
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case Q303:
|
||||
packet[6] = 0x10; // trim(s) ?
|
||||
packet[7] = 0x10; // trim(s) ?
|
||||
packet[8] = 0x03 // high rate (0-3)
|
||||
| GET_FLAG(Servo_AUX1, 0x40)
|
||||
| GET_FLAG(Servo_AUX6, 0x80);
|
||||
packet[9] = 0x40 // always set
|
||||
| GET_FLAG(Servo_AUX5,0x08)
|
||||
| GET_FLAG(Servo_AUX2, 0x80)
|
||||
| GET_FLAG(Servo_AUX3,0x10)
|
||||
| GET_FLAG(Servo_AUX4, 0x01);
|
||||
if(Servo_data[AUX7] < PPM_MIN_COMMAND)
|
||||
packet[9] |= 0x04; // gimbal down
|
||||
else if(Servo_data[AUX7] > PPM_MAX_COMMAND)
|
||||
packet[9] |= 0x20; // gimbal up
|
||||
break;
|
||||
|
||||
case CX35:
|
||||
slider = convert_channel_16b(AUX7, 731, 342);
|
||||
packet[6] = slider >> 2;
|
||||
packet[7] = ((slider & 3) << 6)
|
||||
| 0x3e; // ?? 6 bit left (always 111110 ?)
|
||||
packet[8] = 0x80; // always set
|
||||
packet[9] = cx35_lastButton();
|
||||
break;
|
||||
|
||||
case CX10D:
|
||||
packet[8] |= GET_FLAG(Servo_AUX2, 0x10);
|
||||
packet[9] = 0x02; // rate (0-2)
|
||||
packet[10]= cx10wd_getButtons(); // auto land / take off management
|
||||
break;
|
||||
|
||||
case CX10WD:
|
||||
packet[8] |= GET_FLAG(Servo_AUX2, 0x10);
|
||||
packet[9] = 0x02 // rate (0-2)
|
||||
| cx10wd_getButtons(); // auto land / take off management
|
||||
packet[10] = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? Q303_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no %= rf_ch_num;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_init()
|
||||
{
|
||||
const uint8_t bind_address[] = {0xcc,0xcc,0xcc,0xcc,0xcc};
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case CX35:
|
||||
case CX10D:
|
||||
case CX10WD:
|
||||
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
break;
|
||||
case Q303:
|
||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
break;
|
||||
}
|
||||
XN297_SetTXAddr(bind_address, 5);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
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); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_initialize_txid()
|
||||
{
|
||||
uint8_t i,offset;
|
||||
|
||||
rx_tx_addr[0] = 0x55;
|
||||
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case Q303:
|
||||
case CX10WD:
|
||||
offset = rx_tx_addr[1] & 3;
|
||||
for(i=0; i<4; i++)
|
||||
hopping_frequency[i] = 0x46 + i*2 + offset;
|
||||
break;
|
||||
case CX35:
|
||||
case CX10D:
|
||||
// not thoroughly figured out rx_tx_addr/channels mapping yet
|
||||
// for now 5 msb of rx_tx_addr[1] must be cleared
|
||||
rx_tx_addr[1] &= 7;
|
||||
offset = 6+(rx_tx_addr[1]*3);
|
||||
hopping_frequency[0] = 0x14; // works only if rx_tx_addr[1] < 8
|
||||
for(i=1; i<16; i++)
|
||||
{
|
||||
hopping_frequency[i] = hopping_frequency[i-1] + offset;
|
||||
if(hopping_frequency[i] > 0x41)
|
||||
hopping_frequency[i] -= 0x33;
|
||||
if(hopping_frequency[i] < 0x14)
|
||||
hopping_frequency[i] += offset;
|
||||
}
|
||||
// CX35 tx uses only 4 of those channels (#0,3,6,9)
|
||||
if(sub_protocol == CX35)
|
||||
for(i=0; i<4; i++)
|
||||
hopping_frequency[i] = hopping_frequency[i*3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Q303_callback()
|
||||
{
|
||||
if(IS_BIND_DONE_on)
|
||||
Q303_send_packet(0);
|
||||
else
|
||||
{
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
packet_count = 0;
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q303_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initQ303()
|
||||
{
|
||||
Q303_initialize_txid();
|
||||
Q303_init();
|
||||
bind_counter = Q303_BIND_COUNT;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case Q303:
|
||||
packet_period = 1500;
|
||||
packet_length = 10;
|
||||
rf_ch_num = 4;
|
||||
break;
|
||||
case CX35:
|
||||
packet_period = 3000;
|
||||
packet_length = 10;
|
||||
rf_ch_num = 4;
|
||||
break;
|
||||
case CX10D:
|
||||
packet_period = 3000;
|
||||
packet_length = 11;
|
||||
rf_ch_num = 16;
|
||||
break;
|
||||
case CX10WD:
|
||||
packet_period = 3000;
|
||||
packet_length = 11;
|
||||
rf_ch_num = 4;
|
||||
break;
|
||||
}
|
||||
hopping_frequency_no = 0;
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
return Q303_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -122,22 +122,17 @@ static void __attribute__((unused)) SFHSS_calc_next_chan()
|
||||
}
|
||||
}
|
||||
|
||||
// Channel values are 10-bit values between 86 and 906, 496 is the middle.
|
||||
// Values grow down and to the right, so we just revert every channel.
|
||||
static uint16_t __attribute__((unused)) SFHSS_convert_channel(uint8_t num)
|
||||
{
|
||||
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,906,86));
|
||||
}
|
||||
|
||||
/*// Channel values are 10-bit values between 86 and 906, 496 is the middle.
|
||||
// Values grow down and to the right.
|
||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
{
|
||||
#define spacer1 0x02 //0b10
|
||||
#define spacer1 0x02
|
||||
#define spacer2 (spacer1 << 4)
|
||||
uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4;
|
||||
uint16_t ch1 = SFHSS_convert_channel(CH_AETR[ch_offset+0]);
|
||||
uint16_t ch2 = SFHSS_convert_channel(CH_AETR[ch_offset+1]);
|
||||
uint16_t ch3 = SFHSS_convert_channel(CH_AETR[ch_offset+2]);
|
||||
uint16_t ch4 = SFHSS_convert_channel(CH_AETR[ch_offset+3]);
|
||||
uint16_t ch1 = convert_channel_16b_nolim(CH_AETR[ch_offset+0],86,906);
|
||||
uint16_t ch2 = convert_channel_16b_nolim(CH_AETR[ch_offset+1],86,906);
|
||||
uint16_t ch3 = convert_channel_16b_nolim(CH_AETR[ch_offset+2],86,906);
|
||||
uint16_t ch4 = convert_channel_16b_nolim(CH_AETR[ch_offset+3],86,906);
|
||||
|
||||
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
||||
packet[1] = rx_tx_addr[0];
|
||||
@@ -146,13 +141,40 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
packet[4] = 0;
|
||||
packet[5] = (rf_ch_num << 3) | spacer1 | ((ch1 >> 9) & 0x01);
|
||||
packet[6] = (ch1 >> 1);
|
||||
packet[7] = (ch1 << 7) | spacer2 | ((ch2 >> 5) & 0x1F /*0b11111*/);
|
||||
packet[7] = (ch1 << 7) | spacer2 | ((ch2 >> 5) & 0x1F);
|
||||
packet[8] = (ch2 << 3) | spacer1 | ((ch3 >> 9) & 0x01);
|
||||
packet[9] = (ch3 >> 1);
|
||||
packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F /*0b11111*/);
|
||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 /*0b111 */);
|
||||
packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F);
|
||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07);
|
||||
packet[12] = (fhss_code << 6) | phase;
|
||||
}
|
||||
*/
|
||||
|
||||
// Channel values are 12-bit values between 1020 and 2020, 1520 is the middle.
|
||||
// Futaba @140% is 2070...1520...970
|
||||
// Values grow down and to the right.
|
||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
{
|
||||
uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4;
|
||||
uint16_t ch1 = convert_channel_16b_nolim(CH_AETR[ch_offset+0],2020,1020);
|
||||
uint16_t ch2 = convert_channel_16b_nolim(CH_AETR[ch_offset+1],2020,1020);
|
||||
uint16_t ch3 = convert_channel_16b_nolim(CH_AETR[ch_offset+2],2020,1020);
|
||||
uint16_t ch4 = convert_channel_16b_nolim(CH_AETR[ch_offset+3],2020,1020);
|
||||
|
||||
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
packet[3] = 0x0f; //10J
|
||||
packet[4] = 0x09; //10J
|
||||
packet[5] = (rf_ch_num << 3) | ((ch1 >> 9) & 0x07);
|
||||
packet[6] = (ch1 >> 1);
|
||||
packet[7] = (ch1 << 7) | ((ch2 >> 5) & 0x7F );
|
||||
packet[8] = (ch2 << 3) | ((ch3 >> 9) & 0x07);
|
||||
packet[9] = (ch3 >> 1);
|
||||
packet[10] = (ch3 << 7) | ((ch4 >> 5) & 0x7F );
|
||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 );
|
||||
packet[12] = (fhss_code << 6) | phase;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SFHSS_send_packet()
|
||||
{
|
||||
|
||||
@@ -20,20 +20,15 @@
|
||||
|
||||
// For code readability
|
||||
#define SLT_PAYLOADSIZE 7
|
||||
#define SLT_VISTA_PAYLOADSIZE 11
|
||||
#define SLT_NFREQCHANNELS 15
|
||||
#define SLT_TXID_SIZE 4
|
||||
|
||||
enum {
|
||||
// flags going to packet[6]
|
||||
SLT_VISTA_FLAG_FLIP = 0x04,
|
||||
SLT_VISTA_FLAG_MODE = 0x20
|
||||
};
|
||||
|
||||
enum {
|
||||
SLT_BIND=0,
|
||||
SLT_BUILD,
|
||||
SLT_DATA,
|
||||
SLT_BUILD=0,
|
||||
SLT_DATA1,
|
||||
SLT_DATA2,
|
||||
SLT_DATA3,
|
||||
SLT_BIND
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) SLT_init()
|
||||
@@ -108,37 +103,24 @@ static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len)
|
||||
|
||||
static void __attribute__((unused)) SLT_build_packet()
|
||||
{
|
||||
// aileron, elevator, throttle, rudder, gear, pitch
|
||||
// Set radio channel - once per packet batch
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
// aileron, elevator, throttle, rudder, gear, pitch
|
||||
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
{
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i]);
|
||||
if(sub_protocol==VISTA && CH_AETR[i]==THROTTLE)
|
||||
v = (uint16_t) map(limit_channel_100(THROTTLE),servo_min_100,servo_max_100,850,150); // Throttel is between 850=0% and 150=100%
|
||||
packet[i] = v;
|
||||
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
||||
}
|
||||
// Extra bits for AETR
|
||||
packet[4] = e;
|
||||
if(sub_protocol==SLT)
|
||||
{
|
||||
// 8-bit channels
|
||||
packet[5] = convert_channel_8b(AUX1);
|
||||
packet[6] = convert_channel_8b(AUX2);
|
||||
}
|
||||
else
|
||||
{ // VISTA
|
||||
packet[5] = 0xA6;
|
||||
packet[6] = 0x00;
|
||||
if(Servo_AUX1)
|
||||
packet[6] = SLT_VISTA_FLAG_FLIP;
|
||||
if(Servo_AUX2)
|
||||
packet[6] |= SLT_VISTA_FLAG_MODE;
|
||||
packet[7] = 0x00;
|
||||
packet[8] = 0x7F;
|
||||
packet[9] = 0xAA;
|
||||
packet[10] = 0x00;
|
||||
}
|
||||
// 8-bit channels
|
||||
packet[5] = convert_channel_8b(AUX1);
|
||||
packet[6] = convert_channel_8b(AUX2);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||
@@ -162,83 +144,47 @@ uint16_t SLT_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case SLT_BIND:
|
||||
bind_phase = 0;
|
||||
SLT_send_bind_packet();
|
||||
if(sub_protocol == VISTA)
|
||||
case SLT_BUILD:
|
||||
SLT_build_packet();
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA1:
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA2:
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA3:
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
if (++packet_count >= 100)
|
||||
{
|
||||
phase=SLT_DATA;
|
||||
packet_count = 0;
|
||||
phase++;
|
||||
return 1000;
|
||||
}
|
||||
phase++; // SLT_BUILD
|
||||
return 18000;
|
||||
case SLT_BUILD:
|
||||
if(sub_protocol==SLT)
|
||||
{ // Set radio channel - once per packet batch
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
}
|
||||
SLT_build_packet();
|
||||
packet_count=0;
|
||||
phase++; // SLT_DATA
|
||||
return 1000;
|
||||
case SLT_DATA:
|
||||
if(sub_protocol==VISTA)
|
||||
{ // Change radio channel every 9 packets
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
rf_ch_num++;
|
||||
if(rf_ch_num>=9)
|
||||
{
|
||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
rf_ch_num=0;
|
||||
}
|
||||
}
|
||||
SLT_send_data(packet, sub_protocol == VISTA?SLT_VISTA_PAYLOADSIZE:SLT_PAYLOADSIZE);
|
||||
packet_count++;
|
||||
if(packet_count >= (sub_protocol == VISTA?5:3))
|
||||
{ // repeat the same data packet 3(SLT) or 5(VISTA) times
|
||||
bind_phase++;
|
||||
else
|
||||
{
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
phase = SLT_BUILD; // Refresh data
|
||||
if(sub_protocol == VISTA)
|
||||
return 1000;
|
||||
else
|
||||
if(bind_phase>=100)
|
||||
{ //SLT sends bind packet every 2.2s
|
||||
phase=SLT_BIND;
|
||||
return 1000;
|
||||
}
|
||||
phase = SLT_BUILD;
|
||||
return 19000;
|
||||
}
|
||||
if(sub_protocol == VISTA)
|
||||
{ //VISTA sends bind packet every 1.5s
|
||||
if(bind_phase>=150)
|
||||
phase=SLT_BIND;
|
||||
else
|
||||
return 2000;
|
||||
}
|
||||
return 1000;
|
||||
case SLT_BIND:
|
||||
SLT_send_bind_packet();
|
||||
phase = SLT_BUILD;
|
||||
return 18000;
|
||||
}
|
||||
return 1000;
|
||||
return 19000;
|
||||
}
|
||||
|
||||
uint16_t initSLT()
|
||||
{
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
rf_ch_num=0;
|
||||
hopping_frequency_no = 0;
|
||||
if(sub_protocol == VISTA)
|
||||
{
|
||||
memcpy(rx_tx_addr,"\x00\x00\x23\x00",SLT_TXID_SIZE);
|
||||
memcpy(hopping_frequency,"\x03\x0A\x11\x18\x1F\x26\x13\x0F\x0B\x10\x08\x16\x1D\x24\x06",15);
|
||||
}
|
||||
else
|
||||
SLT_set_freq();
|
||||
SLT_set_freq();
|
||||
SLT_init();
|
||||
SLT_build_packet();
|
||||
phase = SLT_BIND;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
@@ -319,12 +319,12 @@ uint16_t symax_callback()
|
||||
return SYMAX_FIRST_PACKET_DELAY;
|
||||
break;
|
||||
case SYMAX_BIND2:
|
||||
counter = SYMAX_BIND_COUNT;
|
||||
bind_counter = SYMAX_BIND_COUNT;
|
||||
phase = SYMAX_BIND3;
|
||||
SYMAX_send_packet(1);
|
||||
break;
|
||||
case SYMAX_BIND3:
|
||||
if (counter == 0)
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
symax_init2();
|
||||
phase = SYMAX_DATA;
|
||||
@@ -333,7 +333,7 @@ uint16_t symax_callback()
|
||||
else
|
||||
{
|
||||
SYMAX_send_packet(1);
|
||||
counter--;
|
||||
bind_counter--;
|
||||
}
|
||||
break;
|
||||
case SYMAX_DATA:
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#if defined(TX_DEVO7)
|
||||
#define PPM_MAX_100 1920 // 100%
|
||||
#define PPM_MIN_100 1120 // 100%
|
||||
#define PPM_MAX_125 2100 // 125%
|
||||
#define PPM_MIN_125 900 // 125%
|
||||
#define PPM_MAX_125 2120 // 125%
|
||||
#define PPM_MIN_125 920 // 125%
|
||||
#endif
|
||||
|
||||
// SPEKTRUM PPM and channels
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
// HISKY
|
||||
#if defined(TX_HISKY)
|
||||
#define PPM_MAX_100 1900 // 100%
|
||||
#define PPM_MIN_100 1100 // 100%
|
||||
#define PPM_MAX_125 2000 // 125%
|
||||
#define PPM_MIN_125 1000 // 125%
|
||||
#define PPM_MAX_100 1920 // 100%
|
||||
#define PPM_MIN_100 1120 // 100%
|
||||
#define PPM_MAX_125 2020 // 125%
|
||||
#define PPM_MIN_125 1020 // 125%
|
||||
#endif
|
||||
|
||||
// Multiplex MC2020
|
||||
@@ -38,6 +38,14 @@
|
||||
#define PPM_MIN_125 1150 // 125%
|
||||
#endif
|
||||
|
||||
// Walkera PL0811-01H
|
||||
#if defined(TX_WALKERA)
|
||||
#define PPM_MAX_100 1800 // 100%
|
||||
#define PPM_MIN_100 1000 // 100%
|
||||
#define PPM_MAX_125 1900 // 125%
|
||||
#define PPM_MIN_125 900 // 125%
|
||||
#endif
|
||||
|
||||
//Serial MIN MAX values
|
||||
#define SERIAL_MAX_100 2012 // 100%
|
||||
#define SERIAL_MIN_100 988 // 100%
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
//**************************
|
||||
#if defined TELEMETRY
|
||||
|
||||
#if defined MULTI_TELEMETRY
|
||||
#define MULTI_TIME 250 //in ms
|
||||
uint8_t RetrySequence ;
|
||||
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
#define MULTI_TIME 500 //in ms
|
||||
uint32_t lastMulti = 0;
|
||||
#endif
|
||||
|
||||
@@ -28,7 +30,6 @@
|
||||
uint32_t last = 0;
|
||||
uint8_t sport_counter=0;
|
||||
uint8_t RxBt = 0;
|
||||
uint8_t rssi;
|
||||
uint8_t sport = 0;
|
||||
#endif
|
||||
#if defined HUB_TELEMETRY
|
||||
@@ -45,32 +46,17 @@ uint8_t pktx1[MAX_PKTX];
|
||||
uint8_t indx;
|
||||
uint8_t frame[18];
|
||||
|
||||
#ifdef BASH_SERIAL
|
||||
// For bit-bashed serial output
|
||||
volatile struct t_serial_bash
|
||||
{
|
||||
uint8_t head ;
|
||||
uint8_t tail ;
|
||||
uint8_t data[64] ;
|
||||
uint8_t busy ;
|
||||
uint8_t speed ;
|
||||
} SerialControl ;
|
||||
#endif
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
static void multi_send_header(uint8_t type, uint8_t len)
|
||||
{
|
||||
Serial_write('M');
|
||||
Serial_write('P');
|
||||
Serial_write(type);
|
||||
Serial_write(len);
|
||||
}
|
||||
|
||||
static void multi_send_frskyhub()
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_HUB, 9);
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
Serial_write(frame[i]);
|
||||
Serial_write('M');
|
||||
#ifdef MULTI_TELEMETRY
|
||||
Serial_write('P');
|
||||
Serial_write(type);
|
||||
#else
|
||||
(void)type;
|
||||
#endif
|
||||
Serial_write(len);
|
||||
}
|
||||
|
||||
static void multi_send_status()
|
||||
@@ -84,16 +70,21 @@ static void multi_send_status()
|
||||
if (mode_select==MODE_SERIAL)
|
||||
flags |= 0x02;
|
||||
if (remote_callback != 0)
|
||||
flags |= 0x04;
|
||||
if (!IS_BIND_DONE_on)
|
||||
flags |= 0x08;
|
||||
{
|
||||
flags |= 0x04;
|
||||
if (IS_WAIT_BIND_on)
|
||||
flags |= 0x10;
|
||||
else
|
||||
if (!IS_BIND_DONE_on)
|
||||
flags |= 0x08;
|
||||
}
|
||||
Serial_write(flags);
|
||||
|
||||
// Version number example: 1.16.1
|
||||
// Version number example: 1.1.6.1
|
||||
Serial_write(VERSION_MAJOR);
|
||||
Serial_write(VERSION_MINOR);
|
||||
Serial_write(VERSION_REVISION);
|
||||
Serial_write(VERSION_PATCH_LEVEL);
|
||||
Serial_write(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -101,22 +92,25 @@ static void multi_send_status()
|
||||
#ifdef MULTI_TELEMETRY
|
||||
void DSM_frame()
|
||||
{
|
||||
if (pkt[0] == 0x80) {
|
||||
if (pkt[0] == 0x80)
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_DSMBIND, 10);
|
||||
for (uint8_t i = 1; i < 11; i++) // 10 byte of DSM bind response
|
||||
for (uint8_t i = 1; i < 11; i++) // 10 bytes of DSM bind response
|
||||
Serial_write(pkt[i]);
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_DSM, 17);
|
||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
Serial_write(pkt[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void DSM_frame()
|
||||
{
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
Serial_write(pkt[i]);
|
||||
}
|
||||
#endif
|
||||
@@ -128,13 +122,22 @@ static void multi_send_status()
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_AFHDS2A, 29);
|
||||
#else
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
#endif
|
||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||
Serial_write(pkt[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
static void multi_send_frskyhub()
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_HUB, 9);
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
Serial_write(frame[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void frskySendStuffed()
|
||||
{
|
||||
Serial_write(START_STOP);
|
||||
@@ -150,25 +153,53 @@ void frskySendStuffed()
|
||||
Serial_write(START_STOP);
|
||||
}
|
||||
|
||||
void compute_RSSIdbm()
|
||||
{
|
||||
|
||||
RSSI_dBm = (((uint16_t)(pktt[len-2])*18)>>4);
|
||||
if(pktt[len-2] >=128)
|
||||
RSSI_dBm -= 164;
|
||||
else
|
||||
RSSI_dBm += 130;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
for (uint8_t i=3;i<len;i++)
|
||||
pktt[i]=pkt[i];
|
||||
telemetry_link=1;
|
||||
if(pktt[6])
|
||||
telemetry_counter=(telemetry_counter+1)%32;
|
||||
telemetry_link|=1; // Telemetry data is available
|
||||
/*previous version
|
||||
RSSI_dBm = (((uint16_t)(pktt[len-2])*18)>>4);
|
||||
if(pktt[len-2] >=128) RSSI_dBm -= 164;
|
||||
else RSSI_dBm += 130;*/
|
||||
TX_RSSI = pkt[len-2];
|
||||
if(TX_RSSI >=128)
|
||||
TX_RSSI -= 128;
|
||||
else
|
||||
TX_RSSI += 128;
|
||||
TX_LQI = pkt[len-1]&0x7F;
|
||||
for (uint8_t i=3;i<len-2;i++)
|
||||
pktt[i]=pkt[i]; // Buffer telemetry values to be sent
|
||||
|
||||
if(pktt[6]>0 && pktt[6]<=10)
|
||||
{
|
||||
if (protocol==MODE_FRSKYD)
|
||||
{
|
||||
if ( ( pktt[7] & 0x1F ) == (telemetry_counter & 0x1F) )
|
||||
{
|
||||
uint8_t topBit = 0 ;
|
||||
if ( telemetry_counter & 0x80 )
|
||||
{
|
||||
if ( ( telemetry_counter & 0x1F ) != RetrySequence )
|
||||
{
|
||||
topBit = 0x80 ;
|
||||
}
|
||||
}
|
||||
telemetry_counter = ( (telemetry_counter+1)%32 ) | topBit ; // Request next telemetry frame
|
||||
}
|
||||
else
|
||||
{
|
||||
// incorrect sequence
|
||||
RetrySequence = pktt[7] & 0x1F ;
|
||||
telemetry_counter |= 0x80 ;
|
||||
pktt[6]=0 ; // Discard current packet and wait for retransmit
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pktt[6]=0; // Discard packet
|
||||
}
|
||||
//
|
||||
#if defined SPORT_TELEMETRY && defined FRSKYX_CC2500_INO
|
||||
telemetry_lost=0;
|
||||
@@ -192,36 +223,41 @@ void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
||||
}
|
||||
}
|
||||
|
||||
void init_hub_telemetry()
|
||||
void init_frskyd_link_telemetry()
|
||||
{
|
||||
telemetry_link=0;
|
||||
telemetry_counter=0;
|
||||
v_lipo1=0;
|
||||
v_lipo2=0;
|
||||
RSSI_dBm=0;
|
||||
RX_RSSI=0;
|
||||
TX_RSSI=0;
|
||||
RX_LQI=0;
|
||||
TX_LQI=0;
|
||||
}
|
||||
|
||||
void frsky_link_frame()
|
||||
{
|
||||
frame[0] = 0xFE;
|
||||
frame[0] = 0xFE; // Link frame
|
||||
if (protocol==MODE_FRSKYD)
|
||||
{
|
||||
compute_RSSIdbm();
|
||||
frame[1] = pktt[3];
|
||||
frame[2] = pktt[4];
|
||||
frame[3] = pktt[5];
|
||||
frame[4] = (uint8_t)RSSI_dBm;
|
||||
frame[1] = pktt[3]; // A1
|
||||
frame[2] = pktt[4]; // A2
|
||||
frame[3] = pktt[5]; // RX_RSSI
|
||||
telemetry_link &= ~1 ; // Sent
|
||||
telemetry_link |= 2 ; // Send hub if available
|
||||
}
|
||||
else
|
||||
if (protocol==MODE_HUBSAN||protocol==MODE_AFHDS2A||protocol==MODE_BAYANG)
|
||||
{
|
||||
frame[1] = v_lipo1;
|
||||
frame[2] = v_lipo2;
|
||||
frame[3] = (uint8_t)RSSI_dBm;
|
||||
frame[4] = TX_RSSI;
|
||||
frame[3] = RX_RSSI;
|
||||
telemetry_link=0;
|
||||
}
|
||||
frame[5] = frame[6] = frame[7] = frame[8] = 0;
|
||||
frame[4] = TX_RSSI;
|
||||
frame[5] = RX_LQI;
|
||||
frame[6] = TX_LQI;
|
||||
frame[7] = frame[8] = 0;
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_frskyhub();
|
||||
#else
|
||||
@@ -232,66 +268,26 @@ void frsky_link_frame()
|
||||
#if defined HUB_TELEMETRY
|
||||
void frsky_user_frame()
|
||||
{
|
||||
uint8_t indexx = 0, j=8, i;
|
||||
//uint8_t c=0, n=0;
|
||||
|
||||
if(pktt[6]>0 && pktt[6]<=10)
|
||||
{//only valid hub frames
|
||||
frame[0] = 0xFD;
|
||||
frame[2] = pktt[7];
|
||||
switch(pass)
|
||||
if(pktt[6])
|
||||
{//only send valid hub frames
|
||||
frame[0] = 0xFD; // user frame
|
||||
if(pktt[6]>USER_MAX_BYTES)
|
||||
{
|
||||
case 0:
|
||||
indexx=pktt[6];
|
||||
for(i=0;i<indexx;i++)
|
||||
{
|
||||
// if(pktt[j]==0x5E)
|
||||
// {
|
||||
// if(c++)
|
||||
// {
|
||||
// c=0;
|
||||
// n++;
|
||||
// j++;
|
||||
// }
|
||||
// }
|
||||
pktx[i]=pktt[j++];
|
||||
}
|
||||
// indexx = indexx-n;
|
||||
pass=1;
|
||||
|
||||
case 1:
|
||||
indx=indexx;
|
||||
prev_index = indexx;
|
||||
if(indx<USER_MAX_BYTES)
|
||||
{
|
||||
for(i=0;i<indx;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pktt[6]=0;
|
||||
pass=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
indx = USER_MAX_BYTES;
|
||||
for(i=0;i<indx;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pass=2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
indx = prev_index - indx;
|
||||
prev_index=0;
|
||||
if(indx<=(MAX_PKTX-USER_MAX_BYTES)) //10-6=4
|
||||
for(i=0;i<indx;i++)
|
||||
frame[i+3]=pktx[USER_MAX_BYTES+i];
|
||||
pass=0;
|
||||
pktt[6]=0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
frame[1]=USER_MAX_BYTES; // packet size
|
||||
pktt[6]-=USER_MAX_BYTES;
|
||||
telemetry_link |= 2 ; // 2 packets need to be sent
|
||||
}
|
||||
if(!indx)
|
||||
return;
|
||||
frame[1] = indx;
|
||||
else
|
||||
{
|
||||
frame[1]=pktt[6]; // packet size
|
||||
telemetry_link=0; // only 1 packet or processing second packet
|
||||
}
|
||||
frame[2] = pktt[7];
|
||||
for(uint8_t i=0;i<USER_MAX_BYTES;i++)
|
||||
frame[i+3]=pktt[i+8];
|
||||
if(telemetry_link & 2) // prepare the content of second packet
|
||||
for(uint8_t i=8;i<USER_MAX_BYTES+8;i++)
|
||||
pktt[i]=pktt[i+USER_MAX_BYTES];
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_frskyhub();
|
||||
#else
|
||||
@@ -299,10 +295,8 @@ void frsky_user_frame()
|
||||
#endif
|
||||
}
|
||||
else
|
||||
pass=0;
|
||||
telemetry_link=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
HuB RX packets.
|
||||
pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
@@ -317,6 +311,8 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
0A 0F 5E 3A 06 00 5E 5E 3B 09 00 5E
|
||||
05 10 5E 06 16 72 5E 5E 3A 06 00 5E
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
#if defined SPORT_TELEMETRY
|
||||
/* SPORT details serial
|
||||
@@ -437,7 +433,7 @@ void sportSendFrame()
|
||||
frame[0] = 0x98;
|
||||
frame[1] = 0x10;
|
||||
for (i=5;i<8;i++)
|
||||
frame[i]=0;
|
||||
frame[i]=0;
|
||||
}
|
||||
switch (sport_counter)
|
||||
{
|
||||
@@ -451,7 +447,10 @@ void sportSendFrame()
|
||||
case 2: // RSSI
|
||||
frame[2] = 0x01;
|
||||
frame[3] = 0xf1;
|
||||
frame[4] = rssi;
|
||||
frame[4] = RX_RSSI;
|
||||
frame[5] = TX_RSSI;
|
||||
frame[6] = RX_LQI;
|
||||
frame[7] = TX_LQI;
|
||||
break;
|
||||
case 4: //BATT
|
||||
frame[2] = 0x04;
|
||||
@@ -535,45 +534,33 @@ void TelemetryUpdate()
|
||||
h = SerialControl.head ;
|
||||
t = SerialControl.tail ;
|
||||
if ( h >= t )
|
||||
{
|
||||
t += 64 - h ;
|
||||
}
|
||||
t += 128 - h ;
|
||||
else
|
||||
{
|
||||
t -= h ;
|
||||
}
|
||||
if ( t < 32 )
|
||||
{
|
||||
if ( t < 64 )
|
||||
return ;
|
||||
}
|
||||
|
||||
#else
|
||||
uint8_t h ;
|
||||
uint8_t t ;
|
||||
h = tx_head ;
|
||||
t = tx_tail ;
|
||||
if ( h >= t )
|
||||
{
|
||||
t += TXBUFFER_SIZE - h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
t -= h ;
|
||||
}
|
||||
if ( t < 16 )
|
||||
{
|
||||
if ( t < 32 )
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
#if defined MULTI_TELEMETRY
|
||||
{
|
||||
uint32_t now = millis();
|
||||
if ((now - lastMulti) > MULTI_TIME) {
|
||||
multi_send_status();
|
||||
lastMulti = now;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
{
|
||||
uint32_t now = millis();
|
||||
if ((now - lastMulti) > MULTI_TIME)
|
||||
{
|
||||
multi_send_status();
|
||||
lastMulti = now;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined SPORT_TELEMETRY
|
||||
@@ -582,10 +569,10 @@ void TelemetryUpdate()
|
||||
if(telemetry_link)
|
||||
{
|
||||
if(pktt[4] & 0x80)
|
||||
rssi=pktt[4] & 0x7F ;
|
||||
RX_RSSI=pktt[4] & 0x7F ;
|
||||
else
|
||||
RxBt = (pktt[4]<<1) + 1 ;
|
||||
if(pktt[6]<=6)
|
||||
if(pktt[6] && pktt[6]<=6)
|
||||
for (uint8_t i=0; i < pktt[6]; i++)
|
||||
proces_sport_data(pktt[7+i]);
|
||||
telemetry_link=0;
|
||||
@@ -604,7 +591,7 @@ void TelemetryUpdate()
|
||||
#endif
|
||||
|
||||
#if defined DSM_TELEMETRY
|
||||
if(telemetry_link && protocol == MODE_DSM )
|
||||
if(telemetry_link && protocol == MODE_DSM)
|
||||
{ // DSM
|
||||
DSM_frame();
|
||||
telemetry_link=0;
|
||||
@@ -616,17 +603,18 @@ void TelemetryUpdate()
|
||||
{
|
||||
AFHDSA_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(telemetry_link && protocol != MODE_FRSKYX )
|
||||
|
||||
if((telemetry_link & 1 )&& protocol != MODE_FRSKYX)
|
||||
{ // FrSkyD + Hubsan + AFHDS2A + Bayang
|
||||
frsky_link_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if(!telemetry_link && protocol == MODE_FRSKYD)
|
||||
{ // FrSky
|
||||
if((telemetry_link & 2) && protocol == MODE_FRSKYD)
|
||||
{ // FrSkyD
|
||||
frsky_user_frame();
|
||||
return;
|
||||
}
|
||||
@@ -846,7 +834,7 @@ void Serial_write( uint8_t byte )
|
||||
#ifdef INVERT_SERIAL
|
||||
byte |= 1 ; // Start bit
|
||||
#endif
|
||||
uint8_t next = (SerialControl.head + 2) & 0x3f ;
|
||||
uint8_t next = (SerialControl.head + 2) & 0x7f ;
|
||||
if ( next != SerialControl.tail )
|
||||
{
|
||||
SerialControl.data[SerialControl.head] = byte ;
|
||||
@@ -940,7 +928,7 @@ ISR(TIMER0_COMPB_vect)
|
||||
{
|
||||
GPIOR0 = ptr->data[ptr->tail] ;
|
||||
GPIOR2 = ptr->data[ptr->tail+1] ;
|
||||
ptr->tail = ( ptr->tail + 2 ) & 0x3F ;
|
||||
ptr->tail = ( ptr->tail + 2 ) & 0x7F ;
|
||||
GPIOR1 = 8 ;
|
||||
OCR0A = OCR0B + 40 ;
|
||||
OCR0B = OCR0A + 8 * 20 ;
|
||||
@@ -991,7 +979,7 @@ ISR(TIMER0_OVF_vect)
|
||||
{
|
||||
GPIOR0 = ptr->data[ptr->tail] ;
|
||||
GPIOR2 = ptr->data[ptr->tail+1] ;
|
||||
ptr->tail = ( ptr->tail + 2 ) & 0x3F ;
|
||||
ptr->tail = ( ptr->tail + 2 ) & 0x7F ;
|
||||
GPIOR1 = 10 ;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -252,19 +252,18 @@ uint16_t ReadV2x2()
|
||||
return 150;
|
||||
break;
|
||||
case V202_BIND2:
|
||||
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED) {
|
||||
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED)
|
||||
return V2X2_PACKET_CHKTIME;
|
||||
}
|
||||
V2X2_send_packet(1);
|
||||
if (--counter == 0) {
|
||||
if (--bind_counter == 0)
|
||||
{
|
||||
phase = V202_DATA;
|
||||
BIND_DONE;
|
||||
}
|
||||
break;
|
||||
case V202_DATA:
|
||||
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED) {
|
||||
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED)
|
||||
return V2X2_PACKET_CHKTIME;
|
||||
}
|
||||
V2X2_send_packet(0);
|
||||
break;
|
||||
}
|
||||
@@ -278,7 +277,7 @@ uint16_t initV2x2()
|
||||
//
|
||||
if (IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
counter = V2X2_BIND_COUNT;
|
||||
bind_counter = V2X2_BIND_COUNT;
|
||||
phase = V202_INIT2;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -22,8 +22,11 @@
|
||||
#ifdef ORANGE_TX
|
||||
#undef ENABLE_PPM // Disable PPM for OrangeTX module
|
||||
#undef A7105_INSTALLED // Disable A7105 for OrangeTX module
|
||||
#undef A7105_CSN_pin
|
||||
#undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module
|
||||
#undef CC25_CSN_pin
|
||||
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
|
||||
#undef NRF_CSN_pin
|
||||
#define TELEMETRY // Enable telemetry
|
||||
#define INVERT_TELEMETRY // Enable invert telemetry
|
||||
#define DSM_TELEMETRY // Enable DSM telemetry
|
||||
@@ -39,6 +42,7 @@
|
||||
#undef DEVO_CYRF6936_INO
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef J6PRO_CYRF6936_INO
|
||||
#undef WK2x01_CYRF6936_INO
|
||||
#endif
|
||||
#ifndef CC2500_INSTALLED
|
||||
#undef FRSKYD_CC2500_INO
|
||||
@@ -64,6 +68,8 @@
|
||||
#undef FQ777_NRF24L01_INO
|
||||
#undef ASSAN_NRF24L01_INO
|
||||
#undef HONTAI_NRF24L01_INO
|
||||
#undef Q303_NRF24L01_INO
|
||||
#undef GW008_NRF24L01_INO
|
||||
#undef CABELL_NRF24L01_INO
|
||||
#endif
|
||||
|
||||
@@ -77,8 +83,12 @@
|
||||
#undef HUB_TELEMETRY
|
||||
#undef SPORT_TELEMETRY
|
||||
#undef DSM_TELEMETRY
|
||||
#undef MULTI_STATUS
|
||||
#undef MULTI_TELEMETRY
|
||||
#else
|
||||
#if defined MULTI_TELEMETRY && not defined INVERT_TELEMETRY
|
||||
#warning MULTI_TELEMETRY has been defined but not INVERT_TELEMETRY. They should be both enabled for OpenTX telemetry and status to work.
|
||||
#endif
|
||||
#if not defined(BAYANG_NRF24L01_INO)
|
||||
#undef BAYANG_HUB_TELEMETRY
|
||||
#endif
|
||||
@@ -98,7 +108,7 @@
|
||||
#if not defined(DSM_CYRF6936_INO)
|
||||
#undef DSM_TELEMETRY
|
||||
#endif
|
||||
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY)
|
||||
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS)
|
||||
#undef TELEMETRY
|
||||
#undef INVERT_TELEMETRY
|
||||
#endif
|
||||
@@ -111,3 +121,25 @@
|
||||
#if not defined(PPM_MAX_100) || not defined(PPM_MIN_100) || not defined(PPM_MAX_125) || not defined(PPM_MIN_125)
|
||||
#error You must set correct TX end points.
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_BIND_CH)
|
||||
#if BIND_CH<4
|
||||
#error BIND_CH must be above 4.
|
||||
#endif
|
||||
#if BIND_CH>16
|
||||
#error BIND_CH must be below or equal to 16.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MIN_PPM_CHANNELS>16
|
||||
#error MIN_PPM_CHANNELS must be below or equal to 16. The default for this value is 4.
|
||||
#endif
|
||||
#if MIN_PPM_CHANNELS<2
|
||||
#error MIN_PPM_CHANNELS must be larger than 1. The default for this value is 4.
|
||||
#endif
|
||||
#if MAX_PPM_CHANNELS<MIN_PPM_CHANNELS
|
||||
#error MAX_PPM_CHANNELS must be higher than MIN_PPM_CHANNELS. The default for this value is 16.
|
||||
#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
|
||||
|
||||
491
Multiprotocol/WK2x01_cyrf6936.ino
Normal file
491
Multiprotocol/WK2x01_cyrf6936.ino
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
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(WK2x01_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define WK_BIND_COUNT 2980
|
||||
#define WK_NUM_WAIT_LOOPS (100 / 5) //each loop is ~5us. Do not wait more than 100us
|
||||
|
||||
enum {
|
||||
WK_BIND=0,
|
||||
WK_BOUND_1,
|
||||
WK_BOUND_2,
|
||||
WK_BOUND_3,
|
||||
WK_BOUND_4,
|
||||
WK_BOUND_5,
|
||||
WK_BOUND_6,
|
||||
WK_BOUND_7,
|
||||
WK_BOUND_8,
|
||||
};
|
||||
|
||||
static const uint8_t WK_sopcodes[8] = {
|
||||
/* Note these are in order transmitted (LSB 1st) */
|
||||
0xDF,0xB1,0xC0,0x49,0x62,0xDF,0xC1,0x49 //0x49C1DF6249C0B1DF
|
||||
};
|
||||
static const uint8_t init_2801[] = {0xc5, 0x34, 0x60, 0x00, 0x25};
|
||||
static const uint8_t init_2601[] = {0xb9, 0x45, 0xb0, 0xf1, 0x3a};
|
||||
static const uint8_t init_2401[] = {0xa5, 0x23, 0xd0, 0xf0, 0x00};
|
||||
|
||||
uint8_t WK_last_beacon;
|
||||
|
||||
static void __attribute__((unused)) WK_add_pkt_crc(uint8_t init)
|
||||
{
|
||||
uint8_t add = init;
|
||||
uint8_t xou = init;
|
||||
for (uint8_t i = 0; i < 14; i++)
|
||||
{
|
||||
add += packet[i];
|
||||
xou ^= packet[i];
|
||||
}
|
||||
packet[14] = xou;
|
||||
packet[15] = add;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_build_bind_pkt(const uint8_t *init)
|
||||
{
|
||||
packet[0] = init[0];
|
||||
packet[1] = init[1];
|
||||
packet[2] = hopping_frequency[0];
|
||||
packet[3] = hopping_frequency[1];
|
||||
packet[4] = init[2];
|
||||
packet[5] = hopping_frequency[2];
|
||||
packet[6] = 0xff;
|
||||
packet[7] = 0x00;
|
||||
packet[8] = 0x00;
|
||||
packet[9] = 0x32;
|
||||
if (sub_protocol == WK2401)
|
||||
packet[10] = 0x10 | (rx_tx_addr[0] & 0x0e);
|
||||
else
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2] | packet_count;
|
||||
packet[13] = init[3];
|
||||
WK_add_pkt_crc(init[4]);
|
||||
}
|
||||
|
||||
static int16_t __attribute__((unused)) WK_get_channel(uint8_t ch, int32_t scale, int16_t center, int16_t range)
|
||||
{
|
||||
int16_t value = map(Servo_data[CH_AETR[ch]],servo_min_100,servo_max_100,-scale,scale)+center;
|
||||
if (value < center - range) value = center - range;
|
||||
if (value > center + range) value = center + range;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_build_data_pkt_2401()
|
||||
{
|
||||
uint16_t msb = 0;
|
||||
uint8_t offset = 0;
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
if (i == 2)
|
||||
offset = 1;
|
||||
int16_t value = WK_get_channel(i, 0x800, 0, 0xA00); //12 bits, allow value to go to 125%
|
||||
uint16_t base = abs(value) >> 2; //10 bits is the base value
|
||||
uint16_t trim = abs(value) & 0x03; //lowest 2 bits represent trim
|
||||
if (base >= 0x200)
|
||||
{ //if value is > 100%, remainder goes to trim
|
||||
trim = 4 *(base - 0x200);
|
||||
base = 0x1ff;
|
||||
}
|
||||
base = (value >= 0) ? 0x200 + base : 0x200 - base;
|
||||
trim = (value >= 0) ? 0x200 + trim : 0x200 - trim;
|
||||
|
||||
packet[2*i+offset] = base & 0xff;
|
||||
packet[2*i+offset+1] = trim & 0xff;
|
||||
msb = (msb << 4) | ((base >> 6) & 0x0c) | ((trim >> 8) & 0x03);
|
||||
}
|
||||
packet[4] = msb >> 8; //Ele/Ail MSB
|
||||
packet[9] = msb & 0xff; //Thr/Rud MSB
|
||||
packet[10] = 0xe0 | (rx_tx_addr[0] & 0x0e);
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2] | packet_count;
|
||||
packet[13] = 0xf0; //FIXME - What is this?
|
||||
WK_add_pkt_crc(0x00);
|
||||
}
|
||||
|
||||
#define PCT(pct, max) (((int32_t)(max) * (int32_t)(pct) + 1L) / 1000L)
|
||||
#define MAXTHR 426 //Measured to provide equal value at +/-0
|
||||
static void __attribute__((unused)) WK_channels_6plus1_2601(uint8_t frame, int16_t *_v1, int16_t *_v2)
|
||||
{
|
||||
int16_t thr = WK_get_channel(2, 1000, 0, 1000);
|
||||
int16_t v1;
|
||||
uint8_t thr_rev = 0, pitch_rev = 0;
|
||||
if(thr > 0)
|
||||
{
|
||||
if(thr >= 780)
|
||||
{ //78%
|
||||
v1 = 0; //thr = 60% * (x - 78%) / 22% + 40%
|
||||
thr = PCT(1000-MAXTHR,512) * (thr-PCT(780,1000)) / PCT(220,1000) + PCT(MAXTHR,512);
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = 1023 - 1023 * thr / 780;
|
||||
thr = PCT(MAXTHR, 512); //40%
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thr = -thr;
|
||||
thr_rev = 1;
|
||||
if(thr >= 780)
|
||||
{ //78%
|
||||
v1 = 1023; //thr = 60% * (x - 78%) / 22% + 40%
|
||||
thr = PCT(1000-MAXTHR,512) * (thr-PCT(780,1000)) / PCT(220,1000) + PCT(MAXTHR,512);
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = 1023 * thr / 780;
|
||||
thr = PCT(MAXTHR, 512); //40%
|
||||
}
|
||||
}
|
||||
if (thr >= 512)
|
||||
thr = 511;
|
||||
packet[2] = thr & 0xff;
|
||||
packet[4] = (packet[4] & 0xF3) | ((thr >> 6) & 0x04);
|
||||
|
||||
int16_t pitch= WK_get_channel(5, 0x400, 0, 0x400);
|
||||
if (pitch < 0)
|
||||
{
|
||||
pitch_rev = 1;
|
||||
pitch = -pitch;
|
||||
}
|
||||
if (frame == 1)
|
||||
{
|
||||
//Pitch curve and range
|
||||
if (thr > PCT(MAXTHR, 512))
|
||||
*_v2 = pitch - pitch * 16 * (thr - PCT(MAXTHR, 512)) / PCT(1000 - MAXTHR, 512) / 100;
|
||||
else
|
||||
*_v2 = pitch;
|
||||
*_v1 = 0;
|
||||
}
|
||||
else
|
||||
if (frame == 2)
|
||||
{
|
||||
//Throttle curve & Expo
|
||||
*_v1 = v1;
|
||||
*_v2 = 512;
|
||||
}
|
||||
packet[7] = (thr_rev << 5) | (pitch_rev << 2); //reverse bits
|
||||
packet[8] = 0;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_channels_5plus1_2601(uint8_t frame, int16_t *v1, int16_t *v2)
|
||||
{
|
||||
(void)v1;
|
||||
//Zero out pitch, provide ail, ele, thr, rud, gyr + gear
|
||||
if (frame == 1)
|
||||
*v2 = 0; //Pitch curve and range
|
||||
packet[7] = 0;
|
||||
packet[8] = 0;
|
||||
}
|
||||
static void __attribute__((unused)) WK_channels_heli_2601(uint8_t frame, int16_t *v1, int16_t *v2)
|
||||
{
|
||||
//pitch is controlled by rx
|
||||
//we can only control fmode, pit-reverse and pit/thr rate
|
||||
uint8_t pit_rev = 0;
|
||||
if (sub_protocol==W6_HEL_I)
|
||||
pit_rev = 1;
|
||||
int16_t pit_rate = WK_get_channel(5, 0x400, 0, 0x400);
|
||||
uint8_t fmode = 1;
|
||||
if (pit_rate < 0)
|
||||
{
|
||||
pit_rate = -pit_rate;
|
||||
fmode = 0;
|
||||
}
|
||||
if (frame == 1)
|
||||
{
|
||||
//Pitch curve and range
|
||||
*v1 = pit_rate;
|
||||
*v2 = (int16_t)(option) * 0x400 / 100 + 0x400;
|
||||
}
|
||||
packet[7] = (pit_rev << 2); //reverse bits
|
||||
packet[8] = fmode ? 0x02 : 0x00;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_build_data_pkt_2601()
|
||||
{
|
||||
uint8_t msb = 0;
|
||||
uint8_t frame = (packet_count % 3);
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value = WK_get_channel(i, 0x190, 0, 0x1FF);
|
||||
uint16_t mag = value < 0 ? -value : value;
|
||||
packet[i] = mag & 0xff;
|
||||
msb = (msb << 2) | ((mag >> 8) & 0x01) | (value < 0 ? 0x02 : 0x00);
|
||||
}
|
||||
packet[4] = msb;
|
||||
int16_t v1 = 0x200, v2 = 0x200;
|
||||
if (frame == 0)
|
||||
{
|
||||
//Gyro & Rudder mix
|
||||
v1 = WK_get_channel(6, 0x200, 0x200, 0x200);
|
||||
v2 = 0;
|
||||
}
|
||||
if (sub_protocol == W6_5_1)
|
||||
WK_channels_5plus1_2601(frame, &v1, &v2);
|
||||
else if (sub_protocol == W6_6_1)
|
||||
WK_channels_6plus1_2601(frame, &v1, &v2);
|
||||
else
|
||||
WK_channels_heli_2601(frame, &v1, &v2);
|
||||
if (v1 > 1023)
|
||||
v1 = 1023;
|
||||
if (v2 > 1023)
|
||||
v2 = 1023;
|
||||
packet[5] = v2 & 0xff;
|
||||
packet[6] = v1 & 0xff;
|
||||
//packet[7] handled by channel code
|
||||
packet[8] |= (WK_get_channel(4, 0x190, 0, 0x1FF) > 0 ? 1 : 0);
|
||||
packet[9] = ((v1 >> 4) & 0x30) | ((v2 >> 2) & 0xc0) | 0x04 | frame;
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2] | packet_count;
|
||||
packet[13] = 0xff;
|
||||
|
||||
WK_add_pkt_crc(0x3A);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_build_data_pkt_2801()
|
||||
{
|
||||
uint16_t msb = 0;
|
||||
uint8_t offset = 0;
|
||||
uint8_t sign = 0;
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (i == 4) { offset = 1; }
|
||||
int16_t value = WK_get_channel(i, 0x1C2, 0, 0x3FF);
|
||||
uint16_t mag = value < 0 ? -value : value;
|
||||
packet[i+offset] = mag & 0xff;
|
||||
msb = (msb << 2) | ((mag >> 8) & 0x03);
|
||||
if (value < 0) { sign |= 1 << i; }
|
||||
}
|
||||
packet[4] = msb >> 8;
|
||||
packet[9] = msb & 0xff;
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2] | packet_count;
|
||||
packet[13] = sign;
|
||||
WK_add_pkt_crc(0x25);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_build_beacon_pkt_2801()
|
||||
{
|
||||
WK_last_beacon ^= 1;
|
||||
uint8_t en = 0;
|
||||
uint8_t bind_state;
|
||||
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select && option==0 && IS_BIND_DONE_on) //PPM mode and option not already set and bind is finished
|
||||
{
|
||||
BIND_SET_INPUT;
|
||||
BIND_SET_PULLUP; // set pullup
|
||||
if(IS_BIND_BUTTON_on)
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)(30+mode_select),0x01); // Set fixed id mode for the current model
|
||||
option=1;
|
||||
}
|
||||
BIND_SET_OUTPUT;
|
||||
}
|
||||
#endif //ENABLE_PPM
|
||||
if(prev_option!=option && IS_BIND_DONE_on)
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
rx_tx_addr[2]=rx_tx_addr[3]<<4; // Make use of RX_Num
|
||||
bind_counter = WK_BIND_COUNT / 8 + 1;
|
||||
}
|
||||
if (option)
|
||||
{
|
||||
if (bind_counter)
|
||||
bind_state = 0xe4;
|
||||
else
|
||||
bind_state = 0x1b;
|
||||
}
|
||||
else
|
||||
bind_state = 0x99;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{ // failsafe info: WARNING All channels are set to 0 instead of midstick and 0 for throttle
|
||||
packet[i+1] = 0;
|
||||
}
|
||||
packet[0] = en;
|
||||
packet[5] = packet[4];
|
||||
packet[4] = WK_last_beacon << 6;
|
||||
packet[6] = hopping_frequency[0];
|
||||
packet[7] = hopping_frequency[1];
|
||||
packet[8] = hopping_frequency[2];
|
||||
packet[9] = bind_state;
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2] | packet_count;
|
||||
packet[13] = 0x00; //Does this matter? in the docs it is the same as the data packet
|
||||
WK_add_pkt_crc(0x1C);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) wk2x01_cyrf_init() {
|
||||
/* Initialize CYRF chip */
|
||||
CYRF_SetPower(0x28);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A);
|
||||
CYRF_WriteRegister(CYRF_0B_PWR_CTRL, 0x00);
|
||||
CYRF_WriteRegister(CYRF_0C_XTAL_CTRL, 0xC0);
|
||||
CYRF_WriteRegister(CYRF_0D_IO_CFG, 0x04);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x2C);
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xEE);
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
|
||||
CYRF_WriteRegister(CYRF_1D_MODE_OVERRIDE, 0x18);
|
||||
CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
|
||||
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
|
||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x90);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_01_TX_LENGTH, 0x10);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x2C);
|
||||
CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
|
||||
CYRF_WriteRegister(CYRF_27_CLK_OVERRIDE, 0x02);
|
||||
CYRF_ConfigSOPCode(WK_sopcodes);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28);
|
||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x10);
|
||||
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL, 0x20);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x2C);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_BuildPacket_2801()
|
||||
{
|
||||
switch(phase) {
|
||||
case WK_BIND:
|
||||
bind_counter--;
|
||||
WK_build_bind_pkt(init_2801);
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
phase++;
|
||||
}
|
||||
break;
|
||||
case WK_BOUND_1:
|
||||
case WK_BOUND_2:
|
||||
case WK_BOUND_3:
|
||||
case WK_BOUND_4:
|
||||
case WK_BOUND_5:
|
||||
case WK_BOUND_6:
|
||||
case WK_BOUND_7:
|
||||
WK_build_data_pkt_2801();
|
||||
phase++;
|
||||
break;
|
||||
case WK_BOUND_8:
|
||||
WK_build_beacon_pkt_2801();
|
||||
phase = WK_BOUND_1;
|
||||
if (bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
BIND_DONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_BuildPacket_2601()
|
||||
{
|
||||
if (bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
WK_build_bind_pkt(init_2601);
|
||||
if (bind_counter == 0)
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
WK_build_data_pkt_2601();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) WK_BuildPacket_2401()
|
||||
{
|
||||
if (bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
WK_build_bind_pkt(init_2401);
|
||||
if(bind_counter == 0)
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
WK_build_data_pkt_2401();
|
||||
}
|
||||
|
||||
uint16_t WK_cb()
|
||||
{
|
||||
if (packet_sent == 0)
|
||||
{
|
||||
packet_sent = 1;
|
||||
if(sub_protocol == WK2801)
|
||||
WK_BuildPacket_2801();
|
||||
else if(sub_protocol == WK2401)
|
||||
WK_BuildPacket_2401();
|
||||
else
|
||||
WK_BuildPacket_2601();
|
||||
packet_count = (packet_count + 1) % 12;
|
||||
CYRF_WriteDataPacket(packet);
|
||||
return 1600;
|
||||
}
|
||||
packet_sent = 0;
|
||||
uint8_t start=micros();
|
||||
while ((uint8_t)micros()-start < 100) // Wait max 100µs
|
||||
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||
break;
|
||||
if((packet_count & 0x03) == 0)
|
||||
{
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no%=3;
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
//Keep transmit power updated
|
||||
CYRF_SetPower(0x28);
|
||||
}
|
||||
return 1200;
|
||||
}
|
||||
|
||||
uint16_t WK_setup() {
|
||||
wk2x01_cyrf_init();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
|
||||
hopping_frequency_no=0;
|
||||
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
|
||||
CYRF_ConfigRFChannel(hopping_frequency[0]);
|
||||
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
WK_last_beacon = 0;
|
||||
prev_option=option;
|
||||
if(sub_protocol!=WK2801 || option==0)
|
||||
{
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
rx_tx_addr[2]=(hopping_frequency[0] ^ cyrfmfg_id[0] ^ cyrfmfg_id[3])<<4;
|
||||
rx_tx_addr[1]=hopping_frequency[1] ^ cyrfmfg_id[1] ^ cyrfmfg_id[4];
|
||||
rx_tx_addr[0]=hopping_frequency[2] ^ cyrfmfg_id[2] ^ cyrfmfg_id[5];
|
||||
if(sub_protocol == WK2401)
|
||||
rx_tx_addr[0] |= 0x01; //ID must be odd for 2401
|
||||
|
||||
bind_counter = WK_BIND_COUNT;
|
||||
phase = WK_BIND;
|
||||
BIND_IN_PROGRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
rx_tx_addr[2]=rx_tx_addr[3]<<4; // Make use of RX_Num
|
||||
bind_counter = 0;
|
||||
phase = WK_BOUND_1;
|
||||
BIND_DONE;
|
||||
}
|
||||
return 2800;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -18,10 +18,9 @@
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define YD717_BIND_COUNT 60
|
||||
#define YD717_BIND_COUNT 120
|
||||
#define YD717_PACKET_PERIOD 8000 // Timeout for callback in uSec, 8ms=8000us for YD717
|
||||
#define YD717_INITIAL_WAIT 50000 // Initial wait before starting callbacks
|
||||
#define YD717_PACKET_CHKTIME 500 // Time to wait if packet not yet acknowledged or timed out
|
||||
|
||||
// Stock tx fixed frequency is 0x3C. Receiver only binds on this freq.
|
||||
#define YD717_RF_CHANNEL 0x3C
|
||||
@@ -125,32 +124,32 @@ static void __attribute__((unused)) yd717_init()
|
||||
// CRC, radio on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // Disable Acknoledgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00); // Disable all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, YD717_RF_CHANNEL); // Channel 3C
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x3F); // Enable Acknowledgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x1A); // 500uS retransmit t/o, 10 tries
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, YD717_RF_CHANNEL); // Channel 3C
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
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_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
|
||||
// for bind packets set address to prearranged value known to receiver
|
||||
uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65};
|
||||
|
||||
uint8_t bind_rx_tx_addr[5];
|
||||
uint8_t offset=5;
|
||||
if( sub_protocol==SYMAX4 )
|
||||
for(uint8_t i=0; i < 5; i++)
|
||||
bind_rx_tx_addr[i] = 0x60;
|
||||
offset=0;
|
||||
else
|
||||
if( sub_protocol==NIHUI )
|
||||
for(uint8_t i=0; i < 5; i++)
|
||||
bind_rx_tx_addr[i] = 0x64;
|
||||
|
||||
offset=4;
|
||||
for(uint8_t i=0; i < 5; i++)
|
||||
bind_rx_tx_addr[i] = 0x60 + offset;
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bind_rx_tx_addr, 5);
|
||||
}
|
||||
|
||||
uint16_t yd717_callback()
|
||||
@@ -162,6 +161,7 @@ uint16_t yd717_callback()
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); // set address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
||||
yd717_send_packet(0);
|
||||
BIND_DONE; // bind complete
|
||||
}
|
||||
|
||||
@@ -17,16 +17,6 @@
|
||||
/** Multiprotocol module configuration file ***/
|
||||
/**********************************************/
|
||||
|
||||
/********************/
|
||||
/*** BOARD TYPE ***/
|
||||
/********************/
|
||||
//Uncomment one of the line below if you have a different module not based on the original Multi Atmega328p design which includes the 4-in-1.
|
||||
//If you don't know then leave them commented.
|
||||
#ifdef __arm__
|
||||
#define STM32_BOARD // Let's automatically select this board if arm is selected since this is the only one for now...
|
||||
#endif
|
||||
|
||||
|
||||
/*******************/
|
||||
/*** TX SETTINGS ***/
|
||||
/*******************/
|
||||
@@ -42,9 +32,27 @@
|
||||
//#define REVERSE_RUDDER
|
||||
|
||||
|
||||
/**************************/
|
||||
/*** RF CHIPS INSTALLED ***/
|
||||
/**************************/
|
||||
/*************************/
|
||||
/*** BIND FROM CHANNEL ***/
|
||||
/*************************/
|
||||
//Bind from channel enables you to bind when a specified channel is giong from low to high. This feature is only active
|
||||
// if you specify AUTOBIND in PPM mode or set AutoBind to YES for serial mode. It also requires that the throttle channel is low.
|
||||
|
||||
//Comment to globaly disable the bind feature from a channel.
|
||||
#define ENABLE_BIND_CH
|
||||
|
||||
//Set the channel number used for bind. Default is 16.
|
||||
#define BIND_CH 16
|
||||
|
||||
//Comment to disable the wait for bind feature. This feature will not activate the selected
|
||||
// protocol unless a bind is requested using bind from channel or the GUI "Bind" button.
|
||||
//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
|
||||
|
||||
|
||||
/****************/
|
||||
/*** RF CHIPS ***/
|
||||
/****************/
|
||||
//There are 4 RF components supported. If one of them is not installed you must comment it using "//".
|
||||
//If a chip is not installed all associated protocols are disabled.
|
||||
//4-in-1 modules have all RF chips installed
|
||||
@@ -54,6 +62,14 @@
|
||||
#define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
|
||||
//Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI).
|
||||
//It can be activated when flying indoor or small models since the distance is short or if a model is causing issues when flying closed to the TX.
|
||||
//By default low power is completly disabled on all rf chips to prevent mistakes, but you can enable it by uncommenting the lines below:
|
||||
//#define A7105_ENABLE_LOW_POWER
|
||||
//#define CYRF6936_ENABLE_LOW_POWER
|
||||
//#define CC2500_ENABLE_LOW_POWER
|
||||
//#define NRF24L01_ENABLE_LOW_POWER
|
||||
|
||||
|
||||
/****************************/
|
||||
/*** PROTOCOLS TO INCLUDE ***/
|
||||
@@ -71,10 +87,11 @@
|
||||
#define DEVO_CYRF6936_INO
|
||||
#define DSM_CYRF6936_INO
|
||||
#define J6PRO_CYRF6936_INO
|
||||
#define WK2x01_CYRF6936_INO
|
||||
|
||||
//The protocols below need a CC2500 to be installed
|
||||
#define FRSKYD_CC2500_INO
|
||||
#define FRSKYV_CC2500_INO
|
||||
#define FRSKYD_CC2500_INO
|
||||
#define FRSKYX_CC2500_INO
|
||||
#define SFHSS_CC2500_INO
|
||||
|
||||
@@ -96,9 +113,10 @@
|
||||
#define FQ777_NRF24L01_INO
|
||||
#define ASSAN_NRF24L01_INO
|
||||
#define HONTAI_NRF24L01_INO
|
||||
#define Q303_NRF24L01_INO
|
||||
#define GW008_NRF24L01_INO
|
||||
#define CABELL_NRF24L01_INO
|
||||
|
||||
|
||||
/**************************/
|
||||
/*** TELEMETRY SETTINGS ***/
|
||||
/**************************/
|
||||
@@ -107,15 +125,23 @@
|
||||
//If you do not plan using the telemetry comment this global setting using "//" and skip to the next section.
|
||||
#define TELEMETRY
|
||||
|
||||
//Uncomment to invert the polarity of the telemetry serial signal.
|
||||
//For ER9X and ERSKY9X it must be commented. For OpenTX it must be uncommented.
|
||||
//Comment to invert the polarity of the output telemetry serial signal.
|
||||
//This function takes quite some flash space and processor power on an atmega.
|
||||
//For OpenTX it must be uncommented.
|
||||
//On a 9XR_PRO running ersky9x both commented and uncommented will work depending on the radio setting Invert COM1 under the Telemetry menu.
|
||||
//On other addon/replacement boards like the 9xtreme board or the Ar9x board running ersky9x, you need to uncomment the line below.
|
||||
//For er9x it depends if you have an inveter mod or not on the telemetry pin. If you don't have an inverter comment this line.
|
||||
//#define INVERT_TELEMETRY
|
||||
|
||||
//Uncomment to send also Multi status and wrap other telemetry to allow TX to autodetect the format
|
||||
//Only for newest OpenTX version
|
||||
//Comment if you don't want to send Multi status telemetry frames (Protocol available, Bind in progress, version...)
|
||||
//Use with er9x/erksy9x, for OpenTX MULTI_TELEMETRY below is preferred instead
|
||||
#define MULTI_STATUS
|
||||
|
||||
//Uncomment to send Multi status and allow OpenTX to autodetect the telemetry format
|
||||
//Supported by OpenTX version 2.2 RC9 and newer. NOT supported by er9x/ersky9x use MULTI_STATUS instead.
|
||||
//#define MULTI_TELEMETRY
|
||||
|
||||
//Comment a line to disable a protocol telemetry
|
||||
//Comment a line to disable a specific protocol telemetry
|
||||
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded
|
||||
#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
|
||||
#define AFHDS2A_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded
|
||||
@@ -124,6 +150,7 @@
|
||||
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
|
||||
|
||||
/****************************/
|
||||
/*** SERIAL MODE SETTINGS ***/
|
||||
/****************************/
|
||||
@@ -149,8 +176,9 @@
|
||||
#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs)
|
||||
//#define TX_DEVO7 //DEVO (1120<->1920µs)
|
||||
//#define TX_SPEKTRUM //Spektrum (1100<->1900µs)
|
||||
//#define TX_HISKY //HISKY (1100<->1900µs)
|
||||
//#define TX_HISKY //HISKY (1120<->1920µs)
|
||||
//#define TX_MPX //Multiplex MC2020 (1250<->1950µs)
|
||||
//#define TX_WALKERA //Walkera PL0811-01H (1000<->1800µs)
|
||||
//#define TX_CUSTOM //Custom
|
||||
|
||||
// The lines below are used to set the end points in microseconds (µs) if you have selected TX_CUSTOM.
|
||||
@@ -166,6 +194,13 @@
|
||||
#define PPM_MIN_125 1000 // 125%
|
||||
#endif
|
||||
|
||||
// The line below is used to set the minimum number of channels which the module should receive to consider a PPM frame valid.
|
||||
// The default value is 4 to receive at least AETR for flying models but you could also connect the PPM from a car radio which has only 3 channels by changing this number to 3.
|
||||
#define MIN_PPM_CHANNELS 4
|
||||
// The line below is used to set the maximum number of channels which the module should work with. Any channels received above this number are discarded.
|
||||
// The default value is 16 to receive all possible channels but you might want to filter some "bad" channels from the PPM frame like the ones above 6 on the Walkera PL0811.
|
||||
#define MAX_PPM_CHANNELS 16
|
||||
|
||||
//The table below indicates which protocol to run when a specific position on the dial has been selected.
|
||||
//All fields and values are explained below. Everything is configurable from here like in the Serial mode.
|
||||
//Example: You can associate multiple times the same protocol to different dial positions to take advantage of the model match (RX_Num)
|
||||
@@ -196,8 +231,15 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
CX20
|
||||
MODE_HUBSAN
|
||||
NONE
|
||||
MODE_FRSKYV
|
||||
NONE
|
||||
MODE_FRSKYD
|
||||
NONE
|
||||
MODE_FRSKYX
|
||||
CH_16
|
||||
CH_8
|
||||
EU_16
|
||||
EU_8
|
||||
MODE_HISKY
|
||||
Hisky
|
||||
HK310
|
||||
@@ -246,9 +288,6 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
MODE_BAYANG
|
||||
BAYANG
|
||||
H8S3D
|
||||
MODE_FRSKYX
|
||||
CH_16
|
||||
CH_8
|
||||
MODE_ESKY
|
||||
NONE
|
||||
MODE_MT99XX
|
||||
@@ -277,8 +316,6 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
NONE
|
||||
MODE_ASSAN
|
||||
NONE
|
||||
MODE_FRSKYV
|
||||
NONE
|
||||
MODE_HONTAI
|
||||
FORMAT_HONTAI
|
||||
FORMAT_JJRCX1
|
||||
@@ -289,6 +326,20 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
PPM_IBUS
|
||||
PWM_SBUS
|
||||
PPM_SBUS
|
||||
MODE_WK2X01
|
||||
WK2801
|
||||
WK2401
|
||||
W6_5_1
|
||||
W6_6_1
|
||||
W6_HEL
|
||||
W6_HEL_I
|
||||
MODE_Q303
|
||||
Q303
|
||||
CX35
|
||||
CX10D
|
||||
CX10WD
|
||||
MODE_GW008
|
||||
NONE
|
||||
MODE_CABELL
|
||||
CABELL_V3
|
||||
CABELL_SET_FAIL_SAFE
|
||||
@@ -304,6 +355,7 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
// Auto Bind AUTOBIND or NO_AUTOBIND
|
||||
// For protocols which does not require binding at each power up (like Flysky, FrSky...), you might still want a bind to be initiated each time you power up the TX.
|
||||
// As an example, it's usefull for the WLTOYS F929/F939/F949/F959 (all using the Flysky protocol) which requires a bind at each power up.
|
||||
// It also enables the Bind from channel feature, allowing to execute a bind by toggling a designated channel.
|
||||
|
||||
// Option: the value is between -127 and +127.
|
||||
// Option: the value is between -128 and +127.
|
||||
// The option value is only valid for some protocols, read this page for more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md
|
||||
|
||||
@@ -16,16 +16,6 @@
|
||||
#ifndef _IFACE_CC2500_H_
|
||||
#define _IFACE_CC2500_H_
|
||||
|
||||
enum {
|
||||
FRSKY_BIND = 0,
|
||||
FRSKY_BIND_DONE = 1000,
|
||||
FRSKY_DATA1,
|
||||
FRSKY_DATA2,
|
||||
FRSKY_DATA3,
|
||||
FRSKY_DATA4,
|
||||
FRSKY_DATA5
|
||||
};
|
||||
|
||||
enum {
|
||||
CC2500_00_IOCFG2 = 0x00, // GDO2 output pin configuration
|
||||
CC2500_01_IOCFG1 = 0x01, // GDO1 output pin configuration
|
||||
@@ -157,42 +147,4 @@ enum {
|
||||
//void CC2500_ReadData(u8 *dpbuffer, int len);
|
||||
//void CC2500_SetTxRxMode(enum TXRX_State);
|
||||
|
||||
const PROGMEM uint8_t cc2500_conf[][2]={
|
||||
{ CC2500_02_IOCFG0, 0x06 },
|
||||
{ CC2500_00_IOCFG2, 0x06 },
|
||||
{ CC2500_17_MCSM1, 0x0c },
|
||||
{ CC2500_18_MCSM0, 0x18 },
|
||||
{ CC2500_06_PKTLEN, 0x19 },
|
||||
{ CC2500_07_PKTCTRL1, 0x04 },
|
||||
{ CC2500_08_PKTCTRL0, 0x05 },
|
||||
{ CC2500_3E_PATABLE, 0xff },
|
||||
{ CC2500_0B_FSCTRL1, 0x08 },
|
||||
{ CC2500_0C_FSCTRL0, 0x00 }, // option
|
||||
{ CC2500_0D_FREQ2, 0x5c },
|
||||
{ CC2500_0E_FREQ1, 0x76 },
|
||||
{ CC2500_0F_FREQ0, 0x27 },
|
||||
{ CC2500_10_MDMCFG4, 0xAA },
|
||||
{ CC2500_11_MDMCFG3, 0x39 },
|
||||
{ CC2500_12_MDMCFG2, 0x11 },
|
||||
{ CC2500_13_MDMCFG1, 0x23 },
|
||||
{ CC2500_14_MDMCFG0, 0x7a },
|
||||
{ CC2500_15_DEVIATN, 0x42 },
|
||||
{ CC2500_19_FOCCFG, 0x16 },
|
||||
{ CC2500_1A_BSCFG, 0x6c },
|
||||
{ CC2500_1B_AGCCTRL2, 0x43 }, // bind ? 0x43 : 0x03
|
||||
{ CC2500_1C_AGCCTRL1,0x40 },
|
||||
{ CC2500_1D_AGCCTRL0,0x91 },
|
||||
{ CC2500_21_FREND1, 0x56 },
|
||||
{ CC2500_22_FREND0, 0x10 },
|
||||
{ CC2500_23_FSCAL3, 0xa9 },
|
||||
{ CC2500_24_FSCAL2, 0x0A },
|
||||
{ CC2500_25_FSCAL1, 0x00 },
|
||||
{ CC2500_26_FSCAL0, 0x11 },
|
||||
{ CC2500_29_FSTEST, 0x59 },
|
||||
{ CC2500_2C_TEST2, 0x88 },
|
||||
{ CC2500_2D_TEST1, 0x31 },
|
||||
{ CC2500_2E_TEST0, 0x0B },
|
||||
{ CC2500_03_FIFOTHR, 0x07 },
|
||||
{ CC2500_09_ADDR, 0x00 }
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user