mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-12 01:37:52 +00:00
commit
a06e8f945a
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.ffs_db
|
||||
*.ffs_db
|
||||
*.ffs_db
|
||||
*.hc
|
||||
*.ffs_db
|
@ -15,6 +15,7 @@
|
||||
/********************/
|
||||
/** A7105 routines **/
|
||||
/********************/
|
||||
#ifdef A7105_INSTALLED
|
||||
#include "iface_a7105.h"
|
||||
|
||||
void A7105_WriteData(uint8_t len, uint8_t channel)
|
||||
@ -22,21 +23,27 @@ void A7105_WriteData(uint8_t len, uint8_t channel)
|
||||
uint8_t i;
|
||||
A7105_CSN_off;
|
||||
SPI_Write(A7105_RST_WRPTR);
|
||||
SPI_Write(0x05);
|
||||
SPI_Write(A7105_05_FIFO_DATA);
|
||||
for (i = 0; i < len; i++)
|
||||
SPI_Write(packet[i]);
|
||||
A7105_CSN_on;
|
||||
A7105_WriteReg(0x0F, channel);
|
||||
if(protocol!=MODE_FLYSKY)
|
||||
{
|
||||
A7105_Strobe(A7105_STANDBY); //Force standby mode, ie cancel any TX or RX...
|
||||
A7105_SetTxRxMode(TX_EN); //Switch to PA
|
||||
}
|
||||
A7105_WriteReg(A7105_0F_PLL_I, channel);
|
||||
A7105_Strobe(A7105_TX);
|
||||
}
|
||||
|
||||
void A7105_ReadData() {
|
||||
void A7105_ReadData(uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
A7105_Strobe(0xF0); //A7105_RST_RDPTR
|
||||
A7105_Strobe(A7105_RST_RDPTR);
|
||||
A7105_CSN_off;
|
||||
SPI_Write(0x45);
|
||||
for (i=0;i<16;i++)
|
||||
packet[i]=SPI_SDIO_Read();
|
||||
SPI_Write(0x40 | A7105_05_FIFO_DATA); //bit 6 =1 for reading
|
||||
for (i=0;i<len;i++)
|
||||
packet[i]=SPI_SDI_Read();
|
||||
A7105_CSN_on;
|
||||
}
|
||||
|
||||
@ -48,11 +55,12 @@ void A7105_WriteReg(uint8_t address, uint8_t data) {
|
||||
A7105_CSN_on;
|
||||
}
|
||||
|
||||
uint8_t A7105_ReadReg(uint8_t address) {
|
||||
uint8_t A7105_ReadReg(uint8_t address)
|
||||
{
|
||||
uint8_t result;
|
||||
A7105_CSN_off;
|
||||
SPI_Write(address |=0x40); //bit 6 =1 for reading
|
||||
result = SPI_SDIO_Read();
|
||||
result = SPI_SDI_Read();
|
||||
A7105_CSN_on;
|
||||
return(result);
|
||||
}
|
||||
@ -60,13 +68,19 @@ uint8_t A7105_ReadReg(uint8_t address) {
|
||||
//------------------------
|
||||
void A7105_SetTxRxMode(uint8_t mode)
|
||||
{
|
||||
if(mode == TX_EN) {
|
||||
if(mode == TX_EN)
|
||||
{
|
||||
A7105_WriteReg(A7105_0B_GPIO1_PIN1, 0x33);
|
||||
A7105_WriteReg(A7105_0C_GPIO2_PIN_II, 0x31);
|
||||
} else if (mode == RX_EN) {
|
||||
}
|
||||
else
|
||||
if (mode == RX_EN)
|
||||
{
|
||||
A7105_WriteReg(A7105_0B_GPIO1_PIN1, 0x31);
|
||||
A7105_WriteReg(A7105_0C_GPIO2_PIN_II, 0x33);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//The A7105 seems to some with a cross-wired power-amp (A7700)
|
||||
//On the XL7105-D03, TX_EN -> RXSW and RX_EN -> TXSW
|
||||
//This means that sleep mode is wired as RX_EN = 1 and TX_EN = 1
|
||||
@ -81,21 +95,22 @@ uint8_t A7105_Reset()
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
A7105_WriteReg(0x00, 0x00);
|
||||
A7105_WriteReg(A7105_00_MODE, 0x00);
|
||||
delayMilliseconds(1);
|
||||
A7105_SetTxRxMode(TXRX_OFF); //Set both GPIO as output and low
|
||||
result=A7105_ReadReg(0x10) == 0x9E; //check if is reset.
|
||||
result=A7105_ReadReg(A7105_10_PLL_II) == 0x9E; //check if is reset.
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
return result;
|
||||
}
|
||||
|
||||
void A7105_WriteID(uint32_t ida) {
|
||||
void A7105_WriteID(uint32_t ida)
|
||||
{
|
||||
A7105_CSN_off;
|
||||
SPI_Write(0x06);//ex id=0x5475c52a ;txid3txid2txid1txid0
|
||||
SPI_Write((ida>>24)&0xff);//53
|
||||
SPI_Write((ida>>16)&0xff);//75
|
||||
SPI_Write((ida>>8)&0xff);//c5
|
||||
SPI_Write((ida>>0)&0xff);//2a
|
||||
SPI_Write(A7105_06_ID_DATA); //ex id=0x5475c52a ;txid3txid2txid1txid0
|
||||
SPI_Write((ida>>24)&0xff); //53
|
||||
SPI_Write((ida>>16)&0xff); //75
|
||||
SPI_Write((ida>>8)&0xff); //c5
|
||||
SPI_Write((ida>>0)&0xff); //2a
|
||||
A7105_CSN_on;
|
||||
}
|
||||
|
||||
@ -136,7 +151,7 @@ void A7105_SetPower()
|
||||
power=A7105_RANGE_POWER;
|
||||
if(prev_power != power)
|
||||
{
|
||||
A7105_WriteReg(0x28, power);
|
||||
A7105_WriteReg(A7105_28_TX_TEST, power);
|
||||
prev_power=power;
|
||||
}
|
||||
}
|
||||
@ -146,53 +161,79 @@ void A7105_Strobe(uint8_t address) {
|
||||
SPI_Write(address);
|
||||
A7105_CSN_on;
|
||||
}
|
||||
|
||||
#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
|
||||
0xFF, 0xFF
|
||||
};
|
||||
#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
|
||||
0x01, 0x0f
|
||||
};
|
||||
#endif
|
||||
#ifdef AFHDS2A_A7105_INO
|
||||
const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
|
||||
0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f
|
||||
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, 0xFF, 0xFF, 0x2a, 0x32, 0xc3, 0x1f, // 10 - 1f
|
||||
0x1e, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x3b, 0x00, 0x17, 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(uint8_t protocol)
|
||||
void A7105_Init(void)
|
||||
{
|
||||
void *A7105_Regs;
|
||||
uint8_t *A7105_Regs=0;
|
||||
|
||||
if(protocol==INIT_FLYSKY)
|
||||
#ifdef HUBSAN_A7105_INO
|
||||
if(protocol==MODE_HUBSAN)
|
||||
{
|
||||
A7105_WriteID(ID_NORMAL);
|
||||
A7105_Regs=(uint8_t*)HUBSAN_A7105_regs;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
A7105_WriteID(0x5475c52A);//0x2Ac57554
|
||||
#ifdef FLYSKY_A7105_INO
|
||||
if(protocol==MODE_FLYSKY)
|
||||
A7105_Regs=(uint8_t*)FLYSKY_A7105_regs;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef AFHDS2A_A7105_INO
|
||||
A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 0x32; i++)
|
||||
{
|
||||
A7105_WriteID(0x5475c52A);//0x2Ac57554
|
||||
A7105_Regs=(void *)FLYSKY_A7105_regs;
|
||||
}
|
||||
else
|
||||
{
|
||||
A7105_WriteID(ID_NORMAL);
|
||||
A7105_Regs=(void *)HUBSAN_A7105_regs;
|
||||
}
|
||||
for (uint8_t i = 0; i < 0x33; i++){
|
||||
if( pgm_read_byte_near((uint16_t)(A7105_Regs)+i) != 0xFF)
|
||||
A7105_WriteReg(i, pgm_read_byte_near((uint16_t)(A7105_Regs)+i));
|
||||
uint8_t val=pgm_read_byte_near(&A7105_Regs[i]);
|
||||
if( val != 0xFF)
|
||||
A7105_WriteReg(i, val);
|
||||
}
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
|
||||
//IF Filter Bank Calibration
|
||||
A7105_WriteReg(A7105_02_CALC,1);
|
||||
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
|
||||
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
|
||||
// A7105_ReadReg(A7105_22_IF_CALIB_I);
|
||||
// A7105_ReadReg(A7105_24_VCO_CURCAL);
|
||||
|
||||
if(protocol==INIT_FLYSKY)
|
||||
if(protocol!=MODE_HUBSAN)
|
||||
{
|
||||
//VCO Current Calibration
|
||||
A7105_WriteReg(A7105_24_VCO_CURCAL,0x13); //Recommended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(A7105_24_VCO_CURCAL,0x13); //Recommended calibration from A7105 Datasheet
|
||||
//VCO Bank Calibration
|
||||
A7105_WriteReg(A7105_26_VCO_SBCAL_II,0x3b); //Recommended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(A7105_26_VCO_SBCAL_II,0x3b); //Recommended calibration from A7105 Datasheet
|
||||
}
|
||||
|
||||
//VCO Bank Calibrate channel 0
|
||||
@ -208,11 +249,12 @@ void A7105_Init(uint8_t protocol)
|
||||
// A7105_ReadReg(A7105_25_VCO_SBCAL_I);
|
||||
|
||||
//Reset VCO Band calibration
|
||||
if(protocol==INIT_FLYSKY)
|
||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I,0x08);
|
||||
if(protocol!=MODE_HUBSAN)
|
||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I,protocol==MODE_FLYSKY?0x08:0x0A);
|
||||
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_SetPower();
|
||||
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
}
|
||||
#endif
|
@ -19,146 +19,107 @@
|
||||
|
||||
#define EVEN_ODD 0x00
|
||||
//#define EVEN_ODD 0x01
|
||||
static const uint8_t A7105_regs[] = {
|
||||
0x00, 0x62, -1, 0x0f, 0x00, -1 , -1 , 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xf5, 0x00, 0x15,
|
||||
|
||||
const uint8_t PROGMEM JOYSWAY_A7105_regs[] = {
|
||||
0x00, 0x62, 0xFF, 0x0f, 0x00, 0xFF , 0xFF , 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xf5, 0x00, 0x15,
|
||||
0x9e, 0x4b, 0x00, 0x03, 0x56, 0x2b, 0x12, 0x4a, 0x02, 0x80, 0x80, 0x00, 0x0e, 0x91, 0x03, 0x0f,
|
||||
0x16, 0x2a, 0x00, -1, -1, -1, 0x3a, 0x06, 0x1f, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00,
|
||||
0x16, 0x2a, 0x00, 0xFF, 0xFF, 0xFF, 0x3a, 0x06, 0x1f, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00,
|
||||
0x01, 0x0f, 0x00
|
||||
};
|
||||
|
||||
static uint8_t next_ch;
|
||||
|
||||
static int joysway_init()
|
||||
{
|
||||
int i;
|
||||
uint8_t if_calibration1;
|
||||
//uint8_t vco_calibration0;
|
||||
//uint8_t vco_calibration1;
|
||||
|
||||
phase = 0;
|
||||
next_ch = 0x30;
|
||||
|
||||
for (i = 0; i < 0x33; i++)
|
||||
if((uint8_t)A7105_regs[i] != -1)
|
||||
A7105_WriteReg(i, A7105_regs[i]);
|
||||
A7105_WriteID(0x5475c52a);
|
||||
|
||||
A7105_Strobe(A7105_PLL);
|
||||
|
||||
//IF Filter Bank Calibration
|
||||
A7105_WriteReg(0x02, 1);
|
||||
A7105_ReadReg(0x02);
|
||||
uint32_t ms = micros();
|
||||
while(micros() - ms < 500) {
|
||||
if(! A7105_ReadReg(0x02))
|
||||
break;
|
||||
}
|
||||
if (micros() - ms >= 500)
|
||||
return 0;
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
if_calibration1 = A7105_ReadReg(0x22);
|
||||
if(if_calibration1 & A7105_MASK_FBCF) {
|
||||
//Calibration failed...what do we do?
|
||||
return 0;
|
||||
}
|
||||
|
||||
//VCO Current Calibration
|
||||
A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet
|
||||
|
||||
A7105_WriteID(MProtocol_id_master);
|
||||
A7105_Strobe(A7105_PLL);
|
||||
A7105_WriteReg(0x02, 1);
|
||||
ms = micros();
|
||||
while(micros() - ms < 500) {
|
||||
if(! A7105_ReadReg(0x02))
|
||||
break;
|
||||
}
|
||||
if (micros() - ms >= 500)
|
||||
return 0;
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
if_calibration1 = A7105_ReadReg(0x22);
|
||||
if(if_calibration1 & A7105_MASK_FBCF) {
|
||||
//Calibration failed...what do we do?
|
||||
return 0;
|
||||
}
|
||||
A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet
|
||||
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_SetPower();
|
||||
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
return 1;
|
||||
static void joysway_build_packet() {
|
||||
int i;
|
||||
//-100% =~ 0x03e8
|
||||
//+100% =~ 0x07ca
|
||||
//Calculate:
|
||||
//Center = 0x5d9
|
||||
//1 % = 5
|
||||
packet[0] = phase == 0 ? 0xdd : 0xff;
|
||||
packet[1] = (MProtocol_id >> 24) & 0xff;
|
||||
packet[2] = (MProtocol_id >> 16) & 0xff;
|
||||
packet[3] = (MProtocol_id >> 8) & 0xff;
|
||||
packet[4] = (MProtocol_id >> 0) & 0xff;
|
||||
packet[5] = 0x00;
|
||||
static const int chmap[4] = {6, 7, 10, 11};
|
||||
for (i = 0; i < 4; i++) {
|
||||
// if (i >= Model.num_channels) { packet[chmap[i]] = 0x64; continue; }
|
||||
packet[chmap[i]] = map(limit_channel_100(i),servo_min_100,servo_max_100,0,204);
|
||||
}
|
||||
packet[8] = 0x64;
|
||||
packet[9] = 0x64;
|
||||
packet[12] = 0x64;
|
||||
packet[13] = 0x64;
|
||||
packet[14] = phase == 0 ? 0x30 : 0xaa;
|
||||
uint8_t value = 0;
|
||||
for (int i = 0; i < 15; i++) { value += packet[i]; }
|
||||
packet[15] = value;
|
||||
}
|
||||
|
||||
static void joysway_build_packet()
|
||||
{
|
||||
int i;
|
||||
//-100% =~ 0x03e8
|
||||
//+100% =~ 0x07ca
|
||||
//Calculate:
|
||||
//Center = 0x5d9
|
||||
//1 % = 5
|
||||
packet[0] = phase == 0 ? 0xdd : 0xff;
|
||||
packet[1] = (MProtocol_id_master >> 24) & 0xff;
|
||||
packet[2] = (MProtocol_id_master >> 16) & 0xff;
|
||||
packet[3] = (MProtocol_id_master >> 8) & 0xff;
|
||||
packet[4] = (MProtocol_id_master >> 0) & 0xff;
|
||||
packet[5] = 0x00;
|
||||
static const int chmap[4] = {6, 7, 10, 11};
|
||||
for (i = 0; i < 4; i++) {
|
||||
// if (i >= Model.num_channels) { packet[chmap[i]] = 0x64; continue; }
|
||||
uint32_t value = (uint32_t)Servo_data[i] * 0x66 / PPM_MAX + 0x66;
|
||||
if (value < 0) { value = 0; }
|
||||
if (value > 0xff) { value = 0xff; }
|
||||
packet[chmap[i]] = value;
|
||||
}
|
||||
packet[8] = 0x64;
|
||||
packet[9] = 0x64;
|
||||
packet[12] = 0x64;
|
||||
packet[13] = 0x64;
|
||||
packet[14] = phase == 0 ? 0x30 : 0xaa;
|
||||
uint8_t value = 0;
|
||||
for (int i = 0; i < 15; i++) { value += packet[i]; }
|
||||
packet[15] = value;
|
||||
}
|
||||
|
||||
static uint16_t joysway_cb()
|
||||
{
|
||||
uint8_t ch;
|
||||
if (phase == 254) {
|
||||
phase = 0;
|
||||
A7105_WriteID(0x5475c52a);
|
||||
ch = 0x0a;
|
||||
} else if (phase == 2) {
|
||||
A7105_WriteID(MProtocol_id_master);
|
||||
ch = 0x30;
|
||||
} else {
|
||||
if ((phase & 0x01) ^ EVEN_ODD) {
|
||||
ch = 0x30;
|
||||
} else {
|
||||
ch = next_ch;
|
||||
}
|
||||
}
|
||||
if (! ((phase & 0x01) ^ EVEN_ODD)) {
|
||||
next_ch++;
|
||||
if (next_ch == 0x45)
|
||||
next_ch = 0x30;
|
||||
}
|
||||
joysway_build_packet();
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteData(16, ch);
|
||||
phase++;
|
||||
return 6000;
|
||||
static uint16_t joysway_cb() {
|
||||
if (phase == 254) {
|
||||
phase = 0;
|
||||
A7105_WriteID(0x5475c52a);
|
||||
hopping_frequency_no = 0x0a;
|
||||
} else if (phase == 2) {
|
||||
A7105_WriteID(MProtocol_id);
|
||||
hopping_frequency_no = 0x30;
|
||||
} else {
|
||||
if ((phase & 0x01) ^ EVEN_ODD) {
|
||||
hopping_frequency_no = 0x30;
|
||||
} else {
|
||||
hopping_frequency_no = rf_ch_num;
|
||||
}
|
||||
}
|
||||
if (! ((phase & 0x01) ^ EVEN_ODD)) {
|
||||
rf_ch_num++;
|
||||
if (rf_ch_num == 0x45)
|
||||
rf_ch_num = 0x30;
|
||||
}
|
||||
joysway_build_packet();
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteData(16, hopping_frequency_no);
|
||||
phase++;
|
||||
return 6000;
|
||||
}
|
||||
|
||||
static uint16_t JOYSWAY_Setup() {
|
||||
while(1) {
|
||||
A7105_Reset();
|
||||
if (joysway_init())
|
||||
break;
|
||||
int i;
|
||||
u8 if_calibration1;
|
||||
//u8 vco_calibration0;
|
||||
//u8 vco_calibration1;
|
||||
|
||||
counter = 0;
|
||||
// next_ch = 0x30;
|
||||
|
||||
for (i = 0; i < 0x33; i++) {
|
||||
uint8_t val=pgm_read_byte_near(&JOYSWAY_A7105_regs[i]);
|
||||
if( val != 0xFF)
|
||||
A7105_WriteReg(i, val);
|
||||
}
|
||||
A7105_WriteID(0x5475c52a);
|
||||
|
||||
A7105_Strobe(A7105_PLL);
|
||||
|
||||
//IF Filter Bank Calibration
|
||||
A7105_WriteReg(0x02, 1);
|
||||
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
|
||||
//VCO Current Calibration
|
||||
A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet
|
||||
|
||||
A7105_WriteID(MProtocol_id);
|
||||
A7105_Strobe(A7105_PLL);
|
||||
A7105_WriteReg(0x02, 1);
|
||||
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet
|
||||
A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet
|
||||
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_SetPower();
|
||||
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
return 2400;
|
||||
}
|
||||
#endif
|
||||
|
351
Multiprotocol/AFHDS2A_a7105.ino
Normal file
351
Multiprotocol/AFHDS2A_a7105.ino
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
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
|
||||
|
||||
#ifdef AFHDS2A_A7105_INO
|
||||
|
||||
#define AFHDS2A_TXPACKET_SIZE 38
|
||||
#define AFHDS2A_RXPACKET_SIZE 37
|
||||
#define AFHDS2A_NUMFREQ 16
|
||||
|
||||
enum{
|
||||
AFHDS2A_PACKET_STICKS,
|
||||
AFHDS2A_PACKET_SETTINGS,
|
||||
AFHDS2A_PACKET_FAILSAFE,
|
||||
};
|
||||
|
||||
enum{
|
||||
AFHDS2A_BIND1,
|
||||
AFHDS2A_BIND2,
|
||||
AFHDS2A_BIND3,
|
||||
AFHDS2A_BIND4,
|
||||
AFHDS2A_DATA,
|
||||
};
|
||||
|
||||
static void AFHDS2A_calc_channels()
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint32_t rnd = MProtocol_id;
|
||||
while (idx < AFHDS2A_NUMFREQ)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t count_1_42 = 0, count_43_85 = 0, count_86_128 = 0, count_129_168 = 0;
|
||||
rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization
|
||||
|
||||
uint8_t next_ch = ((rnd >> (idx%32)) % 0xa8) + 1;
|
||||
// Keep the distance 2 between the channels - either odd or even
|
||||
if (((next_ch ^ MProtocol_id) & 0x01 )== 0)
|
||||
continue;
|
||||
// Check that it's not duplicate and spread uniformly
|
||||
for (i = 0; i < idx; i++)
|
||||
{
|
||||
if(hopping_frequency[i] == next_ch)
|
||||
break;
|
||||
if(hopping_frequency[i] <= 42)
|
||||
count_1_42++;
|
||||
else if (hopping_frequency[i] <= 85)
|
||||
count_43_85++;
|
||||
else if (hopping_frequency[i] <= 128)
|
||||
count_86_128++;
|
||||
else
|
||||
count_129_168++;
|
||||
}
|
||||
if (i != idx)
|
||||
continue;
|
||||
if ((next_ch <= 42 && count_1_42 < 5)
|
||||
||(next_ch >= 43 && next_ch <= 85 && count_43_85 < 5)
|
||||
||(next_ch >= 86 && next_ch <=128 && count_86_128 < 5)
|
||||
||(next_ch >= 129 && count_129_168 < 5))
|
||||
hopping_frequency[idx++] = next_ch;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TELEMETRY)
|
||||
// telemetry sensors ID
|
||||
enum{
|
||||
AFHDS2A_SENSOR_RX_VOLTAGE = 0x00,
|
||||
AFHDS2A_SENSOR_RX_ERR_RATE = 0xfe,
|
||||
AFHDS2A_SENSOR_RX_RSSI = 0xfc,
|
||||
AFHDS2A_SENSOR_RX_NOISE = 0xfb,
|
||||
AFHDS2A_SENSOR_RX_SNR = 0xfa,
|
||||
};
|
||||
|
||||
static void AFHDS2A_update_telemetry()
|
||||
{
|
||||
// AA | TXID | rx_id | sensor id | sensor # | value 16 bit big endian | sensor id ......
|
||||
// max 7 sensors per packet
|
||||
#if defined AFHDS2A_TELEMETRY
|
||||
if (option & 0x80) {
|
||||
// forward telemetry to TX, skip rx and tx id to save space
|
||||
pkt[0]= TX_RSSI;
|
||||
for(int i=9;i < AFHDS2A_RXPACKET_SIZE; i++)
|
||||
pkt[i-8]=packet[i];
|
||||
|
||||
telemetry_link=2;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||
{
|
||||
uint8_t index = 9+(4*sensor);
|
||||
switch(packet[index])
|
||||
{
|
||||
case AFHDS2A_SENSOR_RX_VOLTAGE:
|
||||
v_lipo = packet[index+3]<<8 | packet[index+2];
|
||||
telemetry_link=1;
|
||||
break;
|
||||
/*case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||
// packet[index+2];
|
||||
break;*/
|
||||
case AFHDS2A_SENSOR_RX_RSSI:
|
||||
RSSI_dBm = -packet[index+2];
|
||||
break;
|
||||
case 0xff:
|
||||
return;
|
||||
/*default:
|
||||
// unknown sensor ID
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void AFHDS2A_build_bind_packet()
|
||||
{
|
||||
uint8_t ch;
|
||||
memcpy( &packet[1], rx_tx_addr, 4);
|
||||
memset( &packet[5], 0xff, 4);
|
||||
packet[10]= 0x00;
|
||||
for(ch=0; ch<AFHDS2A_NUMFREQ; ch++)
|
||||
packet[11+ch] = hopping_frequency[ch];
|
||||
memset( &packet[27], 0xff, 10);
|
||||
packet[37] = 0x00;
|
||||
switch(phase)
|
||||
{
|
||||
case AFHDS2A_BIND1:
|
||||
packet[0] = 0xbb;
|
||||
packet[9] = 0x01;
|
||||
break;
|
||||
case AFHDS2A_BIND2:
|
||||
case AFHDS2A_BIND3:
|
||||
case AFHDS2A_BIND4:
|
||||
packet[0] = 0xbc;
|
||||
if(phase == AFHDS2A_BIND4)
|
||||
{
|
||||
memcpy( &packet[5], &rx_id, 4);
|
||||
memset( &packet[11], 0xff, 16);
|
||||
}
|
||||
packet[9] = phase-1;
|
||||
if(packet[9] > 0x02)
|
||||
packet[9] = 0x02;
|
||||
packet[27]= 0x01;
|
||||
packet[28]= 0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void AFHDS2A_build_packet(uint8_t type)
|
||||
{
|
||||
memcpy( &packet[1], rx_tx_addr, 4);
|
||||
memcpy( &packet[5], rx_id, 4);
|
||||
switch(type)
|
||||
{
|
||||
case AFHDS2A_PACKET_STICKS:
|
||||
packet[0] = 0x58;
|
||||
for(uint8_t ch=0; ch<14; ch++)
|
||||
{
|
||||
packet[9 + ch*2] = Servo_data[CH_AETR[ch]]&0xFF;
|
||||
packet[10 + ch*2] = (Servo_data[CH_AETR[ch]]>>8)&0xFF;
|
||||
}
|
||||
break;
|
||||
case AFHDS2A_PACKET_FAILSAFE:
|
||||
packet[0] = 0x56;
|
||||
for(uint8_t ch=0; ch<14; ch++)
|
||||
{
|
||||
/*if((Model.limits[ch].flags & CH_FAILSAFE_EN))
|
||||
{
|
||||
packet[9 + ch*2] = Servo_data[CH_AETR[ch]] & 0xff;
|
||||
packet[10+ ch*2] = (Servo_data[CH_AETR[ch]] >> 8) & 0xff;
|
||||
}
|
||||
else*/
|
||||
{
|
||||
packet[9 + ch*2] = 0xff;
|
||||
packet[10+ ch*2] = 0xff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AFHDS2A_PACKET_SETTINGS:
|
||||
packet[0] = 0xaa;
|
||||
packet[9] = 0xfd;
|
||||
packet[10]= 0xff;
|
||||
uint16_t val_hz=5*(option & 0x7f)+50; // option value should be between 0 and 70 which gives a value between 50 and 400Hz
|
||||
if(val_hz<50 || val_hz>400) val_hz=50; // default is 50Hz
|
||||
packet[11]= val_hz;
|
||||
packet[12]= val_hz >> 8;
|
||||
if(sub_protocol == PPM_IBUS || sub_protocol == PPM_SBUS)
|
||||
packet[13] = 0x01; // PPM output enabled
|
||||
else
|
||||
packet[13] = 0x00;
|
||||
packet[14]= 0x00;
|
||||
for(uint8_t i=15; i<37; i++)
|
||||
packet[i] = 0xff;
|
||||
packet[18] = 0x05; // ?
|
||||
packet[19] = 0xdc; // ?
|
||||
packet[20] = 0x05; // ?
|
||||
if(sub_protocol == PWM_SBUS || sub_protocol == PPM_SBUS)
|
||||
packet[21] = 0xdd; // SBUS output enabled
|
||||
else
|
||||
packet[21] = 0xde; // IBUS
|
||||
break;
|
||||
}
|
||||
packet[37] = 0x00;
|
||||
}
|
||||
|
||||
#define AFHDS2A_WAIT_WRITE 0x80
|
||||
uint16_t ReadAFHDS2A()
|
||||
{
|
||||
static uint8_t packet_type = AFHDS2A_PACKET_STICKS;
|
||||
static uint16_t packet_counter=0;
|
||||
uint8_t data_rx;
|
||||
uint16_t start;
|
||||
switch(phase)
|
||||
{
|
||||
case AFHDS2A_BIND1:
|
||||
case AFHDS2A_BIND2:
|
||||
case AFHDS2A_BIND3:
|
||||
AFHDS2A_build_bind_packet();
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c);
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)))
|
||||
{ // FECF+CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xbc && packet[9] == 0x01)
|
||||
{
|
||||
uint8_t temp=50+RX_num*4;
|
||||
uint8_t i;
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
rx_id[i] = packet[5+i];
|
||||
eeprom_write_byte((EE_ADDR)(temp+i),rx_id[i]);
|
||||
}
|
||||
phase = AFHDS2A_BIND4;
|
||||
packet_count++;
|
||||
return 3850;
|
||||
}
|
||||
}
|
||||
packet_count++;
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return 1700;
|
||||
case AFHDS2A_BIND1|AFHDS2A_WAIT_WRITE:
|
||||
case AFHDS2A_BIND2|AFHDS2A_WAIT_WRITE:
|
||||
case AFHDS2A_BIND3|AFHDS2A_WAIT_WRITE:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
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_Strobe(A7105_RX);
|
||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||
phase++;
|
||||
if(phase > AFHDS2A_BIND3)
|
||||
phase = AFHDS2A_BIND1;
|
||||
return 2150;
|
||||
case AFHDS2A_BIND4:
|
||||
AFHDS2A_build_bind_packet();
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c);
|
||||
packet_count++;
|
||||
bind_phase++;
|
||||
if(bind_phase>=4)
|
||||
{
|
||||
packet_counter=0;
|
||||
packet_type = AFHDS2A_PACKET_STICKS;
|
||||
hopping_frequency_no=1;
|
||||
phase = AFHDS2A_DATA;
|
||||
BIND_DONE;
|
||||
}
|
||||
return 3850;
|
||||
case AFHDS2A_DATA:
|
||||
AFHDS2A_build_packet(packet_type);
|
||||
if((A7105_ReadReg(A7105_00_MODE) & 0x01)) // Check if something has been received...
|
||||
data_rx=0;
|
||||
else
|
||||
data_rx=1; // Yes
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, hopping_frequency[hopping_frequency_no++]);
|
||||
if(hopping_frequency_no >= AFHDS2A_NUMFREQ)
|
||||
hopping_frequency_no = 0;
|
||||
if(!(packet_counter % 1313))
|
||||
packet_type = AFHDS2A_PACKET_SETTINGS;
|
||||
else if(!(packet_counter % 1569))
|
||||
packet_type = AFHDS2A_PACKET_FAILSAFE;
|
||||
else
|
||||
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)) && data_rx==1)
|
||||
{ // RX+FECF+CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xaa)
|
||||
{
|
||||
if(packet[9] == 0xfc)
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
#if defined(TELEMETRY)
|
||||
else
|
||||
{
|
||||
// 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;
|
||||
AFHDS2A_update_telemetry();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
packet_counter++;
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return 1700;
|
||||
case AFHDS2A_DATA|AFHDS2A_WAIT_WRITE:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
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_Strobe(A7105_RX);
|
||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||
return 2150;
|
||||
}
|
||||
return 3850; // never reached, please the compiler
|
||||
}
|
||||
|
||||
uint16_t initAFHDS2A()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
AFHDS2A_calc_channels();
|
||||
packet_count = 0;
|
||||
bind_phase = 0;
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
phase = AFHDS2A_BIND1;
|
||||
else
|
||||
{
|
||||
phase = AFHDS2A_DATA;
|
||||
//Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX
|
||||
uint8_t temp=50+RX_num*4;
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
rx_id[i]=eeprom_read_byte((EE_ADDR)(temp+i));
|
||||
}
|
||||
hopping_frequency_no = 0;
|
||||
return 50000;
|
||||
}
|
||||
#endif
|
@ -12,9 +12,23 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef STM32_BOARD
|
||||
/************************************/
|
||||
/************************************/
|
||||
/** Arduino replacement routines **/
|
||||
/************************************/
|
||||
// replacement map()
|
||||
int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
|
||||
{
|
||||
// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
long y ;
|
||||
x -= in_min ;
|
||||
y = out_max - out_min ;
|
||||
y *= x ;
|
||||
x = y / (in_max - in_min) ;
|
||||
return x + out_min ;
|
||||
}
|
||||
|
||||
// replacement millis() and micros()
|
||||
// These work polled, no interrupts
|
||||
// micros() MUST be called at least once every 32 milliseconds
|
||||
@ -106,7 +120,7 @@ void delayMicroseconds(unsigned int us)
|
||||
return;
|
||||
us <<= 2; // * 4
|
||||
us -= 2; // - 2
|
||||
#ifdef XMEGA
|
||||
#ifdef ORANGE_TX
|
||||
__asm__ __volatile__ (
|
||||
"1: sbiw %0,1" "\n\t" // 2 cycles
|
||||
"nop \n"
|
||||
@ -123,11 +137,12 @@ void delayMicroseconds(unsigned int us)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef XMEGA
|
||||
#ifndef ORANGE_TX
|
||||
void init()
|
||||
{
|
||||
// this needs to be called before setup() or some functions won't work there
|
||||
sei();
|
||||
}
|
||||
#endif //XMEGA
|
||||
#endif //ORANGE_TX
|
||||
|
||||
#endif //STM32_BOARD
|
||||
|
20
Multiprotocol/Build_orangetx.cmd
Normal file
20
Multiprotocol/Build_orangetx.cmd
Normal file
@ -0,0 +1,20 @@
|
||||
@echo off
|
||||
if "%AVR32_HOME%"=="" (
|
||||
echo.
|
||||
echo You must install winavr to compile Multi for OrangeTX: https://sourceforge.net/projects/winavr/
|
||||
echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
if exist MultiOrange.cpp.orangetx ren *.orangetx *.
|
||||
if exist .dep (make clean)
|
||||
md .dep
|
||||
make
|
||||
if exist MultiOrange.hex (
|
||||
objcopy -I ihex MultiOrange.hex -O binary MultiOrange.bin
|
||||
echo.
|
||||
echo Compilation OK.
|
||||
echo Use MultiOrange.hex to program your OrangeTX module.
|
||||
echo.
|
||||
)
|
||||
pause
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
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
|
||||
@ -17,6 +18,7 @@
|
||||
//CC2500 SPI routines
|
||||
//-------------------------------
|
||||
//-------------------------------
|
||||
#ifdef CC2500_INSTALLED
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
//----------------------------
|
||||
@ -152,4 +154,4 @@ void CC2500_SetPower()
|
||||
prev_power=power;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -56,18 +56,23 @@ enum YD829_FLAGS {
|
||||
};
|
||||
|
||||
enum H8_3D_FLAGS {
|
||||
// flags going to packet[17]
|
||||
H8_3D_FLAG_FLIP = 0x01,
|
||||
H8_3D_FLAG_RATE_MID = 0x02,
|
||||
H8_3D_FLAG_RATE_HIGH = 0x04,
|
||||
H8_3D_FLAG_LIGTH = 0x08, // Light on H22
|
||||
H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22
|
||||
H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20
|
||||
// flags going to packet[17]
|
||||
H8_3D_FLAG_FLIP = 0x01,
|
||||
H8_3D_FLAG_RATE_MID = 0x02,
|
||||
H8_3D_FLAG_RATE_HIGH = 0x04,
|
||||
H8_3D_FLAG_LIGTH = 0x08, // Light on H22
|
||||
H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22
|
||||
H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20
|
||||
};
|
||||
|
||||
enum H8_3D_FLAGS_2 {
|
||||
// flags going to packet[18]
|
||||
H8_3D_FLAG_CALIBRATE = 0x20, // accelerometer calibration
|
||||
// flags going to packet[18]
|
||||
H8_3D_FLAG_CAM_UP = 0x04,
|
||||
H8_3D_FLAG_CAM_DOWN = 0x08,
|
||||
H8_3D_FLAG_CALIBRATE2 = 0x10, // acc calib. (H11D, H20)
|
||||
H8_3D_FLAG_CALIBRATE = 0x20, // acc calib. (H8 3D), headless calib (H20)
|
||||
H8_3D_FLAG_SNAPSHOT = 0x40,
|
||||
H8_3D_FLAG_VIDEO = 0x80,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
@ -119,8 +124,10 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
| GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light
|
||||
| GET_FLAG(Servo_AUX3,H8_3D_FLAG_HEADLESS)
|
||||
| GET_FLAG(Servo_AUX4,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D
|
||||
if(Servo_AUX5)
|
||||
packet[18] = H8_3D_FLAG_CALIBRATE;
|
||||
packet[18] = GET_FLAG(Servo_AUX5,H8_3D_FLAG_CALIBRATE)
|
||||
| GET_FLAG(Servo_AUX5,H8_3D_FLAG_CALIBRATE2)
|
||||
| GET_FLAG(Servo_AUX6,H8_3D_FLAG_SNAPSHOT)
|
||||
| GET_FLAG(Servo_AUX7,H8_3D_FLAG_VIDEO);
|
||||
}
|
||||
uint8_t sum = packet[9];
|
||||
for (uint8_t i=10; i < H8_3D_PACKET_SIZE-1; i++)
|
||||
|
@ -25,10 +25,6 @@
|
||||
#define Q282_PACKET_SIZE 21
|
||||
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
|
||||
#define CX10A_PACKET_PERIOD 6000
|
||||
<<<<<<< HEAD
|
||||
#define CX10A_BIND_COUNT 400 // 2 seconds
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
||||
#define CX10_INITIAL_WAIT 500
|
||||
|
||||
@ -201,30 +197,15 @@ uint16_t CX10_callback()
|
||||
}
|
||||
break;
|
||||
case CX10_BIND2:
|
||||
<<<<<<< HEAD
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{ // Needed for some CX-10A to properly finish the bind
|
||||
CX10_init();
|
||||
bind_counter=CX10A_BIND_COUNT;
|
||||
}
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
||||
=======
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{ // RX fifo data ready
|
||||
XN297_ReadPayload(packet, packet_length);
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
if(packet[9] == 1)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
phase = CX10_BIND1;
|
||||
bind_counter=0;
|
||||
=======
|
||||
BIND_DONE;
|
||||
phase = CX10_DATA;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -234,11 +215,7 @@ uint16_t CX10_callback()
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
CX10_Write_Packet(1);
|
||||
<<<<<<< HEAD
|
||||
delayMicroseconds(400); // 300µs in deviation but not working so using 400µs instead
|
||||
=======
|
||||
delayMicroseconds(400);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
@ -288,10 +265,6 @@ uint16_t initCX10(void)
|
||||
packet_period = CX10A_PACKET_PERIOD;
|
||||
|
||||
phase = CX10_BIND2;
|
||||
<<<<<<< HEAD
|
||||
bind_counter=CX10A_BIND_COUNT;
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
packet[5+i] = 0xff; // clear aircraft id
|
||||
|
@ -12,9 +12,9 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
|
||||
void CYRF_WriteRegister(uint8_t address, uint8_t data)
|
||||
{
|
||||
CYRF_CSN_off;
|
||||
@ -182,28 +182,16 @@ void CYRF_WritePreamble(uint32_t preamble)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void CYRF_StartReceive()
|
||||
{
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL,0x87);
|
||||
}
|
||||
|
||||
/*static void CYRF_ReadDataPacket(uint8_t dpbuffer[])
|
||||
{
|
||||
CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, 0x10);
|
||||
}
|
||||
*/
|
||||
<<<<<<< HEAD
|
||||
static void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length)
|
||||
=======
|
||||
void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
static void CYRF_WriteDataPacketLen(const uint8_t dpbuffer[], uint8_t len)
|
||||
{
|
||||
CYRF_WriteRegister(CYRF_01_TX_LENGTH, len);
|
||||
@ -250,10 +238,14 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
|
||||
for(i = 0; i < NUM_FREQ; i++)
|
||||
{
|
||||
CYRF_ConfigRFChannel(i);
|
||||
CYRF_ReadRegister(CYRF_13_RSSI);
|
||||
CYRF_StartReceive();
|
||||
delayMicroseconds(10);
|
||||
rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI);
|
||||
delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle
|
||||
if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) {
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive
|
||||
delayMicroseconds(15);
|
||||
CYRF_ReadRegister(CYRF_13_RSSI); //dummy read
|
||||
delayMicroseconds(15); //The conversion can occur as often as once every 12us
|
||||
}
|
||||
rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
@ -269,7 +261,9 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
|
||||
rssi[j] = 0xff;
|
||||
}
|
||||
}
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Clear abort RX
|
||||
}
|
||||
|
||||
#if defined(DEVO_CYRF6936_INO) || defined(J6PRO_CYRF6936_INO)
|
||||
@ -304,4 +298,5 @@ static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *da
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
code[i]=pgm_read_byte_near(&data[i]);
|
||||
CYRF_ConfigSOPCode(code);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,277 +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.
|
||||
|
||||
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(J6PRO_CYRF6936_INO)
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define NUM_WAIT_LOOPS (100 / 5) //each loop is ~5us. Do not wait more than 100us
|
||||
|
||||
//For Debug
|
||||
//#define NO_SCRAMBLE
|
||||
|
||||
enum J6ProState {
|
||||
J6PRO_BIND,
|
||||
J6PRO_BIND_01,
|
||||
J6PRO_BIND_03_START,
|
||||
J6PRO_BIND_03_CHECK,
|
||||
J6PRO_BIND_05_1,
|
||||
J6PRO_BIND_05_2,
|
||||
J6PRO_BIND_05_3,
|
||||
J6PRO_BIND_05_4,
|
||||
J6PRO_BIND_05_5,
|
||||
J6PRO_BIND_05_6,
|
||||
J6PRO_CHANSEL,
|
||||
J6PRO_CHAN_1,
|
||||
J6PRO_CHAN_2,
|
||||
J6PRO_CHAN_3,
|
||||
J6PRO_CHAN_4,
|
||||
};
|
||||
|
||||
static const uint8_t J6Pro_sopcodes[][8] = {
|
||||
/* Note these are in order transmitted (LSB 1st) */
|
||||
{0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91},
|
||||
{0x9B, 0xC5, 0xA1, 0x0F, 0xAD, 0x39, 0xA2, 0x0F},
|
||||
{0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A},
|
||||
{0x66, 0xCD, 0x7C, 0x50, 0xDD, 0x26, 0x7C, 0x50},
|
||||
{0x5C, 0xE1, 0xF6, 0x44, 0xAD, 0x16, 0xF6, 0x44},
|
||||
{0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46},
|
||||
{0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C},
|
||||
{0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74},
|
||||
{0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49},
|
||||
{0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72},
|
||||
{0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17},
|
||||
{0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table
|
||||
{0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above,
|
||||
{0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A}, //but with the upper and lower word swapped
|
||||
{0xDD, 0x26, 0x7C, 0x50, 0x66, 0xCD, 0x7C, 0x50},
|
||||
{0xAD, 0x16, 0xF6, 0x44, 0x5C, 0xE1, 0xF6, 0x44},
|
||||
{0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46},
|
||||
{0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C},
|
||||
{0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74},
|
||||
};
|
||||
const uint8_t bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
||||
const uint8_t data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f};
|
||||
|
||||
static uint8_t stateJ6P;
|
||||
static uint8_t radio_ch[4];
|
||||
static uint8_t num_channels;
|
||||
|
||||
void J6Pro_build_bind_packet()
|
||||
{
|
||||
packet[0] = 0x01; //Packet type
|
||||
packet[1] = 0x01; //FIXME: What is this? Model number maybe?
|
||||
packet[2] = 0x56; //FIXME: What is this?
|
||||
packet[3] = cyrfmfg_id[0];
|
||||
packet[4] = cyrfmfg_id[1];
|
||||
packet[5] = cyrfmfg_id[2];
|
||||
packet[6] = cyrfmfg_id[3];
|
||||
packet[7] = cyrfmfg_id[4];
|
||||
packet[8] = cyrfmfg_id[5];
|
||||
}
|
||||
void J6Pro_build_data_packet()
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t upperbits = 0;
|
||||
packet[0] = 0xaa; //FIXME what is this?
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (i >= num_channels) {
|
||||
packet[i+1] = 0xff;
|
||||
continue;
|
||||
}
|
||||
uint32_t value = (uint32_t)Servo_data[i] * 0x200 / PPM_MAX + 0x200;
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > 0x3ff)
|
||||
value = 0x3ff;
|
||||
packet[i+1] = value & 0xff;
|
||||
upperbits |= (value >> 8) << (i * 2);
|
||||
}
|
||||
packet[13] = upperbits & 0xff;
|
||||
packet[14] = (upperbits >> 8) & 0xff;
|
||||
packet[15] = (upperbits >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static void J6Pro_cyrf_init()
|
||||
{
|
||||
/* Initialise CYRF chip */
|
||||
CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
|
||||
CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3c);
|
||||
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
CYRF_WriteRegister(CYRF_03_TX_CFG, 0x05 | CYRF_BIND_POWER);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x8a);
|
||||
CYRF_WriteRegister(CYRF_03_TX_CFG, 0x28 | CYRF_BIND_POWER);
|
||||
CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0e);
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00);
|
||||
CYRF_ConfigDataCode(data_code, 16);
|
||||
CYRF_WritePreamble(0x023333);
|
||||
}
|
||||
static void J6Pro_cyrf_bindinit()
|
||||
{
|
||||
/* Use when binding */
|
||||
//0.060470# 03 2f
|
||||
CYRF_WriteRegister(CYRF_03_TX_CFG, 0x28 | 0x07); //Use max power for binding in case there is no telem module
|
||||
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
CYRF_ConfigSOPCode(bind_sop_code);
|
||||
CYRF_ConfigCRCSeed(0x0000);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
||||
//0.061511# 13 20
|
||||
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
//0.062684# 0f 05
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
//0.062792# 0f 05
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
J6Pro_build_bind_packet(); //01 01 e9 49 ec a9 c4 c1 ff
|
||||
//CYRF_WriteDataPacketLen(packet, 0x09);
|
||||
}
|
||||
static void J6Pro_cyrf_datainit()
|
||||
{
|
||||
/* Use when already bound */
|
||||
//0.094007# 0f 05
|
||||
uint8_t sop_idx = (0xff & (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[5])) % 19;
|
||||
uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
||||
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
CYRF_ConfigSOPCode(J6Pro_sopcodes[sop_idx]);
|
||||
CYRF_ConfigCRCSeed(crc);
|
||||
}
|
||||
|
||||
static void J6Pro_set_radio_channels()
|
||||
{
|
||||
//FIXME: Query free channels
|
||||
//lowest channel is 0x08, upper channel is 0x4d?
|
||||
CYRF_FindBestChannels(radio_ch, 3, 5, 8, 77);
|
||||
radio_ch[3] = radio_ch[0];
|
||||
}
|
||||
|
||||
static uint16_t j6pro_cb()
|
||||
{
|
||||
switch(stateJ6P) {
|
||||
case J6PRO_BIND:
|
||||
J6Pro_cyrf_bindinit();
|
||||
stateJ6P = J6PRO_BIND_01;
|
||||
//no break because we want to send the 1st bind packet now
|
||||
case J6PRO_BIND_01:
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
//0.062684# 0f 05
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
//0.062684# 0f 05
|
||||
CYRF_WriteDataPacketLen(packet, 0x09);
|
||||
stateJ6P = J6PRO_BIND_03_START;
|
||||
return 3000; //3msec
|
||||
case J6PRO_BIND_03_START:
|
||||
{
|
||||
int i = 0;
|
||||
while (! (CYRF_ReadRegister(0x04) & 0x06))
|
||||
if(++i > NUM_WAIT_LOOPS)
|
||||
break;
|
||||
}
|
||||
CYRF_ConfigRFChannel(0x53);
|
||||
CYRF_SetTxRxMode(RX_EN);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
||||
stateJ6P = J6PRO_BIND_03_CHECK;
|
||||
return 30000; //30msec
|
||||
case J6PRO_BIND_03_CHECK:
|
||||
{
|
||||
uint8_t rx = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||
if((rx & 0x1a) == 0x1a) {
|
||||
rx = CYRF_ReadRegister(CYRF_0A_RX_LENGTH);
|
||||
if(rx == 0x0f) {
|
||||
rx = CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||
if(rx == 0x0f) {
|
||||
//Expected and actual length are both 15
|
||||
CYRF_ReadDataPacketLen(packet, rx);
|
||||
if (packet[0] == 0x03 &&
|
||||
packet[3] == cyrfmfg_id[0] &&
|
||||
packet[4] == cyrfmfg_id[1] &&
|
||||
packet[5] == cyrfmfg_id[2] &&
|
||||
packet[6] == cyrfmfg_id[3] &&
|
||||
packet[7] == cyrfmfg_id[4] &&
|
||||
packet[8] == cyrfmfg_id[5])
|
||||
{
|
||||
//Send back Ack
|
||||
packet[0] = 0x05;
|
||||
CYRF_ConfigRFChannel(0x54);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
stateJ6P = J6PRO_BIND_05_1;
|
||||
return 2000; //2msec
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stateJ6P = J6PRO_BIND_01;
|
||||
return 500;
|
||||
}
|
||||
case J6PRO_BIND_05_1:
|
||||
case J6PRO_BIND_05_2:
|
||||
case J6PRO_BIND_05_3:
|
||||
case J6PRO_BIND_05_4:
|
||||
case J6PRO_BIND_05_5:
|
||||
case J6PRO_BIND_05_6:
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
CYRF_WriteDataPacketLen(packet, 0x0f);
|
||||
stateJ6P = stateJ6P + 1;
|
||||
return 4600; //4.6msec
|
||||
case J6PRO_CHANSEL:
|
||||
BIND_DONE;
|
||||
J6Pro_set_radio_channels();
|
||||
J6Pro_cyrf_datainit();
|
||||
stateJ6P = J6PRO_CHAN_1;
|
||||
case J6PRO_CHAN_1:
|
||||
//Keep transmit power updated
|
||||
CYRF_SetPower(CYRF_HIGH_POWER);
|
||||
J6Pro_build_data_packet();
|
||||
//return 3400;
|
||||
case J6PRO_CHAN_2:
|
||||
//return 3500;
|
||||
case J6PRO_CHAN_3:
|
||||
//return 3750
|
||||
case J6PRO_CHAN_4:
|
||||
CYRF_ConfigRFChannel(radio_ch[stateJ6P - J6PRO_CHAN_1]);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
CYRF_WriteDataPacket(packet);
|
||||
if (stateJ6P == J6PRO_CHAN_4) {
|
||||
stateJ6P = J6PRO_CHAN_1;
|
||||
return 13900;
|
||||
}
|
||||
stateJ6P = stateJ6P + 1;
|
||||
return 3550;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t j6pro_setup()
|
||||
{
|
||||
CYRF_Reset();
|
||||
J6Pro_cyrf_init();
|
||||
num_channels = 8;
|
||||
if (IS_AUTOBIND_FLAG_on) {
|
||||
stateJ6P = J6PRO_BIND;
|
||||
BIND_IN_PROGRESS;
|
||||
} else {
|
||||
stateJ6P = J6PRO_CHANSEL;
|
||||
}
|
||||
return 2400;
|
||||
}
|
||||
#endif
|
@ -37,53 +37,53 @@ enum {
|
||||
static void skyartec_init() {
|
||||
CC2500_Reset();
|
||||
|
||||
cc2500_writeReg(CC2500_16_MCSM2, 0x07);
|
||||
cc2500_writeReg(CC2500_17_MCSM1, 0x30);
|
||||
cc2500_writeReg(CC2500_1E_WOREVT1, 0x87);
|
||||
cc2500_writeReg(CC2500_1F_WOREVT0, 0x6b);
|
||||
cc2500_writeReg(CC2500_20_WORCTRL, 0xf8);
|
||||
cc2500_writeReg(CC2500_2A_PTEST, 0x7f);
|
||||
cc2500_writeReg(CC2500_2B_AGCTEST, 0x3f);
|
||||
cc2500_writeReg(CC2500_0B_FSCTRL1, 0x09);
|
||||
cc2500_writeReg(CC2500_0C_FSCTRL0, 0x00);
|
||||
cc2500_writeReg(CC2500_0D_FREQ2, 0x5d);
|
||||
cc2500_writeReg(CC2500_0E_FREQ1, 0x93);
|
||||
cc2500_writeReg(CC2500_0F_FREQ0, 0xb1);
|
||||
cc2500_writeReg(CC2500_10_MDMCFG4, 0x2d);
|
||||
cc2500_writeReg(CC2500_11_MDMCFG3, 0x20);
|
||||
cc2500_writeReg(CC2500_12_MDMCFG2, 0x73);
|
||||
cc2500_writeReg(CC2500_13_MDMCFG1, 0x22);
|
||||
cc2500_writeReg(CC2500_14_MDMCFG0, 0xf8);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, 0xcd);
|
||||
cc2500_writeReg(CC2500_15_DEVIATN, 0x50);
|
||||
cc2500_writeReg(CC2500_21_FREND1, 0xb6);
|
||||
cc2500_writeReg(CC2500_22_FREND0, 0x10);
|
||||
cc2500_writeReg(CC2500_18_MCSM0, 0x18);
|
||||
cc2500_writeReg(CC2500_19_FOCCFG, 0x1d);
|
||||
cc2500_writeReg(CC2500_1A_BSCFG, 0x1c);
|
||||
cc2500_writeReg(CC2500_1B_AGCCTRL2, 0xc7);
|
||||
cc2500_writeReg(CC2500_1C_AGCCTRL1, 0x00);
|
||||
cc2500_writeReg(CC2500_1D_AGCCTRL0, 0xb2);
|
||||
cc2500_writeReg(CC2500_23_FSCAL3, 0xea);
|
||||
cc2500_writeReg(CC2500_24_FSCAL2, 0x0a);
|
||||
cc2500_writeReg(CC2500_25_FSCAL1, 0x00);
|
||||
cc2500_writeReg(CC2500_26_FSCAL0, 0x11);
|
||||
cc2500_writeReg(CC2500_29_FSTEST, 0x59);
|
||||
cc2500_writeReg(CC2500_2C_TEST2, 0x88);
|
||||
cc2500_writeReg(CC2500_2D_TEST1, 0x31);
|
||||
cc2500_writeReg(CC2500_2E_TEST0, 0x0b);
|
||||
cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05);
|
||||
cc2500_writeReg(CC2500_09_ADDR, 0x43);
|
||||
cc2500_writeReg(CC2500_06_PKTLEN, 0xff);
|
||||
cc2500_writeReg(CC2500_04_SYNC1, 0x13);
|
||||
cc2500_writeReg(CC2500_05_SYNC0, 0x18);
|
||||
CC2500_WriteReg(CC2500_16_MCSM2, 0x07);
|
||||
CC2500_WriteReg(CC2500_17_MCSM1, 0x30);
|
||||
CC2500_WriteReg(CC2500_1E_WOREVT1, 0x87);
|
||||
CC2500_WriteReg(CC2500_1F_WOREVT0, 0x6b);
|
||||
CC2500_WriteReg(CC2500_20_WORCTRL, 0xf8);
|
||||
CC2500_WriteReg(CC2500_2A_PTEST, 0x7f);
|
||||
CC2500_WriteReg(CC2500_2B_AGCTEST, 0x3f);
|
||||
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x09);
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00);
|
||||
CC2500_WriteReg(CC2500_0D_FREQ2, 0x5d);
|
||||
CC2500_WriteReg(CC2500_0E_FREQ1, 0x93);
|
||||
CC2500_WriteReg(CC2500_0F_FREQ0, 0xb1);
|
||||
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x2d);
|
||||
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x20);
|
||||
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x73);
|
||||
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x22);
|
||||
CC2500_WriteReg(CC2500_14_MDMCFG0, 0xf8);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, 0xcd);
|
||||
CC2500_WriteReg(CC2500_15_DEVIATN, 0x50);
|
||||
CC2500_WriteReg(CC2500_21_FREND1, 0xb6);
|
||||
CC2500_WriteReg(CC2500_22_FREND0, 0x10);
|
||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x18);
|
||||
CC2500_WriteReg(CC2500_19_FOCCFG, 0x1d);
|
||||
CC2500_WriteReg(CC2500_1A_BSCFG, 0x1c);
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xc7);
|
||||
CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00);
|
||||
CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xb2);
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0xea);
|
||||
CC2500_WriteReg(CC2500_24_FSCAL2, 0x0a);
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00);
|
||||
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11);
|
||||
CC2500_WriteReg(CC2500_29_FSTEST, 0x59);
|
||||
CC2500_WriteReg(CC2500_2C_TEST2, 0x88);
|
||||
CC2500_WriteReg(CC2500_2D_TEST1, 0x31);
|
||||
CC2500_WriteReg(CC2500_2E_TEST0, 0x0b);
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, 0x43);
|
||||
CC2500_WriteReg(CC2500_06_PKTLEN, 0xff);
|
||||
CC2500_WriteReg(CC2500_04_SYNC1, 0x13);
|
||||
CC2500_WriteReg(CC2500_05_SYNC0, 0x18);
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
cc2500_strobe(CC2500_SFTX);
|
||||
cc2500_strobe(CC2500_SFRX);
|
||||
cc2500_strobe(CC2500_SXOFF);
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
CC2500_Strobe(CC2500_SXOFF);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
}
|
||||
|
||||
static void add_pkt_suffix() {
|
||||
@ -104,7 +104,7 @@ static void send_data_packet() {
|
||||
packet[1] = TX_ADDR; //Tx Addr?
|
||||
packet[2] = 0x01; //???
|
||||
for(int i = 0; i < 7; i++) {
|
||||
uint32_t value = (uint32_t)Servo_data[i] * 0x280 / PPM_MAX + 0x280;
|
||||
uint32_t value = map(limit_channel_100(i),servo_min_100,servo_max_100,0,1280);
|
||||
if(value < 0) { value = 0; }
|
||||
if(value > 0x500) { value = 0x500; }
|
||||
packet[3+2*i] = value >> 8;
|
||||
@ -112,11 +112,11 @@ static void send_data_packet() {
|
||||
}
|
||||
add_pkt_suffix();
|
||||
//for(int i = 0; i < 20; i++) printf("%02x ", packet[i]); printf("\n");
|
||||
cc2500_writeReg(CC2500_04_SYNC1, ((binding_idx >> 0) & 0xff));
|
||||
cc2500_writeReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff));
|
||||
cc2500_writeReg(CC2500_09_ADDR, TX_ADDR);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, TX_CHANNEL);
|
||||
cc2500_writeFifo(packet, 20);
|
||||
CC2500_WriteReg(CC2500_04_SYNC1, ((binding_idx >> 0) & 0xff));
|
||||
CC2500_WriteReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff));
|
||||
CC2500_WriteReg(CC2500_09_ADDR, TX_ADDR);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, TX_CHANNEL);
|
||||
CC2500_WriteData(packet, 20);
|
||||
}
|
||||
|
||||
static void send_bind_packet() {
|
||||
@ -135,16 +135,16 @@ static void send_bind_packet() {
|
||||
uint8_t xore = 0;
|
||||
for(int i = 3; i < 11; i++) { xore ^= packet[i]; }
|
||||
packet[11] = xore;
|
||||
cc2500_writeReg(CC2500_04_SYNC1, 0x7d);
|
||||
cc2500_writeReg(CC2500_05_SYNC0, 0x7d);
|
||||
cc2500_writeReg(CC2500_09_ADDR, 0x7d);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, 0x7d);
|
||||
cc2500_writeFifo(packet, 12);
|
||||
CC2500_WriteReg(CC2500_04_SYNC1, 0x7d);
|
||||
CC2500_WriteReg(CC2500_05_SYNC0, 0x7d);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, 0x7d);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, 0x7d);
|
||||
CC2500_WriteData(packet, 12);
|
||||
}
|
||||
|
||||
static uint16_t skyartec_cb() {
|
||||
if (state & 0x01) {
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
if (state == SKYARTEC_LAST) { CC2500_SetPower(); state = SKYARTEC_PKT1; }
|
||||
else { state++; }
|
||||
return 3000;
|
||||
|
@ -15,17 +15,6 @@
|
||||
/************************/
|
||||
/** Convert routines **/
|
||||
/************************/
|
||||
int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
|
||||
{
|
||||
// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
long y ;
|
||||
x -= in_min ;
|
||||
y = out_max - out_min ;
|
||||
y *= x ;
|
||||
x = y / (in_max - in_min) ;
|
||||
return x + out_min ;
|
||||
}
|
||||
|
||||
// Channel value is converted to 8bit values full scale
|
||||
uint8_t convert_channel_8b(uint8_t num)
|
||||
{
|
||||
|
@ -1,538 +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/>.
|
||||
*/
|
||||
|
||||
#if defined(DSM2_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define RANDOM_CHANNELS 0 // disabled
|
||||
//#define RANDOM_CHANNELS 1 // enabled
|
||||
#define BIND_CHANNEL 0x0d //13 This can be any odd channel
|
||||
#define NUM_WAIT_LOOPS (100 / 5) //each loop is ~5us. Do not wait more than 100us
|
||||
|
||||
//During binding we will send BIND_COUNT/2 packets
|
||||
//One packet each 10msec
|
||||
#define BIND_COUNT1 600
|
||||
|
||||
enum {
|
||||
DSM2_BIND = 0,
|
||||
DSM2_CHANSEL = BIND_COUNT1 + 0,
|
||||
DSM2_CH1_WRITE_A = BIND_COUNT1 + 1,
|
||||
DSM2_CH1_CHECK_A = BIND_COUNT1 + 2,
|
||||
DSM2_CH2_WRITE_A = BIND_COUNT1 + 3,
|
||||
DSM2_CH2_CHECK_A = BIND_COUNT1 + 4,
|
||||
DSM2_CH2_READ_A = BIND_COUNT1 + 5,
|
||||
DSM2_CH1_WRITE_B = BIND_COUNT1 + 6,
|
||||
DSM2_CH1_CHECK_B = BIND_COUNT1 + 7,
|
||||
DSM2_CH2_WRITE_B = BIND_COUNT1 + 8,
|
||||
DSM2_CH2_CHECK_B = BIND_COUNT1 + 9,
|
||||
DSM2_CH2_READ_B = BIND_COUNT1 + 10,
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM pncodes[5][9][8] = {
|
||||
/* Note these are in order transmitted (LSB 1st) */
|
||||
{ /* Row 0 */
|
||||
/* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
|
||||
/* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
|
||||
/* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
|
||||
/* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
|
||||
/* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
|
||||
/* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
|
||||
/* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
|
||||
/* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
|
||||
/* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
|
||||
},
|
||||
{ /* Row 1 */
|
||||
/* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
|
||||
/* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
|
||||
/* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
|
||||
/* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
|
||||
/* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
|
||||
/* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
|
||||
/* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
|
||||
/* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
|
||||
/* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
|
||||
},
|
||||
{ /* Row 2 */
|
||||
/* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
|
||||
/* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
|
||||
/* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
|
||||
/* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
|
||||
/* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
|
||||
/* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
|
||||
/* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
|
||||
/* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
|
||||
/* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
|
||||
},
|
||||
{ /* Row 3 */
|
||||
/* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
|
||||
/* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
|
||||
/* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
|
||||
/* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
|
||||
/* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
|
||||
/* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
|
||||
/* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
|
||||
/* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
|
||||
/* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
|
||||
},
|
||||
{ /* Row 4 */
|
||||
/* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
|
||||
/* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
|
||||
/* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
|
||||
/* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
|
||||
/* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
|
||||
/* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
|
||||
/* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
|
||||
/* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
|
||||
/* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
|
||||
},
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len)
|
||||
{
|
||||
for(uint8_t i=0;i<len;i++)
|
||||
buf[i]=pgm_read_byte_near( &pncodes[row][col][i] );
|
||||
}
|
||||
|
||||
//
|
||||
uint8_t chidx;
|
||||
uint8_t sop_col;
|
||||
uint8_t data_col;
|
||||
uint16_t cyrf_state;
|
||||
uint8_t crcidx;
|
||||
uint8_t binding;
|
||||
|
||||
static void __attribute__((unused)) build_bind_packet()
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t sum = 384 - 0x10;//
|
||||
packet[0] = crc >> 8;
|
||||
packet[1] = crc & 0xff;
|
||||
packet[2] = 0xff ^ cyrfmfg_id[2];
|
||||
packet[3] = (0xff ^ cyrfmfg_id[3]) + RX_num;
|
||||
packet[4] = packet[0];
|
||||
packet[5] = packet[1];
|
||||
packet[6] = packet[2];
|
||||
packet[7] = packet[3];
|
||||
for(i = 0; i < 8; i++)
|
||||
sum += packet[i];
|
||||
packet[8] = sum >> 8;
|
||||
packet[9] = sum & 0xff;
|
||||
packet[10] = 0x01; //???
|
||||
packet[11] = option>3?option:option+4;
|
||||
if(sub_protocol==DSMX) //DSMX type
|
||||
packet[12] = 0xb2; // Telemetry off: packet[12] = num_channels < 8 && Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_OFF ? 0xa2 : 0xb2;
|
||||
else
|
||||
packet[12] = option<8?0x01:0x02;
|
||||
packet[13] = 0x00; //???
|
||||
for(i = 8; i < 14; i++)
|
||||
sum += packet[i];
|
||||
packet[14] = sum >> 8;
|
||||
packet[15] = sum & 0xff;
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) PROTOCOL_SticksMoved(uint8_t init)
|
||||
{
|
||||
#define STICK_MOVEMENT 15*(PPM_MAX-PPM_MIN)/100 // defines when the bind dialog should be interrupted (stick movement STICK_MOVEMENT %)
|
||||
static uint16_t ele_start, ail_start;
|
||||
uint16_t ele = Servo_data[ELEVATOR];//CHAN_ReadInput(MIXER_MapChannel(INP_ELEVATOR));
|
||||
uint16_t ail = Servo_data[AILERON];//CHAN_ReadInput(MIXER_MapChannel(INP_AILERON));
|
||||
if(init) {
|
||||
ele_start = ele;
|
||||
ail_start = ail;
|
||||
return 0;
|
||||
}
|
||||
uint16_t ele_diff = ele_start - ele;//abs(ele_start - ele);
|
||||
uint16_t ail_diff = ail_start - ail;//abs(ail_start - ail);
|
||||
return ((ele_diff + ail_diff) > STICK_MOVEMENT);//
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) build_data_packet(uint8_t upper)//
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t bits;
|
||||
|
||||
uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //9 Channels - DM9 TX
|
||||
switch(option>3?option:option+4) // Create channel map based on number of channels
|
||||
{
|
||||
case 12:
|
||||
ch_map[11]=11; // 12 channels
|
||||
case 11:
|
||||
ch_map[10]=10; // 11 channels
|
||||
case 10:
|
||||
ch_map[9]=9; // 10 channels
|
||||
break;
|
||||
case 8:
|
||||
memcpy(ch_map,"\x01\x05\x02\x03\x06\xFF\xFF\x04\x00\x07",10); // 8 channels - DX8 TX
|
||||
break;
|
||||
case 7:
|
||||
memcpy(ch_map,"\x01\x05\x02\x04\x03\x06\x00",7); // 7 channels - DX6i TX
|
||||
break;
|
||||
case 6:
|
||||
memcpy(ch_map,"\x01\x05\x02\x03\x00\x04\xFF",7); // 6 channels - HP6DSM TX
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
memcpy(ch_map,"\x00\x01\x02\x03\xFF\xFF\xFF",7); // 4 channels - Guess
|
||||
if(option&0x01)
|
||||
ch_map[4]=4; // 5 channels - Guess
|
||||
break;
|
||||
}
|
||||
//
|
||||
if( binding && PROTOCOL_SticksMoved(0) )
|
||||
binding = 0;
|
||||
if (sub_protocol==DSMX)
|
||||
{
|
||||
packet[0] = cyrfmfg_id[2];
|
||||
packet[1] = cyrfmfg_id[3] + RX_num;
|
||||
bits=11;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = (0xff ^ cyrfmfg_id[2]);
|
||||
packet[1] = (0xff ^ cyrfmfg_id[3]) + RX_num;
|
||||
bits=10;
|
||||
}
|
||||
//
|
||||
uint16_t max = 1 << bits;//max=2048 for DSMX & 1024 for DSM2 less than 8 ch and 2048 otherwise
|
||||
//uint16_t pct_100 = (uint32_t)max * 100 / 150;//682 1024*100/150
|
||||
//
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
uint8_t idx = ch_map[upper * 7 + i];//1,5,2,3,0,4
|
||||
uint16_t value;
|
||||
if (idx == 0xff)
|
||||
value = 0xffff;
|
||||
else
|
||||
{
|
||||
if (binding)
|
||||
{ // Failsafe position during binding
|
||||
value=max/2; //all channels to middle
|
||||
if(idx==0)
|
||||
value=1; //except throttle
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(idx)
|
||||
{
|
||||
case 0:
|
||||
value=Servo_data[THROTTLE];//85.75-938.25=125%//171-853=100%
|
||||
break;
|
||||
case 1:
|
||||
value=Servo_data[AILERON];
|
||||
break;
|
||||
case 2:
|
||||
value=Servo_data[ELEVATOR];
|
||||
break;
|
||||
case 3:
|
||||
value=Servo_data[RUDDER];
|
||||
break;
|
||||
case 4:
|
||||
value=Servo_data[AUX1];
|
||||
break;
|
||||
case 5:
|
||||
value=Servo_data[AUX2];
|
||||
break;
|
||||
case 6:
|
||||
value=Servo_data[AUX3];
|
||||
break;
|
||||
case 7:
|
||||
value=Servo_data[AUX4];
|
||||
break;
|
||||
}
|
||||
value=map(value,PPM_MIN,PPM_MAX,0,max-1);
|
||||
}
|
||||
value |= (upper && i == 0 ? 0x8000 : 0) | (idx << bits);
|
||||
}
|
||||
packet[i*2+2] = (value >> 8) & 0xff;
|
||||
packet[i*2+3] = (value >> 0) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) get_pn_row(uint8_t channel)
|
||||
{
|
||||
return (sub_protocol == DSMX ? (channel - 2) % 5 : channel % 5);
|
||||
}
|
||||
|
||||
const uint8_t init_vals[][2] = {
|
||||
{CYRF_02_TX_CTRL, 0x00},
|
||||
{CYRF_05_RX_CTRL, 0x00},
|
||||
{CYRF_28_CLK_EN, 0x02},
|
||||
{CYRF_32_AUTO_CAL_TIME, 0x3c},
|
||||
{CYRF_35_AUTOCAL_OFFSET, 0x14},
|
||||
{CYRF_06_RX_CFG, 0x4A},
|
||||
{CYRF_1B_TX_OFFSET_LSB, 0x55},
|
||||
{CYRF_1C_TX_OFFSET_MSB, 0x05},
|
||||
{CYRF_0F_XACT_CFG, 0x24}, // Force Idle
|
||||
{CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode
|
||||
{CYRF_12_DATA64_THOLD, 0x0a},
|
||||
{CYRF_0F_XACT_CFG, 0x04}, // Idle
|
||||
{CYRF_39_ANALOG_CTRL, 0x01},
|
||||
{CYRF_0F_XACT_CFG, 0x24}, //Force IDLE
|
||||
{CYRF_29_RX_ABORT, 0x00}, //Clear RX abort
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold
|
||||
{CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort?
|
||||
{CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold
|
||||
{CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC
|
||||
{CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc
|
||||
{CYRF_14_EOP_CTRL, 0x02}, //set EOP sync == 2
|
||||
{CYRF_01_TX_LENGTH, 0x10}, //16byte packet
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) cyrf_config()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(init_vals[i][0], init_vals[i][1]);
|
||||
CYRF_WritePreamble(0x333304);
|
||||
CYRF_ConfigRFChannel(0x61);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) initialize_bind_state()
|
||||
{
|
||||
uint8_t code[32];
|
||||
|
||||
CYRF_ConfigRFChannel(BIND_CHANNEL); //This seems to be random?
|
||||
uint8_t pn_row = get_pn_row(BIND_CHANNEL);
|
||||
//printf("Ch: %d Row: %d SOP: %d Data: %d\n", BIND_CHANNEL, pn_row, sop_col, data_col);
|
||||
CYRF_ConfigCRCSeed(crc);
|
||||
|
||||
read_code(code,pn_row,sop_col,8);
|
||||
CYRF_ConfigSOPCode(code);
|
||||
read_code(code,pn_row,data_col,16);
|
||||
read_code(code+16,0,8,8);
|
||||
memcpy(code + 24, "\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 8);
|
||||
CYRF_ConfigDataCode(code, 32);
|
||||
|
||||
build_bind_packet();
|
||||
}
|
||||
|
||||
const uint8_t data_vals[][2] = {
|
||||
{CYRF_05_RX_CTRL, 0x83}, //Initialize for reading RSSI
|
||||
{CYRF_29_RX_ABORT, 0x20},
|
||||
{CYRF_0F_XACT_CFG, 0x24},
|
||||
{CYRF_29_RX_ABORT, 0x00},
|
||||
{CYRF_03_TX_CFG, 0x08 | CYRF_HIGH_POWER},
|
||||
{CYRF_10_FRAMING_CFG, 0xea},
|
||||
{CYRF_1F_TX_OVERRIDE, 0x00},
|
||||
{CYRF_1E_RX_OVERRIDE, 0x00},
|
||||
{CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER},
|
||||
{CYRF_12_DATA64_THOLD, 0x3f},
|
||||
{CYRF_10_FRAMING_CFG, 0xff},
|
||||
{CYRF_0F_XACT_CFG, 0x24}, //Switch from reading RSSI to Writing
|
||||
{CYRF_29_RX_ABORT, 0x00},
|
||||
{CYRF_12_DATA64_THOLD, 0x0a},
|
||||
{CYRF_10_FRAMING_CFG, 0xea},
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) cyrf_configdata()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(data_vals) / 2; i++)
|
||||
CYRF_WriteRegister(data_vals[i][0], data_vals[i][1]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) set_sop_data_crc()
|
||||
{
|
||||
uint8_t code[16];
|
||||
uint8_t pn_row = get_pn_row(hopping_frequency[chidx]);
|
||||
//printf("Ch: %d Row: %d SOP: %d Data: %d\n", ch[chidx], pn_row, sop_col, data_col);
|
||||
CYRF_ConfigRFChannel(hopping_frequency[chidx]);
|
||||
CYRF_ConfigCRCSeed(crcidx ? ~crc : crc);
|
||||
|
||||
read_code(code,pn_row,sop_col,8);
|
||||
CYRF_ConfigSOPCode(code);
|
||||
read_code(code,pn_row,data_col,16);
|
||||
CYRF_ConfigDataCode(code, 16);
|
||||
|
||||
if(sub_protocol == DSMX)
|
||||
chidx = (chidx + 1) % 23;
|
||||
else
|
||||
chidx = (chidx + 1) % 2;
|
||||
crcidx = !crcidx;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) 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));
|
||||
uint32_t id_tmp = id;
|
||||
while(idx < 23)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t count_3_27 = 0, count_28_51 = 0, count_52_76 = 0;
|
||||
id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F; // Randomization
|
||||
uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3; // Use least-significant byte and must be larger than 3
|
||||
if (((next_ch ^ id) & 0x01 )== 0)
|
||||
continue;
|
||||
for (i = 0; i < idx; i++)
|
||||
{
|
||||
if(hopping_frequency[i] == next_ch)
|
||||
break;
|
||||
if(hopping_frequency[i] <= 27)
|
||||
count_3_27++;
|
||||
else
|
||||
if (hopping_frequency[i] <= 51)
|
||||
count_28_51++;
|
||||
else
|
||||
count_52_76++;
|
||||
}
|
||||
if (i != idx)
|
||||
continue;
|
||||
if ((next_ch < 28 && count_3_27 < 8)
|
||||
||(next_ch >= 28 && next_ch < 52 && count_28_51 < 7)
|
||||
||(next_ch >= 52 && count_52_76 < 8))
|
||||
hopping_frequency[idx++] = next_ch;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ReadDsm2()
|
||||
{
|
||||
#define CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#define WRITE_DELAY 1650 // 1550 original, Time after write to verify write complete
|
||||
#define READ_DELAY 400 // Time before write to check read state, and switch channels
|
||||
uint8_t i = 0;
|
||||
|
||||
switch(cyrf_state)
|
||||
{
|
||||
default:
|
||||
//Binding
|
||||
cyrf_state++;
|
||||
if(cyrf_state & 1)
|
||||
{
|
||||
//Send packet on even states
|
||||
//Note state has already incremented,
|
||||
// so this is actually 'even' state
|
||||
CYRF_WriteDataPacket(packet);
|
||||
return 8500;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check status on odd states
|
||||
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS);
|
||||
return 1500;
|
||||
}
|
||||
case DSM2_CHANSEL:
|
||||
BIND_DONE;
|
||||
//Select channels and configure for writing data
|
||||
//CYRF_FindBestChannels(ch, 2, 10, 1, 79);
|
||||
cyrf_configdata();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
chidx = 0;
|
||||
crcidx = 0;
|
||||
cyrf_state = DSM2_CH1_WRITE_A; // in fact cyrf_state++
|
||||
set_sop_data_crc();
|
||||
return 10000;
|
||||
case DSM2_CH1_WRITE_A:
|
||||
case DSM2_CH1_WRITE_B:
|
||||
build_data_packet(cyrf_state == DSM2_CH1_WRITE_B);//compare state and DSM2_CH1_WRITE_B return 0 or 1
|
||||
case DSM2_CH2_WRITE_A:
|
||||
case DSM2_CH2_WRITE_B:
|
||||
CYRF_WriteDataPacket(packet);
|
||||
cyrf_state++; // change from WRITE to CHECK mode
|
||||
return WRITE_DELAY;
|
||||
case DSM2_CH1_CHECK_A:
|
||||
case DSM2_CH1_CHECK_B:
|
||||
while (! (CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02))
|
||||
if(++i > NUM_WAIT_LOOPS)
|
||||
break;
|
||||
set_sop_data_crc();
|
||||
cyrf_state++; // change from CH1_CHECK to CH2_WRITE
|
||||
return CH1_CH2_DELAY - WRITE_DELAY;
|
||||
case DSM2_CH2_CHECK_A:
|
||||
case DSM2_CH2_CHECK_B:
|
||||
while (! (CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02))
|
||||
if(++i > NUM_WAIT_LOOPS)
|
||||
break;
|
||||
if (cyrf_state == DSM2_CH2_CHECK_A)
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
// No telemetry...
|
||||
set_sop_data_crc();
|
||||
if (cyrf_state == DSM2_CH2_CHECK_A)
|
||||
{
|
||||
if(option < 8)
|
||||
{
|
||||
cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
|
||||
if(option>3)
|
||||
return 11000 - CH1_CH2_DELAY - WRITE_DELAY ; // force 11ms if option>3 ie 4,5,6,7 channels @11ms
|
||||
else
|
||||
return 22000 - CH1_CH2_DELAY - WRITE_DELAY ; // normal 22ms mode if option<=3 ie 4,5,6,7 channels @22ms
|
||||
}
|
||||
else
|
||||
cyrf_state = DSM2_CH1_WRITE_B; // change from CH2_CHECK_A to CH1_WRITE_A (to transmit upper)
|
||||
}
|
||||
else
|
||||
cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)
|
||||
return 11000 - CH1_CH2_DELAY - WRITE_DELAY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initDsm2()
|
||||
{
|
||||
CYRF_Reset();
|
||||
CYRF_GetMfgData(cyrfmfg_id);//
|
||||
|
||||
cyrf_config();
|
||||
|
||||
if (sub_protocol ==DSMX)
|
||||
calc_dsmx_channel();
|
||||
else
|
||||
{
|
||||
#if RANDOM_CHANNELS == 1
|
||||
uint8_t tmpch[10];
|
||||
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75);
|
||||
//
|
||||
randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed
|
||||
uint8_t idx = random(0xfefefefe) % 10;
|
||||
hopping_frequency[0] = tmpch[idx];
|
||||
while(1)
|
||||
{
|
||||
idx = random(0xfefefefe) % 10;
|
||||
if (tmpch[idx] != hopping_frequency[0])
|
||||
break;
|
||||
}
|
||||
hopping_frequency[1] = tmpch[idx];
|
||||
#else
|
||||
hopping_frequency[0] = (cyrfmfg_id[0] + cyrfmfg_id[2] + cyrfmfg_id[4]) % 39 + 1;
|
||||
hopping_frequency[1] = (cyrfmfg_id[1] + cyrfmfg_id[3] + cyrfmfg_id[5]) % 40 + 40;
|
||||
#endif
|
||||
}
|
||||
|
||||
///}
|
||||
crc = ~((cyrfmfg_id[0] << 8) + cyrfmfg_id[1]); //The crc for channel 'a' is NOT(mfgid[1] << 8 + mfgid[0])
|
||||
crcidx = 0;//The crc for channel 'b' is (mfgid[1] << 8 + mfgid[0])
|
||||
//
|
||||
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;//Ok
|
||||
data_col = 7 - sop_col;//ok
|
||||
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
//
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
cyrf_state = DSM2_BIND;
|
||||
PROTOCOL_SticksMoved(1); //Initialize Stick position
|
||||
initialize_bind_state();
|
||||
binding = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cyrf_state = DSM2_CHANSEL;//
|
||||
binding = 0;
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
@ -135,8 +135,7 @@ static uint8_t __attribute__((unused)) get_pn_row(uint8_t channel)
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM init_vals[][2] = {
|
||||
{CYRF_02_TX_CTRL, 0x03}, // TX interrupt complete and error enabled
|
||||
//0x00 in deviation but needed to know when transmit is over
|
||||
{CYRF_02_TX_CTRL, 0x00}, // All TX interrupt disabled
|
||||
{CYRF_05_RX_CTRL, 0x00}, // All RX interrupt disabled
|
||||
{CYRF_28_CLK_EN, 0x02}, // Force receive clock enable
|
||||
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // Default init value
|
||||
@ -369,13 +368,13 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||
uint16_t ReadDsm()
|
||||
{
|
||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#define DSM_WRITE_DELAY 1550 // Time after write to verify write complete
|
||||
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
|
||||
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet
|
||||
uint16_t start;
|
||||
#if defined DSM_TELEMETRY
|
||||
uint8_t rx_phase;
|
||||
uint8_t len;
|
||||
#endif
|
||||
uint8_t start;
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
@ -451,19 +450,28 @@ uint16_t ReadDsm()
|
||||
return DSM_WRITE_DELAY;
|
||||
case DSM_CH1_CHECK_A:
|
||||
case DSM_CH1_CHECK_B:
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 500) // Wait max 500µs
|
||||
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||
break;
|
||||
set_sop_data_crc();
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||
case DSM_CH2_CHECK_A:
|
||||
case DSM_CH2_CHECK_B:
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 500) // Wait max 500µs
|
||||
while ((uint8_t)micros()-start < 100) // Wait max 100µs, max I've seen is 50µs
|
||||
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||
break;
|
||||
if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B)
|
||||
{
|
||||
#if defined DSM_TELEMETRY
|
||||
// reset cyrf6936 if freezed after switching from TX to RX
|
||||
if (((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x22) == 0x20) || (CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80))
|
||||
{
|
||||
CYRF_Reset();
|
||||
cyrf_config();
|
||||
cyrf_configdata();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
#endif
|
||||
set_sop_data_crc();
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||
}
|
||||
if (phase == DSM_CH2_CHECK_A)
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
#if defined DSM_TELEMETRY
|
||||
|
@ -43,31 +43,7 @@ enum {
|
||||
DEVO_BOUND_10,
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
const uint8_t sopcodes[][8] = {
|
||||
/* Note these are in order transmitted (LSB 1st) */
|
||||
/* 0 */ {0x3C,0x37,0xCC,0x91,0xE2,0xF8,0xCC,0x91}, //0x91CCF8E291CC373C
|
||||
/* 1 */ {0x9B,0xC5,0xA1,0x0F,0xAD,0x39,0xA2,0x0F}, //0x0FA239AD0FA1C59B
|
||||
/* 2 */ {0xEF,0x64,0xB0,0x2A,0xD2,0x8F,0xB1,0x2A}, //0x2AB18FD22AB064EF
|
||||
/* 3 */ {0x66,0xCD,0x7C,0x50,0xDD,0x26,0x7C,0x50}, //0x507C26DD507CCD66
|
||||
/* 4 */ {0x5C,0xE1,0xF6,0x44,0xAD,0x16,0xF6,0x44}, //0x44F616AD44F6E15C
|
||||
/* 5 */ {0x5A,0xCC,0xAE,0x46,0xB6,0x31,0xAE,0x46}, //0x46AE31B646AECC5A
|
||||
/* 6 */ {0xA1,0x78,0xDC,0x3C,0x9E,0x82,0xDC,0x3C}, //0x3CDC829E3CDC78A1
|
||||
/* 7 */ {0xB9,0x8E,0x19,0x74,0x6F,0x65,0x18,0x74}, //0x7418656F74198EB9
|
||||
/* 8 */ {0xDF,0xB1,0xC0,0x49,0x62,0xDF,0xC1,0x49}, //0x49C1DF6249C0B1DF
|
||||
/* 9 */ {0x97,0xE5,0x14,0x72,0x7F,0x1A,0x14,0x72}, //0x72141A7F7214E597
|
||||
};
|
||||
|
||||
uint8_t txState;
|
||||
uint8_t pkt_num;
|
||||
uint8_t ch_idx;
|
||||
uint8_t use_fixed_id;
|
||||
uint8_t failsafe_pkt;
|
||||
|
||||
static void __attribute__((unused)) scramble_pkt()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_scramble_pkt()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
#ifdef NO_SCRAMBLE
|
||||
return;
|
||||
@ -77,11 +53,7 @@ static void __attribute__((unused)) DEVO_scramble_pkt()
|
||||
#endif
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) add_pkt_suffix()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
uint8_t bind_state;
|
||||
#ifdef ENABLE_PPM
|
||||
@ -91,7 +63,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
||||
BIND_SET_PULLUP; // set pullup
|
||||
if(IS_BIND_BUTTON_on)
|
||||
{
|
||||
eeprom_write_byte((uint8_t*)(30+mode_select),0x01); // Set fixed id mode for the current model
|
||||
eeprom_write_byte((EE_ADDR)(30+mode_select),0x01); // Set fixed id mode for the current model
|
||||
option=1;
|
||||
}
|
||||
BIND_SET_OUTPUT;
|
||||
@ -119,11 +91,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
||||
packet[15] = (MProtocol_id >> 16) & 0xff;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) build_beacon_pkt(uint8_t upper)
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x07;
|
||||
uint8_t max = 8;
|
||||
@ -138,11 +106,7 @@ static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||
DEVO_add_pkt_suffix();
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) build_bind_pkt()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_build_bind_pkt()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
|
||||
packet[1] = bind_counter & 0xff;
|
||||
@ -162,11 +126,7 @@ static void __attribute__((unused)) DEVO_build_bind_pkt()
|
||||
packet[15] ^= cyrfmfg_id[2];
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) build_data_pkt()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
static uint8_t ch_idx=0;
|
||||
|
||||
@ -190,11 +150,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
DEVO_add_pkt_suffix();
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) cyrf_set_bound_sop_code()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
/* crc == 0 isn't allowed, so use 1 if the math results in 0 */
|
||||
uint8_t crc = (cyrfmfg_id[0] + (cyrfmfg_id[1] >> 6) + cyrfmfg_id[2]);
|
||||
@ -207,9 +163,6 @@ static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code()
|
||||
CYRF_SetPower(0x08);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) cyrf_init()
|
||||
=======
|
||||
const uint8_t PROGMEM DEVO_init_vals[][2] = {
|
||||
{ CYRF_1D_MODE_OVERRIDE, 0x38 },
|
||||
{ CYRF_03_TX_CFG, 0x08 },
|
||||
@ -233,18 +186,13 @@ const uint8_t PROGMEM DEVO_init_vals[][2] = {
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) DEVO_cyrf_init()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
/* Initialise CYRF chip */
|
||||
for(uint8_t i = 0; i < sizeof(DEVO_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte( &DEVO_init_vals[i][0]), pgm_read_byte( &DEVO_init_vals[i][1]) );
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) set_radio_channels()
|
||||
=======
|
||||
static void __attribute__((unused)) DEVO_set_radio_channels()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
|
||||
hopping_frequency[3] = hopping_frequency[0];
|
||||
@ -337,35 +285,6 @@ uint16_t devo_callback()
|
||||
return 1200;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/*static void __attribute__((unused)) devo_bind()
|
||||
{
|
||||
fixed_id = Model_fixed_id;
|
||||
bind_counter = DEVO_BIND_COUNT;
|
||||
use_fixed_id = 1;
|
||||
//PROTOCOL_SetBindState(0x1388 * 2400 / 1000); //msecs 12000ms
|
||||
}
|
||||
|
||||
|
||||
static void __attribute__((unused)) generate_fixed_id_bind(){
|
||||
if(BIND_0){
|
||||
//randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed
|
||||
uint8_t txid[4];
|
||||
//Model_fixed_id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
Model_fixed_id=0x332211;
|
||||
txid[0]= (id &0xFF);
|
||||
txid[1] = ((id >> 8) & 0xFF);
|
||||
txid[2] = ((id >> 16) & 0xFF);
|
||||
//txid[3] = ((id >> 24) & 0xFF);
|
||||
eeprom_write_block((const void*)txid,(void*)40,3);
|
||||
devo_bind();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
uint16_t DevoInit()
|
||||
{
|
||||
DEVO_cyrf_init();
|
||||
|
@ -15,26 +15,17 @@
|
||||
// Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29
|
||||
|
||||
#if defined(FY326_NRF24L01_INO)
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define FY326_INITIAL_WAIT 500
|
||||
#define FY326_PACKET_PERIOD 1500
|
||||
#define FY326_PACKET_CHKTIME 300
|
||||
#define FY326_PACKET_SIZE 15
|
||||
<<<<<<< HEAD
|
||||
#define FY326_BIND_COUNT 16
|
||||
=======
|
||||
#define FY326_BIND_COUNT 16
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#define FY326_RF_BIND_CHANNEL 0x17
|
||||
#define FY326_NUM_RF_CHANNELS 5
|
||||
|
||||
enum {
|
||||
<<<<<<< HEAD
|
||||
FY326_INIT1 = 0,
|
||||
FY326_BIND1,
|
||||
FY326_BIND2,
|
||||
@ -42,11 +33,6 @@ enum {
|
||||
FY319_INIT1,
|
||||
FY319_BIND1,
|
||||
FY319_BIND2,
|
||||
=======
|
||||
FY326_BIND1=0,
|
||||
FY326_BIND2,
|
||||
FY326_DATA
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
};
|
||||
|
||||
#define rxid channel
|
||||
@ -56,11 +42,7 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
{
|
||||
packet[0] = rx_tx_addr[3];
|
||||
if(bind)
|
||||
<<<<<<< HEAD
|
||||
packet[1] = 0x55;
|
||||
=======
|
||||
packet[1] = 0x55;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
else
|
||||
packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless
|
||||
| GET_FLAG(Servo_AUX2, 0x40) // RTH
|
||||
@ -71,11 +53,10 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
|
||||
packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder
|
||||
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
|
||||
<<<<<<< HEAD
|
||||
if(sub_protocol == FY319) {
|
||||
packet[6] = 255 - scale_channel(AILERON, 0, 255);
|
||||
packet[7] = scale_channel(ELEVATOR, 0, 255);
|
||||
packet[8] = 255 - scale_channel(RUDDER, 0, 255);
|
||||
packet[6] = 255 - convert_channel_8b_scale(AILERON, 0, 255);
|
||||
packet[7] = convert_channel_8b_scale(ELEVATOR, 0, 255);
|
||||
packet[8] = 255 - convert_channel_8b_scale(RUDDER, 0, 255);
|
||||
}
|
||||
else {
|
||||
packet[6] = rx_tx_addr[0];
|
||||
@ -87,16 +68,6 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim;
|
||||
packet[12] = 0; // throttle_trim;
|
||||
packet[13] = rxid;
|
||||
=======
|
||||
packet[6] = rx_tx_addr[0];
|
||||
packet[7] = rx_tx_addr[1];
|
||||
packet[8] = rx_tx_addr[2];
|
||||
packet[9] = CHAN_TO_TRIM(packet[2]); // aileron_trim;
|
||||
packet[10] = CHAN_TO_TRIM(packet[3]); // elevator_trim;
|
||||
packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim;
|
||||
packet[12] = 0; // throttle_trim;
|
||||
packet[13] = rxid;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet[14] = rx_tx_addr[4];
|
||||
|
||||
if (bind)
|
||||
@ -105,20 +76,12 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no %= FY326_NUM_RF_CHANNELS;
|
||||
<<<<<<< HEAD
|
||||
|
||||
}
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
=======
|
||||
}
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
||||
NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
|
||||
|
||||
@ -127,18 +90,12 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
|
||||
static void __attribute__((unused)) FY326_init()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
if(sub_protocol == FY319)
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address
|
||||
=======
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
|
||||
NRF24L01_FlushTx();
|
||||
@ -150,20 +107,14 @@ static void __attribute__((unused)) FY326_init()
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_SetPower();
|
||||
<<<<<<< HEAD
|
||||
|
||||
NRF24L01_Activate(0x73);
|
||||
=======
|
||||
|
||||
NRF24L01_Activate(0x73);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
uint16_t fy326_callback()
|
||||
uint16_t FY326_callback()
|
||||
{
|
||||
uint8_t i;
|
||||
switch (phase) {
|
||||
@ -171,19 +122,19 @@ uint16_t fy326_callback()
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
|
||||
phase = FY319_BIND1;
|
||||
BIND_IN_PROGRESS;
|
||||
return FY326_CHKTIME;
|
||||
return FY326_PACKET_CHKTIME;
|
||||
break;
|
||||
|
||||
case FY319_BIND1:
|
||||
if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) {
|
||||
NRF24L01_ReadPayload(packet, FY326_SIZE);
|
||||
if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) {
|
||||
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
||||
rxid = packet[13];
|
||||
packet[0] = txid[3];
|
||||
packet[0] = rx_tx_addr[3];
|
||||
packet[1] = 0x80;
|
||||
packet[14]= txid[4];
|
||||
packet[14]= rx_tx_addr[4];
|
||||
bind_counter = FY326_BIND_COUNT;
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
@ -191,16 +142,16 @@ uint16_t fy326_callback()
|
||||
NRF24L01_FlushTx();
|
||||
bind_counter = 255;
|
||||
for(i=2; i<6; i++)
|
||||
packet[i] = rf_chans[0];
|
||||
packet[i] = hopping_frequency[0];
|
||||
phase = FY319_BIND2;
|
||||
}
|
||||
return FY326_CHKTIME;
|
||||
return FY326_PACKET_CHKTIME;
|
||||
break;
|
||||
|
||||
case FY319_BIND2:
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet, FY326_SIZE);
|
||||
NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
|
||||
if(bind_counter == 250)
|
||||
packet[1] = 0x40;
|
||||
if(--bind_counter == 0) {
|
||||
@ -212,12 +163,12 @@ uint16_t fy326_callback()
|
||||
case FY326_INIT1:
|
||||
bind_counter = FY326_BIND_COUNT;
|
||||
phase = FY326_BIND2;
|
||||
send_packet(1);
|
||||
return FY326_CHKTIME;
|
||||
FY326_send_packet(1);
|
||||
return FY326_PACKET_CHKTIME;
|
||||
break;
|
||||
|
||||
case FY326_BIND1:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // RX fifo data ready
|
||||
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
||||
rxid = packet[13];
|
||||
@ -240,7 +191,7 @@ uint16_t fy326_callback()
|
||||
break;
|
||||
|
||||
case FY326_BIND2:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS))
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))
|
||||
{ // TX data sent -> switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
@ -255,55 +206,11 @@ uint16_t fy326_callback()
|
||||
FY326_send_packet(0);
|
||||
break;
|
||||
}
|
||||
=======
|
||||
uint16_t FY326_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case FY326_BIND1:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // RX fifo data ready
|
||||
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
||||
rxid = packet[13];
|
||||
rx_tx_addr[0] = 0xAA;
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
BIND_DONE;
|
||||
phase = FY326_DATA;
|
||||
}
|
||||
else
|
||||
if (bind_counter-- == 0)
|
||||
{
|
||||
bind_counter = FY326_BIND_COUNT;
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
FY326_send_packet(1);
|
||||
phase = FY326_BIND2;
|
||||
return FY326_PACKET_CHKTIME;
|
||||
}
|
||||
break;
|
||||
case FY326_BIND2:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))
|
||||
{ // TX data sent -> switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
phase = FY326_BIND1;
|
||||
}
|
||||
else
|
||||
return FY326_PACKET_CHKTIME;
|
||||
break;
|
||||
case FY326_DATA:
|
||||
FY326_send_packet(0);
|
||||
break;
|
||||
}
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
return FY326_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FY326_initialize_txid()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if(sub_protocol == FY319) {
|
||||
hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~0x80;
|
||||
hopping_frequency[1] = (rx_tx_addr[0] >> 4) & ~0x80;
|
||||
@ -317,34 +224,19 @@ static void __attribute__((unused)) FY326_initialize_txid()
|
||||
hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4);
|
||||
hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4);
|
||||
}
|
||||
=======
|
||||
hopping_frequency[0] = (rx_tx_addr[0]&0x0f);
|
||||
hopping_frequency[1] = 0x10 + (rx_tx_addr[0] >> 4);
|
||||
hopping_frequency[2] = 0x20 + (rx_tx_addr[1]&0x0f);
|
||||
hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4);
|
||||
hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
uint16_t initFY326(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
<<<<<<< HEAD
|
||||
rxid = 0xaa;
|
||||
rxid = 0xAA;
|
||||
bind_counter = 0;
|
||||
FY326_initialize_txid();
|
||||
fy326_init();
|
||||
FY326_init();
|
||||
if(sub_protocol == FY319)
|
||||
phase = FY319_INIT1;
|
||||
else
|
||||
phase = FY326_INIT1;
|
||||
=======
|
||||
rxid = 0xAA;
|
||||
bind_counter = 0;
|
||||
FY326_initialize_txid();
|
||||
FY326_init();
|
||||
phase=FY326_BIND1;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
return FY326_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
|
@ -21,34 +21,6 @@
|
||||
//FlySky constants & variables
|
||||
#define FLYSKY_BIND_COUNT 2500
|
||||
|
||||
<<<<<<< HEAD
|
||||
const uint8_t PROGMEM tx_channels[] = {
|
||||
0x0a, 0x5a, 0x14, 0x64, 0x1e, 0x6e, 0x28, 0x78, 0x32, 0x82, 0x3c, 0x8c, 0x46, 0x96, 0x50, 0xa0,
|
||||
0xa0, 0x50, 0x96, 0x46, 0x8c, 0x3c, 0x82, 0x32, 0x78, 0x28, 0x6e, 0x1e, 0x64, 0x14, 0x5a, 0x0a,
|
||||
0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x46, 0x96, 0x1e, 0x6e, 0x3c, 0x8c, 0x28, 0x78, 0x32, 0x82,
|
||||
0x82, 0x32, 0x78, 0x28, 0x8c, 0x3c, 0x6e, 0x1e, 0x96, 0x46, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a,
|
||||
0x28, 0x78, 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96,
|
||||
0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, 0x78, 0x28,
|
||||
0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, 0x14, 0x64,
|
||||
0x64, 0x14, 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50,
|
||||
0x50, 0xa0, 0x46, 0x96, 0x3c, 0x8c, 0x28, 0x78, 0x0a, 0x5a, 0x32, 0x82, 0x1e, 0x6e, 0x14, 0x64,
|
||||
0x64, 0x14, 0x6e, 0x1e, 0x82, 0x32, 0x5a, 0x0a, 0x78, 0x28, 0x8c, 0x3c, 0x96, 0x46, 0xa0, 0x50,
|
||||
0x46, 0x96, 0x3c, 0x8c, 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64,
|
||||
0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, 0x8c, 0x3c, 0x96, 0x46,
|
||||
0x46, 0x96, 0x0a, 0x5a, 0x3c, 0x8c, 0x14, 0x64, 0x50, 0xa0, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82,
|
||||
0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0xa0, 0x50, 0x64, 0x14, 0x8c, 0x3c, 0x5a, 0x0a, 0x96, 0x46,
|
||||
0x46, 0x96, 0x0a, 0x5a, 0x50, 0xa0, 0x3c, 0x8c, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64,
|
||||
0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0x8c, 0x3c, 0xa0, 0x50, 0x5a, 0x0a, 0x96, 0x46
|
||||
};
|
||||
|
||||
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 10
|
||||
FLAG_V9X9_VIDEO = 0x40,
|
||||
@ -56,27 +28,26 @@ enum {
|
||||
// flags going to byte 12
|
||||
FLAG_V9X9_FLIP = 0x10,
|
||||
FLAG_V9X9_LED = 0x20,
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
};
|
||||
|
||||
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,
|
||||
// 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,
|
||||
// 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 ?
|
||||
@ -84,79 +55,6 @@ const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, //
|
||||
|
||||
static void __attribute__((unused)) flysky_apply_extension_flags()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
const uint8_t V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
|
||||
0x49, 0x49, 0x49, 0x49, 0x49, };
|
||||
static uint8_t seq_counter;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case V9X9:
|
||||
if(Servo_AUX1)
|
||||
packet[12] |= FLAG_V9X9_FLIP;
|
||||
if(Servo_AUX2)
|
||||
packet[12] |= FLAG_V9X9_LED;
|
||||
if(Servo_AUX3)
|
||||
packet[10] |= FLAG_V9X9_CAMERA;
|
||||
if(Servo_AUX4)
|
||||
packet[10] |= FLAG_V9X9_VIDEO;
|
||||
break;
|
||||
|
||||
case V6X6:
|
||||
packet[13] = 0x03; // 3 = 100% rate (0=40%, 1=60%, 2=80%)
|
||||
packet[14] = 0x00;
|
||||
if(Servo_AUX1)
|
||||
packet[14] |= FLAG_V6X6_FLIP;
|
||||
if(Servo_AUX2)
|
||||
packet[14] |= FLAG_V6X6_LED;
|
||||
if(Servo_AUX3)
|
||||
packet[14] |= FLAG_V6X6_CAMERA;
|
||||
if(Servo_AUX4)
|
||||
packet[14] |= FLAG_V6X6_VIDEO;
|
||||
if(Servo_AUX5)
|
||||
{
|
||||
packet[13] |= FLAG_V6X6_HLESS1;
|
||||
packet[14] |= FLAG_V6X6_HLESS2;
|
||||
}
|
||||
if(Servo_AUX6) //use option to manipulate these bytes
|
||||
packet[14] |= FLAG_V6X6_RTH;
|
||||
if(Servo_AUX7)
|
||||
packet[14] |= FLAG_V6X6_XCAL;
|
||||
if(Servo_AUX8)
|
||||
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:
|
||||
seq_counter++;
|
||||
if( seq_counter > 9)
|
||||
seq_counter = 0;
|
||||
packet[12] |= 0x20; // bit 6 is always set ?
|
||||
packet[13] = 0x00; // unknown
|
||||
packet[14] = 0x00;
|
||||
if(Servo_AUX1)
|
||||
packet[14] = FLAG_V912_BTMBTN;
|
||||
if(Servo_AUX2)
|
||||
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] = V912_X17_SEQ[seq_counter]; // not sure what [17] & [18] are for
|
||||
if(seq_counter == 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;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
=======
|
||||
static uint8_t seq_counter;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
@ -226,78 +124,39 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
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;AUX1;AUX2;AUX3;AUX4
|
||||
//servodata timing range for flysky.
|
||||
////-100% =~ 0x03e8//=1000us(min)
|
||||
//+100% =~ 0x07ca//=1994us(max)
|
||||
//Center = 0x5d9//=1497us(center)
|
||||
//channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4
|
||||
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];
|
||||
<<<<<<< HEAD
|
||||
const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4};
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
packet[5+2*i]=lowByte(Servo_data[ch[i]]); //low byte of servo timing(1000-2000us)
|
||||
packet[6+2*i]=highByte(Servo_data[ch[i]]); //high byte of servo timing(1000-2000us)
|
||||
}
|
||||
=======
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
packet[5 + i*2]=Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us)
|
||||
packet[6 + i*2]=(Servo_data[CH_AETR[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
||||
}
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
flysky_apply_extension_flags();
|
||||
}
|
||||
|
||||
uint16_t ReadFlySky()
|
||||
{
|
||||
if (bind_counter)
|
||||
{
|
||||
{
|
||||
flysky_build_packet(1);
|
||||
A7105_WriteData(21, 1);
|
||||
bind_counter--;
|
||||
if (! bind_counter)
|
||||
BIND_DONE;
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
else
|
||||
{
|
||||
flysky_build_packet(0);
|
||||
A7105_WriteData(21, pgm_read_byte_near(&tx_channels[chanrow*16+chancol])-chanoffset);
|
||||
chancol = (chancol + 1) % 16;
|
||||
if (! chancol) //Keep transmit power updated
|
||||
A7105_SetPower();
|
||||
}
|
||||
return 1460;
|
||||
}
|
||||
|
||||
uint16_t initFlySky() {
|
||||
//A7105_Reset();
|
||||
A7105_Init(INIT_FLYSKY); //flysky_init();
|
||||
|
||||
if (rx_tx_addr[3] > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912)
|
||||
rx_tx_addr[3] = rx_tx_addr[3] - 0x70;
|
||||
chanrow=rx_tx_addr[3] % 16;
|
||||
chancol=0;
|
||||
chanoffset=rx_tx_addr[3] / 16;
|
||||
|
||||
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
bind_counter = FLYSKY_BIND_COUNT;
|
||||
else
|
||||
bind_counter = 0;
|
||||
return 2400;
|
||||
=======
|
||||
else
|
||||
{
|
||||
flysky_build_packet(0);
|
||||
@ -325,7 +184,7 @@ uint16_t initFlySky()
|
||||
uint8_t chanoffset;
|
||||
uint8_t temp;
|
||||
|
||||
A7105_Init(INIT_FLYSKY); //flysky_init();
|
||||
A7105_Init();
|
||||
|
||||
if ((rx_tx_addr[3]&0xF0) > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912)
|
||||
rx_tx_addr[3]=rx_tx_addr[3]-0x70;
|
||||
@ -352,7 +211,5 @@ uint16_t initFlySky()
|
||||
else
|
||||
bind_counter = 0;
|
||||
return 2400;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -17,297 +17,9 @@
|
||||
*/
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
uint8_t chanskip;
|
||||
uint8_t calData[48][3];
|
||||
uint8_t channr;
|
||||
uint8_t pass_ = 1 ;
|
||||
uint8_t counter_rst;
|
||||
uint8_t ctr;
|
||||
uint8_t FS_flag=0;
|
||||
// uint8_t ptr[4]={0x01,0x12,0x23,0x30};
|
||||
//uint8_t ptr[4]={0x00,0x11,0x22,0x33};
|
||||
|
||||
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]);
|
||||
}
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
static void __attribute__((unused)) set_start(uint8_t ch )
|
||||
{
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeReg(CC2500_23_FSCAL3, calData[ch][0]);
|
||||
cc2500_writeReg(CC2500_24_FSCAL2, calData[ch][1]);
|
||||
cc2500_writeReg(CC2500_25_FSCAL1, calData[ch][2]);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, ch==47?0:pgm_read_word(&hop_data[ch]));
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_init()
|
||||
{
|
||||
CC2500_Reset();
|
||||
|
||||
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);
|
||||
cc2500_writeReg(CC2500_0C_FSCTRL0, option);
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
//
|
||||
for(uint8_t c=0;c < 47;c++){//calibrate hop channels
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR,pgm_read_word(&hop_data[c]));
|
||||
cc2500_strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);//
|
||||
calData[c][0] = cc2500_readReg(CC2500_23_FSCAL3);
|
||||
calData[c][1] = cc2500_readReg(CC2500_24_FSCAL2);
|
||||
calData[c][2] = cc2500_readReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR,0x00);
|
||||
cc2500_strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
calData[47][0] = cc2500_readReg(CC2500_23_FSCAL3);
|
||||
calData[47][1] = cc2500_readReg(CC2500_24_FSCAL2);
|
||||
calData[47][2] = cc2500_readReg(CC2500_25_FSCAL1);
|
||||
//#######END INIT########
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) initialize_data(uint8_t adr)
|
||||
{
|
||||
cc2500_writeReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||
cc2500_writeReg(CC2500_18_MCSM0, 0x8);
|
||||
cc2500_writeReg(CC2500_09_ADDR, adr ? 0x03 : rx_tx_addr[3]);
|
||||
cc2500_writeReg(CC2500_07_PKTCTRL1,0x05);
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) crc_Byte( uint8_t byte )
|
||||
{
|
||||
crc = (crc<<8) ^ pgm_read_word(&CRCTable[((uint8_t)(crc>>8) ^ byte) & 0xFF]);
|
||||
return byte;
|
||||
}
|
||||
|
||||
static uint16_t __attribute__((unused)) scaleForPXX( uint8_t i )
|
||||
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
|
||||
return (uint16_t)(((Servo_data[i]-PPM_MIN)*3)>>1)+64;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_build_bind_packet()
|
||||
{
|
||||
crc=0;
|
||||
packet[0] = 0x1D;
|
||||
packet[1] = 0x03;
|
||||
packet[2] = 0x01;
|
||||
//
|
||||
packet[3] = crc_Byte(rx_tx_addr[3]);
|
||||
packet[4] = crc_Byte(rx_tx_addr[2]);
|
||||
int idx = ((state -FRSKY_BIND) % 10) * 5;
|
||||
packet[5] = crc_Byte(idx);
|
||||
packet[6] = crc_Byte(pgm_read_word(&hop_data[idx++]));
|
||||
packet[7] = crc_Byte(pgm_read_word(&hop_data[idx++]));
|
||||
packet[8] = crc_Byte(pgm_read_word(&hop_data[idx++]));
|
||||
packet[9] = crc_Byte(pgm_read_word(&hop_data[idx++]));
|
||||
packet[10] = crc_Byte(pgm_read_word(&hop_data[idx++]));
|
||||
packet[11] = crc_Byte(0x02);
|
||||
packet[12] = crc_Byte(RX_num);
|
||||
//
|
||||
for(uint8_t i=13;i<28;i++)
|
||||
packet[i]=crc_Byte(0);
|
||||
//
|
||||
packet[28]=highByte(crc);
|
||||
packet[29]=lowByte(crc);
|
||||
//
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frskyX_data_frame()
|
||||
{
|
||||
//0x1D 0xB3 0xFD 0x02 0x56 0x07 0x15 0x00 0x00 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x96 0x12
|
||||
//
|
||||
uint8_t lpass = pass_ ;
|
||||
uint16_t chan_0 ;
|
||||
uint16_t chan_1 ;
|
||||
uint8_t flag2 = 0;
|
||||
uint8_t startChan = 0;
|
||||
crc = 0;
|
||||
//static uint8_t p = 0;
|
||||
//
|
||||
packet[0] = 0x1D;
|
||||
packet[1] = rx_tx_addr[3];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = crc_Byte(0x02);
|
||||
//
|
||||
packet[4] = crc_Byte((ctr<<6)+channr); //*64
|
||||
packet[5] = crc_Byte(counter_rst);
|
||||
packet[6] = crc_Byte(RX_num);
|
||||
// FLAGS 00 - standard packet
|
||||
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
||||
//20 - range check packet
|
||||
packet[7] = crc_Byte(FS_flag);
|
||||
packet[8] = crc_Byte(flag2);
|
||||
//
|
||||
if ( lpass & 1 )
|
||||
startChan += 8 ;
|
||||
|
||||
for(uint8_t i = 0; i <12 ; i+=3)
|
||||
{//12 bytes
|
||||
chan_0 = scaleForPXX(startChan);
|
||||
if(lpass & 1 )
|
||||
chan_0+=2048;
|
||||
|
||||
packet[9+i] = crc_Byte(lowByte(chan_0));//3 bytes*4
|
||||
startChan++;
|
||||
chan_1 = scaleForPXX(startChan);
|
||||
if(lpass & 1 )
|
||||
chan_1+= 2048;
|
||||
|
||||
startChan++;
|
||||
packet[9+i+1]=crc_Byte((((chan_0>>8) & 0x0F)|(chan_1 << 4)));
|
||||
packet[9+i+2]=crc_Byte(chan_1>>4);
|
||||
}
|
||||
//packet[21]=crc_Byte(0x08);//first
|
||||
packet[21]=crc_Byte(0x80);//??? when received first telemetry frame is changed to 0x80
|
||||
//packet[21]=crc_Byte(ptr[p]);//???
|
||||
//p=(p+1)%4;//repeating 4 bytes sequence pattern every 4th frame.
|
||||
|
||||
pass_=lpass+1;
|
||||
|
||||
for (uint8_t i=22;i<28;i++)
|
||||
packet[i]=crc_Byte(0);
|
||||
|
||||
packet[28]=highByte(crc);
|
||||
packet[29]=lowByte(crc);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
uint16_t ReadFrSkyX()
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
default:
|
||||
set_start(47);
|
||||
CC2500_SetPower();
|
||||
cc2500_strobe(CC2500_SFRX);
|
||||
//
|
||||
frskyX_build_bind_packet();
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeFifo(packet, packet[0]+1);
|
||||
state++;
|
||||
return 9000;
|
||||
case FRSKY_BIND_DONE:
|
||||
initialize_data(0);
|
||||
channr=0;
|
||||
BIND_DONE;
|
||||
state++;
|
||||
break;
|
||||
case FRSKY_DATA1:
|
||||
LED_ON;
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
set_start(channr);
|
||||
CC2500_SetPower();
|
||||
cc2500_strobe(CC2500_SFRX);
|
||||
channr = (channr+chanskip)%47;
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeFifo(packet, packet[0]+1);
|
||||
//
|
||||
frskyX_data_frame();
|
||||
state++;
|
||||
return 5500;
|
||||
case FRSKY_DATA2:
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
state++;
|
||||
return 200;
|
||||
case FRSKY_DATA3:
|
||||
cc2500_strobe(CC2500_SRX);
|
||||
state++;
|
||||
return 3000;
|
||||
case FRSKY_DATA4:
|
||||
len = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len &&(len<MAX_PKT))
|
||||
{
|
||||
cc2500_readFifo(pkt, len);
|
||||
#if defined TELEMETRY
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
||||
//parse telemetry packets here
|
||||
//The same telemetry function used by FrSky(D8).
|
||||
#endif
|
||||
}
|
||||
state = FRSKY_DATA1;
|
||||
return 300;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t initFrSkyX()
|
||||
{
|
||||
while(!chanskip)
|
||||
{
|
||||
randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7));
|
||||
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();
|
||||
//
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
state = FRSKY_BIND;
|
||||
initialize_data(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FRSKY_DATA1;
|
||||
initialize_data(0);
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
=======
|
||||
uint8_t chanskip;
|
||||
uint8_t counter_rst;
|
||||
uint8_t ctr;
|
||||
@ -562,13 +274,14 @@ uint16_t ReadFrSkyX()
|
||||
return 3000;
|
||||
case FRSKY_DATA4:
|
||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len && (len<MAX_PKT))
|
||||
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
||||
{
|
||||
counter=0;
|
||||
CC2500_ReadData(pkt, len);
|
||||
#if defined TELEMETRY
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
||||
//parse telemetry packets here
|
||||
//The same telemetry function used by FrSky(D8).
|
||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
||||
//parse telemetry packets here
|
||||
//The same telemetry function used by FrSky(D8).
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -580,7 +293,11 @@ uint16_t ReadFrSkyX()
|
||||
seq_last_sent = 0;
|
||||
seq_last_rcvd = 8;
|
||||
counter=0;
|
||||
#if defined TELEMETRY
|
||||
telemetry_lost=1;
|
||||
#endif
|
||||
}
|
||||
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
|
||||
}
|
||||
state = FRSKY_DATA1;
|
||||
return 300;
|
||||
@ -617,5 +334,4 @@ uint16_t initFrSkyX()
|
||||
seq_last_rcvd = 8;
|
||||
return 10000;
|
||||
}
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#endif
|
@ -1,219 +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/>.
|
||||
*/
|
||||
|
||||
#if defined(FRSKY_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
//##########Variables########
|
||||
//uint32_t state;
|
||||
//uint8_t len;
|
||||
|
||||
/*
|
||||
enum {
|
||||
FRSKY_BIND = 0,
|
||||
FRSKY_BIND_DONE = 1000,
|
||||
FRSKY_DATA1,
|
||||
FRSKY_DATA2,
|
||||
FRSKY_DATA3,
|
||||
FRSKY_DATA4,
|
||||
FRSKY_DATA5
|
||||
};
|
||||
*/
|
||||
|
||||
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||
{
|
||||
// Configure cc2500 for tx mode
|
||||
CC2500_Reset();
|
||||
//
|
||||
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);
|
||||
}
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
|
||||
cc2500_writeReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
|
||||
cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
cc2500_strobe(CC2500_SIDLE); // Go to idle...
|
||||
//
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, 0x00);
|
||||
cc2500_writeReg(CC2500_23_FSCAL3, 0x89);
|
||||
cc2500_strobe(CC2500_SFRX);
|
||||
//#######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
|
||||
//11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01
|
||||
packet[0] = 0x11;
|
||||
packet[1] = 0x03;
|
||||
packet[2] = 0x01;
|
||||
packet[3] = rx_tx_addr[3];
|
||||
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[11] = 0x00;
|
||||
packet[12] = 0x00;
|
||||
packet[13] = 0x00;
|
||||
packet[14] = 0x00;
|
||||
packet[15] = 0x00;
|
||||
packet[16] = 0x00;
|
||||
packet[17] = 0x01;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky2way_data_frame()
|
||||
{//pachet[4] is telemetry user frame counter(hub)
|
||||
//11 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88
|
||||
//11 57 12 00 00 01 f2 f2 f2 f2 06 06 ca ca ca ca 18 18
|
||||
packet[0] = 0x11; //Length
|
||||
packet[1] = rx_tx_addr[3];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = counter;//
|
||||
#if defined TELEMETRY
|
||||
packet[4] = telemetry_counter;
|
||||
#else
|
||||
packet[4] = 0x00;
|
||||
#endif
|
||||
|
||||
packet[5] = 0x01;
|
||||
//
|
||||
packet[10] = 0;
|
||||
packet[11] = 0;
|
||||
packet[16] = 0;
|
||||
packet[17] = 0;
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
uint16_t value;
|
||||
value = convert_channel_frsky(i);
|
||||
if(i < 4)
|
||||
{
|
||||
packet[6+i] = value & 0xff;
|
||||
packet[10+(i>>1)] |= ((value >> 8) & 0x0f) << (4 *(i & 0x01));
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[8+i] = value & 0xff;
|
||||
packet[16+((i-4)>>1)] |= ((value >> 8) & 0x0f) << (4 * ((i-4) & 0x01));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initFrSky_2way()
|
||||
{
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
{
|
||||
frsky2way_init(1);
|
||||
state = FRSKY_BIND;//
|
||||
}
|
||||
else
|
||||
{
|
||||
frsky2way_init(0);
|
||||
state = FRSKY_DATA2;
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
|
||||
uint16_t ReadFrSky_2way()
|
||||
{
|
||||
if (state < FRSKY_BIND_DONE)
|
||||
{
|
||||
frsky2way_build_bind_packet();
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, 0x00);
|
||||
cc2500_writeReg(CC2500_23_FSCAL3, 0x89);
|
||||
cc2500_strobe(CC2500_SFRX);//0x3A
|
||||
cc2500_writeFifo(packet, packet[0]+1);
|
||||
state++;
|
||||
return 9000;
|
||||
}
|
||||
if (state == FRSKY_BIND_DONE)
|
||||
{
|
||||
state = FRSKY_DATA2;
|
||||
frsky2way_init(0);
|
||||
counter = 0;
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
if (state == FRSKY_DATA5)
|
||||
{
|
||||
cc2500_strobe(CC2500_SRX);//0x34 RX enable
|
||||
state = FRSKY_DATA1;
|
||||
return 9200;
|
||||
}
|
||||
counter = (counter + 1) % 188;
|
||||
if (state == FRSKY_DATA4)
|
||||
{ //telemetry receive
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
cc2500_strobe(CC2500_SIDLE);
|
||||
cc2500_writeReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
||||
cc2500_writeReg(CC2500_23_FSCAL3, 0x89);
|
||||
state++;
|
||||
return 1300;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == FRSKY_DATA1)
|
||||
{
|
||||
len = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if (len<=MAX_PKT)//27 bytes
|
||||
{
|
||||
cc2500_readFifo(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
|
||||
}
|
||||
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_23_FSCAL3, 0x89);
|
||||
cc2500_strobe(CC2500_SFRX);
|
||||
frsky2way_data_frame();
|
||||
cc2500_writeFifo(packet, packet[0]+1);
|
||||
state++;
|
||||
}
|
||||
return state == FRSKY_DATA4 ? 7500 : 9000;
|
||||
}
|
||||
#endif
|
@ -122,7 +122,7 @@ static void __attribute__((unused)) build_ch_data()
|
||||
uint8_t i,j;
|
||||
for (i = 0; i< 8; i++) {
|
||||
j=CH_AETR[i];
|
||||
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000);
|
||||
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000);
|
||||
if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
|
||||
temp = 1000 -temp;
|
||||
if (j == AUX3)
|
||||
|
@ -70,6 +70,7 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if(sub_protocol == FORMAT_JJRCX1)
|
||||
packet[0] = GET_FLAG(Servo_AUX2, 0x02); // Arm
|
||||
else
|
||||
@ -112,7 +113,60 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim
|
||||
else
|
||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim
|
||||
*/
|
||||
packet[1] = 0x00;
|
||||
packet[2] = 0x00;
|
||||
packet[3] = (convert_channel_8b_scale(THROTTLE, 0, 127) << 1); // Throttle
|
||||
packet[4] = convert_channel_8b_scale(AILERON, 63, 0); // Aileron
|
||||
packet[5] = convert_channel_8b_scale(ELEVATOR, 0, 63); // Elevator
|
||||
packet[6] = convert_channel_8b_scale(RUDDER, 0, 63); // Rudder
|
||||
if(sub_protocol == FORMAT_X5C1)
|
||||
packet[7] = convert_channel_8b_scale(AILERON, 0, 63)-31; // Aileron trim
|
||||
else
|
||||
packet[7] = convert_channel_8b_scale(AILERON, 0, 32)-16; // Aileron trim
|
||||
if (sub_protocol == FORMAT_X5C1)
|
||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim
|
||||
else
|
||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim
|
||||
|
||||
switch(sub_protocol) {
|
||||
case FORMAT_HONTAI:
|
||||
packet[0] = 0x0b;
|
||||
packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture
|
||||
packet[4] |= GET_FLAG(Servo_AUX6, 0x80) // RTH
|
||||
| GET_FLAG(Servo_AUX5, 0x40); // Headless
|
||||
packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate
|
||||
| GET_FLAG(Servo_AUX1, 0x40); // Flip
|
||||
packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video
|
||||
packet[8] = convert_channel_8b_scale(RUDDER, 0, 32)-16; // Rudder trim
|
||||
break;
|
||||
case FORMAT_X5C1:
|
||||
case FORMAT_JJRCX1:
|
||||
packet[0] = GET_FLAG(Servo_AUX2, 0x02); //Arm
|
||||
packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture
|
||||
packet[4] |= 0x80; // unknown
|
||||
if (sub_protocol == FORMAT_X5C1)
|
||||
packet[4] |= GET_FLAG(Servo_AUX2, 0x40); // Lights (X5C1)
|
||||
packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate
|
||||
| GET_FLAG(Servo_AUX1, 0x40); // Flip
|
||||
packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video
|
||||
packet[8] = 0xc0 // high rate, no rudder trim
|
||||
| GET_FLAG(Servo_AUX6, 0x02) // RTH
|
||||
| GET_FLAG(Servo_AUX5, 0x01); // Headless
|
||||
break;
|
||||
case FORMAT_FQ777:
|
||||
// todo: add missing calibration flag
|
||||
packet[0] = GET_FLAG(Servo_AUX3, 0x01) // Picture
|
||||
| GET_FLAG(Servo_AUX4, 0x02); // Video
|
||||
packet[3] |= GET_FLAG(Servo_AUX1, 0x01); // Flip
|
||||
packet[4] |= 0xc0; // high rate (mid=0xa0, low=0x60)
|
||||
packet[6] |= GET_FLAG(Servo_AUX5, 0x40); // Headless
|
||||
if((packet[4] & 0x3f) > 0x3d && (packet[5] & 0x3f) < 3)
|
||||
packet[5] |= 0x80; // accelerometer recalibration
|
||||
break;
|
||||
packet[8] = convert_channel_8b_scale(RUDDER, 0, 32)-16; // Rudder trim
|
||||
}
|
||||
|
||||
packet_size=HONTAI_PACKET_SIZE;
|
||||
}
|
||||
crc16(packet, packet_size);
|
||||
@ -172,7 +226,8 @@ static void __attribute__((unused)) HONTAI_init()
|
||||
|
||||
const uint8_t PROGMEM hopping_frequency_nonels[][3] = {
|
||||
{0x05, 0x19, 0x28}, // Hontai
|
||||
{0x0a, 0x1e, 0x2d}}; // JJRC X1
|
||||
{0x0a, 0x1e, 0x2d}, // JJRC X1
|
||||
{0x05, 0x19, 0x28}}; // FQ777-951
|
||||
|
||||
const uint8_t PROGMEM addr_vals[4][16] = {
|
||||
{0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a},
|
||||
|
@ -18,24 +18,51 @@
|
||||
#if defined(HUBSAN_A7105_INO)
|
||||
|
||||
#include "iface_a7105.h"
|
||||
enum {
|
||||
FORMAT_H107 = 0,
|
||||
FORMAT_H301,
|
||||
FORMAT_H501,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[9] (Normal)
|
||||
// flags going to packet[9] (H107 Normal)
|
||||
HUBSAN_FLAG_VIDEO= 0x01, // record video
|
||||
HUBSAN_FLAG_FLIP = 0x08, // enable flips
|
||||
HUBSAN_FLAG_LED = 0x04 // enable LEDs
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[9] (Plus series)
|
||||
// flags going to packet[9] (H107 Plus series)
|
||||
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[13] (Plus series)
|
||||
// flags going to packet[9] (H301)
|
||||
FLAG_H301_VIDEO = 0x01,
|
||||
FLAG_H301_STAB = 0x02,
|
||||
FLAG_H301_LED = 0x10,
|
||||
FLAG_H301_RTH = 0x40,
|
||||
};
|
||||
enum{
|
||||
// flags going to packet[13] (H107 Plus series)
|
||||
HUBSAN_FLAG_SNAPSHOT = 0x01,
|
||||
HUBSAN_FLAG_FLIP_PLUS = 0x80,
|
||||
};
|
||||
enum{
|
||||
// flags going to packet[9] (H501S)
|
||||
FLAG_H501_VIDEO = 0x01,
|
||||
FLAG_H501_LED = 0x04,
|
||||
FLAG_H501_RTH = 0x20,
|
||||
FLAG_H501_HEADLESS1 = 0x40,
|
||||
FLAG_H501_GPS_HOLD = 0x80,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[13] (H501S)
|
||||
FLAG_H501_SNAPSHOT = 0x01,
|
||||
FLAG_H501_HEADLESS2 = 0x02,
|
||||
FLAG_H501_ALT_HOLD = 0x08,
|
||||
};
|
||||
|
||||
|
||||
uint32_t sessionid,id_data;
|
||||
|
||||
@ -76,7 +103,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
||||
packet[3] = (sessionid >> 16) & 0xFF;
|
||||
packet[4] = (sessionid >> 8) & 0xFF;
|
||||
packet[5] = (sessionid >> 0) & 0xFF;
|
||||
if(id_data == ID_NORMAL)
|
||||
if(id_data == ID_NORMAL && sub_protocol != FORMAT_H501)
|
||||
{
|
||||
packet[6] = 0x08;
|
||||
packet[7] = 0xe4;
|
||||
@ -89,7 +116,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
||||
packet[13] = 0x26;
|
||||
packet[14] = 0x79;
|
||||
}
|
||||
else
|
||||
else if(id_data == ID_PLUS || sub_protocol == FORMAT_H501)
|
||||
{ //ID_PLUS
|
||||
if(phase >= BIND_3)
|
||||
{
|
||||
@ -109,6 +136,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
||||
static void __attribute__((unused)) hubsan_build_packet()
|
||||
{
|
||||
static uint8_t vtx_freq = 0;
|
||||
static uint32_t h501_packet = 0;
|
||||
memset(packet, 0, 16);
|
||||
if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D)
|
||||
{
|
||||
@ -127,7 +155,7 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
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(id_data == ID_NORMAL && sub_protocol == FORMAT_H107) // H107/L/C/D, H102D
|
||||
{
|
||||
if( packet_count < 100)
|
||||
{
|
||||
@ -151,21 +179,50 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
packet[13] = 0x26;
|
||||
packet[14] = 0x79;
|
||||
}
|
||||
else
|
||||
{ //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 ?
|
||||
else if( sub_protocol == FORMAT_H301) {
|
||||
if(packet_count < 100) {
|
||||
packet[9] = FLAG_H301_STAB;
|
||||
packet_count++;
|
||||
} else {
|
||||
packet[9] = 0;
|
||||
if(Servo_AUX1) packet[9] |= FLAG_H301_LED;
|
||||
if(Servo_AUX2) packet[9] |= FLAG_H301_STAB;
|
||||
if(Servo_AUX3) packet[9] |= FLAG_H301_RTH;
|
||||
if(Servo_AUX4) packet[9] |= FLAG_H301_VIDEO; // H102D
|
||||
}
|
||||
packet[10] = 0x18; // ?
|
||||
packet[12] = 0x5c; // ?
|
||||
packet[14] = 0xf6; // ?
|
||||
} else
|
||||
{ //ID_PLUS +FORMAT_H501
|
||||
packet[3] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64;
|
||||
packet[5] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64;
|
||||
packet[7] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64;
|
||||
if( sub_protocol == FORMAT_H501) { // H501S
|
||||
packet[9] = 0x02;
|
||||
if(Servo_AUX1) packet[9] |= HUBSAN_FLAG_FLIP;
|
||||
if(Servo_AUX2) packet[9] |= FLAG_H501_LED;
|
||||
if(Servo_AUX3) packet[9] |= FLAG_H501_RTH;
|
||||
if(Servo_AUX4) packet[9] |= FLAG_H501_VIDEO;
|
||||
if(Servo_AUX5) packet[9] |= FLAG_H501_HEADLESS1;
|
||||
if(Servo_AUX6) packet[9] |= FLAG_H501_GPS_HOLD;
|
||||
packet[13] = 0;
|
||||
if(Servo_AUX5) packet[9] |= FLAG_H501_HEADLESS2;
|
||||
if(Servo_AUX7) packet[9] |= FLAG_H501_ALT_HOLD;
|
||||
if(Servo_AUX8) packet[9] |= FLAG_H501_SNAPSHOT;
|
||||
}
|
||||
else { // H107P/C+/D+
|
||||
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]= sub_protocol == FORMAT_H501 ? 0x1a : 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
|
||||
@ -176,6 +233,18 @@ static void __attribute__((unused)) hubsan_build_packet()
|
||||
packet[13]= 0x00;
|
||||
packet_count++;
|
||||
}
|
||||
if(sub_protocol == FORMAT_H501) {
|
||||
h501_packet++;
|
||||
if(h501_packet == 10) {
|
||||
memset(packet, 0, 16);
|
||||
packet[0] = 0xe8;
|
||||
}
|
||||
else if(h501_packet == 20) {
|
||||
memset(packet, 0, 16);
|
||||
packet[0] = 0xe9;
|
||||
}
|
||||
if(h501_packet >= 20) h501_packet = 0;
|
||||
}
|
||||
}
|
||||
hubsan_update_crc();
|
||||
}
|
||||
@ -205,7 +274,7 @@ uint16_t ReadHubsan()
|
||||
switch(phase) {
|
||||
case BIND_1:
|
||||
bind_count++;
|
||||
if(bind_count >= 20)
|
||||
if(bind_count >= 20 && sub_protocol != FORMAT_H501)
|
||||
{
|
||||
if(id_data == ID_NORMAL)
|
||||
id_data = ID_PLUS;
|
||||
@ -218,7 +287,6 @@ uint16_t ReadHubsan()
|
||||
case BIND_5:
|
||||
case BIND_7:
|
||||
hubsan_build_bind_packet(phase == BIND_7 ? 9 : (phase == BIND_5 ? 1 : phase + 1 - BIND_1));
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteData(16, channel);
|
||||
phase |= WAIT_WRITE;
|
||||
return 3000;
|
||||
@ -253,7 +321,7 @@ uint16_t ReadHubsan()
|
||||
phase = BIND_1;
|
||||
return 4500; //No signal, restart binding procedure. 12msec elapsed since last write
|
||||
}
|
||||
A7105_ReadData();
|
||||
A7105_ReadData(16);
|
||||
phase++;
|
||||
if (phase == BIND_5)
|
||||
A7105_WriteID(((uint32_t)packet[2] << 24) | ((uint32_t)packet[3] << 16) | ((uint32_t)packet[4] << 8) | packet[5]);
|
||||
@ -264,7 +332,7 @@ uint16_t ReadHubsan()
|
||||
phase = BIND_7;
|
||||
return 15000; //22.5msec elapsed since last write
|
||||
}
|
||||
A7105_ReadData();
|
||||
A7105_ReadData(16);
|
||||
if(packet[1] == 9 && id_data == ID_NORMAL) {
|
||||
phase = DATA_1;
|
||||
A7105_WriteReg(A7105_1F_CODE_I, 0x0F);
|
||||
@ -286,8 +354,15 @@ uint16_t ReadHubsan()
|
||||
if( phase == DATA_1)
|
||||
A7105_SetPower(); //Keep transmit power in sync
|
||||
hubsan_build_packet();
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel);
|
||||
u8 ch;
|
||||
if((phase == DATA_5 && id_data == ID_NORMAL) && sub_protocol == FORMAT_H107) {
|
||||
ch = channel + 0x23;
|
||||
}
|
||||
else {
|
||||
ch = channel;
|
||||
}
|
||||
A7105_WriteData( 16, ch);
|
||||
// A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel);
|
||||
if (phase == DATA_5)
|
||||
phase = DATA_1;
|
||||
else
|
||||
@ -314,7 +389,7 @@ uint16_t ReadHubsan()
|
||||
{
|
||||
if( !(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
{ // data received
|
||||
A7105_ReadData();
|
||||
A7105_ReadData(16);
|
||||
if( hubsan_check_integrity() )
|
||||
{
|
||||
v_lipo=packet[13];// hubsan lipo voltage 8bits the real value is h_lipo/10(0x2A=42 -> 4.2V)
|
||||
@ -322,9 +397,10 @@ uint16_t ReadHubsan()
|
||||
}
|
||||
A7105_Strobe(A7105_RX);
|
||||
// Read TX RSSI
|
||||
RSSI_dBm=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less
|
||||
if(RSSI_dBm<0) RSSI_dBm=0;
|
||||
else if(RSSI_dBm>255) RSSI_dBm=255;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -343,7 +419,7 @@ uint16_t ReadHubsan()
|
||||
|
||||
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();
|
||||
A7105_Init();
|
||||
|
||||
sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||
channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)];
|
||||
|
@ -55,10 +55,10 @@ static void __attribute__((unused)) j6pro_build_data_packet()
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t upperbits = 0;
|
||||
uint16_t value;
|
||||
uint16_t value;
|
||||
packet[0] = 0xaa; //FIXME what is this?
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
{
|
||||
value = convert_channel_10b(CH_AETR[i]);
|
||||
packet[i+1] = value & 0xff;
|
||||
upperbits |= (value >> 8) << (i * 2);
|
||||
@ -76,16 +76,16 @@ static void __attribute__((unused)) j6pro_cyrf_init()
|
||||
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
CYRF_SetPower(0x05);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x8a);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
//CYRF_SetPower(0x05);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_SetPower(0x28);
|
||||
CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0e);
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00);
|
||||
CYRF_ConfigDataCode(j6pro_data_code, 16);
|
||||
CYRF_WritePreamble(0x023333);
|
||||
CYRF_WritePreamble(0x333302);
|
||||
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
//Model match
|
||||
@ -94,36 +94,28 @@ static void __attribute__((unused)) j6pro_cyrf_init()
|
||||
|
||||
static void __attribute__((unused)) cyrf_bindinit()
|
||||
{
|
||||
/* Use when binding */
|
||||
//0.060470# 03 2f
|
||||
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
|
||||
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code);
|
||||
CYRF_ConfigCRCSeed(0x0000);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
||||
//0.061511# 13 20
|
||||
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
//0.062684# 0f 05
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
//0.062792# 0f 05
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
j6pro_build_bind_packet(); //01 01 e9 49 ec a9 c4 c1 ff
|
||||
//CYRF_WriteDataPacketLen(packet, 0x09);
|
||||
/* Use when binding */
|
||||
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
|
||||
//CYRF_ConfigRFChannel(0x52);
|
||||
CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code);
|
||||
CYRF_ConfigCRCSeed(0x0000);
|
||||
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
//CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
|
||||
//CYRF_ConfigRFChannel(0x52);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
//CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
j6pro_build_bind_packet();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) cyrf_datainit()
|
||||
{
|
||||
/* Use when already bound */
|
||||
//0.094007# 0f 05
|
||||
uint8_t sop_idx = (0xff & (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[5])) % 19;
|
||||
uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
||||
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]);
|
||||
CYRF_ConfigCRCSeed(crc);
|
||||
/* Use when already bound */
|
||||
uint8_t sop_idx = (0xff & (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[5])) % 19;
|
||||
uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
||||
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]);
|
||||
CYRF_ConfigCRCSeed(crc);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) j6pro_set_radio_channels()
|
||||
@ -136,10 +128,10 @@ static void __attribute__((unused)) j6pro_set_radio_channels()
|
||||
|
||||
uint16_t ReadJ6Pro()
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t start;
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
{
|
||||
case J6PRO_BIND:
|
||||
cyrf_bindinit();
|
||||
phase = J6PRO_BIND_01;
|
||||
@ -147,9 +139,7 @@ uint16_t ReadJ6Pro()
|
||||
case J6PRO_BIND_01:
|
||||
CYRF_ConfigRFChannel(0x52);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
//0.062684# 0f 05
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
//0.062684# 0f 05
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_WriteDataPacketLen(packet, 0x09);
|
||||
phase = J6PRO_BIND_03_START;
|
||||
return 3000; //3msec
|
||||
@ -160,8 +150,8 @@ uint16_t ReadJ6Pro()
|
||||
break;
|
||||
CYRF_ConfigRFChannel(0x53);
|
||||
CYRF_SetTxRxMode(RX_EN);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
||||
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
|
||||
phase = J6PRO_BIND_03_CHECK;
|
||||
return 30000; //30msec
|
||||
case J6PRO_BIND_03_CHECK:
|
||||
@ -201,7 +191,7 @@ uint16_t ReadJ6Pro()
|
||||
case J6PRO_BIND_05_4:
|
||||
case J6PRO_BIND_05_5:
|
||||
case J6PRO_BIND_05_6:
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_WriteDataPacketLen(packet, 0x0f);
|
||||
phase = phase + 1;
|
||||
return 4600; //4.6msec
|
||||
@ -212,7 +202,7 @@ uint16_t ReadJ6Pro()
|
||||
phase = J6PRO_CHAN_1;
|
||||
case J6PRO_CHAN_1:
|
||||
//Keep transmit power updated
|
||||
CYRF_SetPower(0);
|
||||
CYRF_SetPower(0x28);
|
||||
j6pro_build_data_packet();
|
||||
//return 3400;
|
||||
case J6PRO_CHAN_2:
|
||||
@ -237,12 +227,10 @@ uint16_t initJ6Pro()
|
||||
{
|
||||
j6pro_cyrf_init();
|
||||
|
||||
if(IS_AUTOBIND_FLAG_on) {
|
||||
if(IS_AUTOBIND_FLAG_on)
|
||||
phase = J6PRO_BIND;
|
||||
}
|
||||
else {
|
||||
else
|
||||
phase = J6PRO_CHANSEL;
|
||||
}
|
||||
return 2400;
|
||||
}
|
||||
|
||||
|
@ -246,11 +246,7 @@ static void __attribute__((unused)) kn_init()
|
||||
|
||||
NRF24L01_Initialize();
|
||||
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
||||
=======
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
@ -263,11 +259,7 @@ static void __attribute__((unused)) kn_init()
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||
// Enable: Dynamic Payload Length to enable PCF
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL));
|
||||
=======
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL));
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
||||
NRF24L01_SetPower();
|
||||
|
||||
|
5468
Multiprotocol/Lua Generateur.htm
Normal file
5468
Multiprotocol/Lua Generateur.htm
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
<<<<<<< HEAD
|
||||
// compatible with MJX WLH08, X600, X800, H26D
|
||||
=======
|
||||
// compatible with MJX WLH08, X600, X800, H26D, Eachine E010
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
|
||||
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
@ -30,20 +26,17 @@
|
||||
#define MJXQ_RF_NUM_CHANNELS 4
|
||||
#define MJXQ_ADDRESS_LENGTH 5
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
||||
const uint8_t PROGMEM MJXQ_map_rfchan[][4] = {
|
||||
{0x0A, 0x46, 0x3A, 0x42},
|
||||
{0x0A, 0x3C, 0x36, 0x3F},
|
||||
{0x0A, 0x43, 0x36, 0x3F} };
|
||||
const uint8_t PROGMEM MJXQ_map_txid[][3] = {
|
||||
{0xF8, 0x4F, 0x1C},
|
||||
{0xC8, 0x6E, 0x02},
|
||||
{0x48, 0x6A, 0x40} };
|
||||
const uint8_t PROGMEM MJXQ_map_rfchan[][4] = {
|
||||
{0x0A, 0x46, 0x3A, 0x42},
|
||||
{0x0A, 0x3C, 0x36, 0x3F},
|
||||
{0x0A, 0x43, 0x36, 0x3F} };
|
||||
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
||||
#define MJXQ_PAN_DOWN 0x08
|
||||
#define MJXQ_PAN_UP 0x04
|
||||
@ -57,16 +50,6 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
||||
packet_count++;
|
||||
if(packet_count & MJXQ_PAN_TILT_COUNT)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if(Servo_AUX8)
|
||||
pan=MJXQ_PAN_UP;
|
||||
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
||||
pan=MJXQ_PAN_DOWN;
|
||||
if(Servo_data[AUX9]>PPM_MIN_COMMAND)
|
||||
pan=MJXQ_TILT_UP;
|
||||
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
||||
pan=MJXQ_TILT_DOWN;
|
||||
=======
|
||||
if(Servo_data[AUX8]>PPM_MAX_COMMAND)
|
||||
pan=MJXQ_PAN_UP;
|
||||
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
||||
@ -75,7 +58,6 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
||||
pan+=MJXQ_TILT_UP;
|
||||
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
||||
pan+=MJXQ_TILT_DOWN;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
return pan;
|
||||
}
|
||||
@ -86,17 +68,10 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
packet[0] = convert_channel_8b(THROTTLE);
|
||||
packet[1] = convert_channel_s8b(RUDDER);
|
||||
packet[4] = 0x40; // rudder does not work well with dyntrim
|
||||
<<<<<<< HEAD
|
||||
packet[2] = convert_channel_s8b(ELEVATOR);
|
||||
packet[5] = MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||
packet[3] = convert_channel_s8b(AILERON);
|
||||
packet[6] = MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
||||
=======
|
||||
packet[2] = 0x80 ^ convert_channel_s8b(ELEVATOR);
|
||||
packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||
packet[3] = convert_channel_s8b(AILERON);
|
||||
packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet[7] = rx_tx_addr[0];
|
||||
packet[8] = rx_tx_addr[1];
|
||||
packet[9] = rx_tx_addr[2];
|
||||
@ -115,16 +90,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
// Servo_AUX5 HEADLESS
|
||||
// Servo_AUX6 RTH
|
||||
// Servo_AUX7 AUTOFLIP // X800, X600
|
||||
// Servo_AUX8 ARM // H26WH
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case H26D:
|
||||
case H26WH:
|
||||
packet[10]=MJXQ_pan_tilt_value();
|
||||
// fall through on purpose - no break
|
||||
case WLH08:
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
case E010:
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
||||
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
||||
if (!bind)
|
||||
@ -135,16 +109,13 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
| GET_FLAG(Servo_AUX4, 0x10) //VIDEO
|
||||
| GET_FLAG(!Servo_AUX2, 0x20); // air/ground mode
|
||||
}
|
||||
if (sub_protocol == H26WH) {
|
||||
packet[10] &= ~0x40;
|
||||
packet[14] &= ~0x24;
|
||||
packet[14] |= GET_FLAG(Servo_AUX2, 0x04);
|
||||
}
|
||||
break;
|
||||
case X600:
|
||||
<<<<<<< HEAD
|
||||
if(Servo_AUX5) //HEADLESS
|
||||
{ // driven trims cause issues when headless is enabled
|
||||
packet[5] = 0x40;
|
||||
packet[6] = 0x40;
|
||||
}
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED
|
||||
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
|
||||
if (!bind)
|
||||
@ -175,14 +146,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
packet[15] = sum;
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
if (sub_protocol == H26D)
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
else
|
||||
<<<<<<< HEAD
|
||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
=======
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
switch (Model.proto_opts[PROTOOPTS_FORMAT]) {
|
||||
case H26D:
|
||||
case H26WH:
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
break;
|
||||
default:
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
break;
|
||||
}
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||
@ -190,10 +162,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
if (sub_protocol == H26D)
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
else
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
switch (Model.proto_opts[PROTOOPTS_FORMAT]) {
|
||||
case H26D:
|
||||
case H26WH:
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
break;
|
||||
default:
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
@ -202,31 +179,26 @@ static void __attribute__((unused)) MJXQ_init()
|
||||
{
|
||||
uint8_t addr[MJXQ_ADDRESS_LENGTH];
|
||||
memcpy(addr, "\x6d\x6a\x77\x77\x77", MJXQ_ADDRESS_LENGTH);
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if (sub_protocol == WLH08)
|
||||
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
|
||||
else
|
||||
<<<<<<< HEAD
|
||||
if (sub_protocol == H26D)
|
||||
=======
|
||||
if (sub_protocol == H26D || sub_protocol == E010)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH || sub_protocol == E010)
|
||||
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
|
||||
else
|
||||
{
|
||||
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
|
||||
<<<<<<< HEAD
|
||||
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_RF_NUM_CHANNELS);
|
||||
=======
|
||||
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_ADDRESS_LENGTH);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if (sub_protocol == H26D)
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
|
||||
}
|
||||
else
|
||||
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
|
||||
|
||||
@ -237,63 +209,39 @@ static void __attribute__((unused)) MJXQ_init()
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // rx pipe 0 (used only for blue board)
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
=======
|
||||
if (sub_protocol == E010)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K
|
||||
else
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MJXQ_init2()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
||||
static const uint8_t rf_map[][4] = {
|
||||
{0x0A, 0x46, 0x3A, 0x42},
|
||||
{0x0A, 0x3C, 0x36, 0x3F},
|
||||
{0x0A, 0x43, 0x36, 0x3F} };
|
||||
if (sub_protocol == H26D)
|
||||
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
||||
else
|
||||
if (sub_protocol == WLH08)
|
||||
memcpy(hopping_frequency, rf_map[rx_tx_addr[0]%3], MJXQ_RF_NUM_CHANNELS);
|
||||
=======
|
||||
if (sub_protocol == H26D)
|
||||
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
||||
else
|
||||
if (sub_protocol != WLH08 && sub_protocol != E010)
|
||||
for(uint8_t i=0;i<MJXQ_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]=pgm_read_byte_near( &MJXQ_map_rfchan[rx_tx_addr[4]%3][i] );
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
hopping_frequency[i]=pgm_read_byte_near( &MJXQ_map_rfchan[rx_tx_addr[3]%3][i] );
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MJXQ_initialize_txid()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
||||
static const uint8_t tx_map[][3]={
|
||||
{0xF8, 0x4F, 0x1C},
|
||||
{0xC8, 0x6E, 0x02},
|
||||
{0x48, 0x6A, 0x40} };
|
||||
if (sub_protocol == WLH08)
|
||||
rx_tx_addr[0]&=0xF8; // txid must be multiple of 8
|
||||
else
|
||||
memcpy(rx_tx_addr,tx_map[rx_tx_addr[0]%3],3);
|
||||
=======
|
||||
rx_tx_addr[0]&=0xF8;
|
||||
if (sub_protocol == E010)
|
||||
rx_tx_addr[2]=rx_tx_addr[3]; // Make use of RX_Num
|
||||
if (sub_protocol == H26WH)
|
||||
{
|
||||
memcpy(txid, "\xa4\x03\x00", sizeof(txid));
|
||||
}
|
||||
else if (sub_protocol == E010)
|
||||
{
|
||||
rx_tx_addr[1]=(rx_tx_addr[1]&0xF0)|0x0C;
|
||||
rx_tx_addr[2]&=0xF0;
|
||||
rx_tx_addr[2]<<=4; // Make use of RX_Num
|
||||
}
|
||||
else
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[4]%3][i] );
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[3]%3][i] );
|
||||
}
|
||||
|
||||
uint16_t MJXQ_callback()
|
||||
|
@ -12,11 +12,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
<<<<<<< HEAD
|
||||
// compatible with MT99xx, Eachine H7, Yi Zhan i6S
|
||||
=======
|
||||
// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
|
||||
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
@ -41,8 +37,6 @@ enum{
|
||||
FLAG_MT_FLIP = 0x80,
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
enum{
|
||||
// flags going to packet[6] (LS)
|
||||
FLAG_LS_INVERT = 0x01,
|
||||
@ -53,49 +47,18 @@ enum{
|
||||
FLAG_LS_FLIP = 0x80,
|
||||
};
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
enum {
|
||||
MT99XX_INIT = 0,
|
||||
MT99XX_BIND,
|
||||
MT99XX_DATA
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) MT99XX_send_packet()
|
||||
{
|
||||
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
||||
const uint8_t mys_byte[] = {
|
||||
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
||||
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
||||
};
|
||||
static uint8_t yz_seq_num=0;
|
||||
|
||||
if(sub_protocol != YZ)
|
||||
{ // MT99XX & H7
|
||||
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0xE1); // throttle
|
||||
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder
|
||||
packet[2] = convert_channel_8b_scale(AILERON ,0x00,0xE1); // aileron
|
||||
packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator
|
||||
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
|
||||
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
|
||||
packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP )
|
||||
| GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT )
|
||||
| GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO );
|
||||
if(sub_protocol==MT99)
|
||||
packet[6] |= 0x40 | FLAG_MT_RATE2;
|
||||
else
|
||||
packet[6] |= FLAG_MT_RATE1; // max rate on H7
|
||||
// todo: mys_byte = next channel index ?
|
||||
// low nibble: index in chan list ?
|
||||
// high nibble: 0->start from start of list, 1->start from end of list ?
|
||||
packet[7] = mys_byte[hopping_frequency_no];
|
||||
=======
|
||||
const uint8_t h7_mys_byte[] = {
|
||||
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
||||
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
||||
};
|
||||
|
||||
static const u8 ls_mys_byte[] = {
|
||||
static const uint8_t ls_mys_byte[] = {
|
||||
0x05, 0x15, 0x25, 0x06, 0x16, 0x26,
|
||||
0x07, 0x17, 0x27, 0x00, 0x10, 0x20,
|
||||
0x01, 0x11, 0x21, 0x02, 0x12, 0x22,
|
||||
@ -138,7 +101,6 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
ls_counter=0;
|
||||
}
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
uint8_t result=checksum_offset;
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
result += packet[i];
|
||||
@ -147,15 +109,9 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
else
|
||||
{ // YZ
|
||||
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
|
||||
<<<<<<< HEAD
|
||||
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0x64); // rudder
|
||||
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
||||
packet[3] = convert_channel_8b_scale(AILERON ,0x00,0x64); // aileron
|
||||
=======
|
||||
packet[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder
|
||||
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
||||
packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
if(packet_count++ >= 23)
|
||||
{
|
||||
yz_seq_num ++;
|
||||
@ -176,14 +132,10 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
packet[8] = 0xff;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
||||
=======
|
||||
if(sub_protocol == LS)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
||||
@ -201,16 +153,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
static void __attribute__((unused)) MT99XX_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
=======
|
||||
if(sub_protocol == YZ)
|
||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
@ -222,31 +169,18 @@ static void __attribute__((unused)) MT99XX_init()
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
|
||||
<<<<<<< HEAD
|
||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) | (sub_protocol == YZ ? BV(XN297_UNSCRAMBLED):0) );
|
||||
|
||||
XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
|
||||
=======
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) );
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
rx_tx_addr[3] = 0xCC;
|
||||
rx_tx_addr[4] = 0xCC;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
if(sub_protocol == YZ)
|
||||
{
|
||||
rx_tx_addr[0] = 0x53; // test (SB id)
|
||||
rx_tx_addr[1] = 0x00;
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
checksum_offset = (rx_tx_addr[0] + rx_tx_addr[1]) & 0xff;
|
||||
=======
|
||||
rx_tx_addr[2] = 0x00;
|
||||
}
|
||||
else
|
||||
@ -255,7 +189,6 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
else //MT99 & H7
|
||||
rx_tx_addr[2] = 0x00;
|
||||
checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
|
||||
}
|
||||
|
||||
@ -267,26 +200,16 @@ uint16_t MT99XX_callback()
|
||||
{
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
rx_tx_addr[2] = 0x00;
|
||||
rx_tx_addr[3] = 0xCC;
|
||||
rx_tx_addr[4] = 0xCC;
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// set tx address for data packets
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
=======
|
||||
if(sub_protocol == LS)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet
|
||||
@ -313,25 +236,6 @@ uint16_t initMT99XX(void)
|
||||
MT99XX_init();
|
||||
|
||||
packet[0] = 0x20;
|
||||
<<<<<<< HEAD
|
||||
if(sub_protocol!=YZ)
|
||||
{ // MT99 & H7
|
||||
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x03;
|
||||
packet[3] = 0x25;
|
||||
}
|
||||
else
|
||||
{ // YZ
|
||||
packet_period = MT99XX_PACKET_PERIOD_YZ;
|
||||
packet[1] = 0x15;
|
||||
packet[2] = 0x05;
|
||||
packet[3] = 0x06;
|
||||
}
|
||||
packet[4] = rx_tx_addr[0]; // 1st byte for data state tx address
|
||||
packet[5] = rx_tx_addr[1]; // 2nd byte for data state tx address (always 0x00 on Yi Zhan ?)
|
||||
packet[6] = 0x00; // 3rd byte for data state tx address (always 0x00 ?)
|
||||
=======
|
||||
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||
switch(sub_protocol)
|
||||
{ // MT99 & H7
|
||||
@ -356,7 +260,6 @@ uint16_t initMT99XX(void)
|
||||
packet[4] = rx_tx_addr[0];
|
||||
packet[5] = rx_tx_addr[1];
|
||||
packet[6] = rx_tx_addr[2];
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet[7] = checksum_offset; // checksum offset
|
||||
packet[8] = 0xAA; // fixed
|
||||
packet_count=0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define ARDUINO_AVR_PRO 1
|
||||
//#define __AVR_ATmega328P__ 1
|
||||
|
||||
#define XMEGA 1
|
||||
#define ORANGE_TX 1
|
||||
|
||||
// For BLUE module use:
|
||||
//#define DSM_BLUE
|
BIN
Multiprotocol/Multiprotocol 2.zip
Normal file
BIN
Multiprotocol/Multiprotocol 2.zip
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -14,9 +14,7 @@
|
||||
*/
|
||||
|
||||
|
||||
//---------------------------
|
||||
// AVR nrf chip bitbang SPI functions
|
||||
//---------------------------
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
|
||||
@ -94,6 +92,14 @@ static void NRF24L01_ReadPayload(uint8_t * data, uint8_t length)
|
||||
data[i] = SPI_Read();
|
||||
NRF_CSN_on;
|
||||
}
|
||||
static uint8_t NRF24L01_GetDynamicPayloadSize(void)
|
||||
{
|
||||
NRF_CSN_off;
|
||||
SPI_Write(R_RX_PL_WID);
|
||||
uint8_t res = SPI_Read();
|
||||
NRF_CSN_on;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void NRF24L01_Strobe(uint8_t state)
|
||||
{
|
||||
@ -181,7 +187,8 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||
NRF_CE_on;
|
||||
}
|
||||
else
|
||||
if (mode == RX_EN) {
|
||||
if (mode == RX_EN)
|
||||
{
|
||||
NRF_CE_off;
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // reset the flag(s)
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // switch to RX mode
|
||||
@ -234,11 +241,7 @@ uint8_t NRF24L01_packet_ack()
|
||||
|
||||
///////////////
|
||||
// XN297 emulation layer
|
||||
<<<<<<< HEAD
|
||||
uint8_t xn297_scramble_enabled;
|
||||
=======
|
||||
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
uint8_t xn297_addr_len;
|
||||
uint8_t xn297_tx_addr[5];
|
||||
uint8_t xn297_rx_addr[5];
|
||||
@ -251,16 +254,6 @@ static const uint8_t xn297_scramble[] = {
|
||||
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
||||
0x8e, 0xc5, 0x2f};
|
||||
|
||||
<<<<<<< HEAD
|
||||
const uint16_t PROGMEM xn297_crc_xorout[] = {
|
||||
0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf,
|
||||
0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15,
|
||||
0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9,
|
||||
0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7,
|
||||
0xb798, 0x5133, 0x67db, 0xd94e};
|
||||
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||
@ -334,23 +327,16 @@ void XN297_SetRXAddr(const uint8_t* addr, uint8_t len)
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5);
|
||||
}
|
||||
|
||||
void XN297_Configure(uint16_t flags)
|
||||
void XN297_Configure(uint8_t flags)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
xn297_scramble_enabled = !(flags & BV(XN297_UNSCRAMBLED));
|
||||
xn297_crc = !!(flags & BV(NRF24L01_00_EN_CRC));
|
||||
flags &= ~(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
||||
=======
|
||||
xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC));
|
||||
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
||||
}
|
||||
|
||||
void XN297_SetScrambledMode(const u8 mode)
|
||||
void XN297_SetScrambledMode(const uint8_t mode)
|
||||
{
|
||||
xn297_scramble_enabled = mode;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
@ -412,32 +398,6 @@ void XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
// End of XN297 emulation
|
||||
|
||||
///////////////
|
||||
<<<<<<< HEAD
|
||||
// LT8910 emulation layer
|
||||
uint8_t LT8910_buffer[64];
|
||||
uint8_t LT8910_buffer_start;
|
||||
uint16_t LT8910_buffer_overhead_bits;
|
||||
uint8_t LT8910_addr[8];
|
||||
uint8_t LT8910_addr_size;
|
||||
uint8_t LT8910_Preamble_Len;
|
||||
uint8_t LT8910_Tailer_Len;
|
||||
uint8_t LT8910_CRC_Initial_Data;
|
||||
uint8_t LT8910_Flags;
|
||||
#define LT8910_CRC_ON 6
|
||||
#define LT8910_SCRAMBLE_ON 5
|
||||
#define LT8910_PACKET_LENGTH_EN 4
|
||||
#define LT8910_DATA_PACKET_TYPE_1 3
|
||||
#define LT8910_DATA_PACKET_TYPE_0 2
|
||||
#define LT8910_FEC_TYPE_1 1
|
||||
#define LT8910_FEC_TYPE_0 0
|
||||
|
||||
void LT8910_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uint8_t crc_init)
|
||||
{
|
||||
//Preamble 1 to 8 bytes
|
||||
LT8910_Preamble_Len=preamble_len;
|
||||
//Trailer 4 to 18 bits
|
||||
LT8910_Tailer_Len=trailer_len;
|
||||
=======
|
||||
// LT8900 emulation layer
|
||||
uint8_t LT8900_buffer[64];
|
||||
uint8_t LT8900_buffer_start;
|
||||
@ -462,37 +422,23 @@ void LT8900_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uin
|
||||
LT8900_Preamble_Len=preamble_len;
|
||||
//Trailer 4 to 18 bits
|
||||
LT8900_Tailer_Len=trailer_len;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
//Flags
|
||||
// CRC_ON: 1 on, 0 off
|
||||
// SCRAMBLE_ON: 1 on, 0 off
|
||||
// PACKET_LENGTH_EN: 1 1st byte of payload is payload size
|
||||
// DATA_PACKET_TYPE: 00 NRZ, 01 Manchester, 10 8bit/10bit line code, 11 interleave data type
|
||||
// FEC_TYPE: 00 No FEC, 01 FEC13, 10 FEC23, 11 reserved
|
||||
<<<<<<< HEAD
|
||||
LT8910_Flags=flags;
|
||||
//CRC init constant
|
||||
LT8910_CRC_Initial_Data=crc_init;
|
||||
}
|
||||
|
||||
void LT8910_SetChannel(uint8_t channel)
|
||||
=======
|
||||
LT8900_Flags=flags;
|
||||
//CRC init constant
|
||||
LT8900_CRC_Initial_Data=crc_init;
|
||||
}
|
||||
|
||||
void LT8900_SetChannel(uint8_t channel)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, channel +2); //NRF24L01 is 2400+channel but LT8900 is 2402+channel
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
void LT8910_SetTxRxMode(enum TXRX_State mode)
|
||||
=======
|
||||
void LT8900_SetTxRxMode(enum TXRX_State mode)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
if(mode == TX_EN)
|
||||
{
|
||||
@ -518,35 +464,12 @@ void LT8900_SetTxRxMode(enum TXRX_State mode)
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
void LT8910_BuildOverhead()
|
||||
=======
|
||||
void LT8900_BuildOverhead()
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
uint8_t pos;
|
||||
|
||||
//Build overhead
|
||||
//preamble
|
||||
<<<<<<< HEAD
|
||||
memset(LT8910_buffer,LT8910_addr[0]&0x01?0xAA:0x55,LT8910_Preamble_Len-1);
|
||||
pos=LT8910_Preamble_Len-1;
|
||||
//address
|
||||
for(uint8_t i=0;i<LT8910_addr_size;i++)
|
||||
{
|
||||
LT8910_buffer[pos]=bit_reverse(LT8910_addr[i]);
|
||||
pos++;
|
||||
}
|
||||
//trailer
|
||||
memset(LT8910_buffer+pos,(LT8910_buffer[pos-1]&0x01)==0?0xAA:0x55,3);
|
||||
LT8910_buffer_overhead_bits=pos*8+LT8910_Tailer_Len;
|
||||
//nrf address length max is 5
|
||||
pos+=LT8910_Tailer_Len/8;
|
||||
LT8910_buffer_start=pos>5?5:pos;
|
||||
}
|
||||
|
||||
void LT8910_SetAddress(uint8_t *address,uint8_t addr_size)
|
||||
=======
|
||||
memset(LT8900_buffer,LT8900_addr[0]&0x01?0xAA:0x55,LT8900_Preamble_Len-1);
|
||||
pos=LT8900_Preamble_Len-1;
|
||||
//address
|
||||
@ -564,33 +487,10 @@ void LT8910_SetAddress(uint8_t *address,uint8_t addr_size)
|
||||
}
|
||||
|
||||
void LT8900_SetAddress(uint8_t *address,uint8_t addr_size)
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
uint8_t addr[5];
|
||||
|
||||
//Address size (SyncWord) 2 to 8 bytes, 16/32/48/64 bits
|
||||
<<<<<<< HEAD
|
||||
LT8910_addr_size=addr_size;
|
||||
memcpy(LT8910_addr,address,LT8910_addr_size);
|
||||
|
||||
//Build overhead
|
||||
LT8910_BuildOverhead();
|
||||
|
||||
//Set NRF RX&TX address based on overhead content
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, LT8910_buffer_start-2);
|
||||
for(uint8_t i=0;i<LT8910_buffer_start;i++) // reverse bytes order
|
||||
addr[i]=LT8910_buffer[LT8910_buffer_start-i-1];
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, addr,LT8910_buffer_start);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr,LT8910_buffer_start);
|
||||
}
|
||||
|
||||
uint8_t LT8910_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t i,pos=0,shift,end,buffer[32];
|
||||
unsigned int crc=LT8910_CRC_Initial_Data,a;
|
||||
pos=LT8910_buffer_overhead_bits/8-LT8910_buffer_start;
|
||||
end=pos+len+(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN)?1:0)+(LT8910_Flags&_BV(LT8910_CRC_ON)?2:0);
|
||||
=======
|
||||
LT8900_addr_size=addr_size;
|
||||
for (uint8_t i = 0; i < addr_size; i++)
|
||||
LT8900_addr[i] = address[addr_size-1-i];
|
||||
@ -612,22 +512,14 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
unsigned int crc=LT8900_CRC_Initial_Data,a;
|
||||
pos=LT8900_buffer_overhead_bits/8-LT8900_buffer_start;
|
||||
end=pos+len+(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN)?1:0)+(LT8900_Flags&_BV(LT8900_CRC_ON)?2:0);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
//Read payload
|
||||
NRF24L01_ReadPayload(buffer,end+1);
|
||||
//Check address + trail
|
||||
for(i=0;i<pos;i++)
|
||||
<<<<<<< HEAD
|
||||
if(LT8910_buffer[LT8910_buffer_start+i]!=buffer[i])
|
||||
return 0; // wrong address...
|
||||
//Shift buffer to remove trail bits
|
||||
shift=LT8910_buffer_overhead_bits&0x7;
|
||||
=======
|
||||
if(LT8900_buffer[LT8900_buffer_start+i]!=buffer[i])
|
||||
return 0; // wrong address...
|
||||
//Shift buffer to remove trail bits
|
||||
shift=LT8900_buffer_overhead_bits&0x7;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
for(i=pos;i<end;i++)
|
||||
{
|
||||
a=(buffer[i]<<8)+buffer[i+1];
|
||||
@ -635,11 +527,7 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
buffer[i]=(a>>8)&0xFF;
|
||||
}
|
||||
//Check len
|
||||
<<<<<<< HEAD
|
||||
if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN))
|
||||
=======
|
||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
crc=crc16_update(crc,buffer[pos]);
|
||||
if(bit_reverse(len)!=buffer[pos++])
|
||||
@ -652,11 +540,7 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
msg[i]=bit_reverse(buffer[pos++]);
|
||||
}
|
||||
//Check CRC
|
||||
<<<<<<< HEAD
|
||||
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
||||
=======
|
||||
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
if(buffer[pos++]!=((crc>>8)&0xFF)) return 0; // wrong CRC...
|
||||
if(buffer[pos]!=(crc&0xFF)) return 0; // wrong CRC...
|
||||
@ -665,21 +549,12 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
void LT8910_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
unsigned int crc=LT8910_CRC_Initial_Data,a,mask;
|
||||
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
||||
//Add packet len
|
||||
if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN))
|
||||
=======
|
||||
void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
unsigned int crc=LT8900_CRC_Initial_Data,a,mask;
|
||||
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
||||
//Add packet len
|
||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
tmp=bit_reverse(len);
|
||||
buffer[pos++]=tmp;
|
||||
@ -693,27 +568,12 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||
crc=crc16_update(crc,tmp);
|
||||
}
|
||||
//Add CRC
|
||||
<<<<<<< HEAD
|
||||
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
||||
=======
|
||||
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
{
|
||||
buffer[pos++]=crc>>8;
|
||||
buffer[pos++]=crc;
|
||||
}
|
||||
//Shift everything to fit behind the trailer (4 to 18 bits)
|
||||
<<<<<<< HEAD
|
||||
shift=LT8910_buffer_overhead_bits&0x7;
|
||||
pos_final=LT8910_buffer_overhead_bits/8;
|
||||
mask=~(0xFF<<(8-shift));
|
||||
LT8910_buffer[pos_final+pos]=0xFF;
|
||||
for(i=pos-1;i!=0xFF;i--)
|
||||
{
|
||||
a=buffer[i]<<(8-shift);
|
||||
LT8910_buffer[pos_final+i]=(LT8910_buffer[pos_final+i]&mask>>8)|a>>8;
|
||||
LT8910_buffer[pos_final+i+1]=(LT8910_buffer[pos_final+i+1]&mask)|a;
|
||||
=======
|
||||
shift=LT8900_buffer_overhead_bits&0x7;
|
||||
pos_final=LT8900_buffer_overhead_bits/8;
|
||||
mask=~(0xFF<<(8-shift));
|
||||
@ -723,17 +583,11 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||
a=buffer[i]<<(8-shift);
|
||||
LT8900_buffer[pos_final+i]=(LT8900_buffer[pos_final+i]&mask>>8)|a>>8;
|
||||
LT8900_buffer[pos_final+i+1]=(LT8900_buffer[pos_final+i+1]&mask)|a;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
if(shift)
|
||||
pos++;
|
||||
//Send everything
|
||||
<<<<<<< HEAD
|
||||
NRF24L01_WritePayload(LT8910_buffer+LT8910_buffer_start,pos_final+pos-LT8910_buffer_start);
|
||||
}
|
||||
// End of LT8910 emulation
|
||||
=======
|
||||
NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start);
|
||||
}
|
||||
// End of LT8900 emulation
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#endif
|
||||
|
@ -51,7 +51,7 @@ static void bluefly_init() {
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81
|
||||
|
||||
// 2-bytes CRC, radio on
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // BlueFly - 250kbps
|
||||
NRF24L01_SetPower();
|
||||
@ -63,7 +63,7 @@ static void bluefly_ch_data() {
|
||||
uint32_t temp;
|
||||
int i;
|
||||
for (i = 0; i< 8; ++i) {
|
||||
temp = (uint32_t)Servo_data[ch[i]] * 300/PPM_MAX + 500; // 200-800 range
|
||||
temp = map(limit_channel_100(i),servo_min_100,servo_max_100,200,800); // 200-800 range
|
||||
if (temp < 0)
|
||||
ch_data_bluefly[i] = 0;
|
||||
else if (temp > 1000)
|
||||
@ -140,6 +140,7 @@ static uint16_t bluefly_cb() {
|
||||
}
|
||||
|
||||
static uint16_t BlueFly_setup() {
|
||||
MProtocol_id = (MProtocol_id | ((uint32_t)txid[3]<<32));
|
||||
hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2;
|
||||
bluefly_binding_packet();
|
||||
bluefly_init();
|
||||
|
@ -13,12 +13,6 @@
|
||||
along with Deviation. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NB: Not implemented
|
||||
Uncomment define below to enable telemetry. Also add CFlie protocol to TELEMETRY_SetTypeByProtocol to set type to DSM.
|
||||
#define CFLIE_TELEMETRY
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CFlie_NRF24L01_INO)
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
@ -59,30 +53,15 @@ enum {
|
||||
CFLIE_DATA
|
||||
};
|
||||
|
||||
#ifdef CFLIE_TELEMETRY
|
||||
static const char * const cflie_opts[] = {
|
||||
_tr_noop("Telemetry"), _tr_noop("Off"), _tr_noop("On"), NULL,
|
||||
NULL
|
||||
};
|
||||
enum {
|
||||
PROTOOPTS_TELEMETRY = 0,
|
||||
LAST_PROTO_OPT,
|
||||
};
|
||||
ctassert(LAST_PROTO_OPT <= NUM_PROTO_OPTS, too_many_protocol_opts);
|
||||
|
||||
#define TELEM_OFF 0
|
||||
#define TELEM_ON 1
|
||||
#endif
|
||||
|
||||
#define PACKET_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out
|
||||
#define PACKET_CFLIE_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out
|
||||
|
||||
static uint16_t dbg_cnt = 0;
|
||||
static uint8_t packet_ack() {
|
||||
if (++dbg_cnt > 50) { dbg_cnt = 0; }
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
||||
case BV(NRF24L01_07_TX_DS):
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) {
|
||||
case _BV(NRF24L01_07_TX_DS):
|
||||
return PKT_ACKED;
|
||||
case BV(NRF24L01_07_MAX_RT):
|
||||
case _BV(NRF24L01_07_MAX_RT):
|
||||
return PKT_TIMEOUT;
|
||||
}
|
||||
return PKT_PENDING;
|
||||
@ -97,7 +76,7 @@ static void send_search_packet() {
|
||||
uint8_t buf[1];
|
||||
buf[0] = 0xff;
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT)));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT)));
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
if (rf_channel++ > 125) {
|
||||
@ -119,7 +98,7 @@ static void send_search_packet() {
|
||||
|
||||
NRF24L01_WritePayload(buf, sizeof(buf));
|
||||
|
||||
++packet_counter;
|
||||
++packet_count;
|
||||
}
|
||||
|
||||
// Frac 16.16
|
||||
@ -151,33 +130,39 @@ static void send_cmd_packet() {
|
||||
// Channels in AETR order
|
||||
|
||||
// Roll, aka aileron, float +- 50.0 in degrees
|
||||
// float roll = -(float) Servo_data[AILERON]*50.0/10000;
|
||||
uint32_t f_roll = -Servo_data[AILERON] * FRAC_SCALE / (10000 / 50);
|
||||
uint32_t f_roll = -map(limit_channel_100(AILERON),servo_min_100,servo_max_100,-50,50);
|
||||
|
||||
// Pitch, aka elevator, float +- 50.0 degrees
|
||||
//float pitch = -(float) Servo_data[ELEVATOR]*50.0/10000;
|
||||
uint32_t f_pitch = -Servo_data[ELEVATOR] * FRAC_SCALE / (10000 / 50);
|
||||
uint32_t f_pitch = -map(limit_channel_100(ELEVATOR),servo_min_100,servo_max_100,-50,50);
|
||||
|
||||
// Thrust, aka throttle 0..65535, working range 5535..65535
|
||||
// No space for overshoot here, hard limit Channel3 by -10000..10000
|
||||
uint32_t ch = Servo_data[THROTTLE];
|
||||
if (ch < PPM_MIN) {
|
||||
ch = PPM_MIN;
|
||||
} else if (ch > PPM_MAX) {
|
||||
ch = PPM_MAX;
|
||||
if (ch < servo_min_125) {
|
||||
ch = servo_min_125;
|
||||
} else if (ch > servo_max_125) {
|
||||
ch = servo_max_125;
|
||||
}
|
||||
uint16_t thrust = ch*3L + 35535L;
|
||||
|
||||
// Yaw, aka rudder, float +- 400.0 deg/s
|
||||
// float yaw = -(float) Servo_data[RUDDER]*400.0/10000;
|
||||
uint32_t f_yaw = - Servo_data[RUDDER] * FRAC_SCALE / (10000 / 400);
|
||||
uint32_t f_yaw = - map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,-40,40);
|
||||
frac2float(f_yaw, &yaw);
|
||||
|
||||
// Convert + to X. 181 / 256 = 0.70703125 ~= sqrt(2) / 2
|
||||
uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256;
|
||||
frac2float(f_x_roll, &x_roll);
|
||||
uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256;
|
||||
frac2float(f_x_pitch, &x_pitch);
|
||||
// Switch on/off?
|
||||
if(Servo_AUX1)
|
||||
{
|
||||
frac2float(f_roll, &x_roll);
|
||||
frac2float(f_pitch, &x_pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert + to X. 181 / 256 = 0.70703125 ~= sqrt(2) / 2
|
||||
uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256;
|
||||
frac2float(f_x_roll, &x_roll);
|
||||
uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256;
|
||||
frac2float(f_x_pitch, &x_pitch);
|
||||
}
|
||||
|
||||
int bufptr = 0;
|
||||
buf[bufptr++] = 0x30; // Commander packet to channel 0
|
||||
@ -188,12 +173,12 @@ static void send_cmd_packet() {
|
||||
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT)));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT)));
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
NRF24L01_WritePayload(buf, sizeof(buf));
|
||||
|
||||
++packet_counter;
|
||||
++packet_count;
|
||||
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
@ -203,7 +188,7 @@ static int cflie_init() {
|
||||
|
||||
// CRC, radio on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
// NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
@ -236,21 +221,6 @@ static int cflie_init() {
|
||||
return 50000;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CFLIE_TELEMETRY
|
||||
static void update_telemetry() {
|
||||
static uint8_t frameloss = 0;
|
||||
|
||||
frameloss += NRF24L01_ReadReg(NRF24L01_08_OBSERVE_TX) >> 4;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channel); // reset packet loss counter
|
||||
|
||||
Telemetry.p.dsm.flog.frameloss = frameloss;
|
||||
// Telemetry.p.dsm.flog.volt[0] = read battery voltage from ack payload
|
||||
TELEMETRY_SetUpdated(TELEM_DSM_FLOG_FRAMELOSS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static uint16_t cflie_callback() {
|
||||
switch (phase) {
|
||||
case CFLIE_INIT_SEARCH:
|
||||
@ -264,7 +234,7 @@ static uint16_t cflie_callback() {
|
||||
case CFLIE_SEARCH:
|
||||
switch (packet_ack()) {
|
||||
case PKT_PENDING:
|
||||
return PACKET_CHKTIME; // packet send not yet complete
|
||||
return PACKET_CFLIE_CHKTIME; // packet send not yet complete
|
||||
case PKT_ACKED:
|
||||
phase = CFLIE_DATA;
|
||||
BIND_DONE;
|
||||
@ -275,11 +245,8 @@ static uint16_t cflie_callback() {
|
||||
}
|
||||
break;
|
||||
case CFLIE_DATA:
|
||||
#ifdef CFLIE_TELEMETRY
|
||||
update_telemetry();
|
||||
#endif
|
||||
if (packet_ack() == PKT_PENDING)
|
||||
return PACKET_CHKTIME; // packet send not yet complete
|
||||
return PACKET_CFLIE_CHKTIME; // packet send not yet complete
|
||||
send_cmd_packet();
|
||||
break;
|
||||
}
|
||||
@ -287,31 +254,21 @@ static uint16_t cflie_callback() {
|
||||
}
|
||||
|
||||
|
||||
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
||||
static uint8_t initialize_rx_tx_addr() {
|
||||
static uint16_t Cflie_setup() {
|
||||
rx_tx_addr[0] =
|
||||
rx_tx_addr[1] =
|
||||
rx_tx_addr[2] =
|
||||
rx_tx_addr[3] =
|
||||
rx_tx_addr[4] = 0xE7; // CFlie uses fixed address
|
||||
|
||||
data_rate = NRF24L01_BR_250K;
|
||||
rf_channel = 0;
|
||||
return CFLIE_INIT_SEARCH;
|
||||
// return CFLIE_INIT_DATA;
|
||||
}
|
||||
|
||||
static uint16_t Cflie_setup() {
|
||||
phase = initialize_rx_tx_addr();
|
||||
packet_counter = 0;
|
||||
data_rate = NRF24L01_BR_250K;
|
||||
rf_channel = 0;
|
||||
packet_count = 0;
|
||||
|
||||
int delay = cflie_init();
|
||||
|
||||
#ifdef CFLIE_TELEMETRY
|
||||
memset(&Telemetry, 0, sizeof(Telemetry));
|
||||
TELEMETRY_SetType(TELEM_DSM);
|
||||
#endif
|
||||
if (phase == CFLIE_INIT_SEARCH) { BIND_IN_PROGRESS; }
|
||||
phase = CFLIE_INIT_SEARCH;
|
||||
BIND_IN_PROGRESS;
|
||||
return delay;
|
||||
}
|
||||
|
||||
|
@ -32,15 +32,15 @@ enum {
|
||||
|
||||
|
||||
static uint8_t esky150_packet_ack() {
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
||||
case BV(NRF24L01_07_TX_DS): return PKT_ACKED;
|
||||
case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) {
|
||||
case _BV(NRF24L01_07_TX_DS): return PKT_ACKED;
|
||||
case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||
}
|
||||
return PKT_PENDING;
|
||||
}
|
||||
|
||||
// 2-bytes CRC
|
||||
#define CRC_CONFIG (BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO))
|
||||
#define CRC_CONFIG (_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO))
|
||||
static uint16_t esky150_init() {
|
||||
uint8_t rx_addr[ADDR_esky150_SIZE] = { 0x73, 0x73, 0x74, 0x63 };
|
||||
uint8_t tx_addr[ADDR_esky150_SIZE] = { 0x71, 0x0A, 0x31, 0xF4 };
|
||||
@ -64,7 +64,7 @@ static uint16_t esky150_init() {
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||
// Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL) | BV(NRF2401_1D_EN_ACK_PAY) | BV(NRF2401_1D_EN_DYN_ACK));
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL) | _BV(NRF2401_1D_EN_ACK_PAY) | _BV(NRF2401_1D_EN_DYN_ACK));
|
||||
|
||||
// Delay 50 ms
|
||||
return 50000;
|
||||
@ -80,51 +80,26 @@ static uint16_t esky150_init2() {
|
||||
|
||||
// Turn radio power on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, CRC_CONFIG | BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, CRC_CONFIG | _BV(NRF24L01_00_PWR_UP));
|
||||
// delayMicroseconds(150);
|
||||
return 150;
|
||||
}
|
||||
|
||||
|
||||
static void calc_fh_channels(uint32_t seed) {
|
||||
// Use channels 2..79
|
||||
uint8_t first = seed % 37 + 2;
|
||||
uint8_t second = first + 40;
|
||||
hopping_frequency[0] = first; // 0x22;
|
||||
hopping_frequency[1] = second; // 0x4a;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t convert_channel(uint8_t num) {
|
||||
uint32_t ch = Servo_data[num];
|
||||
if (ch < PPM_MIN) { ch = PPM_MIN; }
|
||||
else if (ch > PPM_MAX) { ch = PPM_MAX; }
|
||||
return (uint8_t) ((ch * 500 / PPM_MAX) + 1500);
|
||||
}
|
||||
static void read_controls(uint8_t* throttle, uint8_t* aileron, uint8_t* elevator, uint8_t* rudder) {
|
||||
*throttle = convert_channel(THROTTLE);
|
||||
*aileron = convert_channel(AILERON);
|
||||
*elevator = convert_channel(ELEVATOR);
|
||||
*rudder = convert_channel(RUDDER);
|
||||
}
|
||||
|
||||
|
||||
static void esky150_send_packet() {
|
||||
uint8_t rf_ch = hopping_frequency[rf_ch_num];
|
||||
rf_ch_num = 1 - rf_ch_num;
|
||||
|
||||
read_controls(&throttle, &aileron, &elevator, &rudder);
|
||||
|
||||
packet[0] = hopping_frequency[0];
|
||||
packet[1] = hopping_frequency[1];
|
||||
packet[2] = (throttle >> 8) & 0xFF;
|
||||
packet[3] = throttle & 0xFF;
|
||||
packet[4] = (aileron >> 8) & 0xFF;
|
||||
packet[5] = aileron & 0xFF;
|
||||
packet[6] = (elevator >> 8) & 0xFF;
|
||||
packet[7] = elevator & 0xFF;
|
||||
packet[8] = (rudder >> 8) & 0xFF;
|
||||
packet[9] = rudder & 0xFF;
|
||||
packet[2] = highByte(Servo_data[THROTTLE]);
|
||||
packet[3] = lowByte(Servo_data[THROTTLE]);
|
||||
packet[4] = highByte(Servo_data[AILERON]);
|
||||
packet[5] = lowByte(Servo_data[AILERON]);
|
||||
packet[6] = highByte(Servo_data[ELEVATOR]);
|
||||
packet[7] = lowByte(Servo_data[ELEVATOR]);
|
||||
packet[8] = highByte(Servo_data[RUDDER]);
|
||||
packet[9] = lowByte(Servo_data[RUDDER]);
|
||||
// Constant values 00 d8 18 f8
|
||||
packet[10] = 0x00;
|
||||
packet[11] = 0xd8;
|
||||
@ -166,6 +141,12 @@ static uint16_t esky150_callback() {
|
||||
static uint16_t esky150_setup() {
|
||||
total_packets = 0;
|
||||
uint16_t timeout = esky150_init();
|
||||
|
||||
// Use channels 2..79
|
||||
uint8_t first = MProtocol_id % 37 + 2;
|
||||
uint8_t second = first + 40;
|
||||
hopping_frequency[0] = first; // 0x22;
|
||||
hopping_frequency[1] = second; // 0x4a;
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ static void config_nrf24l01() {
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // 0:No Auto Acknoledgement; 1:Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // fbl100/v922's packet size = 10, hp100 = 12
|
||||
// 2-bytes CRC, radio off
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||
NRF24L01_SetBitrate(sub_protocol == HP100? NRF24L01_BR_250K:NRF24L01_BR_1M); //hp100:250kbps; fbl100: 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
@ -108,7 +108,7 @@ static void fbl100_build_ch_data() {
|
||||
uint32_t temp;
|
||||
uint8_t i;
|
||||
for (i = 0; i< 8; i++) {
|
||||
temp = (uint32_t)Servo_data[i] * 500/PPM_MAX + 500;
|
||||
temp = (uint32_t)Servo_data[i] -1000;
|
||||
if (i == 2) { temp = 1000 -temp; } // It is clear that fbl100's thro stick is made reversely,so I adjust it here on purposely
|
||||
if (temp < 0) { fbl_data[i] = 0; }
|
||||
else if (temp > 1000) { fbl_data[i] = 1000; }
|
||||
@ -131,11 +131,12 @@ static void hp100_build_ch_data() {
|
||||
uint32_t temp;
|
||||
uint8_t i;
|
||||
for (i = 0; i< 8; i++) {
|
||||
temp = (uint32_t)Servo_data[i] * 300/PPM_MAX + 500;
|
||||
temp=map(limit_channel_100(i),servo_min_100,servo_max_100,200,800);
|
||||
/* temp = (uint32_t)Servo_data[i] * 300/PPM_MAX + 500;
|
||||
if (temp < 0) { temp = 0; }
|
||||
else if (temp > 1000) { temp = 1000; }
|
||||
if (i == 3 || i == 5) { temp = 1000 -temp; } // hp100's rudd and pit channel are made reversely,so I adjust them on purposely
|
||||
|
||||
*/
|
||||
fbl_data[i] = (unsigned int)temp;
|
||||
packet[i] = (uint8_t)fbl_data[i];
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ static void h377_init() {
|
||||
|
||||
// 2-bytes CRC, radio off
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||
NRF24L01_SetBitrate(0); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
@ -100,10 +100,11 @@ static void h377_init() {
|
||||
// H377 channel sequence: AILE ELEV THRO RUDD GEAR PITH, channel data value is from 0 to 1000
|
||||
static void h377_ch_data() {
|
||||
uint32_t temp;
|
||||
uint8_t i;
|
||||
uint8_t i,j;
|
||||
for (i = 0; i< 8; i++) {
|
||||
temp = (uint32_t)Servo_data[i] * 450/PPM_MAX + 500; // max/min servo range is +-125%
|
||||
if (i == 2) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
||||
j=CH_AETR[i];
|
||||
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000); // max/min servo range is +-125%
|
||||
if (j == THROTTLE) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
||||
temp = 1000 -temp;
|
||||
//if (i == 0) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
||||
// temp = 1000 -temp;
|
||||
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
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.
|
||||
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
|
||||
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.
|
||||
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* This protocol is for the HM Hobby HM830 RC Paper Airplane
|
||||
/*
|
||||
This protocol is for the HM Hobby HM830 RC Paper Airplane
|
||||
Protocol spec:
|
||||
Channel data:
|
||||
AA BB CC DD EE FF GG
|
||||
@ -76,7 +77,7 @@ static uint8_t count;
|
||||
static uint8_t rf_ch[] = {0x08, 0x35, 0x12, 0x3f, 0x1c, 0x49, 0x26};
|
||||
static uint8_t bind_addr[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xc2};
|
||||
|
||||
static uint8_t crc8(uint32_t result, uint8_t *data, int len) {
|
||||
static uint8_t HM830_crc8(uint32_t result, uint8_t *data, int len) {
|
||||
int polynomial = 0x01;
|
||||
for(int i = 0; i < len; i++) {
|
||||
result = result ^ data[i];
|
||||
@ -114,26 +115,26 @@ static void HM830_init() {
|
||||
|
||||
static void build_bind_packet_hm830() {
|
||||
for(int i = 0; i < 6; i++) { packet[i] = rx_tx_addr[i]; }
|
||||
packet[6] = crc8(0xa5, packet, 6);
|
||||
packet[6] = HM830_crc8(0xa5, packet, 6);
|
||||
}
|
||||
|
||||
static void build_data_packet() {
|
||||
uint8_t ail_sign = 0, trim_sign = 0;
|
||||
|
||||
throttle = (uint32_t)Servo_data[THROTTLE] * 50 / PPM_MAX + 50;
|
||||
throttle = (uint32_t)map(limit_channel_100(THROTTLE),servo_min_100,servo_max_100,0,100);
|
||||
if (throttle < 0) { throttle = 0; }
|
||||
|
||||
aileron = (uint32_t)Servo_data[AILERON] * 8 / PPM_MAX;
|
||||
aileron = (uint32_t)map(limit_channel_100(AILERON),servo_min_100,servo_max_100,-8,8);
|
||||
if (aileron < 0) { aileron = -aileron; ail_sign = 1; }
|
||||
if (aileron > 7) { aileron = 7; }
|
||||
|
||||
uint8_t turbo = (uint32_t)Servo_data[ELEVATOR] > 0 ? 1 : 0;
|
||||
uint8_t turbo = Servo_data[ELEVATOR] > PPM_SWITCH ? 1 : 0;
|
||||
|
||||
uint8_t trim = ((uint32_t)Servo_data[RUDDER] * 0x1f / PPM_MAX);
|
||||
uint8_t trim = map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,-31,31);
|
||||
if (trim < 0) { trim = -trim; trim_sign = 1; }
|
||||
if (trim > 0x1f) { trim = 0x1f; }
|
||||
|
||||
uint8_t rbutton = (uint32_t)Servo_data[4] > 0 ? 1 : 0;
|
||||
uint8_t rbutton = Servo_data[4] > PPM_SWITCH ? 1 : 0;
|
||||
packet[0] = throttle;
|
||||
packet[1] = aileron;
|
||||
if (ail_sign) { packet[1] |= 0x20; }
|
||||
@ -141,7 +142,7 @@ static void build_data_packet() {
|
||||
if (rbutton) { packet[1] |= 0x80; }
|
||||
packet[5] = trim;
|
||||
if (trim_sign) { packet[5] |= 0x20;}
|
||||
packet[6] = crc8(0xa5, packet, 6);
|
||||
packet[6] = HM830_crc8(0xa5, packet, 6);
|
||||
}
|
||||
|
||||
static void send_packet_hm830() {
|
||||
|
@ -1,272 +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.
|
||||
|
||||
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(HonTai_NRF24L01_INO)
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define BIND_HT_COUNT 80
|
||||
#define PACKET_HT_PERIOD 13500 // Timeout for callback in uSec
|
||||
//printf inside an interrupt handler is really dangerous
|
||||
//this shouldn't be enabled even in debug builds without explicitly
|
||||
//turning it on
|
||||
#define dbgprintf if(0) printf
|
||||
|
||||
#define INITIAL_HT_WAIT 500
|
||||
#define BIND_HT_PACKET_SIZE 10
|
||||
#define PACKET_HT_SIZE 12
|
||||
#define RF_BIND_HT_CHANNEL 0
|
||||
|
||||
enum {
|
||||
FORMAT_HONTAI = 0,
|
||||
FORMAT_JJRCX1,
|
||||
};
|
||||
|
||||
|
||||
#define CHANNEL_LED AUX1
|
||||
#define CHANNEL_ARM AUX1 // for JJRC X1
|
||||
#define CHANNEL_FLIP AUX2
|
||||
#define CHANNEL_PICTURE AUX3
|
||||
#define CHANNEL_VIDEO AUX4
|
||||
#define CHANNEL_HEADLESS AUX5
|
||||
#define CHANNEL_RTH AUX6
|
||||
#define CHANNEL_CALIBRATE AUX7
|
||||
|
||||
enum {
|
||||
HonTai_INIT1 = 0,
|
||||
HonTai_BIND2,
|
||||
HonTai_DATA
|
||||
};
|
||||
|
||||
static uint8_t ht_txid[5];
|
||||
|
||||
static uint8_t rf_chan = 0;
|
||||
static uint8_t rf_channels[][3] = {{0x05, 0x19, 0x28}, // Hontai
|
||||
{0x0a, 0x1e, 0x2d}}; // JJRC X1
|
||||
static uint8_t rx_tx_ht_addr[] = {0xd2, 0xb5, 0x99, 0xb3, 0x4a};
|
||||
static uint8_t addr_vals[4][16] = {
|
||||
{0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a},
|
||||
{0x92, 0x94, 0x96, 0x9a, 0xa4, 0xa6, 0xac, 0xb2, 0xb4, 0xb6, 0xca, 0xcc, 0xd2, 0xd4, 0xd6, 0xda},
|
||||
{0x93, 0x95, 0x99, 0x9b, 0xa5, 0xa9, 0xab, 0xad, 0xb3, 0xb5, 0xc9, 0xcb, 0xcd, 0xd3, 0xd5, 0xd9},
|
||||
{0x25, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x49, 0x4b, 0x4d, 0x59, 0x5b, 0x65, 0x69, 0x6b, 0x6d, 0x6e}};
|
||||
|
||||
// proudly swiped from http://www.drdobbs.com/implementing-the-ccitt-cyclical-redundan/199904926
|
||||
#define POLY 0x8408
|
||||
static uint16_t crc16(uint8_t *data_p, uint32_t length)
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t data;
|
||||
uint32_t crc;
|
||||
|
||||
crc = 0xffff;
|
||||
|
||||
if (length == 0) return (~crc);
|
||||
|
||||
length -= 2;
|
||||
do {
|
||||
for (i = 0, data = (uint8_t)0xff & *data_p++;
|
||||
i < 8;
|
||||
i++, data >>= 1) {
|
||||
if ((crc & 0x0001) ^ (data & 0x0001))
|
||||
crc = (crc >> 1) ^ POLY;
|
||||
else
|
||||
crc >>= 1;
|
||||
}
|
||||
} while (--length);
|
||||
|
||||
crc = ~crc;
|
||||
data = crc;
|
||||
crc = (crc << 8) | (data >> 8 & 0xFF);
|
||||
*data_p++ = crc >> 8;
|
||||
*data_p = crc & 0xff;
|
||||
return crc;
|
||||
}
|
||||
|
||||
#define CHAN_RANGE (PPM_MAX - PPM_MIN)
|
||||
static uint8_t scale_HT_channel(uint8_t ch, uint8_t start, uint8_t end)
|
||||
{
|
||||
uint32_t range = end - start;
|
||||
uint32_t chanval = Servo_data[ch];
|
||||
|
||||
if (chanval < PPM_MIN) chanval = PPM_MIN;
|
||||
else if (chanval > PPM_MAX) chanval = PPM_MAX;
|
||||
|
||||
uint32_t round = range < 0 ? 0 : CHAN_RANGE / range; // channels round up
|
||||
if (start < 0) round = CHAN_RANGE / range / 2; // trims zero centered around zero
|
||||
return (range * (chanval - PPM_MIN + round)) / CHAN_RANGE + start;
|
||||
}
|
||||
|
||||
#define GET_FLAG(ch, mask) (Servo_data[ch] > 0 ? mask : 0)
|
||||
static void send_HT_packet(uint8_t bind)
|
||||
{
|
||||
if (bind) {
|
||||
memcpy(packet, ht_txid, 5);
|
||||
memset(&packet[5], 0, 3);
|
||||
} else {
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
packet[0] = 0x0b;
|
||||
} else {
|
||||
packet[0] = GET_FLAG(CHANNEL_ARM, 0x02);
|
||||
}
|
||||
packet[1] = 0x00;
|
||||
packet[2] = 0x00;
|
||||
packet[3] = (scale_HT_channel(THROTTLE, 0, 127) << 1) // throttle
|
||||
| GET_FLAG(CHANNEL_PICTURE, 0x01);
|
||||
packet[4] = scale_HT_channel(AILERON, 63, 0); // aileron
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
packet[4] |= GET_FLAG(CHANNEL_RTH, 0x80)
|
||||
| GET_FLAG(CHANNEL_HEADLESS, 0x40);
|
||||
} else {
|
||||
packet[4] |= 0x80; // not sure what this bit does
|
||||
}
|
||||
packet[5] = scale_channel(CHANNEL2, 0, 63) // elevator
|
||||
| GET_FLAG(CHANNEL_CALIBRATE, 0x80)
|
||||
| GET_FLAG(CHANNEL_FLIP, 0x40);
|
||||
packet[6] = scale_HT_channel(RUDDER, 0, 63) // rudder
|
||||
| GET_FLAG(CHANNEL_VIDEO, 0x80);
|
||||
packet[7] = scale_HT_channel(AILERON, -16, 16); // aileron trim
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
packet[8] = scale_HT_channel(RUDDER, -16, 16); // rudder trim
|
||||
} else {
|
||||
packet[8] = 0xc0 // always in expert mode
|
||||
| GET_FLAG(CHANNEL_RTH, 0x02)
|
||||
| GET_FLAG(CHANNEL_HEADLESS, 0x01);
|
||||
}
|
||||
packet[9] = scale_HT_channel(ELEVATOR, -16, 16); // elevator trim
|
||||
}
|
||||
crc16(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE);
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
||||
} else {
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? RF_BIND_HT_CHANNEL : rf_channels[sub_protocol][rf_chan++]);
|
||||
rf_chan %= sizeof(rf_channels);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
XN297_WritePayload(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE);
|
||||
} else {
|
||||
NRF24L01_WritePayload(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE);
|
||||
}
|
||||
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void ht_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
// SPI trace of stock TX has these writes to registers that don't appear in
|
||||
// nRF24L01 or Beken 2421 datasheets. Uncomment if you have an XN297 chip?
|
||||
// NRF24L01_WriteRegisterMulti(0x3f, "\x4c\x84\x67,\x9c,\x20", 5);
|
||||
// NRF24L01_WriteRegisterMulti(0x3e, "\xc9\x9a\xb0,\x61,\xbb,\xab,\x9c", 7);
|
||||
// NRF24L01_WriteRegisterMulti(0x39, "\x0b\xdf\xc4,\xa7,\x03,\xab,\x9c", 7);
|
||||
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
XN297_SetTXAddr(rx_tx_ht_addr, sizeof(rx_tx_ht_addr));
|
||||
} else {
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_ht_addr, sizeof(rx_tx_ht_addr));
|
||||
}
|
||||
|
||||
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00);
|
||||
NRF24L01_Activate(0x73); // Deactivate feature register
|
||||
} else {
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xff); // JJRC uses dynamic payload length
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // match other stock settings even though AA disabled...
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
||||
}
|
||||
}
|
||||
|
||||
static void ht_init2()
|
||||
{
|
||||
uint8_t data_tx_addr[] = {0x2a, 0xda, 0xa5, 0x25, 0x24};
|
||||
|
||||
data_tx_addr[0] = addr_vals[0][ ht_txid[3] & 0x0f];
|
||||
data_tx_addr[1] = addr_vals[1][(ht_txid[3] >> 4) & 0x0f];
|
||||
data_tx_addr[2] = addr_vals[2][ ht_txid[4] & 0x0f];
|
||||
data_tx_addr[3] = addr_vals[3][(ht_txid[4] >> 4) & 0x0f];
|
||||
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
XN297_SetTXAddr(data_tx_addr, sizeof(data_tx_addr));
|
||||
} else {
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, sizeof(data_tx_addr));
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t ht_callback()
|
||||
{
|
||||
switch (phase) {
|
||||
case HonTai_INIT1:
|
||||
phase = HonTai_BIND2;
|
||||
break;
|
||||
case HonTai_BIND2:
|
||||
if (counter == 0) {
|
||||
ht_init2();
|
||||
phase = HonTai_DATA;
|
||||
BIND_DONE;
|
||||
} else {
|
||||
send_HT_packet(1);
|
||||
counter -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case HonTai_DATA:
|
||||
send_HT_packet(0);
|
||||
break;
|
||||
}
|
||||
return PACKET_HT_PERIOD;
|
||||
}
|
||||
|
||||
static uint16_t ht_setup()
|
||||
{
|
||||
counter = BIND_HT_COUNT;
|
||||
|
||||
if (sub_protocol == FORMAT_HONTAI) {
|
||||
ht_txid[0] = 0x4c; // first three bytes some kind of model id? - set same as stock tx
|
||||
ht_txid[1] = 0x4b;
|
||||
ht_txid[2] = 0x3a;
|
||||
} else {
|
||||
ht_txid[0] = 0x4b; // JJRC X1
|
||||
ht_txid[1] = 0x59;
|
||||
ht_txid[2] = 0x3a;
|
||||
}
|
||||
ht_txid[3] = (MProtocol_id >> 8 ) & 0xff;
|
||||
ht_txid[4] = MProtocol_id & 0xff;
|
||||
|
||||
ht_init();
|
||||
phase = HonTai_INIT1;
|
||||
|
||||
return INITIAL_HT_WAIT;
|
||||
}
|
||||
#endif
|
||||
|
733
Multiprotocol/Nrf24l01_inav.ino
Normal file
733
Multiprotocol/Nrf24l01_inav.ino
Normal file
@ -0,0 +1,733 @@
|
||||
/***
|
||||
* iNav Protocol
|
||||
*
|
||||
* Data rate is 250Kbps - lower data rate for better reliability and range
|
||||
*
|
||||
* Uses auto acknowledgment and dynamic payload size
|
||||
* ACK payload is used for handshaking in bind phase and telemetry in data phase
|
||||
*
|
||||
* Bind payload size is 16 bytes
|
||||
* Data payload size is 16 bytes dependent on variant of protocol, (small payload is read more quickly (marginal benefit))
|
||||
*
|
||||
* Bind and data payloads are whitened (XORed with a pseudo-random bitstream) to remove strings of 0s or 1s in transmission
|
||||
* packet. This improves reception by helping keep the TX and RX clocks in sync.
|
||||
*
|
||||
* Bind Phase
|
||||
* uses address {0x4b,0x5c,0x6d,0x7e,0x8f}
|
||||
* uses channel 0x4c (76)
|
||||
*
|
||||
* Data Phase
|
||||
* 1) Uses the address received in bind packet
|
||||
*
|
||||
* 2) Hops between RF channels generated from the address received in bind packet.
|
||||
* The number of RF hopping channels is set during bind handshaking:
|
||||
* the transmitter requests a number of hopping channels in payload[7]
|
||||
* the receiver sets ackPayload[7] with the number of hopping channels actually allocated - the transmitter must
|
||||
* use this value.
|
||||
*
|
||||
* 3) There are 16 channels: eight 10-bit analog channels, two 8-bit analog channels, and six digital channels as follows:
|
||||
* Channels 0 to 3, are the AETR channels, values 1000 to 2000 with resolution of 1 (10-bit channels)
|
||||
* Channel AUX1 by deviation convention is used for rate, values 1000, 1500, 2000
|
||||
* Channels AUX2 to AUX6 are binary channels, values 1000 or 2000,
|
||||
* by deviation convention these channels are used for: flip, picture, video, headless, and return to home
|
||||
* Channels AUX7 to AUX10 are analog channels, values 1000 to 2000 with resolution of 1 (10-bit channels)
|
||||
* Channels AUX11 and AUX12 are analog channels, values 1000 to 2000 with resolution of 4 (8-bit channels)
|
||||
***/
|
||||
|
||||
// debug build flags
|
||||
//#define NO_RF_CHANNEL_HOPPING
|
||||
|
||||
#define USE_AUTO_ACKKNOWLEDGEMENT
|
||||
#define USE_WHITENING
|
||||
|
||||
#define INAV_TELEMETRY
|
||||
//#define INAV_TELEMETRY_DEBUG
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#ifdef INAV_NRF24L01_INO
|
||||
static uint8_t INAV_setup() { return 1000; }
|
||||
static uint16_t inav_cb() {}
|
||||
#endif
|
||||
#if 0
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define INAV_BIND_COUNT 345 // 1.5 seconds
|
||||
#define FIRST_INAV_PACKET_DELAY 12000
|
||||
|
||||
#define INAV_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||
#define INAV_INITIAL_WAIT 500
|
||||
|
||||
// For code readability
|
||||
enum {
|
||||
CHANNEL1 = 0,
|
||||
CHANNEL2,
|
||||
CHANNEL3,
|
||||
CHANNEL4,
|
||||
CHANNEL5,
|
||||
CHANNEL6,
|
||||
CHANNEL7,
|
||||
CHANNEL8,
|
||||
CHANNEL9,
|
||||
CHANNEL10,
|
||||
CHANNEL11,
|
||||
CHANNEL12,
|
||||
CHANNEL13,
|
||||
CHANNEL14,
|
||||
CHANNEL15,
|
||||
CHANNEL16,
|
||||
};
|
||||
|
||||
// Deviation transmitter channels
|
||||
#define DEVIATION_CHANNEL_COUNT 12 // Max supported by Devo 7e
|
||||
//#define CHANNEL_LED CHANNEL5
|
||||
#define CHANNEL_RATE CHANNEL5
|
||||
#define CHANNEL_FLIP CHANNEL6
|
||||
#define CHANNEL_PICTURE CHANNEL7
|
||||
#define CHANNEL_VIDEO CHANNEL8
|
||||
#define CHANNEL_HEADLESS CHANNEL9
|
||||
#define CHANNEL_RTH CHANNEL10
|
||||
#define CHANNEL_XCAL CHANNEL11
|
||||
#define CHANNEL_YCAL CHANNEL12
|
||||
// #define GET_FLAG(ch, mask) (Channels[ch] > 0 ? mask : 0)
|
||||
|
||||
|
||||
enum {
|
||||
INAV_RATE_LOW = 0,
|
||||
INAV_RATE_MID = 1,
|
||||
INAV_RATE_HIGH = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
INAV_FLAG_FLIP = 0x01,
|
||||
INAV_FLAG_PICTURE = 0x02,
|
||||
INAV_FLAG_VIDEO = 0x04,
|
||||
INAV_FLAG_RTH = 0x08,
|
||||
INAV_FLAG_HEADLESS = 0x10,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PHASE_INIT = 0,
|
||||
PHASE_INAV_BIND,
|
||||
PHASE_INAV_DATA
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
DATA_INAV_PACKET = 0,
|
||||
BIND_INAV_PACKET = 1,
|
||||
};
|
||||
|
||||
static const char * const inav_opts[] = {
|
||||
#ifdef INAV_TELEMETRY
|
||||
_tr_noop("Telemetry"), _tr_noop("On"), _tr_noop("Off"), NULL,
|
||||
#endif
|
||||
"RxTx Addr1", "-32768", "32767", "1", NULL, // todo: store that elsewhere
|
||||
"RxTx Addr2", "-32768", "32767", "1", NULL, // ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
NULL
|
||||
};
|
||||
|
||||
enum {
|
||||
#ifdef INAV_TELEMETRY
|
||||
PROTOOPTS_TELEMETRY,
|
||||
#endif
|
||||
PROTOOPTS_RX_TX_ADDR1, // todo: store that elsewhere
|
||||
PROTOOPTS_RX_TX_ADDR2, // ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LAST_PROTO_OPT
|
||||
};
|
||||
|
||||
enum {
|
||||
OPTS_6_CHANNELS = 0,
|
||||
OPTS_12_CHANNELS
|
||||
};
|
||||
|
||||
enum {
|
||||
TELEM_ON = 0,
|
||||
TELEM_OFF,
|
||||
};
|
||||
|
||||
// Bit vector from bit position
|
||||
#define BV(bit) (1 << bit)
|
||||
|
||||
// Bit position mnemonics
|
||||
enum {
|
||||
|
||||
NRF24L01_1D_EN_DYN_ACK = 0,
|
||||
NRF24L01_1D_EN_ACK_PAY = 1,
|
||||
NRF24L01_1D_EN_DPL = 2,
|
||||
};
|
||||
|
||||
// Pre-shifted and combined bits
|
||||
enum {
|
||||
NRF24L01_03_SETUP_AW_5BYTES = 0x03,
|
||||
};
|
||||
|
||||
enum {
|
||||
NRF24L01_MAX_PAYLOAD_SIZE = 32,
|
||||
};
|
||||
|
||||
#define INAV_PROTOCOL_PAYLOAD_SIZE_MIN 8
|
||||
#define INAV_PROTOCOL_PAYLOAD_SIZE_DEFAULT 16
|
||||
#define INAV_PROTOCOL_PAYLOAD_SIZE_MAX 16
|
||||
|
||||
static uint32_t lost_packet_counter;
|
||||
|
||||
#define RC_CHANNEL_COUNT_MIN 6
|
||||
#define RC_CHANNEL_COUNT_DEFAULT 16
|
||||
#define RC_CHANNEL_COUNT_MAX 18
|
||||
|
||||
static uint8_t rc_channel_count;
|
||||
|
||||
static uint8_t tx_power;
|
||||
|
||||
#define RX_TX_ADDR_LEN 5
|
||||
static const uint8_t rx_tx_addr_bind[RX_TX_ADDR_LEN] = {0x4b,0x5c,0x6d,0x7e,0x8f};
|
||||
static uint8_t rx_tx_addr[RX_TX_ADDR_LEN];
|
||||
#define RX_TX_ADDR_4 0xD2 // rxTxAddr[4] always set to this value
|
||||
|
||||
#define BIND_PAYLOAD0 0xad // 10101101
|
||||
#define BIND_PAYLOAD1 0xc9 // 11001001
|
||||
#define BIND_ACK_PAYLOAD0 0x95 // 10010101
|
||||
#define BIND_ACK_PAYLOAD1 0xa9 // 10101001
|
||||
#define TELEMETRY_ACK_PAYLOAD0 0x5a // 01011010
|
||||
// TELEMETRY_ACK_PAYLOAD1 is sequence count
|
||||
#define DATA_PAYLOAD0 0x00
|
||||
#define DATA_PAYLOAD1 0x00
|
||||
|
||||
#ifdef USE_AUTO_ACKKNOWLEDGEMENT
|
||||
static uint8_t ackPayloadSize;
|
||||
static uint8_t ackPayload[NRF24L01_MAX_PAYLOAD_SIZE];
|
||||
#endif
|
||||
|
||||
// frequency channel management
|
||||
#define RF_CHANNEL_COUNT_DEFAULT 4
|
||||
#define RF_CHANNEL_COUNT_MAX 4
|
||||
#define RF_CHANNEL_BIND 0x4c
|
||||
static uint8_t rf_channel_index;
|
||||
static uint8_t rf_channels[RF_CHANNEL_COUNT_MAX];
|
||||
static uint8_t rf_channel_count;
|
||||
|
||||
static protocol_phase_t phase;
|
||||
|
||||
#ifndef TELEM_LTM
|
||||
// use DSM telemetry until LTM telemetry is implemented
|
||||
#define TELEM_LTM TELEM_DSM
|
||||
// repurpose the DSM FADESL, FADESR and HOLDS fields to display roll, pitch and yaw
|
||||
#define TELEM_LTM_ATTITUDE_PITCH TELEM_DSM_FLOG_FADESL
|
||||
#define TELEM_LTM_ATTITUDE_ROLL TELEM_DSM_FLOG_FADESR
|
||||
#define TELEM_LTM_ATTITUDE_YAW TELEM_DSM_FLOG_HOLDS
|
||||
// use DSM VOLT2, AMPS1 and AIRSPEED fields
|
||||
#define TELEM_LTM_STATUS_VBAT TELEM_DSM_FLOG_VOLT2
|
||||
#define TELEM_LTM_STATUS_CURRENT TELEM_DSM_AMPS1
|
||||
#define TELEM_LTM_STATUS_RSSI TELEM_DSM_FLOG_FRAMELOSS
|
||||
#define TELEM_LTM_STATUS_AIRSPEED TELEM_DSM_AIRSPEED
|
||||
/*
|
||||
currently unused LTM telemetry fields
|
||||
TELEM_LTM_STATUS_ARMED
|
||||
TELEM_LTM_STATUS_FAILSAFE
|
||||
TELEM_LTM_STATUS_FLIGHTMODE
|
||||
TELEM_LTM_NAVIGATION_GPS_MODE
|
||||
TELEM_LTM_NAVIGATION_NAV_MODE
|
||||
TELEM_LTM_NAVIGATION_ACTION
|
||||
TELEM_LTM_NAVIGATION_WAYPOINT_NUMBER
|
||||
TELEM_LTM_NAVIGATION_ERROR
|
||||
TELEM_LTM_NAVIGATION_FLAGS
|
||||
TELEM_LTM_GPSX_HDOP
|
||||
TELEM_LTM_TUNING_P_ROLL
|
||||
TELEM_LTM_TUNING_I_ROLL
|
||||
TELEM_LTM_TUNING_D_ROLL
|
||||
TELEM_LTM_TUNING_P_PITCH
|
||||
TELEM_LTM_TUNING_I_PITCH
|
||||
TELEM_LTM_TUNING_D_PITCH
|
||||
TELEM_LTM_TUNING_P_YAW
|
||||
TELEM_LTM_TUNING_I_YAW
|
||||
TELEM_LTM_TUNING_D_YAW
|
||||
TELEM_LTM_TUNING_RATES_ROLL
|
||||
TELEM_LTM_TUNING_RATES_PITCH
|
||||
TELEM_LTM_TUNING_RATES_YAW
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
uint8_t convert_channel_8b(uint8_t channel)
|
||||
{
|
||||
return (uint8_t)(convert_channel(channel) >> 2);
|
||||
}
|
||||
*/
|
||||
|
||||
static void whiten_payload(uint8_t *payload, uint8_t len)
|
||||
{
|
||||
#ifdef USE_WHITENING
|
||||
uint8_t whitenCoeff = 0x6b; // 01101011
|
||||
while (len--) {
|
||||
for (uint8_t m = 1; m; m <<= 1) {
|
||||
if (whitenCoeff & 0x80) {
|
||||
whitenCoeff ^= 0x11;
|
||||
(*payload) ^= m;
|
||||
}
|
||||
whitenCoeff <<= 1;
|
||||
}
|
||||
payload++;
|
||||
}
|
||||
#else
|
||||
UNUSED(payload);
|
||||
UNUSED(len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void build_bind_packet(void)
|
||||
{
|
||||
memset(packet, 0, INAV_PROTOCOL_PAYLOAD_SIZE_MAX);
|
||||
packet[0] = BIND_PAYLOAD0;
|
||||
packet[1] = BIND_PAYLOAD1;
|
||||
packet[2] = rx_tx_addr[0];
|
||||
packet[3] = rx_tx_addr[1];
|
||||
packet[4] = rx_tx_addr[2];
|
||||
packet[5] = rx_tx_addr[3];
|
||||
packet[6] = rx_tx_addr[4];
|
||||
packet[7] = rf_channel_count;
|
||||
packet[8] = packet_length;
|
||||
packet[9] = rc_channel_count;
|
||||
}
|
||||
|
||||
static void build_data_packet(void)
|
||||
{
|
||||
packet[0] = 0;
|
||||
packet[1] = 0;
|
||||
// AETR channels have 10 bit resolution
|
||||
const uint16_t aileron = convert_channel_10b(AILERON);
|
||||
const uint16_t elevator = convert_channel_10b(ELEVATOR);
|
||||
const uint16_t throttle = convert_channel_10b(THROTTLE);
|
||||
const uint16_t rudder = convert_channel_10b(RUDDER);
|
||||
packet[2] = aileron >> 2;
|
||||
packet[3] = elevator >> 2;
|
||||
packet[4] = throttle >> 2;
|
||||
packet[5] = rudder >> 2;
|
||||
// pack the AETR low bits
|
||||
packet[6] = (aileron & 0x03) | ((elevator & 0x03) << 2) | ((throttle & 0x03) << 4) | ((rudder & 0x03) << 6);
|
||||
|
||||
uint8_t rate = INAV_RATE_LOW;
|
||||
if (Channels[CHANNEL_RATE] > 0) {
|
||||
rate = INAV_RATE_HIGH;
|
||||
} else if (Channels[CHANNEL_RATE] == 0) {
|
||||
rate = INAV_RATE_MID;
|
||||
}
|
||||
packet[7] = rate; // rate, deviation channel 5, is mapped to AUX1
|
||||
|
||||
const uint8_t flags = GET_FLAG(CHANNEL_FLIP, INAV_FLAG_FLIP)
|
||||
| GET_FLAG(CHANNEL_PICTURE, INAV_FLAG_PICTURE)
|
||||
| GET_FLAG(CHANNEL_VIDEO, INAV_FLAG_VIDEO)
|
||||
| GET_FLAG(CHANNEL_RTH, INAV_FLAG_RTH)
|
||||
| GET_FLAG(CHANNEL_HEADLESS, INAV_FLAG_HEADLESS);
|
||||
packet[8] = flags; // flags, deviation channels 6-10 are mapped to AUX2 t0 AUX6
|
||||
|
||||
// map deviation channels 9-12 to RC channels AUX7-AUX10, use 10 bit resolution
|
||||
// deviation CHANNEL9 (headless) and CHANNEL10 (RTH) are mapped for a second time
|
||||
// duplicate mapping makes maximum use of deviation's 12 channels
|
||||
const uint16_t channel9 = convert_channel_10b(CHANNEL9);
|
||||
const uint16_t channel10 = convert_channel_10b(CHANNEL10);
|
||||
const uint16_t channel11 = convert_channel_10b(CHANNEL11);
|
||||
const uint16_t channel12 = convert_channel_10b(CHANNEL12);
|
||||
packet[9] = channel9 >> 2;
|
||||
packet[10] = channel10 >> 2;
|
||||
packet[11] = channel11 >> 2;
|
||||
packet[12] = channel12 >> 2;
|
||||
packet[13] = (channel9 & 0x03) | ((channel10 & 0x03) << 2) | ((channel11 & 0x03) << 4) | ((channel12 & 0x03) << 6);
|
||||
|
||||
// map deviation channels 7 and 8 to RC channels AUX11 and AUX12, use 10 bit resolution
|
||||
// deviation channels 7 (picture) and 8 (video) are mapped for a second time
|
||||
packet[14] = convert_channel_8b(CHANNEL7);
|
||||
packet[15] = convert_channel_8b(CHANNEL8);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t packet_ack(void)
|
||||
{
|
||||
#ifdef USE_AUTO_ACKKNOWLEDGEMENT
|
||||
const uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||
if (status & BV(NRF24L01_07_TX_DS)) { // NRF24L01_07_TX_DS asserted when ack payload received
|
||||
// ack payload recieved
|
||||
ackPayloadSize = NRF24L01_GetDynamicPayloadSize();
|
||||
if (ackPayloadSize > NRF24L01_MAX_PAYLOAD_SIZE) {
|
||||
ackPayloadSize = 0;
|
||||
NRF24L01_FlushRx();
|
||||
return PKT_PENDING;
|
||||
}
|
||||
NRF24L01_ReadPayload(ackPayload, ackPayloadSize);
|
||||
whiten_payload(ackPayload, ackPayloadSize);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_TX_DS)); // clear TX_DS interrupt
|
||||
return PKT_ACKED;
|
||||
}
|
||||
if (status & BV(NRF24L01_07_MAX_RT)) {
|
||||
// max retries exceeded
|
||||
// clear MAX_RT interrupt to allow further transmission
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_MAX_RT));
|
||||
NRF24L01_FlushTx(); // payload wasn't successfully transmitted, so remove it from TX FIFO
|
||||
return PKT_TIMEOUT;
|
||||
}
|
||||
return PKT_PENDING;
|
||||
#else
|
||||
return PKT_TIMEOUT; // if not using AUTO ACK just return a timeout
|
||||
#endif
|
||||
}
|
||||
|
||||
void transmit_packet(void)
|
||||
{
|
||||
// clear packet MAX_RT status bit so that transmission is not blocked
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_MAX_RT));
|
||||
// set NRF24L01_00_MASK_TX_DS and clear NRF24L01_00_PRIM_RX to initiate transmit
|
||||
// NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_MASK_TX_DS) | BV(NRF24L01_00_MASK_MAX_RT));
|
||||
whiten_payload(packet, packet_length);
|
||||
NRF24L01_WritePayload(packet, packet_length);// asynchronous call
|
||||
}
|
||||
|
||||
static void hop_to_next_channel(void)
|
||||
{
|
||||
#ifndef NO_RF_CHANNEL_HOPPING
|
||||
if (phase == PHASE_INAV_BIND) {
|
||||
return;
|
||||
}
|
||||
++rf_channel_index;
|
||||
if (rf_channel_index >= rf_channel_count) {
|
||||
rf_channel_index = 0;
|
||||
}
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[rf_channel_index]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_packet(uint8_t packet_type)
|
||||
{
|
||||
if (packet_type == DATA_INAV_PACKET) {
|
||||
build_data_packet();
|
||||
} else {
|
||||
build_bind_packet();
|
||||
}
|
||||
transmit_packet();
|
||||
hop_to_next_channel();
|
||||
++packet_count;
|
||||
|
||||
// Check and adjust transmission power. We do this after
|
||||
// transmission to not bother with timeout after power
|
||||
// settings change - we have plenty of time until next
|
||||
// packet.
|
||||
if (tx_power != Model.tx_power) {
|
||||
//Keep transmit power updated
|
||||
tx_power = Model.tx_power;
|
||||
NRF24L01_SetPower(tx_power);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_data_phase(void)
|
||||
{
|
||||
packet_count = 0;
|
||||
lost_packet_counter = 0;
|
||||
phase = PHASE_INAV_DATA;
|
||||
rf_channel_index = 0;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[0]);
|
||||
// RX_ADDR_P0 must equal TX_ADDR for auto ACK
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, RX_TX_ADDR_LEN);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, RX_TX_ADDR_LEN);
|
||||
}
|
||||
|
||||
static void init_nrf24l01(void)
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
// sets PWR_UP, EN_CRC, CRCO - 2 byte CRC
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
||||
|
||||
#ifdef USE_AUTO_ACKKNOWLEDGEMENT
|
||||
// Note that for some cheap NFR24L01 clones the NO_ACK bit in the packet control field is inverted,
|
||||
// see https://ncrmnt.org/2015/03/13/how-do-i-cost-optimize-nrf24l01/
|
||||
// (see section 7.3.3, p28 of nRF24L01+ Product Specification for descripton of packet control field).
|
||||
// This means AUTO_ACK will no work between them and genuine NRF24L01 modules, although AUTO_ACK
|
||||
// between these clones should work.
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, BV(NRF24L01_01_ENAA_P0)); // auto acknowledgment on P0
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, BV(NRF24L01_02_ERX_P0)); // Enable RX on P0 for Auto Ack
|
||||
#else
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00);
|
||||
#endif
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, NRF24L01_03_SETUP_AW_5BYTES); // 5-byte RX/TX address
|
||||
// ARD of 1500us is minimum required for 32 byte ACK payload in 250kbps mode (section 7.4.2, p33 of nRF24L01+ Product Specification)
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, NRF24L01_04_ARD_2500us | NRF24L01_04_ARC_1); // 1 retry after 1500us
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_CHANNEL_BIND);
|
||||
// bitrate and power are set using regigister NRF24L01_06_RF_SETUP
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_SetPower(Model.tx_power);
|
||||
// Writing to the STATUS register clears the specified interrupt bits
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_RX_DR) | BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT));
|
||||
// NRF24L01_08_OBSERVE_TX is read only register
|
||||
// NRF24L01_09_RPD is read only register (called RPD for NRF24L01+, CD for NRF24L01)
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr_bind, RX_TX_ADDR_LEN); // RX_ADDR_P0 must equal TX_ADDR for auto ACK
|
||||
// RX_ADDR for pipes P1-P5 (registers 0B to 0F) aret left at default values
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr_bind, RX_TX_ADDR_LEN);
|
||||
// Payload Widths for P0-P5 (registers 11 to 16) aret left at default values
|
||||
// NRF24L01_17_FIFO_STATUS is read only register for all non-reserved bits
|
||||
// No registers with values 18 to 1B
|
||||
#ifdef USE_AUTO_ACKKNOWLEDGEMENT
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
NRF24L01_Activate(0x73); // Activate feature register, needed for NRF24L01 (harmless for NRF24L01+)
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, BV(NRF24L01_1C_DYNPD_P0)); // dynamic payload length on pipes P0
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF24L01_1D_EN_ACK_PAY) | BV(NRF24L01_1D_EN_DPL));
|
||||
#endif
|
||||
|
||||
NRF24L01_Activate(0x53); // switch bank back
|
||||
|
||||
NRF24L01_SetTxRxMode(TX_EN); // enter transmit mode, sets up NRF24L01_00_CONFIG register
|
||||
}
|
||||
|
||||
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
||||
static void initialize_rx_tx_addr(void)
|
||||
{
|
||||
uint32_t lfsr = 0xb2c54a2ful;
|
||||
|
||||
#ifndef USE_FIXED_MFGID
|
||||
uint8_t var[12];
|
||||
MCU_SerialNumber(var, 12);
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
rand32_r(&lfsr, var[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Model.fixed_id) {
|
||||
for (uint8_t i = 0, j = 0; i < sizeof(Model.fixed_id); ++i, j += 8)
|
||||
rand32_r(&lfsr, (Model.fixed_id >> j) & 0xff);
|
||||
}
|
||||
// Pump zero bytes for LFSR to diverge more
|
||||
for (uint8_t i = 0; i < sizeof(lfsr); ++i) rand32_r(&lfsr, 0);
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(rx_tx_addr)-1; ++i) {
|
||||
rx_tx_addr[i] = lfsr & 0xff;
|
||||
rand32_r(&lfsr, i);
|
||||
}
|
||||
rx_tx_addr[1] &= 0x7f; // clear top bit so saved Model.proto_opts value is positive
|
||||
rx_tx_addr[3] &= 0x7f; // clear top bit so saved Model.proto_opts value is positive
|
||||
rx_tx_addr[4] = RX_TX_ADDR_4; // set to constant, so variable part of rx_tx_addr can be stored in 32-bit value
|
||||
}
|
||||
|
||||
// The hopping channels are determined by the value of rx_tx_addr[0]
|
||||
static void set_hopping_channels(void)
|
||||
{
|
||||
rf_channel_index = 0;
|
||||
const uint8_t addr = rx_tx_addr[0];
|
||||
uint8_t ch = 0x10 + (addr & 0x07);
|
||||
for (int i = 0; i < rf_channel_count; ++i) {
|
||||
rf_channels[i] = ch;
|
||||
ch += 0x0c;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_telemetry(void)
|
||||
{
|
||||
#ifdef INAV_TELEMETRY
|
||||
const uint8_t observeTx = NRF24L01_ReadReg(NRF24L01_08_OBSERVE_TX);
|
||||
const uint8_t lostPacketCount = (observeTx & NRF24L01_08_PLOS_CNT_MASK) >> 4;
|
||||
// const uint8_t autoRetryCount = observeTx & NRF24L01_08_ARC_CNT_MASK;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[rf_channel_index]); // reset packet loss counter
|
||||
|
||||
lost_packet_counter += lostPacketCount;
|
||||
Telemetry.value[TELEM_LTM_STATUS_RSSI] = 100 - 100 * lost_packet_counter / packet_count;
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_STATUS_RSSI);
|
||||
|
||||
// ackPayload contains telemetry in LTM format.
|
||||
// See https://github.com/stronnag/mwptools/blob/master/docs/ltm-definition.txt
|
||||
// ackPayload[0] is a sequence count, LTM begins at ackPayload[2]
|
||||
const uint8_t *ltm = &ackPayload[2];
|
||||
switch (ltm[0]) { // frame type
|
||||
case 'G': // GPS frame
|
||||
{
|
||||
// LTM lat/long: int32 decimal degrees * 10,000,000 (1E7)
|
||||
// LTM 1 degree = 1,000,000
|
||||
// Deviation longitude: +/-180degrees = +/- 180*60*60*1000; W if value<0, E if value>=0; -180degrees = 180degrees
|
||||
// Deviation latitude: +/-90degrees = +/- 90*60*60*1000; S if value<0, N if value>=0
|
||||
// Deviation 1 degree = 3,600,000
|
||||
// Scale factor = 36/10 = 18/5
|
||||
uint32_t latitude;
|
||||
memcpy(&latitude, <m[1], sizeof(uint32_t));
|
||||
Telemetry.gps.latitude = latitude * 18 / 5;
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_LAT);
|
||||
|
||||
uint32_t longitude;
|
||||
memcpy(&longitude, <m[5], sizeof(uint32_t));
|
||||
Telemetry.gps.longitude = longitude * 18 / 5;
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_LONG);
|
||||
|
||||
Telemetry.gps.velocity = ltm[9] * 1000; // LTM m/s; DEV mm/s
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_SPEED);
|
||||
|
||||
uint32_t altitude;
|
||||
memcpy(&altitude, <m[10], sizeof(uint32_t));
|
||||
Telemetry.gps.altitude = altitude * 10; // LTM:cm; DEV:mm
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_ALT);
|
||||
|
||||
Telemetry.gps.satcount = ltm[14] >> 2;
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_SATCOUNT);
|
||||
}
|
||||
break;
|
||||
case 'A': // Attitude frame
|
||||
{
|
||||
const uint16_t heading = ltm[5] | (ltm[6] << 8);
|
||||
Telemetry.gps.heading = heading;
|
||||
TELEMETRY_SetUpdated(TELEM_GPS_HEADING);
|
||||
|
||||
const s16 pitch = ltm[1] | (ltm[2] << 8);
|
||||
Telemetry.value[TELEM_LTM_ATTITUDE_PITCH] = pitch; // LTM:degrees [-180,180]
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_PITCH);
|
||||
|
||||
const s16 roll = ltm[3] | (ltm[4] << 8);
|
||||
Telemetry.value[TELEM_LTM_ATTITUDE_ROLL] = roll; // LTM:degrees [-180,180]
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_ROLL);
|
||||
|
||||
Telemetry.value[TELEM_LTM_ATTITUDE_YAW] = heading;
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_YAW);
|
||||
}
|
||||
break;
|
||||
case 'S': // Status frame
|
||||
{
|
||||
const uint16_t vBat = ltm[1] | (ltm[2] << 8);
|
||||
Telemetry.value[TELEM_LTM_STATUS_VBAT] = (uint32_t)(vBat); // LTM:mV; DEV:V/10
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_STATUS_VBAT);
|
||||
|
||||
const uint16_t amps = ltm[3] | (ltm[4] << 8);
|
||||
Telemetry.value[TELEM_LTM_STATUS_CURRENT] = (uint32_t)(amps); // LTM:mA; DEV:A/10
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_STATUS_CURRENT);
|
||||
|
||||
Telemetry.value[TELEM_LTM_STATUS_AIRSPEED] = ltm[6];
|
||||
TELEMETRY_SetUpdated(TELEM_LTM_STATUS_AIRSPEED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void save_rx_tx_addr(void)
|
||||
{
|
||||
Model.proto_opts[PROTOOPTS_RX_TX_ADDR1] = rx_tx_addr[0] | ((uint16_t)rx_tx_addr[1] << 8);
|
||||
Model.proto_opts[PROTOOPTS_RX_TX_ADDR2] = rx_tx_addr[2] | ((uint16_t)rx_tx_addr[3] << 8);
|
||||
}
|
||||
|
||||
void load_rx_tx_addr(void)
|
||||
{
|
||||
rx_tx_addr[0] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR1]) & 0xff;
|
||||
rx_tx_addr[1] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR1] >> 8) & 0xff;
|
||||
rx_tx_addr[2] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR2]) & 0xff;
|
||||
rx_tx_addr[3] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR2] >> 8) & 0xff;
|
||||
rx_tx_addr[4] = RX_TX_ADDR_4; // set to constant, so variable part of rx_tx_addr can be stored in 32-bit value
|
||||
}
|
||||
|
||||
static void inav_init()
|
||||
{
|
||||
// check options before proceeding with initialiasation
|
||||
packet_length = INAV_PROTOCOL_PAYLOAD_SIZE_DEFAULT;
|
||||
rc_channel_count = RC_CHANNEL_COUNT_DEFAULT;
|
||||
rf_channel_count = RF_CHANNEL_COUNT_DEFAULT;
|
||||
if(IS_AUTOBIND_FLAG_on) {
|
||||
initialize_rx_tx_addr();
|
||||
save_rx_tx_addr();
|
||||
} else {
|
||||
load_rx_tx_addr();
|
||||
}
|
||||
|
||||
packet_count = 0;
|
||||
set_hopping_channels();
|
||||
}
|
||||
|
||||
static uint16_t inav_cb()
|
||||
{
|
||||
static uint16_t bind_counter;
|
||||
static uint8_t bind_acked;
|
||||
|
||||
switch (phase) {
|
||||
case PHASE_INAV_INIT:
|
||||
phase = PHASE_INAV_BIND;
|
||||
bind_counter = INAV_BIND_COUNT;
|
||||
bind_acked = 0;
|
||||
return FIRST_INAV_PACKET_DELAY;
|
||||
break;
|
||||
|
||||
case PHASE_INAV_BIND:
|
||||
if (bind_counter == 0) {
|
||||
set_data_phase();
|
||||
BIND_DONE;
|
||||
} else {
|
||||
if (packet_ack() == PKT_ACKED) {
|
||||
bind_acked = 1;
|
||||
}
|
||||
if (bind_acked == 1) {
|
||||
// bind packet acked, so set bind_counter to zero to enter data phase on next callback
|
||||
bind_counter = 0;
|
||||
return INAV_PACKET_PERIOD;
|
||||
}
|
||||
send_packet(BIND_INAV_PACKET);
|
||||
--bind_counter;
|
||||
}
|
||||
break;
|
||||
|
||||
case PHASE_INAV_DATA:
|
||||
update_telemetry();
|
||||
/*#define PACKET_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out
|
||||
if (packet_ack() == PKT_PENDING) {
|
||||
return PACKET_CHKTIME; // packet send not yet complete
|
||||
}*/
|
||||
packet_ack();
|
||||
send_packet(DATA_INAV_PACKET);
|
||||
break;
|
||||
}
|
||||
return INAV_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
static uint8_t INAV_setup()
|
||||
{
|
||||
CLOCK_StopTimer();
|
||||
tx_power = Model.tx_power;
|
||||
ackPayloadSize = 0;
|
||||
memset(ackPayload, 0, NRF24L01_MAX_PAYLOAD_SIZE);
|
||||
inav_init(bind);
|
||||
init_nrf24l01();
|
||||
|
||||
#ifdef INAV_TELEMETRY
|
||||
memset(&Telemetry, 0, sizeof(Telemetry));
|
||||
TELEMETRY_SetType(TELEM_LTM);
|
||||
#endif
|
||||
|
||||
if(IS_AUTOBIND_FLAG_on) {
|
||||
phase = PHASE_INAV_INIT;
|
||||
// PROTOCOL_SetBindState(INAV_BIND_COUNT * INAV_PACKET_PERIOD / 1000);
|
||||
} else {
|
||||
set_data_phase();
|
||||
// BIND_DONE;
|
||||
}
|
||||
return INAV_INITIAL_WAIT;
|
||||
}
|
||||
/*
|
||||
const void *INAV_Cmds(enum ProtoCmds cmd)
|
||||
{
|
||||
switch(cmd) {
|
||||
case PROTOCMD_INIT: initialize(INIT_BIND); return 0;
|
||||
case PROTOCMD_DEINIT:
|
||||
case PROTOCMD_RESET:
|
||||
CLOCK_StopTimer();
|
||||
return (void *)(NRF24L01_Reset() ? 1L : -1L);
|
||||
//case PROTOCMD_CHECK_AUTOBIND: return 0;
|
||||
case PROTOCMD_CHECK_AUTOBIND: return (void *)1L; // always Autobind
|
||||
case PROTOCMD_BIND: initialize(INIT_BIND); return 0;
|
||||
case PROTOCMD_NUMCHAN: return (void *)((long)rc_channel_count);
|
||||
case PROTOCMD_DEFAULT_NUMCHAN: return (void *)((long)RC_CHANNEL_COUNT_DEFAULT);
|
||||
case PROTOCMD_CURRENT_ID: return 0;
|
||||
case PROTOCMD_GETOPTIONS: return inav_opts;
|
||||
#ifdef INAV_TELEMETRY
|
||||
case PROTOCMD_TELEMETRYSTATE: return (void *)(long)(Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON ? PROTO_TELEM_ON : PROTO_TELEM_OFF);
|
||||
#else
|
||||
case PROTOCMD_TELEMETRYSTATE: return (void *)(long)PROTO_TELEM_UNSUPPORTED;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
@ -189,9 +189,9 @@ static void ne260_init() {
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, vRX_DR | vTX_DS | vMAX_RT); // reset the IRQ flags
|
||||
}
|
||||
|
||||
static void send_data_packet() {
|
||||
static void send_ne_data_packet() {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
uint32_t value = (uint32_t)Servo_data[NE_ch[i]] * 0x40 / PPM_MAX + 0x40;
|
||||
uint32_t value = (uint32_t)map(limit_channel_100(NE_ch[i]),servo_min_100,servo_max_100,0,80);
|
||||
if (value > 0x7f)
|
||||
value = 0x7f;
|
||||
else if(value < 0)
|
||||
@ -210,7 +210,7 @@ static void send_data_packet() {
|
||||
NRF24L01_WritePayload((uint8_t*) packet, PACKET_NE_LENGTH);
|
||||
}
|
||||
|
||||
static void send_bind_packet() {
|
||||
static void send_ne_bind_packet() {
|
||||
packet[0] = 0xAA; //throttle
|
||||
packet[1] = 0xAA; //rudder
|
||||
packet[2] = 0xAA; //elevator
|
||||
@ -243,7 +243,7 @@ static uint16_t ne260_cb() {
|
||||
}
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
send_bind_packet();
|
||||
send_ne_bind_packet();
|
||||
state = NE260_BINDRX;
|
||||
return 500;
|
||||
} else if (state == NE260_BINDRX) {
|
||||
@ -259,7 +259,7 @@ static uint16_t ne260_cb() {
|
||||
else if (state == NE260_DATA1) { neChannel = 10; state = NE260_DATA2; }
|
||||
else if (state == NE260_DATA2) { neChannel = 30; state = NE260_DATA3; }
|
||||
else if (state == NE260_DATA3) { neChannel = 50; state = NE260_DATA1; }
|
||||
send_data_packet();
|
||||
send_ne_data_packet();
|
||||
return 2500;
|
||||
}
|
||||
|
||||
|
152
Multiprotocol/Nrf24l01_q303.ino
Normal file
152
Multiprotocol/Nrf24l01_q303.ino
Normal file
@ -0,0 +1,152 @@
|
||||
#ifdef Q303_NRF24L01_INO
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define Q303_BIND_COUNT 1200
|
||||
|
||||
#define Q303_PACKET_SIZE 10
|
||||
#define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec
|
||||
#define Q303_INITIAL_WAIT 500
|
||||
#define Q303_RF_BIND_CHANNEL 0x02
|
||||
#define Q303_NUM_RF_CHANNELS 4
|
||||
|
||||
static uint8_t tx_addr[5];
|
||||
static uint8_t current_chan;
|
||||
uint8_t txid[4] = {0xAE, 0x89, 0x97, 0x87};
|
||||
static uint8_t rf_chans[4] = {0x4A, 0x4C, 0x4E, 0x48};
|
||||
|
||||
// haven't figured out txid<-->rf channel mapping yet
|
||||
// static const struct { uint8_t txid[sizeof(txid)]; uint8_t rfchan[Q303_NUM_RF_CHANNELS]; } q303_tx_rf_map[] = {{{0xAE, 0x89, 0x97, 0x87}, {0x4A, 0x4C, 0x4E, 0x48}}};
|
||||
|
||||
enum {
|
||||
Q303_BIND,
|
||||
Q303_DATA
|
||||
};
|
||||
|
||||
// flags going to packet[8]
|
||||
#define Q303_FLAG_HIGHRATE 0x03
|
||||
#define Q303_FLAG_AHOLD 0x40
|
||||
#define Q303_FLAG_RTH 0x80
|
||||
|
||||
// flags going to packet[9]
|
||||
#define Q303_FLAG_GIMBAL_DN 0x04
|
||||
#define Q303_FLAG_GIMBAL_UP 0x20
|
||||
#define Q303_FLAG_HEADLESS 0x08
|
||||
#define Q303_FLAG_FLIP 0x80
|
||||
#define Q303_FLAG_SNAPSHOT 0x10
|
||||
#define Q303_FLAG_VIDEO 0x01
|
||||
|
||||
static void send_packet(uint8_t bind)
|
||||
{
|
||||
if(bind) {
|
||||
packet[0] = 0xaa;
|
||||
memcpy(&packet[1], txid, 4);
|
||||
memset(&packet[5], 0, 5);
|
||||
}
|
||||
else {
|
||||
aileron = map(Servo_data[AILERON], 1000, 2000, 0, 1000);
|
||||
elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 0, 1000);
|
||||
throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000);
|
||||
rudder = 1000 - map(Servo_data[RUDDER], 1000, 2000, 0, 1000);
|
||||
|
||||
packet[0] = 0x55;
|
||||
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
|
||||
packet[6] = 0x10; // trim(s) ?
|
||||
packet[7] = 0x10; // trim(s) ?
|
||||
packet[8] = 0x03 // high rate (0-3)
|
||||
| GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD)
|
||||
| GET_FLAG(Servo_AUX6, Q303_FLAG_RTH);
|
||||
packet[9] = 0x40 // always set
|
||||
| GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS)
|
||||
| GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP)
|
||||
| GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT)
|
||||
| GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO);
|
||||
if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH))
|
||||
packet[9] |= Q303_FLAG_GIMBAL_DN;
|
||||
else if(Servo_data[AUX7] > PPM_SWITCH)
|
||||
packet[9] |= Q303_FLAG_GIMBAL_UP;
|
||||
// set low rate for first packets
|
||||
if(bind_counter != 0) {
|
||||
packet[8] &= ~0x03;
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (bind) {
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, Q303_RF_BIND_CHANNEL);
|
||||
} else {
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_chans[current_chan++]);
|
||||
current_chan %= Q303_NUM_RF_CHANNELS;
|
||||
}
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
XN297_WritePayload(packet, Q303_PACKET_SIZE);
|
||||
}
|
||||
|
||||
static uint16_t q303_callback()
|
||||
{
|
||||
switch (phase) {
|
||||
case Q303_BIND:
|
||||
if (bind_counter == 0) {
|
||||
tx_addr[0] = 0x55;
|
||||
memcpy(&tx_addr[1], txid, 4);
|
||||
XN297_SetTXAddr(tx_addr, 5);
|
||||
phase = Q303_DATA;
|
||||
bind_counter = Q303_BIND_COUNT;
|
||||
BIND_DONE;
|
||||
} else {
|
||||
send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
break;
|
||||
case Q303_DATA:
|
||||
send_packet(0);
|
||||
break;
|
||||
}
|
||||
return Q303_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
static uint16_t q303_init()
|
||||
{
|
||||
// memcpy(txid, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].txid, sizeof(txid));
|
||||
// memcpy(rf_chans, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].rfchan, sizeof(rf_chans));
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
XN297_SetTXAddr((uint8_t *) "\xCC\xCC\xCC\xCC\xCC", 5);
|
||||
NRF24L01_FlushTx();
|
||||
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_05_RF_CH, Q303_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_SetPower();
|
||||
|
||||
// this sequence necessary for module from stock tx
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits on
|
||||
NRF24L01_Activate(0x53); // switch bank back
|
||||
|
||||
BIND_IN_PROGRESS;
|
||||
bind_counter = Q303_BIND_COUNT;
|
||||
current_chan = 0;
|
||||
// PROTOCOL_SetBindState(Q303_BIND_COUNT * Q303_PACKET_PERIOD / 1000);
|
||||
phase = Q303_BIND;
|
||||
return Q303_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
@ -112,9 +112,9 @@ static const uint8_t * rf_udi_channels = NULL;
|
||||
|
||||
static uint8_t packet_udi_ack()
|
||||
{
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
||||
case BV(NRF24L01_07_TX_DS): return PKT_ACKED;
|
||||
case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) {
|
||||
case _BV(NRF24L01_07_TX_DS): return PKT_ACKED;
|
||||
case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||
}
|
||||
return PKT_PENDING;
|
||||
}
|
||||
@ -207,7 +207,7 @@ static void UDI_init2()
|
||||
|
||||
// Turn radio power on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
uint8_t config = BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP);
|
||||
uint8_t config = _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, config);
|
||||
// Implicit delay in callback
|
||||
// delayMicroseconds(150);
|
||||
@ -239,15 +239,11 @@ static void add_pkt_checksum()
|
||||
|
||||
static uint8_t convert_channel(uint8_t num, uint8_t chn_max, uint8_t sign_ofs)
|
||||
{
|
||||
uint32_t ch = Servo_data[num];
|
||||
if (ch < PPM_MIN) {
|
||||
ch = PPM_MIN;
|
||||
} else if (ch > PPM_MAX) {
|
||||
ch = PPM_MAX;
|
||||
}
|
||||
uint32_t ch = map(limit_channel_100(num),servo_min_100,servo_max_100,-1000, 1000);
|
||||
|
||||
uint32_t chn_val;
|
||||
if (sign_ofs) chn_val = (((ch * chn_max / PPM_MAX) + sign_ofs) >> 1);
|
||||
else chn_val = (ch * chn_max / PPM_MAX);
|
||||
if (sign_ofs) chn_val = (((ch * chn_max / servo_max_100) + sign_ofs) >> 1);
|
||||
else chn_val = (ch * chn_max / servo_max_100);
|
||||
if (chn_val < 0) chn_val = 0;
|
||||
else if (chn_val > chn_max) chn_val = chn_max;
|
||||
return (uint8_t) chn_val;
|
||||
@ -260,8 +256,8 @@ static void read_controls(uint8_t* throttle, uint8_t* rudder, uint8_t* elevator,
|
||||
// Protocol is registered AETRG, that is
|
||||
// Aileron is channel 0, Elevator - 1, Throttle - 2, Rudder - 3
|
||||
// Sometimes due to imperfect calibration or mixer settings
|
||||
// throttle can be less than PPM_MIN or larger than
|
||||
// PPM_MAX. As we have no space here, we hard-limit
|
||||
// throttle can be less than servo_min_100 or larger than
|
||||
// servo_max_100. As we have no space here, we hard-limit
|
||||
// channels values by min..max range
|
||||
|
||||
// Channel 3: throttle is 0-100
|
||||
@ -277,28 +273,28 @@ static void read_controls(uint8_t* throttle, uint8_t* rudder, uint8_t* elevator,
|
||||
*aileron = convert_channel(AILERON, 0x3f, 0x20);
|
||||
|
||||
// Channel 5
|
||||
if (Servo_data[AUX1] <= 0) *flags &= ~UDI_FLIP360;
|
||||
else *flags |= UDI_FLIP360;
|
||||
if (Servo_AUX1) *flags |= UDI_FLIP360;
|
||||
else *flags &= ~UDI_FLIP360;
|
||||
|
||||
// Channel 6
|
||||
if (Servo_data[AUX2] <= 0) *flags &= ~UDI_FLIP;
|
||||
else *flags |= UDI_FLIP;
|
||||
if (Servo_AUX2) *flags |= UDI_FLIP;
|
||||
else *flags &= ~UDI_FLIP;
|
||||
|
||||
// Channel 7
|
||||
if (Servo_data[AUX3] <= 0) *flags &= ~UDI_CAMERA;
|
||||
else *flags |= UDI_CAMERA;
|
||||
if (Servo_AUX3) *flags |= UDI_CAMERA;
|
||||
else *flags &= ~UDI_CAMERA;
|
||||
|
||||
// Channel 8
|
||||
if (Servo_data[AUX4] <= 0) *flags &= ~UDI_VIDEO;
|
||||
else *flags |= UDI_VIDEO;
|
||||
if (Servo_AUX4) *flags |= UDI_VIDEO;
|
||||
else *flags &= ~UDI_VIDEO;
|
||||
|
||||
// Channel 9
|
||||
if (Servo_data[AUX5] <= 0) *flags &= ~UDI_LIGHTS;
|
||||
else *flags |= UDI_LIGHTS;
|
||||
if (Servo_AUX5) *flags |= UDI_LIGHTS;
|
||||
else *flags &= ~UDI_LIGHTS;
|
||||
|
||||
// Channel 10
|
||||
if (Servo_data[AUX6] <= 0) *flags &= ~UDI_MODE2;
|
||||
else *flags |= UDI_MODE2;
|
||||
if (Servo_AUX6) *flags |= UDI_MODE2;
|
||||
else *flags &= ~UDI_MODE2;
|
||||
}
|
||||
|
||||
static void send_udi_packet(uint8_t bind)
|
||||
@ -325,7 +321,7 @@ static void send_udi_packet(uint8_t bind)
|
||||
packet[5] = randoms[1];
|
||||
packet[6] = randoms[2];
|
||||
if (sub_protocol == U839_2014) {
|
||||
packet[7] = (packet_counter < 4) ? 0x3f : 0x04; // first four packets use 0x3f here, then 0x04
|
||||
packet[7] = (packet_count < 4) ? 0x3f : 0x04; // first four packets use 0x3f here, then 0x04
|
||||
}
|
||||
} else if (bind == 2) {
|
||||
// Bind phase 2
|
||||
@ -374,7 +370,7 @@ static void send_udi_packet(uint8_t bind)
|
||||
uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS,status);
|
||||
|
||||
if (packet_sent && bind && (status & BV(NRF24L01_07_TX_DS))) {
|
||||
if (packet_sent && bind && (status & _BV(NRF24L01_07_TX_DS))) {
|
||||
bind_step_success = 1;
|
||||
}
|
||||
|
||||
@ -396,7 +392,7 @@ static void send_udi_packet(uint8_t bind)
|
||||
}
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet, payload_size);
|
||||
++packet_counter;
|
||||
++packet_count;
|
||||
packet_sent = 1;
|
||||
}
|
||||
|
||||
@ -433,7 +429,7 @@ static uint16_t UDI_callback() {
|
||||
break;
|
||||
case UDI_BIND1_RX:
|
||||
// Check if data has been received
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR) ) {
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR) ) {
|
||||
uint8_t data[UDI_PAYLOADSIZE];
|
||||
NRF24L01_ReadPayload(data, payload_size);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E); // On original TX this is done on LAST packet check only !
|
||||
@ -514,7 +510,7 @@ static uint16_t UDI_callback() {
|
||||
|
||||
case UDI_BIND2_RX:
|
||||
// Check if data has been received
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR) ) {
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR) ) {
|
||||
uint8_t data[UDI_PAYLOADSIZE];
|
||||
NRF24L01_ReadPayload(data, payload_size);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E);
|
||||
@ -570,7 +566,7 @@ static uint16_t UDI_callback() {
|
||||
|
||||
static uint16_t UDI_setup()
|
||||
{
|
||||
packet_counter = 0;
|
||||
packet_count = 0;
|
||||
UDI_init();
|
||||
phase = UDI_INIT2;
|
||||
|
||||
|
89
Multiprotocol/PPM_SERIE.txt
Normal file
89
Multiprotocol/PPM_SERIE.txt
Normal file
@ -0,0 +1,89 @@
|
||||
#define PPM_TEST 3 //test voie valeur
|
||||
|
||||
#define PPM_MIN_COMMAND 1250
|
||||
#define PPM_SWITCH 1550
|
||||
#define PPM_MAX_COMMAND 1750
|
||||
#define isterie 10
|
||||
|
||||
|
||||
#define PPM_Pin 3 //this must be 2 or 3
|
||||
int ppm[18]; //array for storing up to 16 servo signals
|
||||
int maxi = 0, mini = 3000, decal, moy, a,r, val;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); Serial.println("ready");
|
||||
pinMode(PPM_Pin, INPUT); attachInterrupt(PPM_Pin - 2, read_ppm, CHANGE);
|
||||
|
||||
TCCR1A = 0; //reset timer1
|
||||
TCCR1B = 0;
|
||||
TCCR1B |= (1 << CS11); //set timer1 to increment every 0,5 us
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//You can delete everithing inside loop() and put your own code here
|
||||
int count;
|
||||
if(ppm[PPM_TEST]<mini || ppm[PPM_TEST]>maxi) {
|
||||
maxi = max( maxi, ppm[PPM_TEST]);
|
||||
mini = min( mini, ppm[PPM_TEST]);
|
||||
moy = (maxi + mini)/2;
|
||||
decal = (maxi - moy) / 125 * 100;
|
||||
a = moy + decal;
|
||||
r = moy - decal;
|
||||
}
|
||||
Serial.print(a); Serial.print(" ");
|
||||
Serial.print(r); Serial.print(" ");
|
||||
Serial.print(maxi); Serial.print(" ");
|
||||
Serial.print(mini); Serial.print(" ");
|
||||
Serial.print(moy); Serial.print(" ");
|
||||
if((PPM_SWITCH - isterie) < moy < (PPM_SWITCH + isterie)) {
|
||||
Serial.print(" . Pb istérie PPM middel ");
|
||||
Serial.print(PPM_SWITCH);
|
||||
}
|
||||
else {
|
||||
Serial.print(" . ");
|
||||
|
||||
count = 0;
|
||||
Serial.print(ppm[count]); Serial.print(" "); count++;
|
||||
Serial.print(ppm[count]); Serial.print(" "); count++;
|
||||
Serial.print(ppm[count]); Serial.print(" "); count++;
|
||||
Serial.print(ppm[count]); Serial.print(" "); count++;
|
||||
for( ;count<17;count++) {
|
||||
val=ppm[count];
|
||||
if((moy-2*isterie) < val < (moy+2*isterie)) { Serial.print("2"); }
|
||||
else if(PPM_MAX_COMMAND < val < 2200) { Serial.print("3"); }
|
||||
else if(PPM_MAX_COMMAND < val) { Serial.print("+"); }
|
||||
else if(800 < val < PPM_MIN_COMMAND) { Serial.print("1"); }
|
||||
else { Serial.print("."); }
|
||||
|
||||
}
|
||||
/*
|
||||
while(ppm[count] != 0){ //print out the servo values
|
||||
Serial.print(count); Serial.print(" ");
|
||||
Serial.print(ppm[count]); Serial.print(" ");
|
||||
count++;
|
||||
}
|
||||
*/
|
||||
}
|
||||
Serial.println("");
|
||||
delay(100); //you can even use delays!!!
|
||||
}
|
||||
|
||||
void read_ppm(){ //leave this alone
|
||||
#if F_CPU == 16000000
|
||||
#define PPM_SCALE 1L
|
||||
#elif F_CPU == 8000000
|
||||
#define PPM_SCALE 0L
|
||||
#else
|
||||
#error // 8 or 16MHz only !
|
||||
#endif
|
||||
static unsigned int pulse;
|
||||
static unsigned long counter;
|
||||
static byte channel;
|
||||
|
||||
counter = TCNT1;
|
||||
TCNT1 = 0;
|
||||
|
||||
if(counter < 510 << PPM_SCALE){ pulse = counter; } //must be a pulse if less than 510us
|
||||
else if(counter > 1910 << PPM_SCALE){ channel = 0; } //sync pulses over 1910us
|
||||
else{ ppm[channel] = (counter + pulse) >> PPM_SCALE; channel++; } //servo values between 510us and 2420us will end up here
|
||||
}
|
@ -15,195 +15,323 @@
|
||||
//*******************
|
||||
//*** Pinouts ***
|
||||
//*******************
|
||||
#ifndef STM32_BOARD
|
||||
// TX
|
||||
#define SERIAL_TX_pin 1 //PD1
|
||||
#define SERIAL_TX_port PORTD
|
||||
#define SERIAL_TX_ddr DDRD
|
||||
#define SERIAL_TX_output SERIAL_TX_ddr |= _BV(SERIAL_TX_pin)
|
||||
#define SERIAL_TX_on SERIAL_TX_port |= _BV(SERIAL_TX_pin)
|
||||
#define SERIAL_TX_off SERIAL_TX_port &= ~_BV(SERIAL_TX_pin)
|
||||
#ifdef DEBUG_TX
|
||||
#define DEBUG_TX_on SERIAL_TX_on
|
||||
#define DEBUG_TX_off SERIAL_TX_off
|
||||
#define DEBUG_TX_toggle SERIAL_TX_port ^= _BV(SERIAL_TX_pin)
|
||||
#else
|
||||
#define DEBUG_TX_on
|
||||
#define DEBUG_TX_off
|
||||
#define DEBUG_TX_toggle
|
||||
#endif
|
||||
|
||||
// TX
|
||||
#define SERIAL_TX_pin 1 //PD1
|
||||
#define SERIAL_TX_port PORTD
|
||||
#define SERIAL_TX_ddr DDRD
|
||||
#define SERIAL_TX_output SERIAL_TX_ddr |= _BV(SERIAL_TX_pin)
|
||||
#define SERIAL_TX_on SERIAL_TX_port |= _BV(SERIAL_TX_pin)
|
||||
#define SERIAL_TX_off SERIAL_TX_port &= ~_BV(SERIAL_TX_pin)
|
||||
#ifdef DEBUG_TX
|
||||
#define DEBUG_TX_on SERIAL_TX_ON
|
||||
#define DEBUG_TX_off SERIAL_TX_OFF
|
||||
#define DEBUG_TX_toggle SERIAL_TX_port ^= _BV(SERIAL_TX_pin)
|
||||
#else
|
||||
#define DEBUG_TX_on
|
||||
#define DEBUG_TX_off
|
||||
#define DEBUG_TX_toggle
|
||||
// Dial
|
||||
#define MODE_DIAL1_pin 2
|
||||
#define MODE_DIAL1_port PORTB
|
||||
#define MODE_DIAL1_ipr PINB
|
||||
#define MODE_DIAL2_pin 3
|
||||
#define MODE_DIAL2_port PORTB
|
||||
#define MODE_DIAL2_ipr PINB
|
||||
#define MODE_DIAL3_pin 4
|
||||
#define MODE_DIAL3_port PORTB
|
||||
#define MODE_DIAL3_ipr PINB
|
||||
#define MODE_DIAL4_pin 0
|
||||
#define MODE_DIAL4_port PORTC
|
||||
#define MODE_DIAL4_ipr PINC
|
||||
|
||||
// PPM
|
||||
#define PPM_pin 3 //D3 = PD3
|
||||
#define PPM_port PORTD
|
||||
|
||||
// SDIO
|
||||
#define SDI_pin 5 //D5 = PD5
|
||||
#define SDI_port PORTD
|
||||
#define SDI_ipr PIND
|
||||
#define SDI_ddr DDRD
|
||||
#ifdef ORANGE_TX
|
||||
#define SDI_on SDI_port.OUTSET = _BV(SDI_pin)
|
||||
#define SDI_off SDI_port.OUTCLR = _BV(SDI_pin)
|
||||
#else
|
||||
#define SDI_on SDI_port |= _BV(SDI_pin)
|
||||
#define SDI_off SDI_port &= ~_BV(SDI_pin)
|
||||
#define SDI_1 (SDI_ipr & _BV(SDI_pin))
|
||||
#define SDI_0 (SDI_ipr & _BV(SDI_pin)) == 0x00
|
||||
#endif
|
||||
#define SDI_input SDI_ddr &= ~_BV(SDI_pin)
|
||||
#define SDI_output SDI_ddr |= _BV(SDI_pin)
|
||||
|
||||
//SDO
|
||||
#define SDO_pin 6 //D6 = PD6
|
||||
#define SDO_port PORTD
|
||||
#define SDO_ipr PIND
|
||||
#ifdef ORANGE_TX
|
||||
#define SDO_1 (SDO_port.IN & _BV(SDO_pin))
|
||||
#define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00
|
||||
#else
|
||||
#define SDO_1 (SDO_ipr & _BV(SDO_pin))
|
||||
#define SDO_0 (SDO_ipr & _BV(SDO_pin)) == 0x00
|
||||
#endif
|
||||
|
||||
// SCLK
|
||||
#define SCLK_port PORTD
|
||||
#define SCLK_ddr DDRD
|
||||
#ifdef ORANGE_TX
|
||||
#define SCLK_pin 7 //PD7
|
||||
#define SCLK_on SCLK_port.OUTSET = _BV(SCLK_pin)
|
||||
#define SCLK_off SCLK_port.OUTCLR = _BV(SCLK_pin)
|
||||
#else
|
||||
#define SCLK_pin 4 //D4 = PD4
|
||||
#define SCLK_output SCLK_ddr |= _BV(SCLK_pin)
|
||||
#define SCLK_on SCLK_port |= _BV(SCLK_pin)
|
||||
#define SCLK_off SCLK_port &= ~_BV(SCLK_pin)
|
||||
#endif
|
||||
|
||||
// A7105
|
||||
#define A7105_CSN_pin 2 //D2 = PD2
|
||||
#define A7105_CSN_port PORTD
|
||||
#define A7105_CSN_ddr DDRD
|
||||
#define A7105_CSN_output A7105_CSN_ddr |= _BV(A7105_CSN_pin)
|
||||
#define A7105_CSN_on A7105_CSN_port |= _BV(A7105_CSN_pin)
|
||||
#define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin)
|
||||
|
||||
// CC2500
|
||||
#define CC25_CSN_pin 7 //D7 = PD7
|
||||
#define CC25_CSN_port PORTD
|
||||
#define CC25_CSN_ddr DDRD
|
||||
#define CC25_CSN_output CC25_CSN_ddr |= _BV(CC25_CSN_pin)
|
||||
#define CC25_CSN_on CC25_CSN_port |= _BV(CC25_CSN_pin)
|
||||
#define CC25_CSN_off CC25_CSN_port &= ~_BV(CC25_CSN_pin)
|
||||
|
||||
// NRF24L01
|
||||
#define NRF_CSN_pin 0 //D8 = PB0
|
||||
#define NRF_CSN_port PORTB
|
||||
#define NRF_CSN_ddr DDRB
|
||||
#define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin)
|
||||
#define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin)
|
||||
#define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin)
|
||||
#define NRF_CE_on
|
||||
#define NRF_CE_off
|
||||
|
||||
// CYRF6936
|
||||
#ifdef ORANGE_TX
|
||||
#define CYRF_CSN_pin 4 //PD4
|
||||
#define CYRF_CSN_port PORTD
|
||||
#define CYRF_CSN_ddr DDRD
|
||||
#define CYRF_CSN_on CYRF_CSN_port.OUTSET = _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_off CYRF_CSN_port.OUTCLR = _BV(CYRF_CSN_pin)
|
||||
|
||||
#define CYRF_RST_pin 0 //PE0
|
||||
#define CYRF_RST_port PORTE
|
||||
#define CYRF_RST_ddr DDRE
|
||||
#define CYRF_RST_HI CYRF_RST_port.OUTSET = _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_LO CYRF_RST_port.OUTCLR = _BV(CYRF_RST_pin)
|
||||
#else
|
||||
#define CYRF_CSN_pin 1 //D9 = PB1
|
||||
#define CYRF_CSN_port PORTB
|
||||
#define CYRF_CSN_ddr DDRB
|
||||
#define CYRF_CSN_output CYRF_CSN_ddr |= _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_on CYRF_CSN_port |= _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_off CYRF_CSN_port &= ~_BV(CYRF_CSN_pin)
|
||||
|
||||
#define CYRF_RST_pin 5 //A5 = PC5
|
||||
#define CYRF_RST_port PORTC
|
||||
#define CYRF_RST_ddr DDRC
|
||||
#define CYRF_RST_output CYRF_RST_ddr |= _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_HI CYRF_RST_port |= _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_LO CYRF_RST_port &= ~_BV(CYRF_RST_pin)
|
||||
#endif
|
||||
|
||||
//RF Switch
|
||||
#ifdef ORANGE_TX
|
||||
#define PE1_on
|
||||
#define PE1_off
|
||||
#define PE2_on
|
||||
#define PE2_off
|
||||
#else
|
||||
#define PE1_pin 1 //A1 = PC1
|
||||
#define PE1_port PORTC
|
||||
#define PE1_ddr DDRC
|
||||
#define PE1_output PE1_ddr |= _BV(PE1_pin)
|
||||
#define PE1_on PE1_port |= _BV(PE1_pin)
|
||||
#define PE1_off PE1_port &= ~_BV(PE1_pin)
|
||||
|
||||
#define PE2_pin 2 //A2 = PC2
|
||||
#define PE2_port PORTC
|
||||
#define PE2_ddr DDRC
|
||||
#define PE2_output PE2_ddr |= _BV(PE2_pin)
|
||||
#define PE2_on PE2_port |= _BV(PE2_pin)
|
||||
#define PE2_off PE2_port &= ~_BV(PE2_pin)
|
||||
#endif
|
||||
|
||||
// LED
|
||||
#ifdef ORANGE_TX
|
||||
#define LED_pin 1 //PD1
|
||||
#define LED_port PORTD
|
||||
#define LED_ddr DDRD
|
||||
#define LED_on LED_port.OUTCLR = _BV(LED_pin)
|
||||
#define LED_off LED_port.OUTSET = _BV(LED_pin)
|
||||
#define LED_toggle LED_port.OUTTGL = _BV(LED_pin)
|
||||
#define LED_output LED_port.DIRSET = _BV(LED_pin)
|
||||
#define IS_LED_on (LED_port.OUT & _BV(LED_pin))
|
||||
#else
|
||||
#define LED_pin 5 //D13 = PB5
|
||||
#define LED_port PORTB
|
||||
#define LED_ddr DDRB
|
||||
#define LED_on LED_port |= _BV(LED_pin)
|
||||
#define LED_off LED_port &= ~_BV(LED_pin)
|
||||
#define LED_toggle LED_port ^= _BV(LED_pin)
|
||||
#define LED_output LED_ddr |= _BV(LED_pin)
|
||||
#define IS_LED_on (LED_port & _BV(LED_pin))
|
||||
#endif
|
||||
|
||||
//BIND
|
||||
#ifdef ORANGE_TX
|
||||
#define BIND_pin 2 //PD2
|
||||
#define BIND_port PORTD
|
||||
#define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 )
|
||||
#else
|
||||
#define BIND_pin 5 //D13 = PB5
|
||||
#define BIND_port PORTB
|
||||
#define BIND_ipr PINB
|
||||
#define BIND_ddr DDRB
|
||||
#define BIND_SET_INPUT BIND_ddr &= ~_BV(BIND_pin)
|
||||
#define BIND_SET_OUTPUT BIND_ddr |= _BV(BIND_pin)
|
||||
#define BIND_SET_PULLUP BIND_port |= _BV(BIND_pin)
|
||||
#define IS_BIND_BUTTON_on ( (BIND_ipr & _BV(BIND_pin)) == 0x00 )
|
||||
#endif
|
||||
#else //STM32_BOARD
|
||||
#define BIND_pin PA0
|
||||
#define LED_pin PA1
|
||||
//
|
||||
#define PPM_pin PA8 //PPM 5V tolerant
|
||||
//
|
||||
#define S1_pin PA4 //Dial switch pins
|
||||
#define S2_pin PA5
|
||||
#define S3_pin PA6
|
||||
#define S4_pin PA7
|
||||
//
|
||||
#define PE1_pin PB4 //PE1
|
||||
#define PE2_pin PB5 //PE2
|
||||
//CS pins
|
||||
#define CC25_CSN_pin PB6 //CC2500
|
||||
#define NRF_CSN_pin PB7 //NRF24L01
|
||||
#define CYRF_RST_pin PB8 //CYRF RESET
|
||||
#define A7105_CSN_pin PB9 //A7105
|
||||
#define CYRF_CSN_pin PB12 //CYRF CSN
|
||||
//SPI pins
|
||||
#define SCK_pin PB13 //SCK
|
||||
#define SDO_pin PB14 //MISO
|
||||
#define SDI_pin PB15 //MOSI
|
||||
//
|
||||
#define TX_INV_pin PB3
|
||||
#define RX_INV_pin PB1
|
||||
//
|
||||
#define PE1_on digitalWrite(PE1_pin,HIGH)
|
||||
#define PE1_off digitalWrite(PE1_pin,LOW)
|
||||
//
|
||||
#define PE2_on digitalWrite(PE2_pin,HIGH)
|
||||
#define PE2_off digitalWrite(PE2_pin,LOW)
|
||||
|
||||
#define A7105_CSN_on digitalWrite(A7105_CSN_pin,HIGH)
|
||||
#define A7105_CSN_off digitalWrite(A7105_CSN_pin,LOW)
|
||||
|
||||
#define NRF_CE_on
|
||||
#define NRF_CE_off
|
||||
|
||||
#define SCK_on digitalWrite(SCK_pin,HIGH)
|
||||
#define SCK_off digitalWrite(SCK_pin,LOW)
|
||||
|
||||
#define SDI_on digitalWrite(SDI_pin,HIGH)
|
||||
#define SDI_off digitalWrite(SDI_pin,LOW)
|
||||
|
||||
#define SDI_1 (digitalRead(SDI_pin)==HIGH)
|
||||
#define SDI_0 (digitalRead(SDI_pin)==LOW)
|
||||
|
||||
#define CC25_CSN_on digitalWrite(CC25_CSN_pin,HIGH)
|
||||
#define CC25_CSN_off digitalWrite(CC25_CSN_pin,LOW)
|
||||
|
||||
#define NRF_CSN_on digitalWrite(NRF_CSN_pin,HIGH)
|
||||
#define NRF_CSN_off digitalWrite(NRF_CSN_pin,LOW)
|
||||
|
||||
#define CYRF_CSN_on digitalWrite(CYRF_CSN_pin,HIGH)
|
||||
#define CYRF_CSN_off digitalWrite(CYRF_CSN_pin,LOW)
|
||||
|
||||
#define CYRF_RST_HI digitalWrite(CYRF_RST_pin,HIGH) //reset cyrf
|
||||
#define CYRF_RST_LO digitalWrite(CYRF_RST_pin,LOW) //
|
||||
|
||||
#define SDO_1 (digitalRead(SDO_pin)==HIGH)
|
||||
#define SDO_0 (digitalRead(SDO_pin)==LOW)
|
||||
|
||||
#define TX_INV_on digitalWrite(TX_INV_pin,HIGH)
|
||||
#define TX_INV_off digitalWrite(TX_INV_pin,LOW)
|
||||
|
||||
#define RX_INV_on digitalWrite(RX_INV_pin,HIGH)
|
||||
#define RX_INV_off digitalWrite(RX_INV_pin,LOW)
|
||||
|
||||
#define LED_on digitalWrite(LED_pin,HIGH)
|
||||
#define LED_off digitalWrite(LED_pin,LOW)
|
||||
#define LED_toggle digitalWrite(LED_pin ,!digitalRead(LED_pin))
|
||||
#define LED_output pinMode(LED_pin,OUTPUT)
|
||||
#define IS_LED_on ( digitalRead(LED_pin)==HIGH)
|
||||
|
||||
#define BIND_SET_INPUT pinMode(BIND_pin,INPUT)
|
||||
#define BIND_SET_PULLUP digitalWrite(BIND_pin,HIGH)
|
||||
#define BIND_SET_OUTPUT pinMode(BIND_pin,OUTPUT)
|
||||
#define IS_BIND_BUTTON_on (digitalRead(BIND_pin)==LOW)
|
||||
|
||||
#define cli() noInterrupts()
|
||||
#define sei() interrupts()
|
||||
#define delayMilliseconds(x) delay(x)
|
||||
#endif
|
||||
|
||||
// Dial
|
||||
#define MODE_DIAL1_pin 2
|
||||
#define MODE_DIAL1_port PORTB
|
||||
#define MODE_DIAL1_ipr PINB
|
||||
#define MODE_DIAL2_pin 3
|
||||
#define MODE_DIAL2_port PORTB
|
||||
#define MODE_DIAL2_ipr PINB
|
||||
#define MODE_DIAL3_pin 4
|
||||
#define MODE_DIAL3_port PORTB
|
||||
#define MODE_DIAL3_ipr PINB
|
||||
#define MODE_DIAL4_pin 0
|
||||
#define MODE_DIAL4_port PORTC
|
||||
#define MODE_DIAL4_ipr PINC
|
||||
|
||||
// PPM
|
||||
#define PPM_pin 3 //D3 = PD3
|
||||
#define PPM_port PORTD
|
||||
|
||||
// SDIO
|
||||
#define SDI_pin 5 //D5 = PD5
|
||||
#define SDI_port PORTD
|
||||
#define SDI_ipr PIND
|
||||
#define SDI_ddr DDRD
|
||||
#ifdef XMEGA
|
||||
#define SDI_on SDI_port.OUTSET = _BV(SDI_pin)
|
||||
#define SDI_off SDI_port.OUTCLR = _BV(SDI_pin)
|
||||
//*******************
|
||||
//*** Timer ***
|
||||
//*******************
|
||||
#ifdef ORANGE_TX
|
||||
#define TIFR1 TCC1.INTFLAGS
|
||||
#define OCF1A_bm TC1_CCAIF_bm
|
||||
#define OCR1A TCC1.CCA
|
||||
#define TCNT1 TCC1.CNT
|
||||
#define UDR0 USARTC0.DATA
|
||||
#define OCF1B_bm TC1_CCBIF_bm
|
||||
#define OCR1B TCC1.CCB
|
||||
#define TIMSK1 TCC1.INTCTRLB
|
||||
#define SET_TIMSK1_OCIE1B TIMSK1 = (TIMSK1 & 0xF3) | 0x04
|
||||
#define CLR_TIMSK1_OCIE1B TIMSK1 &= 0xF3
|
||||
#else
|
||||
#define SDI_on SDI_port |= _BV(SDI_pin)
|
||||
#define SDI_off SDI_port &= ~_BV(SDI_pin)
|
||||
#define SDI_1 (SDI_ipr & _BV(SDI_pin))
|
||||
#define SDI_0 (SDI_ipr & _BV(SDI_pin)) == 0x00
|
||||
#endif
|
||||
#define SDI_input SDI_ddr &= ~_BV(SDI_pin)
|
||||
#define SDI_output SDI_ddr |= _BV(SDI_pin)
|
||||
|
||||
//SDO
|
||||
#define SDO_pin 6 //D6 = PD6
|
||||
#define SDO_port PORTD
|
||||
#define SDO_ipr PIND
|
||||
#ifdef XMEGA
|
||||
#define SDO_1 (SDO_port.IN & _BV(SDO_pin))
|
||||
#define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00
|
||||
#else
|
||||
#define SDO_1 (SDO_ipr & _BV(SDO_pin))
|
||||
#define SDO_0 (SDO_ipr & _BV(SDO_pin)) == 0x00
|
||||
#ifdef STM32_BOARD
|
||||
#define OCR1A TIMER2_BASE->CCR1
|
||||
#define TCNT1 TIMER2_BASE->CNT
|
||||
#define UDR0 USART2_BASE->DR
|
||||
#define TIFR1 TIMER2_BASE->SR
|
||||
#define OCF1A_bm TIMER_SR_CC1IF
|
||||
#define UCSR0B USART2_BASE->CR1
|
||||
#define RXCIE0 USART_CR1_RXNEIE_BIT
|
||||
#define TXCIE0 USART_CR1_TXEIE_BIT
|
||||
//#define TIFR1 TIMER2_BASE->SR
|
||||
#else
|
||||
#define OCF1A_bm _BV(OCF1A)
|
||||
#define OCF1B_bm _BV(OCF1B)
|
||||
#define SET_TIMSK1_OCIE1B TIMSK1 |= _BV(OCIE1B)
|
||||
#define CLR_TIMSK1_OCIE1B TIMSK1 &=~_BV(OCIE1B)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SCLK
|
||||
#define SCLK_port PORTD
|
||||
#define SCLK_ddr DDRD
|
||||
#ifdef XMEGA
|
||||
#define SCLK_pin 7 //PD7
|
||||
#define SCLK_on SCLK_port.OUTSET = _BV(SCLK_pin)
|
||||
#define SCLK_off SCLK_port.OUTCLR = _BV(SCLK_pin)
|
||||
//*******************
|
||||
//*** EEPROM ***
|
||||
//*******************
|
||||
#ifdef STM32_BOARD
|
||||
#define EE_ADDR uint16
|
||||
#define eeprom_write_byte EEPROM.write
|
||||
#define eeprom_read_byte EEPROM.read
|
||||
#else
|
||||
#define SCLK_pin 4 //D4 = PD4
|
||||
#define SCLK_output SCLK_ddr |= _BV(SCLK_pin)
|
||||
#define SCLK_on SCLK_port |= _BV(SCLK_pin)
|
||||
#define SCLK_off SCLK_port &= ~_BV(SCLK_pin)
|
||||
#endif
|
||||
|
||||
// A7105
|
||||
#define A7105_CSN_pin 2 //D2 = PD2
|
||||
#define A7105_CSN_port PORTD
|
||||
#define A7105_CSN_ddr DDRD
|
||||
#define A7105_CSN_output A7105_CSN_ddr |= _BV(A7105_CSN_pin)
|
||||
#define A7105_CSN_on A7105_CSN_port |= _BV(A7105_CSN_pin)
|
||||
#define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin)
|
||||
|
||||
// CC2500
|
||||
#define CC25_CSN_pin 7 //D7 = PD7
|
||||
#define CC25_CSN_port PORTD
|
||||
#define CC25_CSN_ddr DDRD
|
||||
#define CC25_CSN_output CC25_CSN_ddr |= _BV(CC25_CSN_pin)
|
||||
#define CC25_CSN_on CC25_CSN_port |= _BV(CC25_CSN_pin)
|
||||
#define CC25_CSN_off CC25_CSN_port &= ~_BV(CC25_CSN_pin)
|
||||
|
||||
// NRF24L01
|
||||
#define NRF_CSN_pin 0 //D8 = PB0
|
||||
#define NRF_CSN_port PORTB
|
||||
#define NRF_CSN_ddr DDRB
|
||||
#define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin)
|
||||
#define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin)
|
||||
#define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin)
|
||||
#define NRF_CE_on
|
||||
#define NRF_CE_off
|
||||
|
||||
// CYRF6936
|
||||
#ifdef XMEGA
|
||||
#define CYRF_CSN_pin 4 //PD4
|
||||
#define CYRF_CSN_port PORTD
|
||||
#define CYRF_CSN_ddr DDRD
|
||||
#define CYRF_CSN_on CYRF_CSN_port.OUTSET = _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_off CYRF_CSN_port.OUTCLR = _BV(CYRF_CSN_pin)
|
||||
|
||||
#define CYRF_RST_pin 0 //PE0
|
||||
#define CYRF_RST_port PORTE
|
||||
#define CYRF_RST_ddr DDRE
|
||||
#define CYRF_RST_HI CYRF_RST_port.OUTSET = _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_LO CYRF_RST_port.OUTCLR = _BV(CYRF_RST_pin)
|
||||
#else
|
||||
#define CYRF_CSN_pin 1 //D9 = PB1
|
||||
#define CYRF_CSN_port PORTB
|
||||
#define CYRF_CSN_ddr DDRB
|
||||
#define CYRF_CSN_output CYRF_CSN_ddr |= _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_on CYRF_CSN_port |= _BV(CYRF_CSN_pin)
|
||||
#define CYRF_CSN_off CYRF_CSN_port &= ~_BV(CYRF_CSN_pin)
|
||||
|
||||
#define CYRF_RST_pin 5 //A5 = PC5
|
||||
#define CYRF_RST_port PORTC
|
||||
#define CYRF_RST_ddr DDRC
|
||||
#define CYRF_RST_output CYRF_RST_ddr |= _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_HI CYRF_RST_port |= _BV(CYRF_RST_pin)
|
||||
#define CYRF_RST_LO CYRF_RST_port &= ~_BV(CYRF_RST_pin)
|
||||
#endif
|
||||
|
||||
//RF Switch
|
||||
#ifdef XMEGA
|
||||
#define PE1_on
|
||||
#define PE1_off
|
||||
#define PE2_on
|
||||
#define PE2_off
|
||||
#else
|
||||
#define PE1_pin 1 //A1 = PC1
|
||||
#define PE1_port PORTC
|
||||
#define PE1_ddr DDRC
|
||||
#define PE1_output PE1_ddr |= _BV(PE1_pin)
|
||||
#define PE1_on PE1_port |= _BV(PE1_pin)
|
||||
#define PE1_off PE1_port &= ~_BV(PE1_pin)
|
||||
|
||||
#define PE2_pin 2 //A2 = PC2
|
||||
#define PE2_port PORTC
|
||||
#define PE2_ddr DDRC
|
||||
#define PE2_output PE2_ddr |= _BV(PE2_pin)
|
||||
#define PE2_on PE2_port |= _BV(PE2_pin)
|
||||
#define PE2_off PE2_port &= ~_BV(PE2_pin)
|
||||
#endif
|
||||
|
||||
// LED
|
||||
#ifdef XMEGA
|
||||
#define LED_pin 1 //PD1
|
||||
#define LED_port PORTD
|
||||
#define LED_ddr DDRD
|
||||
#define LED_on LED_port.OUTCLR = _BV(LED_pin)
|
||||
#define LED_off LED_port.OUTSET = _BV(LED_pin)
|
||||
#define LED_toggle LED_port.OUTTGL = _BV(LED_pin)
|
||||
#define LED_output LED_port.DIRSET = _BV(LED_pin)
|
||||
#define IS_LED_on (LED_port.OUT & _BV(LED_pin))
|
||||
#else
|
||||
#define LED_pin 5 //D13 = PB5
|
||||
#define LED_port PORTB
|
||||
#define LED_ddr DDRB
|
||||
#define LED_on LED_port |= _BV(LED_pin)
|
||||
#define LED_off LED_port &= ~_BV(LED_pin)
|
||||
#define LED_toggle LED_port ^= _BV(LED_pin)
|
||||
#define LED_output LED_ddr |= _BV(LED_pin)
|
||||
#define IS_LED_on (LED_port & _BV(LED_pin))
|
||||
#endif
|
||||
|
||||
//BIND
|
||||
#ifdef XMEGA
|
||||
#define BIND_pin 2 //PD2
|
||||
#define BIND_port PORTD
|
||||
#define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 )
|
||||
#else
|
||||
#define BIND_pin 5 //D13 = PB5
|
||||
#define BIND_port PORTB
|
||||
#define BIND_ipr PINB
|
||||
#define BIND_ddr DDRB
|
||||
#define BIND_SET_INPUT BIND_ddr &= ~_BV(BIND_pin)
|
||||
#define BIND_SET_OUTPUT BIND_ddr |= _BV(BIND_pin)
|
||||
#define BIND_SET_PULLUP BIND_port |= _BV(BIND_pin)
|
||||
#define IS_BIND_BUTTON_on ( (BIND_ipr & _BV(BIND_pin)) == 0x00 )
|
||||
#define EE_ADDR uint8_t*
|
||||
#endif
|
||||
|
275
Multiprotocol/README.md
Normal file
275
Multiprotocol/README.md
Normal file
@ -0,0 +1,275 @@
|
||||
# DIY-Multiprotocol-TX-Module
|
||||
|
||||
 
|
||||
|
||||
Fork du projet https://github.com/pascallanger/DIY-Multiprotocol-TX-Module
|
||||
|
||||
Afin d'ajouter :
|
||||
- Un rebind hardware en PPM
|
||||
- La radio TARANIS (TAERB, B = rebind ;-) ) et redéclaration des radios
|
||||
|
||||
|
||||
|
||||
Programme des évolutions :
|
||||
- Ajout du futur protocole INAV
|
||||
|
||||
|
||||
#Schematic
|
||||

|
||||
|
||||
Notes:
|
||||
- Attention: All modules are 3.3V only, never power them with 5V.
|
||||
|
||||
|
||||
#Protocoles ajoutés mais non testés (Issue de Deviation)
|
||||
##Other
|
||||
###OPENLRS
|
||||
Empty protocol
|
||||
|
||||
##CYRF6936 RF Module
|
||||
###J6PRO
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|---|---|---
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
###WK2x01
|
||||
Autobind
|
||||
|
||||
####Sub_protocol WK2401
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
CH1|CH2|CH3|CH4
|
||||
|
||||
|
||||
####Sub_protocol WK2601
|
||||
Option:
|
||||
|
||||
0 = 5+1
|
||||
2 = 6+1
|
||||
..1 = Hélicoptère (. = autres options pour ce mode)
|
||||
.01 = Hélicoptère normal
|
||||
.11 = Hélicoptère avec pit inversé
|
||||
0.1 = Pitch curve -100
|
||||
1.1 = Pitch curve 100
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
CH1|CH2|CH3|CH4|???|CONF|Gyro & Rudder mix
|
||||
|
||||
CONF: Option 1 = Rate Throtle
|
||||
|
||||
Option 2 = Pitch
|
||||
|
||||
|
||||
####Sub_protocol WK2801
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
|
||||
|
||||
##A7105 RF Module
|
||||
###Flysky AFHDS2A
|
||||
Telemetry enabled for battery voltage and TX RSSI
|
||||
Option= 0-PWM_IBUS 1-PPM_IBUS 2-PWM_SBUS 3-PPM_SBUS
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15
|
||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
|
||||
T|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|Failsave T
|
||||
|
||||
###HUBSAN
|
||||
Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
|
||||
|
||||
Autobind protocol
|
||||
|
||||
Telemetry enabled for battery voltage and TX RSSI
|
||||
|
||||
Option=vTX frequency (H107D) 5645 - 5900 MHz
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||
####Sub_protocol H301
|
||||
CH5|CH6|CH7|CH8
|
||||
---|---|---|---
|
||||
LED|STAB|RTH|VIDEO
|
||||
|
||||
####Sub_protocol H501
|
||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|---|---|---
|
||||
FLIP|LIGHT|RTH|VIDEO|HEADLESS|GPS_HOLD|ALT_HOLD|SNAPSHOT
|
||||
|
||||
###Joysway
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
A|E|T|R
|
||||
|
||||
##CC2500 RF Module
|
||||
###SKYARTEC
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
? | ? | ? | ? | ? | ? | ?
|
||||
|
||||
##NRF24L01 RF Module
|
||||
###BLUEFLY
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6
|
||||
---|---|---|---|---|---
|
||||
A|E|T|R|GEAR|PITCH
|
||||
|
||||
###CFLIE
|
||||
Modele: CrazyFlie Nano quad
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
A|E|T|R
|
||||
|
||||
###CG023
|
||||
###Sub_protocol H8_3D
|
||||
Models: EAchine H8 mini 3D, JJRC H20/H22, JJRC H11D
|
||||
|
||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|---|---
|
||||
FLIP|LIGTH|OPT1|OPT2|CAL|SNAPSHOT|VIDEO
|
||||
|
||||
JJRC H20: OPT1=Headless, OPT2=RTH
|
||||
|
||||
JJRC H22: OPT1=RTH, OPT2=180/360° flip mode
|
||||
|
||||
H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), OPT2=switch 180/360° flip mode
|
||||
|
||||
CAL: calibrate accelerometers
|
||||
|
||||
###ESKY150
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
A|E|T|R
|
||||
|
||||
###FBL100
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
? | ? | ? | ? | ? | ? | ? | ?
|
||||
|
||||
####Sub_protocol HP100
|
||||
Same channels assignement as above.
|
||||
|
||||
###Fy326
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP|HEADLESS|RTH|Calibrate|Expert
|
||||
|
||||
####Sub_protocol FY319
|
||||
Same channels assignement as above.
|
||||
|
||||
###H377
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8
|
||||
|
||||
###HISKY
|
||||
####Sub_protocol HK310
|
||||
|
||||
###HM830
|
||||
Modele: HM Hobby HM830 RC Paper Airplane
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---
|
||||
A|Turbo|T|Trim|Bouton
|
||||
|
||||
###HONTAI
|
||||
Autobind protocol
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|---|---|---|---|----|----
|
||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
||||
|
||||
####Sub_protocol HONTAI
|
||||
####Sub_protocol JJRCX1
|
||||
CH6|
|
||||
---|
|
||||
ARM|
|
||||
|
||||
####Sub_protocol X5C1
|
||||
X5C1 clone
|
||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|----|----
|
||||
FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
||||
####Sub_protocol FQ777
|
||||
Format FQ777-951C
|
||||
|
||||
CH6|CH7|CH8|CH9
|
||||
---|---|---|---
|
||||
FLIP|SNAPSHOT|VIDEO|HEADLESS
|
||||
|
||||
###INAV
|
||||
En cours de passage
|
||||
|
||||
###MJX
|
||||
####Sub_protocol H26WH
|
||||
|
||||
###NE260
|
||||
Modele: Nine Eagles SoloPro
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
A|E|T|R
|
||||
|
||||
###Q303
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|AHOLD|FLIP|SNAPSHOT|VIDEO|HEADLESS|RTH|GIMBAL
|
||||
|
||||
###UDI
|
||||
Modele: Known UDI 2.4GHz protocol variants, all using BK2421
|
||||
* UDI U819 coaxial 3ch helicoper
|
||||
* UDI U816/817/818 quadcopters
|
||||
- "V1" with orange LED on TX, U816 RX labeled '' , U817/U818 RX labeled 'UD-U817B'
|
||||
- "V2" with red LEDs on TX, U816 RX labeled '', U817/U818 RX labeled 'UD-U817OG'
|
||||
- "V3" with green LEDs on TX. Did not get my hands on yet.
|
||||
* U830 mini quadcopter with tilt steering ("Protocol 2014")
|
||||
* U839 nano quadcopter ("Protocol 2014")
|
||||
|
||||
Autobind
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP 360|FLIP|VIDEO|LED|MODE 2
|
||||
|
||||
####Sub_protocol U816_V1 (orange)
|
||||
####Sub_protocol U816_V2 (red)
|
||||
####Sub_protocol U839_2014
|
||||
Same channels assignement as above.
|
||||
|
||||
###V2X2
|
||||
####Sub_protocol V2X2
|
||||
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|---|---|---|---|----|----
|
||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|MAG_CAL_X|MAG_CAL_Y
|
||||
|
||||
PICTURE: also automatic Missile Launcher and Hoist in one direction
|
||||
|
||||
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir
|
||||
####Sub_protocol JXD-506
|
||||
CH10|CH11|CH12
|
||||
----|----|----
|
||||
ARM|EMERGENCY|PAN CAMERA
|
||||
|
||||
###D'autres à venir
|
@ -1,5 +1,3 @@
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
/*
|
||||
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
|
||||
@ -15,7 +13,6 @@
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
@ -42,17 +39,10 @@ void SHENQI_init()
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address
|
||||
|
||||
<<<<<<< HEAD
|
||||
LT8910_Config(4, 8, _BV(LT8910_CRC_ON)|_BV(LT8910_PACKET_LENGTH_EN), 0xAA);
|
||||
LT8910_SetChannel(2);
|
||||
LT8910_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4);
|
||||
LT8910_SetTxRxMode(RX_EN);
|
||||
=======
|
||||
LT8900_Config(4, 8, _BV(LT8900_CRC_ON)|_BV(LT8900_PACKET_LENGTH_EN), 0xAA);
|
||||
LT8900_SetChannel(2);
|
||||
LT8900_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4);
|
||||
LT8900_SetTxRxMode(RX_EN);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
}
|
||||
|
||||
void SHENQI_send_packet()
|
||||
@ -61,16 +51,6 @@ void SHENQI_send_packet()
|
||||
if(packet_count==0)
|
||||
{
|
||||
uint8_t bind_addr[4];
|
||||
<<<<<<< HEAD
|
||||
bind_addr[0]=0x9A;
|
||||
bind_addr[1]=0x9A;
|
||||
bind_addr[2]=rx_tx_addr[2];
|
||||
bind_addr[3]=rx_tx_addr[3];
|
||||
LT8910_SetAddress(bind_addr,4);
|
||||
LT8910_SetChannel(2);
|
||||
packet[1]=rx_tx_addr[1];
|
||||
packet[2]=rx_tx_addr[0];
|
||||
=======
|
||||
bind_addr[0]=rx_tx_addr[0];
|
||||
bind_addr[1]=rx_tx_addr[1];
|
||||
bind_addr[2]=0x9A;
|
||||
@ -79,39 +59,24 @@ void SHENQI_send_packet()
|
||||
LT8900_SetChannel(2);
|
||||
packet[1]=rx_tx_addr[2];
|
||||
packet[2]=rx_tx_addr[3];
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet_period=2508;
|
||||
}
|
||||
else
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
LT8910_SetAddress(rx_tx_addr,4);
|
||||
packet[1]=255-convert_channel_8b(RUDDER);
|
||||
packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0);
|
||||
uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[1]&0x0F);
|
||||
LT8910_SetChannel(freq);
|
||||
=======
|
||||
LT8900_SetAddress(rx_tx_addr,4);
|
||||
packet[1]=255-convert_channel_8b(RUDDER);
|
||||
packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0);
|
||||
uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[2]&0x0F);
|
||||
LT8900_SetChannel(freq);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no==60)
|
||||
hopping_frequency_no=0;
|
||||
packet_period=1750;
|
||||
}
|
||||
// Send packet + 1 retransmit - not sure why but needed (not present on original TX...)
|
||||
<<<<<<< HEAD
|
||||
LT8910_WritePayload(packet,3);
|
||||
while(NRF24L01_packet_ack()!=PKT_ACKED);
|
||||
LT8910_WritePayload(packet,3);
|
||||
=======
|
||||
LT8900_WritePayload(packet,3);
|
||||
while(NRF24L01_packet_ack()!=PKT_ACKED);
|
||||
LT8900_WritePayload(packet,3);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
||||
packet_count++;
|
||||
if(packet_count==7)
|
||||
@ -129,16 +94,6 @@ uint16_t SHENQI_callback()
|
||||
SHENQI_send_packet();
|
||||
else
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
||||
{
|
||||
if(LT8910_ReadPayload(packet, 3))
|
||||
{
|
||||
BIND_DONE;
|
||||
rx_tx_addr[3]=packet[1];
|
||||
rx_tx_addr[2]=packet[2];
|
||||
LT8910_SetTxRxMode(TX_EN);
|
||||
=======
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{
|
||||
if(LT8900_ReadPayload(packet, 3))
|
||||
@ -147,7 +102,6 @@ uint16_t SHENQI_callback()
|
||||
rx_tx_addr[0]=packet[1];
|
||||
rx_tx_addr[1]=packet[2];
|
||||
LT8900_SetTxRxMode(TX_EN);
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
packet_period=14000;
|
||||
}
|
||||
NRF24L01_FlushRx();
|
||||
@ -162,11 +116,7 @@ uint16_t initSHENQI()
|
||||
SHENQI_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count=0;
|
||||
<<<<<<< HEAD
|
||||
packet_period=100;
|
||||
=======
|
||||
packet_period=500;
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
return 1000;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
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/slt_nrf24l01.c dated 2015-02-13
|
||||
// Last sync with deviation main github branch
|
||||
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
|
||||
@ -24,11 +24,11 @@
|
||||
#define SLT_TXID_SIZE 4
|
||||
|
||||
enum {
|
||||
SLT_INIT2 = 0,
|
||||
SLT_BIND,
|
||||
SLT_BUILD=0,
|
||||
SLT_DATA1,
|
||||
SLT_DATA2,
|
||||
SLT_DATA3
|
||||
SLT_DATA3,
|
||||
SLT_BIND
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) SLT_init()
|
||||
@ -45,24 +45,18 @@ static void __attribute__((unused)) SLT_init()
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xC3\xC3\xAA\x55", 4);
|
||||
NRF24L01_FlushRx();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_init2()
|
||||
{
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
|
||||
NRF24L01_FlushTx();
|
||||
packet_sent = 0;
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
// Turn radio power on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_set_tx_id(void)
|
||||
static void __attribute__((unused)) SLT_set_freq(void)
|
||||
{
|
||||
// Frequency hopping sequence generation
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
for (uint8_t i = 0; i < SLT_TXID_SIZE; ++i)
|
||||
{
|
||||
uint8_t next_i = (i+1) % 4; // is & 3 better than % 4 ?
|
||||
uint8_t next_i = (i+1) % SLT_TXID_SIZE; // is & 3 better than % 4 ?
|
||||
uint8_t base = i < 2 ? 0x03 : 0x10;
|
||||
hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base;
|
||||
hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base;
|
||||
@ -72,8 +66,9 @@ static void __attribute__((unused)) SLT_set_tx_id(void)
|
||||
}
|
||||
|
||||
// unique
|
||||
uint8_t done = 0;
|
||||
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
|
||||
{
|
||||
uint8_t done = 0;
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
@ -86,14 +81,13 @@ static void __attribute__((unused)) SLT_set_tx_id(void)
|
||||
hopping_frequency[i] = hopping_frequency[i] - 0x50 + 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_wait_radio()
|
||||
{
|
||||
if (packet_sent)
|
||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ;
|
||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
||||
packet_sent = 0;
|
||||
}
|
||||
|
||||
@ -109,9 +103,15 @@ 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) {
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
{
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i]);
|
||||
packet[i] = v;
|
||||
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
||||
@ -121,81 +121,71 @@ static void __attribute__((unused)) SLT_build_packet()
|
||||
// 8-bit channels
|
||||
packet[5] = convert_channel_8b(AUX1);
|
||||
packet[6] = convert_channel_8b(AUX2);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||
{
|
||||
SLT_wait_radio();
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", 4);
|
||||
BIND_DONE;
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50);
|
||||
SLT_send_data(rx_tx_addr, 4);
|
||||
SLT_send_data(rx_tx_addr, SLT_TXID_SIZE);
|
||||
|
||||
// NB: we should wait until the packet's sent before changing TX address!
|
||||
SLT_wait_radio();
|
||||
SLT_wait_radio(); //Wait until the packet's sent before changing TX address!
|
||||
|
||||
BIND_DONE;
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4);
|
||||
NRF24L01_SetPower(); //Change power back to normal level
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
|
||||
}
|
||||
|
||||
uint16_t SLT_callback()
|
||||
{
|
||||
uint16_t delay_us = 20000; // 3 packets with 1ms intervals every 22ms
|
||||
switch (phase)
|
||||
{
|
||||
case SLT_INIT2:
|
||||
SLT_init2();
|
||||
phase = SLT_BIND;
|
||||
delay_us = 150;
|
||||
break;
|
||||
case SLT_BIND:
|
||||
SLT_send_bind_packet();
|
||||
phase = SLT_DATA1;
|
||||
delay_us = 19000;
|
||||
break;
|
||||
case SLT_DATA1:
|
||||
case SLT_BUILD:
|
||||
SLT_build_packet();
|
||||
SLT_send_data(packet, 7);
|
||||
phase = SLT_DATA2;
|
||||
delay_us = 1000;
|
||||
break;
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA1:
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA2:
|
||||
SLT_send_data(packet, 7);
|
||||
phase = SLT_DATA3;
|
||||
delay_us = 1000;
|
||||
break;
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
phase++;
|
||||
return 1000;
|
||||
case SLT_DATA3:
|
||||
SLT_send_data(packet, 7);
|
||||
if (++counter >= 100)
|
||||
SLT_send_data(packet, SLT_PAYLOADSIZE);
|
||||
if (++packet_count >= 100)
|
||||
{
|
||||
counter = 0;
|
||||
phase = SLT_BIND;
|
||||
delay_us = 1000;
|
||||
packet_count = 0;
|
||||
phase++;
|
||||
return 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
phase = SLT_DATA1;
|
||||
phase = SLT_BUILD;
|
||||
return 19000;
|
||||
}
|
||||
break;
|
||||
case SLT_BIND:
|
||||
SLT_send_bind_packet();
|
||||
phase = SLT_BUILD;
|
||||
return 18000;
|
||||
}
|
||||
return delay_us;
|
||||
return 19000;
|
||||
}
|
||||
|
||||
uint16_t initSLT()
|
||||
{
|
||||
counter = 0;
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
hopping_frequency_no = 0;
|
||||
SLT_set_freq();
|
||||
SLT_init();
|
||||
phase = SLT_INIT2;
|
||||
SLT_set_tx_id();
|
||||
phase = SLT_BIND;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
|
@ -15,72 +15,145 @@
|
||||
/********************/
|
||||
/** SPI routines **/
|
||||
/********************/
|
||||
#ifdef XMEGA
|
||||
#define XNOP() NOP()
|
||||
#ifdef STM32_BOARD
|
||||
|
||||
SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port
|
||||
|
||||
void initSPI2()
|
||||
{
|
||||
//SPI_DISABLE();
|
||||
SPI_2.end();
|
||||
SPI2_BASE->CR1 &= ~SPI_CR1_DFF_8_BIT; //8 bits format This bit should be written only when SPI is disabled (SPE = ?0?) for correct operation.
|
||||
SPI_2.begin(); //Initialize the SPI_2 port.
|
||||
|
||||
SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
|
||||
SPI_2.setDataMode(SPI_MODE0); // Set the SPI_2 data mode 0
|
||||
SPI_2.setClockDivider(SPI_CLOCK_DIV8); // Set the speed (36 / 8 = 4.5 MHz SPI_2 speed)
|
||||
}
|
||||
|
||||
void SPI_Write(uint8_t command)
|
||||
{//working OK
|
||||
SPI2_BASE->DR = command; //Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag).
|
||||
while (!(SPI2_BASE->SR & SPI_SR_RXNE));
|
||||
command = SPI2_BASE->DR; // ... and read the last received data.
|
||||
}
|
||||
|
||||
uint8_t SPI_Read(void)
|
||||
{
|
||||
SPI_Write(0x00);
|
||||
return SPI2_BASE->DR;
|
||||
}
|
||||
|
||||
uint8_t SPI_SDI_Read()
|
||||
{
|
||||
uint8_t rx=0;
|
||||
cli(); //Fix Hubsan droputs??
|
||||
while(!(SPI2_BASE->SR & SPI_SR_TXE));
|
||||
while((SPI2_BASE->SR & SPI_SR_BSY));
|
||||
//
|
||||
SPI_DISABLE();
|
||||
SPI_SET_BIDIRECTIONAL();
|
||||
volatile uint8_t x = SPI2_BASE->DR;
|
||||
(void)x;
|
||||
SPI_ENABLE();
|
||||
//
|
||||
SPI_DISABLE();
|
||||
while(!(SPI2_BASE->SR& SPI_SR_RXNE));
|
||||
rx=SPI2_BASE->DR;
|
||||
SPI_SET_UNIDIRECTIONAL();
|
||||
SPI_ENABLE();
|
||||
sei();//fix Hubsan dropouts??
|
||||
return rx;
|
||||
}
|
||||
|
||||
void SPI_ENABLE()
|
||||
{
|
||||
SPI2_BASE->CR1 |= SPI_CR1_SPE;
|
||||
}
|
||||
|
||||
void SPI_DISABLE()
|
||||
{
|
||||
SPI2_BASE->CR1 &= ~SPI_CR1_SPE;
|
||||
}
|
||||
|
||||
void SPI_SET_BIDIRECTIONAL()
|
||||
{
|
||||
SPI2_BASE->CR1 |= SPI_CR1_BIDIMODE;
|
||||
SPI2_BASE->CR1 &= ~ SPI_CR1_BIDIOE;//receive only
|
||||
}
|
||||
|
||||
void SPI_SET_UNIDIRECTIONAL()
|
||||
{
|
||||
SPI2_BASE->CR1 &= ~SPI_CR1_BIDIMODE;
|
||||
}
|
||||
#else
|
||||
#define XNOP()
|
||||
#endif
|
||||
#ifdef ORANGE_TX
|
||||
#define XNOP() NOP()
|
||||
#else
|
||||
#define XNOP()
|
||||
#endif
|
||||
|
||||
void SPI_Write(uint8_t command)
|
||||
{
|
||||
uint8_t n=8;
|
||||
|
||||
SCLK_off;//SCK start low
|
||||
XNOP();
|
||||
SDI_off;
|
||||
XNOP();
|
||||
do
|
||||
void SPI_Write(uint8_t command)
|
||||
{
|
||||
if(command&0x80)
|
||||
SDI_on;
|
||||
else
|
||||
SDI_off;
|
||||
XNOP();
|
||||
SCLK_on;
|
||||
XNOP();
|
||||
XNOP();
|
||||
command = command << 1;
|
||||
SCLK_off;
|
||||
XNOP();
|
||||
}
|
||||
while(--n) ;
|
||||
SDI_on;
|
||||
}
|
||||
uint8_t n=8;
|
||||
|
||||
uint8_t SPI_Read(void)
|
||||
{
|
||||
uint8_t result=0,i;
|
||||
for(i=0;i<8;i++)
|
||||
SCLK_off;//SCK start low
|
||||
XNOP();
|
||||
SDI_off;
|
||||
XNOP();
|
||||
do
|
||||
{
|
||||
if(command&0x80)
|
||||
SDI_on;
|
||||
else
|
||||
SDI_off;
|
||||
XNOP();
|
||||
SCLK_on;
|
||||
XNOP();
|
||||
XNOP();
|
||||
command = command << 1;
|
||||
SCLK_off;
|
||||
XNOP();
|
||||
}
|
||||
while(--n) ;
|
||||
SDI_on;
|
||||
}
|
||||
|
||||
uint8_t SPI_Read(void)
|
||||
{
|
||||
result=result<<1;
|
||||
if(SDO_1)
|
||||
result |= 0x01;
|
||||
SCLK_on;
|
||||
XNOP();
|
||||
XNOP();
|
||||
NOP();
|
||||
SCLK_off;
|
||||
XNOP();
|
||||
XNOP();
|
||||
uint8_t result=0,i;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
result=result<<1;
|
||||
if(SDO_1)
|
||||
result |= 0x01;
|
||||
SCLK_on;
|
||||
XNOP();
|
||||
XNOP();
|
||||
NOP();
|
||||
SCLK_off;
|
||||
XNOP();
|
||||
XNOP();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef A7105_INSTALLED
|
||||
uint8_t SPI_SDIO_Read(void)
|
||||
{
|
||||
uint8_t result=0;
|
||||
SDI_input;
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
{
|
||||
result=result<<1;
|
||||
if(SDI_1) ///if SDIO =1
|
||||
result |= 0x01;
|
||||
SCLK_on;
|
||||
NOP();
|
||||
SCLK_off;
|
||||
#ifdef A7105_INSTALLED
|
||||
uint8_t SPI_SDI_Read(void)
|
||||
{
|
||||
uint8_t result=0;
|
||||
SDI_input;
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
{
|
||||
result=result<<1;
|
||||
if(SDI_1) ///if SDIO =1
|
||||
result |= 0x01;
|
||||
SCLK_on;
|
||||
NOP();
|
||||
SCLK_off;
|
||||
}
|
||||
SDI_output;
|
||||
return result;
|
||||
}
|
||||
SDI_output;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif//STM32_BOARD
|
@ -22,6 +22,16 @@
|
||||
#define PPM_MIN_125 1000 // 125%
|
||||
#endif
|
||||
|
||||
// TAARANIS PPM and channels
|
||||
#if defined(TX_TARANIS)
|
||||
#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 INVERT_TELEMETRY
|
||||
#endif
|
||||
|
||||
// HISKY
|
||||
#if defined(TX_HISKY)
|
||||
#define PPM_MAX_100 1900 // 100%
|
||||
@ -37,7 +47,6 @@
|
||||
#define PPM_MAX_125 2050 // 125%
|
||||
#define PPM_MIN_125 1150 // 125%
|
||||
#endif
|
||||
|
||||
//Serial MIN MAX values
|
||||
#define SERIAL_MAX_100 2012 // 100%
|
||||
#define SERIAL_MIN_100 988 // 100%
|
||||
@ -47,203 +56,156 @@
|
||||
//PPM values used to compare
|
||||
#define PPM_MIN_COMMAND 1250
|
||||
#define PPM_SWITCH 1550
|
||||
#define PPM_SWITCH_B 1450
|
||||
#define PPM_MAX_COMMAND 1750
|
||||
|
||||
//Channel definitions
|
||||
#ifdef AETR
|
||||
enum {
|
||||
AILERON =0,
|
||||
ELEVATOR,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
#ifdef AERT
|
||||
enum {
|
||||
AILERON =0,
|
||||
ELEVATOR,
|
||||
RUDDER,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef ARET
|
||||
enum {
|
||||
AILERON =0,
|
||||
RUDDER,
|
||||
ELEVATOR,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef ARTE
|
||||
enum {
|
||||
AILERON =0,
|
||||
RUDDER,
|
||||
THROTTLE,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef ATRE
|
||||
enum {
|
||||
AILERON =0,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef ATER
|
||||
enum {
|
||||
AILERON =0,
|
||||
THROTTLE,
|
||||
ELEVATOR,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
|
||||
#ifdef EATR
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
AILERON,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
#ifdef EART
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
AILERON,
|
||||
RUDDER,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef ERAT
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
RUDDER,
|
||||
AILERON,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef ERTA
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
RUDDER,
|
||||
THROTTLE,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef ETRA
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef ETAR
|
||||
enum {
|
||||
ELEVATOR =0,
|
||||
THROTTLE,
|
||||
AILERON,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 0
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
|
||||
#ifdef TEAR
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
ELEVATOR,
|
||||
AILERON,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
#ifdef TERA
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
ELEVATOR,
|
||||
RUDDER,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef TREA
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
RUDDER,
|
||||
ELEVATOR,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef TRAE
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
RUDDER,
|
||||
AILERON,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 1
|
||||
#endif
|
||||
#ifdef TARE
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
AILERON,
|
||||
RUDDER,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 2
|
||||
#endif
|
||||
#ifdef TAER
|
||||
enum {
|
||||
THROTTLE =0,
|
||||
AILERON,
|
||||
ELEVATOR,
|
||||
RUDDER,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 0
|
||||
#define RUDDER 3
|
||||
#endif
|
||||
|
||||
#ifdef RETA
|
||||
enum {
|
||||
RUDDER =0,
|
||||
ELEVATOR,
|
||||
THROTTLE,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
#ifdef REAT
|
||||
enum {
|
||||
RUDDER =0,
|
||||
ELEVATOR,
|
||||
AILERON,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 1
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
#ifdef RAET
|
||||
enum {
|
||||
RUDDER =0,
|
||||
AILERON,
|
||||
ELEVATOR,
|
||||
THROTTLE,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 3
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
#ifdef RATE
|
||||
enum {
|
||||
RUDDER =0,
|
||||
AILERON,
|
||||
THROTTLE,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 1
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 2
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
#ifdef RTAE
|
||||
enum {
|
||||
RUDDER =0,
|
||||
THROTTLE,
|
||||
AILERON,
|
||||
ELEVATOR,
|
||||
};
|
||||
#define AILERON 2
|
||||
#define ELEVATOR 3
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
#ifdef RTEA
|
||||
enum {
|
||||
RUDDER =0,
|
||||
THROTTLE,
|
||||
ELEVATOR,
|
||||
AILERON,
|
||||
};
|
||||
#define AILERON 3
|
||||
#define ELEVATOR 2
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
|
||||
#define AUX1 4
|
||||
|
@ -1,178 +1,3 @@
|
||||
<<<<<<< HEAD
|
||||
//*************************************
|
||||
// FrSky Telemetry serial code *
|
||||
// By Midelic on RCGroups *
|
||||
//*************************************
|
||||
|
||||
#if defined TELEMETRY
|
||||
#if defined FRSKYX_CC2500_INO
|
||||
#define SPORT_TELEMETRY
|
||||
#endif
|
||||
#if defined FRSKY_CC2500_INO
|
||||
#define HUB_TELEMETRY
|
||||
#endif
|
||||
#if defined SPORT_TELEMETRY
|
||||
#define SPORT_TELEMETRY
|
||||
#define SPORT_TIME 12000
|
||||
uint32_t last=0;
|
||||
uint8_t sport_counter=0;
|
||||
uint8_t RxBt=0;
|
||||
uint8_t rssi;
|
||||
uint8_t ADC2;
|
||||
#endif
|
||||
#if defined HUB_TELEMETRY
|
||||
#define MAX_PKTX 10
|
||||
uint8_t pktx[MAX_PKTX];
|
||||
uint8_t index;
|
||||
uint8_t prev_index;
|
||||
uint8_t pass = 0;
|
||||
#endif
|
||||
#define USER_MAX_BYTES 6
|
||||
uint8_t frame[18];
|
||||
|
||||
void frskySendStuffed()
|
||||
{
|
||||
Serial_write(0x7E);
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
if ((frame[i] == 0x7e) || (frame[i] == 0x7d))
|
||||
{
|
||||
Serial_write(0x7D);
|
||||
frame[i] ^= 0x20;
|
||||
}
|
||||
Serial_write(frame[i]);
|
||||
}
|
||||
Serial_write(0x7E);
|
||||
}
|
||||
|
||||
void compute_RSSIdbm(){
|
||||
|
||||
RSSI_dBm = (((uint16_t)(pktt[len-2])*18)>>5);
|
||||
if(pktt[len-2] >=128)
|
||||
RSSI_dBm -= 82;
|
||||
else
|
||||
RSSI_dBm += 65;
|
||||
}
|
||||
|
||||
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)
|
||||
{//only packets with the required id and packet length
|
||||
for(uint8_t i=3;i<6;i++)
|
||||
pktt[i]=0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t i=3;i<len;i++)
|
||||
pktt[i]=pkt[i];
|
||||
telemetry_link=1;
|
||||
if(pktt[6]>0)
|
||||
telemetry_counter=(telemetry_counter+1)%32;
|
||||
}
|
||||
}
|
||||
|
||||
void frsky_link_frame()
|
||||
{
|
||||
frame[0] = 0xFE;
|
||||
if ((cur_protocol[0]&0x1F)==MODE_FRSKY)
|
||||
{
|
||||
compute_RSSIdbm();
|
||||
frame[1] = pktt[3];
|
||||
frame[2] = pktt[4];
|
||||
frame[3] = (uint8_t)RSSI_dBm;
|
||||
frame[4] = pktt[5]*2;
|
||||
}
|
||||
else
|
||||
if ((cur_protocol[0]&0x1F)==MODE_HUBSAN)
|
||||
{
|
||||
frame[1] = v_lipo*2; //v_lipo; common 0x2A=42/10=4.2V
|
||||
frame[2] = frame[1];
|
||||
frame[3] = 0x00;
|
||||
frame[4] = (uint8_t)RSSI_dBm;
|
||||
}
|
||||
frame[5] = frame[6] = frame[7] = frame[8] = 0;
|
||||
frskySendStuffed();
|
||||
}
|
||||
|
||||
#if defined HUB_TELEMETRY
|
||||
void frsky_user_frame()
|
||||
{
|
||||
uint8_t indexx = 0, c=0, j=8, n=0, i;
|
||||
|
||||
if(pktt[6]>0 && pktt[6]<=MAX_PKTX)
|
||||
{//only valid hub frames
|
||||
frame[0] = 0xFD;
|
||||
frame[1] = 0;
|
||||
frame[2] = pktt[7];
|
||||
|
||||
switch(pass)
|
||||
{
|
||||
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:
|
||||
index=indexx;
|
||||
prev_index = indexx;
|
||||
if(index<USER_MAX_BYTES)
|
||||
{
|
||||
for(i=0;i<index;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pktt[6]=0;
|
||||
pass=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = USER_MAX_BYTES;
|
||||
for(i=0;i<index;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pass=2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
index = prev_index - index;
|
||||
prev_index=0;
|
||||
if(index<MAX_PKTX-USER_MAX_BYTES) //10-6=4
|
||||
for(i=0;i<index;i++)
|
||||
frame[i+3]=pktx[USER_MAX_BYTES+i];
|
||||
pass=0;
|
||||
pktt[6]=0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!index)
|
||||
return;
|
||||
frame[1] = index;
|
||||
frskySendStuffed();
|
||||
}
|
||||
else
|
||||
pass=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined SPORT_TELEMETRY
|
||||
|
||||
/* SPORT details serial
|
||||
100K 8E2 normal-multiprotocol
|
||||
-every 12ms-
|
||||
1 2 3 4 5 6 7 8 9 CRC DESCR
|
||||
=======
|
||||
/*
|
||||
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
|
||||
@ -212,7 +37,7 @@
|
||||
#define MAX_PKTX 10
|
||||
uint8_t pktx[MAX_PKTX];
|
||||
uint8_t pktx1[MAX_PKTX];
|
||||
uint8_t index;
|
||||
uint8_t indx;
|
||||
uint8_t frame[18];
|
||||
|
||||
#ifdef BASH_SERIAL
|
||||
@ -236,6 +61,15 @@ void DSM_frame()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined AFHDS2A_TELEMETRY
|
||||
void AFHDSA_short_frame()
|
||||
{
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||
Serial_write(pkt[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void frskySendStuffed()
|
||||
{
|
||||
Serial_write(START_STOP);
|
||||
@ -272,6 +106,7 @@ void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
||||
telemetry_counter=(telemetry_counter+1)%32;
|
||||
//
|
||||
#if defined SPORT_TELEMETRY && defined FRSKYX_CC2500_INO
|
||||
telemetry_lost=0;
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{
|
||||
if ((pktt[5] >> 4 & 0x0f) == 0x08)
|
||||
@ -304,12 +139,12 @@ void frsky_link_frame()
|
||||
frame[4] = (uint8_t)RSSI_dBm;
|
||||
}
|
||||
else
|
||||
if (protocol==MODE_HUBSAN)
|
||||
if (protocol==MODE_HUBSAN||protocol==MODE_AFHDS2A)
|
||||
{
|
||||
frame[1] = v_lipo*2; //v_lipo; common 0x2A=42/10=4.2V
|
||||
frame[2] = frame[1];
|
||||
frame[3] = 0x00;
|
||||
frame[4] = (uint8_t)RSSI_dBm;
|
||||
frame[3] = protocol==MODE_HUBSAN?0x00:(uint8_t)RSSI_dBm;
|
||||
frame[4] = TX_RSSI;
|
||||
}
|
||||
frame[5] = frame[6] = frame[7] = frame[8] = 0;
|
||||
frskySendStuffed();
|
||||
@ -346,28 +181,28 @@ void frsky_user_frame()
|
||||
pass=1;
|
||||
|
||||
case 1:
|
||||
index=indexx;
|
||||
indx=indexx;
|
||||
prev_index = indexx;
|
||||
if(index<USER_MAX_BYTES)
|
||||
if(indx<USER_MAX_BYTES)
|
||||
{
|
||||
for(i=0;i<index;i++)
|
||||
for(i=0;i<indx;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pktt[6]=0;
|
||||
pass=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = USER_MAX_BYTES;
|
||||
for(i=0;i<index;i++)
|
||||
indx = USER_MAX_BYTES;
|
||||
for(i=0;i<indx;i++)
|
||||
frame[i+3]=pktx[i];
|
||||
pass=2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
index = prev_index - index;
|
||||
indx = prev_index - indx;
|
||||
prev_index=0;
|
||||
if(index<=(MAX_PKTX-USER_MAX_BYTES)) //10-6=4
|
||||
for(i=0;i<index;i++)
|
||||
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;
|
||||
@ -375,9 +210,9 @@ void frsky_user_frame()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!index)
|
||||
if(!indx)
|
||||
return;
|
||||
frame[1] = index;
|
||||
frame[1] = indx;
|
||||
frskySendStuffed();
|
||||
}
|
||||
else
|
||||
@ -405,7 +240,6 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
100K 8E2 normal-multiprotocol
|
||||
-every 12ms-or multiple of 12; %36
|
||||
1 2 3 4 5 6 7 8 9 CRC DESCR
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
7E 98 10 05 F1 20 23 0F 00 A6 SWR_ID
|
||||
7E 98 10 01 F1 33 00 00 00 C9 RSSI_ID
|
||||
7E 98 10 04 F1 58 00 00 00 A1 BATT_ID
|
||||
@ -417,24 +251,15 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
Telemetry frames(RF) SPORT info 15 bytes
|
||||
SPORT frame 6+3 bytes
|
||||
=======
|
||||
Telemetry frames(RF) SPORT info
|
||||
15 bytes payload
|
||||
SPORT frame valid 6+3 bytes
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
[00] PKLEN 0E 0E 0E 0E
|
||||
[01] TXID1 DD DD DD DD
|
||||
[02] TXID2 6D 6D 6D 6D
|
||||
[03] CONST 02 02 02 02
|
||||
[04] RS/RB 2C D0 2C CE //D0;CE=2*RSSI;....2C = RX battery voltage(5V from Bec)
|
||||
<<<<<<< HEAD
|
||||
[05] ????? 03 10 21 32 //TX/RX telemetry hand-shake bytes
|
||||
=======
|
||||
[05] HD-SK 03 10 21 32 //TX/RX telemetry hand-shake bytes
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
[06] NO.BT 00 00 06 03 //No.of valid SPORT frame bytes in the frame
|
||||
[07] STRM1 00 00 7E 00
|
||||
[08] STRM2 00 00 1A 00
|
||||
@ -442,146 +267,6 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
[10] STRM4 03 03 03 03
|
||||
[11] STRM5 F1 F1 F1 F1
|
||||
[12] STRM6 D1 D1 D0 D0
|
||||
<<<<<<< HEAD
|
||||
[13] CHKSUM1
|
||||
[14] CHKSUM2
|
||||
*/
|
||||
|
||||
|
||||
void sportSend(uint8_t *p)
|
||||
{
|
||||
uint16_t crc_s = 0;
|
||||
Serial_write(0x7e);//+9
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i == 8)
|
||||
p[i] = 0xff - crc_s;
|
||||
if ((p[i] == 0x7e) || (p[i] == 0x7d))
|
||||
{
|
||||
Serial_write(0x7d);
|
||||
Serial_write(0x20 ^ p[i]);
|
||||
}
|
||||
else
|
||||
Serial_write(p[i]);
|
||||
if (i>0)
|
||||
{
|
||||
crc_s += p[i]; //0-1FF
|
||||
crc_s += crc_s >> 8; //0-100
|
||||
crc_s &= 0x00ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sportIdle()
|
||||
{
|
||||
Serial_write(0x7e);
|
||||
}
|
||||
|
||||
void sportSendFrame()
|
||||
{
|
||||
//at the moment only SWR RSSI,RxBt and A2.
|
||||
sport_counter = (sport_counter + 1) %9;
|
||||
|
||||
for (uint8_t i=5;i<8;i++)
|
||||
frame[i]=0;
|
||||
|
||||
switch (sport_counter)
|
||||
{
|
||||
case 0: // SWR
|
||||
frame[0] = 0x98;
|
||||
frame[1] = 0x10;
|
||||
frame[2] = 0x05;
|
||||
frame[3] = 0xf1;
|
||||
frame[4] = 0x20;//dummy values if swr 20230f00
|
||||
frame[5] = 0x23;
|
||||
frame[6] = 0x0F;
|
||||
frame[7] = 0x00;
|
||||
break;
|
||||
case 1: // RSSI
|
||||
frame[0] = 0x98;
|
||||
frame[1] = 0x10;
|
||||
frame[2] = 0x01;
|
||||
frame[3] = 0xf1;
|
||||
frame[4] = rssi;
|
||||
break;
|
||||
case 2: //BATT
|
||||
frame[0] = 0x98;
|
||||
frame[1] = 0x10;
|
||||
frame[2] = 0x04;
|
||||
frame[3] = 0xf1;
|
||||
frame[4] = RxBt;//a1;
|
||||
break;
|
||||
case 3: //ADC2(A2)
|
||||
frame[0] = 0x1A;
|
||||
frame[1] = 0x10;
|
||||
frame[2] = 0x03;
|
||||
frame[3] = 0xf1;
|
||||
frame[4] = ADC2;//a2;;
|
||||
break;
|
||||
default:
|
||||
sportIdle();
|
||||
return;
|
||||
}
|
||||
sportSend(frame);
|
||||
}
|
||||
|
||||
void process_sport_data()//only for ADC2
|
||||
{
|
||||
uint8_t j=7;
|
||||
if(pktt[6]>0 && pktt[6]<=USER_MAX_BYTES)
|
||||
{
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
if(pktt[j++]==0x03)
|
||||
if(pktt[j]==0xF1)
|
||||
{
|
||||
ADC2=pktt[j+1];
|
||||
break;
|
||||
}
|
||||
pktt[6]=0;//new frame
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void frskyUpdate()
|
||||
{
|
||||
if(telemetry_link && (cur_protocol[0]&0x1F) != MODE_FRSKYX )
|
||||
{
|
||||
frsky_link_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if(!telemetry_link && (cur_protocol[0]&0x1F) != MODE_HUBSAN && (cur_protocol[0]&0x1F) != MODE_FRSKYX)
|
||||
{
|
||||
frsky_user_frame();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined SPORT_TELEMETRY
|
||||
if ((cur_protocol[0]&0x1F)==MODE_FRSKYX)
|
||||
{
|
||||
if(telemetry_link)
|
||||
{
|
||||
process_sport_data();
|
||||
if(pktt[4]>0x36)
|
||||
rssi=pktt[4]/2;
|
||||
else
|
||||
RxBt=pktt[4];
|
||||
telemetry_link=0;
|
||||
}
|
||||
uint32_t now = micros();
|
||||
if ((now - last) > SPORT_TIME)
|
||||
{
|
||||
sportSendFrame();
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
=======
|
||||
[13] CHKSUM1 --|2 CRC bytes sent by RX (calculated on RX side crc16/table)
|
||||
[14] CHKSUM2 --|
|
||||
+2 appended bytes automatically RSSI and LQI/CRC bytes(len=0x0E+3);
|
||||
@ -635,7 +320,11 @@ void sportSendFrame()
|
||||
{
|
||||
uint8_t i;
|
||||
sport_counter = (sport_counter + 1) %36;
|
||||
|
||||
if(telemetry_lost)
|
||||
{
|
||||
sportIdle();
|
||||
return;
|
||||
}
|
||||
if(sport_counter<6)
|
||||
{
|
||||
frame[0] = 0x98;
|
||||
@ -686,30 +375,30 @@ void proces_sport_data(uint8_t data)
|
||||
case 0:
|
||||
if (data == START_STOP)
|
||||
{//waiting for 0x7e
|
||||
index = 0;
|
||||
indx = 0;
|
||||
pass = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (data == START_STOP) // Happens if missed packet
|
||||
{//waiting for 0x7e
|
||||
index = 0;
|
||||
indx = 0;
|
||||
pass = 1;
|
||||
break;
|
||||
}
|
||||
if(data == BYTESTUFF)//if they are stuffed
|
||||
pass=2;
|
||||
else
|
||||
if (index < MAX_PKTX)
|
||||
pktx[index++] = data;
|
||||
if (indx < MAX_PKTX)
|
||||
pktx[indx++] = data;
|
||||
break;
|
||||
case 2:
|
||||
if (index < MAX_PKTX)
|
||||
pktx[index++] = data ^ STUFF_MASK; //unstuff bytes
|
||||
if (indx < MAX_PKTX)
|
||||
pktx[indx++] = data ^ STUFF_MASK; //unstuff bytes
|
||||
pass=1;
|
||||
break;
|
||||
} // end switch
|
||||
if (index >= FRSKY_SPORT_PACKET_SIZE)
|
||||
if (indx >= FRSKY_SPORT_PACKET_SIZE)
|
||||
{//8 bytes no crc
|
||||
if ( sport )
|
||||
{
|
||||
@ -732,93 +421,99 @@ void proces_sport_data(uint8_t data)
|
||||
|
||||
void TelemetryUpdate()
|
||||
{
|
||||
#if defined SPORT_TELEMETRY
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{ // FrSkyX
|
||||
if(telemetry_link)
|
||||
{
|
||||
if(pktt[4] & 0x80)
|
||||
rssi=pktt[4] & 0x7F ;
|
||||
else
|
||||
RxBt = (pktt[4]<<1) + 1 ;
|
||||
for (uint8_t i=0; i < pktt[6]; i++)
|
||||
proces_sport_data(pktt[7+i]);
|
||||
telemetry_link=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for space in tx buffer
|
||||
|
||||
#ifdef BASH_SERIAL
|
||||
uint8_t h ;
|
||||
uint8_t t ;
|
||||
h = SerialControl.head ;
|
||||
t = SerialControl.tail ;
|
||||
if ( h >= t )
|
||||
{
|
||||
t += 64 - h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
t -= h ;
|
||||
}
|
||||
if ( t < 32 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined DSM_TELEMETRY
|
||||
if(telemetry_link && protocol == MODE_DSM )
|
||||
{ // DSM
|
||||
DSM_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(telemetry_link && protocol != MODE_FRSKYX )
|
||||
{ // FrSky + Hubsan
|
||||
frsky_link_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if(!telemetry_link && protocol == MODE_FRSKYD)
|
||||
{ // FrSky
|
||||
frsky_user_frame();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined SPORT_TELEMETRY
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{ // FrSkyX
|
||||
uint32_t now = micros();
|
||||
if ((now - last) > SPORT_TIME)
|
||||
#ifdef BASH_SERIAL
|
||||
uint8_t h ;
|
||||
uint8_t t ;
|
||||
h = SerialControl.head ;
|
||||
t = SerialControl.tail ;
|
||||
if ( h >= t )
|
||||
{
|
||||
sportSendFrame();
|
||||
last += SPORT_TIME ;
|
||||
t += 64 - h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
t -= h ;
|
||||
}
|
||||
if ( t < 32 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined SPORT_TELEMETRY
|
||||
if (protocol==MODE_FRSKYX)
|
||||
{ // FrSkyX
|
||||
if(telemetry_link)
|
||||
{
|
||||
if(pktt[4] & 0x80)
|
||||
rssi=pktt[4] & 0x7F ;
|
||||
else
|
||||
RxBt = (pktt[4]<<1) + 1 ;
|
||||
if(pktt[6]<=6)
|
||||
for (uint8_t i=0; i < pktt[6]; i++)
|
||||
proces_sport_data(pktt[7+i]);
|
||||
telemetry_link=0;
|
||||
}
|
||||
uint32_t now = micros();
|
||||
if ((now - last) > SPORT_TIME)
|
||||
{
|
||||
sportSendFrame();
|
||||
#ifdef STM32_BOARD
|
||||
last=now;
|
||||
#else
|
||||
last += SPORT_TIME ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined DSM_TELEMETRY
|
||||
if(telemetry_link && protocol == MODE_DSM )
|
||||
{ // DSM
|
||||
DSM_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined AFHDS2A_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == MODE_AFHDS2A)
|
||||
{
|
||||
AFHDSA_short_frame();
|
||||
telemetry_link=0;
|
||||
}
|
||||
#endif
|
||||
if(telemetry_link && protocol != MODE_FRSKYX )
|
||||
{ // FrSkyD + Hubsan + AFHDS2A
|
||||
frsky_link_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if(!telemetry_link && protocol == MODE_FRSKYD)
|
||||
{ // FrSky
|
||||
frsky_user_frame();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -829,94 +524,139 @@ void TelemetryUpdate()
|
||||
/**************************/
|
||||
|
||||
#ifndef BASH_SERIAL
|
||||
// Routines for normal serial output
|
||||
void Serial_write(uint8_t data)
|
||||
{
|
||||
uint8_t nextHead ;
|
||||
nextHead = tx_head + 1 ;
|
||||
if ( nextHead >= TXBUFFER_SIZE )
|
||||
nextHead = 0 ;
|
||||
tx_buff[nextHead]=data;
|
||||
tx_head = nextHead ;
|
||||
tx_resume();
|
||||
}
|
||||
|
||||
void initTXSerial( uint8_t speed)
|
||||
{
|
||||
#ifdef ENABLE_PPM
|
||||
if(speed==SPEED_9600)
|
||||
{ // 9600
|
||||
#ifdef XMEGA
|
||||
USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;
|
||||
#else
|
||||
//9600 bauds
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x67;
|
||||
UCSR0A = 0 ; // Clear X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
}
|
||||
else if(speed==SPEED_57600)
|
||||
{ // 57600
|
||||
#ifdef XMEGA
|
||||
/*USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;*/
|
||||
#else
|
||||
//57600 bauds
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x22;
|
||||
UCSR0A = 0x02 ; // Set X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
}
|
||||
else if(speed==SPEED_125K)
|
||||
{ // 125000
|
||||
#ifdef XMEGA
|
||||
/*USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;*/
|
||||
#else
|
||||
//125000 bauds
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x07;
|
||||
UCSR0A = 0x00 ; // Clear X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifndef XMEGA
|
||||
UCSR0B |= (1<<TXEN0);//tx enable
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XMEGA
|
||||
ISR(USARTC0_DRE_vect)
|
||||
#else
|
||||
ISR(USART_UDRE_vect)
|
||||
#endif
|
||||
{ // Transmit interrupt
|
||||
if(tx_head!=tx_tail)
|
||||
// Routines for normal serial output
|
||||
void Serial_write(uint8_t data)
|
||||
{
|
||||
if(++tx_tail>=TXBUFFER_SIZE)//head
|
||||
tx_tail=0;
|
||||
UDR0=tx_buff[tx_tail];
|
||||
uint8_t nextHead ;
|
||||
nextHead = tx_head + 1 ;
|
||||
if ( nextHead >= TXBUFFER_SIZE )
|
||||
nextHead = 0 ;
|
||||
tx_buff[nextHead]=data;
|
||||
tx_head = nextHead ;
|
||||
tx_resume();
|
||||
}
|
||||
if (tx_tail == tx_head)
|
||||
tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
|
||||
}
|
||||
|
||||
void initTXSerial( uint8_t speed)
|
||||
{
|
||||
#ifdef ENABLE_PPM
|
||||
if(speed==SPEED_9600)
|
||||
{ // 9600
|
||||
#ifdef ORANGE_TX
|
||||
USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(9600,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x67;
|
||||
UCSR0A = 0 ; // Clear X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else if(speed==SPEED_57600)
|
||||
{ // 57600
|
||||
#ifdef ORANGE_TX
|
||||
/*USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;*/
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(57600,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x22;
|
||||
UCSR0A = 0x02 ; // Set X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else if(speed==SPEED_125K)
|
||||
{ // 125000
|
||||
#ifdef ORANGE_TX
|
||||
/*USARTC0.BAUDCTRLA = 207 ;
|
||||
USARTC0.BAUDCTRLB = 0 ;
|
||||
USARTC0.CTRLB = 0x18 ;
|
||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
||||
USARTC0.CTRLC = 0x03 ;*/
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(125000,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x07;
|
||||
UCSR0A = 0x00 ; // Clear X2 bit
|
||||
//Set frame format to 8 data bits, none, 1 stop bit
|
||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifndef ORANGE_TX
|
||||
#ifndef STM32_BOARD
|
||||
UCSR0B |= (1<<TXEN0);//tx enable
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//Serial TX
|
||||
#ifdef ORANGE_TX
|
||||
ISR(USARTC0_DRE_vect)
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
void __irq_usart3()
|
||||
#else
|
||||
ISR(USART_UDRE_vect)
|
||||
#endif
|
||||
#endif
|
||||
{ // Transmit interrupt
|
||||
#ifdef STM32_BOARD
|
||||
if(USART3_BASE->SR & USART_SR_TXE)
|
||||
{
|
||||
#endif
|
||||
if(tx_head!=tx_tail)
|
||||
{
|
||||
if(++tx_tail>=TXBUFFER_SIZE)//head
|
||||
tx_tail=0;
|
||||
#ifdef STM32_BOARD
|
||||
USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit
|
||||
#else
|
||||
UDR0=tx_buff[tx_tail];
|
||||
#endif
|
||||
}
|
||||
if (tx_tail == tx_head)
|
||||
tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
|
||||
#ifdef STM32_BOARD
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef STM32_BOARD
|
||||
void usart2_begin(uint32_t baud,uint32_t config )
|
||||
{
|
||||
usart_init(USART2);
|
||||
usart_config_gpios_async(USART2,GPIOA,PIN_MAP[PA3].gpio_bit,GPIOA,PIN_MAP[PA2].gpio_bit,config);
|
||||
usart_set_baud_rate(USART2, STM32_PCLK1, baud);//
|
||||
usart_enable(USART2);
|
||||
}
|
||||
void usart3_begin(uint32_t baud,uint32_t config )
|
||||
{
|
||||
usart_init(USART3);
|
||||
usart_config_gpios_async(USART3,GPIOB,PIN_MAP[PB11].gpio_bit,GPIOB,PIN_MAP[PB10].gpio_bit,config);
|
||||
usart_set_baud_rate(USART3, STM32_PCLK1, baud);
|
||||
usart_enable(USART3);
|
||||
}
|
||||
#endif
|
||||
#else //BASH_SERIAL
|
||||
// Routines for bit-bashed serial output
|
||||
|
||||
@ -1149,4 +889,3 @@ ISR(TIMER0_OVF_vect)
|
||||
#endif // BASH_SERIAL
|
||||
|
||||
#endif // TELEMETRY
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
|
@ -15,6 +15,8 @@
|
||||
// compatible with WLToys V2x2, JXD JD38x, JD39x, JJRC H6C, Yizhan Tarantula X6 ...
|
||||
// Last sync with hexfet new_protocols/v202_nrf24l01.c dated 2015-03-15
|
||||
|
||||
// ajout jdx506 : https://github.com/DeviationTX/deviation/compare/master...goebish:protocol_jxd_506
|
||||
|
||||
#if defined(V2X2_NRF24L01_INO)
|
||||
|
||||
|
||||
@ -40,7 +42,12 @@ enum {
|
||||
// flags going to byte 10
|
||||
V2X2_FLAG_HEADLESS = 0x02,
|
||||
V2X2_FLAG_MAG_CAL_X = 0x08,
|
||||
V2X2_FLAG_MAG_CAL_Y = 0x20
|
||||
V2X2_FLAG_MAG_CAL_Y = 0x20,
|
||||
//
|
||||
JXD_FLAG_START_STOP= 0x40, // arm / disarm JXD-506
|
||||
JXD_FLAG_EMERGENCY = 0x80, // JXD-506
|
||||
JXD_FLAG_CAMERA_UP = 0x01, // JXD-506
|
||||
JXD_FLAG_CAMERA_DN = 0x02, // JXD-506
|
||||
};
|
||||
|
||||
//
|
||||
@ -182,12 +189,26 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind)
|
||||
// Channel 9
|
||||
if (Servo_AUX5)
|
||||
flags2 = V2X2_FLAG_HEADLESS;
|
||||
// Channel 10
|
||||
if (Servo_AUX6)
|
||||
flags2 |= V2X2_FLAG_MAG_CAL_X;
|
||||
// Channel 11
|
||||
if (Servo_AUX7)
|
||||
flags2 |= V2X2_FLAG_MAG_CAL_Y;
|
||||
|
||||
if(sub_protocol == FORMAT_JXD506) {
|
||||
// Channel 10
|
||||
if (Servo_AUX6) flags2 |= JXD_FLAG_START_STOP;
|
||||
// Channel 11
|
||||
if (Servo_AUX7) flags2 |= JXD_FLAG_EMERGENCY;
|
||||
|
||||
// Channel 12 down
|
||||
if (Servo_data[AUX8] < PPM_SWITCH_B) flags2 |= JXD_FLAG_CAMERA_DN;
|
||||
// Channel 12 up
|
||||
if (Servo_data[AUX8] > PPM_SWITCH) flags2 |= JXD_FLAG_CAMERA_UP;
|
||||
|
||||
} else {
|
||||
// Channel 10
|
||||
if (Servo_AUX6)
|
||||
flags2 |= V2X2_FLAG_MAG_CAL_X;
|
||||
// Channel 11
|
||||
if (Servo_AUX7)
|
||||
flags2 |= V2X2_FLAG_MAG_CAL_Y;
|
||||
}
|
||||
}
|
||||
// TX id
|
||||
packet[7] = rx_tx_addr[1];
|
||||
|
101
Multiprotocol/Validate.h
Normal file
101
Multiprotocol/Validate.h
Normal file
@ -0,0 +1,101 @@
|
||||
// Check selected board type
|
||||
#if defined (STM32_BOARD) && defined (ORANGE_TX)
|
||||
#error You must comment the board type STM32_BOARD in _Config.h to compile ORANGE_TX
|
||||
#endif
|
||||
#if not defined (ORANGE_TX) && not defined (STM32_BOARD)
|
||||
//Atmega328p
|
||||
#if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
|
||||
#error You must select one of these boards: "Multi 4-in-1", "Arduino Pro or Pro Mini" or "Arduino Mini"
|
||||
#endif
|
||||
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
||||
#error You must select the processor type "ATmega328(5V, 16MHz)"
|
||||
#endif
|
||||
#endif
|
||||
#if defined (STM32_BOARD) && not defined (ORANGE_TX)
|
||||
//STM32
|
||||
#ifndef ARDUINO_GENERIC_STM32F103C
|
||||
#error You must select the board type "Generic STM32F103C series"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Change/Force configuration if OrangeTX
|
||||
#ifdef ORANGE_TX
|
||||
#undef ENABLE_PPM // Disable PPM for OrangeTX module
|
||||
#undef A7105_INSTALLED // Disable A7105 for OrangeTX module
|
||||
#undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module
|
||||
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
|
||||
#define TELEMETRY // Enable telemetry
|
||||
#define INVERT_TELEMETRY // Enable invert telemetry
|
||||
#define DSM_TELEMETRY // Enable DSM telemetry
|
||||
#endif
|
||||
|
||||
//Make sure protocols are selected correctly
|
||||
#ifndef A7105_INSTALLED
|
||||
#undef FLYSKY_A7105_INO
|
||||
#undef HUBSAN_A7105_INO
|
||||
#undef AFHDS2A_A7105_INO
|
||||
#endif
|
||||
#ifndef CYRF6936_INSTALLED
|
||||
#undef DEVO_CYRF6936_INO
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef J6PRO_CYRF6936_INO
|
||||
#endif
|
||||
#ifndef CC2500_INSTALLED
|
||||
#undef FRSKYD_CC2500_INO
|
||||
#undef FRSKYV_CC2500_INO
|
||||
#undef FRSKYX_CC2500_INO
|
||||
#undef SFHSS_CC2500_INO
|
||||
#endif
|
||||
#ifndef NRF24L01_INSTALLED
|
||||
#undef BAYANG_NRF24L01_INO
|
||||
#undef CG023_NRF24L01_INO
|
||||
#undef CX10_NRF24L01_INO
|
||||
#undef ESKY_NRF24L01_INO
|
||||
#undef HISKY_NRF24L01_INO
|
||||
#undef KN_NRF24L01_INO
|
||||
#undef SLT_NRF24L01_INO
|
||||
#undef SYMAX_NRF24L01_INO
|
||||
#undef V2X2_NRF24L01_INO
|
||||
#undef YD717_NRF24L01_INO
|
||||
#undef MT99XX_NRF24L01_INO
|
||||
#undef MJXQ_NRF24L01_INO
|
||||
#undef SHENQI_NRF24L01_INO
|
||||
#undef FY326_NRF24L01_INO
|
||||
#undef FQ777_NRF24L01_INO
|
||||
#undef ASSAN_NRF24L01_INO
|
||||
#undef HONTAI_NRF24L01_INO
|
||||
#endif
|
||||
|
||||
//Make sure telemetry is selected correctly
|
||||
#ifndef TELEMETRY
|
||||
#undef INVERT_TELEMETRY
|
||||
#undef DSM_TELEMETRY
|
||||
#undef SPORT_TELEMETRY
|
||||
#undef HUB_TELEMETRY
|
||||
#undef AFHDS2A_TELEMETRY
|
||||
#else
|
||||
#if not defined(DSM_CYRF6936_INO)
|
||||
#undef DSM_TELEMETRY
|
||||
#endif
|
||||
#if not defined(FRSKYD_CC2500_INO) && not defined(HUBSAN_A7105_INO) && not defined(AFHDS2A_A7105_INO)
|
||||
#undef HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(FRSKYX_CC2500_INO)
|
||||
#undef SPORT_TELEMETRY
|
||||
#endif
|
||||
#if not defined(AFHDS2A_A7105_INO)
|
||||
#undef AFHDS2A_TELEMETRY
|
||||
#endif
|
||||
#if not defined(DSM_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(AFHDS2A_TELEMETRY)
|
||||
#undef TELEMETRY
|
||||
#undef INVERT_TELEMETRY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Make sure TX is defined correctly
|
||||
#ifndef AILERON
|
||||
#error You must select a correct channel order.
|
||||
#endif
|
||||
#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
|
@ -34,16 +34,6 @@
|
||||
|
||||
#define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused
|
||||
|
||||
<<<<<<< HEAD
|
||||
enum {
|
||||
YD717_INIT1 = 0,
|
||||
YD717_BIND2,
|
||||
YD717_BIND3,
|
||||
YD717_DATA
|
||||
};
|
||||
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
|
||||
{
|
||||
uint8_t rudder_trim, elevator_trim, aileron_trim;
|
||||
@ -149,11 +139,6 @@ static void __attribute__((unused)) yd717_init()
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) YD717_init1()
|
||||
{
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// for bind packets set address to prearranged value known to receiver
|
||||
uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65};
|
||||
|
||||
@ -168,16 +153,6 @@ static void __attribute__((unused)) YD717_init1()
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static void __attribute__((unused)) YD717_init2()
|
||||
{
|
||||
// set rx/tx address for data phase
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
uint16_t yd717_callback()
|
||||
{
|
||||
if(IS_BIND_DONE_on)
|
||||
|
@ -13,98 +13,32 @@
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
<<<<<<< HEAD
|
||||
/** Multiprotocol module configuration file ***/
|
||||
|
||||
//Uncomment your TX type
|
||||
#define TARANIS //TARANIS TAER (1100<->1900µs)
|
||||
//#define TX_ER9X //ER9X AETR (988<->2012µs)
|
||||
//#define TX_DEVO7 //DEVO7 EATR (1120<->1920µs)
|
||||
//#define TX_SPEKTRUM //Spektrum TAER (1100<->1900µs)
|
||||
//#define TX_HISKY //HISKY AETR (1100<->1900µs)
|
||||
|
||||
//Uncomment to enable telemetry
|
||||
#define TELEMETRY
|
||||
|
||||
//Comment if a module is not installed
|
||||
#define A7105_INSTALLED
|
||||
#define CYRF6936_INSTALLED
|
||||
//#define CC2500_INSTALLED
|
||||
#define NFR24L01_INSTALLED
|
||||
|
||||
//Comment a protocol to exclude it from compilation
|
||||
#ifdef A7105_INSTALLED
|
||||
#define JOYSWAY_A7105_INO
|
||||
|
||||
#define FLYSKY_A7105_INO
|
||||
#define HUBSAN_A7105_INO
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#define J6PRO_CYRF6936_INO
|
||||
#define WK2x01_CYRF6936_INO
|
||||
|
||||
#define DEVO_CYRF6936_INO
|
||||
#define DSM2_CYRF6936_INO
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#define SKYARTEC_CC2500_INO
|
||||
|
||||
#define FRSKY_CC2500_INO
|
||||
#define FRSKYX_CC2500_INO
|
||||
#endif
|
||||
#ifdef NFR24L01_INSTALLED
|
||||
#define HM830_NRF24L01_INO
|
||||
#define CFlie_NRF24L01_INO
|
||||
#define H377_NRF24L01_INO
|
||||
#define ESKY150_NRF24L01_INO
|
||||
#define HonTai_NRF24L01_INO
|
||||
#define UDI_NRF24L01_INO
|
||||
#define NE260_NRF24L01_INO
|
||||
#define BlueFly_NRF24L01_INO //probleme gene id
|
||||
#define FBL100_NRF24L01_INO // finir id
|
||||
|
||||
#define BAYANG_NRF24L01_INO
|
||||
#define CG023_NRF24L01_INO
|
||||
#define CX10_NRF24L01_INO
|
||||
#define ESKY_NRF24L01_INO
|
||||
#define HISKY_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define SLT_NRF24L01_INO
|
||||
#define SYMAX_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
#define MT99XX_NRF24L01_INO
|
||||
#define MJXQ_NRF24L01_INO
|
||||
#define SHENQI_NRF24L01_INO
|
||||
#define FY326_NRF24L01_INO
|
||||
#endif
|
||||
|
||||
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
|
||||
const PPM_Parameters PPM_prot[15]= {
|
||||
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option
|
||||
/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 },
|
||||
/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 3 */ {MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, // D7 fine tuning
|
||||
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 6 */ {MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // 6 channels @ 11ms
|
||||
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 9 */ {MODE_KN , FEILUN , 0 , P_HIGH , AUTOBIND , 0 },
|
||||
=======
|
||||
/**********************************************/
|
||||
/** 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 ***/
|
||||
/*******************/
|
||||
//Modify the channel order based on your TX: AETR, TAER, RETA...
|
||||
//Examples: Flysky & DEVO is AETR, JR/Spektrum radio is TAER, Multiplex is AERT...
|
||||
//Default is AETR.
|
||||
#define AETR
|
||||
#define EATR
|
||||
|
||||
|
||||
//Modify the channel for a software reset modul: AUX...(channel number - 4)
|
||||
//Default is AUX10 (channel 14).
|
||||
#define SWITCH_RESET 14
|
||||
|
||||
/**************************/
|
||||
/*** RF CHIPS INSTALLED ***/
|
||||
/**************************/
|
||||
@ -112,53 +46,70 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
//If a chip is not installed all associated protocols are disabled.
|
||||
//4-in-1 modules have all RF chips installed
|
||||
//!!!If a RF chip is present it MUST be marked as installed!!! or weird things will happen you have been warned.
|
||||
#define A7105_INSTALLED
|
||||
#define CYRF6936_INSTALLED
|
||||
#define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
#define A7105_INSTALLED
|
||||
#define CYRF6936_INSTALLED
|
||||
// #define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
|
||||
|
||||
/****************************/
|
||||
/*** PROTOCOLS TO INCLUDE ***/
|
||||
/****************************/
|
||||
//In this section select the protocols you want to be accessible when using the module.
|
||||
//All the protocols will not fit in the module so you need to pick and choose.
|
||||
//All the protocols will not fit in the Atmega328p module so you need to pick and choose.
|
||||
//Comment the protocols you are not using with "//" to save Flash space.
|
||||
|
||||
//The protocols below need an A7105 to be installed
|
||||
#define FLYSKY_A7105_INO
|
||||
#define HUBSAN_A7105_INO
|
||||
#define JOYSWAY_A7105_INO
|
||||
|
||||
#define FLYSKY_A7105_INO
|
||||
#define HUBSAN_A7105_INO
|
||||
#define AFHDS2A_A7105_INO
|
||||
//The protocols below need a CYRF6936 to be installed
|
||||
#define DEVO_CYRF6936_INO
|
||||
#define DSM_CYRF6936_INO
|
||||
#define J6PRO_CYRF6936_INO
|
||||
// #define WK2x01_CYRF6936_INO //!\\ //pb voie
|
||||
|
||||
#define DEVO_CYRF6936_INO
|
||||
#define DSM_CYRF6936_INO
|
||||
// #define J6PRO_CYRF6936_INO
|
||||
|
||||
//The protocols below need a CC2500 to be installed
|
||||
#define FRSKYD_CC2500_INO
|
||||
#define FRSKYV_CC2500_INO
|
||||
#define FRSKYX_CC2500_INO
|
||||
#define SFHSS_CC2500_INO
|
||||
#define SKYARTEC_CC2500_INO
|
||||
|
||||
#define FRSKYD_CC2500_INO
|
||||
#define FRSKYV_CC2500_INO
|
||||
#define FRSKYX_CC2500_INO
|
||||
#define SFHSS_CC2500_INO
|
||||
|
||||
//The protocols below need a NRF24L01 to be installed
|
||||
#define BAYANG_NRF24L01_INO
|
||||
#define CG023_NRF24L01_INO
|
||||
#define CX10_NRF24L01_INO
|
||||
#define ESKY_NRF24L01_INO
|
||||
#define HISKY_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define SLT_NRF24L01_INO
|
||||
#define SYMAX_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
#define MT99XX_NRF24L01_INO
|
||||
#define MJXQ_NRF24L01_INO
|
||||
#define SHENQI_NRF24L01_INO
|
||||
#define FY326_NRF24L01_INO
|
||||
#define FQ777_NRF24L01_INO
|
||||
#define ASSAN_NRF24L01_INO
|
||||
#define HONTAI_NRF24L01_INO
|
||||
|
||||
#define HM830_NRF24L01_INO
|
||||
// #define CFlie_NRF24L01_INO //!\\ //pb voie gaz
|
||||
// #define H377_NRF24L01_INO
|
||||
// #define ESKY150_NRF24L01_INO
|
||||
// #define HonTai_NRF24L01_INO
|
||||
// #define UDI_NRF24L01_INO
|
||||
// #define NE260_NRF24L01_INO
|
||||
// #define BlueFly_NRF24L01_INO //probleme gene id
|
||||
// #define FBL100_NRF24L01_INO // finir id //!\\ //pb voie ???
|
||||
// #define INAV_NRF24L01_INO // a faire
|
||||
#define Q303_NRF24L01_INO
|
||||
|
||||
#define BAYANG_NRF24L01_INO
|
||||
#define CG023_NRF24L01_INO
|
||||
#define CX10_NRF24L01_INO
|
||||
#define ESKY_NRF24L01_INO
|
||||
// #define HISKY_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define SLT_NRF24L01_INO
|
||||
#define SYMAX_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
// #define MT99XX_NRF24L01_INO
|
||||
// #define MJXQ_NRF24L01_INO
|
||||
// #define SHENQI_NRF24L01_INO
|
||||
// #define FY326_NRF24L01_INO
|
||||
// #define FQ777_NRF24L01_INO
|
||||
// #define ASSAN_NRF24L01_INO
|
||||
// #define HONTAI_NRF24L01_INO
|
||||
|
||||
/**************************/
|
||||
/*** TELEMETRY SETTINGS ***/
|
||||
@ -173,10 +124,10 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
//#define INVERT_TELEMETRY
|
||||
|
||||
//Comment a line to disable a protocol telemetry
|
||||
#define DSM_TELEMETRY
|
||||
#define SPORT_TELEMETRY
|
||||
#define HUB_TELEMETRY
|
||||
|
||||
#define DSM_TELEMETRY
|
||||
#define SPORT_TELEMETRY
|
||||
#define HUB_TELEMETRY
|
||||
#define AFHDS2A_TELEMETRY
|
||||
|
||||
/****************************/
|
||||
/*** SERIAL MODE SETTINGS ***/
|
||||
@ -200,17 +151,18 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
//It is important for the module to know the endpoints of your radio.
|
||||
//Below are some standard transmitters already preconfigured.
|
||||
//Uncomment only the one which matches your transmitter.
|
||||
#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_MPX //Multiplex MC2020 (1250<->1950µs)
|
||||
//#define TX_CUSTOM //Custom
|
||||
//#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs)
|
||||
#define TX_TARANIS //TARANIS AETR (1100<->1900µs)
|
||||
//#define TX_DEVO7 //DEVO (1120<->1920µs)
|
||||
//#define TX_SPEKTRUM //Spektrum (1100<->1900µs)
|
||||
//#define TX_HISKY //HISKY (1100<->1900µs)
|
||||
//#define TX_MPX //Multiplex MC2020 (1250<->1950µs)
|
||||
//#define TX_CUSTOM //Custom
|
||||
|
||||
// The lines below are used to set the end points in microseconds (µs) if you have selected TX_CUSTOM.
|
||||
// A few things to considered:
|
||||
// A few things to consider:
|
||||
// - If you put too big values compared to your TX you won't be able to reach the extremes which is bad for throttle as an example
|
||||
// - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the end
|
||||
// - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the ends
|
||||
// - Centered stick value is usually 1500. It should match the middle between MIN and MAX, ie Center=(MAX-MIN)/2+MIN. If your TX is not centered you can adjust the value MIN or MAX.
|
||||
// - 100% is the value when the model is by default, 125% is the value when you extend the servo travel which is only used by some protocols
|
||||
#if defined(TX_CUSTOM)
|
||||
@ -225,7 +177,7 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
//Example: You can associate multiple times the same protocol to different dial positions to take advantage of the model match (RX_Num)
|
||||
const PPM_Parameters PPM_prot[15]= {
|
||||
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option
|
||||
/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 },
|
||||
/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
||||
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
@ -234,7 +186,6 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
/* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 11 */ {MODE_SLT , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 12 */ {MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
@ -242,11 +193,7 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
/* 14 */ {MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||
/* 15 */ {MODE_SYMAX , SYMAX5C , 0 , P_HIGH , NO_AUTOBIND , 0 }
|
||||
};
|
||||
<<<<<<< HEAD
|
||||
/* Available protocols and associated sub protocols:
|
||||
=======
|
||||
/* Available protocols and associated sub protocols to pick and choose from
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
MODE_FLYSKY
|
||||
Flysky
|
||||
V9X9
|
||||
@ -254,28 +201,18 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
V912
|
||||
MODE_HUBSAN
|
||||
NONE
|
||||
<<<<<<< HEAD
|
||||
MODE_FRSKY
|
||||
=======
|
||||
MODE_FRSKYD
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
NONE
|
||||
MODE_HISKY
|
||||
Hisky
|
||||
HK310
|
||||
MODE_V2X2
|
||||
NONE
|
||||
<<<<<<< HEAD
|
||||
MODE_DSM2
|
||||
DSM2
|
||||
DSMX
|
||||
=======
|
||||
MODE_DSM
|
||||
DSM2_22
|
||||
DSM2_11
|
||||
DSMX_22
|
||||
DSMX_11
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
MODE_DEVO
|
||||
NONE
|
||||
MODE_YD717
|
||||
@ -308,142 +245,26 @@ const PPM_Parameters PPM_prot[15]= {
|
||||
MODE_BAYANG
|
||||
NONE
|
||||
MODE_FRSKYX
|
||||
<<<<<<< HEAD
|
||||
NONE
|
||||
=======
|
||||
CH_16
|
||||
CH_8
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
MODE_ESKY
|
||||
NONE
|
||||
MODE_MT99XX
|
||||
MT99
|
||||
H7
|
||||
YZ
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
LS
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
MODE_MJXQ
|
||||
WLH08
|
||||
X600
|
||||
X800
|
||||
H26D
|
||||
<<<<<<< HEAD
|
||||
E010
|
||||
MODE_SHENQI
|
||||
NONE
|
||||
MODE_FY326
|
||||
FY326
|
||||
FY319
|
||||
|
||||
RX_Num value between 0 and 15
|
||||
|
||||
Power P_HIGH or P_LOW
|
||||
|
||||
Auto Bind AUTOBIND or NO_AUTOBIND
|
||||
|
||||
Option value between 0 and 255. 0xD7 or 0x00 for Frsky fine tuning.
|
||||
*/
|
||||
|
||||
//******************
|
||||
//TX definitions with timing endpoints and channels order
|
||||
|
||||
// Turnigy PPM and channels
|
||||
#if defined(TX_ER9X)
|
||||
#define PPM_MAX 2140
|
||||
#define PPM_MIN 860
|
||||
#define PPM_MAX_100 2012
|
||||
#define PPM_MIN_100 988
|
||||
#define AETR
|
||||
#endif
|
||||
|
||||
// Devo PPM and channels
|
||||
#if defined(TX_DEVO7)
|
||||
#define PPM_MAX 2100
|
||||
#define PPM_MIN 900
|
||||
#define PPM_MAX_100 1920
|
||||
#define PPM_MIN_100 1120
|
||||
#define EATR
|
||||
#endif
|
||||
|
||||
// SPEKTRUM PPM and channels
|
||||
#if defined(TX_SPEKTRUM)
|
||||
#define PPM_MAX 2000
|
||||
#define PPM_MIN 1000
|
||||
#define PPM_MAX_100 1900
|
||||
#define PPM_MIN_100 1100
|
||||
#define TAER
|
||||
#endif
|
||||
|
||||
// TARANIS PPM and channels
|
||||
#if defined(TARANIS)
|
||||
#define PPM_MAX 2000
|
||||
#define PPM_MIN 1000
|
||||
#define PPM_MAX_100 1900
|
||||
#define PPM_MIN_100 1100
|
||||
#define EATR
|
||||
#endif
|
||||
|
||||
// HISKY
|
||||
#if defined(TX_HISKY)
|
||||
#define PPM_MAX 2000
|
||||
#define PPM_MIN 1000
|
||||
#define PPM_MAX_100 1900
|
||||
#define PPM_MIN_100 1100
|
||||
#define AETR
|
||||
#endif
|
||||
|
||||
#if defined(EATR)
|
||||
enum chan_order{
|
||||
ELEVATOR=0,
|
||||
AILERON,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(TAER)
|
||||
enum chan_order{
|
||||
THROTTLE=0,
|
||||
AILERON,
|
||||
ELEVATOR,
|
||||
RUDDER,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(AETR)
|
||||
enum chan_order{
|
||||
AILERON =0,
|
||||
ELEVATOR,
|
||||
THROTTLE,
|
||||
RUDDER,
|
||||
};
|
||||
#endif
|
||||
enum chan_orders{
|
||||
AUX1 =4,
|
||||
AUX2,
|
||||
AUX3,
|
||||
AUX4,
|
||||
AUX5,
|
||||
AUX6,
|
||||
AUX7,
|
||||
AUX8,
|
||||
AUX9
|
||||
};
|
||||
|
||||
#define PPM_MIN_COMMAND 1250
|
||||
#define PPM_SWITCH 1550
|
||||
#define PPM_MAX_COMMAND 1750
|
||||
|
||||
//Uncoment the desired serial speed
|
||||
#define BAUD 100000
|
||||
//#define BAUD 125000
|
||||
=======
|
||||
E010
|
||||
MODE_SHENQI
|
||||
NONE
|
||||
MODE_FY326
|
||||
NONE
|
||||
MODE_SFHSS
|
||||
NONE
|
||||
MODE_J6PRO
|
||||
@ -458,6 +279,9 @@ enum chan_orders{
|
||||
FORMAT_HONTAI
|
||||
FORMAT_JJRCX1
|
||||
FORMAT_X5C1
|
||||
FQ777-951
|
||||
MODE_AFHDS2A
|
||||
NONE
|
||||
*/
|
||||
|
||||
// RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded...
|
||||
@ -468,8 +292,7 @@ enum chan_orders{
|
||||
|
||||
// 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 exxample, it's usefull for the WLTOYS F929/F939/F949/F959 (all using the Flysky protocol) which requires a bind at each power up.
|
||||
// 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.
|
||||
|
||||
// Option: the value is between -127 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
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
// 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
|
4
Multiprotocol/_EEPROM.txt
Normal file
4
Multiprotocol/_EEPROM.txt
Normal file
@ -0,0 +1,4 @@
|
||||
0-4 rx Flysky afhds2a
|
||||
10+ 0-4 tx id
|
||||
+10 réf gene id
|
||||
30+6 devo reset Autobind auto
|
890
Multiprotocol/boards.txt
Normal file
890
Multiprotocol/boards.txt
Normal file
@ -0,0 +1,890 @@
|
||||
# See: http://code.google.com/p/arduino/wiki/Platforms
|
||||
|
||||
menu.cpu=Processor
|
||||
|
||||
##############################################################
|
||||
|
||||
yun.name=Arduino Yún
|
||||
yun.upload.via_ssh=true
|
||||
|
||||
yun.vid.0=0x2341
|
||||
yun.pid.0=0x0041
|
||||
yun.vid.1=0x2341
|
||||
yun.pid.1=0x8041
|
||||
yun.vid.2=0x2A03
|
||||
yun.pid.2=0x0041
|
||||
yun.vid.3=0x2A03
|
||||
yun.pid.3=0x8041
|
||||
|
||||
yun.upload.tool=avrdude
|
||||
yun.upload.protocol=avr109
|
||||
yun.upload.maximum_size=28672
|
||||
yun.upload.maximum_data_size=2560
|
||||
yun.upload.speed=57600
|
||||
yun.upload.disable_flushing=true
|
||||
yun.upload.use_1200bps_touch=true
|
||||
yun.upload.wait_for_upload_port=true
|
||||
|
||||
yun.bootloader.tool=avrdude
|
||||
yun.bootloader.low_fuses=0xff
|
||||
yun.bootloader.high_fuses=0xd8
|
||||
yun.bootloader.extended_fuses=0xfb
|
||||
yun.bootloader.file=caterina/Caterina-Yun.hex
|
||||
yun.bootloader.unlock_bits=0x3F
|
||||
yun.bootloader.lock_bits=0x2F
|
||||
|
||||
yun.build.mcu=atmega32u4
|
||||
yun.build.f_cpu=16000000L
|
||||
yun.build.vid=0x2341
|
||||
yun.build.pid=0x8041
|
||||
yun.build.usb_product="Arduino Yun"
|
||||
yun.build.board=AVR_YUN
|
||||
yun.build.core=arduino
|
||||
yun.build.variant=yun
|
||||
yun.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
uno.name=Arduino/Genuino Uno
|
||||
|
||||
uno.vid.0=0x2341
|
||||
uno.pid.0=0x0043
|
||||
uno.vid.1=0x2341
|
||||
uno.pid.1=0x0001
|
||||
uno.vid.2=0x2A03
|
||||
uno.pid.2=0x0043
|
||||
uno.vid.3=0x2341
|
||||
uno.pid.3=0x0243
|
||||
|
||||
uno.upload.tool=avrdude
|
||||
uno.upload.protocol=arduino
|
||||
uno.upload.maximum_size=32256
|
||||
uno.upload.maximum_data_size=2048
|
||||
uno.upload.speed=115200
|
||||
|
||||
uno.bootloader.tool=avrdude
|
||||
uno.bootloader.low_fuses=0xFF
|
||||
uno.bootloader.high_fuses=0xDE
|
||||
uno.bootloader.extended_fuses=0x05
|
||||
uno.bootloader.unlock_bits=0x3F
|
||||
uno.bootloader.lock_bits=0x0F
|
||||
uno.bootloader.file=optiboot/optiboot_atmega328.hex
|
||||
|
||||
uno.build.mcu=atmega328p
|
||||
uno.build.f_cpu=16000000L
|
||||
uno.build.board=AVR_UNO
|
||||
uno.build.core=arduino
|
||||
uno.build.variant=standard
|
||||
|
||||
##############################################################
|
||||
|
||||
diecimila.name=Arduino Duemilanove or Diecimila
|
||||
|
||||
diecimila.upload.tool=avrdude
|
||||
diecimila.upload.protocol=arduino
|
||||
|
||||
diecimila.bootloader.tool=avrdude
|
||||
diecimila.bootloader.low_fuses=0xFF
|
||||
diecimila.bootloader.unlock_bits=0x3F
|
||||
diecimila.bootloader.lock_bits=0x0F
|
||||
|
||||
diecimila.build.f_cpu=16000000L
|
||||
diecimila.build.board=AVR_DUEMILANOVE
|
||||
diecimila.build.core=arduino
|
||||
diecimila.build.variant=standard
|
||||
|
||||
## Arduino Duemilanove or Diecimila w/ ATmega328
|
||||
## ---------------------------------------------
|
||||
diecimila.menu.cpu.atmega328=ATmega328
|
||||
|
||||
diecimila.menu.cpu.atmega328.upload.maximum_size=30720
|
||||
diecimila.menu.cpu.atmega328.upload.maximum_data_size=2048
|
||||
diecimila.menu.cpu.atmega328.upload.speed=57600
|
||||
|
||||
diecimila.menu.cpu.atmega328.bootloader.high_fuses=0xDA
|
||||
diecimila.menu.cpu.atmega328.bootloader.extended_fuses=0x05
|
||||
diecimila.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
|
||||
|
||||
diecimila.menu.cpu.atmega328.build.mcu=atmega328p
|
||||
|
||||
## Arduino Duemilanove or Diecimila w/ ATmega168
|
||||
## ---------------------------------------------
|
||||
diecimila.menu.cpu.atmega168=ATmega168
|
||||
|
||||
diecimila.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
diecimila.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
diecimila.menu.cpu.atmega168.upload.speed=19200
|
||||
|
||||
diecimila.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
diecimila.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
diecimila.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
|
||||
|
||||
diecimila.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
##############################################################
|
||||
|
||||
nano.name=Arduino Nano
|
||||
|
||||
nano.upload.tool=avrdude
|
||||
nano.upload.protocol=arduino
|
||||
|
||||
nano.bootloader.tool=avrdude
|
||||
nano.bootloader.unlock_bits=0x3F
|
||||
nano.bootloader.lock_bits=0x0F
|
||||
|
||||
nano.build.f_cpu=16000000L
|
||||
nano.build.board=AVR_NANO
|
||||
nano.build.core=arduino
|
||||
nano.build.variant=eightanaloginputs
|
||||
|
||||
## Arduino Nano w/ ATmega328
|
||||
## -------------------------
|
||||
nano.menu.cpu.atmega328=ATmega328
|
||||
|
||||
nano.menu.cpu.atmega328.upload.maximum_size=30720
|
||||
nano.menu.cpu.atmega328.upload.maximum_data_size=2048
|
||||
nano.menu.cpu.atmega328.upload.speed=57600
|
||||
|
||||
nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF
|
||||
nano.menu.cpu.atmega328.bootloader.high_fuses=0xDA
|
||||
nano.menu.cpu.atmega328.bootloader.extended_fuses=0x05
|
||||
nano.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
|
||||
|
||||
nano.menu.cpu.atmega328.build.mcu=atmega328p
|
||||
|
||||
## Arduino Nano w/ ATmega168
|
||||
## -------------------------
|
||||
nano.menu.cpu.atmega168=ATmega168
|
||||
|
||||
nano.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
nano.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
nano.menu.cpu.atmega168.upload.speed=19200
|
||||
|
||||
nano.menu.cpu.atmega168.bootloader.low_fuses=0xff
|
||||
nano.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
nano.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
nano.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
|
||||
|
||||
nano.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
##############################################################
|
||||
|
||||
mega.name=Arduino/Genuino Mega or Mega 2560
|
||||
|
||||
mega.vid.0=0x2341
|
||||
mega.pid.0=0x0010
|
||||
mega.vid.1=0x2341
|
||||
mega.pid.1=0x0042
|
||||
mega.vid.2=0x2A03
|
||||
mega.pid.2=0x0010
|
||||
mega.vid.3=0x2A03
|
||||
mega.pid.3=0x0042
|
||||
mega.vid.4=0x2341
|
||||
mega.pid.4=0x0210
|
||||
mega.vid.5=0x2341
|
||||
mega.pid.5=0x0242
|
||||
|
||||
mega.upload.tool=avrdude
|
||||
mega.upload.maximum_data_size=8192
|
||||
|
||||
mega.bootloader.tool=avrdude
|
||||
mega.bootloader.low_fuses=0xFF
|
||||
mega.bootloader.unlock_bits=0x3F
|
||||
mega.bootloader.lock_bits=0x0F
|
||||
|
||||
mega.build.f_cpu=16000000L
|
||||
mega.build.core=arduino
|
||||
mega.build.variant=mega
|
||||
# default board may be overridden by the cpu menu
|
||||
mega.build.board=AVR_MEGA2560
|
||||
|
||||
## Arduino/Genuino Mega w/ ATmega2560
|
||||
## -------------------------
|
||||
mega.menu.cpu.atmega2560=ATmega2560 (Mega 2560)
|
||||
|
||||
mega.menu.cpu.atmega2560.upload.protocol=wiring
|
||||
mega.menu.cpu.atmega2560.upload.maximum_size=253952
|
||||
mega.menu.cpu.atmega2560.upload.speed=115200
|
||||
|
||||
mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
|
||||
mega.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD
|
||||
mega.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex
|
||||
|
||||
mega.menu.cpu.atmega2560.build.mcu=atmega2560
|
||||
mega.menu.cpu.atmega2560.build.board=AVR_MEGA2560
|
||||
|
||||
## Arduino Mega w/ ATmega1280
|
||||
## -------------------------
|
||||
mega.menu.cpu.atmega1280=ATmega1280
|
||||
|
||||
mega.menu.cpu.atmega1280.upload.protocol=arduino
|
||||
mega.menu.cpu.atmega1280.upload.maximum_size=126976
|
||||
mega.menu.cpu.atmega1280.upload.speed=57600
|
||||
|
||||
mega.menu.cpu.atmega1280.bootloader.high_fuses=0xDA
|
||||
mega.menu.cpu.atmega1280.bootloader.extended_fuses=0xF5
|
||||
mega.menu.cpu.atmega1280.bootloader.file=atmega/ATmegaBOOT_168_atmega1280.hex
|
||||
|
||||
mega.menu.cpu.atmega1280.build.mcu=atmega1280
|
||||
mega.menu.cpu.atmega1280.build.board=AVR_MEGA
|
||||
|
||||
##############################################################
|
||||
|
||||
megaADK.name=Arduino Mega ADK
|
||||
|
||||
megaADK.vid.0=0x2341
|
||||
megaADK.pid.0=0x003f
|
||||
megaADK.vid.1=0x2341
|
||||
megaADK.pid.1=0x0044
|
||||
megaADK.vid.2=0x2A03
|
||||
megaADK.pid.2=0x003f
|
||||
megaADK.vid.3=0x2A03
|
||||
megaADK.pid.3=0x0044
|
||||
|
||||
megaADK.upload.tool=avrdude
|
||||
megaADK.upload.protocol=wiring
|
||||
megaADK.upload.maximum_size=253952
|
||||
megaADK.upload.maximum_data_size=8192
|
||||
megaADK.upload.speed=115200
|
||||
|
||||
megaADK.bootloader.tool=avrdude
|
||||
megaADK.bootloader.low_fuses=0xFF
|
||||
megaADK.bootloader.high_fuses=0xD8
|
||||
megaADK.bootloader.extended_fuses=0xFD
|
||||
megaADK.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex
|
||||
megaADK.bootloader.unlock_bits=0x3F
|
||||
megaADK.bootloader.lock_bits=0x0F
|
||||
|
||||
megaADK.build.mcu=atmega2560
|
||||
megaADK.build.f_cpu=16000000L
|
||||
megaADK.build.board=AVR_ADK
|
||||
megaADK.build.core=arduino
|
||||
megaADK.build.variant=mega
|
||||
|
||||
##############################################################
|
||||
|
||||
leonardo.name=Arduino Leonardo
|
||||
leonardo.vid.0=0x2341
|
||||
leonardo.pid.0=0x0036
|
||||
leonardo.vid.1=0x2341
|
||||
leonardo.pid.1=0x8036
|
||||
leonardo.vid.2=0x2A03
|
||||
leonardo.pid.2=0x0036
|
||||
leonardo.vid.3=0x2A03
|
||||
leonardo.pid.3=0x8036
|
||||
|
||||
leonardo.upload.tool=avrdude
|
||||
leonardo.upload.protocol=avr109
|
||||
leonardo.upload.maximum_size=28672
|
||||
leonardo.upload.maximum_data_size=2560
|
||||
leonardo.upload.speed=57600
|
||||
leonardo.upload.disable_flushing=true
|
||||
leonardo.upload.use_1200bps_touch=true
|
||||
leonardo.upload.wait_for_upload_port=true
|
||||
|
||||
leonardo.bootloader.tool=avrdude
|
||||
leonardo.bootloader.low_fuses=0xff
|
||||
leonardo.bootloader.high_fuses=0xd8
|
||||
leonardo.bootloader.extended_fuses=0xcb
|
||||
leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
|
||||
leonardo.bootloader.unlock_bits=0x3F
|
||||
leonardo.bootloader.lock_bits=0x2F
|
||||
|
||||
leonardo.build.mcu=atmega32u4
|
||||
leonardo.build.f_cpu=16000000L
|
||||
leonardo.build.vid=0x2341
|
||||
leonardo.build.pid=0x8036
|
||||
leonardo.build.usb_product="Arduino Leonardo"
|
||||
leonardo.build.board=AVR_LEONARDO
|
||||
leonardo.build.core=arduino
|
||||
leonardo.build.variant=leonardo
|
||||
leonardo.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
micro.name=Arduino/Genuino Micro
|
||||
|
||||
micro.vid.0=0x2341
|
||||
micro.pid.0=0x0037
|
||||
micro.vid.1=0x2341
|
||||
micro.pid.1=0x8037
|
||||
micro.vid.2=0x2A03
|
||||
micro.pid.2=0x0037
|
||||
micro.vid.3=0x2A03
|
||||
micro.pid.3=0x8037
|
||||
|
||||
micro.vid.4=0x2341
|
||||
micro.pid.4=0x0237
|
||||
# If the board is a 2341:0237 use 2341:8237 for build and set
|
||||
# other parameters as well
|
||||
micro.vid.4.build.vid=0x2341
|
||||
micro.vid.4.build.pid=0x8237
|
||||
micro.vid.4.build.usb_product="Genuino Micro"
|
||||
micro.vid.4.bootloader.file=caterina/Caterina-Genuino-Micro.hex
|
||||
|
||||
micro.vid.5=0x2341
|
||||
micro.pid.5=0x8237
|
||||
# If the board is a 2341:8237 use 2341:8237 for build and set
|
||||
# other paramters as well
|
||||
micro.vid.5.build.vid=0x2341
|
||||
micro.vid.5.build.pid=0x8237
|
||||
micro.vid.5.build.usb_product="Genuino Micro"
|
||||
micro.vid.5.bootloader.file=caterina/Caterina-Genuino-Micro.hex
|
||||
|
||||
micro.upload.tool=avrdude
|
||||
micro.upload.protocol=avr109
|
||||
micro.upload.maximum_size=28672
|
||||
micro.upload.maximum_data_size=2560
|
||||
micro.upload.speed=57600
|
||||
micro.upload.disable_flushing=true
|
||||
micro.upload.use_1200bps_touch=true
|
||||
micro.upload.wait_for_upload_port=true
|
||||
|
||||
micro.bootloader.tool=avrdude
|
||||
micro.bootloader.low_fuses=0xff
|
||||
micro.bootloader.high_fuses=0xd8
|
||||
micro.bootloader.extended_fuses=0xcb
|
||||
micro.bootloader.file=caterina/Caterina-Micro.hex
|
||||
micro.bootloader.unlock_bits=0x3F
|
||||
micro.bootloader.lock_bits=0x2F
|
||||
|
||||
micro.build.mcu=atmega32u4
|
||||
micro.build.f_cpu=16000000L
|
||||
micro.build.vid=0x2341
|
||||
micro.build.pid=0x8037
|
||||
micro.build.usb_product="Arduino Micro"
|
||||
micro.build.board=AVR_MICRO
|
||||
micro.build.core=arduino
|
||||
micro.build.variant=micro
|
||||
micro.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
esplora.name=Arduino Esplora
|
||||
esplora.vid.0=0x2341
|
||||
esplora.pid.0=0x003C
|
||||
esplora.vid.1=0x2341
|
||||
esplora.pid.1=0x803C
|
||||
esplora.vid.2=0x2A03
|
||||
esplora.pid.2=0x003C
|
||||
esplora.vid.3=0x2A03
|
||||
esplora.pid.3=0x803C
|
||||
|
||||
esplora.upload.tool=avrdude
|
||||
esplora.upload.protocol=avr109
|
||||
esplora.upload.maximum_size=28672
|
||||
esplora.upload.maximum_data_size=2560
|
||||
esplora.upload.speed=57600
|
||||
esplora.upload.disable_flushing=true
|
||||
esplora.upload.use_1200bps_touch=true
|
||||
esplora.upload.wait_for_upload_port=true
|
||||
|
||||
esplora.bootloader.tool=avrdude
|
||||
esplora.bootloader.low_fuses=0xff
|
||||
esplora.bootloader.high_fuses=0xd8
|
||||
esplora.bootloader.extended_fuses=0xcb
|
||||
esplora.bootloader.file=caterina/Caterina-Esplora.hex
|
||||
esplora.bootloader.unlock_bits=0x3F
|
||||
esplora.bootloader.lock_bits=0x2F
|
||||
|
||||
esplora.build.mcu=atmega32u4
|
||||
esplora.build.f_cpu=16000000L
|
||||
esplora.build.vid=0x2341
|
||||
esplora.build.pid=0x803c
|
||||
esplora.build.usb_product="Arduino Esplora"
|
||||
esplora.build.board=AVR_ESPLORA
|
||||
esplora.build.core=arduino
|
||||
esplora.build.variant=leonardo
|
||||
esplora.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
mini.name=Arduino Mini
|
||||
|
||||
mini.upload.tool=avrdude
|
||||
mini.upload.protocol=arduino
|
||||
|
||||
mini.bootloader.tool=avrdude
|
||||
mini.bootloader.low_fuses=0xff
|
||||
mini.bootloader.unlock_bits=0x3F
|
||||
mini.bootloader.lock_bits=0x0F
|
||||
|
||||
mini.build.f_cpu=16000000L
|
||||
mini.build.board=AVR_MINI
|
||||
mini.build.core=arduino
|
||||
mini.build.variant=eightanaloginputs
|
||||
|
||||
## Arduino Mini w/ ATmega328
|
||||
## -------------------------
|
||||
mini.menu.cpu.atmega328=ATmega328
|
||||
|
||||
mini.menu.cpu.atmega328.upload.maximum_size=28672
|
||||
mini.menu.cpu.atmega328.upload.maximum_data_size=2048
|
||||
mini.menu.cpu.atmega328.upload.speed=115200
|
||||
|
||||
mini.menu.cpu.atmega328.bootloader.high_fuses=0xd8
|
||||
mini.menu.cpu.atmega328.bootloader.extended_fuses=0x05
|
||||
mini.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328-Mini.hex
|
||||
|
||||
mini.menu.cpu.atmega328.build.mcu=atmega328p
|
||||
|
||||
## Arduino Mini w/ ATmega168
|
||||
## -------------------------
|
||||
mini.menu.cpu.atmega168=ATmega168
|
||||
|
||||
mini.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
mini.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
mini.menu.cpu.atmega168.upload.speed=19200
|
||||
|
||||
mini.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
mini.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
mini.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
|
||||
|
||||
mini.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
##############################################################
|
||||
|
||||
ethernet.name=Arduino Ethernet
|
||||
|
||||
ethernet.upload.tool=avrdude
|
||||
ethernet.upload.protocol=arduino
|
||||
ethernet.upload.maximum_size=32256
|
||||
ethernet.upload.maximum_data_size=2048
|
||||
ethernet.upload.speed=115200
|
||||
|
||||
ethernet.bootloader.tool=avrdude
|
||||
ethernet.bootloader.low_fuses=0xff
|
||||
ethernet.bootloader.high_fuses=0xde
|
||||
ethernet.bootloader.extended_fuses=0x05
|
||||
ethernet.bootloader.file=optiboot/optiboot_atmega328.hex
|
||||
ethernet.bootloader.unlock_bits=0x3F
|
||||
ethernet.bootloader.lock_bits=0x0F
|
||||
|
||||
ethernet.build.variant=ethernet
|
||||
ethernet.build.mcu=atmega328p
|
||||
ethernet.build.f_cpu=16000000L
|
||||
ethernet.build.board=AVR_ETHERNET
|
||||
ethernet.build.core=arduino
|
||||
|
||||
##############################################################
|
||||
|
||||
fio.name=Arduino Fio
|
||||
|
||||
fio.upload.tool=avrdude
|
||||
fio.upload.protocol=arduino
|
||||
fio.upload.maximum_size=30720
|
||||
fio.upload.maximum_data_size=2048
|
||||
fio.upload.speed=57600
|
||||
|
||||
fio.bootloader.tool=avrdude
|
||||
fio.bootloader.low_fuses=0xFF
|
||||
fio.bootloader.high_fuses=0xDA
|
||||
fio.bootloader.extended_fuses=0x05
|
||||
fio.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
|
||||
fio.bootloader.unlock_bits=0x3F
|
||||
fio.bootloader.lock_bits=0x0F
|
||||
|
||||
fio.build.mcu=atmega328p
|
||||
fio.build.f_cpu=8000000L
|
||||
fio.build.board=AVR_FIO
|
||||
fio.build.core=arduino
|
||||
fio.build.variant=eightanaloginputs
|
||||
|
||||
##############################################################
|
||||
|
||||
bt.name=Arduino BT
|
||||
|
||||
bt.upload.tool=avrdude
|
||||
bt.upload.protocol=arduino
|
||||
bt.upload.speed=19200
|
||||
bt.upload.disable_flushing=true
|
||||
|
||||
bt.bootloader.tool=avrdude
|
||||
bt.bootloader.low_fuses=0xff
|
||||
bt.bootloader.unlock_bits=0x3F
|
||||
bt.bootloader.lock_bits=0x0F
|
||||
|
||||
bt.build.f_cpu=16000000L
|
||||
bt.build.board=AVR_BT
|
||||
bt.build.core=arduino
|
||||
bt.build.variant=eightanaloginputs
|
||||
|
||||
## Arduino BT w/ ATmega328
|
||||
## -----------------------
|
||||
bt.menu.cpu.atmega328=ATmega328
|
||||
bt.menu.cpu.atmega328.upload.maximum_size=28672
|
||||
bt.menu.cpu.atmega328.upload.maximum_data_size=2048
|
||||
|
||||
bt.menu.cpu.atmega328.bootloader.high_fuses=0xd8
|
||||
bt.menu.cpu.atmega328.bootloader.extended_fuses=0x05
|
||||
bt.menu.cpu.atmega328.bootloader.file=bt/ATmegaBOOT_168_atmega328_bt.hex
|
||||
|
||||
bt.menu.cpu.atmega328.build.mcu=atmega328p
|
||||
|
||||
## Arduino BT w/ ATmega168
|
||||
## -----------------------
|
||||
bt.menu.cpu.atmega168=ATmega168
|
||||
bt.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
bt.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
|
||||
bt.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
bt.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
bt.menu.cpu.atmega168.bootloader.file=bt/ATmegaBOOT_168.hex
|
||||
|
||||
bt.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
##############################################################
|
||||
|
||||
LilyPadUSB.name=LilyPad Arduino USB
|
||||
LilyPadUSB.vid.0=0x1B4F
|
||||
LilyPadUSB.pid.0=0x9207
|
||||
LilyPadUSB.vid.1=0x1B4F
|
||||
LilyPadUSB.pid.1=0x9208
|
||||
|
||||
LilyPadUSB.upload.tool=avrdude
|
||||
LilyPadUSB.upload.protocol=avr109
|
||||
LilyPadUSB.upload.maximum_size=28672
|
||||
LilyPadUSB.upload.maximum_data_size=2560
|
||||
LilyPadUSB.upload.speed=57600
|
||||
LilyPadUSB.upload.disable_flushing=true
|
||||
LilyPadUSB.upload.use_1200bps_touch=true
|
||||
LilyPadUSB.upload.wait_for_upload_port=true
|
||||
|
||||
LilyPadUSB.bootloader.tool=avrdude
|
||||
LilyPadUSB.bootloader.low_fuses=0xff
|
||||
LilyPadUSB.bootloader.high_fuses=0xd8
|
||||
LilyPadUSB.bootloader.extended_fuses=0xce
|
||||
LilyPadUSB.bootloader.file=caterina-LilyPadUSB/Caterina-LilyPadUSB.hex
|
||||
LilyPadUSB.bootloader.unlock_bits=0x3F
|
||||
LilyPadUSB.bootloader.lock_bits=0x2F
|
||||
|
||||
LilyPadUSB.build.mcu=atmega32u4
|
||||
LilyPadUSB.build.f_cpu=8000000L
|
||||
LilyPadUSB.build.vid=0x1B4F
|
||||
LilyPadUSB.build.pid=0x9208
|
||||
LilyPadUSB.build.usb_product="LilyPad USB"
|
||||
LilyPadUSB.build.board=AVR_LILYPAD_USB
|
||||
LilyPadUSB.build.core=arduino
|
||||
LilyPadUSB.build.variant=leonardo
|
||||
LilyPadUSB.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
lilypad.name=LilyPad Arduino
|
||||
|
||||
lilypad.upload.tool=avrdude
|
||||
lilypad.upload.protocol=arduino
|
||||
|
||||
lilypad.bootloader.tool=avrdude
|
||||
lilypad.bootloader.unlock_bits=0x3F
|
||||
lilypad.bootloader.lock_bits=0x0F
|
||||
|
||||
lilypad.build.f_cpu=8000000L
|
||||
lilypad.build.board=AVR_LILYPAD
|
||||
lilypad.build.core=arduino
|
||||
lilypad.build.variant=standard
|
||||
|
||||
## LilyPad Arduino w/ ATmega328
|
||||
## ----------------------------
|
||||
lilypad.menu.cpu.atmega328=ATmega328
|
||||
|
||||
lilypad.menu.cpu.atmega328.upload.maximum_size=30720
|
||||
lilypad.menu.cpu.atmega328.upload.maximum_data_size=2048
|
||||
lilypad.menu.cpu.atmega328.upload.speed=57600
|
||||
|
||||
lilypad.menu.cpu.atmega328.bootloader.low_fuses=0xFF
|
||||
lilypad.menu.cpu.atmega328.bootloader.high_fuses=0xDA
|
||||
lilypad.menu.cpu.atmega328.bootloader.extended_fuses=0x05
|
||||
lilypad.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
|
||||
|
||||
lilypad.menu.cpu.atmega328.build.mcu=atmega328p
|
||||
|
||||
## LilyPad Arduino w/ ATmega168
|
||||
## ----------------------------
|
||||
lilypad.menu.cpu.atmega168=ATmega168
|
||||
|
||||
lilypad.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
lilypad.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
lilypad.menu.cpu.atmega168.upload.speed=19200
|
||||
|
||||
lilypad.menu.cpu.atmega168.bootloader.low_fuses=0xe2
|
||||
lilypad.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
lilypad.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
lilypad.menu.cpu.atmega168.bootloader.file=lilypad/LilyPadBOOT_168.hex
|
||||
|
||||
lilypad.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
##############################################################
|
||||
|
||||
pro.name=Arduino Pro or Pro Mini
|
||||
|
||||
pro.upload.tool=avrdude
|
||||
pro.upload.protocol=arduino
|
||||
|
||||
pro.bootloader.tool=avrdude
|
||||
pro.bootloader.unlock_bits=0x3F
|
||||
pro.bootloader.lock_bits=0x0F
|
||||
|
||||
pro.build.board=AVR_PRO
|
||||
pro.build.core=arduino
|
||||
pro.build.variant=eightanaloginputs
|
||||
|
||||
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
|
||||
## -------------------------------------------------
|
||||
pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)
|
||||
|
||||
pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720
|
||||
pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
|
||||
pro.menu.cpu.16MHzatmega328.upload.speed=57600
|
||||
|
||||
pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
|
||||
pro.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA
|
||||
pro.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0x05
|
||||
pro.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
|
||||
|
||||
pro.menu.cpu.16MHzatmega328.build.mcu=atmega328p
|
||||
pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
|
||||
|
||||
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
|
||||
## --------------------------------------------------
|
||||
pro.menu.cpu.8MHzatmega328=ATmega328 (3.3V, 8 MHz)
|
||||
|
||||
pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
|
||||
pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
|
||||
pro.menu.cpu.8MHzatmega328.upload.speed=57600
|
||||
|
||||
pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
|
||||
pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
|
||||
pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0x05
|
||||
pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
|
||||
|
||||
pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p
|
||||
pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L
|
||||
|
||||
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168
|
||||
## -------------------------------------------------
|
||||
pro.menu.cpu.16MHzatmega168=ATmega168 (5V, 16 MHz)
|
||||
|
||||
pro.menu.cpu.16MHzatmega168.upload.maximum_size=14336
|
||||
pro.menu.cpu.16MHzatmega168.upload.maximum_data_size=1024
|
||||
pro.menu.cpu.16MHzatmega168.upload.speed=19200
|
||||
|
||||
pro.menu.cpu.16MHzatmega168.bootloader.low_fuses=0xff
|
||||
pro.menu.cpu.16MHzatmega168.bootloader.high_fuses=0xdd
|
||||
pro.menu.cpu.16MHzatmega168.bootloader.extended_fuses=0x00
|
||||
pro.menu.cpu.16MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
|
||||
|
||||
pro.menu.cpu.16MHzatmega168.build.mcu=atmega168
|
||||
pro.menu.cpu.16MHzatmega168.build.f_cpu=16000000L
|
||||
|
||||
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
|
||||
## --------------------------------------------------
|
||||
pro.menu.cpu.8MHzatmega168=ATmega168 (3.3V, 8 MHz)
|
||||
|
||||
pro.menu.cpu.8MHzatmega168.upload.maximum_size=14336
|
||||
pro.menu.cpu.8MHzatmega168.upload.maximum_data_size=1024
|
||||
pro.menu.cpu.8MHzatmega168.upload.speed=19200
|
||||
|
||||
pro.menu.cpu.8MHzatmega168.bootloader.low_fuses=0xc6
|
||||
pro.menu.cpu.8MHzatmega168.bootloader.high_fuses=0xdd
|
||||
pro.menu.cpu.8MHzatmega168.bootloader.extended_fuses=0x00
|
||||
pro.menu.cpu.8MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_pro_8MHz.hex
|
||||
|
||||
pro.menu.cpu.8MHzatmega168.build.mcu=atmega168
|
||||
pro.menu.cpu.8MHzatmega168.build.f_cpu=8000000L
|
||||
|
||||
##############################################################
|
||||
|
||||
atmegang.name=Arduino NG or older
|
||||
|
||||
atmegang.upload.tool=avrdude
|
||||
atmegang.upload.protocol=arduino
|
||||
atmegang.upload.speed=19200
|
||||
|
||||
atmegang.bootloader.tool=avrdude
|
||||
atmegang.bootloader.unlock_bits=0x3F
|
||||
atmegang.bootloader.lock_bits=0x0F
|
||||
|
||||
atmegang.build.mcu=atmegang
|
||||
atmegang.build.f_cpu=16000000L
|
||||
atmegang.build.board=AVR_NG
|
||||
atmegang.build.core=arduino
|
||||
atmegang.build.variant=standard
|
||||
|
||||
## Arduino NG or older w/ ATmega168
|
||||
## --------------------------------
|
||||
atmegang.menu.cpu.atmega168=ATmega168
|
||||
|
||||
atmegang.menu.cpu.atmega168.upload.maximum_size=14336
|
||||
atmegang.menu.cpu.atmega168.upload.maximum_data_size=1024
|
||||
|
||||
atmegang.menu.cpu.atmega168.bootloader.low_fuses=0xff
|
||||
atmegang.menu.cpu.atmega168.bootloader.high_fuses=0xdd
|
||||
atmegang.menu.cpu.atmega168.bootloader.extended_fuses=0x00
|
||||
atmegang.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
|
||||
|
||||
atmegang.menu.cpu.atmega168.build.mcu=atmega168
|
||||
|
||||
## Arduino NG or older w/ ATmega8
|
||||
## ------------------------------
|
||||
atmegang.menu.cpu.atmega8=ATmega8
|
||||
|
||||
atmegang.menu.cpu.atmega8.upload.maximum_size=7168
|
||||
atmegang.menu.cpu.atmega8.upload.maximum_data_size=1024
|
||||
|
||||
atmegang.menu.cpu.atmega8.bootloader.low_fuses=0xdf
|
||||
atmegang.menu.cpu.atmega8.bootloader.high_fuses=0xca
|
||||
atmegang.menu.cpu.atmega8.bootloader.file=atmega8/ATmegaBOOT-prod-firmware-2009-11-07.hex
|
||||
|
||||
atmegang.menu.cpu.atmega8.build.mcu=atmega8
|
||||
|
||||
##############################################################
|
||||
|
||||
robotControl.name=Arduino Robot Control
|
||||
robotControl.vid.0=0x2341
|
||||
robotControl.pid.0=0x0038
|
||||
robotControl.vid.1=0x2341
|
||||
robotControl.pid.1=0x8038
|
||||
robotControl.vid.2=0x2A03
|
||||
robotControl.pid.2=0x0038
|
||||
robotControl.vid.3=0x2A03
|
||||
robotControl.pid.3=0x8038
|
||||
|
||||
robotControl.upload.tool=avrdude
|
||||
robotControl.upload.protocol=avr109
|
||||
robotControl.upload.maximum_size=28672
|
||||
robotControl.upload.maximum_data_size=2560
|
||||
robotControl.upload.speed=57600
|
||||
robotControl.upload.disable_flushing=true
|
||||
robotControl.upload.use_1200bps_touch=true
|
||||
robotControl.upload.wait_for_upload_port=true
|
||||
|
||||
robotControl.bootloader.tool=avrdude
|
||||
robotControl.bootloader.low_fuses=0xff
|
||||
robotControl.bootloader.high_fuses=0xd8
|
||||
robotControl.bootloader.extended_fuses=0xcb
|
||||
robotControl.bootloader.file=caterina-Arduino_Robot/Caterina-Robot-Control.hex
|
||||
robotControl.bootloader.unlock_bits=0x3F
|
||||
robotControl.bootloader.lock_bits=0x2F
|
||||
|
||||
robotControl.build.mcu=atmega32u4
|
||||
robotControl.build.f_cpu=16000000L
|
||||
robotControl.build.vid=0x2341
|
||||
robotControl.build.pid=0x8038
|
||||
robotControl.build.usb_product="Robot Control"
|
||||
robotControl.build.board=AVR_ROBOT_CONTROL
|
||||
robotControl.build.core=arduino
|
||||
robotControl.build.variant=robot_control
|
||||
robotControl.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
robotMotor.name=Arduino Robot Motor
|
||||
robotMotor.vid.0=0x2341
|
||||
robotMotor.pid.0=0x0039
|
||||
robotMotor.vid.1=0x2341
|
||||
robotMotor.pid.1=0x8039
|
||||
robotMotor.vid.2=0x2A03
|
||||
robotMotor.pid.2=0x0039
|
||||
robotMotor.vid.3=0x2A03
|
||||
robotMotor.pid.3=0x8039
|
||||
|
||||
robotMotor.upload.tool=avrdude
|
||||
robotMotor.upload.protocol=avr109
|
||||
robotMotor.upload.maximum_size=28672
|
||||
robotMotor.upload.maximum_data_size=2560
|
||||
robotMotor.upload.speed=57600
|
||||
robotMotor.upload.disable_flushing=true
|
||||
robotMotor.upload.use_1200bps_touch=true
|
||||
robotMotor.upload.wait_for_upload_port=true
|
||||
|
||||
robotMotor.bootloader.tool=avrdude
|
||||
robotMotor.bootloader.low_fuses=0xff
|
||||
robotMotor.bootloader.high_fuses=0xd8
|
||||
robotMotor.bootloader.extended_fuses=0xcb
|
||||
robotMotor.bootloader.file=caterina-Arduino_Robot/Caterina-Robot-Motor.hex
|
||||
robotMotor.bootloader.unlock_bits=0x3F
|
||||
robotMotor.bootloader.lock_bits=0x2F
|
||||
|
||||
robotMotor.build.mcu=atmega32u4
|
||||
robotMotor.build.f_cpu=16000000L
|
||||
robotMotor.build.vid=0x2341
|
||||
robotMotor.build.pid=0x8039
|
||||
robotMotor.build.usb_product="Robot Motor"
|
||||
robotMotor.build.board=AVR_ROBOT_MOTOR
|
||||
robotMotor.build.core=arduino
|
||||
robotMotor.build.variant=robot_motor
|
||||
robotMotor.build.extra_flags={build.usb_flags}
|
||||
|
||||
##############################################################
|
||||
|
||||
gemma.vid.0=0x2341
|
||||
gemma.pid.0=0x0c9f
|
||||
|
||||
gemma.name=Arduino Gemma
|
||||
|
||||
gemma.bootloader.low_fuses=0xF1
|
||||
gemma.bootloader.high_fuses=0xD5
|
||||
gemma.bootloader.extended_fuses=0xFE
|
||||
gemma.bootloader.tool=avrdude
|
||||
gemma.bootloader.lock_bits=
|
||||
gemma.bootloader.unlock_bits=
|
||||
gemma.bootloader.file=gemma/gemma_v1.hex
|
||||
|
||||
gemma.build.mcu=attiny85
|
||||
gemma.build.f_cpu=8000000L
|
||||
gemma.build.core=arduino
|
||||
gemma.build.variant=gemma
|
||||
gemma.build.board=AVR_GEMMA
|
||||
|
||||
gemma.upload.tool=avrdude
|
||||
gemma.upload.maximum_size=5310
|
||||
|
||||
##############################################################
|
||||
|
||||
## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328
|
||||
## --------------------------------------------------
|
||||
multi.name=Multi 4-in-1
|
||||
|
||||
multi.upload.tool=avrdude
|
||||
multi.upload.protocol=arduino
|
||||
|
||||
multi.bootloader.tool=avrdude
|
||||
multi.bootloader.unlock_bits=0x3F
|
||||
multi.bootloader.lock_bits=0x0F
|
||||
|
||||
multi.build.board=AVR_PRO
|
||||
multi.build.core=arduino
|
||||
multi.build.variant=eightanaloginputs
|
||||
|
||||
multi.menu.cpu.16MHzatmega328=ATmega328 (3.3V, 16 MHz)
|
||||
|
||||
multi.menu.cpu.16MHzatmega328.upload.maximum_size=32768
|
||||
multi.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
|
||||
multi.menu.cpu.16MHzatmega328.upload.speed=57600
|
||||
multi.menu.cpu.16MHzatmega328.upload.using=arduino:arduinoisp
|
||||
|
||||
multi.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
|
||||
multi.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xD2
|
||||
multi.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0xFD
|
||||
multi.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
|
||||
|
||||
multi.menu.cpu.16MHzatmega328.build.mcu=atmega328p
|
||||
multi.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
|
||||
## --------------------------------------------------
|
||||
multi.menu.cpu.16MHzatmega328opti=ATmega328 Opti (3.3V, 16 MHz)
|
||||
|
||||
multi.menu.cpu.16MHzatmega328opti.upload.maximum_size=32768
|
||||
multi.menu.cpu.16MHzatmega328opti.upload.maximum_data_size=2048
|
||||
multi.menu.cpu.16MHzatmega328opti.upload.speed=57600
|
||||
multi.menu.cpu.16MHzatmega328opti.upload.using=arduino:arduinoisp
|
||||
|
||||
multi.menu.cpu.16MHzatmega328opti.bootloader.low_fuses=0xFF
|
||||
multi.menu.cpu.16MHzatmega328opti.bootloader.high_fuses=0xD6
|
||||
multi.menu.cpu.16MHzatmega328opti.bootloader.extended_fuses=0xFD
|
||||
multi.menu.cpu.16MHzatmega328opti.bootloader.file=atmega/optiboot_atmega328_16.hex
|
||||
|
||||
multi.menu.cpu.16MHzatmega328opti.build.mcu=atmega328p
|
||||
multi.menu.cpu.16MHzatmega328opti.build.f_cpu=16000000L
|
||||
|
||||
##############################################################
|
BIN
Multiprotocol/calcul chanel.ods
Normal file
BIN
Multiprotocol/calcul chanel.ods
Normal file
Binary file not shown.
@ -87,9 +87,4 @@ enum A7105_MASK {
|
||||
A7105_MASK_VBCF = 1 << 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
INIT_FLYSKY,
|
||||
INIT_HUBSAN
|
||||
};
|
||||
|
||||
#endif
|
@ -103,13 +103,8 @@ enum {
|
||||
//#define NOP 0xFF
|
||||
|
||||
// XN297 emulation layer
|
||||
<<<<<<< HEAD
|
||||
#define XN297_UNSCRAMBLED 8
|
||||
|
||||
=======
|
||||
enum {
|
||||
XN297_UNSCRAMBLED = 0,
|
||||
XN297_SCRAMBLED
|
||||
};
|
||||
>>>>>>> refs/remotes/pascallanger/master
|
||||
#endif
|
@ -1,94 +0,0 @@
|
||||
-- Multiprotocole Midelic et Pascallanger
|
||||
local debut = 0
|
||||
local tps = 0
|
||||
local tpsact = 1024
|
||||
local mix, mixe
|
||||
local channel
|
||||
|
||||
local inp = {
|
||||
{ "Protocole", VALUE, 1, 26, 2 },
|
||||
{ "Switch", SOURCE }
|
||||
}
|
||||
-- 6 7 8 15 16 17 24 25 26
|
||||
-- 4 5 12 13 14 21 22 23
|
||||
-- 1 2 3 9 10 11 18 19 20
|
||||
local out = { "Bind", "Gaz", "Aile", "Prof", "Dir" }
|
||||
|
||||
local function run_func(proto, sw)
|
||||
-- test mixage lua
|
||||
if debut == 0 then
|
||||
-- passage en lua
|
||||
for channel = 0, 3, 1 do
|
||||
local mix = model.getMix(channel, 0)
|
||||
mix_source = mix["source"]
|
||||
if mix_source < 33 or 1 then
|
||||
model.deleteMix(channel, 0)
|
||||
mix["source"] = channel + 34
|
||||
mix["name"] = "Lua "
|
||||
model.insertMix(channel, 0, mix)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- inter install
|
||||
channel = 4
|
||||
mix = { name="Raz Bind", source=33, weight=100, switch=0, multiplex=REPLACE }
|
||||
count = model.getMixesCount(channel + 0)
|
||||
if count == 0 and inter == 1 then
|
||||
model.insertMix(channel + 0, 0, mix)
|
||||
elseif count == 1 and inter == 0 then
|
||||
mixe = model.getMix(channel, 0)
|
||||
if mixe["name"] == mix["name"] then
|
||||
model.deleteMix(channel, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- delais init
|
||||
if proto ~= debut then
|
||||
tps = getTime() + 250 -- delai pour mini 12 cycle PPM
|
||||
tpsact = 1024
|
||||
debut = proto
|
||||
end
|
||||
|
||||
local gaz = 1024
|
||||
local ail = 0
|
||||
local dir = 0
|
||||
local pro = 0
|
||||
|
||||
if tpsact == 0 and sw < 100 then
|
||||
-- reprise valeur input
|
||||
pro = getValue(1)
|
||||
ail = getValue(2)
|
||||
gaz = getValue(3)
|
||||
dir = getValue(4)
|
||||
elseif tpsact ~= 0 then
|
||||
-- decallage pour position memo (centre)
|
||||
if proto > 4 then proto = proto + 1 end
|
||||
|
||||
-- calcul position
|
||||
-- decallage pour > 18
|
||||
if proto > 18 then
|
||||
ail = 1024
|
||||
proto = proto - 18
|
||||
end
|
||||
-- decallage pour > 9
|
||||
if proto > 9 then
|
||||
ail = -1024
|
||||
proto = proto - 9
|
||||
end
|
||||
|
||||
if proto < 4 then pro = -1024 end
|
||||
if proto > 6 then pro = 1024 end
|
||||
|
||||
if proto % 3 == 1 then dir = -1024 end
|
||||
if proto % 3 == 0 then dir = 1024 end
|
||||
|
||||
if tps < getTime() then
|
||||
tpsact = tpsact - 512
|
||||
if tpsact>-20 then tps = getTime() + 250 end
|
||||
end
|
||||
sw = tpsact
|
||||
end
|
||||
|
||||
return sw, gaz, ail, pro, dir
|
||||
end
|
||||
return { run=run_func, input=inp, output=out}
|
@ -13,21 +13,28 @@
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Check selected board type
|
||||
#ifndef XMEGA
|
||||
#if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
|
||||
#error You must select the board type "Arduino Pro or Pro Mini" or "Arduino Mini"
|
||||
#endif
|
||||
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
||||
#error You must select the processor type "ATmega328(5V, 16MHz)"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
// Protocols max 31 x2
|
||||
//******************
|
||||
enum PROTOCOLS
|
||||
{
|
||||
MODE_JOYSWAY = 40, // =>A7105
|
||||
MODE_WK2x01 = 41, // =>CYRF6936
|
||||
MODE_SKYARTEC = 42, // =>CC2500
|
||||
|
||||
MODE_UDI = 44, // =>NRF24L01
|
||||
MODE_FBL100 = 45, // =>NRF24L01
|
||||
|
||||
MODE_HM830 = 50, // =>NRF24L01
|
||||
MODE_CFLIE = 51, // =>NRF24L01
|
||||
MODE_H377 = 52, // =>NRF24L01
|
||||
MODE_ESKY150 = 53, // =>NRF24L01
|
||||
MODE_BlueFly = 54, // =>NRF24L01
|
||||
MODE_NE260 = 55, // =>NRF24L01
|
||||
|
||||
MODE_INAV = 57, // =>NRF24L01
|
||||
MODE_Q303 = 58, // =>NRF24L01
|
||||
|
||||
MODE_SERIAL = 0, // Serial commands
|
||||
MODE_FLYSKY = 1, // =>A7105
|
||||
MODE_HUBSAN = 2, // =>A7105
|
||||
@ -56,19 +63,26 @@ enum PROTOCOLS
|
||||
MODE_FRSKYV = 25, // =>CC2500
|
||||
MODE_HONTAI = 26, // =>NRF24L01
|
||||
MODE_OPENLRS = 27, // =>OpenLRS hardware
|
||||
MODE_AFHDS2A = 28, // =>A7105
|
||||
};
|
||||
|
||||
enum Flysky
|
||||
{
|
||||
Flysky = 0,
|
||||
V9X9 = 1,
|
||||
V6X6 = 2,
|
||||
V912 = 3
|
||||
Flysky=0,
|
||||
V9X9=1,
|
||||
V6X6=2,
|
||||
V912=3
|
||||
};
|
||||
enum AFHDS2A
|
||||
{
|
||||
PWM_IBUS = 0,
|
||||
PPM_IBUS = 1,
|
||||
PWM_SBUS = 2,
|
||||
PPM_SBUS = 3,
|
||||
};
|
||||
enum Hisky
|
||||
{
|
||||
Hisky = 0,
|
||||
HK310 = 1
|
||||
Hisky=0,
|
||||
HK310=1
|
||||
};
|
||||
enum DSM
|
||||
{
|
||||
@ -80,38 +94,38 @@ enum DSM
|
||||
};
|
||||
enum YD717
|
||||
{
|
||||
YD717 = 0,
|
||||
SKYWLKR = 1,
|
||||
SYMAX4 = 2,
|
||||
XINXUN = 3,
|
||||
NIHUI = 4
|
||||
YD717=0,
|
||||
SKYWLKR=1,
|
||||
SYMAX4=2,
|
||||
XINXUN=3,
|
||||
NIHUI=4
|
||||
};
|
||||
enum KN
|
||||
{
|
||||
WLTOYS = 0,
|
||||
FEILUN = 1
|
||||
WLTOYS=0,
|
||||
FEILUN=1
|
||||
};
|
||||
enum SYMAX
|
||||
{
|
||||
SYMAX = 0,
|
||||
SYMAX5C = 1
|
||||
SYMAX=0,
|
||||
SYMAX5C=1
|
||||
};
|
||||
enum CX10
|
||||
{
|
||||
CX10_GREEN = 0,
|
||||
CX10_BLUE = 1, // also compatible with CX10-A, CX12
|
||||
DM007 = 2,
|
||||
Q282 = 3,
|
||||
JC3015_1 = 4,
|
||||
JC3015_2 = 5,
|
||||
MK33041 = 6,
|
||||
Q242 = 7
|
||||
CX10_GREEN = 0,
|
||||
CX10_BLUE=1, // also compatible with CX10-A, CX12
|
||||
DM007=2,
|
||||
Q282=3,
|
||||
JC3015_1=4,
|
||||
JC3015_2=5,
|
||||
MK33041=6,
|
||||
Q242=7
|
||||
};
|
||||
enum CG023
|
||||
{
|
||||
CG023 = 0,
|
||||
YD829 = 1,
|
||||
H8_3D = 2
|
||||
CG023 = 0,
|
||||
YD829 = 1,
|
||||
H8_3D = 2
|
||||
};
|
||||
enum MT99XX
|
||||
{
|
||||
@ -126,7 +140,8 @@ enum MJXQ
|
||||
X600 = 1,
|
||||
X800 = 2,
|
||||
H26D = 3,
|
||||
E010 = 4
|
||||
E010 = 4,
|
||||
H26WH = 5
|
||||
};
|
||||
enum FRSKYX
|
||||
{
|
||||
@ -135,9 +150,44 @@ enum FRSKYX
|
||||
};
|
||||
enum HONTAI
|
||||
{
|
||||
FORMAT_HONTAI = 0,
|
||||
FORMAT_HONTAI = 0,
|
||||
FORMAT_JJRCX1 = 1,
|
||||
FORMAT_X5C1 = 2
|
||||
FORMAT_X5C1 = 2,
|
||||
FORMAT_FQ777 = 3
|
||||
};
|
||||
|
||||
enum HUBSAN
|
||||
{
|
||||
H107 = 0,
|
||||
H301 = 1,
|
||||
H501 = 2
|
||||
};
|
||||
enum FY326
|
||||
{
|
||||
FY326 = 0,
|
||||
FY319 = 1
|
||||
};
|
||||
enum V2X2 {
|
||||
FORMAT_V202 = 0,
|
||||
FORMAT_JXD506 = 1,
|
||||
};
|
||||
enum WK2X01
|
||||
{
|
||||
WK2801 = 0,
|
||||
WK2601 = 1,
|
||||
WK2401 = 2
|
||||
};
|
||||
|
||||
enum UDI
|
||||
{
|
||||
U816_V1 = 0,
|
||||
U816_V2 = 1,
|
||||
U839_2014 = 2
|
||||
};
|
||||
enum FBL100
|
||||
{
|
||||
FBL100 = 0,
|
||||
HP100 = 1
|
||||
};
|
||||
|
||||
#define NONE 0
|
||||
@ -159,27 +209,6 @@ struct PPM_Parameters
|
||||
// Macros
|
||||
#define NOP() __asm__ __volatile__("nop")
|
||||
|
||||
//*******************
|
||||
//*** Timer ***
|
||||
//*******************
|
||||
#ifdef XMEGA
|
||||
#define TIFR1 TCC1.INTFLAGS
|
||||
#define OCF1A_bm TC1_CCAIF_bm
|
||||
#define OCR1A TCC1.CCA
|
||||
#define TCNT1 TCC1.CNT
|
||||
#define UDR0 USARTC0.DATA
|
||||
#define OCF1B_bm TC1_CCBIF_bm
|
||||
#define OCR1B TCC1.CCB
|
||||
#define TIMSK1 TCC1.INTCTRLB
|
||||
#define SET_TIMSK1_OCIE1B TIMSK1 = (TIMSK1 & 0xF3) | 0x04
|
||||
#define CLR_TIMSK1_OCIE1B TIMSK1 &= 0xF3
|
||||
#else
|
||||
#define OCF1A_bm _BV(OCF1A)
|
||||
#define OCF1B_bm _BV(OCF1B)
|
||||
#define SET_TIMSK1_OCIE1B TIMSK1 |= _BV(OCIE1B)
|
||||
#define CLR_TIMSK1_OCIE1B TIMSK1 &=~_BV(OCIE1B)
|
||||
#endif
|
||||
|
||||
//***************
|
||||
//*** Flags ***
|
||||
//***************
|
||||
@ -188,7 +217,7 @@ struct PPM_Parameters
|
||||
#define IS_RX_FLAG_on ( ( protocol_flags & _BV(0) ) !=0 )
|
||||
//
|
||||
#define CHANGE_PROTOCOL_FLAG_on protocol_flags |= _BV(1)
|
||||
#define CHANGE_PROTOCOL_FLAG_off protocol_flags &= ~_BV(1)
|
||||
#define CHANGE_PROTOCOL_FLAG_off protocol_flags &= ~_BV(1)
|
||||
#define IS_CHANGE_PROTOCOL_FLAG_on ( ( protocol_flags & _BV(1) ) !=0 )
|
||||
//
|
||||
#define POWER_FLAG_on protocol_flags |= _BV(2)
|
||||
@ -206,8 +235,9 @@ struct PPM_Parameters
|
||||
#define BIND_BUTTON_FLAG_on protocol_flags |= _BV(5)
|
||||
#define BIND_BUTTON_FLAG_off protocol_flags &= ~_BV(5)
|
||||
#define IS_BIND_BUTTON_FLAG_on ( ( protocol_flags & _BV(5) ) !=0 )
|
||||
|
||||
//PPM RX OK
|
||||
#define PPM_FLAG_off protocol_flags &= ~_BV(6)
|
||||
#define PPM_FLAG_off protocol_flags &= ~_BV(6)
|
||||
#define PPM_FLAG_on protocol_flags |= _BV(6)
|
||||
#define IS_PPM_FLAG_on ( ( protocol_flags & _BV(6) ) !=0 )
|
||||
//Bind flag
|
||||
@ -227,19 +257,27 @@ struct PPM_Parameters
|
||||
#define RX_MISSED_BUFF_on protocol_flags2 |= _BV(2)
|
||||
#define IS_RX_MISSED_BUFF_on ( ( protocol_flags2 & _BV(2) ) !=0 )
|
||||
//TX Pause
|
||||
#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3)
|
||||
#define TX_MAIN_PAUSE_on protocol_flags2 |= _BV(3)
|
||||
#define IS_TX_MAIN_PAUSE_on ( ( protocol_flags2 & _BV(3) ) !=0 )
|
||||
#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3)
|
||||
#define TX_MAIN_PAUSE_on protocol_flags2 |= _BV(3)
|
||||
#define IS_TX_MAIN_PAUSE_on ( ( protocol_flags2 & _BV(3) ) !=0 )
|
||||
|
||||
#define TX_RX_PAUSE_off protocol_flags2 &= ~_BV(4)
|
||||
#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4)
|
||||
#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
|
||||
#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4)
|
||||
#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
|
||||
|
||||
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
|
||||
//Signal OK
|
||||
#define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5)
|
||||
#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 )
|
||||
|
||||
//********************
|
||||
//*** Blink timing ***
|
||||
//********************
|
||||
#define BLINK_BIND_TIME 100
|
||||
#define BLINK_SERIAL_TIME 500
|
||||
#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
|
||||
|
||||
@ -409,6 +447,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
FrskyV 25
|
||||
HONTAI 26
|
||||
OpenLRS 27
|
||||
AFHDS2A 28
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
@ -416,30 +455,31 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
RxNum value is 0..15 (bits 0..3)
|
||||
Type is 0..7 <<4 (bit 4..6)
|
||||
sub_protocol==Flysky
|
||||
Flysky 0
|
||||
V9x9 1
|
||||
V6x6 2
|
||||
V912 3
|
||||
Flysky 0
|
||||
V9x9 1
|
||||
V6x6 2
|
||||
V912 3
|
||||
sub_protocol==Hisky
|
||||
Hisky 0
|
||||
HK310 1
|
||||
Hisky 0
|
||||
HK310 1
|
||||
sub_protocol==DSM
|
||||
DSM2_22 0
|
||||
DSM2_11 1
|
||||
DSMX_22 2
|
||||
DSMX_11 3
|
||||
DSM_AUTO 4
|
||||
sub_protocol==YD717
|
||||
YD717 0
|
||||
SKYWLKR 1
|
||||
SYMAX4 2
|
||||
XINXUN 3
|
||||
NIHUI 4
|
||||
YD717 0
|
||||
SKYWLKR 1
|
||||
SYMAX4 2
|
||||
XINXUN 3
|
||||
NIHUI 4
|
||||
sub_protocol==KN
|
||||
WLTOYS 0
|
||||
FEILUN 1
|
||||
WLTOYS 0
|
||||
FEILUN 1
|
||||
sub_protocol==SYMAX
|
||||
SYMAX 0
|
||||
SYMAX5C 1
|
||||
SYMAX 0
|
||||
SYMAX5C 1
|
||||
sub_protocol==CX10
|
||||
CX10_GREEN 0
|
||||
CX10_BLUE 1 // also compatible with CX10-A, CX12
|
||||
@ -464,6 +504,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
X800 2
|
||||
H26D 3
|
||||
E010 4
|
||||
sub_protocol==FY326
|
||||
FY326 0
|
||||
FY319 1
|
||||
sub_protocol==FRSKYX
|
||||
CH_16 0
|
||||
CH_8 1
|
||||
@ -471,7 +514,13 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
FORMAT_HONTAI 0
|
||||
FORMAT_JJRCX1 1
|
||||
FORMAT_X5C1 2
|
||||
Power value => 0x80 0=High/1=Low
|
||||
FQ777-521 3
|
||||
sub_protocol==AFHDS2A
|
||||
PWM_IBUS 0
|
||||
PPM_IBUS 1
|
||||
PWM_SBUS 2
|
||||
PPM_SBUS 3
|
||||
Power value => 0x80 0=High/1=Low
|
||||
Stream[3] = option_protocol;
|
||||
option_protocol value is -127..127
|
||||
Stream[4] to [25] = Channels
|
||||
@ -483,3 +532,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
2047 +125%
|
||||
Channels bits are concatenated to fit in 22 bytes like in SBUS protocol
|
||||
*/
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
BIN
Multiprotocol/sync.ffs_db
Normal file
BIN
Multiprotocol/sync.ffs_db
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user