mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-10 01:08:13 +00:00
- Change how PPM is handled with a resolution of 2048 and scaled to match serial input range. PPM is now fully scaled for all protocols which was not the case before. If you are using PPM, you might have to adjust the end points depending on the protocols. - Change all range conversions to use 2048 where possible - Updated all protocols with new range functions - Protocols which are taking advantage of 2048 are Assan, FrSky V/D/X, DSM, Devo, WK2x01 - Renamed AUX xto CHx for code readbility
245 lines
6.0 KiB
C++
245 lines
6.0 KiB
C++
/*
|
|
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/>.
|
|
*/
|
|
// Last sync with hexfet new_protocols/flysky_a7105.c dated 2015-09-28
|
|
|
|
#if defined(FLYSKY_A7105_INO)
|
|
|
|
#include "iface_a7105.h"
|
|
|
|
//FlySky constants & variables
|
|
#define FLYSKY_BIND_COUNT 2500
|
|
|
|
enum {
|
|
// flags going to byte 10
|
|
FLAG_V9X9_VIDEO = 0x40,
|
|
FLAG_V9X9_CAMERA= 0x80,
|
|
// flags going to byte 12
|
|
FLAG_V9X9_FLIP = 0x10,
|
|
FLAG_V9X9_LED = 0x20,
|
|
};
|
|
|
|
enum {
|
|
// flags going to byte 13
|
|
FLAG_V6X6_HLESS1= 0x80,
|
|
// flags going to byte 14
|
|
FLAG_V6X6_VIDEO = 0x01,
|
|
FLAG_V6X6_YCAL = 0x02,
|
|
FLAG_V6X6_XCAL = 0x04,
|
|
FLAG_V6X6_RTH = 0x08,
|
|
FLAG_V6X6_CAMERA= 0x10,
|
|
FLAG_V6X6_HLESS2= 0x20,
|
|
FLAG_V6X6_LED = 0x40,
|
|
FLAG_V6X6_FLIP = 0x80,
|
|
};
|
|
|
|
enum {
|
|
// flags going to byte 14
|
|
FLAG_V912_TOPBTN= 0x40,
|
|
FLAG_V912_BTMBTN= 0x80,
|
|
};
|
|
|
|
const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
|
|
0x49, 0x49, 0x49, 0x49, 0x49, };
|
|
|
|
static void __attribute__((unused)) flysky_apply_extension_flags()
|
|
{
|
|
switch(sub_protocol)
|
|
{
|
|
case V9X9:
|
|
if(CH5_SW)
|
|
packet[12] |= FLAG_V9X9_FLIP;
|
|
if(CH6_SW)
|
|
packet[12] |= FLAG_V9X9_LED;
|
|
if(CH7_SW)
|
|
packet[10] |= FLAG_V9X9_CAMERA;
|
|
if(CH8_SW)
|
|
packet[10] |= FLAG_V9X9_VIDEO;
|
|
break;
|
|
|
|
case V6X6:
|
|
packet[13] = 0x03; // 3 = 100% rate (0=40%, 1=60%, 2=80%)
|
|
packet[14] = 0x00;
|
|
if(CH5_SW)
|
|
packet[14] |= FLAG_V6X6_FLIP;
|
|
if(CH6_SW)
|
|
packet[14] |= FLAG_V6X6_LED;
|
|
if(CH7_SW)
|
|
packet[14] |= FLAG_V6X6_CAMERA;
|
|
if(CH8_SW)
|
|
packet[14] |= FLAG_V6X6_VIDEO;
|
|
if(CH9_SW)
|
|
{
|
|
packet[13] |= FLAG_V6X6_HLESS1;
|
|
packet[14] |= FLAG_V6X6_HLESS2;
|
|
}
|
|
if(CH10_SW)
|
|
packet[14] |= FLAG_V6X6_RTH;
|
|
if(CH11_SW)
|
|
packet[14] |= FLAG_V6X6_XCAL;
|
|
if(CH12_SW)
|
|
packet[14] |= FLAG_V6X6_YCAL;
|
|
packet[15] = 0x10; // unknown
|
|
packet[16] = 0x10; // unknown
|
|
packet[17] = 0xAA; // unknown
|
|
packet[18] = 0xAA; // unknown
|
|
packet[19] = 0x60; // unknown, changes at irregular interval in stock TX
|
|
packet[20] = 0x02; // unknown
|
|
break;
|
|
|
|
case V912:
|
|
packet_count++;
|
|
if( packet_count > 9)
|
|
packet_count = 0;
|
|
packet[12] |= 0x20; // bit 6 is always set ?
|
|
packet[13] = 0x00; // unknown
|
|
packet[14] = 0x00;
|
|
if(CH5_SW)
|
|
packet[14] = FLAG_V912_BTMBTN;
|
|
if(CH6_SW)
|
|
packet[14] |= FLAG_V912_TOPBTN;
|
|
packet[15] = 0x27; // [15] and [16] apparently hold an analog channel with a value lower than 1000
|
|
packet[16] = 0x03; // maybe it's there for a pitch channel for a CP copter ?
|
|
packet[17] = pgm_read_byte( &V912_X17_SEQ[packet_count] ) ; // not sure what [17] & [18] are for
|
|
if(packet_count == 0) // V912 Rx does not even read those bytes... [17-20]
|
|
packet[18] = 0x02;
|
|
else
|
|
packet[18] = 0x00;
|
|
packet[19] = 0x00; // unknown
|
|
packet[20] = 0x00; // unknown
|
|
break;
|
|
|
|
case CX20:
|
|
packet[19] = 0x00; // unknown
|
|
packet[20] = (hopping_frequency_no<<4)|0x0A;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|
{
|
|
uint8_t i;
|
|
//servodata timing range for flysky.
|
|
//-100% =~ 0x03e8//=1000us(min)
|
|
//+100% =~ 0x07ca//=1994us(max)
|
|
//Center = 0x5d9//=1497us(center)
|
|
//channel order AIL;ELE;THR;RUD;CH5;CH6;CH7;CH8
|
|
packet[0] = init ? 0xaa : 0x55;
|
|
packet[1] = rx_tx_addr[3];
|
|
packet[2] = rx_tx_addr[2];
|
|
packet[3] = rx_tx_addr[1];
|
|
packet[4] = rx_tx_addr[0];
|
|
for(i = 0; i < 8; i++)
|
|
{
|
|
uint16_t temp=convert_channel_ppm(CH_AETR[i]);
|
|
if(sub_protocol == CX20 && CH_AETR[i]==ELEVATOR)
|
|
temp=3000-temp;
|
|
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
|
|
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
|
}
|
|
flysky_apply_extension_flags();
|
|
}
|
|
|
|
uint16_t ReadFlySky()
|
|
{
|
|
#ifndef FORCE_FLYSKY_TUNING
|
|
A7105_AdjustLOBaseFreq(1);
|
|
#endif
|
|
if(IS_BIND_DONE)
|
|
{
|
|
flysky_build_packet(1);
|
|
A7105_WriteData(21, 1);
|
|
bind_counter--;
|
|
if (bind_counter==0)
|
|
BIND_DONE;
|
|
}
|
|
else
|
|
{
|
|
flysky_build_packet(0);
|
|
A7105_WriteData(21, hopping_frequency[hopping_frequency_no & 0x0F]);
|
|
A7105_SetPower();
|
|
}
|
|
hopping_frequency_no++;
|
|
|
|
if(sub_protocol==CX20)
|
|
return 3984;
|
|
else
|
|
return 1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490.
|
|
}
|
|
|
|
const uint8_t PROGMEM tx_channels[8][4] = {
|
|
{ 0x12, 0x34, 0x56, 0x78},
|
|
{ 0x18, 0x27, 0x36, 0x45},
|
|
{ 0x41, 0x82, 0x36, 0x57},
|
|
{ 0x84, 0x13, 0x65, 0x72},
|
|
{ 0x87, 0x64, 0x15, 0x32},
|
|
{ 0x76, 0x84, 0x13, 0x52},
|
|
{ 0x71, 0x62, 0x84, 0x35},
|
|
{ 0x71, 0x86, 0x43, 0x52}
|
|
};
|
|
|
|
uint16_t initFlySky()
|
|
{
|
|
uint8_t chanrow;
|
|
uint8_t chanoffset;
|
|
uint8_t temp;
|
|
|
|
A7105_Init();
|
|
|
|
// limit offset to 9 as higher values don't work with some RX (ie V912)
|
|
// limit offset to 9 as CX20 repeats the same channels after that
|
|
if ((rx_tx_addr[3]&0xF0) > 0x90)
|
|
rx_tx_addr[3]=rx_tx_addr[3]-0x70;
|
|
|
|
// Build frequency hop table
|
|
chanrow=rx_tx_addr[3] & 0x0F;
|
|
chanoffset=rx_tx_addr[3]/16;
|
|
for(uint8_t i=0;i<16;i++)
|
|
{
|
|
temp=pgm_read_byte_near(&tx_channels[chanrow>>1][i>>2]);
|
|
if(i&0x02)
|
|
temp&=0x0F;
|
|
else
|
|
temp>>=4;
|
|
temp*=0x0A;
|
|
if(i&0x01)
|
|
temp+=0x50;
|
|
if(sub_protocol==CX20)
|
|
{
|
|
if(temp==0x0A)
|
|
temp+=0x37;
|
|
if(temp==0xA0)
|
|
{
|
|
if (chanoffset<4)
|
|
temp=0x37;
|
|
else if (chanoffset<9)
|
|
temp=0x2D;
|
|
else
|
|
temp=0x29;
|
|
}
|
|
}
|
|
hopping_frequency[((chanrow&1)?15-i:i)]=temp-chanoffset;
|
|
}
|
|
hopping_frequency_no=0;
|
|
packet_count=0;
|
|
if(IS_BIND_IN_PROGRESS)
|
|
bind_counter = FLYSKY_BIND_COUNT;
|
|
else
|
|
bind_counter = 0;
|
|
return 2400;
|
|
}
|
|
#endif
|