BUGS new protocol

BUGS new protocol (number 41)
Models: Bugs 3, 6 and 8
Autobind protocol
Telemetry: TX & RX RSSI, Battery voltage good/bad
ARM	CH5
LED		CH6
FLIP		CH7
PICTURE	CH8
VIDEO	CH9
This commit is contained in:
Pascal Langer 2018-08-28 16:13:28 +02:00
parent db093cf25b
commit e7449897f9
8 changed files with 549 additions and 22 deletions

View File

@ -182,6 +182,11 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
offset=(int16_t)FORCE_HUBSAN_TUNING;
#endif
break;
case PROTO_BUGS:
#ifdef FORCE_HUBSAN_TUNING
offset=(int16_t)FORCE_HUBSAN_TUNING;
#endif
break;
case PROTO_FLYSKY:
#ifdef FORCE_FLYSKY_TUNING
offset=(int16_t)FORCE_FLYSKY_TUNING;
@ -222,21 +227,40 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
//debugln("Channel: %d, offset: %d, bip: %2x, bfp: %4x", Channel_data[14], offset, bip, bfp);
}
static void __attribute__((unused)) A7105_SetVCOBand(uint8_t vb1, uint8_t vb2)
{ // Set calibration band value to best match
uint8_t diff1, diff2;
if (vb1 >= 4)
diff1 = vb1 - 4;
else
diff1 = 4 - vb1;
if (vb2 >= 4)
diff2 = vb2 - 4;
else
diff2 = 4 - vb2;
if (diff1 == diff2 || diff1 > diff2)
A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb1 | 0x08);
else
A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb2 | 0x08);
}
#ifdef HUBSAN_A7105_INO
const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07,
0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF
0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF, // 00 - 0f
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07, // 10 - 1f
0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20 - 2f
0xFF, 0xFF // 30 - 31
};
#endif
#ifdef FLYSKY_A7105_INO
const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50,
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f,
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
0x01, 0x0f
0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, // 00 - 0f
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
0x01, 0x0f // 30 - 31
};
#endif
#ifdef AFHDS2A_A7105_INO
@ -247,13 +271,37 @@ const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
0x01, 0x0f // 30 - 31
};
#endif
#ifdef BUGS_A7105_INO
const uint8_t PROGMEM BUGS_A7105_regs[] = {
0xFF, 0x42, 0x00, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0x01, 0x50, // 00 - 0f
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x40, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
0x16, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3b, 0x00, 0x0b, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
0x01, 0x0f // 30 - 31
};
#endif
#define ID_NORMAL 0x55201041
#define ID_PLUS 0xAA201041
void A7105_Init(void)
{
uint8_t *A7105_Regs=0;
uint8_t vco_calibration0, vco_calibration1;
#ifdef BUGS_A7105_INO
if(protocol==PROTO_BUGS)
{
if(IS_BIND_DONE)
{ // Read radio_id from EEPROM
radio_id=0;
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*4;
for(uint8_t i=0; i<4; i++)
radio_id|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<i;
}
A7105_WriteID(radio_id);
A7105_Regs=(uint8_t*)BUGS_A7105_regs;
}
else
#endif
#ifdef HUBSAN_A7105_INO
if(protocol==PROTO_HUBSAN)
{
@ -310,17 +358,19 @@ void A7105_Init(void)
A7105_WriteReg(A7105_0F_CHANNEL, 0);
A7105_WriteReg(A7105_02_CALC,2);
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
// A7105_ReadReg(A7105_25_VCO_SBCAL_I);
vco_calibration0 = A7105_ReadReg(A7105_25_VCO_SBCAL_I);
//VCO Bank Calibrate channel A0
A7105_WriteReg(A7105_0F_CHANNEL, 0xa0);
A7105_WriteReg(A7105_02_CALC, 2);
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
// A7105_ReadReg(A7105_25_VCO_SBCAL_I);
vco_calibration1 = A7105_ReadReg(A7105_25_VCO_SBCAL_I);
//Reset VCO Band calibration
if(protocol!=PROTO_HUBSAN)
A7105_WriteReg(A7105_25_VCO_SBCAL_I,protocol==PROTO_FLYSKY?0x08:0x0A);
if(protocol==PROTO_BUGS)
A7105_SetVCOBand(vco_calibration0 & 0x07, vco_calibration1 & 0x07); // Set calibration band value to best match
else
if(protocol!=PROTO_HUBSAN)
A7105_WriteReg(A7105_25_VCO_SBCAL_I,protocol==PROTO_FLYSKY?0x08:0x0A); //Reset VCO Band calibration
A7105_SetTxRxMode(TX_EN);
A7105_SetPower();

View File

@ -0,0 +1,458 @@
/*
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/>.
*/
#ifdef BUGS_A7105_INO
//////////// rxid -> radioid algorithm //////////////////////////////
// Hex digit 1 is periodic with length 2, and hex digit 2 is periodic
// with length 16. However, storing the byte of those 2 digits
// instead of manipulating bits results simpler code and smaller binary.
const uint8_t PROGMEM BUGS_most_popular_67_cycle[]= {
0x34, 0xc5, 0x6a, 0xb4, 0x29, 0xd5, 0x2c, 0xd3, 0x91, 0xb3, 0x6c, 0x49,
0x52, 0x9c, 0x4d, 0x65, 0xc3, 0x4a, 0x5b, 0xd6, 0x92, 0x6d, 0x94, 0xa6,
0x55, 0xcd, 0x2b, 0x9a, 0x36, 0x95, 0x4b, 0xd4, 0x35, 0x8d, 0x96, 0xb2,
0xa3 };
static uint8_t __attribute__((unused)) BUGS_most_popular_67(uint8_t i)
{
uint8_t ii;
if (i == 0)
return 0xd2;
else if (i == 1)
return 0xda;
else if (i % 16 < 2)
{
ii = 2 * (i / 16) + i % 16 - 2;
if (ii % 2 == 0)
ii += 7;
}
else
ii=2 * (i / 16) + (i % 16 - 2) % 7;
return pgm_read_byte_near( &BUGS_most_popular_67_cycle[ii]);
}
static uint8_t __attribute__((unused)) BUGS_most_popular_45(uint8_t i)
{
if (i == 0)
return 0xa3;
else if (i == 1)
return 0x86;
else
{
if (i % 8 == 1)
i -= 8;
else
i--;
return BUGS_most_popular_67(i);
}
}
static uint8_t __attribute__((unused)) BUGS_most_popular_23(uint8_t i)
{
if (i == 0)
return 0xb2;
else if (i == 1)
return 0xcb;
else
{
if (i % 8 == 1)
i -= 8;
else
i--;
return BUGS_most_popular_45(i);
}
}
const uint8_t PROGMEM BUGS_most_popular_01[] = {
0x52, 0xac, 0x59, 0xa4, 0x53, 0xab, 0x57, 0xa9,
0x56, 0xa5, 0x5b, 0xa7, 0x5d, 0xa6, 0x58, 0xad};
static uint32_t __attribute__((unused)) BUGS_most_popular(uint8_t i)
{
i += !(i <= 127);
uint8_t mp01=pgm_read_byte_near( &BUGS_most_popular_01[i % 16] );
return (uint32_t) mp01 << 24 |
(uint32_t) BUGS_most_popular_23(i) << 16 |
(uint32_t) BUGS_most_popular_45(i) << 8 |
BUGS_most_popular_67(i);
}
static uint32_t __attribute__((unused)) BUGS_second_most_popular(uint8_t i)
{
if (i < 127)
return BUGS_most_popular(i + 1);
else if (i > 128)
return BUGS_most_popular(i - 1);
else
return 0x52d6926d;
}
// The 22 irregular values do not match the above periodicities. They might be
// errors from the readout, but let us try them here as long as it is not
// proven.
#define BUGS_NBR_IRREGULAR 22
const uint16_t PROGMEM BUGS_irregular_keys[BUGS_NBR_IRREGULAR] = {
1131, 1287, 2842, 4668, 5311, 11594, 13122, 13813,
20655, 22975, 25007, 25068, 28252, 33309, 35364, 35765,
37731, 40296, 43668, 46540, 49868, 65535 };
const uint32_t PROGMEM BUGS_irregular_values[BUGS_NBR_IRREGULAR] = {
0x52d6926d, 0xa586da34, 0x5329d52c, 0xa66c4952,
0x536c4952, 0x524a5bd6, 0x534d65c3, 0xa9d391b3,
0x5249529c, 0xa555cd2b, 0xac9a3695, 0x58d391b3,
0xa791b36c, 0x53926d94, 0xa7926d94, 0xa72cd391,
0xa9b429d5, 0x5629d52c, 0xad2b9a36, 0xa74d65c3,
0x526d94a6, 0xad96b2a3 };
static uint32_t __attribute__((unused)) BUGS_is_irregular(uint16_t i)
{
for (uint8_t j = 0; j < BUGS_NBR_IRREGULAR; ++j)
if (pgm_read_word_near( &BUGS_irregular_keys[j]) == i)
return pgm_read_dword_near( &BUGS_irregular_values[j]);
return 0;
}
static uint32_t __attribute__((unused)) BUGS_rxid_to_radioid(uint16_t rxid)
{
uint8_t block = rxid / 256;
uint8_t second_seq_size;
bool use_most_popular;
if (rxid < 32768)
{
second_seq_size = 128 - block;
use_most_popular = rxid % 256 >= second_seq_size;
}
else
{
second_seq_size = block - 127;
use_most_popular = 255 - rxid % 256 >= second_seq_size;
}
uint32_t v = BUGS_is_irregular(rxid);
if (!v)
{
if (use_most_popular)
v = BUGS_most_popular(rxid % 255);
else
v = BUGS_second_most_popular(rxid % 255);
}
return v;
}
//////////// rxid -> radioid algorithm //////////////////////////////
// For code readability
#define BUGS_CH_SW_ARM CH5_SW
#define BUGS_CH_SW_LED CH6_SW
#define BUGS_CH_SW_FLIP CH7_SW
#define BUGS_CH_SW_PICTURE CH8_SW
#define BUGS_CH_SW_VIDEO CH9_SW
// flags packet byte 4
#define BUGS_FLAG_FLIP 0x08 // automatic flip
#define BUGS_FLAG_MODE 0x04 // low/high speed select (set is high speed)
#define BUGS_FLAG_VIDEO 0x02 // toggle video
#define BUGS_FLAG_PICTURE 0x01 // toggle picture
// flags packet byte 5
#define BUGS_FLAG_LED 0x80 // enable LEDs
#define BUGS_FLAG_ARM 0x40 // arm (toggle to turn on motors)
#define BUGS_FLAG_DISARM 0x20 // disarm (toggle to turn off motors)
#define BUGS_PACKET_SIZE 22
#define BUGS_NUM_RFCHAN 16
static uint8_t BUGS_armed, BUGS_arm_flags;
static uint8_t BUGS_arm_channel_previous;
enum {
BUGS_BIND_1,
BUGS_BIND_2,
BUGS_BIND_3,
BUGS_DATA_1,
BUGS_DATA_2,
BUGS_DATA_3,
};
static void __attribute__((unused)) BUGS_check_arming()
{
uint8_t arm_channel = BUGS_CH_SW_ARM;
if (arm_channel != BUGS_arm_channel_previous)
{
BUGS_arm_channel_previous = arm_channel;
if (arm_channel)
{
BUGS_armed = 1;
BUGS_arm_flags ^= BUGS_FLAG_ARM;
}
else
{
BUGS_armed = 0;
BUGS_arm_flags ^= BUGS_FLAG_DISARM;
}
}
}
static void __attribute__((unused)) BUGS_build_packet(uint8_t bind)
{
uint8_t force_values = bind | !BUGS_armed;
uint8_t change_channel = ((packet_count & 0x1) << 6);
uint16_t aileron = convert_channel_16b_limit(AILERON,800,0);
uint16_t elevator = convert_channel_16b_limit(ELEVATOR,800,0);
uint16_t throttle = convert_channel_16b_limit(THROTTLE,0,800);
uint16_t rudder = convert_channel_16b_limit(RUDDER,800,0);
memset(packet, 0, BUGS_PACKET_SIZE);
packet[1] = 0x76; // txid (rx uses to know hopping frequencies)
packet[2] = 0x71;
packet[3] = 0x94;
BUGS_check_arming(); // sets globals arm_flags and armed
if(bind)
{
packet[4] = change_channel | 0x80;
packet[5] = 0x06 | BUGS_arm_flags;
}
else
{
packet[4] = change_channel | BUGS_FLAG_MODE
| GET_FLAG(BUGS_CH_SW_FLIP, BUGS_FLAG_FLIP)
| GET_FLAG(BUGS_CH_SW_PICTURE, BUGS_FLAG_PICTURE)
| GET_FLAG(BUGS_CH_SW_VIDEO, BUGS_FLAG_VIDEO);
packet[5] = 0x06 | BUGS_arm_flags
| GET_FLAG(BUGS_CH_SW_LED, BUGS_FLAG_LED);
}
packet[6] = force_values ? 100 : (aileron >> 2);
packet[7] = force_values ? 100 : (elevator >> 2);
packet[8] = force_values ? 0 : (throttle >> 2);
packet[9] = force_values ? 100 : (rudder >> 2);
packet[10] = 100;
packet[11] = 100;
packet[12] = 100;
packet[13] = 100;
packet[14] = ((aileron << 6) & 0xc0)
| ((elevator << 4) & 0x30)
| ((throttle << 2) & 0x0c)
| ((rudder ) & 0x03);
// packet[15] = 0;
// driven trims
packet[16] = aileron / 8 + 14;
packet[17] = elevator / 8 + 14;
packet[18] = 64;
packet[19] = rudder / 8 + 14;
// packet[20] = 0;
// packet[21] = 0;
uint8_t check = 0x6d;
for (uint8_t i=1; i < BUGS_PACKET_SIZE; i++)
check ^= packet[i];
packet[0] = check;
}
const uint8_t PROGMEM BUGS_hop []= {
0x1d, 0x3b, 0x4d, 0x29, 0x11, 0x2d, 0x0b, 0x3d, 0x59, 0x48, 0x17, 0x41, 0x23, 0x4e, 0x2a, 0x63, // bind phase ID=0xac59a453
0x4b, 0x19, 0x35, 0x1e, 0x63, 0x0f, 0x45, 0x21, 0x51, 0x3a, 0x5d, 0x25, 0x0a, 0x44, 0x61, 0x27, // data phase ID=0xA4C56AB4 for txid 767194 if rx responds C6 BB 57 7F 00 00 00 00 00 00 FF 87 40 00 00 00
};
static void __attribute__((unused))BUGS_set_radio_data(uint8_t index)
{ // captured radio data for bugs rx/tx version A2
// it appears that the hopping frequencies are determined by the txid
// and the data phase radio id is determined by the first 2 bytes of the
// rx bind packet
if(index==0)
radio_id=0xac59a453; // bind phase ID=0xac59a453
else // 1
radio_id=0xA4C56AB4; // data phase ID=0xA4C56AB4 for txid 767194 if rx responds C6 BB 57 7F 00 00 00 00 00 00 FF 87 40 00 00 00
uint8_t offset=index*BUGS_NUM_RFCHAN;
for(uint8_t i=0; i<BUGS_NUM_RFCHAN;i++)
hopping_frequency[i]=pgm_read_byte_near( &BUGS_hop[i+offset] );
}
static void __attribute__((unused)) BUGS_increment_counts()
{ // this logic works with the use of packet_count in BUGS_build_packet
// to properly indicate channel changes to rx
packet_count += 1;
if ((packet_count & 1) == 0)
{
hopping_frequency_no += 1;
hopping_frequency_no %= BUGS_NUM_RFCHAN;
}
}
#define BUGS_DELAY_POST_TX 1100
#define BUGS_DELAY_WAIT_TX 500
#define BUGS_DELAY_WAIT_RX 2000
#define BUGS_DELAY_POST_RX 2000
#define BUGS_DELAY_BIND_RST 200
// FIFO config is one less than desired value
#define BUGS_FIFO_SIZE_RX 15
#define BUGS_FIFO_SIZE_TX 21
uint16_t ReadBUGS(void)
{
uint8_t mode, timeout, base_adr;
uint16_t rxid;
// keep frequency tuning updated
#ifndef FORCE_FLYSKY_TUNING
A7105_AdjustLOBaseFreq(1);
#endif
switch(phase)
{
case BUGS_BIND_1:
BUGS_build_packet(1);
A7105_Strobe(A7105_STANDBY);
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_TX);
A7105_WriteData(BUGS_PACKET_SIZE, hopping_frequency[hopping_frequency_no]);
phase = BUGS_BIND_2;
packet_period = BUGS_DELAY_POST_TX;
break;
case BUGS_BIND_2:
// wait here a bit for tx complete because
// need to start rx immediately to catch return packet
timeout = 20;
while (A7105_ReadReg(A7105_00_MODE) & 0x01)
if (timeout-- == 0)
{
packet_period = BUGS_DELAY_WAIT_TX; // don't proceed until transmission complete
break;
}
A7105_SetTxRxMode(RX_EN);
A7105_WriteReg(A7105_0F_PLL_I, hopping_frequency[hopping_frequency_no] - 2);
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_RX);
A7105_Strobe(A7105_RX);
BUGS_increment_counts();
phase = BUGS_BIND_3;
packet_period = BUGS_DELAY_WAIT_RX;
break;
case BUGS_BIND_3:
mode = A7105_ReadReg(A7105_00_MODE);
A7105_Strobe(A7105_STANDBY);
A7105_SetTxRxMode(TX_EN);
if (mode & 0x01)
{
phase = BUGS_BIND_1;
packet_period = BUGS_DELAY_BIND_RST; // No received data so restart binding procedure.
break;
}
A7105_ReadData(16);
if ((packet[0] + packet[1] + packet[2] + packet[3]) == 0)
{
phase = BUGS_BIND_1;
packet_period = BUGS_DELAY_BIND_RST; // No received data so restart binding procedure.
break;
}
A7105_Strobe(A7105_STANDBY);
// set radio_id
rxid = (packet[1] << 8) + packet[2];
radio_id = BUGS_rxid_to_radioid(rxid);
base_adr=BUGS_EEPROM_OFFSET+RX_num*4;
for(uint8_t i=0; i<4; i++)
eeprom_write_byte((EE_ADDR)(base_adr+i),radio_id>>i); // Save radio_id in EEPROM
BUGS_set_radio_data(1);
A7105_WriteID(radio_id);
BIND_DONE;
phase = BUGS_DATA_1;
packet_count = 0;
hopping_frequency_no = 0;
packet_period = BUGS_DELAY_POST_RX;
break;
case BUGS_DATA_1:
A7105_SetPower();
BUGS_build_packet(0);
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_TX);
A7105_WriteData(BUGS_PACKET_SIZE, hopping_frequency[hopping_frequency_no]);
phase = BUGS_DATA_2;
packet_period = BUGS_DELAY_POST_TX;
break;
case BUGS_DATA_2:
// wait here a bit for tx complete because
// need to start rx immediately to catch return packet
timeout = 20;
while (A7105_ReadReg(A7105_00_MODE) & 0x01)
if (timeout-- == 0)
{
packet_period = BUGS_DELAY_WAIT_TX; // don't proceed until transmission complete
break;
}
A7105_SetTxRxMode(RX_EN);
A7105_WriteReg(A7105_0F_PLL_I, hopping_frequency[hopping_frequency_no] - 2);
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_RX);
A7105_Strobe(A7105_RX);
BUGS_increment_counts();
phase = BUGS_DATA_3;
packet_period = BUGS_DELAY_WAIT_RX;
break;
case BUGS_DATA_3:
mode = A7105_ReadReg(A7105_00_MODE);
A7105_Strobe(A7105_STANDBY);
A7105_SetTxRxMode(TX_EN);
if (!(mode & 0x01))
{
A7105_ReadData(16);
v_lipo1=packet[10] == 0xff ? 0xff : 0x00; // Voltage in this case is only an alert on level good or bad.
RX_RSSI=packet[3];
// Read TX RSSI
int16_t temp=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // Value from A7105 is between 8 for maximum signal strength to 160 or less
if(temp<0) temp=0;
else if(temp>255) temp=255;
TX_RSSI=temp;
telemetry_link=1;
}
phase = BUGS_DATA_1;
packet_period = BUGS_DELAY_POST_RX;
break;
}
return packet_period;
}
uint16_t initBUGS(void)
{
if (IS_BIND_IN_PROGRESS)
{
BUGS_set_radio_data(0);
phase = BUGS_BIND_1;
}
else
{
BUGS_set_radio_data(1);
phase = BUGS_DATA_1;
}
A7105_Init();
hopping_frequency_no = 0;
packet_count = 0;
BUGS_armed = 0;
BUGS_arm_flags = BUGS_FLAG_DISARM; // initial value from captures
BUGS_arm_channel_previous = BUGS_CH_SW_ARM;
return 10000;
}
#endif

View File

@ -38,3 +38,4 @@
38,CFlie
39,Hitec,OPT_FW,OPT_HUB,MINIMA
40,WFLY
41,BUGS

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 32
#define VERSION_PATCH_LEVEL 33
//******************
// Protocols
@ -67,6 +67,7 @@ enum PROTOCOLS
PROTO_CFLIE = 38, // =>NRF24L01
PROTO_HITEC = 39, // =>CC2500
PROTO_WFLY = 40, // =>CYRF6936
PROTO_BUGS = 41, // =>A7105
};
enum Flysky
@ -510,9 +511,10 @@ enum {
#define EEPROM_ID_OFFSET 10 // Module ID (4 bytes)
#define EEPROM_BANK_OFFSET 15 // Current bank number (1 byte)
#define EEPROM_ID_VALID_OFFSET 20 // 1 byte flag that ID is valid
#define MODELMODE_EEPROM_OFFSET 30 // Autobind mode, 1 byte per model, end is 46
#define AFHDS2A_EEPROM_OFFSET 50 // RX ID, 4 byte per model id, end is 114
#define CONFIG_EEPROM_OFFSET 120 // Current configuration of the multimodule
#define MODELMODE_EEPROM_OFFSET 30 // Autobind mode, 1 byte per model, end is 30+16=46
#define AFHDS2A_EEPROM_OFFSET 50 // RX ID, 4 byte per model id, end is 50+64=114
#define BUGS_EEPROM_OFFSET 114 // RX ID, 4 byte per model id, end is 114+64=178
//#define CONFIG_EEPROM_OFFSET 178 // Current configuration of the multimodule
//****************************************
//*** MULTI protocol serial definition ***
@ -571,6 +573,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
CFlie 38
Hitec 39
WFLY 40
BUGS 41
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No

View File

@ -110,6 +110,7 @@ uint16_t seed;
uint16_t failsafe_count;
uint16_t state;
uint8_t len;
uint32_t radio_id;
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO)
uint8_t calData[48];
@ -614,7 +615,7 @@ uint8_t Update_All()
update_led_status();
#if defined(TELEMETRY)
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC))
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_BUGS) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_BUGS) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC))
#endif
TelemetryUpdate();
#endif
@ -915,6 +916,13 @@ static void protocol_init()
remote_callback = ReadHubsan;
break;
#endif
#if defined(BUGS_A7105_INO)
case PROTO_BUGS:
PE1_off; //antenna RF1
next_callback = initBUGS();
remote_callback = ReadBUGS;
break;
#endif
#endif
#ifdef CC2500_INSTALLED
#if defined(FRSKYD_CC2500_INO)
@ -1569,7 +1577,7 @@ void pollBoot()
#if defined(TELEMETRY)
void PPM_Telemetry_serial_init()
{
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG) || (protocol==PROTO_CABELL) )
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS))
initTXSerial( SPEED_9600 ) ;
if(protocol==PROTO_FRSKYX)
initTXSerial( SPEED_57600 ) ;

View File

@ -367,7 +367,7 @@ void frsky_link_frame()
telemetry_link |= 2 ; // Send hub if available
}
else
if (protocol==PROTO_HUBSAN||protocol==PROTO_AFHDS2A||protocol==PROTO_BAYANG||protocol==PROTO_CABELL||protocol==PROTO_HITEC)
if (protocol==PROTO_HUBSAN||protocol==PROTO_AFHDS2A||protocol==PROTO_BAYANG||protocol==PROTO_CABELL||protocol==PROTO_HITEC||protocol==PROTO_BUGS)
{
frame[1] = v_lipo1;
frame[2] = v_lipo2;
@ -997,7 +997,7 @@ void TelemetryUpdate()
#endif
if((telemetry_link & 1 )&& protocol != PROTO_FRSKYX)
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs
frsky_link_frame();
return;
}

View File

@ -138,6 +138,7 @@
#undef FLYSKY_A7105_INO
#undef HUBSAN_A7105_INO
#undef AFHDS2A_A7105_INO
#undef BUGS_A7105_INO
#endif
#ifndef CYRF6936_INSTALLED
#undef DEVO_CYRF6936_INO
@ -191,6 +192,7 @@
#undef BAYANG_HUB_TELEMETRY
#undef CABELL_HUB_TELEMETRY
#undef HUBSAN_HUB_TELEMETRY
#undef BUGS_HUB_TELEMETRY
#undef HUB_TELEMETRY
#undef SPORT_TELEMETRY
#undef SPORT_POLLING
@ -234,7 +236,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(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY)
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY)
#undef TELEMETRY
#undef INVERT_TELEMETRY
#undef SPORT_POLLING

View File

@ -112,6 +112,7 @@
//#define FORCE_FLYSKY_TUNING 0
//#define FORCE_HUBSAN_TUNING 0
//#define FORCE_AFHDS2A_TUNING 0
//#define FORCE_BUGS_TUNING 0
/** Low Power **/
//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).
@ -151,6 +152,7 @@
#define AFHDS2A_A7105_INO
#define FLYSKY_A7105_INO
#define HUBSAN_A7105_INO
#define BUGS_A7105_INO
//The protocols below need a CYRF6936 to be installed
#define DEVO_CYRF6936_INO
@ -247,6 +249,7 @@
#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to TX like er9x
#define HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define BUGS_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, ersky9x and OpenTX
@ -557,6 +560,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
MINIMA
PROTO_WFLY
NONE
PROTO_BUGS
NONE
*/
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...