Core and all protocols have been updated

Lot of changes in this new master
ChangeLog:
- Core: LED flashing when an invalid protocol has been selected
- Core: Channels 5 to 12 available as switches for all protocols: code
and size optimization
- Documentation (readme.md): fully updated, all protocols/sub
protocols/channels described, models example, many improvements
- All protocols have been updated in some way, here are some highlights:
* Bayang: added picture, video and inverted channels
* CG023->H8_3D: added light and calibration channels
* CX10: added sub protocols Q282, JC3015_1, JC3015_2, MK33041
* ESky: added new protocol - untested
* Hubsan: added compatibility with the new Hubsan Plus protocol
* KN: fully rewritten protocol: added sub protocols WLTOYS and FEILUN,
11 channels support

New version successfully tested on all my models: Flysky RX/F939/V911
protocol Flysky, Frsky RX protocol Frsky, Hubsan X4 protocol Hubsan,
Hisky HCP100/HCP80 protocol Hisky, HK-3000/HK3100 RX protocol
Hisky/HK310, XINXUN X39 protocol YD717/XINXUN, Symax X5C-1 protocol
SymaX/SYMAX, Cheerson CX-10A protocol CX10/BLUE, Eachine 3D-X4 protocol
CG023.

To access new protocols from er9x/ersky9x, you need to build a version
from this github repository https://github.com/pascallanger/mbtx based
on the latest er9x r820 and ersky9x r218.
This commit is contained in:
pascallanger
2016-01-20 10:50:56 +01:00
parent 481d4c15d6
commit bc42dbf88a
23 changed files with 1199 additions and 798 deletions

View File

@@ -12,19 +12,31 @@
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// Last sync with hexfet new_protocols/hubsan_a7105.c dated 2015-12-11
#if defined(HUBSAN_A7105_INO)
#include "iface_a7105.h"
enum{
HUBSAN_FLAG_VIDEO = 0x01, // record video
HUBSAN_FLAG_FLIP = 0x08,
HUBSAN_FLAG_LIGHT = 0x04
// flags going to packet[9] (Normal)
HUBSAN_FLAG_VIDEO= 0x01, // record video
HUBSAN_FLAG_FLIP = 0x08, // enable flips
HUBSAN_FLAG_LED = 0x04 // enable LEDs
};
uint32_t sessionid;
const uint32_t txid = 0xdb042679;
enum{
// flags going to packet[9] (Plus series)
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
};
enum{
// flags going to packet[13] (Plus series)
HUBSAN_FLAG_SNAPSHOT = 0x01,
HUBSAN_FLAG_FLIP_PLUS = 0x80,
};
uint32_t sessionid,id_data;
enum {
BIND_1,
@@ -43,7 +55,7 @@ enum {
};
#define WAIT_WRITE 0x80
void update_crc()
static void update_crc()
{
uint8_t sum = 0;
for(uint8_t i = 0; i < 15; i++)
@@ -51,23 +63,41 @@ void update_crc()
packet[15] = (256 - (sum % 256)) & 0xFF;
}
void hubsan_build_bind_packet(uint8_t state)
static void hubsan_build_bind_packet(uint8_t bind_state)
{
packet[0] = state;
static uint8_t handshake_counter;
if(phase < BIND_7)
handshake_counter = 0;
memset(packet, 0, 16);
packet[0] = bind_state;
packet[1] = channel;
packet[2] = (sessionid >> 24) & 0xFF;
packet[3] = (sessionid >> 16) & 0xFF;
packet[4] = (sessionid >> 8) & 0xFF;
packet[5] = (sessionid >> 0) & 0xFF;
packet[6] = 0x08;
packet[7] = 0xe4;
packet[8] = 0xea;
packet[9] = 0x9e;
packet[10] = 0x50;
packet[11] = (txid >> 24) & 0xFF;
packet[12] = (txid >> 16) & 0xFF;
packet[13] = (txid >> 8) & 0xFF;
packet[14] = (txid >> 0) & 0xFF;
if(id_data == ID_NORMAL)
{
packet[6] = 0x08;
packet[7] = 0xe4;
packet[8] = 0xea;
packet[9] = 0x9e;
packet[10] = 0x50;
//const uint32_t txid = 0xdb042679;
packet[11] = 0xDB;
packet[12] = 0x04;
packet[13] = 0x26;
packet[14] = 0x79;
}
else
{ //ID_PLUS
if(phase >= BIND_3)
{
packet[7] = 0x62;
packet[8] = 0x16;
}
if(phase == BIND_7)
packet[2] = handshake_counter++;
}
update_crc();
}
@@ -75,69 +105,111 @@ void hubsan_build_bind_packet(uint8_t state)
//ee : rudder observed range: 0x34 - 0xcc (smaller is right)52-204-60%
//gg : elevator observed range: 0x3e - 0xbc (smaller is up)62-188 -50%
//ii : aileron observed range: 0x45 - 0xc3 (smaller is right)69-195-50%
void hubsan_build_packet()
static void hubsan_build_packet()
{
static uint8_t vtx_freq = 0;
memset(packet, 0, 16);
if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D)
{
vtx_freq = option;
packet[0] = 0x40;
packet[1] = (option>0xF2)?0x17:0x16;
packet[2] = option+0x0D; // 5645 - 5900 MHz
packet[0] = 0x40; // vtx data packet
packet[1] = (vtx_freq>0xF2)?0x17:0x16;
packet[2] = vtx_freq+0x0D; // 5645 - 5900 MHz
packet[3] = 0x82;
packet_count++;
}
else //20 00 00 00 80 00 7d 00 84 02 64 db 04 26 79 7b
{
packet[0] = 0x20;
packet[2] = convert_channel_8b(THROTTLE);//throtle
packet[0] = 0x20; // normal data packet
packet[2] = convert_channel_8b(THROTTLE); //Throtle
}
packet[4] = 0xFF - convert_channel_8b(RUDDER);//Rudder is reversed
packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed
packet[8] = convert_channel_8b(AILERON);//aileron
if( packet_count < 100) {
packet[9] = 0x02 | HUBSAN_FLAG_LIGHT | HUBSAN_FLAG_FLIP;
packet_count++;
packet[4] = 0xFF - convert_channel_8b(RUDDER); //Rudder is reversed
packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed
packet[8] = convert_channel_8b(AILERON); //Aileron
if(id_data == ID_NORMAL)
{
if( packet_count < 100)
{
packet[9] = 0x02 | HUBSAN_FLAG_LED | HUBSAN_FLAG_FLIP; // sends default value for the 100 first packets
packet_count++;
}
else
{
packet[9] = 0x02;
// Channel 5
if(Servo_AUX1) packet[9] |= HUBSAN_FLAG_FLIP;
// Channel 6
if(Servo_AUX2) packet[9] |= HUBSAN_FLAG_LED;
// Channel 8
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; // H102D
}
packet[10] = 0x64;
//const uint32_t txid = 0xdb042679;
packet[11] = 0xDB;
packet[12] = 0x04;
packet[13] = 0x26;
packet[14] = 0x79;
}
else
{
packet[9] = 0x02;
// Channel 5
if( Servo_data[AUX1] >= PPM_SWITCH)
packet[9] |= HUBSAN_FLAG_FLIP;
// Channel 6
if( Servo_data[AUX2] >= PPM_SWITCH)
packet[9] |= HUBSAN_FLAG_LIGHT;
// Channel 8
if( Servo_data[AUX4] > PPM_SWITCH)
packet[9] |= HUBSAN_FLAG_VIDEO;
{ //ID_PLUS
packet[3] = 0x64;
packet[5] = 0x64;
packet[7] = 0x64;
packet[9] = 0x06;
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
packet[10]= 0x19;
packet[12]= 0x5C; // ghost channel ?
packet[13] = 0;
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
packet[14]= 0x49; // ghost channel ?
if(packet_count < 100)
{ // set channels to neutral for first 100 packets
packet[2] = 0x80; // throttle neutral is at mid stick on plus series
packet[4] = 0x80;
packet[6] = 0x80;
packet[8] = 0x80;
packet[9] = 0x06;
packet[13]= 0x00;
packet_count++;
}
}
packet[10] = 0x64;
packet[11] = (txid >> 24) & 0xFF;
packet[12] = (txid >> 16) & 0xFF;
packet[13] = (txid >> 8) & 0xFF;
packet[14] = (txid >> 0) & 0xFF;
update_crc();
}
uint8_t hubsan_check_integrity()
#if defined(TELEMETRY)
/*static uint8_t hubsan_check_integrity()
{
uint8_t sum = 0;
for(int i = 0; i < 15; i++)
int sum = 0;
for(uint8_t i = 0; i < 15; i++)
sum += packet[i];
return packet[15] == ((256 - (sum % 256)) & 0xFF);
}
*/
#endif
uint16_t ReadHubsan()
{
static uint8_t txState=0;
static uint8_t rfMode=0;
static uint8_t bind_count=0;
uint16_t delay;
uint8_t i;
switch(phase) {
case BIND_1:
bind_count++;
if(bind_count >= 20)
{
if(id_data == ID_NORMAL)
id_data = ID_PLUS;
else
id_data = ID_NORMAL;
A7105_WriteID(id_data);
bind_count = 0;
}
case BIND_3:
case BIND_5:
case BIND_7:
@@ -151,13 +223,22 @@ uint16_t ReadHubsan()
case BIND_5 | WAIT_WRITE:
case BIND_7 | WAIT_WRITE:
//wait for completion
for(i = 0; i< 20; i++) {
for(i = 0; i< 20; i++)
if(! (A7105_ReadReg(A7105_00_MODE) & 0x01))
break;
}
A7105_SetTxRxMode(RX_EN);
A7105_Strobe(A7105_RX);
phase &= ~WAIT_WRITE;
if(id_data == ID_PLUS)
{
if(state == BIND_7 && packet[2] == 9)
{
state = DATA_1;
A7105_WriteReg(A7105_1F_CODE_I, 0x0F);
BIND_DONE;
return 4500;
}
}
phase++;
return 4500; //7.5msec elapsed since last write
case BIND_2:
@@ -180,7 +261,7 @@ uint16_t ReadHubsan()
return 15000; //22.5msec elapsed since last write
}
A7105_ReadData();
if(packet[1] == 9) {
if(packet[1] == 9 && id_data == ID_NORMAL) {
phase = DATA_1;
A7105_WriteReg(A7105_1F_CODE_I, 0x0F);
BIND_DONE;
@@ -200,7 +281,7 @@ uint16_t ReadHubsan()
A7105_SetPower(); //Keep transmit power in sync
hubsan_build_packet();
A7105_Strobe(A7105_STANDBY);
A7105_WriteData(16, phase == DATA_5 ? channel + 0x23 : channel);
A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel);
if (phase == DATA_5)
phase = DATA_1;
else
@@ -249,13 +330,18 @@ uint16_t initHubsan() {
const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82};
A7105_Init(INIT_HUBSAN); //hubsan_init();
randomSeed((uint32_t)analogRead(A0) << 10 | analogRead(A4));
randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7));
sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)];
BIND_IN_PROGRESS; // autobind protocol
phase = BIND_1;
packet_count=0;
id_data=ID_NORMAL;
#if defined(TELEMETRY)
v_lipo=0;
telemetry_link=0;
#endif
return 10000;
}