mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-12 09:47:54 +00:00
Création
This commit is contained in:
parent
89bea4c38b
commit
068b21cbb1
@ -30,12 +30,12 @@ void A7105_WriteData(uint8_t len, uint8_t channel)
|
|||||||
A7105_Strobe(A7105_TX);
|
A7105_Strobe(A7105_TX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void A7105_ReadData() {
|
void A7105_ReadData(uint8_t len=16) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
A7105_Strobe(0xF0); //A7105_RST_RDPTR
|
A7105_Strobe(0xF0); //A7105_RST_RDPTR
|
||||||
A7105_CSN_off;
|
A7105_CSN_off;
|
||||||
SPI_Write(0x45);
|
SPI_Write(0x45);
|
||||||
for (i=0;i<16;i++)
|
for (i=0;i<len;i++)
|
||||||
packet[i]=SPI_SDIO_Read();
|
packet[i]=SPI_SDIO_Read();
|
||||||
A7105_CSN_on;
|
A7105_CSN_on;
|
||||||
}
|
}
|
||||||
@ -159,15 +159,24 @@ const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
|
|||||||
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
|
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
|
||||||
0x01, 0x0f, 0xff
|
0x01, 0x0f, 0xff
|
||||||
};
|
};
|
||||||
|
const uint8_t AFHDS2A_regs[] = {
|
||||||
|
-1 , 0x42 | (1<<5), 0x00, 0x25, 0x00, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f
|
||||||
|
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, -1, -1, 0x2a, 0x32, 0xc3, 0x1f, // 10 - 1f
|
||||||
|
0x1e, -1, 0x00, -1, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
|
||||||
|
0x01, 0x0f // 30 - 31
|
||||||
|
};
|
||||||
#define ID_NORMAL 0x55201041
|
#define ID_NORMAL 0x55201041
|
||||||
#define ID_PLUS 0xAA201041
|
#define ID_PLUS 0xAA201041
|
||||||
void A7105_Init(uint8_t protocol)
|
void A7105_Init(uint8_t protocol)
|
||||||
{
|
{
|
||||||
void *A7105_Regs;
|
void *A7105_Regs;
|
||||||
|
|
||||||
if(protocol==INIT_FLYSKY)
|
if(protocol==INIT_FLYSKY || protocol==INIT_FLYSKY_AFHDS2A)
|
||||||
{
|
{
|
||||||
A7105_WriteID(0x5475c52A);//0x2Ac57554
|
A7105_WriteID(0x5475c52A);//0x2Ac57554
|
||||||
|
if(protocol==INIT_FLYSKY_AFHDS2A)
|
||||||
|
A7105_Regs=(void *)AFHDS2A_regs;
|
||||||
|
else
|
||||||
A7105_Regs=(void *)FLYSKY_A7105_regs;
|
A7105_Regs=(void *)FLYSKY_A7105_regs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -187,7 +196,7 @@ void A7105_Init(uint8_t protocol)
|
|||||||
// A7105_ReadReg(A7105_22_IF_CALIB_I);
|
// A7105_ReadReg(A7105_22_IF_CALIB_I);
|
||||||
// A7105_ReadReg(A7105_24_VCO_CURCAL);
|
// A7105_ReadReg(A7105_24_VCO_CURCAL);
|
||||||
|
|
||||||
if(protocol==INIT_FLYSKY)
|
if(protocol==INIT_FLYSKY || protocol==INIT_FLYSKY_AFHDS2A)
|
||||||
{
|
{
|
||||||
//VCO Current Calibration
|
//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
|
||||||
@ -210,6 +219,8 @@ void A7105_Init(uint8_t protocol)
|
|||||||
//Reset VCO Band calibration
|
//Reset VCO Band calibration
|
||||||
if(protocol==INIT_FLYSKY)
|
if(protocol==INIT_FLYSKY)
|
||||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I,0x08);
|
A7105_WriteReg(A7105_25_VCO_SBCAL_I,0x08);
|
||||||
|
if(protocol==INIT_FLYSKY_AFHDS2A)
|
||||||
|
A7105_WriteReg(A7105_25_VCO_SBCAL_I,0x0A);
|
||||||
|
|
||||||
A7105_SetTxRxMode(TX_EN);
|
A7105_SetTxRxMode(TX_EN);
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
|
@ -109,9 +109,7 @@ static void joysway_build_packet()
|
|||||||
static const int chmap[4] = {6, 7, 10, 11};
|
static const int chmap[4] = {6, 7, 10, 11};
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
// if (i >= Model.num_channels) { packet[chmap[i]] = 0x64; continue; }
|
// if (i >= Model.num_channels) { packet[chmap[i]] = 0x64; continue; }
|
||||||
uint32_t value = (uint32_t)Servo_data[i] * 0x66 / PPM_MAX + 0x66;
|
uint32_t value = map(limit_channel_100(i),servo_min_100,servo_max_100,0,204);
|
||||||
if (value < 0) { value = 0; }
|
|
||||||
if (value > 0xff) { value = 0xff; }
|
|
||||||
packet[chmap[i]] = value;
|
packet[chmap[i]] = value;
|
||||||
}
|
}
|
||||||
packet[8] = 0x64;
|
packet[8] = 0x64;
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
#define Q282_PACKET_SIZE 21
|
#define Q282_PACKET_SIZE 21
|
||||||
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
|
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
|
||||||
#define CX10A_PACKET_PERIOD 6000
|
#define CX10A_PACKET_PERIOD 6000
|
||||||
<<<<<<< HEAD
|
|
||||||
#define CX10A_BIND_COUNT 400 // 2 seconds
|
|
||||||
=======
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
|
||||||
#define CX10_INITIAL_WAIT 500
|
#define CX10_INITIAL_WAIT 500
|
||||||
|
|
||||||
@ -201,30 +197,15 @@ uint16_t CX10_callback()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CX10_BIND2:
|
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))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{ // RX fifo data ready
|
{ // RX fifo data ready
|
||||||
XN297_ReadPayload(packet, packet_length);
|
XN297_ReadPayload(packet, packet_length);
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
if(packet[9] == 1)
|
if(packet[9] == 1)
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
phase = CX10_BIND1;
|
|
||||||
bind_counter=0;
|
|
||||||
=======
|
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
phase = CX10_DATA;
|
phase = CX10_DATA;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -234,11 +215,7 @@ uint16_t CX10_callback()
|
|||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
CX10_Write_Packet(1);
|
CX10_Write_Packet(1);
|
||||||
<<<<<<< HEAD
|
|
||||||
delayMicroseconds(400); // 300µs in deviation but not working so using 400µs instead
|
|
||||||
=======
|
|
||||||
delayMicroseconds(400);
|
delayMicroseconds(400);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
// switch to RX mode
|
// switch to RX mode
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
@ -288,10 +265,6 @@ uint16_t initCX10(void)
|
|||||||
packet_period = CX10A_PACKET_PERIOD;
|
packet_period = CX10A_PACKET_PERIOD;
|
||||||
|
|
||||||
phase = CX10_BIND2;
|
phase = CX10_BIND2;
|
||||||
<<<<<<< HEAD
|
|
||||||
bind_counter=CX10A_BIND_COUNT;
|
|
||||||
=======
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
|
||||||
for(uint8_t i=0; i<4; i++)
|
for(uint8_t i=0; i<4; i++)
|
||||||
packet[5+i] = 0xff; // clear aircraft id
|
packet[5+i] = 0xff; // clear aircraft id
|
||||||
|
@ -192,18 +192,11 @@ static void CYRF_StartReceive()
|
|||||||
CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, 0x10);
|
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)
|
void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length)
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
|
CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
static void CYRF_WriteDataPacketLen(const uint8_t dpbuffer[], uint8_t len)
|
static void CYRF_WriteDataPacketLen(const uint8_t dpbuffer[], uint8_t len)
|
||||||
{
|
{
|
||||||
CYRF_WriteRegister(CYRF_01_TX_LENGTH, len);
|
CYRF_WriteRegister(CYRF_01_TX_LENGTH, len);
|
||||||
|
@ -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() {
|
static void skyartec_init() {
|
||||||
CC2500_Reset();
|
CC2500_Reset();
|
||||||
|
|
||||||
cc2500_writeReg(CC2500_16_MCSM2, 0x07);
|
CC2500_WriteReg(CC2500_16_MCSM2, 0x07);
|
||||||
cc2500_writeReg(CC2500_17_MCSM1, 0x30);
|
CC2500_WriteReg(CC2500_17_MCSM1, 0x30);
|
||||||
cc2500_writeReg(CC2500_1E_WOREVT1, 0x87);
|
CC2500_WriteReg(CC2500_1E_WOREVT1, 0x87);
|
||||||
cc2500_writeReg(CC2500_1F_WOREVT0, 0x6b);
|
CC2500_WriteReg(CC2500_1F_WOREVT0, 0x6b);
|
||||||
cc2500_writeReg(CC2500_20_WORCTRL, 0xf8);
|
CC2500_WriteReg(CC2500_20_WORCTRL, 0xf8);
|
||||||
cc2500_writeReg(CC2500_2A_PTEST, 0x7f);
|
CC2500_WriteReg(CC2500_2A_PTEST, 0x7f);
|
||||||
cc2500_writeReg(CC2500_2B_AGCTEST, 0x3f);
|
CC2500_WriteReg(CC2500_2B_AGCTEST, 0x3f);
|
||||||
cc2500_writeReg(CC2500_0B_FSCTRL1, 0x09);
|
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x09);
|
||||||
cc2500_writeReg(CC2500_0C_FSCTRL0, 0x00);
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00);
|
||||||
cc2500_writeReg(CC2500_0D_FREQ2, 0x5d);
|
CC2500_WriteReg(CC2500_0D_FREQ2, 0x5d);
|
||||||
cc2500_writeReg(CC2500_0E_FREQ1, 0x93);
|
CC2500_WriteReg(CC2500_0E_FREQ1, 0x93);
|
||||||
cc2500_writeReg(CC2500_0F_FREQ0, 0xb1);
|
CC2500_WriteReg(CC2500_0F_FREQ0, 0xb1);
|
||||||
cc2500_writeReg(CC2500_10_MDMCFG4, 0x2d);
|
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x2d);
|
||||||
cc2500_writeReg(CC2500_11_MDMCFG3, 0x20);
|
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x20);
|
||||||
cc2500_writeReg(CC2500_12_MDMCFG2, 0x73);
|
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x73);
|
||||||
cc2500_writeReg(CC2500_13_MDMCFG1, 0x22);
|
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x22);
|
||||||
cc2500_writeReg(CC2500_14_MDMCFG0, 0xf8);
|
CC2500_WriteReg(CC2500_14_MDMCFG0, 0xf8);
|
||||||
cc2500_writeReg(CC2500_0A_CHANNR, 0xcd);
|
CC2500_WriteReg(CC2500_0A_CHANNR, 0xcd);
|
||||||
cc2500_writeReg(CC2500_15_DEVIATN, 0x50);
|
CC2500_WriteReg(CC2500_15_DEVIATN, 0x50);
|
||||||
cc2500_writeReg(CC2500_21_FREND1, 0xb6);
|
CC2500_WriteReg(CC2500_21_FREND1, 0xb6);
|
||||||
cc2500_writeReg(CC2500_22_FREND0, 0x10);
|
CC2500_WriteReg(CC2500_22_FREND0, 0x10);
|
||||||
cc2500_writeReg(CC2500_18_MCSM0, 0x18);
|
CC2500_WriteReg(CC2500_18_MCSM0, 0x18);
|
||||||
cc2500_writeReg(CC2500_19_FOCCFG, 0x1d);
|
CC2500_WriteReg(CC2500_19_FOCCFG, 0x1d);
|
||||||
cc2500_writeReg(CC2500_1A_BSCFG, 0x1c);
|
CC2500_WriteReg(CC2500_1A_BSCFG, 0x1c);
|
||||||
cc2500_writeReg(CC2500_1B_AGCCTRL2, 0xc7);
|
CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xc7);
|
||||||
cc2500_writeReg(CC2500_1C_AGCCTRL1, 0x00);
|
CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00);
|
||||||
cc2500_writeReg(CC2500_1D_AGCCTRL0, 0xb2);
|
CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xb2);
|
||||||
cc2500_writeReg(CC2500_23_FSCAL3, 0xea);
|
CC2500_WriteReg(CC2500_23_FSCAL3, 0xea);
|
||||||
cc2500_writeReg(CC2500_24_FSCAL2, 0x0a);
|
CC2500_WriteReg(CC2500_24_FSCAL2, 0x0a);
|
||||||
cc2500_writeReg(CC2500_25_FSCAL1, 0x00);
|
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00);
|
||||||
cc2500_writeReg(CC2500_26_FSCAL0, 0x11);
|
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11);
|
||||||
cc2500_writeReg(CC2500_29_FSTEST, 0x59);
|
CC2500_WriteReg(CC2500_29_FSTEST, 0x59);
|
||||||
cc2500_writeReg(CC2500_2C_TEST2, 0x88);
|
CC2500_WriteReg(CC2500_2C_TEST2, 0x88);
|
||||||
cc2500_writeReg(CC2500_2D_TEST1, 0x31);
|
CC2500_WriteReg(CC2500_2D_TEST1, 0x31);
|
||||||
cc2500_writeReg(CC2500_2E_TEST0, 0x0b);
|
CC2500_WriteReg(CC2500_2E_TEST0, 0x0b);
|
||||||
cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05);
|
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||||
cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05);
|
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05);
|
||||||
cc2500_writeReg(CC2500_09_ADDR, 0x43);
|
CC2500_WriteReg(CC2500_09_ADDR, 0x43);
|
||||||
cc2500_writeReg(CC2500_06_PKTLEN, 0xff);
|
CC2500_WriteReg(CC2500_06_PKTLEN, 0xff);
|
||||||
cc2500_writeReg(CC2500_04_SYNC1, 0x13);
|
CC2500_WriteReg(CC2500_04_SYNC1, 0x13);
|
||||||
cc2500_writeReg(CC2500_05_SYNC0, 0x18);
|
CC2500_WriteReg(CC2500_05_SYNC0, 0x18);
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
cc2500_strobe(CC2500_SFTX);
|
CC2500_Strobe(CC2500_SFTX);
|
||||||
cc2500_strobe(CC2500_SFRX);
|
CC2500_Strobe(CC2500_SFRX);
|
||||||
cc2500_strobe(CC2500_SXOFF);
|
CC2500_Strobe(CC2500_SXOFF);
|
||||||
cc2500_strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_pkt_suffix() {
|
static void add_pkt_suffix() {
|
||||||
@ -104,7 +104,7 @@ static void send_data_packet() {
|
|||||||
packet[1] = TX_ADDR; //Tx Addr?
|
packet[1] = TX_ADDR; //Tx Addr?
|
||||||
packet[2] = 0x01; //???
|
packet[2] = 0x01; //???
|
||||||
for(int i = 0; i < 7; i++) {
|
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 < 0) { value = 0; }
|
||||||
if(value > 0x500) { value = 0x500; }
|
if(value > 0x500) { value = 0x500; }
|
||||||
packet[3+2*i] = value >> 8;
|
packet[3+2*i] = value >> 8;
|
||||||
@ -112,11 +112,11 @@ static void send_data_packet() {
|
|||||||
}
|
}
|
||||||
add_pkt_suffix();
|
add_pkt_suffix();
|
||||||
//for(int i = 0; i < 20; i++) printf("%02x ", packet[i]); printf("\n");
|
//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_04_SYNC1, ((binding_idx >> 0) & 0xff));
|
||||||
cc2500_writeReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff));
|
CC2500_WriteReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff));
|
||||||
cc2500_writeReg(CC2500_09_ADDR, TX_ADDR);
|
CC2500_WriteReg(CC2500_09_ADDR, TX_ADDR);
|
||||||
cc2500_writeReg(CC2500_0A_CHANNR, TX_CHANNEL);
|
CC2500_WriteReg(CC2500_0A_CHANNR, TX_CHANNEL);
|
||||||
cc2500_writeFifo(packet, 20);
|
CC2500_WriteData(packet, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bind_packet() {
|
static void send_bind_packet() {
|
||||||
@ -135,16 +135,16 @@ static void send_bind_packet() {
|
|||||||
uint8_t xore = 0;
|
uint8_t xore = 0;
|
||||||
for(int i = 3; i < 11; i++) { xore ^= packet[i]; }
|
for(int i = 3; i < 11; i++) { xore ^= packet[i]; }
|
||||||
packet[11] = xore;
|
packet[11] = xore;
|
||||||
cc2500_writeReg(CC2500_04_SYNC1, 0x7d);
|
CC2500_WriteReg(CC2500_04_SYNC1, 0x7d);
|
||||||
cc2500_writeReg(CC2500_05_SYNC0, 0x7d);
|
CC2500_WriteReg(CC2500_05_SYNC0, 0x7d);
|
||||||
cc2500_writeReg(CC2500_09_ADDR, 0x7d);
|
CC2500_WriteReg(CC2500_09_ADDR, 0x7d);
|
||||||
cc2500_writeReg(CC2500_0A_CHANNR, 0x7d);
|
CC2500_WriteReg(CC2500_0A_CHANNR, 0x7d);
|
||||||
cc2500_writeFifo(packet, 12);
|
CC2500_WriteData(packet, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t skyartec_cb() {
|
static uint16_t skyartec_cb() {
|
||||||
if (state & 0x01) {
|
if (state & 0x01) {
|
||||||
cc2500_strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
if (state == SKYARTEC_LAST) { CC2500_SetPower(); state = SKYARTEC_PKT1; }
|
if (state == SKYARTEC_LAST) { CC2500_SetPower(); state = SKYARTEC_PKT1; }
|
||||||
else { state++; }
|
else { state++; }
|
||||||
return 3000;
|
return 3000;
|
||||||
|
@ -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
|
|
@ -43,31 +43,7 @@ enum {
|
|||||||
DEVO_BOUND_10,
|
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()
|
static void __attribute__((unused)) DEVO_scramble_pkt()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
#ifdef NO_SCRAMBLE
|
#ifdef NO_SCRAMBLE
|
||||||
return;
|
return;
|
||||||
@ -77,11 +53,7 @@ static void __attribute__((unused)) DEVO_scramble_pkt()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
static void __attribute__((unused)) add_pkt_suffix()
|
|
||||||
=======
|
|
||||||
static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
uint8_t bind_state;
|
uint8_t bind_state;
|
||||||
#ifdef ENABLE_PPM
|
#ifdef ENABLE_PPM
|
||||||
@ -119,11 +91,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
|||||||
packet[15] = (MProtocol_id >> 16) & 0xff;
|
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)
|
static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x07;
|
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x07;
|
||||||
uint8_t max = 8;
|
uint8_t max = 8;
|
||||||
@ -138,11 +106,7 @@ static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
|||||||
DEVO_add_pkt_suffix();
|
DEVO_add_pkt_suffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
static void __attribute__((unused)) build_bind_pkt()
|
|
||||||
=======
|
|
||||||
static void __attribute__((unused)) DEVO_build_bind_pkt()
|
static void __attribute__((unused)) DEVO_build_bind_pkt()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
|
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
|
||||||
packet[1] = bind_counter & 0xff;
|
packet[1] = bind_counter & 0xff;
|
||||||
@ -162,11 +126,7 @@ static void __attribute__((unused)) DEVO_build_bind_pkt()
|
|||||||
packet[15] ^= cyrfmfg_id[2];
|
packet[15] ^= cyrfmfg_id[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
static void __attribute__((unused)) build_data_pkt()
|
|
||||||
=======
|
|
||||||
static void __attribute__((unused)) DEVO_build_data_pkt()
|
static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
static uint8_t ch_idx=0;
|
static uint8_t ch_idx=0;
|
||||||
|
|
||||||
@ -190,11 +150,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
|||||||
DEVO_add_pkt_suffix();
|
DEVO_add_pkt_suffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
static void __attribute__((unused)) cyrf_set_bound_sop_code()
|
|
||||||
=======
|
|
||||||
static void __attribute__((unused)) DEVO_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 */
|
/* 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]);
|
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);
|
CYRF_SetPower(0x08);
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
static void __attribute__((unused)) cyrf_init()
|
|
||||||
=======
|
|
||||||
const uint8_t PROGMEM DEVO_init_vals[][2] = {
|
const uint8_t PROGMEM DEVO_init_vals[][2] = {
|
||||||
{ CYRF_1D_MODE_OVERRIDE, 0x38 },
|
{ CYRF_1D_MODE_OVERRIDE, 0x38 },
|
||||||
{ CYRF_03_TX_CFG, 0x08 },
|
{ CYRF_03_TX_CFG, 0x08 },
|
||||||
@ -233,18 +186,13 @@ const uint8_t PROGMEM DEVO_init_vals[][2] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void __attribute__((unused)) DEVO_cyrf_init()
|
static void __attribute__((unused)) DEVO_cyrf_init()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
/* Initialise CYRF chip */
|
/* Initialise CYRF chip */
|
||||||
for(uint8_t i = 0; i < sizeof(DEVO_init_vals) / 2; i++)
|
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]) );
|
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()
|
static void __attribute__((unused)) DEVO_set_radio_channels()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
|
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
|
||||||
hopping_frequency[3] = hopping_frequency[0];
|
hopping_frequency[3] = hopping_frequency[0];
|
||||||
@ -337,35 +285,6 @@ uint16_t devo_callback()
|
|||||||
return 1200;
|
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()
|
uint16_t DevoInit()
|
||||||
{
|
{
|
||||||
DEVO_cyrf_init();
|
DEVO_cyrf_init();
|
||||||
|
@ -15,26 +15,17 @@
|
|||||||
// Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29
|
// Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29
|
||||||
|
|
||||||
#if defined(FY326_NRF24L01_INO)
|
#if defined(FY326_NRF24L01_INO)
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
#define FY326_INITIAL_WAIT 500
|
#define FY326_INITIAL_WAIT 500
|
||||||
#define FY326_PACKET_PERIOD 1500
|
#define FY326_PACKET_PERIOD 1500
|
||||||
#define FY326_PACKET_CHKTIME 300
|
#define FY326_PACKET_CHKTIME 300
|
||||||
#define FY326_PACKET_SIZE 15
|
#define FY326_PACKET_SIZE 15
|
||||||
<<<<<<< HEAD
|
|
||||||
#define FY326_BIND_COUNT 16
|
#define FY326_BIND_COUNT 16
|
||||||
=======
|
|
||||||
#define FY326_BIND_COUNT 16
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#define FY326_RF_BIND_CHANNEL 0x17
|
#define FY326_RF_BIND_CHANNEL 0x17
|
||||||
#define FY326_NUM_RF_CHANNELS 5
|
#define FY326_NUM_RF_CHANNELS 5
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
<<<<<<< HEAD
|
|
||||||
FY326_INIT1 = 0,
|
FY326_INIT1 = 0,
|
||||||
FY326_BIND1,
|
FY326_BIND1,
|
||||||
FY326_BIND2,
|
FY326_BIND2,
|
||||||
@ -42,11 +33,6 @@ enum {
|
|||||||
FY319_INIT1,
|
FY319_INIT1,
|
||||||
FY319_BIND1,
|
FY319_BIND1,
|
||||||
FY319_BIND2,
|
FY319_BIND2,
|
||||||
=======
|
|
||||||
FY326_BIND1=0,
|
|
||||||
FY326_BIND2,
|
|
||||||
FY326_DATA
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define rxid channel
|
#define rxid channel
|
||||||
@ -56,11 +42,7 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
|||||||
{
|
{
|
||||||
packet[0] = rx_tx_addr[3];
|
packet[0] = rx_tx_addr[3];
|
||||||
if(bind)
|
if(bind)
|
||||||
<<<<<<< HEAD
|
|
||||||
packet[1] = 0x55;
|
packet[1] = 0x55;
|
||||||
=======
|
|
||||||
packet[1] = 0x55;
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
else
|
else
|
||||||
packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless
|
packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless
|
||||||
| GET_FLAG(Servo_AUX2, 0x40) // RTH
|
| 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[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
|
||||||
packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder
|
packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder
|
||||||
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
|
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
|
||||||
<<<<<<< HEAD
|
|
||||||
if(sub_protocol == FY319) {
|
if(sub_protocol == FY319) {
|
||||||
packet[6] = 255 - scale_channel(AILERON, 0, 255);
|
packet[6] = 255 - convert_channel_8b_scale(AILERON, 0, 255);
|
||||||
packet[7] = scale_channel(ELEVATOR, 0, 255);
|
packet[7] = convert_channel_8b_scale(ELEVATOR, 0, 255);
|
||||||
packet[8] = 255 - scale_channel(RUDDER, 0, 255);
|
packet[8] = 255 - convert_channel_8b_scale(RUDDER, 0, 255);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
packet[6] = rx_tx_addr[0];
|
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[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim;
|
||||||
packet[12] = 0; // throttle_trim;
|
packet[12] = 0; // throttle_trim;
|
||||||
packet[13] = rxid;
|
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];
|
packet[14] = rx_tx_addr[4];
|
||||||
|
|
||||||
if (bind)
|
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++]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||||
hopping_frequency_no %= FY326_NUM_RF_CHANNELS;
|
hopping_frequency_no %= FY326_NUM_RF_CHANNELS;
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear packet status bits and TX FIFO
|
// clear packet status bits and TX FIFO
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
NRF24L01_FlushTx();
|
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);
|
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()
|
static void __attribute__((unused)) FY326_init()
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
if(sub_protocol == FY319)
|
if(sub_protocol == FY319)
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address
|
||||||
else
|
else
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address
|
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_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_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
@ -150,20 +107,14 @@ static void __attribute__((unused)) FY326_init()
|
|||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
=======
|
|
||||||
|
|
||||||
NRF24L01_Activate(0x73);
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
|
||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
uint16_t FY326_callback()
|
||||||
uint16_t fy326_callback()
|
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
@ -171,19 +122,19 @@ uint16_t fy326_callback()
|
|||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
NRF24L01_SetTxRxMode(RX_EN);
|
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;
|
phase = FY319_BIND1;
|
||||||
BIND_IN_PROGRESS;
|
BIND_IN_PROGRESS;
|
||||||
return FY326_CHKTIME;
|
return FY326_PACKET_CHKTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FY319_BIND1:
|
case FY319_BIND1:
|
||||||
if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) {
|
if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) {
|
||||||
NRF24L01_ReadPayload(packet, FY326_SIZE);
|
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
||||||
rxid = packet[13];
|
rxid = packet[13];
|
||||||
packet[0] = txid[3];
|
packet[0] = rx_tx_addr[3];
|
||||||
packet[1] = 0x80;
|
packet[1] = 0x80;
|
||||||
packet[14]= txid[4];
|
packet[14]= rx_tx_addr[4];
|
||||||
bind_counter = FY326_BIND_COUNT;
|
bind_counter = FY326_BIND_COUNT;
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
@ -191,16 +142,16 @@ uint16_t fy326_callback()
|
|||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
bind_counter = 255;
|
bind_counter = 255;
|
||||||
for(i=2; i<6; i++)
|
for(i=2; i<6; i++)
|
||||||
packet[i] = rf_chans[0];
|
packet[i] = hopping_frequency[0];
|
||||||
phase = FY319_BIND2;
|
phase = FY319_BIND2;
|
||||||
}
|
}
|
||||||
return FY326_CHKTIME;
|
return FY326_PACKET_CHKTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FY319_BIND2:
|
case FY319_BIND2:
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_WritePayload(packet, FY326_SIZE);
|
NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
|
||||||
if(bind_counter == 250)
|
if(bind_counter == 250)
|
||||||
packet[1] = 0x40;
|
packet[1] = 0x40;
|
||||||
if(--bind_counter == 0) {
|
if(--bind_counter == 0) {
|
||||||
@ -212,54 +163,10 @@ uint16_t fy326_callback()
|
|||||||
case FY326_INIT1:
|
case FY326_INIT1:
|
||||||
bind_counter = FY326_BIND_COUNT;
|
bind_counter = FY326_BIND_COUNT;
|
||||||
phase = FY326_BIND2;
|
phase = FY326_BIND2;
|
||||||
send_packet(1);
|
|
||||||
return FY326_CHKTIME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
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;
|
return FY326_PACKET_CHKTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FY326_DATA:
|
|
||||||
FY326_send_packet(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
uint16_t FY326_callback()
|
|
||||||
{
|
|
||||||
switch (phase)
|
|
||||||
{
|
|
||||||
case FY326_BIND1:
|
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
|
{ // RX fifo data ready
|
||||||
@ -282,6 +189,7 @@ uint16_t FY326_callback()
|
|||||||
return FY326_PACKET_CHKTIME;
|
return FY326_PACKET_CHKTIME;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FY326_BIND2:
|
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
|
{ // TX data sent -> switch to RX mode
|
||||||
@ -293,17 +201,16 @@ uint16_t FY326_callback()
|
|||||||
else
|
else
|
||||||
return FY326_PACKET_CHKTIME;
|
return FY326_PACKET_CHKTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FY326_DATA:
|
case FY326_DATA:
|
||||||
FY326_send_packet(0);
|
FY326_send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
return FY326_PACKET_PERIOD;
|
return FY326_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) FY326_initialize_txid()
|
static void __attribute__((unused)) FY326_initialize_txid()
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
if(sub_protocol == FY319) {
|
if(sub_protocol == FY319) {
|
||||||
hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~0x80;
|
hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~0x80;
|
||||||
hopping_frequency[1] = (rx_tx_addr[0] >> 4) & ~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[3] = 0x30 + (rx_tx_addr[1] >> 4);
|
||||||
hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 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)
|
uint16_t initFY326(void)
|
||||||
{
|
{
|
||||||
BIND_IN_PROGRESS; // autobind protocol
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
<<<<<<< HEAD
|
|
||||||
rxid = 0xaa;
|
|
||||||
bind_counter = 0;
|
|
||||||
FY326_initialize_txid();
|
|
||||||
fy326_init();
|
|
||||||
if(sub_protocol == FY319)
|
|
||||||
phase = FY319_INIT1;
|
|
||||||
else
|
|
||||||
phase = FY326_INIT1;
|
|
||||||
=======
|
|
||||||
rxid = 0xAA;
|
rxid = 0xAA;
|
||||||
bind_counter = 0;
|
bind_counter = 0;
|
||||||
FY326_initialize_txid();
|
FY326_initialize_txid();
|
||||||
FY326_init();
|
FY326_init();
|
||||||
phase=FY326_BIND1;
|
if(sub_protocol == FY319)
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
phase = FY319_INIT1;
|
||||||
|
else
|
||||||
|
phase = FY326_INIT1;
|
||||||
return FY326_INITIAL_WAIT;
|
return FY326_INITIAL_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,26 +21,6 @@
|
|||||||
//FlySky constants & variables
|
//FlySky constants & variables
|
||||||
#define FLYSKY_BIND_COUNT 2500
|
#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 {
|
enum {
|
||||||
// flags going to byte 10
|
// flags going to byte 10
|
||||||
FLAG_V9X9_VIDEO = 0x40,
|
FLAG_V9X9_VIDEO = 0x40,
|
||||||
@ -48,15 +28,6 @@ enum {
|
|||||||
// flags going to byte 12
|
// flags going to byte 12
|
||||||
FLAG_V9X9_FLIP = 0x10,
|
FLAG_V9X9_FLIP = 0x10,
|
||||||
FLAG_V9X9_LED = 0x20,
|
FLAG_V9X9_LED = 0x20,
|
||||||
=======
|
|
||||||
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,
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -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()
|
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;
|
static uint8_t seq_counter;
|
||||||
switch(sub_protocol)
|
switch(sub_protocol)
|
||||||
{
|
{
|
||||||
@ -226,7 +124,6 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
||||||
@ -242,20 +139,11 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|||||||
packet[2] = rx_tx_addr[2];
|
packet[2] = rx_tx_addr[2];
|
||||||
packet[3] = rx_tx_addr[1];
|
packet[3] = rx_tx_addr[1];
|
||||||
packet[4] = rx_tx_addr[0];
|
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++)
|
for(i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
packet[5 + i*2]=Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us)
|
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)
|
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();
|
flysky_apply_extension_flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,35 +157,6 @@ uint16_t ReadFlySky()
|
|||||||
if (! bind_counter)
|
if (! bind_counter)
|
||||||
BIND_DONE;
|
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
|
else
|
||||||
{
|
{
|
||||||
flysky_build_packet(0);
|
flysky_build_packet(0);
|
||||||
@ -352,7 +211,5 @@ uint16_t initFlySky()
|
|||||||
else
|
else
|
||||||
bind_counter = 0;
|
bind_counter = 0;
|
||||||
return 2400;
|
return 2400;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
317
Multiprotocol/Flysky_afhds2a_a7105.ino
Normal file
317
Multiprotocol/Flysky_afhds2a_a7105.ino
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
// adaptation de https://github.com/goebish/deviation/blob/c5dd9fcc1441fc05fe9effa4c378886aeb3938d4/src/protocol/flysky_afhds2a_a7105.c
|
||||||
|
#ifdef AFHDS2A_A7105_INO
|
||||||
|
#define EEPROMadress 0 // rx ID 32bit
|
||||||
|
#define SERVO_HZ 0 //Frequency's servo 0=50 1=400 2=5
|
||||||
|
|
||||||
|
#define TXPACKET_SIZE 38
|
||||||
|
#define RXPACKET_SIZE 37
|
||||||
|
#define NUMFREQ 16
|
||||||
|
#define TXID_SIZE 4
|
||||||
|
#define RXID_SIZE 4
|
||||||
|
|
||||||
|
static uint8_t rxid[RXID_SIZE];
|
||||||
|
static uint8_t packet_type;
|
||||||
|
static uint8_t bind_reply;
|
||||||
|
|
||||||
|
|
||||||
|
enum{
|
||||||
|
PACKET_STICKS,
|
||||||
|
PACKET_SETTINGS,
|
||||||
|
PACKET_FAILSAFE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum{
|
||||||
|
BIND1,
|
||||||
|
BIND2,
|
||||||
|
BIND3,
|
||||||
|
BIND4,
|
||||||
|
DATA1,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
PWM_IBUS = 0,
|
||||||
|
PPM_IBUS,
|
||||||
|
PWM_SBUS,
|
||||||
|
PPM_SBUS
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void build_packet(uint8_t type) {
|
||||||
|
switch(type) {
|
||||||
|
case PACKET_STICKS:
|
||||||
|
packet[0] = 0x58;
|
||||||
|
memcpy( &packet[1], rx_tx_addr, 4);
|
||||||
|
memcpy( &packet[5], rxid, 4);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
packet[37] = 0x00;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PACKET_SETTINGS:
|
||||||
|
packet[0] = 0xaa;
|
||||||
|
memcpy( &packet[1], rx_tx_addr, 4);
|
||||||
|
memcpy( &packet[5], rxid, 4);
|
||||||
|
packet[9] = 0xfd;
|
||||||
|
packet[10]= 0xff;
|
||||||
|
packet[11]= SERVO_HZ & 0xff;
|
||||||
|
packet[12]= (SERVO_HZ >> 8) & 0xff;
|
||||||
|
if(option == PPM_IBUS || option == 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(option == PWM_SBUS || option == PPM_SBUS)
|
||||||
|
packet[21] = 0xdd; // SBUS output enabled
|
||||||
|
else
|
||||||
|
packet[21] = 0xde;
|
||||||
|
packet[37] = 0x00;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PACKET_FAILSAFE:
|
||||||
|
packet[0] = 0x56;
|
||||||
|
memcpy( &packet[1], rx_tx_addr, 4);
|
||||||
|
memcpy( &packet[5], rxid, 4);
|
||||||
|
for(uint8_t ch=0; ch<14; ch++) {
|
||||||
|
if(ch==0) {
|
||||||
|
// if(ch < Model.num_channels && (Model.limits[ch].flags & CH_FAILSAFE_EN)) {
|
||||||
|
uint32_t value = ((uint32_t)Servo_data[AUX11] + 100) * 5 + 1000;
|
||||||
|
packet[9 + ch*2] = value & 0xff;
|
||||||
|
packet[10+ ch*2] = (value >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
packet[9 + ch*2] = 0xff;
|
||||||
|
packet[10+ ch*2] = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet[37] = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TELEMETRY)
|
||||||
|
// telemetry sensors ID
|
||||||
|
enum{
|
||||||
|
SENSOR_RX_VOLTAGE = 0x00,
|
||||||
|
SENSOR_RX_ERR_RATE = 0xfe,
|
||||||
|
SENSOR_RX_RSSI = 0xfc,
|
||||||
|
SENSOR_RX_NOISE = 0xfb,
|
||||||
|
SENSOR_RX_SNR = 0xfa,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void update_telemetry() {
|
||||||
|
// AA | TXID | RXID | sensor id | sensor # | value 16 bit big endian | sensor id ......
|
||||||
|
// max 7 sensors per packet
|
||||||
|
|
||||||
|
for(uint8_t sensor=0; sensor<7; sensor++) {
|
||||||
|
uint8_t index = 9+(4*sensor);
|
||||||
|
switch(packet[index]) {
|
||||||
|
case SENSOR_RX_VOLTAGE:
|
||||||
|
v_lipo = packet[index+3]<<8 | packet[index+2];
|
||||||
|
telemetry_link=1;
|
||||||
|
break;
|
||||||
|
case SENSOR_RX_ERR_RATE:
|
||||||
|
// packet[index+2];
|
||||||
|
break;
|
||||||
|
case 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<16; ch++) {
|
||||||
|
packet[11+ch] = hopping_frequency[ch];
|
||||||
|
}
|
||||||
|
memset( &packet[27], 0xff, 10);
|
||||||
|
packet[37] = 0x00;
|
||||||
|
switch(phase) {
|
||||||
|
case BIND1:
|
||||||
|
packet[0] = 0xbb;
|
||||||
|
packet[9] = 0x01;
|
||||||
|
break;
|
||||||
|
case BIND2:
|
||||||
|
case BIND3:
|
||||||
|
case BIND4:
|
||||||
|
packet[0] = 0xbc;
|
||||||
|
if(phase == BIND4) {
|
||||||
|
memcpy( &packet[5], &rxid, 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 calc_afhds_channels(uint32_t seed) {
|
||||||
|
int idx = 0;
|
||||||
|
uint32_t rnd = seed;
|
||||||
|
while (idx < NUMFREQ) {
|
||||||
|
int i;
|
||||||
|
int 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 ^ seed) & 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WAIT_WRITE 0x80
|
||||||
|
static uint16_t afhds2a_cb() {
|
||||||
|
switch(phase) {
|
||||||
|
case BIND1:
|
||||||
|
case BIND2:
|
||||||
|
case BIND3:
|
||||||
|
A7105_Strobe(A7105_STANDBY);
|
||||||
|
afhds2a_build_bind_packet();
|
||||||
|
A7105_WriteData(38, packet_count%2 ? 0x0d : 0x8c);
|
||||||
|
if(A7105_ReadReg(0) == 0x1b) { // todo: replace with check crc+fec
|
||||||
|
A7105_Strobe(A7105_RST_RDPTR);
|
||||||
|
A7105_ReadData(RXPACKET_SIZE);
|
||||||
|
if(packet[0] == 0xbc) {
|
||||||
|
for(uint8_t i=0; i<4; i++) {
|
||||||
|
rxid[i] = packet[5+i];
|
||||||
|
}
|
||||||
|
eeprom_write_block((const void*)rxid,(void*)EEPROMadress,4);
|
||||||
|
if(packet[9] == 0x01)
|
||||||
|
phase = BIND4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet_count++;
|
||||||
|
phase |= WAIT_WRITE;
|
||||||
|
return 1700;
|
||||||
|
case BIND1|WAIT_WRITE:
|
||||||
|
case BIND2|WAIT_WRITE:
|
||||||
|
case BIND3|WAIT_WRITE:
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
phase &= ~WAIT_WRITE;
|
||||||
|
phase++;
|
||||||
|
if(phase > BIND3)
|
||||||
|
phase = BIND1;
|
||||||
|
return 2150;
|
||||||
|
case BIND4:
|
||||||
|
A7105_Strobe(A7105_STANDBY);
|
||||||
|
afhds2a_build_bind_packet();
|
||||||
|
A7105_WriteData(38, packet_count%2 ? 0x0d : 0x8c);
|
||||||
|
packet_count++;
|
||||||
|
bind_reply++;
|
||||||
|
if(bind_reply>=4) {
|
||||||
|
packet_count=0;
|
||||||
|
channel=1;
|
||||||
|
phase = DATA1;
|
||||||
|
BIND_DONE;
|
||||||
|
}
|
||||||
|
phase |= WAIT_WRITE;
|
||||||
|
return 1700;
|
||||||
|
case BIND4|WAIT_WRITE:
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
phase &= ~WAIT_WRITE;
|
||||||
|
return 2150;
|
||||||
|
case DATA1:
|
||||||
|
A7105_Strobe(A7105_STANDBY);
|
||||||
|
build_packet(packet_type);
|
||||||
|
A7105_WriteData(38, hopping_frequency[channel++]);
|
||||||
|
if(channel >= 16)
|
||||||
|
channel = 0;
|
||||||
|
if(!(packet_count % 1313))
|
||||||
|
packet_type = PACKET_SETTINGS;
|
||||||
|
else if(!(packet_count % 1569))
|
||||||
|
packet_type = PACKET_FAILSAFE;
|
||||||
|
else
|
||||||
|
packet_type = PACKET_STICKS; // todo : check for settings changes
|
||||||
|
// got some data from RX ?
|
||||||
|
// we've no way to know if RX fifo has been filled
|
||||||
|
// as we can't poll GIO1 or GIO2 to check WTR
|
||||||
|
// we can't check A7105_MASK_TREN either as we know
|
||||||
|
// it's currently in transmit mode.
|
||||||
|
if(!(A7105_ReadReg(0) & (1<<5 | 1<<6))) { // FECF+CRCF Ok
|
||||||
|
A7105_Strobe(A7105_RST_RDPTR);
|
||||||
|
A7105_ReadData(1);
|
||||||
|
if(packet[0] == 0xaa) {
|
||||||
|
A7105_Strobe(A7105_RST_RDPTR);
|
||||||
|
A7105_ReadData(RXPACKET_SIZE);
|
||||||
|
if(packet[9] == 0xfc) { // rx is asking for settings
|
||||||
|
packet_type=PACKET_SETTINGS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if defined(TELEMETRY)
|
||||||
|
update_telemetry();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet_count++;
|
||||||
|
phase |= WAIT_WRITE;
|
||||||
|
return 1700;
|
||||||
|
case DATA1|WAIT_WRITE:
|
||||||
|
phase &= ~WAIT_WRITE;
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
return 2150;
|
||||||
|
}
|
||||||
|
return 3850; // never reached, please the compiler
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t AFHDS2A_setup()
|
||||||
|
{
|
||||||
|
A7105_Init(INIT_FLYSKY_AFHDS2A); //flysky_init();
|
||||||
|
|
||||||
|
calc_afhds_channels(MProtocol_id);
|
||||||
|
packet_type = PACKET_STICKS;
|
||||||
|
packet_count = 0;
|
||||||
|
bind_reply = 0;
|
||||||
|
if(IS_AUTOBIND_FLAG_on) {
|
||||||
|
phase = BIND1;
|
||||||
|
BIND_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
phase = DATA1;
|
||||||
|
eeprom_read_block((void*)rxid,(const void*)EEPROMadress,4);
|
||||||
|
}
|
||||||
|
channel = 0;
|
||||||
|
return 50000;
|
||||||
|
}
|
||||||
|
#endif
|
@ -20,294 +20,6 @@
|
|||||||
|
|
||||||
#include "iface_cc2500.h"
|
#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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 chanskip;
|
||||||
uint8_t counter_rst;
|
uint8_t counter_rst;
|
||||||
uint8_t ctr;
|
uint8_t ctr;
|
||||||
@ -617,5 +329,4 @@ uint16_t initFrSkyX()
|
|||||||
seq_last_rcvd = 8;
|
seq_last_rcvd = 8;
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#endif
|
#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
|
|
@ -70,6 +70,7 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if(sub_protocol == FORMAT_JJRCX1)
|
if(sub_protocol == FORMAT_JJRCX1)
|
||||||
packet[0] = GET_FLAG(Servo_AUX2, 0x02); // Arm
|
packet[0] = GET_FLAG(Servo_AUX2, 0x02); // Arm
|
||||||
else
|
else
|
||||||
@ -112,6 +113,59 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
|||||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim
|
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim
|
||||||
else
|
else
|
||||||
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim
|
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;
|
packet_size=HONTAI_PACKET_SIZE;
|
||||||
}
|
}
|
||||||
@ -172,7 +226,8 @@ static void __attribute__((unused)) HONTAI_init()
|
|||||||
|
|
||||||
const uint8_t PROGMEM hopping_frequency_nonels[][3] = {
|
const uint8_t PROGMEM hopping_frequency_nonels[][3] = {
|
||||||
{0x05, 0x19, 0x28}, // Hontai
|
{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] = {
|
const uint8_t PROGMEM addr_vals[4][16] = {
|
||||||
{0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a},
|
{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)
|
#if defined(HUBSAN_A7105_INO)
|
||||||
|
|
||||||
#include "iface_a7105.h"
|
#include "iface_a7105.h"
|
||||||
|
enum {
|
||||||
|
FORMAT_H107 = 0,
|
||||||
|
FORMAT_H301,
|
||||||
|
FORMAT_H501,
|
||||||
|
};
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
// flags going to packet[9] (Normal)
|
// flags going to packet[9] (H107 Normal)
|
||||||
HUBSAN_FLAG_VIDEO= 0x01, // record video
|
HUBSAN_FLAG_VIDEO= 0x01, // record video
|
||||||
HUBSAN_FLAG_FLIP = 0x08, // enable flips
|
HUBSAN_FLAG_FLIP = 0x08, // enable flips
|
||||||
HUBSAN_FLAG_LED = 0x04 // enable LEDs
|
HUBSAN_FLAG_LED = 0x04 // enable LEDs
|
||||||
};
|
};
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
// flags going to packet[9] (Plus series)
|
// flags going to packet[9] (H107 Plus series)
|
||||||
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
|
HUBSAN_FLAG_HEADLESS = 0x08, // headless mode
|
||||||
};
|
};
|
||||||
|
|
||||||
enum{
|
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_SNAPSHOT = 0x01,
|
||||||
HUBSAN_FLAG_FLIP_PLUS = 0x80,
|
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;
|
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[3] = (sessionid >> 16) & 0xFF;
|
||||||
packet[4] = (sessionid >> 8) & 0xFF;
|
packet[4] = (sessionid >> 8) & 0xFF;
|
||||||
packet[5] = (sessionid >> 0) & 0xFF;
|
packet[5] = (sessionid >> 0) & 0xFF;
|
||||||
if(id_data == ID_NORMAL)
|
if(id_data == ID_NORMAL && sub_protocol != FORMAT_H501)
|
||||||
{
|
{
|
||||||
packet[6] = 0x08;
|
packet[6] = 0x08;
|
||||||
packet[7] = 0xe4;
|
packet[7] = 0xe4;
|
||||||
@ -89,7 +116,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state)
|
|||||||
packet[13] = 0x26;
|
packet[13] = 0x26;
|
||||||
packet[14] = 0x79;
|
packet[14] = 0x79;
|
||||||
}
|
}
|
||||||
else
|
else if(id_data == ID_PLUS || sub_protocol == FORMAT_H501)
|
||||||
{ //ID_PLUS
|
{ //ID_PLUS
|
||||||
if(phase >= BIND_3)
|
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 void __attribute__((unused)) hubsan_build_packet()
|
||||||
{
|
{
|
||||||
static uint8_t vtx_freq = 0;
|
static uint8_t vtx_freq = 0;
|
||||||
|
static uint32_t h501_packet = 0;
|
||||||
memset(packet, 0, 16);
|
memset(packet, 0, 16);
|
||||||
if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D)
|
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[4] = 0xFF - convert_channel_8b(RUDDER); //Rudder is reversed
|
||||||
packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed
|
packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed
|
||||||
packet[8] = convert_channel_8b(AILERON); //Aileron
|
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)
|
if( packet_count < 100)
|
||||||
{
|
{
|
||||||
@ -151,21 +179,50 @@ static void __attribute__((unused)) hubsan_build_packet()
|
|||||||
packet[13] = 0x26;
|
packet[13] = 0x26;
|
||||||
packet[14] = 0x79;
|
packet[14] = 0x79;
|
||||||
}
|
}
|
||||||
else
|
else if( sub_protocol == FORMAT_H301) {
|
||||||
{ //ID_PLUS
|
if(packet_count < 100) {
|
||||||
packet[3] = 0x64;
|
packet[9] = FLAG_H301_STAB;
|
||||||
packet[5] = 0x64;
|
packet_count++;
|
||||||
packet[7] = 0x64;
|
} 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;
|
packet[9] = 0x06;
|
||||||
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
|
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
|
||||||
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
|
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
|
||||||
packet[10]= 0x19;
|
packet[10]= sub_protocol == FORMAT_H501 ? 0x1a : 0x19;
|
||||||
packet[12]= 0x5C; // ghost channel ?
|
packet[12]= 0x5C; // ghost channel ?
|
||||||
packet[13] = 0;
|
packet[13] = 0;
|
||||||
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
|
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
|
||||||
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
|
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
|
||||||
packet[14]= 0x49; // ghost channel ?
|
packet[14]= 0x49; // ghost channel ?
|
||||||
|
}
|
||||||
if(packet_count < 100)
|
if(packet_count < 100)
|
||||||
{ // set channels to neutral for first 100 packets
|
{ // set channels to neutral for first 100 packets
|
||||||
packet[2] = 0x80; // throttle neutral is at mid stick on plus series
|
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[13]= 0x00;
|
||||||
packet_count++;
|
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();
|
hubsan_update_crc();
|
||||||
}
|
}
|
||||||
@ -205,7 +274,7 @@ uint16_t ReadHubsan()
|
|||||||
switch(phase) {
|
switch(phase) {
|
||||||
case BIND_1:
|
case BIND_1:
|
||||||
bind_count++;
|
bind_count++;
|
||||||
if(bind_count >= 20)
|
if(bind_count >= 20 && sub_protocol != FORMAT_H501)
|
||||||
{
|
{
|
||||||
if(id_data == ID_NORMAL)
|
if(id_data == ID_NORMAL)
|
||||||
id_data = ID_PLUS;
|
id_data = ID_PLUS;
|
||||||
@ -287,7 +356,15 @@ uint16_t ReadHubsan()
|
|||||||
A7105_SetPower(); //Keep transmit power in sync
|
A7105_SetPower(); //Keep transmit power in sync
|
||||||
hubsan_build_packet();
|
hubsan_build_packet();
|
||||||
A7105_Strobe(A7105_STANDBY);
|
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)
|
if (phase == DATA_5)
|
||||||
phase = DATA_1;
|
phase = DATA_1;
|
||||||
else
|
else
|
||||||
|
@ -246,11 +246,7 @@ static void __attribute__((unused)) kn_init()
|
|||||||
|
|
||||||
NRF24L01_Initialize();
|
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));
|
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_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
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_Activate(0x73);
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||||
// Enable: Dynamic Payload Length to enable PCF
|
// 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));
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL));
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
|
||||||
NRF24L01_SetPower();
|
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
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
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
|
// 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
|
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
|
||||||
|
|
||||||
#if defined(MJXQ_NRF24L01_INO)
|
#if defined(MJXQ_NRF24L01_INO)
|
||||||
@ -30,8 +26,6 @@
|
|||||||
#define MJXQ_RF_NUM_CHANNELS 4
|
#define MJXQ_RF_NUM_CHANNELS 4
|
||||||
#define MJXQ_ADDRESS_LENGTH 5
|
#define MJXQ_ADDRESS_LENGTH 5
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
// haven't figured out txid<-->rf channel mapping for MJX models
|
||||||
const uint8_t PROGMEM MJXQ_map_rfchan[][4] = {
|
const uint8_t PROGMEM MJXQ_map_rfchan[][4] = {
|
||||||
{0x0A, 0x46, 0x3A, 0x42},
|
{0x0A, 0x46, 0x3A, 0x42},
|
||||||
@ -43,7 +37,6 @@ const uint8_t PROGMEM MJXQ_map_txid[][3] = {
|
|||||||
{0x48, 0x6A, 0x40} };
|
{0x48, 0x6A, 0x40} };
|
||||||
|
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
||||||
#define MJXQ_PAN_DOWN 0x08
|
#define MJXQ_PAN_DOWN 0x08
|
||||||
#define MJXQ_PAN_UP 0x04
|
#define MJXQ_PAN_UP 0x04
|
||||||
@ -57,16 +50,6 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
|||||||
packet_count++;
|
packet_count++;
|
||||||
if(packet_count & MJXQ_PAN_TILT_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)
|
if(Servo_data[AUX8]>PPM_MAX_COMMAND)
|
||||||
pan=MJXQ_PAN_UP;
|
pan=MJXQ_PAN_UP;
|
||||||
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
||||||
@ -75,7 +58,6 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
|||||||
pan+=MJXQ_TILT_UP;
|
pan+=MJXQ_TILT_UP;
|
||||||
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
||||||
pan+=MJXQ_TILT_DOWN;
|
pan+=MJXQ_TILT_DOWN;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
return pan;
|
return pan;
|
||||||
}
|
}
|
||||||
@ -86,17 +68,10 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
packet[0] = convert_channel_8b(THROTTLE);
|
packet[0] = convert_channel_8b(THROTTLE);
|
||||||
packet[1] = convert_channel_s8b(RUDDER);
|
packet[1] = convert_channel_s8b(RUDDER);
|
||||||
packet[4] = 0x40; // rudder does not work well with dyntrim
|
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[2] = 0x80 ^ convert_channel_s8b(ELEVATOR);
|
||||||
packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||||
packet[3] = convert_channel_s8b(AILERON);
|
packet[3] = convert_channel_s8b(AILERON);
|
||||||
packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim 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[7] = rx_tx_addr[0];
|
||||||
packet[8] = rx_tx_addr[1];
|
packet[8] = rx_tx_addr[1];
|
||||||
packet[9] = rx_tx_addr[2];
|
packet[9] = rx_tx_addr[2];
|
||||||
@ -121,10 +96,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
packet[10]=MJXQ_pan_tilt_value();
|
packet[10]=MJXQ_pan_tilt_value();
|
||||||
// fall through on purpose - no break
|
// fall through on purpose - no break
|
||||||
case WLH08:
|
case WLH08:
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
case E010:
|
case E010:
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
||||||
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
||||||
if (!bind)
|
if (!bind)
|
||||||
@ -137,14 +109,6 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case X600:
|
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[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED
|
||||||
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
|
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
|
||||||
if (!bind)
|
if (!bind)
|
||||||
@ -178,11 +142,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
if (sub_protocol == H26D)
|
if (sub_protocol == H26D)
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
else
|
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));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
||||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||||
@ -205,20 +165,12 @@ static void __attribute__((unused)) MJXQ_init()
|
|||||||
if (sub_protocol == WLH08)
|
if (sub_protocol == WLH08)
|
||||||
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
<<<<<<< HEAD
|
|
||||||
if (sub_protocol == H26D)
|
|
||||||
=======
|
|
||||||
if (sub_protocol == H26D || sub_protocol == E010)
|
if (sub_protocol == H26D || sub_protocol == E010)
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
|
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);
|
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_ADDRESS_LENGTH);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,53 +189,25 @@ static void __attribute__((unused)) MJXQ_init()
|
|||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
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)
|
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)
|
if (sub_protocol == E010)
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K
|
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K
|
||||||
else
|
else
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) MJXQ_init2()
|
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)
|
if (sub_protocol == H26D)
|
||||||
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
if (sub_protocol != WLH08 && sub_protocol != E010)
|
if (sub_protocol != WLH08 && sub_protocol != E010)
|
||||||
for(uint8_t i=0;i<MJXQ_RF_NUM_CHANNELS;i++)
|
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] );
|
hopping_frequency[i]=pgm_read_byte_near( &MJXQ_map_rfchan[rx_tx_addr[4]%3][i] );
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) MJXQ_initialize_txid()
|
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;
|
rx_tx_addr[0]&=0xF8;
|
||||||
if (sub_protocol == E010)
|
if (sub_protocol == E010)
|
||||||
{
|
{
|
||||||
@ -293,7 +217,6 @@ static void __attribute__((unused)) MJXQ_initialize_txid()
|
|||||||
else
|
else
|
||||||
for(uint8_t i=0;i<3;i++)
|
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] );
|
rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[4]%3][i] );
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MJXQ_callback()
|
uint16_t MJXQ_callback()
|
||||||
|
@ -12,11 +12,7 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
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
|
// 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
|
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
|
||||||
|
|
||||||
#if defined(MT99XX_NRF24L01_INO)
|
#if defined(MT99XX_NRF24L01_INO)
|
||||||
@ -41,8 +37,6 @@ enum{
|
|||||||
FLAG_MT_FLIP = 0x80,
|
FLAG_MT_FLIP = 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
enum{
|
enum{
|
||||||
// flags going to packet[6] (LS)
|
// flags going to packet[6] (LS)
|
||||||
FLAG_LS_INVERT = 0x01,
|
FLAG_LS_INVERT = 0x01,
|
||||||
@ -53,43 +47,12 @@ enum{
|
|||||||
FLAG_LS_FLIP = 0x80,
|
FLAG_LS_FLIP = 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
enum {
|
enum {
|
||||||
MT99XX_INIT = 0,
|
MT99XX_INIT = 0,
|
||||||
MT99XX_BIND,
|
MT99XX_BIND,
|
||||||
MT99XX_DATA
|
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[] = {
|
const uint8_t h7_mys_byte[] = {
|
||||||
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
||||||
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
||||||
@ -138,7 +101,6 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
ls_counter=0;
|
ls_counter=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
uint8_t result=checksum_offset;
|
uint8_t result=checksum_offset;
|
||||||
for(uint8_t i=0; i<8; i++)
|
for(uint8_t i=0; i<8; i++)
|
||||||
result += packet[i];
|
result += packet[i];
|
||||||
@ -147,15 +109,9 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
else
|
else
|
||||||
{ // YZ
|
{ // YZ
|
||||||
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
|
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[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder
|
||||||
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
||||||
packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron
|
packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
if(packet_count++ >= 23)
|
if(packet_count++ >= 23)
|
||||||
{
|
{
|
||||||
yz_seq_num ++;
|
yz_seq_num ++;
|
||||||
@ -176,14 +132,10 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
packet[8] = 0xff;
|
packet[8] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
|
||||||
=======
|
|
||||||
if(sub_protocol == LS)
|
if(sub_protocol == LS)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||||
else
|
else
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
||||||
@ -201,16 +153,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
static void __attribute__((unused)) MT99XX_init()
|
static void __attribute__((unused)) MT99XX_init()
|
||||||
{
|
{
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
<<<<<<< HEAD
|
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
|
||||||
NRF24L01_FlushTx();
|
|
||||||
=======
|
|
||||||
if(sub_protocol == YZ)
|
if(sub_protocol == YZ)
|
||||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
|
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_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_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
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) );
|
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()
|
static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
rx_tx_addr[3] = 0xCC;
|
rx_tx_addr[3] = 0xCC;
|
||||||
rx_tx_addr[4] = 0xCC;
|
rx_tx_addr[4] = 0xCC;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
if(sub_protocol == YZ)
|
if(sub_protocol == YZ)
|
||||||
{
|
{
|
||||||
rx_tx_addr[0] = 0x53; // test (SB id)
|
rx_tx_addr[0] = 0x53; // test (SB id)
|
||||||
rx_tx_addr[1] = 0x00;
|
rx_tx_addr[1] = 0x00;
|
||||||
<<<<<<< HEAD
|
|
||||||
}
|
|
||||||
checksum_offset = (rx_tx_addr[0] + rx_tx_addr[1]) & 0xff;
|
|
||||||
=======
|
|
||||||
rx_tx_addr[2] = 0x00;
|
rx_tx_addr[2] = 0x00;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -255,7 +189,6 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
|||||||
else //MT99 & H7
|
else //MT99 & H7
|
||||||
rx_tx_addr[2] = 0x00;
|
rx_tx_addr[2] = 0x00;
|
||||||
checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
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;
|
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,26 +200,16 @@ uint16_t MT99XX_callback()
|
|||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
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
|
// set tx address for data packets
|
||||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
|
||||||
=======
|
|
||||||
if(sub_protocol == LS)
|
if(sub_protocol == LS)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||||
else
|
else
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet
|
XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet
|
||||||
@ -313,25 +236,6 @@ uint16_t initMT99XX(void)
|
|||||||
MT99XX_init();
|
MT99XX_init();
|
||||||
|
|
||||||
packet[0] = 0x20;
|
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;
|
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||||
switch(sub_protocol)
|
switch(sub_protocol)
|
||||||
{ // MT99 & H7
|
{ // MT99 & H7
|
||||||
@ -356,7 +260,6 @@ uint16_t initMT99XX(void)
|
|||||||
packet[4] = rx_tx_addr[0];
|
packet[4] = rx_tx_addr[0];
|
||||||
packet[5] = rx_tx_addr[1];
|
packet[5] = rx_tx_addr[1];
|
||||||
packet[6] = rx_tx_addr[2];
|
packet[6] = rx_tx_addr[2];
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
packet[7] = checksum_offset; // checksum offset
|
packet[7] = checksum_offset; // checksum offset
|
||||||
packet[8] = 0xAA; // fixed
|
packet[8] = 0xAA; // fixed
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
|
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
@ -94,6 +94,14 @@ static void NRF24L01_ReadPayload(uint8_t * data, uint8_t length)
|
|||||||
data[i] = SPI_Read();
|
data[i] = SPI_Read();
|
||||||
NRF_CSN_on;
|
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)
|
static void NRF24L01_Strobe(uint8_t state)
|
||||||
{
|
{
|
||||||
@ -234,11 +242,7 @@ uint8_t NRF24L01_packet_ack()
|
|||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// XN297 emulation layer
|
// XN297 emulation layer
|
||||||
<<<<<<< HEAD
|
|
||||||
uint8_t xn297_scramble_enabled;
|
|
||||||
=======
|
|
||||||
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
uint8_t xn297_addr_len;
|
uint8_t xn297_addr_len;
|
||||||
uint8_t xn297_tx_addr[5];
|
uint8_t xn297_tx_addr[5];
|
||||||
uint8_t xn297_rx_addr[5];
|
uint8_t xn297_rx_addr[5];
|
||||||
@ -251,16 +255,6 @@ static const uint8_t xn297_scramble[] = {
|
|||||||
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
||||||
0x8e, 0xc5, 0x2f};
|
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[] = {
|
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
||||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||||
@ -334,14 +328,8 @@ void XN297_SetRXAddr(const uint8_t* addr, uint8_t len)
|
|||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5);
|
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));
|
xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC));
|
||||||
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
||||||
@ -350,7 +338,6 @@ void XN297_Configure(uint16_t flags)
|
|||||||
void XN297_SetScrambledMode(const u8 mode)
|
void XN297_SetScrambledMode(const u8 mode)
|
||||||
{
|
{
|
||||||
xn297_scramble_enabled = mode;
|
xn297_scramble_enabled = mode;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||||
@ -412,32 +399,6 @@ void XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
// End of XN297 emulation
|
// 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
|
// LT8900 emulation layer
|
||||||
uint8_t LT8900_buffer[64];
|
uint8_t LT8900_buffer[64];
|
||||||
uint8_t LT8900_buffer_start;
|
uint8_t LT8900_buffer_start;
|
||||||
@ -462,37 +423,23 @@ void LT8900_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uin
|
|||||||
LT8900_Preamble_Len=preamble_len;
|
LT8900_Preamble_Len=preamble_len;
|
||||||
//Trailer 4 to 18 bits
|
//Trailer 4 to 18 bits
|
||||||
LT8900_Tailer_Len=trailer_len;
|
LT8900_Tailer_Len=trailer_len;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
//Flags
|
//Flags
|
||||||
// CRC_ON: 1 on, 0 off
|
// CRC_ON: 1 on, 0 off
|
||||||
// SCRAMBLE_ON: 1 on, 0 off
|
// SCRAMBLE_ON: 1 on, 0 off
|
||||||
// PACKET_LENGTH_EN: 1 1st byte of payload is payload size
|
// 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
|
// 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
|
// 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;
|
LT8900_Flags=flags;
|
||||||
//CRC init constant
|
//CRC init constant
|
||||||
LT8900_CRC_Initial_Data=crc_init;
|
LT8900_CRC_Initial_Data=crc_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LT8900_SetChannel(uint8_t channel)
|
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
|
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)
|
void LT8900_SetTxRxMode(enum TXRX_State mode)
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
if(mode == TX_EN)
|
if(mode == TX_EN)
|
||||||
{
|
{
|
||||||
@ -518,35 +465,12 @@ void LT8900_SetTxRxMode(enum TXRX_State mode)
|
|||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
void LT8910_BuildOverhead()
|
|
||||||
=======
|
|
||||||
void LT8900_BuildOverhead()
|
void LT8900_BuildOverhead()
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
uint8_t pos;
|
uint8_t pos;
|
||||||
|
|
||||||
//Build overhead
|
//Build overhead
|
||||||
//preamble
|
//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);
|
memset(LT8900_buffer,LT8900_addr[0]&0x01?0xAA:0x55,LT8900_Preamble_Len-1);
|
||||||
pos=LT8900_Preamble_Len-1;
|
pos=LT8900_Preamble_Len-1;
|
||||||
//address
|
//address
|
||||||
@ -564,33 +488,10 @@ void LT8910_SetAddress(uint8_t *address,uint8_t addr_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LT8900_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];
|
uint8_t addr[5];
|
||||||
|
|
||||||
//Address size (SyncWord) 2 to 8 bytes, 16/32/48/64 bits
|
//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;
|
LT8900_addr_size=addr_size;
|
||||||
for (uint8_t i = 0; i < addr_size; i++)
|
for (uint8_t i = 0; i < addr_size; i++)
|
||||||
LT8900_addr[i] = address[addr_size-1-i];
|
LT8900_addr[i] = address[addr_size-1-i];
|
||||||
@ -612,22 +513,14 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
unsigned int crc=LT8900_CRC_Initial_Data,a;
|
unsigned int crc=LT8900_CRC_Initial_Data,a;
|
||||||
pos=LT8900_buffer_overhead_bits/8-LT8900_buffer_start;
|
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);
|
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
|
//Read payload
|
||||||
NRF24L01_ReadPayload(buffer,end+1);
|
NRF24L01_ReadPayload(buffer,end+1);
|
||||||
//Check address + trail
|
//Check address + trail
|
||||||
for(i=0;i<pos;i++)
|
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])
|
if(LT8900_buffer[LT8900_buffer_start+i]!=buffer[i])
|
||||||
return 0; // wrong address...
|
return 0; // wrong address...
|
||||||
//Shift buffer to remove trail bits
|
//Shift buffer to remove trail bits
|
||||||
shift=LT8900_buffer_overhead_bits&0x7;
|
shift=LT8900_buffer_overhead_bits&0x7;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
for(i=pos;i<end;i++)
|
for(i=pos;i<end;i++)
|
||||||
{
|
{
|
||||||
a=(buffer[i]<<8)+buffer[i+1];
|
a=(buffer[i]<<8)+buffer[i+1];
|
||||||
@ -635,11 +528,7 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
buffer[i]=(a>>8)&0xFF;
|
buffer[i]=(a>>8)&0xFF;
|
||||||
}
|
}
|
||||||
//Check len
|
//Check len
|
||||||
<<<<<<< HEAD
|
|
||||||
if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN))
|
|
||||||
=======
|
|
||||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
crc=crc16_update(crc,buffer[pos]);
|
crc=crc16_update(crc,buffer[pos]);
|
||||||
if(bit_reverse(len)!=buffer[pos++])
|
if(bit_reverse(len)!=buffer[pos++])
|
||||||
@ -652,11 +541,7 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
msg[i]=bit_reverse(buffer[pos++]);
|
msg[i]=bit_reverse(buffer[pos++]);
|
||||||
}
|
}
|
||||||
//Check CRC
|
//Check CRC
|
||||||
<<<<<<< HEAD
|
|
||||||
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
|
||||||
=======
|
|
||||||
if(LT8900_Flags&_BV(LT8900_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>>8)&0xFF)) return 0; // wrong CRC...
|
||||||
if(buffer[pos]!=(crc&0xFF)) return 0; // wrong CRC...
|
if(buffer[pos]!=(crc&0xFF)) return 0; // wrong CRC...
|
||||||
@ -665,21 +550,12 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
return 1;
|
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)
|
void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||||
{
|
{
|
||||||
unsigned int crc=LT8900_CRC_Initial_Data,a,mask;
|
unsigned int crc=LT8900_CRC_Initial_Data,a,mask;
|
||||||
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
||||||
//Add packet len
|
//Add packet len
|
||||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
tmp=bit_reverse(len);
|
tmp=bit_reverse(len);
|
||||||
buffer[pos++]=tmp;
|
buffer[pos++]=tmp;
|
||||||
@ -693,27 +569,12 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
|||||||
crc=crc16_update(crc,tmp);
|
crc=crc16_update(crc,tmp);
|
||||||
}
|
}
|
||||||
//Add CRC
|
//Add CRC
|
||||||
<<<<<<< HEAD
|
|
||||||
if(LT8910_Flags&_BV(LT8910_CRC_ON))
|
|
||||||
=======
|
|
||||||
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
{
|
{
|
||||||
buffer[pos++]=crc>>8;
|
buffer[pos++]=crc>>8;
|
||||||
buffer[pos++]=crc;
|
buffer[pos++]=crc;
|
||||||
}
|
}
|
||||||
//Shift everything to fit behind the trailer (4 to 18 bits)
|
//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;
|
shift=LT8900_buffer_overhead_bits&0x7;
|
||||||
pos_final=LT8900_buffer_overhead_bits/8;
|
pos_final=LT8900_buffer_overhead_bits/8;
|
||||||
mask=~(0xFF<<(8-shift));
|
mask=~(0xFF<<(8-shift));
|
||||||
@ -723,17 +584,10 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
|||||||
a=buffer[i]<<(8-shift);
|
a=buffer[i]<<(8-shift);
|
||||||
LT8900_buffer[pos_final+i]=(LT8900_buffer[pos_final+i]&mask>>8)|a>>8;
|
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;
|
LT8900_buffer[pos_final+i+1]=(LT8900_buffer[pos_final+i+1]&mask)|a;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
if(shift)
|
if(shift)
|
||||||
pos++;
|
pos++;
|
||||||
//Send everything
|
//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);
|
NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start);
|
||||||
}
|
}
|
||||||
// End of LT8900 emulation
|
// End of LT8900 emulation
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
@ -51,7 +51,7 @@ static void bluefly_init() {
|
|||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81
|
||||||
|
|
||||||
// 2-bytes CRC, radio on
|
// 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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // BlueFly - 250kbps
|
NRF24L01_SetBitrate(NRF24L01_BR_250K); // BlueFly - 250kbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
@ -63,7 +63,7 @@ static void bluefly_ch_data() {
|
|||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i< 8; ++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)
|
if (temp < 0)
|
||||||
ch_data_bluefly[i] = 0;
|
ch_data_bluefly[i] = 0;
|
||||||
else if (temp > 1000)
|
else if (temp > 1000)
|
||||||
@ -140,6 +140,7 @@ static uint16_t bluefly_cb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t BlueFly_setup() {
|
static uint16_t BlueFly_setup() {
|
||||||
|
MProtocol_id = (MProtocol_id | ((uint32_t)txid[3]<<32));
|
||||||
hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2;
|
hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2;
|
||||||
bluefly_binding_packet();
|
bluefly_binding_packet();
|
||||||
bluefly_init();
|
bluefly_init();
|
||||||
|
@ -13,12 +13,6 @@
|
|||||||
along with Deviation. If not, see <http://www.gnu.org/licenses/>.
|
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)
|
#if defined(CFlie_NRF24L01_INO)
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
@ -59,30 +53,15 @@ enum {
|
|||||||
CFLIE_DATA
|
CFLIE_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CFLIE_TELEMETRY
|
#define PACKET_CFLIE_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out
|
||||||
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
|
|
||||||
|
|
||||||
static uint16_t dbg_cnt = 0;
|
static uint16_t dbg_cnt = 0;
|
||||||
static uint8_t packet_ack() {
|
static uint8_t packet_ack() {
|
||||||
if (++dbg_cnt > 50) { dbg_cnt = 0; }
|
if (++dbg_cnt > 50) { dbg_cnt = 0; }
|
||||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) {
|
||||||
case BV(NRF24L01_07_TX_DS):
|
case _BV(NRF24L01_07_TX_DS):
|
||||||
return PKT_ACKED;
|
return PKT_ACKED;
|
||||||
case BV(NRF24L01_07_MAX_RT):
|
case _BV(NRF24L01_07_MAX_RT):
|
||||||
return PKT_TIMEOUT;
|
return PKT_TIMEOUT;
|
||||||
}
|
}
|
||||||
return PKT_PENDING;
|
return PKT_PENDING;
|
||||||
@ -97,7 +76,7 @@ static void send_search_packet() {
|
|||||||
uint8_t buf[1];
|
uint8_t buf[1];
|
||||||
buf[0] = 0xff;
|
buf[0] = 0xff;
|
||||||
// clear packet status bits and TX FIFO
|
// 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_FlushTx();
|
||||||
|
|
||||||
if (rf_channel++ > 125) {
|
if (rf_channel++ > 125) {
|
||||||
@ -119,7 +98,7 @@ static void send_search_packet() {
|
|||||||
|
|
||||||
NRF24L01_WritePayload(buf, sizeof(buf));
|
NRF24L01_WritePayload(buf, sizeof(buf));
|
||||||
|
|
||||||
++packet_counter;
|
++packet_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frac 16.16
|
// Frac 16.16
|
||||||
@ -151,33 +130,39 @@ static void send_cmd_packet() {
|
|||||||
// Channels in AETR order
|
// Channels in AETR order
|
||||||
|
|
||||||
// Roll, aka aileron, float +- 50.0 in degrees
|
// Roll, aka aileron, float +- 50.0 in degrees
|
||||||
// float roll = -(float) Servo_data[AILERON]*50.0/10000;
|
uint32_t f_roll = -map(limit_channel_100(AILERON),servo_min_100,servo_max_100,-50,50);
|
||||||
uint32_t f_roll = -Servo_data[AILERON] * FRAC_SCALE / (10000 / 50);
|
|
||||||
|
|
||||||
// Pitch, aka elevator, float +- 50.0 degrees
|
// Pitch, aka elevator, float +- 50.0 degrees
|
||||||
//float pitch = -(float) Servo_data[ELEVATOR]*50.0/10000;
|
uint32_t f_pitch = -map(limit_channel_100(ELEVATOR),servo_min_100,servo_max_100,-50,50);
|
||||||
uint32_t f_pitch = -Servo_data[ELEVATOR] * FRAC_SCALE / (10000 / 50);
|
|
||||||
|
|
||||||
// Thrust, aka throttle 0..65535, working range 5535..65535
|
// Thrust, aka throttle 0..65535, working range 5535..65535
|
||||||
// No space for overshoot here, hard limit Channel3 by -10000..10000
|
// No space for overshoot here, hard limit Channel3 by -10000..10000
|
||||||
uint32_t ch = Servo_data[THROTTLE];
|
uint32_t ch = Servo_data[THROTTLE];
|
||||||
if (ch < PPM_MIN) {
|
if (ch < servo_min_125) {
|
||||||
ch = PPM_MIN;
|
ch = servo_min_125;
|
||||||
} else if (ch > PPM_MAX) {
|
} else if (ch > servo_max_125) {
|
||||||
ch = PPM_MAX;
|
ch = servo_max_125;
|
||||||
}
|
}
|
||||||
uint16_t thrust = ch*3L + 35535L;
|
uint16_t thrust = ch*3L + 35535L;
|
||||||
|
|
||||||
// Yaw, aka rudder, float +- 400.0 deg/s
|
// Yaw, aka rudder, float +- 400.0 deg/s
|
||||||
// float yaw = -(float) Servo_data[RUDDER]*400.0/10000;
|
uint32_t f_yaw = - map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,-40,40);
|
||||||
uint32_t f_yaw = - Servo_data[RUDDER] * FRAC_SCALE / (10000 / 400);
|
|
||||||
frac2float(f_yaw, &yaw);
|
frac2float(f_yaw, &yaw);
|
||||||
|
|
||||||
|
// 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
|
// Convert + to X. 181 / 256 = 0.70703125 ~= sqrt(2) / 2
|
||||||
uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256;
|
uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256;
|
||||||
frac2float(f_x_roll, &x_roll);
|
frac2float(f_x_roll, &x_roll);
|
||||||
uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256;
|
uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256;
|
||||||
frac2float(f_x_pitch, &x_pitch);
|
frac2float(f_x_pitch, &x_pitch);
|
||||||
|
}
|
||||||
|
|
||||||
int bufptr = 0;
|
int bufptr = 0;
|
||||||
buf[bufptr++] = 0x30; // Commander packet to channel 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
|
// 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_FlushTx();
|
||||||
|
|
||||||
NRF24L01_WritePayload(buf, sizeof(buf));
|
NRF24L01_WritePayload(buf, sizeof(buf));
|
||||||
|
|
||||||
++packet_counter;
|
++packet_count;
|
||||||
|
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
}
|
}
|
||||||
@ -203,7 +188,7 @@ static int cflie_init() {
|
|||||||
|
|
||||||
// CRC, radio on
|
// CRC, radio on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
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, 0x00); // No Auto Acknowledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||||
@ -236,21 +221,6 @@ static int cflie_init() {
|
|||||||
return 50000;
|
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() {
|
static uint16_t cflie_callback() {
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case CFLIE_INIT_SEARCH:
|
case CFLIE_INIT_SEARCH:
|
||||||
@ -264,7 +234,7 @@ static uint16_t cflie_callback() {
|
|||||||
case CFLIE_SEARCH:
|
case CFLIE_SEARCH:
|
||||||
switch (packet_ack()) {
|
switch (packet_ack()) {
|
||||||
case PKT_PENDING:
|
case PKT_PENDING:
|
||||||
return PACKET_CHKTIME; // packet send not yet complete
|
return PACKET_CFLIE_CHKTIME; // packet send not yet complete
|
||||||
case PKT_ACKED:
|
case PKT_ACKED:
|
||||||
phase = CFLIE_DATA;
|
phase = CFLIE_DATA;
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
@ -275,11 +245,8 @@ static uint16_t cflie_callback() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CFLIE_DATA:
|
case CFLIE_DATA:
|
||||||
#ifdef CFLIE_TELEMETRY
|
|
||||||
update_telemetry();
|
|
||||||
#endif
|
|
||||||
if (packet_ack() == PKT_PENDING)
|
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();
|
send_cmd_packet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -287,8 +254,7 @@ static uint16_t cflie_callback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
static uint16_t Cflie_setup() {
|
||||||
static uint8_t initialize_rx_tx_addr() {
|
|
||||||
rx_tx_addr[0] =
|
rx_tx_addr[0] =
|
||||||
rx_tx_addr[1] =
|
rx_tx_addr[1] =
|
||||||
rx_tx_addr[2] =
|
rx_tx_addr[2] =
|
||||||
@ -297,21 +263,12 @@ static uint8_t initialize_rx_tx_addr() {
|
|||||||
|
|
||||||
data_rate = NRF24L01_BR_250K;
|
data_rate = NRF24L01_BR_250K;
|
||||||
rf_channel = 0;
|
rf_channel = 0;
|
||||||
return CFLIE_INIT_SEARCH;
|
packet_count = 0;
|
||||||
// return CFLIE_INIT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t Cflie_setup() {
|
|
||||||
phase = initialize_rx_tx_addr();
|
|
||||||
packet_counter = 0;
|
|
||||||
|
|
||||||
int delay = cflie_init();
|
int delay = cflie_init();
|
||||||
|
|
||||||
#ifdef CFLIE_TELEMETRY
|
phase = CFLIE_INIT_SEARCH;
|
||||||
memset(&Telemetry, 0, sizeof(Telemetry));
|
BIND_IN_PROGRESS;
|
||||||
TELEMETRY_SetType(TELEM_DSM);
|
|
||||||
#endif
|
|
||||||
if (phase == CFLIE_INIT_SEARCH) { BIND_IN_PROGRESS; }
|
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,15 +32,15 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
static uint8_t esky150_packet_ack() {
|
static uint8_t esky150_packet_ack() {
|
||||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
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_TX_DS): return PKT_ACKED;
|
||||||
case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||||
}
|
}
|
||||||
return PKT_PENDING;
|
return PKT_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-bytes CRC
|
// 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() {
|
static uint16_t esky150_init() {
|
||||||
uint8_t rx_addr[ADDR_esky150_SIZE] = { 0x73, 0x73, 0x74, 0x63 };
|
uint8_t rx_addr[ADDR_esky150_SIZE] = { 0x73, 0x73, 0x74, 0x63 };
|
||||||
uint8_t tx_addr[ADDR_esky150_SIZE] = { 0x71, 0x0A, 0x31, 0xF4 };
|
uint8_t tx_addr[ADDR_esky150_SIZE] = { 0x71, 0x0A, 0x31, 0xF4 };
|
||||||
@ -64,7 +64,7 @@ static uint16_t esky150_init() {
|
|||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||||
// Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK
|
// 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
|
// Delay 50 ms
|
||||||
return 50000;
|
return 50000;
|
||||||
@ -80,51 +80,26 @@ static uint16_t esky150_init2() {
|
|||||||
|
|
||||||
// Turn radio power on
|
// Turn radio power on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
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);
|
// delayMicroseconds(150);
|
||||||
return 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() {
|
static void esky150_send_packet() {
|
||||||
uint8_t rf_ch = hopping_frequency[rf_ch_num];
|
uint8_t rf_ch = hopping_frequency[rf_ch_num];
|
||||||
rf_ch_num = 1 - rf_ch_num;
|
rf_ch_num = 1 - rf_ch_num;
|
||||||
|
|
||||||
read_controls(&throttle, &aileron, &elevator, &rudder);
|
|
||||||
|
|
||||||
packet[0] = hopping_frequency[0];
|
packet[0] = hopping_frequency[0];
|
||||||
packet[1] = hopping_frequency[1];
|
packet[1] = hopping_frequency[1];
|
||||||
packet[2] = (throttle >> 8) & 0xFF;
|
packet[2] = highByte(Servo_data[THROTTLE]);
|
||||||
packet[3] = throttle & 0xFF;
|
packet[3] = lowByte(Servo_data[THROTTLE]);
|
||||||
packet[4] = (aileron >> 8) & 0xFF;
|
packet[4] = highByte(Servo_data[AILERON]);
|
||||||
packet[5] = aileron & 0xFF;
|
packet[5] = lowByte(Servo_data[AILERON]);
|
||||||
packet[6] = (elevator >> 8) & 0xFF;
|
packet[6] = highByte(Servo_data[ELEVATOR]);
|
||||||
packet[7] = elevator & 0xFF;
|
packet[7] = lowByte(Servo_data[ELEVATOR]);
|
||||||
packet[8] = (rudder >> 8) & 0xFF;
|
packet[8] = highByte(Servo_data[RUDDER]);
|
||||||
packet[9] = rudder & 0xFF;
|
packet[9] = lowByte(Servo_data[RUDDER]);
|
||||||
// Constant values 00 d8 18 f8
|
// Constant values 00 d8 18 f8
|
||||||
packet[10] = 0x00;
|
packet[10] = 0x00;
|
||||||
packet[11] = 0xd8;
|
packet[11] = 0xd8;
|
||||||
@ -167,6 +142,12 @@ static uint16_t esky150_setup() {
|
|||||||
total_packets = 0;
|
total_packets = 0;
|
||||||
uint16_t timeout = esky150_init();
|
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;
|
return timeout;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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_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
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // fbl100/v922's packet size = 10, hp100 = 12
|
||||||
// 2-bytes CRC, radio off
|
// 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_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_SetBitrate(sub_protocol == HP100? NRF24L01_BR_250K:NRF24L01_BR_1M); //hp100:250kbps; fbl100: 1Mbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
@ -108,7 +108,7 @@ static void fbl100_build_ch_data() {
|
|||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i< 8; 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 (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; }
|
if (temp < 0) { fbl_data[i] = 0; }
|
||||||
else if (temp > 1000) { fbl_data[i] = 1000; }
|
else if (temp > 1000) { fbl_data[i] = 1000; }
|
||||||
@ -131,11 +131,12 @@ static void hp100_build_ch_data() {
|
|||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i< 8; 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; }
|
if (temp < 0) { temp = 0; }
|
||||||
else if (temp > 1000) { temp = 1000; }
|
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
|
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;
|
fbl_data[i] = (unsigned int)temp;
|
||||||
packet[i] = (uint8_t)fbl_data[i];
|
packet[i] = (uint8_t)fbl_data[i];
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ static void h377_init() {
|
|||||||
|
|
||||||
// 2-bytes CRC, radio off
|
// 2-bytes CRC, radio off
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||||
NRF24L01_SetBitrate(0); // 1Mbps
|
NRF24L01_SetBitrate(0); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
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
|
// H377 channel sequence: AILE ELEV THRO RUDD GEAR PITH, channel data value is from 0 to 1000
|
||||||
static void h377_ch_data() {
|
static void h377_ch_data() {
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
uint8_t i;
|
uint8_t i,j;
|
||||||
for (i = 0; i< 8; i++) {
|
for (i = 0; i< 8; i++) {
|
||||||
temp = (uint32_t)Servo_data[i] * 450/PPM_MAX + 500; // max/min servo range is +-125%
|
j=CH_AETR[i];
|
||||||
if (i == 2) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
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;
|
temp = 1000 -temp;
|
||||||
//if (i == 0) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
//if (i == 0) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose
|
||||||
// temp = 1000 -temp;
|
// temp = 1000 -temp;
|
||||||
|
@ -76,7 +76,7 @@ static uint8_t count;
|
|||||||
static uint8_t rf_ch[] = {0x08, 0x35, 0x12, 0x3f, 0x1c, 0x49, 0x26};
|
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 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;
|
int polynomial = 0x01;
|
||||||
for(int i = 0; i < len; i++) {
|
for(int i = 0; i < len; i++) {
|
||||||
result = result ^ data[i];
|
result = result ^ data[i];
|
||||||
@ -114,26 +114,26 @@ static void HM830_init() {
|
|||||||
|
|
||||||
static void build_bind_packet_hm830() {
|
static void build_bind_packet_hm830() {
|
||||||
for(int i = 0; i < 6; i++) { packet[i] = rx_tx_addr[i]; }
|
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() {
|
static void build_data_packet() {
|
||||||
uint8_t ail_sign = 0, trim_sign = 0;
|
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; }
|
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 < 0) { aileron = -aileron; ail_sign = 1; }
|
||||||
if (aileron > 7) { aileron = 7; }
|
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 < 0) { trim = -trim; trim_sign = 1; }
|
||||||
if (trim > 0x1f) { trim = 0x1f; }
|
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[0] = throttle;
|
||||||
packet[1] = aileron;
|
packet[1] = aileron;
|
||||||
if (ail_sign) { packet[1] |= 0x20; }
|
if (ail_sign) { packet[1] |= 0x20; }
|
||||||
@ -141,7 +141,7 @@ static void build_data_packet() {
|
|||||||
if (rbutton) { packet[1] |= 0x80; }
|
if (rbutton) { packet[1] |= 0x80; }
|
||||||
packet[5] = trim;
|
packet[5] = trim;
|
||||||
if (trim_sign) { packet[5] |= 0x20;}
|
if (trim_sign) { packet[5] |= 0x20;}
|
||||||
packet[6] = crc8(0xa5, packet, 6);
|
packet[6] = HM830_crc8(0xa5, packet, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_packet_hm830() {
|
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 BIND_COUNT 345 // 1.5 seconds
|
||||||
|
#define FIRST_PACKET_DELAY 12000
|
||||||
|
|
||||||
|
#define PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||||
|
#define 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 {
|
||||||
|
RATE_LOW = 0,
|
||||||
|
RATE_MID = 1,
|
||||||
|
RATE_HIGH = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FLAG_FLIP = 0x01,
|
||||||
|
FLAG_PICTURE = 0x02,
|
||||||
|
FLAG_VIDEO = 0x04,
|
||||||
|
FLAG_RTH = 0x08,
|
||||||
|
FLAG_HEADLESS = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PHASE_INAV_INIT = 0,
|
||||||
|
PHASE_INAV_BIND,
|
||||||
|
PHASE_INAV_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DATA_PACKET = 0,
|
||||||
|
BIND_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 = RATE_LOW;
|
||||||
|
if (Channels[CHANNEL_RATE] > 0) {
|
||||||
|
rate = RATE_HIGH;
|
||||||
|
} else if (Channels[CHANNEL_RATE] == 0) {
|
||||||
|
rate = RATE_MID;
|
||||||
|
}
|
||||||
|
packet[7] = rate; // rate, deviation channel 5, is mapped to AUX1
|
||||||
|
|
||||||
|
const uint8_t flags = GET_FLAG(CHANNEL_FLIP, FLAG_FLIP)
|
||||||
|
| GET_FLAG(CHANNEL_PICTURE, FLAG_PICTURE)
|
||||||
|
| GET_FLAG(CHANNEL_VIDEO, FLAG_VIDEO)
|
||||||
|
| GET_FLAG(CHANNEL_RTH, FLAG_RTH)
|
||||||
|
| GET_FLAG(CHANNEL_HEADLESS, 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_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 = BIND_COUNT;
|
||||||
|
bind_acked = 0;
|
||||||
|
return FIRST_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 PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
send_packet(BIND_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_PACKET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 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(BIND_COUNT * PACKET_PERIOD / 1000);
|
||||||
|
} else {
|
||||||
|
set_data_phase();
|
||||||
|
// BIND_DONE;
|
||||||
|
}
|
||||||
|
return 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
|
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++) {
|
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)
|
if (value > 0x7f)
|
||||||
value = 0x7f;
|
value = 0x7f;
|
||||||
else if(value < 0)
|
else if(value < 0)
|
||||||
@ -210,7 +210,7 @@ static void send_data_packet() {
|
|||||||
NRF24L01_WritePayload((uint8_t*) packet, PACKET_NE_LENGTH);
|
NRF24L01_WritePayload((uint8_t*) packet, PACKET_NE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bind_packet() {
|
static void send_ne_bind_packet() {
|
||||||
packet[0] = 0xAA; //throttle
|
packet[0] = 0xAA; //throttle
|
||||||
packet[1] = 0xAA; //rudder
|
packet[1] = 0xAA; //rudder
|
||||||
packet[2] = 0xAA; //elevator
|
packet[2] = 0xAA; //elevator
|
||||||
@ -243,7 +243,7 @@ static uint16_t ne260_cb() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
send_bind_packet();
|
send_ne_bind_packet();
|
||||||
state = NE260_BINDRX;
|
state = NE260_BINDRX;
|
||||||
return 500;
|
return 500;
|
||||||
} else if (state == NE260_BINDRX) {
|
} 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_DATA1) { neChannel = 10; state = NE260_DATA2; }
|
||||||
else if (state == NE260_DATA2) { neChannel = 30; state = NE260_DATA3; }
|
else if (state == NE260_DATA2) { neChannel = 30; state = NE260_DATA3; }
|
||||||
else if (state == NE260_DATA3) { neChannel = 50; state = NE260_DATA1; }
|
else if (state == NE260_DATA3) { neChannel = 50; state = NE260_DATA1; }
|
||||||
send_data_packet();
|
send_ne_data_packet();
|
||||||
return 2500;
|
return 2500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,9 +112,9 @@ static const uint8_t * rf_udi_channels = NULL;
|
|||||||
|
|
||||||
static uint8_t packet_udi_ack()
|
static uint8_t packet_udi_ack()
|
||||||
{
|
{
|
||||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) {
|
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_TX_DS): return PKT_ACKED;
|
||||||
case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT;
|
||||||
}
|
}
|
||||||
return PKT_PENDING;
|
return PKT_PENDING;
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ static void UDI_init2()
|
|||||||
|
|
||||||
// Turn radio power on
|
// Turn radio power on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
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);
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, config);
|
||||||
// Implicit delay in callback
|
// Implicit delay in callback
|
||||||
// delayMicroseconds(150);
|
// 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)
|
static uint8_t convert_channel(uint8_t num, uint8_t chn_max, uint8_t sign_ofs)
|
||||||
{
|
{
|
||||||
uint32_t ch = Servo_data[num];
|
uint32_t ch = map(limit_channel_100(num),servo_min_100,servo_max_100,-1000, 1000);
|
||||||
if (ch < PPM_MIN) {
|
|
||||||
ch = PPM_MIN;
|
|
||||||
} else if (ch > PPM_MAX) {
|
|
||||||
ch = PPM_MAX;
|
|
||||||
}
|
|
||||||
uint32_t chn_val;
|
uint32_t chn_val;
|
||||||
if (sign_ofs) chn_val = (((ch * chn_max / PPM_MAX) + sign_ofs) >> 1);
|
if (sign_ofs) chn_val = (((ch * chn_max / servo_max_100) + sign_ofs) >> 1);
|
||||||
else chn_val = (ch * chn_max / PPM_MAX);
|
else chn_val = (ch * chn_max / servo_max_100);
|
||||||
if (chn_val < 0) chn_val = 0;
|
if (chn_val < 0) chn_val = 0;
|
||||||
else if (chn_val > chn_max) chn_val = chn_max;
|
else if (chn_val > chn_max) chn_val = chn_max;
|
||||||
return (uint8_t) chn_val;
|
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
|
// Protocol is registered AETRG, that is
|
||||||
// Aileron is channel 0, Elevator - 1, Throttle - 2, Rudder - 3
|
// Aileron is channel 0, Elevator - 1, Throttle - 2, Rudder - 3
|
||||||
// Sometimes due to imperfect calibration or mixer settings
|
// Sometimes due to imperfect calibration or mixer settings
|
||||||
// throttle can be less than PPM_MIN or larger than
|
// throttle can be less than servo_min_100 or larger than
|
||||||
// PPM_MAX. As we have no space here, we hard-limit
|
// servo_max_100. As we have no space here, we hard-limit
|
||||||
// channels values by min..max range
|
// channels values by min..max range
|
||||||
|
|
||||||
// Channel 3: throttle is 0-100
|
// 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);
|
*aileron = convert_channel(AILERON, 0x3f, 0x20);
|
||||||
|
|
||||||
// Channel 5
|
// Channel 5
|
||||||
if (Servo_data[AUX1] <= 0) *flags &= ~UDI_FLIP360;
|
if (Servo_AUX1) *flags |= UDI_FLIP360;
|
||||||
else *flags |= UDI_FLIP360;
|
else *flags &= ~UDI_FLIP360;
|
||||||
|
|
||||||
// Channel 6
|
// Channel 6
|
||||||
if (Servo_data[AUX2] <= 0) *flags &= ~UDI_FLIP;
|
if (Servo_AUX2) *flags |= UDI_FLIP;
|
||||||
else *flags |= UDI_FLIP;
|
else *flags &= ~UDI_FLIP;
|
||||||
|
|
||||||
// Channel 7
|
// Channel 7
|
||||||
if (Servo_data[AUX3] <= 0) *flags &= ~UDI_CAMERA;
|
if (Servo_AUX3) *flags |= UDI_CAMERA;
|
||||||
else *flags |= UDI_CAMERA;
|
else *flags &= ~UDI_CAMERA;
|
||||||
|
|
||||||
// Channel 8
|
// Channel 8
|
||||||
if (Servo_data[AUX4] <= 0) *flags &= ~UDI_VIDEO;
|
if (Servo_AUX4) *flags |= UDI_VIDEO;
|
||||||
else *flags |= UDI_VIDEO;
|
else *flags &= ~UDI_VIDEO;
|
||||||
|
|
||||||
// Channel 9
|
// Channel 9
|
||||||
if (Servo_data[AUX5] <= 0) *flags &= ~UDI_LIGHTS;
|
if (Servo_AUX5) *flags |= UDI_LIGHTS;
|
||||||
else *flags |= UDI_LIGHTS;
|
else *flags &= ~UDI_LIGHTS;
|
||||||
|
|
||||||
// Channel 10
|
// Channel 10
|
||||||
if (Servo_data[AUX6] <= 0) *flags &= ~UDI_MODE2;
|
if (Servo_AUX6) *flags |= UDI_MODE2;
|
||||||
else *flags |= UDI_MODE2;
|
else *flags &= ~UDI_MODE2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_udi_packet(uint8_t bind)
|
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[5] = randoms[1];
|
||||||
packet[6] = randoms[2];
|
packet[6] = randoms[2];
|
||||||
if (sub_protocol == U839_2014) {
|
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) {
|
} else if (bind == 2) {
|
||||||
// Bind phase 2
|
// Bind phase 2
|
||||||
@ -374,7 +370,7 @@ static void send_udi_packet(uint8_t bind)
|
|||||||
uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS,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;
|
bind_step_success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +392,7 @@ static void send_udi_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_WritePayload(packet, payload_size);
|
NRF24L01_WritePayload(packet, payload_size);
|
||||||
++packet_counter;
|
++packet_count;
|
||||||
packet_sent = 1;
|
packet_sent = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +429,7 @@ static uint16_t UDI_callback() {
|
|||||||
break;
|
break;
|
||||||
case UDI_BIND1_RX:
|
case UDI_BIND1_RX:
|
||||||
// Check if data has been received
|
// 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];
|
uint8_t data[UDI_PAYLOADSIZE];
|
||||||
NRF24L01_ReadPayload(data, payload_size);
|
NRF24L01_ReadPayload(data, payload_size);
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E); // On original TX this is done on LAST packet check only !
|
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:
|
case UDI_BIND2_RX:
|
||||||
// Check if data has been received
|
// 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];
|
uint8_t data[UDI_PAYLOADSIZE];
|
||||||
NRF24L01_ReadPayload(data, payload_size);
|
NRF24L01_ReadPayload(data, payload_size);
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E);
|
||||||
@ -570,7 +566,7 @@ static uint16_t UDI_callback() {
|
|||||||
|
|
||||||
static uint16_t UDI_setup()
|
static uint16_t UDI_setup()
|
||||||
{
|
{
|
||||||
packet_counter = 0;
|
packet_count = 0;
|
||||||
UDI_init();
|
UDI_init();
|
||||||
phase = UDI_INIT2;
|
phase = UDI_INIT2;
|
||||||
|
|
||||||
|
230
Multiprotocol/README.md
Normal file
230
Multiprotocol/README.md
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
###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
|
||||||
|
|
||||||
|
###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
|
||||||
|
|
||||||
|
###NE260
|
||||||
|
Modele: Nine Eagles SoloPro
|
||||||
|
|
||||||
|
Autobind
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4
|
||||||
|
---|---|---|---
|
||||||
|
A|E|T|R
|
||||||
|
|
||||||
|
###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.
|
||||||
|
|
||||||
|
|
||||||
|
###D'autres à venir
|
@ -1,5 +1,3 @@
|
|||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
/*
|
/*
|
||||||
This project is free software: you can redistribute it and/or modify
|
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
|
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/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#if defined(SHENQI_NRF24L01_INO)
|
#if defined(SHENQI_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
@ -42,17 +39,10 @@ void SHENQI_init()
|
|||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address
|
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_Config(4, 8, _BV(LT8900_CRC_ON)|_BV(LT8900_PACKET_LENGTH_EN), 0xAA);
|
||||||
LT8900_SetChannel(2);
|
LT8900_SetChannel(2);
|
||||||
LT8900_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4);
|
LT8900_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4);
|
||||||
LT8900_SetTxRxMode(RX_EN);
|
LT8900_SetTxRxMode(RX_EN);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHENQI_send_packet()
|
void SHENQI_send_packet()
|
||||||
@ -61,16 +51,6 @@ void SHENQI_send_packet()
|
|||||||
if(packet_count==0)
|
if(packet_count==0)
|
||||||
{
|
{
|
||||||
uint8_t bind_addr[4];
|
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[0]=rx_tx_addr[0];
|
||||||
bind_addr[1]=rx_tx_addr[1];
|
bind_addr[1]=rx_tx_addr[1];
|
||||||
bind_addr[2]=0x9A;
|
bind_addr[2]=0x9A;
|
||||||
@ -79,39 +59,24 @@ void SHENQI_send_packet()
|
|||||||
LT8900_SetChannel(2);
|
LT8900_SetChannel(2);
|
||||||
packet[1]=rx_tx_addr[2];
|
packet[1]=rx_tx_addr[2];
|
||||||
packet[2]=rx_tx_addr[3];
|
packet[2]=rx_tx_addr[3];
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
packet_period=2508;
|
packet_period=2508;
|
||||||
}
|
}
|
||||||
else
|
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);
|
LT8900_SetAddress(rx_tx_addr,4);
|
||||||
packet[1]=255-convert_channel_8b(RUDDER);
|
packet[1]=255-convert_channel_8b(RUDDER);
|
||||||
packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0);
|
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);
|
uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[2]&0x0F);
|
||||||
LT8900_SetChannel(freq);
|
LT8900_SetChannel(freq);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
hopping_frequency_no++;
|
hopping_frequency_no++;
|
||||||
if(hopping_frequency_no==60)
|
if(hopping_frequency_no==60)
|
||||||
hopping_frequency_no=0;
|
hopping_frequency_no=0;
|
||||||
packet_period=1750;
|
packet_period=1750;
|
||||||
}
|
}
|
||||||
// Send packet + 1 retransmit - not sure why but needed (not present on original TX...)
|
// 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);
|
LT8900_WritePayload(packet,3);
|
||||||
while(NRF24L01_packet_ack()!=PKT_ACKED);
|
while(NRF24L01_packet_ack()!=PKT_ACKED);
|
||||||
LT8900_WritePayload(packet,3);
|
LT8900_WritePayload(packet,3);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
|
||||||
packet_count++;
|
packet_count++;
|
||||||
if(packet_count==7)
|
if(packet_count==7)
|
||||||
@ -129,16 +94,6 @@ uint16_t SHENQI_callback()
|
|||||||
SHENQI_send_packet();
|
SHENQI_send_packet();
|
||||||
else
|
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( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{
|
{
|
||||||
if(LT8900_ReadPayload(packet, 3))
|
if(LT8900_ReadPayload(packet, 3))
|
||||||
@ -147,7 +102,6 @@ uint16_t SHENQI_callback()
|
|||||||
rx_tx_addr[0]=packet[1];
|
rx_tx_addr[0]=packet[1];
|
||||||
rx_tx_addr[1]=packet[2];
|
rx_tx_addr[1]=packet[2];
|
||||||
LT8900_SetTxRxMode(TX_EN);
|
LT8900_SetTxRxMode(TX_EN);
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
packet_period=14000;
|
packet_period=14000;
|
||||||
}
|
}
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
@ -162,11 +116,7 @@ uint16_t initSHENQI()
|
|||||||
SHENQI_init();
|
SHENQI_init();
|
||||||
hopping_frequency_no = 0;
|
hopping_frequency_no = 0;
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
<<<<<<< HEAD
|
|
||||||
packet_period=100;
|
|
||||||
=======
|
|
||||||
packet_period=500;
|
packet_period=500;
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,16 @@
|
|||||||
#define PPM_MIN_125 1000 // 125%
|
#define PPM_MIN_125 1000 // 125%
|
||||||
#endif
|
#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
|
// HISKY
|
||||||
#if defined(TX_HISKY)
|
#if defined(TX_HISKY)
|
||||||
#define PPM_MAX_100 1900 // 100%
|
#define PPM_MAX_100 1900 // 100%
|
||||||
@ -37,7 +47,6 @@
|
|||||||
#define PPM_MAX_125 2050 // 125%
|
#define PPM_MAX_125 2050 // 125%
|
||||||
#define PPM_MIN_125 1150 // 125%
|
#define PPM_MIN_125 1150 // 125%
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Serial MIN MAX values
|
//Serial MIN MAX values
|
||||||
#define SERIAL_MAX_100 2012 // 100%
|
#define SERIAL_MAX_100 2012 // 100%
|
||||||
#define SERIAL_MIN_100 988 // 100%
|
#define SERIAL_MIN_100 988 // 100%
|
||||||
|
@ -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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -190,6 +15,7 @@
|
|||||||
//**************************
|
//**************************
|
||||||
// Telemetry serial code *
|
// Telemetry serial code *
|
||||||
//**************************
|
//**************************
|
||||||
|
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
|
|
||||||
#if defined SPORT_TELEMETRY
|
#if defined SPORT_TELEMETRY
|
||||||
@ -304,7 +130,7 @@ void frsky_link_frame()
|
|||||||
frame[4] = (uint8_t)RSSI_dBm;
|
frame[4] = (uint8_t)RSSI_dBm;
|
||||||
}
|
}
|
||||||
else
|
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[1] = v_lipo*2; //v_lipo; common 0x2A=42/10=4.2V
|
||||||
frame[2] = frame[1];
|
frame[2] = frame[1];
|
||||||
@ -405,7 +231,6 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
|||||||
100K 8E2 normal-multiprotocol
|
100K 8E2 normal-multiprotocol
|
||||||
-every 12ms-or multiple of 12; %36
|
-every 12ms-or multiple of 12; %36
|
||||||
1 2 3 4 5 6 7 8 9 CRC DESCR
|
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 05 F1 20 23 0F 00 A6 SWR_ID
|
||||||
7E 98 10 01 F1 33 00 00 00 C9 RSSI_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
|
7E 98 10 04 F1 58 00 00 00 A1 BATT_ID
|
||||||
@ -417,24 +242,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
|
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
|
Telemetry frames(RF) SPORT info
|
||||||
15 bytes payload
|
15 bytes payload
|
||||||
SPORT frame valid 6+3 bytes
|
SPORT frame valid 6+3 bytes
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
[00] PKLEN 0E 0E 0E 0E
|
[00] PKLEN 0E 0E 0E 0E
|
||||||
[01] TXID1 DD DD DD DD
|
[01] TXID1 DD DD DD DD
|
||||||
[02] TXID2 6D 6D 6D 6D
|
[02] TXID2 6D 6D 6D 6D
|
||||||
[03] CONST 02 02 02 02
|
[03] CONST 02 02 02 02
|
||||||
[04] RS/RB 2C D0 2C CE //D0;CE=2*RSSI;....2C = RX battery voltage(5V from Bec)
|
[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
|
[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
|
[06] NO.BT 00 00 06 03 //No.of valid SPORT frame bytes in the frame
|
||||||
[07] STRM1 00 00 7E 00
|
[07] STRM1 00 00 7E 00
|
||||||
[08] STRM2 00 00 1A 00
|
[08] STRM2 00 00 1A 00
|
||||||
@ -442,146 +258,6 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
|||||||
[10] STRM4 03 03 03 03
|
[10] STRM4 03 03 03 03
|
||||||
[11] STRM5 F1 F1 F1 F1
|
[11] STRM5 F1 F1 F1 F1
|
||||||
[12] STRM6 D1 D1 D0 D0
|
[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)
|
[13] CHKSUM1 --|2 CRC bytes sent by RX (calculated on RX side crc16/table)
|
||||||
[14] CHKSUM2 --|
|
[14] CHKSUM2 --|
|
||||||
+2 appended bytes automatically RSSI and LQI/CRC bytes(len=0x0E+3);
|
+2 appended bytes automatically RSSI and LQI/CRC bytes(len=0x0E+3);
|
||||||
@ -796,7 +472,7 @@ void TelemetryUpdate()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(telemetry_link && protocol != MODE_FRSKYX )
|
if(telemetry_link && protocol != MODE_FRSKYX )
|
||||||
{ // FrSky + Hubsan
|
{ // FrSky + Hubsan + Flysky AFHDS2A
|
||||||
frsky_link_frame();
|
frsky_link_frame();
|
||||||
telemetry_link=0;
|
telemetry_link=0;
|
||||||
return;
|
return;
|
||||||
@ -1149,4 +825,4 @@ ISR(TIMER0_OVF_vect)
|
|||||||
#endif // BASH_SERIAL
|
#endif // BASH_SERIAL
|
||||||
|
|
||||||
#endif // TELEMETRY
|
#endif // TELEMETRY
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
|
@ -34,16 +34,6 @@
|
|||||||
|
|
||||||
#define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused
|
#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)
|
static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
|
||||||
{
|
{
|
||||||
uint8_t rudder_trim, elevator_trim, aileron_trim;
|
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_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
||||||
NRF24L01_Activate(0x73);
|
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
|
// for bind packets set address to prearranged value known to receiver
|
||||||
uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65};
|
uint8_t bind_rx_tx_addr[] = {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);
|
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()
|
uint16_t yd717_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE_on)
|
if(IS_BIND_DONE_on)
|
||||||
|
@ -13,85 +13,6 @@
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
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 ***/
|
/** Multiprotocol module configuration file ***/
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
@ -102,7 +23,7 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
//Modify the channel order based on your TX: AETR, TAER, RETA...
|
//Modify the channel order based on your TX: AETR, TAER, RETA...
|
||||||
//Examples: Flysky & DEVO is AETR, JR/Spektrum radio is TAER, Multiplex is AERT...
|
//Examples: Flysky & DEVO is AETR, JR/Spektrum radio is TAER, Multiplex is AERT...
|
||||||
//Default is AETR.
|
//Default is AETR.
|
||||||
#define AETR
|
#define EATR
|
||||||
|
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
@ -114,7 +35,7 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
//!!!If a RF chip is present it MUST be marked as installed!!! or weird things will happen you have been warned.
|
//!!!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 A7105_INSTALLED
|
||||||
#define CYRF6936_INSTALLED
|
#define CYRF6936_INSTALLED
|
||||||
#define CC2500_INSTALLED
|
// #define CC2500_INSTALLED
|
||||||
#define NRF24L01_INSTALLED
|
#define NRF24L01_INSTALLED
|
||||||
|
|
||||||
|
|
||||||
@ -126,39 +47,55 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
//Comment the protocols you are not using with "//" to save Flash space.
|
//Comment the protocols you are not using with "//" to save Flash space.
|
||||||
|
|
||||||
//The protocols below need an A7105 to be installed
|
//The protocols below need an A7105 to be installed
|
||||||
|
#define AFHDS2A_A7105_INO
|
||||||
|
// #define JOYSWAY_A7105_INO
|
||||||
|
|
||||||
#define FLYSKY_A7105_INO
|
#define FLYSKY_A7105_INO
|
||||||
#define HUBSAN_A7105_INO
|
#define HUBSAN_A7105_INO
|
||||||
|
|
||||||
//The protocols below need a CYRF6936 to be installed
|
//The protocols below need a CYRF6936 to be installed
|
||||||
|
// #define WK2x01_CYRF6936_INO //!\\ //pb voie
|
||||||
|
|
||||||
#define DEVO_CYRF6936_INO
|
#define DEVO_CYRF6936_INO
|
||||||
#define DSM_CYRF6936_INO
|
#define DSM_CYRF6936_INO
|
||||||
#define J6PRO_CYRF6936_INO
|
// #define J6PRO_CYRF6936_INO
|
||||||
|
|
||||||
//The protocols below need a CC2500 to be installed
|
//The protocols below need a CC2500 to be installed
|
||||||
|
#define SKYARTEC_CC2500_INO
|
||||||
|
|
||||||
#define FRSKYD_CC2500_INO
|
#define FRSKYD_CC2500_INO
|
||||||
#define FRSKYV_CC2500_INO
|
#define FRSKYV_CC2500_INO
|
||||||
#define FRSKYX_CC2500_INO
|
#define FRSKYX_CC2500_INO
|
||||||
#define SFHSS_CC2500_INO
|
#define SFHSS_CC2500_INO
|
||||||
|
|
||||||
//The protocols below need a NRF24L01 to be installed
|
//The protocols below need a NRF24L01 to be installed
|
||||||
|
#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
|
||||||
|
|
||||||
#define BAYANG_NRF24L01_INO
|
#define BAYANG_NRF24L01_INO
|
||||||
#define CG023_NRF24L01_INO
|
#define CG023_NRF24L01_INO
|
||||||
#define CX10_NRF24L01_INO
|
#define CX10_NRF24L01_INO
|
||||||
#define ESKY_NRF24L01_INO
|
#define ESKY_NRF24L01_INO
|
||||||
#define HISKY_NRF24L01_INO
|
// #define HISKY_NRF24L01_INO
|
||||||
#define KN_NRF24L01_INO
|
#define KN_NRF24L01_INO
|
||||||
#define SLT_NRF24L01_INO
|
#define SLT_NRF24L01_INO
|
||||||
#define SYMAX_NRF24L01_INO
|
#define SYMAX_NRF24L01_INO
|
||||||
#define V2X2_NRF24L01_INO
|
#define V2X2_NRF24L01_INO
|
||||||
#define YD717_NRF24L01_INO
|
#define YD717_NRF24L01_INO
|
||||||
#define MT99XX_NRF24L01_INO
|
// #define MT99XX_NRF24L01_INO
|
||||||
#define MJXQ_NRF24L01_INO
|
// #define MJXQ_NRF24L01_INO
|
||||||
#define SHENQI_NRF24L01_INO
|
// #define SHENQI_NRF24L01_INO
|
||||||
#define FY326_NRF24L01_INO
|
// #define FY326_NRF24L01_INO
|
||||||
#define FQ777_NRF24L01_INO
|
// #define FQ777_NRF24L01_INO
|
||||||
#define ASSAN_NRF24L01_INO
|
// #define ASSAN_NRF24L01_INO
|
||||||
#define HONTAI_NRF24L01_INO
|
// #define HONTAI_NRF24L01_INO
|
||||||
|
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
/*** TELEMETRY SETTINGS ***/
|
/*** TELEMETRY SETTINGS ***/
|
||||||
@ -200,7 +137,8 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
//It is important for the module to know the endpoints of your radio.
|
//It is important for the module to know the endpoints of your radio.
|
||||||
//Below are some standard transmitters already preconfigured.
|
//Below are some standard transmitters already preconfigured.
|
||||||
//Uncomment only the one which matches your transmitter.
|
//Uncomment only the one which matches your transmitter.
|
||||||
#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs)
|
//#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs)
|
||||||
|
#define TX_TARANIS //TARANIS TAER (1100<->1900µs)
|
||||||
//#define TX_DEVO7 //DEVO (1120<->1920µs)
|
//#define TX_DEVO7 //DEVO (1120<->1920µs)
|
||||||
//#define TX_SPEKTRUM //Spektrum (1100<->1900µs)
|
//#define TX_SPEKTRUM //Spektrum (1100<->1900µs)
|
||||||
//#define TX_HISKY //HISKY (1100<->1900µs)
|
//#define TX_HISKY //HISKY (1100<->1900µs)
|
||||||
@ -225,7 +163,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)
|
//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]= {
|
const PPM_Parameters PPM_prot[15]= {
|
||||||
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option
|
// 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 },
|
/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
||||||
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
@ -234,7 +172,6 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 8 */ {MODE_YD717 , YD717 , 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 },
|
/* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
/* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 11 */ {MODE_SLT , 0 , 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 },
|
/* 12 */ {MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
@ -242,11 +179,7 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
/* 14 */ {MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 15 */ {MODE_SYMAX , SYMAX5C , 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
|
/* Available protocols and associated sub protocols to pick and choose from
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
MODE_FLYSKY
|
MODE_FLYSKY
|
||||||
Flysky
|
Flysky
|
||||||
V9X9
|
V9X9
|
||||||
@ -254,28 +187,18 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
V912
|
V912
|
||||||
MODE_HUBSAN
|
MODE_HUBSAN
|
||||||
NONE
|
NONE
|
||||||
<<<<<<< HEAD
|
|
||||||
MODE_FRSKY
|
|
||||||
=======
|
|
||||||
MODE_FRSKYD
|
MODE_FRSKYD
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
NONE
|
NONE
|
||||||
MODE_HISKY
|
MODE_HISKY
|
||||||
Hisky
|
Hisky
|
||||||
HK310
|
HK310
|
||||||
MODE_V2X2
|
MODE_V2X2
|
||||||
NONE
|
NONE
|
||||||
<<<<<<< HEAD
|
|
||||||
MODE_DSM2
|
|
||||||
DSM2
|
|
||||||
DSMX
|
|
||||||
=======
|
|
||||||
MODE_DSM
|
MODE_DSM
|
||||||
DSM2_22
|
DSM2_22
|
||||||
DSM2_11
|
DSM2_11
|
||||||
DSMX_22
|
DSMX_22
|
||||||
DSMX_11
|
DSMX_11
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
MODE_DEVO
|
MODE_DEVO
|
||||||
NONE
|
NONE
|
||||||
MODE_YD717
|
MODE_YD717
|
||||||
@ -308,142 +231,26 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
MODE_BAYANG
|
MODE_BAYANG
|
||||||
NONE
|
NONE
|
||||||
MODE_FRSKYX
|
MODE_FRSKYX
|
||||||
<<<<<<< HEAD
|
|
||||||
NONE
|
|
||||||
=======
|
|
||||||
CH_16
|
CH_16
|
||||||
CH_8
|
CH_8
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
MODE_ESKY
|
MODE_ESKY
|
||||||
NONE
|
NONE
|
||||||
MODE_MT99XX
|
MODE_MT99XX
|
||||||
MT99
|
MT99
|
||||||
H7
|
H7
|
||||||
YZ
|
YZ
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
LS
|
LS
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
MODE_MJXQ
|
MODE_MJXQ
|
||||||
WLH08
|
WLH08
|
||||||
X600
|
X600
|
||||||
X800
|
X800
|
||||||
H26D
|
H26D
|
||||||
<<<<<<< HEAD
|
E010
|
||||||
MODE_SHENQI
|
MODE_SHENQI
|
||||||
NONE
|
NONE
|
||||||
MODE_FY326
|
MODE_FY326
|
||||||
FY326
|
FY326
|
||||||
FY319
|
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
|
MODE_SFHSS
|
||||||
NONE
|
NONE
|
||||||
MODE_J6PRO
|
MODE_J6PRO
|
||||||
@ -458,6 +265,7 @@ enum chan_orders{
|
|||||||
FORMAT_HONTAI
|
FORMAT_HONTAI
|
||||||
FORMAT_JJRCX1
|
FORMAT_JJRCX1
|
||||||
FORMAT_X5C1
|
FORMAT_X5C1
|
||||||
|
FQ777-951
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 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...
|
// 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...
|
||||||
@ -472,4 +280,3 @@ enum chan_orders{
|
|||||||
|
|
||||||
// Option: the value is between -127 and +127.
|
// 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
|
// 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
|
|
||||||
|
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
|
BIN
Multiprotocol/calcul chanel.ods
Normal file
BIN
Multiprotocol/calcul chanel.ods
Normal file
Binary file not shown.
@ -89,6 +89,7 @@ enum A7105_MASK {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
INIT_FLYSKY,
|
INIT_FLYSKY,
|
||||||
|
INIT_FLYSKY_AFHDS2A,
|
||||||
INIT_HUBSAN
|
INIT_HUBSAN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,13 +103,8 @@ enum {
|
|||||||
//#define NOP 0xFF
|
//#define NOP 0xFF
|
||||||
|
|
||||||
// XN297 emulation layer
|
// XN297 emulation layer
|
||||||
<<<<<<< HEAD
|
|
||||||
#define XN297_UNSCRAMBLED 8
|
|
||||||
|
|
||||||
=======
|
|
||||||
enum {
|
enum {
|
||||||
XN297_UNSCRAMBLED = 0,
|
XN297_UNSCRAMBLED = 0,
|
||||||
XN297_SCRAMBLED
|
XN297_SCRAMBLED
|
||||||
};
|
};
|
||||||
>>>>>>> refs/remotes/pascallanger/master
|
|
||||||
#endif
|
#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}
|
|
@ -16,7 +16,7 @@
|
|||||||
// Check selected board type
|
// Check selected board type
|
||||||
#ifndef XMEGA
|
#ifndef XMEGA
|
||||||
#if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
|
#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"
|
// #error You must select the board type "Arduino Pro or Pro Mini" or "Arduino Mini"
|
||||||
#endif
|
#endif
|
||||||
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
||||||
#error You must select the processor type "ATmega328(5V, 16MHz)"
|
#error You must select the processor type "ATmega328(5V, 16MHz)"
|
||||||
@ -24,10 +24,27 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//******************
|
//******************
|
||||||
// Protocols
|
// Protocols max 31 x2
|
||||||
//******************
|
//******************
|
||||||
enum PROTOCOLS
|
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_AFHDS2A = 31, // =>A7105
|
||||||
|
MODE_INAV = 57, // =>NRF24L01
|
||||||
|
|
||||||
MODE_SERIAL = 0, // Serial commands
|
MODE_SERIAL = 0, // Serial commands
|
||||||
MODE_FLYSKY = 1, // =>A7105
|
MODE_FLYSKY = 1, // =>A7105
|
||||||
MODE_HUBSAN = 2, // =>A7105
|
MODE_HUBSAN = 2, // =>A7105
|
||||||
@ -57,7 +74,6 @@ enum PROTOCOLS
|
|||||||
MODE_HONTAI = 26, // =>NRF24L01
|
MODE_HONTAI = 26, // =>NRF24L01
|
||||||
MODE_OPENLRS = 27, // =>OpenLRS hardware
|
MODE_OPENLRS = 27, // =>OpenLRS hardware
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flysky
|
enum Flysky
|
||||||
{
|
{
|
||||||
Flysky=0,
|
Flysky=0,
|
||||||
@ -137,7 +153,39 @@ enum HONTAI
|
|||||||
{
|
{
|
||||||
FORMAT_HONTAI = 0,
|
FORMAT_HONTAI = 0,
|
||||||
FORMAT_JJRCX1 = 1,
|
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 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
|
#define NONE 0
|
||||||
@ -206,6 +254,7 @@ struct PPM_Parameters
|
|||||||
#define BIND_BUTTON_FLAG_on protocol_flags |= _BV(5)
|
#define BIND_BUTTON_FLAG_on protocol_flags |= _BV(5)
|
||||||
#define BIND_BUTTON_FLAG_off protocol_flags &= ~_BV(5)
|
#define BIND_BUTTON_FLAG_off protocol_flags &= ~_BV(5)
|
||||||
#define IS_BIND_BUTTON_FLAG_on ( ( protocol_flags & _BV(5) ) !=0 )
|
#define IS_BIND_BUTTON_FLAG_on ( ( protocol_flags & _BV(5) ) !=0 )
|
||||||
|
|
||||||
//PPM RX OK
|
//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 PPM_FLAG_on protocol_flags |= _BV(6)
|
||||||
@ -230,9 +279,11 @@ struct PPM_Parameters
|
|||||||
#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3)
|
#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3)
|
||||||
#define TX_MAIN_PAUSE_on 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 IS_TX_MAIN_PAUSE_on ( ( protocol_flags2 & _BV(3) ) !=0 )
|
||||||
|
|
||||||
#define TX_RX_PAUSE_off protocol_flags2 &= ~_BV(4)
|
#define TX_RX_PAUSE_off protocol_flags2 &= ~_BV(4)
|
||||||
#define TX_RX_PAUSE_on 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 IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
|
||||||
|
|
||||||
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
|
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
|
||||||
|
|
||||||
//********************
|
//********************
|
||||||
@ -464,13 +515,17 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
X800 2
|
X800 2
|
||||||
H26D 3
|
H26D 3
|
||||||
E010 4
|
E010 4
|
||||||
|
sub_protocol==FY326
|
||||||
|
FY326 0
|
||||||
|
FY319 1
|
||||||
sub_protocol==FRSKYX
|
sub_protocol==FRSKYX
|
||||||
CH_16 0
|
CH_16 0
|
||||||
CH_8 1
|
CH_8 1
|
||||||
sub_protocol==HONTAI
|
sub_protocol==HONTAI
|
||||||
FORMAT_HONTAI 0
|
HONTAI 0
|
||||||
FORMAT_JJRCX1 1
|
JJRCX1 1
|
||||||
FORMAT_X5C1 2
|
X5C1 2
|
||||||
|
FQ777-521 3
|
||||||
Power value => 0x80 0=High/1=Low
|
Power value => 0x80 0=High/1=Low
|
||||||
Stream[3] = option_protocol;
|
Stream[3] = option_protocol;
|
||||||
option_protocol value is -127..127
|
option_protocol value is -127..127
|
||||||
@ -483,3 +538,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
2047 +125%
|
2047 +125%
|
||||||
Channels bits are concatenated to fit in 22 bytes like in SBUS protocol
|
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