Browse Source

move to real cpp not ardunio

master
Schoenberger, Philipp 6 years ago
parent
commit
87a7f65481
  1. 12
      Multiprotocol/FrSkyD_cc2500.cpp
  2. 25
      Multiprotocol/FrSkyD_cc2500.h
  3. 26
      Multiprotocol/FrSkyV_cc2500.cpp
  4. 39
      Multiprotocol/FrSkyV_cc2500.h
  5. 42
      Multiprotocol/FrSkyX_cc2500.cpp
  6. 37
      Multiprotocol/FrSkyX_cc2500.h
  7. 979
      Multiprotocol/Multiprotocol.h
  8. 265
      Multiprotocol/Multiprotocol.ino
  9. 211
      Multiprotocol/TX_Def.h
  10. 363
      Multiprotocol/Validate.h
  11. 66
      Multiprotocol/cc2500_spi.cpp
  12. 33
      Multiprotocol/cc2500_spi.h
  13. 217
      Multiprotocol/common.cpp
  14. 77
      Multiprotocol/common.h
  15. 235
      Multiprotocol/config.cpp
  16. 371
      Multiprotocol/config.h
  17. 6
      Multiprotocol/debug.h
  18. 77
      Multiprotocol/input.cpp
  19. 44
      Multiprotocol/input.h
  20. 38
      Multiprotocol/inputs.ino
  21. 15
      Multiprotocol/pins.h
  22. 57
      Multiprotocol/spi.cpp
  23. 38
      Multiprotocol/spi.h
  24. 98
      Multiprotocol/state.cpp
  25. 29
      Multiprotocol/state.h
  26. 217
      Multiprotocol/tx_def.h
  27. 57
      config

12
Multiprotocol/FrSkyD_cc2500.ino → Multiprotocol/FrSkyD_cc2500.cpp

@ -13,10 +13,11 @@
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if defined(FRSKYD_CC2500_INO)
#include "iface_cc2500.h"
#include "common.h"
#include "cc2500_spi.h"
#include "Multiprotocol.h"
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
void frsky2way_init(uint8_t bind)
{ {
//debugln("frsky2way_init"); //debugln("frsky2way_init");
FRSKY_init_cc2500(FRSKYD_cc2500_conf); FRSKY_init_cc2500(FRSKYD_cc2500_conf);
@ -31,7 +32,7 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
//#######END INIT######## //#######END INIT########
} }
static void __attribute__((unused)) frsky2way_build_bind_packet()
void frsky2way_build_bind_packet()
{ {
//debugln("build bind"); //debugln("build bind");
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01 //11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
@ -57,7 +58,7 @@ static void __attribute__((unused)) frsky2way_build_bind_packet()
packet[17] = 0x01; packet[17] = 0x01;
} }
static void __attribute__((unused)) frsky2way_data_frame()
void frsky2way_data_frame()
{ {
//pachet[4] is telemetry user frame counter(hub) //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 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88
@ -212,4 +213,3 @@ uint16_t ReadFrSky_2way()
} }
return state == FRSKY_DATA4 ? 7500 : 9000; return state == FRSKY_DATA4 ? 7500 : 9000;
} }
#endif

25
Multiprotocol/FrSkyD_cc2500.h

@ -0,0 +1,25 @@
/*
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/>.
*/
#ifndef _FRSKYD_CC2500_H_
#define _FRSKYD_CC2500_H_
#include <stdint.h>
void frsky2way_init(uint8_t bind);
void frsky2way_build_bind_packet();
void frsky2way_data_frame(void);
uint16_t initFrSky_2way(void);
uint16_t ReadFrSky_2way(void);
#endif

26
Multiprotocol/FrSkyV_cc2500.ino → Multiprotocol/FrSkyV_cc2500.cpp

@ -13,21 +13,12 @@
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if defined(FRSKYV_CC2500_INO)
#define FRSKYV_BIND_COUNT 200 #define FRSKYV_BIND_COUNT 200
#include "FrSkyV_cc2500.h"
#include "cc2500_spi.h"
#include "common.h"
enum {
FRSKYV_DATA1=0,
FRSKYV_DATA2,
FRSKYV_DATA3,
FRSKYV_DATA4,
FRSKYV_DATA5
};
#include "iface_cc2500.h"
static uint8_t __attribute__((unused)) FRSKYV_crc8(uint8_t result, uint8_t *data, uint8_t len)
uint8_t FRSKYV_crc8(uint8_t result, uint8_t *data, uint8_t len)
{ {
for(uint8_t i = 0; i < len; i++) for(uint8_t i = 0; i < len; i++)
{ {
@ -41,7 +32,7 @@ static uint8_t __attribute__((unused)) FRSKYV_crc8(uint8_t result, uint8_t *data
return result; return result;
} }
static uint8_t __attribute__((unused)) FRSKYV_crc8_le(uint8_t *data, uint8_t len)
uint8_t FRSKYV_crc8_le(uint8_t *data, uint8_t len)
{ {
uint8_t result = 0xD6; uint8_t result = 0xD6;
@ -57,7 +48,7 @@ static uint8_t __attribute__((unused)) FRSKYV_crc8_le(uint8_t *data, uint8_t len
return result; return result;
} }
static void __attribute__((unused)) FRSKYV_build_bind_packet()
void FRSKYV_build_bind_packet()
{ {
//0e 03 01 57 12 00 06 0b 10 15 1a 00 00 00 61 //0e 03 01 57 12 00 06 0b 10 15 1a 00 00 00 61
packet[0] = 0x0e; //Length packet[0] = 0x0e; //Length
@ -77,7 +68,7 @@ static void __attribute__((unused)) FRSKYV_build_bind_packet()
packet[14] = FRSKYV_crc8(0x93, packet, 14); packet[14] = FRSKYV_crc8(0x93, packet, 14);
} }
static uint8_t __attribute__((unused)) FRSKYV_calc_channel()
uint8_t FRSKYV_calc_channel()
{ {
uint32_t temp=seed; uint32_t temp=seed;
temp = (temp * 0xaa) % 0x7673; temp = (temp * 0xaa) % 0x7673;
@ -85,7 +76,7 @@ static uint8_t __attribute__((unused)) FRSKYV_calc_channel()
return (seed & 0xff) % 0x32; return (seed & 0xff) % 0x32;
} }
static void __attribute__((unused)) FRSKYV_build_data_packet()
void FRSKYV_build_data_packet()
{ {
uint8_t idx = 0; // transmit lower channels uint8_t idx = 0; // transmit lower channels
@ -162,4 +153,3 @@ uint16_t initFRSKYV()
return 10000; return 10000;
} }
#endif

39
Multiprotocol/FrSkyV_cc2500.h

@ -0,0 +1,39 @@
/*
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/>.
*/
#ifndef _FRSKYV_CC2500_H_
#define _FRSKYV_CC2500_H_
#define FRSKYV_BIND_COUNT 200
#include <stdint.h>
#include "Multiprotocol.h"
enum frskyv_data_e {
FRSKYV_DATA1=0,
FRSKYV_DATA2,
FRSKYV_DATA3,
FRSKYV_DATA4,
FRSKYV_DATA5
};
uint8_t FRSKYV_crc8(uint8_t result, uint8_t *data, uint8_t len);
uint8_t FRSKYV_crc8_le(uint8_t *data, uint8_t len);
void FRSKYV_build_bind_packet(void);
uint8_t FRSKYV_calc_channel(void);
void FRSKYV_build_data_packet(void);
uint16_t ReadFRSKYV(void);
uint16_t initFRSKYV(void);
#endif

42
Multiprotocol/FrSkyX_cc2500.ino → Multiprotocol/FrSkyX_cc2500.cpp

@ -15,24 +15,27 @@
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if defined(FRSKYX_CC2500_INO)
#include "iface_cc2500.h"
#include "Arduino.h"
#include "Multiprotocol.h"
#include "FrSkyX_cc2500.h"
#include <stdint.h>
#include "common.h"
#include "cc2500_spi.h"
uint8_t FrX_chanskip; uint8_t FrX_chanskip;
uint8_t FrX_send_seq ; uint8_t FrX_send_seq ;
uint8_t FrX_receive_seq ; uint8_t FrX_receive_seq ;
#define FRX_FAILSAFE_TIMEOUT 1032
static void __attribute__((unused)) frskyX_set_start(uint8_t ch )
void frskyX_set_start(uint8_t ch)
{ {
CC2500_Strobe(CC2500_SIDLE); CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]); CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]); CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
} }
static void __attribute__((unused)) frskyX_init()
void frskyX_init(void)
{ {
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
// //
@ -47,7 +50,7 @@ static void __attribute__((unused)) frskyX_init()
//#######END INIT######## //#######END INIT########
} }
static void __attribute__((unused)) frskyX_initialize_data(uint8_t adr)
void frskyX_initialize_data(uint8_t adr)
{ {
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
CC2500_WriteReg(CC2500_18_MCSM0, 0x8); CC2500_WriteReg(CC2500_18_MCSM0, 0x8);
@ -56,17 +59,19 @@ static void __attribute__((unused)) frskyX_initialize_data(uint8_t adr)
} }
//**CRC** //**CRC**
const uint16_t PROGMEM frskyX_CRC_Short[]={
const uint16_t frskyX_CRC_Short[]={
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 }; 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 };
static uint16_t __attribute__((unused)) frskyX_CRCTable(uint8_t val)
uint16_t frskyX_CRCTable(uint8_t val)
{ {
uint16_t word ; uint16_t word ;
word = pgm_read_word(&frskyX_CRC_Short[val&0x0F]) ; word = pgm_read_word(&frskyX_CRC_Short[val&0x0F]) ;
val /= 16 ; val /= 16 ;
return word ^ (0x1081 * val) ; return word ^ (0x1081 * val) ;
} }
static uint16_t __attribute__((unused)) frskyX_crc_x(uint8_t *data, uint8_t len)
uint16_t frskyX_crc_x(uint8_t *data, uint8_t len)
{ {
uint16_t crc = 0; uint16_t crc = 0;
for(uint8_t i=0; i < len; i++) for(uint8_t i=0; i < len; i++)
@ -74,7 +79,7 @@ static uint16_t __attribute__((unused)) frskyX_crc_x(uint8_t *data, uint8_t len)
return crc; return crc;
} }
static void __attribute__((unused)) frskyX_build_bind_packet()
void frskyX_build_bind_packet(void)
{ {
// debugln("%s:%d build bind", __func__, __LINE__); // debugln("%s:%d build bind", __func__, __LINE__);
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
@ -104,14 +109,14 @@ static void __attribute__((unused)) frskyX_build_bind_packet()
// 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182 // 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182
//64=860,1024=1500,1984=2140//Taranis 125% //64=860,1024=1500,1984=2140//Taranis 125%
static uint16_t __attribute__((unused)) frskyX_scaleForPXX( uint8_t i )
uint16_t frskyX_scaleForPXX(uint8_t i)
{ //mapped 860,2140(125%) range to 64,1984(PXX values); { //mapped 860,2140(125%) range to 64,1984(PXX values);
uint16_t chan_val=convert_channel_frsky(i)-1226; uint16_t chan_val=convert_channel_frsky(i)-1226;
if(i>7) chan_val|=2048; // upper channels offset if(i>7) chan_val|=2048; // upper channels offset
return chan_val; return chan_val;
} }
#ifdef FAILSAFE_ENABLE
static uint16_t __attribute__((unused)) frskyX_scaleForPXX_FS( uint8_t i )
uint16_t frskyX_scaleForPXX_FS(uint8_t i)
{ //mapped 1,2046(125%) range to 64,1984(PXX values); { //mapped 1,2046(125%) range to 64,1984(PXX values);
uint16_t chan_val=((Failsafe_data[i]*15)>>4)+64; uint16_t chan_val=((Failsafe_data[i]*15)>>4)+64;
if(Failsafe_data[i]==FAILSAFE_CHANNEL_NOPULSES) if(Failsafe_data[i]==FAILSAFE_CHANNEL_NOPULSES)
@ -121,10 +126,8 @@ static uint16_t __attribute__((unused)) frskyX_scaleForPXX_FS( uint8_t i )
if(i>7) chan_val|=2048; // upper channels offset if(i>7) chan_val|=2048; // upper channels offset
return chan_val; return chan_val;
} }
#endif
#define FRX_FAILSAFE_TIME 1032
static void __attribute__((unused)) frskyX_data_frame()
void frskyX_data_frame(void)
{ {
//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 //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
// //
@ -232,7 +235,7 @@ static void __attribute__((unused)) frskyX_data_frame()
packet[limit]=lcrc;//low byte packet[limit]=lcrc;//low byte
} }
uint16_t ReadFrSkyX()
uint16_t ReadFrSkyX(void)
{ {
switch(state) switch(state)
{ {
@ -323,7 +326,7 @@ uint16_t ReadFrSkyX()
return 1; return 1;
} }
uint16_t initFrSkyX()
uint16_t initFrSkyX(void)
{ {
set_rx_tx_addr(MProtocol_id_master); set_rx_tx_addr(MProtocol_id_master);
Frsky_init_hop(); Frsky_init_hop();
@ -358,4 +361,3 @@ uint16_t initFrSkyX()
FrX_receive_seq = 0 ; FrX_receive_seq = 0 ;
return 10000; return 10000;
} }
#endif

37
Multiprotocol/FrSkyX_cc2500.h

@ -0,0 +1,37 @@
/* **************************
* By Midelic on RCGroups *
**************************
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/>.
*/
#ifndef _FRSKYX_CC2500_H_
#define _FRSKYX_CC2500_H_
#include <stdint.h>
#define FRX_FAILSAFE_TIMEOUT 1032
#define FRX_FAILSAFE_TIME 1032
void frskyX_set_start(uint8_t ch);
void frskyX_init(void);
void frskyX_initialize_data(uint8_t adr);
uint16_t frskyX_CRCTable(uint8_t val);
uint16_t frskyX_crc_x(uint8_t *data, uint8_t len);
void frskyX_build_bind_packet(void);
uint16_t frskyX_scaleForPXX(uint8_t i);
uint16_t frskyX_scaleForPXX_FS(uint8_t i);
void frskyX_data_frame(void);
uint16_t ReadFrSkyX(void);
uint16_t initFrSkyX(void);
#endif

979
Multiprotocol/Multiprotocol.h
File diff suppressed because it is too large
View File

265
Multiprotocol/Multiprotocol.ino

@ -32,32 +32,36 @@
#include "MultiOrange.h" #include "MultiOrange.h"
#endif #endif
#include "config.h"
#include "tx_def.h"
#include "Multiprotocol.h" #include "Multiprotocol.h"
//Multiprotocol module configuration file //Multiprotocol module configuration file
#include "_Config.h"
#include "Pins.h"
#include "TX_Def.h"
#include "pins.h"
#include "Validate.h" #include "Validate.h"
#include "common.h"
#include "state.h" #include "state.h"
#include "input.h"
#include "cc2500_spi.h"
#include "FrSkyX_cc2500.h"
#include "FrSkyV_cc2500.h"
#include "FrSkyD_cc2500.h"
//Global constants/variables //Global constants/variables
uint32_t MProtocol_id;//tx id, uint32_t MProtocol_id;//tx id,
uint32_t MProtocol_id_master; uint32_t MProtocol_id_master;
uint32_t blink=0,last_signal=0; uint32_t blink=0,last_signal=0;
uint8_t protocol_flags=0,protocol_flags2=0;
// //
uint16_t counter; uint16_t counter;
uint8_t channel; uint8_t channel;
uint8_t packet[40]; uint8_t packet[40];
#define NUM_CHN 16
// Servo data // Servo data
uint16_t Channel_data[NUM_CHN]; uint16_t Channel_data[NUM_CHN];
uint8_t Channel_AUX; uint8_t Channel_AUX;
#ifdef FAILSAFE_ENABLE
uint16_t Failsafe_data[NUM_CHN];
#endif
// Protocol variables // Protocol variables
uint8_t cyrfmfg_id[6];//for dsm2 and devo uint8_t cyrfmfg_id[6];//for dsm2 and devo
@ -96,7 +100,6 @@ const uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, CH5, CH6, CH7, CH8
// Mode_select variables // Mode_select variables
uint8_t mode_select; uint8_t mode_select;
uint8_t protocol_flags=0,protocol_flags2=0;
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
// PPM variable // PPM variable
@ -126,7 +129,6 @@ volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
volatile uint8_t discard_frame = 0; volatile uint8_t discard_frame = 0;
// Telemetry // Telemetry
#define MAX_PKT 29
uint8_t pkt[MAX_PKT];//telemetry receiving packets uint8_t pkt[MAX_PKT];//telemetry receiving packets
float TIMER_PRESCALE = 5.82; float TIMER_PRESCALE = 5.82;
// Callback // Callback
@ -140,8 +142,8 @@ void setup()
#ifdef DEBUG_SERIAL #ifdef DEBUG_SERIAL
Serial.begin(115200,SERIAL_8N1); Serial.begin(115200,SERIAL_8N1);
while (!Serial); // Wait for ever for the serial port to connect... while (!Serial); // Wait for ever for the serial port to connect...
debugln("Multiprotocol version: %d.%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_PATCH_LEVEL);
debugln("time %s ", __TIME__);
debugln("Multiprotocol startup");
debugln("time %s ", __TIME__);
#endif #endif
// General pinout // General pinout
@ -307,7 +309,7 @@ void setup()
else else
#endif //ENABLE_PPM #endif //ENABLE_PPM
debugln("Init complete"); debugln("Init complete");
update_inputs();
input.update();
init_state(); init_state();
} }
@ -315,121 +317,55 @@ void setup()
// Protocol scheduler // Protocol scheduler
void loop() void loop()
{ {
uint32_t next_callback;
uint16_t diff=0xFFFF;
uint32_t end__ = micros();
uint32_t start = micros();
if(remote_callback==0 || IS_WAIT_BIND_on || diff>2*200)
{
do
{
Update_All();
}
while(remote_callback==0 || IS_WAIT_BIND_on);
}
while(1)
{
#if 0
if( (TIFR1 & OCF1A_bm) != 0)
{
cli(); // Disable global int due to RW of 16 bits registers
OCR1A=TCNT1; // Callback should already have been called... Use "now" as new sync point.
sei(); // Enable global int
}
else
while((TIFR1 & OCF1A_bm) == 0); // Wait before callback
uint32_t next_callback;
#endif
if(remote_callback==0 || IS_WAIT_BIND_on ) {
do {
Update_All();
} while(remote_callback==0 || IS_WAIT_BIND_on);
}
uint32_t end__ = micros();
uint32_t start = micros();
end__ = micros();
do
{
//TX_MAIN_PAUSE_on;
//tx_pause();
start = end__;
next_callback=remote_callback();
while(1) {
start = end__;
next_callback = remote_callback();
#if 0
TX_MAIN_PAUSE_off;
tx_resume();
while(next_callback>4000)
{ // start to wait here as much as we can...
next_callback-=2000; // We will wait below for 2ms
cli(); // Disable global int due to RW of 16 bits registers
OCR1A += 2000 * TIMER_PRESCALE; // set compare A for callback
TIFR1=OCF1A_bm; // clear compare A=callback flag
sei(); // enable global int
if(Update_All()) // Protocol changed?
{
next_callback=0; // Launch new protocol ASAP
break;
}
while((TIFR1 & OCF1A_bm) == 0); // wait 2ms...
}
// at this point we have a maximum of 4ms in next_callback
cli(); // Disable global int due to RW of 16 bits registers
OCR1A+= next_callback*TIMER_PRESCALE ; // set compare A for callback
TIFR1=OCF1A_bm; // clear compare A=callback flag
diff=OCR1A-TCNT1; // compare timer and comparator
sei(); // enable global int
#else
if (next_callback > 4000) {
input.update();
update_state();
}
if (next_callback > 4000) {
update_inputs();
update_state();
}
uint32_t wait_until = start + next_callback;
end__ = micros();
if (end__-start < next_callback) {
uint32_t wait = next_callback;
wait -= ((end__-start));
//wait -= 1000;
delayMicroseconds(wait);
//debugln("%lu vs %lu",wait,next_callback);
/*
debugln("took %lu (%lu - %lu) vs %lu wait %lu wait until %lu",
end__-start, start, end__,
next_callback,
wait, wait_until);
*/
end__ += wait;
}
#endif
end__ = micros();
//debugln("%lu vs %lu",end__-start,next_callback);
//debugln("next %d diff %lu (%lu to %lu) diff %x ",org_next_call, end__ - start_, end__, start_, diff);
uint32_t wait_until = start + next_callback;
end__ = micros();
if (end__-start < next_callback) {
uint32_t wait = next_callback;
wait -= ((end__-start));
delayMicroseconds(wait);
end__ += wait;
} }
while(diff&0x8000); // Callback did not took more than requested time for next callback
// so we can launch Update_All before next callback
end__ = micros();
} }
} }
uint8_t Update_All() uint8_t Update_All()
{ {
#ifdef ENABLE_SERIAL #ifdef ENABLE_SERIAL
#ifdef CHECK_FOR_BOOTLOADER
if ( (mode_select==MODE_SERIAL) && (NotBootChecking == 0) )
pollBoot() ;
else
#endif
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
{ {
update_serial_data(); // Update protocol and data update_serial_data(); // Update protocol and data
update_channels_aux(); update_channels_aux();
INPUT_SIGNAL_on; //valid signal received
last_signal=millis(); last_signal=millis();
} }
#endif //ENABLE_SERIAL #endif //ENABLE_SERIAL
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
{ {
debugln("%s:%d",__func__, __LINE__);
for(uint8_t i=0;i<PPM_chan_max;i++)
{ // update servo data without interrupts to prevent bad read
debugln("%s:%d",__func__, __LINE__);
for(uint8_t i=0;i<PPM_chan_max;i++) {
// update servo data without interrupts to prevent bad read
uint16_t val; uint16_t val;
cli(); // disable global int cli(); // disable global int
val = PPM_data[i]; val = PPM_data[i];
@ -441,7 +377,6 @@ uint8_t Update_All()
} }
PPM_FLAG_off; // wait for next frame before update PPM_FLAG_off; // wait for next frame before update
update_channels_aux(); update_channels_aux();
INPUT_SIGNAL_on; // valid signal received
last_signal=millis(); last_signal=millis();
} }
#endif //ENABLE_PPM #endif //ENABLE_PPM
@ -470,14 +405,12 @@ uint8_t Update_All()
} }
#endif //ENABLE_BIND_CH #endif //ENABLE_BIND_CH
update_inputs();
input.update();
if(IS_CHANGE_PROTOCOL_FLAG_on) if(IS_CHANGE_PROTOCOL_FLAG_on)
{ {
debugln("%s:%d set bind prog",__func__, __LINE__);
// Protocol needs to be changed or relaunched for bind
debugln("%s:%d set bind prog",__func__, __LINE__);
// Protocol needs to be changed or relaunched for bind
protocol_init(); //init new protocol protocol_init(); //init new protocol
return 1; return 1;
} }
@ -641,26 +574,18 @@ static void protocol_init()
switch(protocol) // Init the requested protocol switch(protocol) // Init the requested protocol
{ {
#ifdef CC2500_INSTALLED
#if defined(FRSKYD_CC2500_INO)
case PROTO_FRSKYD:
next_callback = initFrSky_2way();
remote_callback = ReadFrSky_2way;
break;
#endif
#if defined(FRSKYV_CC2500_INO)
case PROTO_FRSKYV:
next_callback = initFRSKYV();
remote_callback = ReadFRSKYV;
break;
#endif
#if defined(FRSKYX_CC2500_INO)
case PROTO_FRSKYX:
next_callback = initFrSkyX();
remote_callback = ReadFrSkyX;
break;
#endif
#endif
case PROTO_FRSKYD:
next_callback = initFrSky_2way();
remote_callback = ReadFrSky_2way;
break;
case PROTO_FRSKYV:
next_callback = initFRSKYV();
remote_callback = ReadFRSKYV;
break;
case PROTO_FRSKYX:
next_callback = initFrSkyX();
remote_callback = ReadFrSkyX;
break;
} }
} }
@ -889,84 +814,10 @@ void modules_reset()
} }
#endif #endif
#ifdef CHECK_FOR_BOOTLOADER
void pollBoot()
{
uint8_t rxchar ;
uint8_t lState = BootState ;
uint8_t millisTime = millis(); // Call this once only
#ifdef ORANGE_TX
if ( USARTC0.STATUS & USART_RXCIF_bm )
#elif defined STM32_BOARD
if ( USART2_BASE->SR & USART_SR_RXNE )
#else
if ( UCSR0A & ( 1 << RXC0 ) )
#endif
{
rxchar = UDR0 ;
BootCount += 1 ;
if ( ( lState == BOOT_WAIT_30_IDLE ) || ( lState == BOOT_WAIT_30_DATA ) )
{
if ( lState == BOOT_WAIT_30_IDLE ) // Waiting for 0x30
BootTimer = millisTime ; // Start timeout
if ( rxchar == 0x30 )
lState = BOOT_WAIT_20 ;
else
lState = BOOT_WAIT_30_DATA ;
}
else
if ( lState == BOOT_WAIT_20 && rxchar == 0x20 ) // Waiting for 0x20
lState = BOOT_READY ;
}
else // No byte received
{
if ( lState != BOOT_WAIT_30_IDLE ) // Something received
{
uint8_t time = millisTime - BootTimer ;
if ( time > 5 )
{
#ifdef STM32_BOARD
if ( BootCount > 4 )
#else
if ( BootCount > 2 )
#endif
{ // Run normally
NotBootChecking = 0xFF ;
Mprotocol_serial_init( 0 ) ;
}
else if ( lState == BOOT_READY )
{
#ifdef STM32_BOARD
nvic_sys_reset();
while(1); /* wait until reset */
#else
cli(); // Disable global int due to RW of 16 bits registers
void (*p)();
#ifndef ORANGE_TX
p = (void (*)())0x3F00 ; // Word address (0x7E00 byte)
#else
p = (void (*)())0x4000 ; // Word address (0x8000 byte)
#endif
(*p)() ; // go to boot
#endif
}
else
{
lState = BOOT_WAIT_30_IDLE ;
BootCount = 0 ;
}
}
}
}
BootState = lState ;
}
#endif //CHECK_FOR_BOOTLOADER
#if defined(TELEMETRY) #if defined(TELEMETRY)
void PPM_Telemetry_serial_init() void PPM_Telemetry_serial_init()
{ {
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS))
if( (protocol==PROTO_FRSKYD))
initTXSerial( SPEED_9600 ) ; initTXSerial( SPEED_9600 ) ;
if(protocol==PROTO_FRSKYX) if(protocol==PROTO_FRSKYX)
initTXSerial( SPEED_57600 ) ; initTXSerial( SPEED_57600 ) ;
@ -976,7 +827,7 @@ void PPM_Telemetry_serial_init()
#endif #endif
// Convert 32b id to rx_tx_addr // Convert 32b id to rx_tx_addr
static void set_rx_tx_addr(uint32_t id)
void set_rx_tx_addr(uint32_t id)
{ // Used by almost all protocols { // Used by almost all protocols
rx_tx_addr[0] = (id >> 24) & 0xFF; rx_tx_addr[0] = (id >> 24) & 0xFF;
rx_tx_addr[1] = (id >> 16) & 0xFF; rx_tx_addr[1] = (id >> 16) & 0xFF;
@ -985,7 +836,7 @@ static void set_rx_tx_addr(uint32_t id)
rx_tx_addr[4] = (rx_tx_addr[2]&0xF0)|(rx_tx_addr[3]&0x0F); rx_tx_addr[4] = (rx_tx_addr[2]&0xF0)|(rx_tx_addr[3]&0x0F);
} }
static uint32_t random_id(uint16_t address, uint8_t create_new)
uint32_t random_id(uint16_t address, uint8_t create_new)
{ {
#ifndef FORCE_GLOBAL_ID #ifndef FORCE_GLOBAL_ID
uint32_t id=0; uint32_t id=0;

211
Multiprotocol/TX_Def.h

@ -1,211 +0,0 @@
// Turnigy PPM and channels
#if defined(TX_ER9X)
#define PPM_MAX_100 2012 // 100%
#define PPM_MIN_100 988 // 100%
#endif
// Devo PPM and channels
#if defined(TX_DEVO7)
#define PPM_MAX_100 1920 // 100%
#define PPM_MIN_100 1120 // 100%
#endif
// SPEKTRUM PPM and channels
#if defined(TX_SPEKTRUM)
#define PPM_MAX_100 1900 // 100%
#define PPM_MIN_100 1100 // 100%
#endif
// HISKY
#if defined(TX_HISKY)
#define PPM_MAX_100 1920 // 100%
#define PPM_MIN_100 1120 // 100%
#endif
// Multiplex MC2020
#if defined(TX_MPX)
#define PPM_MAX_100 1950 // 100%
#define PPM_MIN_100 1250 // 100%
#endif
// Walkera PL0811-01H
#if defined(TX_WALKERA)
#define PPM_MAX_100 1800 // 100%
#define PPM_MIN_100 1000 // 100%
#endif
//Channel MIN MAX values
#define CHANNEL_MAX_100 1844 // 100%
#define CHANNEL_MIN_100 204 // 100%
#define CHANNEL_MAX_125 2047 // 125%
#define CHANNEL_MIN_125 0 // 125%
#define CHANNEL_MIN_COMMAND 784 // 1350us
#define CHANNEL_SWITCH 1104 // 1550us
#define CHANNEL_MAX_COMMAND 1424 // 1750us
//Channel definitions
#ifdef AETR
#define AILERON 0
#define ELEVATOR 1
#define THROTTLE 2
#define RUDDER 3
#endif
#ifdef AERT
#define AILERON 0
#define ELEVATOR 1
#define THROTTLE 3
#define RUDDER 2
#endif
#ifdef ARET
#define AILERON 0
#define ELEVATOR 2
#define THROTTLE 3
#define RUDDER 1
#endif
#ifdef ARTE
#define AILERON 0
#define ELEVATOR 3
#define THROTTLE 2
#define RUDDER 1
#endif
#ifdef ATRE
#define AILERON 0
#define ELEVATOR 3
#define THROTTLE 1
#define RUDDER 2
#endif
#ifdef ATER
#define AILERON 0
#define ELEVATOR 2
#define THROTTLE 1
#define RUDDER 3
#endif
#ifdef EATR
#define AILERON 1
#define ELEVATOR 0
#define THROTTLE 2
#define RUDDER 3
#endif
#ifdef EART
#define AILERON 1
#define ELEVATOR 0
#define THROTTLE 3
#define RUDDER 2
#endif
#ifdef ERAT
#define AILERON 2
#define ELEVATOR 0
#define THROTTLE 3
#define RUDDER 1
#endif
#ifdef ERTA
#define AILERON 3
#define ELEVATOR 0
#define THROTTLE 2
#define RUDDER 1
#endif
#ifdef ETRA
#define AILERON 3
#define ELEVATOR 0
#define THROTTLE 1
#define RUDDER 2
#endif
#ifdef ETAR
#define AILERON 2
#define ELEVATOR 0
#define THROTTLE 1
#define RUDDER 3
#endif
#ifdef TEAR
#define AILERON 2
#define ELEVATOR 1
#define THROTTLE 0
#define RUDDER 3
#endif
#ifdef TERA
#define AILERON 3
#define ELEVATOR 1
#define THROTTLE 0
#define RUDDER 2
#endif
#ifdef TREA
#define AILERON 3
#define ELEVATOR 2
#define THROTTLE 0
#define RUDDER 1
#endif
#ifdef TRAE
#define AILERON 2
#define ELEVATOR 3
#define THROTTLE 0
#define RUDDER 1
#endif
#ifdef TARE
#define AILERON 1
#define ELEVATOR 3
#define THROTTLE 0
#define RUDDER 2
#endif
#ifdef TAER
#define AILERON 1
#define ELEVATOR 2
#define THROTTLE 0
#define RUDDER 3
#endif
#ifdef RETA
#define AILERON 3
#define ELEVATOR 1
#define THROTTLE 2
#define RUDDER 0
#endif
#ifdef REAT
#define AILERON 2
#define ELEVATOR 1
#define THROTTLE 3
#define RUDDER 0
#endif
#ifdef RAET
#define AILERON 1
#define ELEVATOR 2
#define THROTTLE 3
#define RUDDER 0
#endif
#ifdef RATE
#define AILERON 1
#define ELEVATOR 3
#define THROTTLE 2
#define RUDDER 0
#endif
#ifdef RTAE
#define AILERON 2
#define ELEVATOR 3
#define THROTTLE 1
#define RUDDER 0
#endif
#ifdef RTEA
#define AILERON 3
#define ELEVATOR 2
#define THROTTLE 1
#define RUDDER 0
#endif
#define CH1 0
#define CH2 1
#define CH3 2
#define CH4 3
#define CH5 4
#define CH6 5
#define CH7 6
#define CH8 7
#define CH9 8
#define CH10 9
#define CH11 10
#define CH12 11
#define CH13 12
#define CH14 13
#define CH15 14
#define CH16 15

363
Multiprotocol/Validate.h

@ -1,21 +1,26 @@
#ifndef _VALIDATE_H_
#define _VALIDATE_H_
#include "config.h"
#include "tx_def.h"
// Check selected board type // Check selected board type
#if defined (STM32_BOARD) && defined (ORANGE_TX) #if defined (STM32_BOARD) && defined (ORANGE_TX)
#error You must comment the board type STM32_BOARD in _Config.h to compile ORANGE_TX
#error You must comment the board type STM32_BOARD in _Config.h to compile ORANGE_TX
#endif #endif
#if not defined (ORANGE_TX) && not defined (STM32_BOARD) #if not defined (ORANGE_TX) && not defined (STM32_BOARD)
//Atmega328p
#if (not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_LEONARDO) )&& not defined(ARDUINO_MULTI_NO_BOOT) && not defined(ARDUINO_MULTI_FLASH_FROM_TX) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
#warning You must select one of these boards: "Multi 4-in-1", "Arduino Pro or Pro Mini" or "Arduino Mini"
#endif
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__) || not defined(__AVR_ATmega32U4__)
#warning You must select the processor type "ATmega328(5V, 16MHz)"
#endif
//Atmega328p
#if (not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_LEONARDO) )&& not defined(ARDUINO_MULTI_NO_BOOT) && not defined(ARDUINO_MULTI_FLASH_FROM_TX) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
#warning You must select one of these boards: "Multi 4-in-1", "Arduino Pro or Pro Mini" or "Arduino Mini"
#endif
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__) || not defined(__AVR_ATmega32U4__)
#warning You must select the processor type "ATmega328(5V, 16MHz)"
#endif
#endif #endif
#if defined (STM32_BOARD) && not defined (ORANGE_TX) #if defined (STM32_BOARD) && not defined (ORANGE_TX)
//STM32
#if not defined(ARDUINO_GENERIC_STM32F103C) && not defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX) && not defined(ARDUINO_MULTI_STM32_NO_BOOT) && not defined(ARDUINO_MULTI_STM32_WITH_BOOT)
#error You must select one of these boards: "Multi 4-in-1 (STM32F103CB)" or "Generic STM32F103C series"
#endif
//STM32
#if not defined(ARDUINO_GENERIC_STM32F103C) && not defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX) && not defined(ARDUINO_MULTI_STM32_NO_BOOT) && not defined(ARDUINO_MULTI_STM32_WITH_BOOT)
#error You must select one of these boards: "Multi 4-in-1 (STM32F103CB)" or "Generic STM32F103C series"
#endif
#endif #endif
// Check for minimum version of multi-module boards // Check for minimum version of multi-module boards
@ -24,251 +29,253 @@
#define MIN_STM32_BOARD 104 #define MIN_STM32_BOARD 104
//AVR //AVR
#if (defined(ARDUINO_MULTI_NO_BOOT) && ARDUINO_MULTI_NO_BOOT < MIN_AVR_BOARD) || (defined(ARDUINO_MULTI_FLASH_FROM_TX) && ARDUINO_MULTI_FLASH_FROM_TX < MIN_AVR_BOARD) #if (defined(ARDUINO_MULTI_NO_BOOT) && ARDUINO_MULTI_NO_BOOT < MIN_AVR_BOARD) || (defined(ARDUINO_MULTI_FLASH_FROM_TX) && ARDUINO_MULTI_FLASH_FROM_TX < MIN_AVR_BOARD)
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
#endif #endif
//OrangeRX //OrangeRX
#if (defined(ARDUINO_MULTI_ORANGERX) && ARDUINO_MULTI_ORANGERX < MIN_ORX_BOARD) #if (defined(ARDUINO_MULTI_ORANGERX) && ARDUINO_MULTI_ORANGERX < MIN_ORX_BOARD)
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
#endif #endif
//STM32 //STM32
#if (defined(ARDUINO_MULTI_STM32_NO_BOOT) && ARDUINO_MULTI_STM32_NO_BOOT < MIN_STM32_BOARD) || (defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX) && ARDUINO_MULTI_STM32_FLASH_FROM_TX < MIN_STM32_BOARD) || (defined(ARDUINO_MULTI_STM32_WITH_BOOT) && ARDUINO_MULTI_STM32_WITH_BOOT < MIN_STM32_BOARD) #if (defined(ARDUINO_MULTI_STM32_NO_BOOT) && ARDUINO_MULTI_STM32_NO_BOOT < MIN_STM32_BOARD) || (defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX) && ARDUINO_MULTI_STM32_FLASH_FROM_TX < MIN_STM32_BOARD) || (defined(ARDUINO_MULTI_STM32_WITH_BOOT) && ARDUINO_MULTI_STM32_WITH_BOOT < MIN_STM32_BOARD)
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 STM32 Board.
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 STM32 Board.
#endif #endif
// Error if CHECK_FOR_BOOTLOADER is not enabled but a FLASH_FROM_TX board is selected // Error if CHECK_FOR_BOOTLOADER is not enabled but a FLASH_FROM_TX board is selected
#if (defined(ARDUINO_MULTI_FLASH_FROM_TX) || defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX)) &! defined(CHECK_FOR_BOOTLOADER) #if (defined(ARDUINO_MULTI_FLASH_FROM_TX) || defined(ARDUINO_MULTI_STM32_FLASH_FROM_TX)) &! defined(CHECK_FOR_BOOTLOADER)
#if defined(STM32_BOARD)
#error "You have selected the 'Flash from TX' upload method but not enabled CHECK_FOR_BOOTLOADER."
#else
#error "You have selected the 'Flash from TX' bootloader but not enabled CHECK_FOR_BOOTLOADER."
#endif
#if defined(STM32_BOARD)
#error "You have selected the 'Flash from TX' upload method but not enabled CHECK_FOR_BOOTLOADER."
#else
#error "You have selected the 'Flash from TX' bootloader but not enabled CHECK_FOR_BOOTLOADER."
#endif
#endif #endif
// Error if CHECK_FOR_BOOTLOADER is enabled but the 'Flash from TX' bootloader // Error if CHECK_FOR_BOOTLOADER is enabled but the 'Flash from TX' bootloader
#if defined(ARDUINO_MULTI_NO_BOOT) && defined(CHECK_FOR_BOOTLOADER) #if defined(ARDUINO_MULTI_NO_BOOT) && defined(CHECK_FOR_BOOTLOADER)
#error "You have enabled CHECK_FOR_BOOTLOADER but not selected the 'Flash from TX' bootloader."
#error "You have enabled CHECK_FOR_BOOTLOADER but not selected the 'Flash from TX' bootloader."
#endif #endif
//Check number of banks //Check number of banks
#if NBR_BANKS < 1 || NBR_BANKS > 5 #if NBR_BANKS < 1 || NBR_BANKS > 5
#error "You need to select a number of banks between 1 and 5."
#error "You need to select a number of banks between 1 and 5."
#endif #endif
//Check failsafe throttle value //Check failsafe throttle value
#ifdef FAILSAFE_ENABLE #ifdef FAILSAFE_ENABLE
#if ( FAILSAFE_THROTTLE_LOW < -125 ) || ( FAILSAFE_THROTTLE_LOW > 125 )
#error "The failsafe value for throttle is outside of the range -125..125."
#endif
#if ( FAILSAFE_THROTTLE_LOW < -125 ) || ( FAILSAFE_THROTTLE_LOW > 125 )
#error "The failsafe value for throttle is outside of the range -125..125."
#endif
#endif #endif
// Check forced tuning values are valid // Check forced tuning values are valid
#ifdef FORCE_FRSKYD_TUNING #ifdef FORCE_FRSKYD_TUNING
#if ( FORCE_FRSKYD_TUNING < -127 ) || ( FORCE_FRSKYD_TUNING > 127 )
#error "The FrSkyD forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_FRSKYD_TUNING < -127 ) || ( FORCE_FRSKYD_TUNING > 127 )
#error "The FrSkyD forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_FRSKYV_TUNING #ifdef FORCE_FRSKYV_TUNING
#if ( FORCE_FRSKYV_TUNING < -127 ) || ( FORCE_FRSKYV_TUNING > 127 )
#error "The FrSkyV forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_FRSKYV_TUNING < -127 ) || ( FORCE_FRSKYV_TUNING > 127 )
#error "The FrSkyV forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_FRSKYX_TUNING #ifdef FORCE_FRSKYX_TUNING
#if ( FORCE_FRSKYX_TUNING < -127 ) || ( FORCE_FRSKYX_TUNING > 127 )
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_FRSKYX_TUNING < -127 ) || ( FORCE_FRSKYX_TUNING > 127 )
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_SFHSS_TUNING #ifdef FORCE_SFHSS_TUNING
#if ( FORCE_SFHSS_TUNING < -127 ) || ( FORCE_SFHSS_TUNING > 127 )
#error "The SFHSS forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_SFHSS_TUNING < -127 ) || ( FORCE_SFHSS_TUNING > 127 )
#error "The SFHSS forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_CORONA_TUNING #ifdef FORCE_CORONA_TUNING
#if ( FORCE_CORONA_TUNING < -127 ) || ( FORCE_CORONA_TUNING > 127 )
#error "The CORONA forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_CORONA_TUNING < -127 ) || ( FORCE_CORONA_TUNING > 127 )
#error "The CORONA forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_HITEC_TUNING #ifdef FORCE_HITEC_TUNING
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
#endif
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
#endif
#endif #endif
#ifdef FORCE_FLYSKY_TUNING #ifdef FORCE_FLYSKY_TUNING
#if ( FORCE_FLYSKY_TUNING < -300 ) || ( FORCE_FLYSKY_TUNING > 300 )
#error "The Flysky forced frequency tuning value is outside of the range -300..300."
#endif
#if ( FORCE_FLYSKY_TUNING < -300 ) || ( FORCE_FLYSKY_TUNING > 300 )
#error "The Flysky forced frequency tuning value is outside of the range -300..300."
#endif
#endif #endif
#ifdef FORCE_HUBSAN_TUNING #ifdef FORCE_HUBSAN_TUNING
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
#endif
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
#endif
#endif #endif
#ifdef FORCE_AFHDS2A_TUNING #ifdef FORCE_AFHDS2A_TUNING
#if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
#error "The AFHDS2A forced frequency tuning value is outside of the range -300..300."
#endif
#if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
#error "The AFHDS2A forced frequency tuning value is outside of the range -300..300."
#endif
#endif #endif
#ifndef USE_A7105_CH15_TUNING #ifndef USE_A7105_CH15_TUNING
#ifndef FORCE_FLYSKY_TUNING
#define FORCE_FLYSKY_TUNING 0
#endif
#ifndef FORCE_HUBSAN_TUNING
#define FORCE_HUBSAN_TUNING 0
#endif
#ifndef FORCE_AFHDS2A_TUNING
#define FORCE_AFHDS2A_TUNING 0
#endif
#ifndef FORCE_FLYSKY_TUNING
#define FORCE_FLYSKY_TUNING 0
#endif
#ifndef FORCE_HUBSAN_TUNING
#define FORCE_HUBSAN_TUNING 0
#endif
#ifndef FORCE_AFHDS2A_TUNING
#define FORCE_AFHDS2A_TUNING 0
#endif
#endif #endif
//Change/Force configuration if OrangeTX //Change/Force configuration if OrangeTX
#ifdef ORANGE_TX #ifdef ORANGE_TX
#undef ENABLE_PPM // Disable PPM for OrangeTX module
#undef A7105_INSTALLED // Disable A7105 for OrangeTX module
#undef A7105_CSN_pin
#undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module
#undef CC25_CSN_pin
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
#undef NRF_CSN_pin
#define TELEMETRY // Enable telemetry
#define INVERT_TELEMETRY // Enable invert telemetry
#define DSM_TELEMETRY // Enable DSM telemetry
#undef ENABLE_PPM // Disable PPM for OrangeTX module
#undef A7105_INSTALLED // Disable A7105 for OrangeTX module
#undef A7105_CSN_pin
#undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module
#undef CC25_CSN_pin
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
#undef NRF_CSN_pin
#define TELEMETRY // Enable telemetry
#define INVERT_TELEMETRY // Enable invert telemetry
#define DSM_TELEMETRY // Enable DSM telemetry
#endif #endif
//Make sure protocols are selected correctly //Make sure protocols are selected correctly
#ifndef A7105_INSTALLED #ifndef A7105_INSTALLED
#undef FLYSKY_A7105_INO
#undef HUBSAN_A7105_INO
#undef AFHDS2A_A7105_INO
#undef BUGS_A7105_INO
#undef FLYSKY_A7105_INO
#undef HUBSAN_A7105_INO
#undef AFHDS2A_A7105_INO
#undef BUGS_A7105_INO
#endif #endif
#ifndef CYRF6936_INSTALLED #ifndef CYRF6936_INSTALLED
#undef DEVO_CYRF6936_INO
#undef DSM_CYRF6936_INO
#undef J6PRO_CYRF6936_INO
#undef WFLY_CYRF6936_INO
#undef WK2x01_CYRF6936_INO
#undef DEVO_CYRF6936_INO
#undef DSM_CYRF6936_INO
#undef J6PRO_CYRF6936_INO
#undef WFLY_CYRF6936_INO
#undef WK2x01_CYRF6936_INO
#endif #endif
#ifndef CC2500_INSTALLED #ifndef CC2500_INSTALLED
#undef FRSKYD_CC2500_INO
#undef FRSKYV_CC2500_INO
#undef FRSKYX_CC2500_INO
#undef SFHSS_CC2500_INO
#undef CORONA_CC2500_INO
#undef HITEC_CC2500_INO
#undef FRSKYD_CC2500_INO
#undef FRSKYV_CC2500_INO
#undef FRSKYX_CC2500_INO
#undef SFHSS_CC2500_INO
#undef CORONA_CC2500_INO
#undef HITEC_CC2500_INO
#endif #endif
#ifndef NRF24L01_INSTALLED #ifndef NRF24L01_INSTALLED
#undef BAYANG_NRF24L01_INO
#undef CG023_NRF24L01_INO
#undef CX10_NRF24L01_INO
#undef ESKY_NRF24L01_INO
#undef HISKY_NRF24L01_INO
#undef KN_NRF24L01_INO
#undef SLT_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
#undef V2X2_NRF24L01_INO
#undef YD717_NRF24L01_INO
#undef MT99XX_NRF24L01_INO
#undef MJXQ_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef FY326_NRF24L01_INO
#undef FQ777_NRF24L01_INO
#undef ASSAN_NRF24L01_INO
#undef HONTAI_NRF24L01_INO
#undef Q303_NRF24L01_INO
#undef GW008_NRF24L01_INO
#undef DM002_NRF24L01_INO
#undef CABELL_NRF24L01_INO
#undef ESKY150_NRF24L01_INO
#undef H8_3D_NRF24L01_INO
#undef CFLIE_NRF24L01_INO
#undef BAYANG_NRF24L01_INO
#undef CG023_NRF24L01_INO
#undef CX10_NRF24L01_INO
#undef ESKY_NRF24L01_INO
#undef HISKY_NRF24L01_INO
#undef KN_NRF24L01_INO
#undef SLT_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
#undef V2X2_NRF24L01_INO
#undef YD717_NRF24L01_INO
#undef MT99XX_NRF24L01_INO
#undef MJXQ_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef FY326_NRF24L01_INO
#undef FQ777_NRF24L01_INO
#undef ASSAN_NRF24L01_INO
#undef HONTAI_NRF24L01_INO
#undef Q303_NRF24L01_INO
#undef GW008_NRF24L01_INO
#undef DM002_NRF24L01_INO
#undef CABELL_NRF24L01_INO
#undef ESKY150_NRF24L01_INO
#undef H8_3D_NRF24L01_INO
#undef CFLIE_NRF24L01_INO
#endif #endif
//Make sure telemetry is selected correctly //Make sure telemetry is selected correctly
#ifndef TELEMETRY #ifndef TELEMETRY
#undef INVERT_TELEMETRY
#undef AFHDS2A_FW_TELEMETRY
#undef AFHDS2A_HUB_TELEMETRY
#undef HITEC_FW_TELEMETRY
#undef HITEC_HUB_TELEMETRY
#undef BAYANG_HUB_TELEMETRY
#undef CABELL_HUB_TELEMETRY
#undef HUBSAN_HUB_TELEMETRY
#undef BUGS_HUB_TELEMETRY
#undef HUB_TELEMETRY
#undef SPORT_TELEMETRY
#undef SPORT_POLLING
#undef DSM_TELEMETRY
#undef MULTI_STATUS
#undef MULTI_TELEMETRY
#undef INVERT_TELEMETRY
#undef AFHDS2A_FW_TELEMETRY
#undef AFHDS2A_HUB_TELEMETRY
#undef HITEC_FW_TELEMETRY
#undef HITEC_HUB_TELEMETRY
#undef BAYANG_HUB_TELEMETRY
#undef CABELL_HUB_TELEMETRY
#undef HUBSAN_HUB_TELEMETRY
#undef BUGS_HUB_TELEMETRY
#undef HUB_TELEMETRY
#undef SPORT_TELEMETRY
#undef SPORT_POLLING
#undef DSM_TELEMETRY
#undef MULTI_STATUS
#undef MULTI_TELEMETRY
#else #else
#if defined MULTI_TELEMETRY && not defined INVERT_TELEMETRY
#warning MULTI_TELEMETRY has been defined but not INVERT_TELEMETRY. They should be both enabled for OpenTX telemetry and status to work.
#endif
#if not defined(BAYANG_NRF24L01_INO)
#undef BAYANG_HUB_TELEMETRY
#endif
#if not defined(CABELL_NRF24L01_INO)
#undef CABELL_HUB_TELEMETRY
#endif
#if not defined(HUBSAN_A7105_INO)
#undef HUBSAN_HUB_TELEMETRY
#endif
#if not defined(AFHDS2A_A7105_INO)
#undef AFHDS2A_HUB_TELEMETRY
#undef AFHDS2A_FW_TELEMETRY
#endif
#if not defined(HITEC_CC2500_INO)
#undef HITEC_HUB_TELEMETRY
#undef HITEC_FW_TELEMETRY
#endif
#if not defined(FRSKYD_CC2500_INO)
#undef HUB_TELEMETRY
#endif
#if not defined(FRSKYX_CC2500_INO)
#undef SPORT_TELEMETRY
#undef SPORT_POLLING
#endif
#if not defined (SPORT_TELEMETRY) || not defined (STM32_BOARD)
#undef SPORT_POLLING
#endif
#if defined SPORT_POLLING && not defined INVERT_TELEMETRY
#error SPORT_POLLING has been defined but not INVERT_TELEMETRY. They should be both enabled to work.
#endif
#if not defined(DSM_CYRF6936_INO)
#undef DSM_TELEMETRY
#endif
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY)
#undef TELEMETRY
#undef INVERT_TELEMETRY
#undef SPORT_POLLING
#endif
#if defined MULTI_TELEMETRY && not defined INVERT_TELEMETRY
#warning MULTI_TELEMETRY has been defined but not INVERT_TELEMETRY. They should be both enabled for OpenTX telemetry and status to work.
#endif
#if not defined(BAYANG_NRF24L01_INO)
#undef BAYANG_HUB_TELEMETRY
#endif
#if not defined(CABELL_NRF24L01_INO)
#undef CABELL_HUB_TELEMETRY
#endif
#if not defined(HUBSAN_A7105_INO)
#undef HUBSAN_HUB_TELEMETRY
#endif
#if not defined(AFHDS2A_A7105_INO)
#undef AFHDS2A_HUB_TELEMETRY
#undef AFHDS2A_FW_TELEMETRY
#endif
#if not defined(HITEC_CC2500_INO)
#undef HITEC_HUB_TELEMETRY
#undef HITEC_FW_TELEMETRY
#endif
#if not defined(FRSKYD_CC2500_INO)
#undef HUB_TELEMETRY
#endif
#if not defined(FRSKYX_CC2500_INO)
#undef SPORT_TELEMETRY
#undef SPORT_POLLING
#endif
#if not defined (SPORT_TELEMETRY) || not defined (STM32_BOARD)
#undef SPORT_POLLING
#endif
#if defined SPORT_POLLING && not defined INVERT_TELEMETRY
#error SPORT_POLLING has been defined but not INVERT_TELEMETRY. They should be both enabled to work.
#endif
#if not defined(DSM_CYRF6936_INO)
#undef DSM_TELEMETRY
#endif
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY)
#undef TELEMETRY
#undef INVERT_TELEMETRY
#undef SPORT_POLLING
#endif
#endif #endif
//Make sure TX is defined correctly //Make sure TX is defined correctly
#ifndef AILERON #ifndef AILERON
#error You must select a correct channel order.
#error You must select a correct channel order.
#endif #endif
#if not defined(PPM_MAX_100) || not defined(PPM_MIN_100) #if not defined(PPM_MAX_100) || not defined(PPM_MIN_100)
#error You must set correct PPM end points for your TX.
#error You must set correct PPM end points for your TX.
#endif #endif
#if defined(ENABLE_BIND_CH) #if defined(ENABLE_BIND_CH)
#if BIND_CH<4
#error BIND_CH must be above 4.
#endif
#if BIND_CH>16
#error BIND_CH must be below or equal to 16.
#endif
#if BIND_CH<4
#error BIND_CH must be above 4.
#endif
#if BIND_CH>16
#error BIND_CH must be below or equal to 16.
#endif
#endif #endif
#if MIN_PPM_CHANNELS>16 #if MIN_PPM_CHANNELS>16
#error MIN_PPM_CHANNELS must be below or equal to 16. The default for this value is 4.
#error MIN_PPM_CHANNELS must be below or equal to 16. The default for this value is 4.
#endif #endif
#if MIN_PPM_CHANNELS<2 #if MIN_PPM_CHANNELS<2
#error MIN_PPM_CHANNELS must be larger than 1. The default for this value is 4.
#error MIN_PPM_CHANNELS must be larger than 1. The default for this value is 4.
#endif #endif
#if MAX_PPM_CHANNELS<MIN_PPM_CHANNELS #if MAX_PPM_CHANNELS<MIN_PPM_CHANNELS
#error MAX_PPM_CHANNELS must be higher than MIN_PPM_CHANNELS. The default for this value is 16.
#error MAX_PPM_CHANNELS must be higher than MIN_PPM_CHANNELS. The default for this value is 16.
#endif #endif
#if MAX_PPM_CHANNELS>16 #if MAX_PPM_CHANNELS>16
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
#endif
#endif #endif

66
Multiprotocol/CC2500_SPI.ino → Multiprotocol/cc2500_spi.cpp

@ -18,10 +18,11 @@
//CC2500 SPI routines //CC2500 SPI routines
//------------------------------- //-------------------------------
//------------------------------- //-------------------------------
#ifdef CC2500_INSTALLED
#include "iface_cc2500.h"
#include <stdint.h>
#include "pins.h"
#include "cc2500_spi.h"
#include "spi.h"
//----------------------------
void CC2500_WriteReg(uint8_t address, uint8_t data) void CC2500_WriteReg(uint8_t address, uint8_t data)
{ {
CC25_CSN_off; CC25_CSN_off;
@ -31,8 +32,7 @@ void CC2500_WriteReg(uint8_t address, uint8_t data)
CC25_CSN_on; CC25_CSN_on;
} }
//----------------------
static void CC2500_ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length)
void CC2500_ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length)
{ {
CC25_CSN_off; CC25_CSN_off;
SPI_Write(CC2500_READ_BURST | address); SPI_Write(CC2500_READ_BURST | address);
@ -41,8 +41,7 @@ static void CC2500_ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t le
CC25_CSN_on; CC25_CSN_on;
} }
//--------------------------------------------
static uint8_t CC2500_ReadReg(uint8_t address)
uint8_t CC2500_ReadReg(uint8_t address)
{ {
uint8_t result; uint8_t result;
CC25_CSN_off; CC25_CSN_off;
@ -52,13 +51,11 @@ static uint8_t CC2500_ReadReg(uint8_t address)
return(result); return(result);
} }
//------------------------
void CC2500_ReadData(uint8_t *dpbuffer, uint8_t len) void CC2500_ReadData(uint8_t *dpbuffer, uint8_t len)
{ {
CC2500_ReadRegisterMulti(CC2500_3F_RXFIFO, dpbuffer, len); CC2500_ReadRegisterMulti(CC2500_3F_RXFIFO, dpbuffer, len);
} }
//*********************************************
void CC2500_Strobe(uint8_t state) void CC2500_Strobe(uint8_t state)
{ {
CC25_CSN_off; CC25_CSN_off;
@ -66,7 +63,7 @@ void CC2500_Strobe(uint8_t state)
CC25_CSN_on; CC25_CSN_on;
} }
static void CC2500_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length)
void CC2500_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length)
{ {
CC25_CSN_off; CC25_CSN_off;
SPI_Write(CC2500_WRITE_BURST | address); SPI_Write(CC2500_WRITE_BURST | address);
@ -84,38 +81,20 @@ void CC2500_WriteData(uint8_t *dpbuffer, uint8_t len)
void CC2500_SetTxRxMode(uint8_t mode) void CC2500_SetTxRxMode(uint8_t mode)
{ {
if(mode == TX_EN)
{//from deviation firmware
if(mode == TX_EN) {
//from deviation firmware
CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F);
CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F | 0x40); CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F | 0x40);
}
else
if (mode == RX_EN)
{
} else {
if (mode == RX_EN) {
CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F); CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F);
CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F | 0x40); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F | 0x40);
}
else
{
} else {
CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F); CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F);
CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F);
} }
}
} }
//------------------------
/*static void cc2500_resetChip(void)
{
// Toggle chip select signal
CC25_CSN_on;
delayMicroseconds(30);
CC25_CSN_off;
delayMicroseconds(30);
CC25_CSN_on;
delayMicroseconds(45);
CC2500_Strobe(CC2500_SRES);
_delay_ms(100);
}
*/
uint8_t CC2500_Reset() uint8_t CC2500_Reset()
{ {
CC2500_Strobe(CC2500_SRES); CC2500_Strobe(CC2500_SRES);
@ -123,24 +102,6 @@ uint8_t CC2500_Reset()
CC2500_SetTxRxMode(TXRX_OFF); CC2500_SetTxRxMode(TXRX_OFF);
return CC2500_ReadReg(CC2500_0E_FREQ1) == 0xC4;//check if reset return CC2500_ReadReg(CC2500_0E_FREQ1) == 0xC4;//check if reset
} }
/*
static void CC2500_SetPower_Value(uint8_t power)
{
const unsigned char patable[8]= {
0xC5, // -12dbm
0x97, // -10dbm
0x6E, // -8dbm
0x7F, // -6dbm
0xA9, // -4dbm
0xBB, // -2dbm
0xFE, // 0dbm
0xFF // 1.5dbm
};
if (power > 7)
power = 7;
CC2500_WriteReg(CC2500_3E_PATABLE, patable[power]);
}
*/
void CC2500_SetPower() void CC2500_SetPower()
{ {
uint8_t power=CC2500_BIND_POWER; uint8_t power=CC2500_BIND_POWER;
@ -158,4 +119,3 @@ void CC2500_SetPower()
prev_power=power; prev_power=power;
} }
} }
#endif

33
Multiprotocol/iface_cc2500.h → Multiprotocol/cc2500_spi.h

@ -1,3 +1,4 @@
/* /*
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
@ -12,9 +13,29 @@
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/>.
*/ */
//-------------------------------
//-------------------------------
//CC2500 SPI routines
//-------------------------------
//-------------------------------
#ifndef _CC2500_SPI_
#define _CC2500_SPI_
#include <stdint.h>
#include "Multiprotocol.h"
void CC2500_WriteReg(uint8_t address, uint8_t data);
#ifndef _IFACE_CC2500_H_
#define _IFACE_CC2500_H_
void CC2500_ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length);
uint8_t CC2500_ReadReg(uint8_t address);
void CC2500_ReadData(uint8_t *dpbuffer, uint8_t len);
void CC2500_Strobe(uint8_t state);
void CC2500_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length);
void CC2500_WriteData(uint8_t *dpbuffer, uint8_t len);
void CC2500_SetTxRxMode(uint8_t mode);
uint8_t CC2500_Reset();
void CC2500_SetPower();
#include <stdint.h>
enum { enum {
CC2500_00_IOCFG2 = 0x00, // GDO2 output pin configuration CC2500_00_IOCFG2 = 0x00, // GDO2 output pin configuration
@ -139,12 +160,4 @@ enum {
#define CC2500_LQI_CRC_OK_BM 0x80 #define CC2500_LQI_CRC_OK_BM 0x80
#define CC2500_LQI_EST_BM 0x7F #define CC2500_LQI_EST_BM 0x7F
//void CC2500_WriteReg(u8 addr, u8 data);
//u8 CC2500_ReadReg(u8 addr);
//void CC2500_Reset();
//void CC2500_Strobe(u8 cmd);
//void CC2500_WriteData(u8 *packet, u8 length);
//void CC2500_ReadData(u8 *dpbuffer, int len);
//void CC2500_SetTxRxMode(enum TXRX_State);
#endif #endif

217
Multiprotocol/Common.ino → Multiprotocol/common.cpp

@ -12,23 +12,33 @@
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/>.
*/ */
#include "config.h"
#include "tx_def.h"
#include "common.h"
#include "Multiprotocol.h"
#include "cc2500_spi.h"
void InitFailsafe()
#ifdef FAILSAFE_ENABLE
uint16_t Failsafe_data[NUM_CHN];
#endif
void InitFailsafe(void)
{ {
for (uint8_t i = 0; i < NUM_CHN; i++) for (uint8_t i = 0; i < NUM_CHN; i++)
Failsafe_data[i] = 1024; Failsafe_data[i] = 1024;
Failsafe_data[THROTTLE] = (uint16_t)204; //1=-125%, 204=-100%
Failsafe_data[THROTTLE] = (uint16_t)204; //1=-125%, 204=-100%
FAILSAFE_VALUES_on; FAILSAFE_VALUES_on;
} }
void InitPPM()
void InitPPM(void)
{ {
for(uint8_t i=0;i<NUM_CHN;i++) for(uint8_t i=0;i<NUM_CHN;i++)
PPM_data[i]=PPM_MAX_100+PPM_MIN_100; PPM_data[i]=PPM_MAX_100+PPM_MIN_100;
PPM_data[THROTTLE]=PPM_MIN_100*2; PPM_data[THROTTLE]=PPM_MIN_100*2;
} }
void InitChannel()
void InitChannel(void)
{ {
for (uint8_t i = 0; i < NUM_CHN; i++) for (uint8_t i = 0; i < NUM_CHN; i++)
Channel_data[i] = 1024; Channel_data[i] = 1024;
@ -48,16 +58,18 @@ void reverse_channel(uint8_t num)
// Channel value is converted to ppm 860<->2140 -125%<->+125% and 988<->2012 -100%<->+100% // Channel value is converted to ppm 860<->2140 -125%<->+125% and 988<->2012 -100%<->+100%
uint16_t convert_channel_ppm(uint8_t num) uint16_t convert_channel_ppm(uint8_t num)
{ {
uint16_t val = Channel_data[num];
return (((val << 2) + val) >> 3) + 860; //value range 860<->2140 -125%<->+125%
uint16_t val = Channel_data[num];
return (((val << 2) + val) >> 3) + 860; //value range 860<->2140 -125%<->+125%
} }
// Channel value 100% is converted to 10bit values 0<->1023 // Channel value 100% is converted to 10bit values 0<->1023
uint16_t convert_channel_10b(uint8_t num) uint16_t convert_channel_10b(uint8_t num)
{ {
uint16_t val = Channel_data[num]; uint16_t val = Channel_data[num];
val = ((val << 2) + val) >> 3; val = ((val << 2) + val) >> 3;
if (val <= 128) return 0;
if (val >= 1152) return 1023;
if (val <= 128)
return 0;
if (val >= 1152)
return 1023;
return val - 128; return val - 128;
} }
// Channel value 100% is converted to 8bit values 0<->255 // Channel value 100% is converted to 8bit values 0<->255
@ -75,7 +87,7 @@ uint8_t convert_channel_8b(uint8_t num)
// Channel value 100% is converted to value scaled // Channel value 100% is converted to value scaled
int16_t convert_channel_16b_limit(uint8_t num, int16_t min, int16_t max) int16_t convert_channel_16b_limit(uint8_t num, int16_t min, int16_t max)
{ {
int32_t val = limit_channel_100(num); // 204<->1844
int32_t val = limit_channel_100(num); // 204<->1844
val = (val - CHANNEL_MIN_100) * (max - min) / (CHANNEL_MAX_100 - CHANNEL_MIN_100) + min; val = (val - CHANNEL_MIN_100) * (max - min) / (CHANNEL_MAX_100 - CHANNEL_MIN_100) + min;
return (uint16_t)val; return (uint16_t)val;
} }
@ -83,7 +95,7 @@ int16_t convert_channel_16b_limit(uint8_t num, int16_t min, int16_t max)
// Channel value -125%<->125% is scaled to 16bit value with no limit // Channel value -125%<->125% is scaled to 16bit value with no limit
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max) int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max)
{ {
int32_t val = Channel_data[num]; // 0<->2047
int32_t val = Channel_data[num]; // 0<->2047
val = (val - CHANNEL_MIN_100) * (max - min) / (CHANNEL_MAX_100 - CHANNEL_MIN_100) + min; val = (val - CHANNEL_MIN_100) * (max - min) / (CHANNEL_MAX_100 - CHANNEL_MIN_100) + min;
return (uint16_t)val; return (uint16_t)val;
} }
@ -133,15 +145,6 @@ uint16_t convert_channel_frsky(uint8_t num)
/** FrSky D and X routines **/ /** FrSky D and X routines **/
/******************************/ /******************************/
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) #if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
enum {
FRSKY_BIND = 0,
FRSKY_BIND_DONE = 1000,
FRSKY_DATA1,
FRSKY_DATA2,
FRSKY_DATA3,
FRSKY_DATA4,
FRSKY_DATA5
};
void Frsky_init_hop(void) void Frsky_init_hop(void)
{ {
@ -168,7 +171,7 @@ void Frsky_init_hop(void)
/** FrSky V, D and X routines **/ /** FrSky V, D and X routines **/
/******************************/ /******************************/
#if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) #if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
const PROGMEM uint8_t FRSKY_common_startreg_cc2500_conf[] = {
uint8_t FRSKY_common_startreg_cc2500_conf[] = {
CC2500_02_IOCFG0 , CC2500_02_IOCFG0 ,
CC2500_00_IOCFG2 , CC2500_00_IOCFG2 ,
CC2500_17_MCSM1 , CC2500_17_MCSM1 ,
@ -178,7 +181,7 @@ const PROGMEM uint8_t FRSKY_common_startreg_cc2500_conf[] = {
CC2500_08_PKTCTRL0 , CC2500_08_PKTCTRL0 ,
CC2500_3E_PATABLE , CC2500_3E_PATABLE ,
CC2500_0B_FSCTRL1 , CC2500_0B_FSCTRL1 ,
CC2500_0C_FSCTRL0 , // replaced by option value
CC2500_0C_FSCTRL0 , // replaced by option value
CC2500_0D_FREQ2 , CC2500_0D_FREQ2 ,
CC2500_0E_FREQ1 , CC2500_0E_FREQ1 ,
CC2500_0F_FREQ0 , CC2500_0F_FREQ0 ,
@ -191,100 +194,100 @@ const PROGMEM uint8_t FRSKY_common_startreg_cc2500_conf[] = {
}; };
#if defined(FRSKYV_CC2500_INO) #if defined(FRSKYV_CC2500_INO)
const PROGMEM uint8_t FRSKYV_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0xff ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x05 ,
/*3E_PATABLE*/ 0xfe ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x58 ,
/*0F_FREQ0*/ 0x9d ,
/*10_MDMCFG4*/ 0xAA ,
/*11_MDMCFG3*/ 0x10 ,
/*12_MDMCFG2*/ 0x93 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x41
uint8_t FRSKYV_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0xff ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x05 ,
/*3E_PATABLE*/ 0xfe ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x58 ,
/*0F_FREQ0*/ 0x9d ,
/*10_MDMCFG4*/ 0xAA ,
/*11_MDMCFG3*/ 0x10 ,
/*12_MDMCFG2*/ 0x93 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x41
}; };
#endif #endif
#if defined(FRSKYD_CC2500_INO) #if defined(FRSKYD_CC2500_INO)
const PROGMEM uint8_t FRSKYD_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x19 ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x05 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x76 ,
/*0F_FREQ0*/ 0x27 ,
/*10_MDMCFG4*/ 0xAA ,
/*11_MDMCFG3*/ 0x39 ,
/*12_MDMCFG2*/ 0x11 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x42
uint8_t FRSKYD_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x19 ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x05 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x76 ,
/*0F_FREQ0*/ 0x27 ,
/*10_MDMCFG4*/ 0xAA ,
/*11_MDMCFG3*/ 0x39 ,
/*12_MDMCFG2*/ 0x11 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x42
}; };
#endif #endif
#if defined(FRSKYX_CC2500_INO) #if defined(FRSKYX_CC2500_INO)
const PROGMEM uint8_t FRSKYX_cc2500_conf[] = {
uint8_t FRSKYX_cc2500_conf[] = {
//FRSKYX //FRSKYX
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x1E ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x01 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x0A ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x76 ,
/*0F_FREQ0*/ 0x27 ,
/*10_MDMCFG4*/ 0x7B ,
/*11_MDMCFG3*/ 0x61 ,
/*12_MDMCFG2*/ 0x13 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x51
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0c ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x1E ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x01 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x0A ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x76 ,
/*0F_FREQ0*/ 0x27 ,
/*10_MDMCFG4*/ 0x7B ,
/*11_MDMCFG3*/ 0x61 ,
/*12_MDMCFG2*/ 0x13 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x51
}; };
const PROGMEM uint8_t FRSKYXEU_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0E ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x23 ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x01 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x80 ,
/*0F_FREQ0*/ 0x00 ,
/*10_MDMCFG4*/ 0x7B ,
/*11_MDMCFG3*/ 0xF8 ,
/*12_MDMCFG2*/ 0x03 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x53
uint8_t FRSKYXEU_cc2500_conf[] = {
/*02_IOCFG0*/ 0x06 ,
/*00_IOCFG2*/ 0x06 ,
/*17_MCSM1*/ 0x0E ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0x23 ,
/*07_PKTCTRL1*/ 0x04 ,
/*08_PKTCTRL0*/ 0x01 ,
/*3E_PATABLE*/ 0xff ,
/*0B_FSCTRL1*/ 0x08 ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x80 ,
/*0F_FREQ0*/ 0x00 ,
/*10_MDMCFG4*/ 0x7B ,
/*11_MDMCFG3*/ 0xF8 ,
/*12_MDMCFG2*/ 0x03 ,
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x53
}; };
#endif #endif
const PROGMEM uint8_t FRSKY_common_end_cc2500_conf[][2] = {
uint8_t FRSKY_common_end_cc2500_conf[][2] = {
{ CC2500_19_FOCCFG, 0x16 }, { CC2500_19_FOCCFG, 0x16 },
{ CC2500_1A_BSCFG, 0x6c }, { CC2500_1A_BSCFG, 0x6c },
{ CC2500_1B_AGCCTRL2, 0x43 }, { CC2500_1B_AGCCTRL2, 0x43 },
@ -308,17 +311,17 @@ void FRSKY_init_cc2500(const uint8_t *ptr)
{ {
for (uint8_t i = 0; i < 19; i++) for (uint8_t i = 0; i < 19; i++)
{ {
uint8_t reg = pgm_read_byte_near(&FRSKY_common_startreg_cc2500_conf[i]);
uint8_t val = pgm_read_byte_near(&ptr[i]);
uint8_t reg = FRSKY_common_startreg_cc2500_conf[i];
uint8_t val = ptr[i];
if (reg == CC2500_0C_FSCTRL0) if (reg == CC2500_0C_FSCTRL0)
val = option; val = option;
CC2500_WriteReg(reg, val); CC2500_WriteReg(reg, val);
} }
prev_option = option ; // Save option to monitor FSCTRL0 change
prev_option = option ; // Save option to monitor FSCTRL0 change
for (uint8_t i = 0; i < 17; i++) for (uint8_t i = 0; i < 17; i++)
{ {
uint8_t reg = pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][0]);
uint8_t val = pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][1]);
uint8_t reg = FRSKY_common_end_cc2500_conf[i][0];
uint8_t val = FRSKY_common_end_cc2500_conf[i][1];
CC2500_WriteReg(reg, val); CC2500_WriteReg(reg, val);
} }
CC2500_SetTxRxMode(TX_EN); CC2500_SetTxRxMode(TX_EN);

77
Multiprotocol/common.h

@ -0,0 +1,77 @@
/*
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/>.
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdint.h>
#include "config.h"
#include "tx_def.h"
void InitFailsafe(void);
void InitPPM(void);
void InitChannel(void);
void reverse_channel(uint8_t num);
uint16_t convert_channel_ppm(uint8_t num);
uint16_t convert_channel_10b(uint8_t num);
uint8_t convert_channel_8b(uint8_t num);
int16_t convert_channel_16b_limit(uint8_t num, int16_t min, int16_t max);
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max);
uint8_t convert_channel_s8b(uint8_t num);
uint16_t limit_channel_100(uint8_t num);
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high);
void convert_failsafe_HK310(uint8_t num, uint8_t *low, uint8_t *high);
uint16_t convert_channel_frsky(uint8_t num);
/******************************/
/** FrSky D and X routines **/
/******************************/
enum {
FRSKY_BIND = 0,
FRSKY_BIND_DONE = 1000,
FRSKY_DATA1,
FRSKY_DATA2,
FRSKY_DATA3,
FRSKY_DATA4,
FRSKY_DATA5
};
void Frsky_init_hop(void);
/******************************/
/** FrSky V, D and X routines **/
/******************************/
#if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
extern uint8_t FRSKY_common_startreg_cc2500_conf[];
#if defined(FRSKYV_CC2500_INO)
extern uint8_t FRSKYV_cc2500_conf[];
#endif
#if defined(FRSKYD_CC2500_INO)
extern uint8_t FRSKYD_cc2500_conf[];
#endif
#if defined(FRSKYX_CC2500_INO)
extern uint8_t FRSKYX_cc2500_conf[];
extern uint8_t FRSKYXEU_cc2500_conf[];
#endif
extern uint8_t FRSKY_common_end_cc2500_conf[][2];
void FRSKY_init_cc2500(const uint8_t *ptr);
#ifdef FAILSAFE_ENABLE
extern uint16_t Failsafe_data[NUM_CHN];
#endif
#endif
#endif

235
Multiprotocol/config.cpp

@ -0,0 +1,235 @@
/*
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/>.
*/
#include "config.h"
uint8_t curr_bank = 0;
const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
//****************************** BANK 1 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 0 },
/* 2 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 20 },
/* 3 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 40 },
/* 4 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 60 },
/* 5 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 80 },
/* 6 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 100 },
/* 7 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 120 },
/* 8 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 140 },
/* 9 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 160 },
/* 10 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 180 },
/* 11 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 200 },
/* 12 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 220 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 240 },
/* 14 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 255 },
//****************************** BANK 2 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -120 },
/* 2 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -100 },
/* 3 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -80 },
/* 4 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -60 },
/* 5 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -40 },
/* 6 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -20 },
/* 7 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 0 },
/* 8 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 10 },
/* 9 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 20 },
/* 10 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 40 },
/* 11 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 60 },
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 80 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 100 },
/* 14 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 120 },
//****************************** BANK 3 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -120 },
/* 2 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -100 },
/* 3 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -80 },
/* 4 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -60 },
/* 5 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -40 },
/* 6 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -20 },
/* 7 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 0 },
/* 8 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 10 },
/* 9 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 20 },
/* 10 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 40 },
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 60 },
/* 12 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 80 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 100 },
/* 14 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 120 },
};
/* Available protocols and associated sub protocols to pick and choose from
PROTO_FLYSKY
Flysky
V9X9
V6X6
V912
CX20
PROTO_HUBSAN
H107
H301
H501
PROTO_FRSKYV
NONE
PROTO_FRSKYD
NONE
PROTO_FRSKYX
CH_16
CH_8
EU_16
EU_8
PROTO_HISKY
Hisky
HK310
PROTO_V2X2
V2X2
JXD506
PROTO_DSM
DSM2_22
DSM2_11
DSMX_22
DSMX_11
PROTO_DEVO
NONE
PROTO_YD717
YD717
SKYWLKRP_LOW
SYMAX4
XINXUN
NIHUI
PROTO_KN
WLTOYS
FEILUN
PROTO_SYMAX
SYMAX
SYMAX5C
PROTO_SLT
NONE
PROTO_CX10
CX10_GREEN
CX10_BLUE
DM007
JC3015_1
JC3015_2
MK33041
PROTO_Q2X2
Q222
Q242
Q282
PROTO_SLT
SLT
VISTA
PROTO_CG023
CG023
YD829
PROTO_BAYANG
BAYANG
H8S3D
X16_AH
IRDRONE
PROTO_ESKY
NONE
PROTO_MT99XX
MT99
H7
YZ
LS
FY805
PROTO_MJXQ
WLH08
X600
X800
H26D
E010
H26WH
PROTO_SHENQI
NONE
PROTO_FY326
FY326
FY319
PROTO_SFHSS
NONE
PROTO_J6PRO
NONE
PROTO_FQ777
NONE
PROTO_ASSAN
NONE
PROTO_HONTAI
HONTAI
JJRCX1
X5C1
FQ777_951
PROTO_AFHDS2A
PWM_IBUS
PPM_IBUS
PWM_SBUS
PPM_SBUS
PROTO_WK2x01
WK2801
WK2401
W6_5_1
W6_6_1
W6_HEL
W6_HEL_I
PROTO_Q303
Q303
CX35
CX10D
CX10WD
PROTO_GW008
NONE
PROTO_DM002
NONE
PROTO_CABELL
CABELL_V3
CABELL_V3_TELEMETRY
CABELL_SET_FAIL_SAFE
CABELL_UNBIND
PROTO_ESKY150
PROTO_H8_3D
H8_3D
H20H
H20MINI
H30MINI
PROTO_CORONA
COR_V1
COR_V2
FD_V3
PROTO_CFLIE
NONE
PROTO_HITEC
OPT_FW
OPT_HUB
MINIMA
PROTO_WFLY
NONE
PROTO_BUGS
NONE
PROTO_SLT
SLT_V1
SLT_V2
Q100
Q200
MR100
*/
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...
// RX_Num value is between 0 and 15.
// Power P_HIGH or P_LOW: High or low power setting for the transmission.
// For indoor P_LOW is more than enough.
// Auto Bind AUTOBIND or NO_AUTOBIND
// For protocols which does not require binding at each power up (like Flysky, FrSky...), you might still want a bind to be initiated each time you power up the TX.
// As an example, it's usefull for the WLTOYS F929/F939/F949/F959 (all using the Flysky protocol) which requires a bind at each power up.
// It also enables the Bind from channel feature, allowing to execute a bind by toggling a designated channel.
// Option: the value is between -128 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

371
Multiprotocol/_Config.h → Multiprotocol/config.h

@ -12,7 +12,10 @@
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/>.
*/ */
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include <stdint.h>
/**********************************************/ /**********************************************/
/** Multiprotocol module configuration file ***/ /** Multiprotocol module configuration file ***/
/**********************************************/ /**********************************************/
@ -33,7 +36,7 @@
//Comment to globaly disable the bind feature from a channel. //Comment to globaly disable the bind feature from a channel.
#define ENABLE_BIND_CH #define ENABLE_BIND_CH
//Set the channel number used for bind. Default is 16. //Set the channel number used for bind. Default is 16.
#define BIND_CH 16
#define BIND_CH 16
//Comment to disable the wait for bind feature. If Autobind is enabled in the model config, this feature will not activate //Comment to disable the wait for bind feature. If Autobind is enabled in the model config, this feature will not activate
// the selected protocol unless a bind is requested using bind from channel or the GUI "Bind" button. // the selected protocol unless a bind is requested using bind from channel or the GUI "Bind" button.
@ -59,9 +62,9 @@
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol. //Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md //For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127. //Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
//#define FORCE_FRSKYD_TUNING 0
//#define FORCE_FRSKYV_TUNING 0
//#define FORCE_FRSKYX_TUNING 0
//#define FORCE_FRSKYD_TUNING 0
//#define FORCE_FRSKYV_TUNING 0
//#define FORCE_FRSKYX_TUNING 0
/** Low Power **/ /** Low Power **/
//Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI). //Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI).
@ -78,13 +81,13 @@
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model //If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
// then you can force the ID to a certain known value using the lines below. // then you can force the ID to a certain known value using the lines below.
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!! //Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
#define FORCE_GLOBAL_ID 0x12345678
#define FORCE_GLOBAL_ID 0x12345678
//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs. //Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs.
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model //If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
// then you can force the ID to a certain known value using the lines below. // then you can force the ID to a certain known value using the lines below.
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!! //Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
//#define FORCE_CYRF_ID "\x12\x34\x56\x78\x9A\xBC"
//#define FORCE_CYRF_ID "\x12\x34\x56\x78\x9A\xBC"
/****************************/ /****************************/
@ -95,9 +98,9 @@
//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 a CC2500 to be installed //The protocols below need a CC2500 to be installed
#define FRSKYD_CC2500_INO
#define FRSKYV_CC2500_INO
#define FRSKYX_CC2500_INO
#define FRSKYD_CC2500_INO
#define FRSKYV_CC2500_INO
#define FRSKYX_CC2500_INO
/**************************/ /**************************/
@ -147,17 +150,17 @@
//#define MULTI_TELEMETRY //#define MULTI_TELEMETRY
//Comment a line to disable a specific protocol telemetry //Comment a line to disable a specific protocol telemetry
//#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, ersky9x and OpenTX
//#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
//#define AFHDS2A_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by ersky9x and OpenTX
//#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to TX like er9x
//#define HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define BUGS_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, ersky9x and OpenTX
//#define HITEC_FW_TELEMETRY // Under development: Forward received telemetry packets to be decoded by ersky9x and OpenTX
//#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, ersky9x and OpenTX
//#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
//#define AFHDS2A_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by ersky9x and OpenTX
//#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to TX like er9x
//#define HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define BUGS_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
//#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, ersky9x and OpenTX
//#define HITEC_FW_TELEMETRY // Under development: Forward received telemetry packets to be decoded by ersky9x and OpenTX
//SPORT_POLLING is an implementation of the same polling routine as XJT module for sport telemetry bidirectional communication. //SPORT_POLLING is an implementation of the same polling routine as XJT module for sport telemetry bidirectional communication.
//This is useful for passing sport control frames from TX to RX(ex: changing Betaflight PID or VTX channels on the fly using LUA scripts with OpentX). //This is useful for passing sport control frames from TX to RX(ex: changing Betaflight PID or VTX channels on the fly using LUA scripts with OpentX).
@ -188,13 +191,13 @@
//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 microseconds)
//#define TX_DEVO7 //DEVO (1120<->1920 microseconds)
//#define TX_SPEKTRUM //Spektrum (1100<->1900 microseconds)
//#define TX_HISKY //HISKY (1120<->1920 microseconds)
//#define TX_MPX //Multiplex MC2020 (1250<->1950 microseconds)
//#define TX_WALKERA //Walkera PL0811-01H (1000<->1800 microseconds)
//#define TX_CUSTOM //Custom
#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012 microseconds)
//#define TX_DEVO7 //DEVO (1120<->1920 microseconds)
//#define TX_SPEKTRUM //Spektrum (1100<->1900 microseconds)
//#define TX_HISKY //HISKY (1120<->1920 microseconds)
//#define TX_MPX //Multiplex MC2020 (1250<->1950 microseconds)
//#define TX_WALKERA //Walkera PL0811-01H (1000<->1800 microseconds)
//#define TX_CUSTOM //Custom
// The lines below are used to set the end points in microseconds if you have selected TX_CUSTOM. // The lines below are used to set the end points in microseconds if you have selected TX_CUSTOM.
// A few things to consider: // A few things to consider:
@ -202,10 +205,6 @@
// - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the ends // - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the ends
// - Centered stick value is usually 1500. It should match the middle between MIN and MAX, ie Center=(MAX+MIN)/2. If your TX is not centered you can adjust the value MIN or MAX. // - Centered stick value is usually 1500. It should match the middle between MIN and MAX, ie Center=(MAX+MIN)/2. If your TX is not centered you can adjust the value MIN or MAX.
// - 100% is referred as the value when the TX is set to default with no trims // - 100% is referred as the value when the TX is set to default with no trims
#if defined(TX_CUSTOM)
#define PPM_MAX_100 1900 // 100%
#define PPM_MIN_100 1100 // 100%
#endif
/** Number of PPM Channels **/ /** Number of PPM Channels **/
// The line below is used to set the minimum number of channels which the module should receive to consider a PPM frame valid. // The line below is used to set the minimum number of channels which the module should receive to consider a PPM frame valid.
@ -215,240 +214,82 @@
// The default value is 16 to receive all possible channels but you might want to filter some "bad" channels from the PPM frame like the ones above 6 on the Walkera PL0811. // The default value is 16 to receive all possible channels but you might want to filter some "bad" channels from the PPM frame like the ones above 6 on the Walkera PL0811.
#define MAX_PPM_CHANNELS 16 #define MAX_PPM_CHANNELS 16
/** Rotary Switch Protocol Selector Settings **/
//The table below indicates which protocol to run when a specific position on the rotary switch has been selected.
//All fields and values are explained below. Everything is configurable from here like in the Serial mode.
//Tip: You can associate multiple times the same protocol to different rotary switch positions to take advantage of the model match based on RX_Num
#define NBR_BANKS 3
extern uint8_t curr_bank;
//A system of banks enable the access to more protocols than positions on the rotary switch. Banks can be selected by placing the rotary switch on position 15, power up the module and
// short press the bind button multiple times until you reach the desired one. The bank number currently selected is indicated by the number of LED flash.
// Full procedure is located here: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md#protocol-selection-in-ppm-mode
struct PPM_Parameters
{
uint8_t protocol : 6;
uint8_t sub_proto : 3;
uint8_t rx_num : 4;
//The parameter below indicates the number of desired banks between 1 and 5. Default is 5.
#define NBR_BANKS 3
uint8_t curr_bank = 0;
const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
#if NBR_BANKS > 0
//****************************** BANK 1 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 0 },
/* 2 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 20 },
/* 3 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 40 },
/* 4 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 60 },
/* 5 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 80 },
/* 6 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 100 },
/* 7 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 120 },
/* 8 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 140 },
/* 9 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 160 },
/* 10 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 180 },
/* 11 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 200 },
/* 12 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 220 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 240 },
/* 14 */ {PROTO_FRSKYD, 0 , 0 , P_LOW , AUTOBIND , 255 },
#endif
#if NBR_BANKS > 1
//****************************** BANK 2 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -120 },
/* 2 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -100 },
/* 3 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -80 },
/* 4 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -60 },
/* 5 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -40 },
/* 6 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , -20 },
/* 7 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 0 },
/* 8 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 10 },
/* 9 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 20 },
/* 10 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 40 },
/* 11 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 60 },
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 80 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 100 },
/* 14 */ {PROTO_FRSKYX, EU_16 , 0 , P_LOW , AUTOBIND , 120 },
#endif
#if NBR_BANKS > 2
//****************************** BANK 3 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
/* 1 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -120 },
/* 2 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -100 },
/* 3 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -80 },
/* 4 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -60 },
/* 5 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -40 },
/* 6 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , -20 },
/* 7 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 0 },
/* 8 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 10 },
/* 9 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 20 },
/* 10 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 40 },
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 60 },
/* 12 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 80 }, // option=fine freq tuning
/* 13 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 100 },
/* 14 */ {PROTO_FRSKYX, CH_16 , 0 , P_LOW , AUTOBIND , 120 },
#endif
#define P_HIGH 1
#define P_LOW 0
uint8_t power : 1;
#define AUTOBIND 1
#define NO_AUTOBIND 0
uint8_t autobind : 1;
uint8_t option;
};
//******************
// Protocols
//******************
enum PROTOCOLS
{
MODE_SERIAL = 0, // Serial commands
PROTO_FLYSKY = 1, // =>A7105
PROTO_HUBSAN = 2, // =>A7105
PROTO_FRSKYD = 3, // =>CC2500
PROTO_HISKY = 4, // =>NRF24L01
PROTO_V2X2 = 5, // =>NRF24L01
PROTO_DSM = 6, // =>CYRF6936
PROTO_DEVO = 7, // =>CYRF6936
PROTO_YD717 = 8, // =>NRF24L01
PROTO_KN = 9, // =>NRF24L01
PROTO_SYMAX = 10, // =>NRF24L01
PROTO_SLT = 11, // =>NRF24L01
PROTO_CX10 = 12, // =>NRF24L01
PROTO_CG023 = 13, // =>NRF24L01
PROTO_BAYANG = 14, // =>NRF24L01
PROTO_FRSKYX = 15, // =>CC2500
PROTO_ESKY = 16, // =>NRF24L01
PROTO_MT99XX = 17, // =>NRF24L01
PROTO_MJXQ = 18, // =>NRF24L01
PROTO_SHENQI = 19, // =>NRF24L01
PROTO_FY326 = 20, // =>NRF24L01
PROTO_SFHSS = 21, // =>CC2500
PROTO_J6PRO = 22, // =>CYRF6936
PROTO_FQ777 = 23, // =>NRF24L01
PROTO_ASSAN = 24, // =>NRF24L01
PROTO_FRSKYV = 25, // =>CC2500
PROTO_HONTAI = 26, // =>NRF24L01
PROTO_OPENLRS = 27, // =>OpenLRS hardware
PROTO_AFHDS2A = 28, // =>A7105
PROTO_Q2X2 = 29, // =>NRF24L01, extension of CX-10 protocol
PROTO_WK2x01 = 30, // =>CYRF6936
PROTO_Q303 = 31, // =>NRF24L01
PROTO_GW008 = 32, // =>NRF24L01
PROTO_DM002 = 33, // =>NRF24L01
PROTO_CABELL = 34, // =>NRF24L01
PROTO_ESKY150 = 35, // =>NRF24L01
PROTO_H8_3D = 36, // =>NRF24L01
PROTO_CORONA = 37, // =>CC2500
PROTO_CFLIE = 38, // =>NRF24L01
PROTO_HITEC = 39, // =>CC2500
PROTO_WFLY = 40, // =>CYRF6936
PROTO_BUGS = 41, // =>A7105
}; };
/* Available protocols and associated sub protocols to pick and choose from
PROTO_FLYSKY
Flysky
V9X9
V6X6
V912
CX20
PROTO_HUBSAN
H107
H301
H501
PROTO_FRSKYV
NONE
PROTO_FRSKYD
NONE
PROTO_FRSKYX
CH_16
CH_8
EU_16
EU_8
PROTO_HISKY
Hisky
HK310
PROTO_V2X2
V2X2
JXD506
PROTO_DSM
DSM2_22
DSM2_11
DSMX_22
DSMX_11
PROTO_DEVO
NONE
PROTO_YD717
YD717
SKYWLKRP_LOW
SYMAX4
XINXUN
NIHUI
PROTO_KN
WLTOYS
FEILUN
PROTO_SYMAX
SYMAX
SYMAX5C
PROTO_SLT
NONE
PROTO_CX10
CX10_GREEN
CX10_BLUE
DM007
JC3015_1
JC3015_2
MK33041
PROTO_Q2X2
Q222
Q242
Q282
PROTO_SLT
SLT
VISTA
PROTO_CG023
CG023
YD829
PROTO_BAYANG
BAYANG
H8S3D
X16_AH
IRDRONE
PROTO_ESKY
NONE
PROTO_MT99XX
MT99
H7
YZ
LS
FY805
PROTO_MJXQ
WLH08
X600
X800
H26D
E010
H26WH
PROTO_SHENQI
NONE
PROTO_FY326
FY326
FY319
PROTO_SFHSS
NONE
PROTO_J6PRO
NONE
PROTO_FQ777
NONE
PROTO_ASSAN
NONE
PROTO_HONTAI
HONTAI
JJRCX1
X5C1
FQ777_951
PROTO_AFHDS2A
PWM_IBUS
PPM_IBUS
PWM_SBUS
PPM_SBUS
PROTO_WK2x01
WK2801
WK2401
W6_5_1
W6_6_1
W6_HEL
W6_HEL_I
PROTO_Q303
Q303
CX35
CX10D
CX10WD
PROTO_GW008
NONE
PROTO_DM002
NONE
PROTO_CABELL
CABELL_V3
CABELL_V3_TELEMETRY
CABELL_SET_FAIL_SAFE
CABELL_UNBIND
PROTO_ESKY150
PROTO_H8_3D
H8_3D
H20H
H20MINI
H30MINI
PROTO_CORONA
COR_V1
COR_V2
FD_V3
PROTO_CFLIE
NONE
PROTO_HITEC
OPT_FW
OPT_HUB
MINIMA
PROTO_WFLY
NONE
PROTO_BUGS
NONE
PROTO_SLT
SLT_V1
SLT_V2
Q100
Q200
MR100
*/
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...
// RX_Num value is between 0 and 15.
// Power P_HIGH or P_LOW: High or low power setting for the transmission.
// For indoor P_LOW is more than enough.
// Auto Bind AUTOBIND or NO_AUTOBIND
// For protocols which does not require binding at each power up (like Flysky, FrSky...), you might still want a bind to be initiated each time you power up the TX.
// As an example, it's usefull for the WLTOYS F929/F939/F949/F959 (all using the Flysky protocol) which requires a bind at each power up.
// It also enables the Bind from channel feature, allowing to execute a bind by toggling a designated channel.
// Option: the value is between -128 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
enum FRSKYX_SUP_PROTOCOL
{
CH_16 = 0,
CH_8 = 1,
EU_16 = 2,
EU_8 = 3,
};
extern const PPM_Parameters PPM_prot[14*NBR_BANKS];
#endif

6
Multiprotocol/debug.h

@ -1,5 +1,7 @@
#ifndef DEBUG_H
#define DEBUG_H
#ifndef _DEBUG_H_
#define _DEBUG_H_
#include "Arduino.h"
#include <stdio.h>
//******************** //********************
//** Debug messages ** //** Debug messages **

77
Multiprotocol/input.cpp

@ -0,0 +1,77 @@
#include "Arduino.h"
#include <string.h>
#include "config.h"
#include "tx_def.h"
#include "Multiprotocol.h"
#include "input.h"
#include "pins.h"
#include "state.h"
Input input;
Input::Input(void) {
this->curr = &(this->input[0]);
this->old = &(this->input[1]);
memset(this->input,0, sizeof(this->input));
}
void Input::mark_processed(void) {
struct data* temp = this->old;
this->old = this->curr;
this->curr = temp;
}
struct Input::data* Input::get_curr_input(void) {
return this->curr;
}
struct Input::data* Input::get_old_input(void) {
return this->old;
}
void Input::update(void) {
this->curr->throttle = analogRead(Throttle_pin);
this->curr->yaw = analogRead(Yaw_pin);
this->curr->roll = analogRead(Roll_pin);
this->curr->pitch = analogRead(Pitch_pin);
this->curr->aux[0] = digitalRead(Aux1_pin);
this->curr->aux[1] = digitalRead(Aux2_pin);
this->curr->aux[2] = digitalRead(Aux3_pin);
this->curr->aux[3] = digitalRead(Aux4_pin);
this->curr->aux[4] = digitalRead(Aux5_pin);
this->curr->aux[5] = digitalRead(Aux6_pin);
this->curr->menu = digitalRead(Menu_pin);
// only do channeloutpu if needed
if (curr_state != s_fly)
return;
Channel_data[THROTTLE] = map(this->curr->throttle, 0, 3500, CHANNEL_MIN_100, CHANNEL_MAX_100);
Channel_data[RUDDER] = map(this->curr->yaw, 0, 3500, CHANNEL_MIN_100, CHANNEL_MAX_100);
Channel_data[AILERON] = map(this->curr->roll, 0, 3500, CHANNEL_MIN_100, CHANNEL_MAX_100);
Channel_data[ELEVATOR] = map(this->curr->pitch, 0, 3500, CHANNEL_MIN_100, CHANNEL_MAX_100);
for (uint8_t i = 0; i<6; ++i) {
if(this->curr->aux[i])
Channel_data[CH5+i] = CHANNEL_MAX_100;
else
Channel_data[CH5+i] = CHANNEL_MIN_100;
}
}
bool Input::menu_triggered(void) {
return false;
}
bool Input::left_triggered(void) {
return false;
}
bool Input::right_triggered(void) {
return false;
}
bool Input::down_triggered(void) {
return false;
}
bool Input::up_triggered(void) {
return false;
}

44
Multiprotocol/input.h

@ -0,0 +1,44 @@
#ifndef _INPUT_H_
#define _INPUT_H_
#include <stdint.h>
#include "tx_def.h"
class Input {
private:
struct data {
uint16_t throttle;
uint16_t yaw;
uint16_t roll;
uint16_t pitch;
bool aux[6];
bool menu;
};
int curr_input;
public:
struct data input[2];
struct data* curr;
struct data* old;
Input(void);
void update(void);
struct data* get_curr_input(void);
struct data* get_old_input(void);
void update_inputs(void);
void mark_processed(void);
// menu inputs
bool menu_triggered(void);
bool left_triggered(void);
bool right_triggered(void);
bool down_triggered(void);
bool up_triggered(void);
};
extern uint16_t Channel_data[NUM_CHN];
extern Input input;
#endif

38
Multiprotocol/inputs.ino

@ -1,38 +0,0 @@
void update_inputs(void) {
INPUT_SIGNAL_on;
if (state < FRSKY_BIND_DONE)
return;
uint16_t throttle = analogRead(Throttle_pin);
uint16_t yaw = analogRead(Yaw_pin);
uint16_t roll = analogRead(Roll_pin);
uint16_t pitch = analogRead(Pitch_pin);
uint16_t aux1 = 0;//analogRead(Aux1_pin);
uint16_t aux2 = analogRead(Aux2_pin);
uint16_t ch_min=CHANNEL_MIN_100;
uint16_t ch_max=CHANNEL_MAX_100;
Channel_data[THROTTLE] += map(throttle, 0, 3500, ch_min, ch_max);
Channel_data[RUDDER] += map(yaw, 0, 3500, ch_min, ch_max);
Channel_data[AILERON] += map(roll, 0, 3500, ch_min, ch_max);
Channel_data[ELEVATOR] += map(pitch, 0, 3500, ch_min, ch_max);
//Channel_data[CH5] += map(aux1, 0, 3500, ch_min, ch_max);
Channel_data[CH6] += map(aux2, 0, 3500, ch_min, ch_max);
Channel_data[THROTTLE] /= 2;
Channel_data[RUDDER] /= 2;
Channel_data[AILERON] /= 2;
Channel_data[ELEVATOR] /= 2;
Channel_data[CH5] /= 2;
Channel_data[CH6] /= 2;
//debugln("T %d y %d r %d p %d a1 %d a2 %d",throttle,yaw,roll,pitch,aux1,aux2);
//debugln("T %d y %d r %d p %d a1 %d a2 %d",Channel_data[THROTTLE],Channel_data[RUDDER],Channel_data[AILERON],Channel_data[ELEVATOR],Channel_data[CH5],Channel_data[CH6]);
}

15
Multiprotocol/Pins.h → Multiprotocol/pins.h

@ -13,6 +13,11 @@
//******************* //*******************
//*** Pinouts *** //*** Pinouts ***
//******************* //*******************
#ifndef _PINS_H_
#define _PINS_H_
#include "Arduino.h"
#define LED_off #define LED_off
#define LED_on #define LED_on
#define LED_output #define LED_output
@ -29,10 +34,18 @@
#define Yaw_pin PA5 #define Yaw_pin PA5
#define Roll_pin PA6 #define Roll_pin PA6
#define Pitch_pin PA7 #define Pitch_pin PA7
#define Aux1_pin PB0
#define Aux2_pin PB0 #define Aux2_pin PB0
#define Aux3_pin PB0
#define Aux4_pin PB0
#define Aux5_pin PB0
#define Aux6_pin PB0
#define Menu_pin PB0
#define cli() #define cli()
#define sei() #define sei()
#define NOP() __asm__ __volatile__("nop")
#define SDI_on digitalWrite(SDI_pin, HIGH) #define SDI_on digitalWrite(SDI_pin, HIGH)
#define SDI_off digitalWrite(SDI_pin, LOW) #define SDI_off digitalWrite(SDI_pin, LOW)
@ -66,3 +79,5 @@
//*** EEPROM *** //*** EEPROM ***
//******************* //*******************
#define EE_ADDR uint8_t* #define EE_ADDR uint8_t*
#endif

57
Multiprotocol/spi.cpp

@ -0,0 +1,57 @@
/*
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/>.
*/
#include <stdint.h>
#include "pins.h"
#include "spi.h"
/********************/
/** SPI routines **/
/********************/
void SPI_Write(uint8_t command)
{
uint8_t n=8;
SCLK_off;//SCK start low
SDI_off;
do
{
if(command&0x80)
SDI_on;
else
SDI_off;
SCLK_on;
//delay(1);
command = command << 1;
SCLK_off;
}
while(--n) ;
SDI_on;
}
uint8_t SPI_Read(void)
{
uint8_t result=0,i;
for(i=0;i<8;i++)
{
result=result<<1;
if(SDO_1)
result |= 0x01;
SCLK_on;
NOP();
SCLK_off;
}
return result;
}

38
Multiprotocol/SPI.ino → Multiprotocol/spi.h

@ -15,39 +15,11 @@
/********************/ /********************/
/** SPI routines **/ /** SPI routines **/
/********************/ /********************/
void SPI_Write(uint8_t command)
{
uint8_t n=8;
#ifndef _SPI_H_
#define _SPI_H_
SCLK_off;//SCK start low
SDI_off;
do
{
if(command&0x80)
SDI_on;
else
SDI_off;
SCLK_on;
//delay(1);
command = command << 1;
SCLK_off;
}
while(--n) ;
SDI_on;
}
void SPI_Write(uint8_t command);
uint8_t SPI_Read(void);
uint8_t SPI_Read(void)
{
uint8_t result=0,i;
for(i=0;i<8;i++)
{
result=result<<1;
if(SDO_1)
result |= 0x01;
SCLK_on;
NOP();
SCLK_off;
}
return result;
}
#endif

98
Multiprotocol/state.cpp

@ -1,7 +1,9 @@
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include "state.h"
#include <stdio.h>
#include "Arduino.h" #include "Arduino.h"
#include "state.h"
#include "debug.h" #include "debug.h"
#include "tx_def.h"
LiquidCrystal_I2C lcd(0x27,16,2); LiquidCrystal_I2C lcd(0x27,16,2);
@ -10,6 +12,8 @@ State *new_state = NULL;
State *s_init = new LCD_state_init(); State *s_init = new LCD_state_init();
State *s_bind = new LCD_state_bind(); State *s_bind = new LCD_state_bind();
State *s_fly = new LCD_state_fly();
State *s_menu = new LCD_state_menu();
enum lcd_special_chars { enum lcd_special_chars {
@ -25,17 +29,17 @@ enum lcd_special_chars {
}; };
// 6 Byte-Arrays für 6 verschiedene Batteriesymbole // 6 Byte-Arrays für 6 verschiedene Batteriesymbole
__extension__ struct lcd_special_chars_data { byte data[MAX_SPECIAL_CHARS]; } __extension__ struct lcd_special_chars_data { byte data[MAX_SPECIAL_CHARS]; }
lcd_special_chars_data[MAX_SPECIAL_CHARS] =
lcd_special_chars_data[MAX_SPECIAL_CHARS] =
{ {
//[battery_0] = //[battery_0] =
{ 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111 }, { 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111 },
//[battery_33] = //[battery_33] =
{ 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b11111, 0b11111, 0b11111 }, { 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b11111, 0b11111, 0b11111 },
//[battery_66] =
//[battery_66] =
{ 0b01110, 0b11011, 0b10001, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 }, { 0b01110, 0b11011, 0b10001, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 },
//[battery_100] = //[battery_100] =
{ 0b01110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 }, { 0b01110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 },
//[rssiantenna] =
//[rssiantenna] =
{ 0b10101, 0b10101, 0b01110, 0b00100, 0b00100, 0b00101, 0b00101, 0b00101 }, { 0b10101, 0b10101, 0b01110, 0b00100, 0b00100, 0b00101, 0b00101, 0b00101 },
//[rssi_bars_1] = //[rssi_bars_1] =
{ 0b00001, 0b00001, 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101 }, { 0b00001, 0b00001, 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101 },
@ -54,12 +58,11 @@ void install_special_caracters(void)
} }
void init_state(void) { void init_state(void) {
Wire.setSDA(PB9); Wire.setSDA(PB9);
Wire.setSCL(PB8); Wire.setSCL(PB8);
Wire.begin(); Wire.begin();
lcd.init(); lcd.init();
lcd.backlight(); lcd.backlight();
curr_state = NULL; curr_state = NULL;
new_state = s_init; new_state = s_init;
@ -86,54 +89,103 @@ void update_state(void) {
//LCD_state_init //LCD_state_init
LCD_state_init::LCD_state_init(void) { LCD_state_init::LCD_state_init(void) {
snprintf(this->line1,sizeof(this->line2)," wellcome ");
snprintf(this->line2,sizeof(this->line2)," phschoen ");
snprintf(this->line[0],sizeof(this->line[0])," wellcome ");
snprintf(this->line[1],sizeof(this->line[1])," phschoen ");
} }
void LCD_state_init::enter(void) { void LCD_state_init::enter(void) {
lcd.setCursor(0,0); lcd.setCursor(0,0);
lcd.print(this->line1);
lcd.print(this->line[0]);
lcd.setCursor(0,1); lcd.setCursor(0,1);
lcd.print(this->line2);
time_enter = millis();
lcd.print(this->line[1]);
this->time_enter = millis();
} }
void LCD_state_init::update(void) void LCD_state_init::update(void)
{ {
uint32_t diff; uint32_t diff;
diff = millis()-time_enter;
diff = millis() - this->time_enter;
if (diff > 5 * 1000) { if (diff > 5 * 1000) {
new_state = s_bind; new_state = s_bind;
} }
} }
void LCD_state_init::leave(void) void LCD_state_init::leave(void)
{ {
lcd.clear();
} }
//LCD_state_bind //LCD_state_bind
LCD_state_bind::LCD_state_bind(void) { LCD_state_bind::LCD_state_bind(void) {
snprintf(this->line1,sizeof(this->line2),"bind mode ");
snprintf(this->line2,sizeof(this->line2)," ");
snprintf(this->line[0],sizeof(this->line[0]),"bind mode ");
snprintf(this->line[1],sizeof(this->line[1])," ");
this->bind_time = 20; this->bind_time = 20;
} }
void LCD_state_bind::enter(void) { void LCD_state_bind::enter(void) {
lcd.setCursor(0,0); lcd.setCursor(0,0);
lcd.print(this->line1);
lcd.print(this->line[0]);
lcd.setCursor(0,1); lcd.setCursor(0,1);
lcd.print(this->line2);
lcd.print(this->line[1]);
this->time_enter = millis(); this->time_enter = millis();
} }
void LCD_state_bind::update(void) void LCD_state_bind::update(void)
{ {
debugln("blubber\n"); debugln("blubber\n");
unsigned long remain = millis() - this->time_enter;
remain = remain/1000; // to sec
remain = this->bind_time - remain;
snprintf(this->line2,sizeof(this->line2),"remaining sec %02d",remain);
unsigned long time_in_ms = millis() - this->time_enter;
unsigned long time_in_s = time_in_ms/1000; // to sec
unsigned long remain_s = this->bind_time - time_in_s;
snprintf(this->line[0],sizeof(this->line[1]),"remaining sec %02d",remain_s);
lcd.setCursor(0,1); lcd.setCursor(0,1);
lcd.print(this->line2);
time_enter = millis();
lcd.print(this->line[0]);
if (time_in_s >= this->bind_time)
new_state = s_menu;
} }
void LCD_state_bind::leave(void) void LCD_state_bind::leave(void)
{
lcd.clear();
}
// LCD_state_menu
LCD_state_menu::LCD_state_menu(void) {
snprintf(this->line[0],sizeof(this->line[0]),"Menubind mode ");
snprintf(this->line[1],sizeof(this->line[1])," ");
this->curr_selected = 0;
}
void LCD_state_menu::enter(void) {
lcd.setCursor(0,0);
lcd.print(this->line[0]);
lcd.setCursor(0,1);
lcd.print(this->line[1]);
this->time_enter = millis();
}
void LCD_state_menu::update(void)
{ {
} }
void LCD_state_menu::leave(void)
{
lcd.clear();
}
// LCD_state_fly
LCD_state_fly::LCD_state_fly(void) {
snprintf(this->line[0],sizeof(this->line[0]),"fly mode ");
snprintf(this->line[1],sizeof(this->line[1])," ");
}
void LCD_state_fly::enter(void) {
lcd.setCursor(0,0);
lcd.print(this->line[0]);
lcd.setCursor(0,1);
lcd.print(this->line[1]);
this->time_enter = millis();
}
void LCD_state_fly::update(void)
{
}
void LCD_state_fly::leave(void)
{
lcd.clear();
}

29
Multiprotocol/state.h

@ -3,6 +3,7 @@
#define _STATE_H_ #define _STATE_H_
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include <stdint.h>
void init_state(void); void init_state(void);
@ -10,9 +11,8 @@ void update_state(void);
class State { class State {
protected: protected:
char line1[17];
char line2[17];
char line[2][17];
public: public:
virtual void enter(void) { virtual void enter(void) {
@ -50,13 +50,34 @@ public:
void leave(void); void leave(void);
}; };
class LCD_state_flight: public State {
class LCD_state_fly: public State {
private: private:
unsigned long time_enter; unsigned long time_enter;
public: public:
LCD_state_fly(void);
void enter(void); void enter(void);
void update(void); void update(void);
void leave(void); void leave(void);
}; };
class LCD_state_menu: public State {
private:
unsigned long time_enter;
uint8_t curr_selected;
public:
LCD_state_menu(void);
void enter(void);
void update(void);
void leave(void);
};
extern State *curr_state;
extern State *new_state;
extern State *s_init;
extern State *s_bind;
extern State *s_fly;
extern State *s_menu;
#endif /*_STATE_H_*/ #endif /*_STATE_H_*/

217
Multiprotocol/tx_def.h

@ -0,0 +1,217 @@
#ifndef _TX_DEV_H_
#define _TX_DEV_H_
// Turnigy PPM and channels
#if defined(TX_ER9X)
#define PPM_MAX_100 2012 // 100%
#define PPM_MIN_100 988 // 100%
#endif
// Devo PPM and channels
#if defined(TX_DEVO7)
#define PPM_MAX_100 1920 // 100%
#define PPM_MIN_100 1120 // 100%
#endif
// SPEKTRUM PPM and channels
#if defined(TX_SPEKTRUM)
#define PPM_MAX_100 1900 // 100%
#define PPM_MIN_100 1100 // 100%
#endif
// HISKY
#if defined(TX_HISKY)
#define PPM_MAX_100 1920 // 100%
#define PPM_MIN_100 1120 // 100%
#endif
// Multiplex MC2020
#if defined(TX_MPX)
#define PPM_MAX_100 1950 // 100%
#define PPM_MIN_100 1250 // 100%
#endif
// Walkera PL0811-01H
#if defined(TX_WALKERA)
#define PPM_MAX_100 1800 // 100%
#define PPM_MIN_100 1000 // 100%
#endif
//Channel MIN MAX values
#define CHANNEL_MAX_100 1844 // 100%
#define CHANNEL_MIN_100 204 // 100%
#define CHANNEL_MAX_125 2047 // 125%
#define CHANNEL_MIN_125 0 // 125%
#define CHANNEL_MIN_COMMAND 784 // 1350us
#define CHANNEL_SWITCH 1104 // 1550us
#define CHANNEL_MAX_COMMAND 1424 // 1750us
//Channel definitions
#ifdef AETR
#define AILERON 0
#define ELEVATOR 1
#define THROTTLE 2
#define RUDDER 3
#endif
#ifdef AERT
#define AILERON 0
#define ELEVATOR 1
#define THROTTLE 3
#define RUDDER 2
#endif
#ifdef ARET
#define AILERON 0
#define ELEVATOR 2
#define THROTTLE 3
#define RUDDER 1
#endif
#ifdef ARTE
#define AILERON 0
#define ELEVATOR 3
#define THROTTLE 2
#define RUDDER 1
#endif
#ifdef ATRE
#define AILERON 0
#define ELEVATOR 3
#define THROTTLE 1
#define RUDDER 2
#endif
#ifdef ATER
#define AILERON 0
#define ELEVATOR 2
#define THROTTLE 1
#define RUDDER 3
#endif
#ifdef EATR
#define AILERON 1
#define ELEVATOR 0
#define THROTTLE 2
#define RUDDER 3
#endif
#ifdef EART
#define AILERON 1
#define ELEVATOR 0
#define THROTTLE 3
#define RUDDER 2
#endif
#ifdef ERAT
#define AILERON 2
#define ELEVATOR 0
#define THROTTLE 3
#define RUDDER 1
#endif
#ifdef ERTA
#define AILERON 3
#define ELEVATOR 0
#define THROTTLE 2
#define RUDDER 1
#endif
#ifdef ETRA
#define AILERON 3
#define ELEVATOR 0
#define THROTTLE 1
#define RUDDER 2
#endif
#ifdef ETAR
#define AILERON 2
#define ELEVATOR 0
#define THROTTLE 1
#define RUDDER 3
#endif
#ifdef TEAR
#define AILERON 2
#define ELEVATOR 1
#define THROTTLE 0
#define RUDDER 3
#endif
#ifdef TERA
#define AILERON 3
#define ELEVATOR 1
#define THROTTLE 0
#define RUDDER 2
#endif
#ifdef TREA
#define AILERON 3
#define ELEVATOR 2
#define THROTTLE 0
#define RUDDER 1
#endif
#ifdef TRAE
#define AILERON 2
#define ELEVATOR 3
#define THROTTLE 0
#define RUDDER 1
#endif
#ifdef TARE
#define AILERON 1
#define ELEVATOR 3
#define THROTTLE 0
#define RUDDER 2
#endif
#ifdef TAER
#define AILERON 1
#define ELEVATOR 2
#define THROTTLE 0
#define RUDDER 3
#endif
#ifdef RETA
#define AILERON 3
#define ELEVATOR 1
#define THROTTLE 2
#define RUDDER 0
#endif
#ifdef REAT
#define AILERON 2
#define ELEVATOR 1
#define THROTTLE 3
#define RUDDER 0
#endif
#ifdef RAET
#define AILERON 1
#define ELEVATOR 2
#define THROTTLE 3
#define RUDDER 0
#endif
#ifdef RATE
#define AILERON 1
#define ELEVATOR 3
#define THROTTLE 2
#define RUDDER 0
#endif
#ifdef RTAE
#define AILERON 2
#define ELEVATOR 3
#define THROTTLE 1
#define RUDDER 0
#endif
#ifdef RTEA
#define AILERON 3
#define ELEVATOR 2
#define THROTTLE 1
#define RUDDER 0
#endif
#define CH1 0
#define CH2 1
#define CH3 2
#define CH4 3
#define CH5 4
#define CH6 5
#define CH7 6
#define CH8 7
#define CH9 8
#define CH10 9
#define CH11 10
#define CH12 11
#define CH13 12
#define CH14 13
#define CH15 14
#define CH16 15
#define NUM_CHN 16
#endif /* _TX_DEV_H_ */

57
config

@ -0,0 +1,57 @@
resource MOTOR 1 A03
resource MOTOR 2 B08
resource MOTOR 3 A02
resource MOTOR 4 B09
resource PWM 1 D07
resource PWM 2 C08
resource PWM 3 K05
resource PWM 4 D04
resource PWM 5 B02
resource PWM 7 B01
resource PWM 8 A02
feature -RX_PPM
feature -OSD
feature RX_SERIAL
feature LED_STRIP
beeper -GPS_STATUS
beeper -ON_USB
beeper -CAM_CONNECTION_OPEN
beeper -CAM_CONNECTION_CLOSED
serial 2 64 115200 57600 0 115200
led 0 1,0::CW:0
led 1 0,0::CW:0
aux 0 0 0 1650 2100 0
aux 1 1 1 1600 2100 0
aux 2 2 1 925 1400 0
aux 3 27 0 1475 2100 0
set acc_calibration = 46,25,-115
set baro_hardware = NONE
set mid_rc = 1518
set min_check = 1003
set max_check = 1995
set serialrx_provider = SBUS
set blackbox_device = NONE
set align_board_yaw = 270
set bat_capacity = 750
profile 0
profile 1
profile 2
profile 2
rateprofile 0
rateprofile 1
rateprofile 2
rateprofile 3
rateprofile 4
rateprofile 5
rateprofile 0
save
Loading…
Cancel
Save