_Config.h file and all protocol settings for PPM mode

This commit is contained in:
pascallanger 2016-01-22 16:23:39 +01:00
parent 3fcaf93788
commit 151e82a2c3
7 changed files with 320 additions and 358 deletions

View File

@ -151,7 +151,7 @@ static void frsky2way_init(uint8_t bind)
cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05); cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05);
cc2500_writeReg(CC2500_3E_PATABLE, 0xff); cc2500_writeReg(CC2500_3E_PATABLE, 0xff);
cc2500_writeReg(CC2500_0B_FSCTRL1, 0x08); cc2500_writeReg(CC2500_0B_FSCTRL1, 0x08);
cc2500_writeReg(CC2500_0C_FSCTRL0, fine); cc2500_writeReg(CC2500_0C_FSCTRL0, option);
//base freq FREQ = 0x5C7627 (F = 2404MHz) //base freq FREQ = 0x5C7627 (F = 2404MHz)
cc2500_writeReg(CC2500_0D_FREQ2, 0x5c); cc2500_writeReg(CC2500_0D_FREQ2, 0x5c);
cc2500_writeReg(CC2500_0E_FREQ1, 0x76); cc2500_writeReg(CC2500_0E_FREQ1, 0x76);

View File

@ -18,21 +18,21 @@
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
#define BIND_COUNT 1000 #define HISKY_BIND_COUNT 1000
#define TXID_SIZE 5 #define HISKY_TXID_SIZE 5
#define FREQUENCE_NUM 20 #define HISKY_FREQUENCE_NUM 20
// //
uint8_t bind_buf_arry[4][10]; uint8_t bind_buf_arry[4][10];
// HiSky protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence // HiSky protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence
// which does not depend on this id and is passed explicitly in binding sequence. So we are free // which does not depend on this id and is passed explicitly in binding sequence. So we are free
// to generate this sequence as we wish. It should be in the range [02..77] // to generate this sequence as we wish. It should be in the range [02..77]
static void calc_fh_channels(uint32_t seed) static void calc_fh_channels()
{ {
uint8_t idx = 0; uint8_t idx = 0;
uint32_t rnd = seed; uint32_t rnd = MProtocol_id;
while (idx < FREQUENCE_NUM) while (idx < HISKY_FREQUENCE_NUM)
{ {
uint8_t i; uint8_t i;
uint8_t count_2_26 = 0, count_27_50 = 0, count_51_74 = 0; uint8_t count_2_26 = 0, count_27_50 = 0, count_51_74 = 0;
@ -41,7 +41,7 @@ static void calc_fh_channels(uint32_t seed)
// Use least-significant byte. 73 is prime, so channels 76..77 are unused // Use least-significant byte. 73 is prime, so channels 76..77 are unused
uint8_t next_ch = ((rnd >> 8) % 73) + 2; uint8_t next_ch = ((rnd >> 8) % 73) + 2;
// Keep the distance 2 between the channels - either odd or even // Keep the distance 2 between the channels - either odd or even
if (((next_ch ^ (uint8_t)seed) & 0x01 )== 0) if (((next_ch ^ (uint8_t)rx_tx_addr[3]) & 0x01 )== 0)
continue; continue;
// Check that it's not duplicated and spread uniformly // Check that it's not duplicated and spread uniformly
for (i = 0; i < idx; i++) { for (i = 0; i < idx; i++) {
@ -195,7 +195,7 @@ uint16_t hisky_cb()
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
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++; hopping_frequency_no++;
if (hopping_frequency_no >= FREQUENCE_NUM) if (hopping_frequency_no >= HISKY_FREQUENCE_NUM)
hopping_frequency_no = 0; hopping_frequency_no = 0;
break; break;
case 7: case 7:
@ -213,15 +213,19 @@ uint16_t hisky_cb()
return 1000; // send 1 binding packet and 1 data packet per 9ms return 1000; // send 1 binding packet and 1 data packet per 9ms
} }
// Generate internal id from TX id and manufacturer id (STM32 unique id)
static void initialize_tx_id() static void initialize_tx_id()
{ {
//Generate frequency hopping table //Generate frequency hopping table
if(sub_protocol==HK310) if(sub_protocol==HK310)
for(uint8_t i=0;i<FREQUENCE_NUM;i++) {
hopping_frequency[i]=i; // Sequential order hop channels... // for HiSky surface protocol, the transmitter always generates hop channels in sequential order.
// The transmitter only generates the first hop channel between 0 and 49. So the channel range is from 0 to 69.
hopping_frequency_no=rx_tx_addr[0]%50;
for(uint8_t i=0;i<HISKY_FREQUENCE_NUM;i++)
hopping_frequency[i]=hopping_frequency_no++; // Sequential order hop channels...
}
else else
calc_fh_channels(MProtocol_id); calc_fh_channels();
} }
uint16_t initHiSky() uint16_t initHiSky()
@ -234,7 +238,7 @@ uint16_t initHiSky()
binding_idx = 0; binding_idx = 0;
if(IS_AUTOBIND_FLAG_on) if(IS_AUTOBIND_FLAG_on)
bind_counter = BIND_COUNT; bind_counter = HISKY_BIND_COUNT;
else else
bind_counter = 0; bind_counter = 0;
return 1000; return 1000;

View File

@ -12,6 +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/>.
*/ */
// compatible with Hubsan H102D, H107/L/C/D and H107P/C+/D+
// Last sync with hexfet new_protocols/hubsan_a7105.c dated 2015-12-11 // Last sync with hexfet new_protocols/hubsan_a7105.c dated 2015-12-11
#if defined(HUBSAN_A7105_INO) #if defined(HUBSAN_A7105_INO)

View File

@ -4,7 +4,7 @@
http://www.rcgroups.com/forums/showthread.php?t=2165676 http://www.rcgroups.com/forums/showthread.php?t=2165676
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/edit/master/README.md https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/edit/master/README.md
Thanks to PhracturedBlue Thanks to PhracturedBlue, Hexfet, Goebish and all protocol developers
Ported from deviation firmware Ported from deviation firmware
This project is free software: you can redistribute it and/or modify This project is free software: you can redistribute it and/or modify
@ -23,71 +23,10 @@
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <util/delay.h> #include <util/delay.h>
#include "Multiprotocol.h"
//****************************************************** //Multiprotocol module configuration file
//****************************************************** #include "_Config.h"
// Multiprotocol module configuration starts here
//Uncomment the type of TX
#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)
#include "multiprotocol.h"
//Uncomment to enable 8 channels serial protocol, 16 otherwise
//#define NUM_SERIAL_CH_8
//Uncomment to enable telemetry
#define TELEMETRY
//Comment protocols to exclude from compilation
#define BAYANG_NRF24L01_INO
#define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO
#define DEVO_CYRF6936_INO
#define DSM2_CYRF6936_INO
#define ESKY_NRF24L01_INO
#define FLYSKY_A7105_INO
#define FRSKY_CC2500_INO
#define HISKY_NRF24L01_INO
#define HUBSAN_A7105_INO
#define KN_NRF24L01_INO
#define SLT_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define YD717_NRF24L01_INO
//#define FRSKYX_CC2500_INO
//Update this table to set which protocol/sub_protocol is called for the corresponding dial number
static const uint8_t PPM_prot[15][2]= { {MODE_FLYSKY , Flysky }, //Dial=1
{MODE_HUBSAN , 0 }, //Dial=2
{MODE_FRSKY , 0 }, //Dial=3
{MODE_HISKY , Hisky }, //Dial=4
{MODE_V2X2 , 0 }, //Dial=5
{MODE_DSM2 , DSM2 }, //Dial=6
{MODE_DEVO , 0 }, //Dial=7
{MODE_YD717 , YD717 }, //Dial=8
{MODE_KN , WLTOYS }, //Dial=9
{MODE_SYMAX , SYMAX }, //Dial=10
{MODE_SLT , 0 }, //Dial=11
{MODE_CX10 , CX10_BLUE }, //Dial=12
{MODE_CG023 , CG023 }, //Dial=13
{MODE_BAYANG , 0 }, //Dial=14
{MODE_SYMAX , SYMAX5C } //Dial=15
};
//CC2500 RF module frequency adjustment, use in case you cannot bind with Frsky RX
//Note: this is set via Option when serial protocol is used
//values from 0-127 offset increase frequency, values from 255 to 127 decrease base frequency
//uint8_t fine = 0x00;
uint8_t fine = 0xd7; //* 215=-41 *
// Multiprotocol module configuration ends here
//******************************************************
//******************************************************
//Global constants/variables //Global constants/variables
@ -132,11 +71,7 @@ uint8_t mode_select;
uint8_t protocol_flags=0,protocol_flags2=0; uint8_t protocol_flags=0,protocol_flags2=0;
// Serial variables // Serial variables
#if defined(NUM_SERIAL_CH_8) //8 channels serial protocol
#define RXBUFFER_SIZE 14
#else //16 channels serial protocol
#define RXBUFFER_SIZE 25 #define RXBUFFER_SIZE 25
#endif
#define TXBUFFER_SIZE 12 #define TXBUFFER_SIZE 12
volatile uint8_t rx_buff[RXBUFFER_SIZE]; volatile uint8_t rx_buff[RXBUFFER_SIZE];
volatile uint8_t rx_ok_buff[RXBUFFER_SIZE]; volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
@ -213,18 +148,22 @@ void setup()
LED_SET_OUTPUT; LED_SET_OUTPUT;
// Read or create protocol id // Read or create protocol id
MProtocol_id=random_id(10,false); MProtocol_id_master=random_id(10,false);
MProtocol_id_master=MProtocol_id;
//Set power transmission flags
POWER_FLAG_on; //By default high power for everything
//Protocol and interrupts initialization //Protocol and interrupts initialization
if(mode_select != MODE_SERIAL) if(mode_select != MODE_SERIAL)
{ // PPM { // PPM
cur_protocol[0]= PPM_prot[mode_select-1][0]; mode_select--;
sub_protocol = PPM_prot[mode_select-1][1]; cur_protocol[0] = PPM_prot[mode_select].protocol;
protocol_init(cur_protocol[0]); sub_protocol = PPM_prot[mode_select].sub_proto;
MProtocol_id = PPM_prot[mode_select].rx_num + MProtocol_id_master;
option = PPM_prot[mode_select].option;
if(PPM_prot[mode_select].power) POWER_FLAG_on;
if(PPM_prot[mode_select].autobind) AUTOBIND_FLAG_on;
mode_select++;
protocol_init();
//Configure PPM interrupt //Configure PPM interrupt
EICRA |=(1<<ISC11); // The rising edge of INT1 pin D3 generates an interrupt request EICRA |=(1<<ISC11); // The rising edge of INT1 pin D3 generates an interrupt request
@ -250,7 +189,7 @@ void loop()
{ // Protocol needs to be changed { // Protocol needs to be changed
LED_OFF; //led off during protocol init LED_OFF; //led off during protocol init
module_reset(); //reset previous module module_reset(); //reset previous module
protocol_init(cur_protocol[0]&0x1F); //init new protocol protocol_init(); //init new protocol
CHANGE_PROTOCOL_FLAG_off; //done CHANGE_PROTOCOL_FLAG_off; //done
} }
} }
@ -341,7 +280,8 @@ static void CheckTimer(uint16_t (*cb)(void))
} }
} }
static void protocol_init(uint8_t protocol) // Protocol start
static void protocol_init()
{ {
uint16_t next_callback=0; // Default is immediate call back uint16_t next_callback=0; // Default is immediate call back
remote_callback = 0; remote_callback = 0;
@ -358,7 +298,7 @@ static void protocol_init(uint8_t protocol)
CTRL1_on; //NRF24L01 antenna RF3 by default CTRL1_on; //NRF24L01 antenna RF3 by default
CTRL2_off; //NRF24L01 antenna RF3 by default CTRL2_off; //NRF24L01 antenna RF3 by default
switch(protocol) // Init the requested protocol switch(cur_protocol[0]&0x1F) // Init the requested protocol
{ {
#if defined(FLYSKY_A7105_INO) #if defined(FLYSKY_A7105_INO)
case MODE_FLYSKY: case MODE_FLYSKY:
@ -496,7 +436,6 @@ static void update_serial_data()
POWER_FLAG_on; //power high POWER_FLAG_on; //power high
option=rx_ok_buff[2]; option=rx_ok_buff[2];
fine=option; // Update FrSky fine tuning
if( ((rx_ok_buff[0]&0x5F) != (cur_protocol[0]&0x5F)) || ( (rx_ok_buff[1]&0x7F) != cur_protocol[1] ) ) if( ((rx_ok_buff[0]&0x5F) != (cur_protocol[0]&0x5F)) || ( (rx_ok_buff[1]&0x7F) != cur_protocol[1] ) )
{ // New model has been selected { // New model has been selected
@ -511,19 +450,7 @@ static void update_serial_data()
CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind
cur_protocol[0] = rx_ok_buff[0]; //store current protocol cur_protocol[0] = rx_ok_buff[0]; //store current protocol
// decode channel values // decode channel values
#if defined(NUM_SERIAL_CH_8) //8 channels serial protocol
Servo_data[0]=rx_ok_buff[3]+((rx_ok_buff[11]&0xC0)<<2);
Servo_data[1]=rx_ok_buff[4]+((rx_ok_buff[11]&0x30)<<4);
Servo_data[2]=rx_ok_buff[5]+((rx_ok_buff[11]&0x0C)<<6);
Servo_data[3]=rx_ok_buff[6]+((rx_ok_buff[11]&0x03)<<8);
Servo_data[4]=rx_ok_buff[7]+((rx_ok_buff[12]&0xC0)<<2);
Servo_data[5]=rx_ok_buff[8]+((rx_ok_buff[12]&0x30)<<4);
Servo_data[6]=rx_ok_buff[9]+((rx_ok_buff[12]&0x0C)<<6);
Servo_data[7]=rx_ok_buff[10]+((rx_ok_buff[12]&0x03)<<8);
for(uint8_t i=0;i<8;i++)
Servo_data[i]=((Servo_data[i]*5)>>2)+860; //range 860-2140;
#else //16 channels serial protocol
volatile uint8_t *p=rx_ok_buff+2; volatile uint8_t *p=rx_ok_buff+2;
uint8_t dec=-3; uint8_t dec=-3;
for(uint8_t i=0;i<NUM_CHN;i++) for(uint8_t i=0;i<NUM_CHN;i++)
@ -537,7 +464,6 @@ static void update_serial_data()
p++; p++;
Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125%
} }
#endif
RX_FLAG_off; //data has been processed RX_FLAG_off; //data has been processed
} }
@ -617,16 +543,6 @@ uint16_t limit_channel_100(uint8_t ch)
return Servo_data[ch]; return Servo_data[ch];
} }
// Convert 32b id to rx_tx_addr
static void set_rx_tx_addr(uint32_t id)
{ // Used by almost all protocols
rx_tx_addr[0] = (id >> 24) & 0xFF;
rx_tx_addr[1] = (id >> 16) & 0xFF;
rx_tx_addr[2] = (id >> 8) & 0xFF;
rx_tx_addr[3] = (id >> 0) & 0xFF;
rx_tx_addr[4] = 0xC1; // for YD717: always uses first data port
}
#if defined(TELEMETRY) #if defined(TELEMETRY)
void Serial_write(uint8_t data) void Serial_write(uint8_t data)
{ {
@ -641,21 +557,12 @@ void Serial_write(uint8_t data)
static void Mprotocol_serial_init() static void Mprotocol_serial_init()
{ {
#if defined(NUM_SERIAL_CH_8) //8 channels serial protocol
#define BAUD 125000
#include <util/setbaud.h>
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
//Set frame format to 8 data bits, no parity, 1 stop bit
UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
#else //16 channels serial protocol
#define BAUD 100000 #define BAUD 100000
#include <util/setbaud.h> #include <util/setbaud.h>
UBRR0H = UBRRH_VALUE; UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE; UBRR0L = UBRRL_VALUE;
//Set frame format to 8 data bits, even parity, 2 stop bits //Set frame format to 8 data bits, even parity, 2 stop bits
UCSR0C |= (1<<UPM01)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); UCSR0C |= (1<<UPM01)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
#endif
while ( UCSR0A & (1 << RXC0) )//flush receive buffer while ( UCSR0A & (1 << RXC0) )//flush receive buffer
UDR0; UDR0;
//enable reception and RC complete interrupt //enable reception and RC complete interrupt
@ -663,6 +570,16 @@ static void Mprotocol_serial_init()
UCSR0B |= (1<<TXEN0);//tx enable UCSR0B |= (1<<TXEN0);//tx enable
} }
// Convert 32b id to rx_tx_addr
static void set_rx_tx_addr(uint32_t id)
{ // Used by almost all protocols
rx_tx_addr[0] = (id >> 24) & 0xFF;
rx_tx_addr[1] = (id >> 16) & 0xFF;
rx_tx_addr[2] = (id >> 8) & 0xFF;
rx_tx_addr[3] = (id >> 0) & 0xFF;
rx_tx_addr[4] = 0xC1; // for YD717: always uses first data port
}
static uint32_t random_id(uint16_t adress, uint8_t create_new) static uint32_t random_id(uint16_t adress, uint8_t create_new)
{ {
uint32_t id; uint32_t id;
@ -694,6 +611,7 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new)
/**************************/ /**************************/
/**************************/ /**************************/
//PPM
ISR(INT1_vect) ISR(INT1_vect)
{ // Interrupt on PPM pin { // Interrupt on PPM pin
static int8_t chan=-1; static int8_t chan=-1;
@ -722,53 +640,7 @@ ISR(INT1_vect)
Prev_TCNT1+=Cur_TCNT1; Prev_TCNT1+=Cur_TCNT1;
} }
#if defined(TELEMETRY) //Serial RX
ISR(USART_UDRE_vect)
{ // Transmit interrupt
uint8_t t = tx_tail;
if(tx_head!=t)
{
if(++t>=TXBUFFER_SIZE)//head
t=0;
UDR0=tx_buff[t];
tx_tail=t;
}
if (t == tx_head)
UCSR0B &= ~(1<<UDRIE0); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
}
#endif
#if defined(NUM_SERIAL_CH_8) //8 channels serial protocol
ISR(USART_RX_vect)
{ // RX interrupt
static uint16_t crc = 0;
if(idx==0)
{ // Let's try to sync at this point
OCR1B=TCNT1+5000L; // timer for 2500us
TIFR1=(1<<OCF1B); // clear OCR1B match flag
TIMSK1 |=(1<<OCIE1B); // enable interrupt on compare B match
crc=0;
}
if(idx<RXBUFFER_SIZE-1)
{ // Store bytes in buffer and calculate crc as we go
rx_buff[idx]=UDR0;
crc = (crc<<8) ^ pgm_read_word(&CRCTable[((uint8_t)(crc>>8) ^ rx_buff[idx++]) & 0xFF]);
}
else
{ // A frame has been received and needs to be checked before giving it to main
TIMSK1 &=~(1<<OCIE1B); // disable interrupt on compare B match
if(UDR0==(uint8_t)(crc & 0xFF) && !IS_RX_FLAG_on)
{ //Good frame received and main has finished with previous buffer
for(idx=0;idx<RXBUFFER_SIZE;idx++)
rx_ok_buff[idx]=rx_buff[idx]; // Duplicate the buffer
RX_FLAG_on; //flag for main to process servo data
LED_ON;
}
idx=0;
}
}
#else //16 channels serial protocol
ISR(USART_RX_vect) ISR(USART_RX_vect)
{ // RX interrupt { // RX interrupt
if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
@ -805,9 +677,26 @@ ISR(USART_RX_vect)
idx=0; // Error encountered discard full frame... idx=0; // Error encountered discard full frame...
} }
} }
#endif
//Serial timer
ISR(TIMER1_COMPB_vect) ISR(TIMER1_COMPB_vect)
{ // Timer1 compare B interrupt { // Timer1 compare B interrupt
idx=0; idx=0;
} }
#if defined(TELEMETRY)
//Serial TX
ISR(USART_UDRE_vect)
{ // Transmit interrupt
uint8_t t = tx_tail;
if(tx_head!=t)
{
if(++t>=TXBUFFER_SIZE)//head
t=0;
UDR0=tx_buff[t];
tx_tail=t;
}
if (t == tx_head)
UCSR0B &= ~(1<<UDRIE0); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
}
#endif

220
Multiprotocol/_Config.h Normal file
View File

@ -0,0 +1,220 @@
/*
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/>.
*/
/** Multiprotocol module configuration file ***/
//Uncomment your TX type
#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 a protocol to exclude it from compilation
#define BAYANG_NRF24L01_INO
#define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO
#define DEVO_CYRF6936_INO
#define DSM2_CYRF6936_INO
#define ESKY_NRF24L01_INO
#define FLYSKY_A7105_INO
#define FRSKY_CC2500_INO
#define HISKY_NRF24L01_INO
#define HUBSAN_A7105_INO
#define KN_NRF24L01_INO
#define SLT_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define YD717_NRF24L01_INO
//#define FRSKYX_CC2500_INO
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
static const PPM_Parameters PPM_prot[15]=
{
// Protocol Sub protocol RX_Num Power Auto Bind Option
{MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=1
{MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=2
{MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, //Dial=3
{MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=4
{MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=5
{MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=6
{MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=7
{MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=8
{MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=9
{MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=10
{MODE_SLT , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=11
{MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=12
{MODE_CG023 , CG023 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=13
{MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=14
{MODE_SYMAX , SYMAX5C , 0 , P_HIGH , NO_AUTOBIND , 0 } //Dial=15
};
/* Available protocols and associated sub protocols:
MODE_FLYSKY
Flysky
V9X9
V6X6
V912
MODE_HUBSAN
NONE
MODE_FRSKY
NONE
MODE_HISKY
Hisky
HK310
MODE_V2X2
NONE
MODE_DSM2
DSM2
DSMX
MODE_DEVO
NONE
MODE_YD717
YD717
SKYWLKR
SYMAX4
XINXUN
NIHUI
MODE_KN
WLTOYS
FEILUN
MODE_SYMAX
SYMAX
SYMAX5C
MODE_SLT
NONE
MODE_CX10
CX10_GREEN
CX10_BLUE
DM007
Q282
JC3015_1
JC3015_2
MK33041
MODE_CG023
CG023
YD829
H8_3D
MODE_BAYANG
NONE
MODE_FRSKYX
NONE
MODE_ESKY
NONE
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
enum chan_order{
AILERON =0,
ELEVATOR,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#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
enum chan_order{
ELEVATOR=0,
AILERON,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#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
enum chan_order{
THROTTLE=0,
AILERON,
ELEVATOR,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#endif
// HISKY
#if defined(TX_HISKY)
#define PPM_MAX 2000
#define PPM_MIN 1000
#define PPM_MAX_100 1900
#define PPM_MIN_100 1100
enum chan_order{
AILERON =0,
ELEVATOR,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#endif
#define PPM_MIN_COMMAND 1250
#define PPM_SWITCH 1550
#define PPM_MAX_COMMAND 1750

View File

@ -87,101 +87,21 @@ enum CG023
H8_3D = 2 H8_3D = 2
}; };
//****************** #define NONE 0
//TX definitions with timing endpoints and channels order #define P_HIGH 1
//****************** #define P_LOW 0
#define AUTOBIND 1
#define NO_AUTOBIND 0
// Turnigy PPM and channels struct PPM_Parameters
#if defined(TX_ER9X) {
#define PPM_MAX 2140 uint8_t protocol : 5;
#define PPM_MIN 860 uint8_t sub_proto : 3;
#define PPM_MAX_100 2012 uint8_t rx_num : 4;
#define PPM_MIN_100 988 uint8_t power : 1;
enum chan_order{ uint8_t autobind : 1;
AILERON =0, uint8_t option;
ELEVATOR,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
}; };
#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
enum chan_order{
ELEVATOR=0,
AILERON,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#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
enum chan_order{
THROTTLE=0,
AILERON,
ELEVATOR,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#endif
// HISKY
#if defined(TX_HISKY)
#define PPM_MAX 2000
#define PPM_MIN 1000
#define PPM_MAX_100 1900
#define PPM_MIN_100 1100
enum chan_order{
AILERON =0,
ELEVATOR,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#endif
#define PPM_MIN_COMMAND 1250
#define PPM_SWITCH 1550
#define PPM_MAX_COMMAND 1750
//******************* //*******************
//*** Pinouts *** //*** Pinouts ***
@ -523,86 +443,5 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
1843 +100% 1843 +100%
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
**************************
8 channels serial protocol
**************************
Serial: 125000 Baud 8n1 _ xxxx xxxx - ---
Channels:
Nbr=8
10bits=0..1023
0 -125%
96 -100%
512 0%
928 +100%
1023 +125%
Stream[0] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
sub_protocol is 0..31 (bits 0..4)
=> Reserved 0
Flysky 1
Hubsan 2
Frsky 3
Hisky 4
V2x2 5
DSM2 6
Devo 7
YD717 8
KN 9
SymaX 10
SLT 11
CX10 12
CG023 13
Bayang 14
FrskyX 15
ESky 16
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
Stream[1] = RxNum | Power | Type;
RxNum value is 0..15 (bits 0..3)
Type is 0..7 <<4 (bit 4..6)
sub_protocol==Flysky
Flysky 0
V9x9 1
V6x6 2
V912 3
sub_protocol==Hisky
Hisky 0
HK310 1
sub_protocol==DSM2
DSM2 0
DSMX 1
sub_protocol==YD717
YD717 0
SKYWLKR 1
SYMAX4 2
XINXUN 3
NIHUI 4
sub_protocol==KN
WLTOYS 0
FEILUN 1
sub_protocol==SYMAX
SYMAX 0
SYMAX5C 1
sub_protocol==CX10
CX10_GREEN 0
CX10_BLUE 1 // also compatible with CX10-A, CX12
DM007 2
Q282 3
JC3015_1 4
JC3015_2 5
MK33041 6
sub_protocol==CG023
CG023 0
YD829 1
H8_3D 2
Power value => 0x80 0=High/1=Low
Stream[2] = option_protocol;
option_protocol value is -127..127
Stream[i+3] = lowByte(channel[i]) // with i[0..7]
Stream[11] = highByte(channel[0])<<6 | highByte(channel[1])<<4 | highByte(channel[2])<<2 | highByte(channel[3])
Stream[12] = highByte(channel[4])<<6 | highByte(channel[5])<<4 | highByte(channel[6])<<2 | highByte(channel[7])
Stream[13] = lowByte(CRC16(Stream[0..12])
*/ */

View File

@ -26,12 +26,21 @@ The source code is partly based on the Deviation TX project, thanks to all the d
###Using standard PPM output (trainer port) ###Using standard PPM output (trainer port)
The multiprotocol TX module can be used on any TX with a trainer port. The multiprotocol TX module can be used on any TX with a trainer port.
Channels order is AETR by default but can be changed in the source code. Channels order is AETR by default but can be changed in the _Config.h.
The protocol selection is done via a dip switch or a rotary dip switch for access to up to 15 different protocols. The protocol selection is done via a dip switch or a rotary dip switch.
![Screenshot](http://media.digikey.com/photos/Grayhill%20Photos/94HBB16T_sml.jpg) ![Screenshot](http://media.digikey.com/photos/Grayhill%20Photos/94HBB16T_sml.jpg)
You can access to up to 15 different protocols and associated settings.
Settings per selection are located in _Config.h:
- Protocol and type: many main protocols have variants
- RX Num: number your different RXs and make sure only one model will react to the commands
- Power: High or low, enables to lower the power setting of your TX (indoor for example).
- Option: -127..+127 allowing to set specific protocol options. Like for Hubsan to set the video frequency.
- Autobind: Yes or No. At the model selection (or power applied to the TX) a bind sequence will be initiated
###Using a serial output ###Using a serial output
The multiprotocol TX module takes full advantage of being used on a Turnigy 9X, 9XR, 9XR Pro, Taranis, 9Xtreme, AR9X, ... running [er9x or ersky9X](https://github.com/MikeBland/mbtx/tree/next). (A version for OpenTX is being looked at) The multiprotocol TX module takes full advantage of being used on a Turnigy 9X, 9XR, 9XR Pro, Taranis, 9Xtreme, AR9X, ... running [er9x or ersky9X](https://github.com/MikeBland/mbtx/tree/next). (A version for OpenTX is being looked at)
@ -50,8 +59,8 @@ Options are:
Notes: Notes:
- Using this solution does not need any modification of the TX since it uses the TX module slot PPM pin for serial transfer. - Using this solution does not need any modification of the TX since it uses the TX module slot PPM pin for serial transfer.
- There are 2 versions of serial protocol either 8 or 16 channels. 16 channels is the latest version. Make sure to use the right version based on your version of er9x/ersky9x. - There are 2 versions of serial protocol either 8 or 16 channels. 16 channels is the latest and only available version going forward. Make sure to use the right version based on your version of er9x/ersky9x.
- Channels order is AETR by default but can be changed in the source code. - Channels order is AETR by default but can be changed in _Config.h.
###Telemetry ###Telemetry
Telemetry is available for er9x and ersky9x TXs. Telemetry is available for er9x and ersky9x TXs.
@ -85,7 +94,7 @@ Notes:
###Protocol selection ###Protocol selection
####Using the dial for PPM input ####Using the dial for PPM input
PPM is only allowing access to a subset of existing protocols & sub_protocols. PPM is only allowing access to a subset of existing protocols.
The default association dial position / protocol is listed below. The default association dial position / protocol is listed below.
Dial|Protocol|Sub_protocol|RF Module Dial|Protocol|Sub_protocol|RF Module
@ -109,7 +118,7 @@ Dial|Protocol|Sub_protocol|RF Module
Notes: Notes:
- The dial selection must be done before the power is applied. - The dial selection must be done before the power is applied.
- The protocols and subprotocols accessible by the dial can be personalized by modifying the source code. - The protocols, subprotocols and all other settings can be personalized by modifying the _Config.h file.
####Using serial input with er9x/ersky9x ####Using serial input with er9x/ersky9x
Serial is allowing access to all existing protocols & sub_protocols listed below. Serial is allowing access to all existing protocols & sub_protocols listed below.
@ -455,7 +464,7 @@ Arduino 1.6.5
Compilation of the code posted here works. So if it doesn't for you this is a problem with your setup, please double check everything before asking. Compilation of the code posted here works. So if it doesn't for you this is a problem with your setup, please double check everything before asking.
Multiprotocol.ino header can be modified to compile with/without some protocols, change protocols/sub_protocols associated with dial for PPM input, different channel orders, different channels timing, 8 or 16 channels serial protocol, Telemetry or not, ... _Config.h file can be modified to compile with/without some protocols, change protocols/sub_protocols/settings associated with dial for PPM input, different channel orders, different channels timing, Telemetry or not, ...
###Upload the code using ISP (In System Programming) ###Upload the code using ISP (In System Programming)
It is recommended to use an external programmer like [USBASP](http://www.banggood.com/USBASP-USBISP-3_3-5V-AVR-Downloader-Programmer-With-ATMEGA8-ATMEGA128-p-934425.html) to upload the code in the Atmega328. The programmer should be set to 3.3V or nothing to not supply any over voltage to the multimodule and avoid any damages. It is recommended to use an external programmer like [USBASP](http://www.banggood.com/USBASP-USBISP-3_3-5V-AVR-Downloader-Programmer-With-ATMEGA8-ATMEGA128-p-934425.html) to upload the code in the Atmega328. The programmer should be set to 3.3V or nothing to not supply any over voltage to the multimodule and avoid any damages.