Browse Source

implement fly mode with lcd

master
Schoenberger, Philipp 6 years ago
parent
commit
85b0024366
No known key found for this signature in database GPG Key ID: 77E9DF7A0452BF64
  1. 20
      remote/include/FrSkyD_cc2500.h
  2. 10
      remote/include/Multiprotocol.h
  3. 51
      remote/include/common.h
  4. 1
      remote/include/config.h
  5. 2
      remote/include/eeprom.h
  6. 10
      remote/include/input.h
  7. 31
      remote/include/pins.h
  8. 11
      remote/include/state.h
  9. 113
      remote/src/FrSkyD_cc2500.cpp
  10. 246
      remote/src/Multiprotocol.cpp
  11. 19
      remote/src/common.ds
  12. 3
      remote/src/config.cpp
  13. 8
      remote/src/eeprom.cpp
  14. 44
      remote/src/input.cpp
  15. 1
      remote/src/state_bind.cpp
  16. 173
      remote/src/state_fly.cpp
  17. 6
      remote/src/state_init.cpp
  18. 1
      remote/src/state_menu.cpp

20
remote/include/FrSkyD_cc2500.h

@ -17,8 +17,27 @@
#define _FRSKYD_CC2500_H_
#include <stdint.h>
enum {
FRSKY_BIND = 0,
FRSKY_BIND_DONE = 1000,
FRSKY_DATA1,
FRSKY_DATA2,
FRSKY_DATA3,
FRSKY_DATA4,
FRSKY_DATA5
};
#define MAX_PKT 29
extern uint8_t pkt[MAX_PKT];//telemetry receiving packets
extern uint8_t freq_offset;
extern uint16_t state;
void Frsky_init_hop(void);
void FRSKY_init_cc2500(const uint8_t *ptr);
void frsky2way_init(uint8_t bind);
void frsky2way_build_bind_packet();
@ -30,4 +49,5 @@ uint16_t ReadFrSky_2way(void);
uint16_t ReadFrSky_2way_bind(void);
uint16_t convert_channel_frsky(uint8_t num);
void set_rx_tx_addr(uint32_t id);
#endif

10
remote/include/Multiprotocol.h

@ -24,24 +24,15 @@
#include "stdint.h"
void set_rx_tx_addr(uint32_t id);
#define MAX_PKT 29
extern uint8_t hopping_frequency_no;
extern uint8_t sub_protocol;
extern uint8_t calData[48];
extern uint32_t MProtocol_id_master;
extern uint8_t protocol_flags;
extern uint8_t protocol_flags2;
extern uint8_t pkt[MAX_PKT];//telemetry receiving packets
extern uint8_t prev_option;
extern uint8_t crc8;
extern uint8_t packet_count;
extern uint8_t RX_num;
extern uint8_t binding_idx;
extern uint8_t packet[40];
extern uint8_t rx_tx_addr[5];
extern uint8_t option;
extern uint16_t state;
extern uint16_t seed;
extern uint8_t phase;
extern uint8_t len;
@ -86,7 +77,6 @@ enum MultiPacketTypes
//
#define BIND_BUTTON_FLAG_on protocol_flags |= _BV(5)
#define BIND_BUTTON_FLAG_off protocol_flags &= ~_BV(5)
#define IS_BIND_BUTTON_FLAG_on ( ( protocol_flags & _BV(5) ) !=0 )
//Bind flag
#define BIND_IN_PROGRESS protocol_flags &= ~_BV(7)
#define BIND_DONE protocol_flags |= _BV(7)

51
remote/include/common.h

@ -1,51 +0,0 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdint.h>
#include "config.h"
#include "tx_def.h"
void InitChannel(void);
/******************************/
/** FrSky D and X routines **/
/******************************/
enum {
FRSKY_BIND = 0,
FRSKY_BIND_DONE = 1000,
FRSKY_DATA1,
FRSKY_DATA2,
FRSKY_DATA3,
FRSKY_DATA4,
FRSKY_DATA5
};
/******************************/
/** 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[];
extern uint8_t FRSKYD_cc2500_conf[];
extern uint8_t FRSKY_common_end_cc2500_conf[][2];
void FRSKY_init_cc2500(const uint8_t *ptr);
#endif
#endif

1
remote/include/config.h

@ -163,7 +163,6 @@
/*** PPM MODE SETTINGS ***/
/*************************/
#define NBR_BANKS 1
extern uint8_t curr_bank;
struct PPM_Parameters
{

2
remote/include/eeprom.h

@ -21,7 +21,7 @@ public:
int set_master_id(uint32_t master_id);
private:
#define CURRENT_VERSION 0x01
#define CURRENT_VERSION 0x02
struct eeprom_data_v1 {
uint8_t version;
uint32_t data_crc;

10
remote/include/input.h

@ -18,7 +18,6 @@ class Input {
CH_AUX3 = 6,
CH_AUX4 = 7,
CH_AUX5 = 8,
CH_AUX6 = 8,
CH_MAX = 8,
CH_COUNT = 9,
@ -49,6 +48,7 @@ class Input {
void invert_ch(enum input_channels ch);
void print_ch(enum input_channels ch);
void print();
void calibration_reset(void);
bool calibration_update(void);
@ -69,8 +69,8 @@ class Input {
};
// actual tx channel data
uint16_t channel_data[CH_COUNT];
uint16_t failsafe_data[CH_COUNT];
uint16_t channel_data[NUM_TX_CHN];
uint16_t failsafe_data[NUM_TX_CHN];
struct data input[2];
struct data* curr;
@ -80,9 +80,9 @@ class Input {
struct ch_config ch_config[CH_COUNT];
// pin setttings
uint32_t pins[CH_COUNT];
int pins[CH_COUNT];
};
extern const char* ch_name[NUM_TX_CHN];
extern const char* ch_name[Input::CH_COUNT];
extern Input input;
#endif

31
remote/include/pins.h

@ -18,12 +18,6 @@
#include "Arduino.h"
#define LED_off
#define LED_on
#define LED_output
#define IS_LED_on false
#define LED_toggle
//
#define SDI_pin PA0 /* SDIO MOSI */
#define SCLK_pin PA1 /* SCLK */
@ -37,18 +31,29 @@
#define Roll_pin PA7
#define Pitch_pin PA6
#define Aux1_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 Aux1_pin PB1
#define Aux2_pin PB10
#define Aux3_pin PB11
#define Aux4_pin PB13
#define Aux5_pin PB15
#define Menu_pin PB12
#define Battery_pin PA9
#define Led_pin PC13
#define Buzzer_pin PA8
#define cli()
#define sei()
#define NOP() __asm__ __volatile__("nop")
#define BUZZER_off digitalWrite(Buzzer_pin, LOW)
#define BUZZER_on digitalWrite(Buzzer_pin, HIGH)
#define BUZZER_output pinMode(Buzzer_pin, OUTPUT)
#define LED_off digitalWrite(Led_pin, LOW)
#define LED_on digitalWrite(Led_pin, HIGH)
#define LED_output pinMode(Led_pin,OUTPUT)
#define SDI_on digitalWrite(SDI_pin, HIGH)
#define SDI_off digitalWrite(SDI_pin, LOW)
#define SDI_1 (digitalRead(SDI_pin) == HIGH)

11
remote/include/state.h

@ -8,9 +8,12 @@
extern LiquidCrystal_I2C lcd;
enum lcd_special_chars {
battery_char = 0,
rssiantenna= 1,
rssi_bars = 2,
clock_char = 3,
battery_char_1 = 0,
battery_char_2 = 1,
rssiantenna= 3,
rssi_bars = 4,
clock_char = 5,
MAX_SPECIAL_CHARS =8,
};
@ -61,6 +64,8 @@ public:
class LCD_state_fly: public State {
private:
unsigned long time_enter;
uint16_t last_time;
void print_akku(uint8_t akku_quad, uint8_t akku_remote);
void print_rssi(uint8_t rssi_percent);
void print_time(uint16_t time);

113
remote/src/FrSkyD_cc2500.cpp

@ -13,17 +13,85 @@
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include "cc2500_spi.h"
#include "Multiprotocol.h"
#include "input.h"
#include "FrSkyD_cc2500.h"
#include "common.h"
uint8_t rx_tx_addr[5];
uint8_t hopping_frequency[50];
uint8_t pkt[MAX_PKT];//telemetry receiving packets
uint16_t state;
uint16_t counter;
uint8_t freq_offset;
uint8_t freq_offset_prev;
const uint8_t FRSKY_common_startreg_cc2500_conf[] = {
CC2500_02_IOCFG0 ,
CC2500_00_IOCFG2 ,
CC2500_17_MCSM1 ,
CC2500_18_MCSM0 ,
CC2500_06_PKTLEN ,
CC2500_07_PKTCTRL1 ,
CC2500_08_PKTCTRL0 ,
CC2500_3E_PATABLE ,
CC2500_0B_FSCTRL1 ,
CC2500_0C_FSCTRL0 , // replaced by frequency offset value
CC2500_0D_FREQ2 ,
CC2500_0E_FREQ1 ,
CC2500_0F_FREQ0 ,
CC2500_10_MDMCFG4 ,
CC2500_11_MDMCFG3 ,
CC2500_12_MDMCFG2 ,
CC2500_13_MDMCFG1 ,
CC2500_14_MDMCFG0 ,
CC2500_15_DEVIATN
};
const uint8_t FRSKY_common_end_cc2500_conf[][2] = {
{ CC2500_19_FOCCFG, 0x16 },
{ CC2500_1A_BSCFG, 0x6c },
{ CC2500_1B_AGCCTRL2, 0x43 },
{ CC2500_1C_AGCCTRL1, 0x40 },
{ CC2500_1D_AGCCTRL0, 0x91 },
{ CC2500_21_FREND1, 0x56 },
{ CC2500_22_FREND0, 0x10 },
{ CC2500_23_FSCAL3, 0xa9 },
{ CC2500_24_FSCAL2, 0x0A },
{ CC2500_25_FSCAL1, 0x00 },
{ CC2500_26_FSCAL0, 0x11 },
{ CC2500_29_FSTEST, 0x59 },
{ CC2500_2C_TEST2, 0x88 },
{ CC2500_2D_TEST1, 0x31 },
{ CC2500_2E_TEST0, 0x0B },
{ CC2500_03_FIFOTHR, 0x07 },
{ CC2500_09_ADDR, 0x00 }
};
const 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
};
void frsky2way_init(uint8_t bind)
{
//debugln("frsky2way_init");
@ -39,7 +107,7 @@ void frsky2way_init(uint8_t bind)
//#######END INIT########
}
void frsky2way_build_bind_packet()
void frsky2way_build_bind_packet(void)
{
//debugln("build bind");
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
@ -192,10 +260,12 @@ uint16_t ReadFrSky_2way()
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
if ( prev_option != option ) {
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
prev_option = option ;
// Frequency offset update
if ( freq_offset_prev != freq_offset) {
CC2500_WriteReg(CC2500_0C_FSCTRL0, freq_offset);
freq_offset_prev = freq_offset;
}
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
CC2500_Strobe(CC2500_SFRX);
frsky2way_data_frame();
@ -236,3 +306,34 @@ void Frsky_init_hop(void)
hopping_frequency[i] = i > 46 ? 0 : val;
}
}
void FRSKY_init_cc2500(const uint8_t *ptr)
{
for (uint8_t i = 0; i < 19; i++)
{
uint8_t reg = FRSKY_common_startreg_cc2500_conf[i];
uint8_t val = ptr[i];
if (reg == CC2500_0C_FSCTRL0)
val = freq_offset;
CC2500_WriteReg(reg, val);
}
freq_offset_prev = freq_offset;
for (uint8_t i = 0; i < 17; i++)
{
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_SetTxRxMode(TX_EN);
CC2500_SetPower();
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
}
void set_rx_tx_addr(uint32_t id)
{ // Used by almost all protocols
rx_tx_addr[0] = (id >> 24) & 0xFF;
rx_tx_addr[1] = (id >> 16) & 0xFF;
rx_tx_addr[2] = (id >> 8) & 0xFF;
rx_tx_addr[3] = (id >> 0) & 0xFF;
rx_tx_addr[4] = (rx_tx_addr[2]&0xF0)|(rx_tx_addr[3]&0x0F);
}

246
remote/src/Multiprotocol.cpp

@ -33,7 +33,6 @@
#include "pins.h"
#include "Validate.h"
#include "common.h"
#include "state.h"
#include "input.h"
#include "cc2500_spi.h"
@ -43,21 +42,14 @@
#include "FrSkyD_cc2500.h"
//Global constants/variables
uint32_t MProtocol_id;//tx id,
uint32_t MProtocol_id_master;
uint32_t blink=0,last_signal=0;
uint8_t protocol_flags=0,protocol_flags2=0;
//
uint8_t channel;
uint8_t packet[40];
static void protocol_init(void);
uint16_t seed;
// Protocol variables
uint8_t cyrfmfg_id[6];//for dsm2 and devo
uint8_t rx_tx_addr[5];
uint8_t rx_id[4];
uint8_t phase;
uint16_t bind_counter;
@ -68,260 +60,66 @@ uint8_t packet_count;
uint8_t packet_sent;
uint8_t packet_length;
uint8_t *hopping_frequency_ptr;
uint8_t hopping_frequency_no=0;
uint8_t rf_ch_num;
uint8_t throttle, rudder, elevator, aileron;
uint8_t flags;
uint16_t crc;
uint8_t crc8;
uint16_t failsafe_count;
uint8_t len;
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO)
uint8_t calData[48];
#endif
// Mode_select variables
uint8_t mode_select;
#if not defined (ORANGE_TX) && not defined (STM32_BOARD)
//Random variable
volatile uint32_t gWDT_entropy=0;
#endif
//Serial protocol
uint8_t sub_protocol;
uint8_t protocol;
uint8_t option;
uint8_t cur_protocol[3];
uint8_t prev_option;
uint8_t RX_num;
//Serial RX variables
#define BAUD 100000
#define RXBUFFER_SIZE 26
volatile uint8_t rx_buff[RXBUFFER_SIZE];
volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
volatile uint8_t discard_frame = 0;
// Telemetry
uint8_t pkt[MAX_PKT];//telemetry receiving packets
float TIMER_PRESCALE = 5.82;
// Callback
typedef uint16_t (*void_function_t) (void);//pointer to a function with no parameters which return an uint16_t integer
void_function_t remote_callback = 0;
//forward declarations
void modules_reset();
uint32_t random_id(bool create_new);
// Init
void setup()
{
// Setup diagnostic uart before anything else
#ifdef ENABLE_DBEUG
Serial.begin(115200,SERIAL_8N1);
delay(1000);
while (!Serial); // Wait for ever for the serial port to connect...
delay(1000);
debugln("Multiprotocol startup");
debugln("time %s ", __TIME__);
#endif
// all inputs
// outputs
SDI_output;
SCLK_output;
CC25_CSN_output;
// all inputs
// outputs
SDI_output;
SCLK_output;
CC25_CSN_output;
// Random
//random_init();
CC25_CSN_on;
SDI_on;
SCLK_off;
// Random
//random_init();
CC25_CSN_on;
SDI_on;
SCLK_off;
//Wait for every component to start
delay(100);
// Read status of bind button
if( /*IS_BIND_BUTTON_on */ true)
{
BIND_BUTTON_FLAG_on; // If bind button pressed save the status
BIND_IN_PROGRESS; // Request bind
}
else
BIND_DONE;
// Read status of mode select binary switch
// after this mode_select will be one of {0000, 0001, ..., 1111}
String str;
debugln("select bank:");
str="";
while(true) {
if (Serial.available() > 0) {
char recieved = Serial.read();
if (recieved == '\n') {
int new_bank = atoi(str.c_str());
curr_bank = new_bank;
debugln("Bank selection %d", new_bank);
break;
}else {
str += recieved;
}
}
}
debugln("select mode:");
str="";
while(true) {
if (Serial.available() > 0) {
char recieved = Serial.read();
if (recieved == '\n') {
int new_mode = atoi(str.c_str());
debugln("Protocol selection switch reads as %d with \'%s\'", new_mode,str.c_str());
mode_select = new_mode;
break;
}else {
str += recieved;
}
}
}
debugln("Protocol selection switch reads as %d", mode_select);
BIND_IN_PROGRESS; // Request bind
// Update LED
LED_off;
LED_output;
//Init RF modules
modules_reset();
{
seed = analogRead(PA0);
randomSeed(seed);
}
// Read or create protocol id
MProtocol_id_master=random_id(false);
debugln("Module Id: %lx", MProtocol_id_master);
//Protocol and interrupts initialization
//frquency offset initialization
{
uint8_t line=curr_bank*14+mode_select-1;
protocol = PPM_prot[line].protocol;
cur_protocol[1] = protocol;
sub_protocol = PPM_prot[line].sub_proto;
RX_num = PPM_prot[line].rx_num;
debug("protocol: %d ", protocol);
switch(protocol) {
case PROTO_FRSKYD:
debugln("PROTO_FRSKYD");
break;
case PROTO_FRSKYX:
debugln("PROTO_FRSKYX");
break;
case PROTO_FRSKYV:
debugln("PROTO_FRSKYV");
break;
}
debug("sub_protocol: %d\n", sub_protocol);
option = PPM_prot[line].option; // Use radio-defined option value
debug("freq offset: %d\n", option);
line++;
freq_offset = 0;
debug("freq offset: %d\n", freq_offset);
CC2500_Reset();
protocol_init();
//Wait for cc2500 to reset
delay(100);
}
debug("Init complete\n");
input.init();
input.update();
init_state();
debug("Init complete\n");
}
// Main
// Protocol scheduler
void loop()
{
uint32_t s;
s =micros();
input.update();
s =micros();
update_state();
return;
uint32_t next_callback;
uint32_t end__ = micros();
uint32_t start = micros();
while(1) {
start = end__;
next_callback = remote_callback();
if (next_callback > 4000) {
uint32_t s;
s =micros();
input.update();
debug("input took %lu", (micros()-s));
s =micros();
update_state();
debugln("state took %lu", (micros()-s));
}
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__ = micros();
}
}
// Protocol start
static void protocol_init() {
modules_reset(); // Reset all modules
uint32_t next_callback = 0;
//Set global ID and rx_tx_addr
MProtocol_id = RX_num + MProtocol_id_master;
set_rx_tx_addr(MProtocol_id);
debugln("Protocol selected: %d, sub proto %d, rxnum %d, option %d", protocol, sub_protocol, RX_num, option);
switch(protocol) // Init the requested protocol
{
case PROTO_FRSKYD:
next_callback = initFrSky_2way();
remote_callback = ReadFrSky_2way;
break;
}
delayMicroseconds(next_callback);
}
void modules_reset()
{
CC2500_Reset();
//Wait for every component to reset
delay(100);
}
// Convert 32b id to rx_tx_addr
void set_rx_tx_addr(uint32_t id)
{ // Used by almost all protocols
rx_tx_addr[0] = (id >> 24) & 0xFF;
rx_tx_addr[1] = (id >> 16) & 0xFF;
rx_tx_addr[2] = (id >> 8) & 0xFF;
rx_tx_addr[3] = (id >> 0) & 0xFF;
rx_tx_addr[4] = (rx_tx_addr[2]&0xF0)|(rx_tx_addr[3]&0x0F);
}
uint32_t random_id(bool create_new)
{
}

19
remote/src/common.cpp → remote/src/common.ds

@ -147,25 +147,6 @@ uint8_t FRSKYXEU_cc2500_conf[] = {
};
#endif
uint8_t FRSKY_common_end_cc2500_conf[][2] = {
{ CC2500_19_FOCCFG, 0x16 },
{ CC2500_1A_BSCFG, 0x6c },
{ CC2500_1B_AGCCTRL2, 0x43 },
{ CC2500_1C_AGCCTRL1, 0x40 },
{ CC2500_1D_AGCCTRL0, 0x91 },
{ CC2500_21_FREND1, 0x56 },
{ CC2500_22_FREND0, 0x10 },
{ CC2500_23_FSCAL3, 0xa9 },
{ CC2500_24_FSCAL2, 0x0A },
{ CC2500_25_FSCAL1, 0x00 },
{ CC2500_26_FSCAL0, 0x11 },
{ CC2500_29_FSTEST, 0x59 },
{ CC2500_2C_TEST2, 0x88 },
{ CC2500_2D_TEST1, 0x31 },
{ CC2500_2E_TEST0, 0x0B },
{ CC2500_03_FIFOTHR, 0x07 },
{ CC2500_09_ADDR, 0x00 }
};
void FRSKY_init_cc2500(const uint8_t *ptr)
{

3
remote/src/config.cpp

@ -13,10 +13,9 @@
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]= {
//****************************** BANK 1 ******************************
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
// 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 },

8
remote/src/eeprom.cpp

@ -32,14 +32,14 @@ int Eeprom_config::validate() {
}
if (this->current_config.version != CURRENT_VERSION) {
debugln("wrong version %d vs %d \n", this->current_config.version, CURRENT_VERSION);
debugln("wrong version %lu vs %lu \n", this->current_config.version, CURRENT_VERSION);
return -1;
}
crc_calc = tiny_crc32(&(this->current_config.data), sizeof(this->current_config.data));
if (crc_calc != this->current_config.data_crc) {
debugln("wrong version %d vs %d \n", crc_calc, this->current_config.data_crc);
debugln("wrong crc %lu vs %lu \n", crc_calc, this->current_config.data_crc);
return -1;
}
debugln("valid config\n");
@ -48,16 +48,12 @@ int Eeprom_config::validate() {
int Eeprom_config::read(void) {
uint8_t *data = NULL;
debugln("enter \n");
data = (uint8_t *) &this->current_config;
debugln("for start\n");
for (uint8_t i = 0; i < sizeof(struct eeprom_data_v1) ; i++) {
data[i] = EEPROM.read(0x10 + i);
debugln("Read %d\n",i);
}
debugln("Read end\n");
this->sucessfull_read = true;
return 0;
}

44
remote/src/input.cpp

@ -9,7 +9,7 @@
Input input;
const char* ch_name[NUM_TX_CHN] = {
const char* ch_name[Input::CH_COUNT] = {
"CH_ROLL",
"CH_PITCH",
"CH_THROTTLE",
@ -20,24 +20,23 @@ const char* ch_name[NUM_TX_CHN] = {
"CH_AUX3",
"CH_AUX4",
"CH_AUX5",
"CH_AUX6"
};
Input::Input(void) {
uint8_t i;
this->curr = &(this->input[0]);
this->old = &(this->input[1]);
memset(this->input,0, sizeof(this->input));
//InitFailsafe
for (uint8_t i = 0; i < NUM_TX_CHN; i++)
for (i = 0; i < NUM_TX_CHN; i++) {
//InitFailsafe
this->failsafe_data[i] = (CHANNEL_MAX_100 - CHANNEL_MIN_100) / 2 + CHANNEL_MIN_100;
this->failsafe_data[CH_THROTTLE] = CHANNEL_MIN_100; //1=-125%, 204=-100%
// init channel
for (uint8_t i = 0; i < NUM_TX_CHN; i++)
// init channel
this->channel_data[i] = 1024;
this->channel_data[CH_THROTTLE] = 204;
}
this->failsafe_data[CH_THROTTLE] = CHANNEL_MIN_100; //1=-125%, 204=-100%
this->channel_data[CH_THROTTLE] = CHANNEL_MIN_100;
}
uint16_t* Input::get_channel_data(void) {
@ -77,9 +76,6 @@ void Input::init() {
this->pins[CH_AUX5] = Aux5_pin;
this->ch_config[CH_AUX5].is_analog = false;
this->pins[CH_AUX6] = Aux6_pin;
this->ch_config[CH_AUX6].is_analog = false;
for (uint8_t i = 0; i < CH_COUNT; ++i) {
pinMode(this->pins[i], INPUT);
}
@ -96,7 +92,6 @@ void Input::init() {
this->ch_config[CH_AUX2].inverted = false;
this->ch_config[CH_AUX3].inverted = false;
this->ch_config[CH_AUX4].inverted = false;
this->ch_config[CH_AUX5].inverted = false;
}
bool Input::is_centered(void) {
@ -145,10 +140,11 @@ void Input::invert_ch(enum Input::input_channels ch) {
this->ch_config[ch].inverted = !this->ch_config[ch].inverted;
}
void Input::print_ch(enum Input::input_channels ch) {
debug("ch%d: %04d %04d min %d max %d high %d mid %d low %d\n",
debug("ch%d: %04d %04d %04d min %d max %d high %d mid %d low %d\n",
ch,
this->ch_raw[ch],
this->curr->ch_data[ch],
this->old->ch_data[ch],
this->ch_config[ch].min,
this->ch_config[ch].max,
this->is_high((enum Input::input_channels)ch),
@ -156,6 +152,17 @@ void Input::print_ch(enum Input::input_channels ch) {
this->is_low((enum Input::input_channels)ch)
);
}
void Input::print() {
debug("menu %d (old %d)\n", this->curr->menu, this->old->menu);
for (uint8_t i = 0; i < CH_COUNT; ++i) {
print_ch((enum Input::input_channels) i);
}
for (uint8_t i = 0; i < NUM_TX_CHN; ++i) {
debug("chdata %d \n", this->channel_data[i]);
}
}
bool Input::calibration_update(void) {
bool changed = false;
@ -201,12 +208,14 @@ void Input::get_calibration(struct ch_config *curr_config)
}
void Input::update(void) {
this->mark_processed();
for (uint8_t ch = 0; ch < CH_MAX; ch ++) {
if (this->ch_config[ch].is_analog)
if (this->ch_config[ch].is_analog) {
this->ch_raw[ch] = analogRead(this->pins[ch]);
else
} else {
this->ch_raw[ch] = digitalRead(this->pins[ch]) == HIGH;
}
// do inverting
if (this->ch_config[ch].inverted)
@ -234,4 +243,3 @@ void Input::update(void) {
this->curr->aux[4],this->curr->aux[5],this->curr->menu
);*/
}
// Channel value for FrSky (PPM is multiplied by 1.5)

1
remote/src/state_bind.cpp

@ -54,7 +54,6 @@ void LCD_state_bind::update(void)
lcd.setCursor(14,1);
lcd.print(line);
uint32_t wait_until = start + next_callback_time;
end__ = micros();
if (end__ - start < next_callback_time) {

173
remote/src/state_fly.cpp

@ -7,30 +7,20 @@
#include "eeprom.h"
#include "debug.h"
#include "tx_def.h"
#include "common.h"
LCD_state_fly::LCD_state_fly(void) {
}
void LCD_state_fly::enter(void) {
this->last_time = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("fly mode ");
lcd.setCursor(0,1);
lcd.print(" ");
this->time_enter = millis();
}
void LCD_state_fly::print_time(uint16_t time)
{
/**
* 0123456789012345
* fly mode A PP
* T SSS AA PP A PP
**/
char line[17];
lcd.setCursor(0,1);
byte clock_char_data[8] = {
byte clock_char_data[] = {
0b01110,
0b10101,
0b10101,
@ -41,9 +31,52 @@ void LCD_state_fly::print_time(uint16_t time)
0b00000
};
lcd.createChar(clock_char, clock_char_data);
lcd.setCursor(0,1);
lcd.write(clock_char);
snprintf(line, sizeof(line), "%*d", 3, time);
byte rssi_antenna_[] = {
0b10101,
0b10001,
0b01110,
0b00100,
0b00100,
0b00100,
0b00101,
0b00101, };
lcd.createChar(rssiantenna, rssi_antenna_);
lcd.setCursor(6,1);
lcd.write(rssiantenna);
byte rssi_bars_[] = {
0b00001,
0b00001,
0b00001,
0b00001,
0b00101,
0b00101,
0b10101,
0b10101 };
lcd.createChar(rssi_bars, rssi_bars_);
lcd.setCursor(7,1);
lcd.write(rssi_bars);
}
void LCD_state_fly::print_time(uint16_t time)
{
char line[17];
/**
* 0123456789012345
* fly mode A PP
* T SSS AA PP A PP
**/
if(this->last_time==time)
return;
this->last_time=time;
lcd.setCursor(1,1);
snprintf(line, sizeof(line), "%*u", 3, time);
lcd.print(line);
}
void LCD_state_fly::print_akku(uint8_t akku_quad, uint8_t akku_remote)
@ -57,8 +90,7 @@ void LCD_state_fly::print_akku(uint8_t akku_quad, uint8_t akku_remote)
char line[17];
uint8_t akku[] = {akku_remote, akku_quad};
for (uint8_t i = 0; i < 2; ++i) {
lcd.setCursor(12,i);
for (int i = 0; i < 2; ++i) {
battery_char_data[0] = 0b01110;
battery_char_data[1] = ( akku[i] > 90) ? 0b11111 : 0b11011;
battery_char_data[2] = ( akku[i] > 75) ? 0b11111 : 0b10001;
@ -67,44 +99,29 @@ void LCD_state_fly::print_akku(uint8_t akku_quad, uint8_t akku_remote)
battery_char_data[5] = ( akku[i] > 30) ? 0b11111 : 0b10001;
battery_char_data[6] = ( akku[i] > 15) ? 0b11111 : 0b10001;
battery_char_data[7] = 0b11111;
lcd.createChar(battery_char, battery_char_data);
lcd.write(battery_char);
snprintf(line, sizeof(line), " %*d", 2, akku[i]);
lcd.createChar(battery_char+i, battery_char_data);
lcd.setCursor(12,i);
lcd.write(battery_char+i);
lcd.setCursor(13,i);
snprintf(line, sizeof(line), "%*d", 3, akku[i]);
lcd.print(line);
}
return;
}
void LCD_state_fly::print_rssi(uint8_t rssi_percent)
{
char line[17];
byte rssi_antenna[8] = { 0b10101, 0b10101, 0b01110, 0b00100, 0b00100, 0b00101, 0b00101, 0b00101 };
byte rssi_antenna_1[8] = { 0b00001, 0b00001, 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101 };
byte rssi_antenna_2[8] = { 0b00001, 0b00001, 0b00001, 0b00001, 0b10101, 0b10101, 0b10101, 0b10101 };
byte rssi_antenna_3[8] = { 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101, 0b10101, 0b10101 };
lcd.setCursor(6,1);
lcd.createChar(rssiantenna, rssi_antenna);
lcd.write(rssiantenna);
if (rssi_percent > 75) {/* 100-75 -> 3 */
lcd.createChar(rssi_bars, rssi_antenna_3);
lcd.write(rssi_bars);
} else if (rssi_percent > 50) { /* 74-50 -> 2 */
lcd.createChar(rssi_bars, rssi_antenna_2);
lcd.write(rssi_bars);
} else if (rssi_percent > 25) { /* 49-25 -> 1 */
lcd.createChar(rssi_bars, rssi_antenna_1);
lcd.write(rssi_bars);
} else { /* 25-0 -> 0 */
lcd.write(' ');
}
snprintf(line, sizeof(line), " %*d", 2, rssi_percent);
lcd.setCursor(8,1);
snprintf(line, sizeof(line), "%*d", 3, rssi_percent);
lcd.print(line);
}
void LCD_state_fly::update(void)
{
uint8_t call=0;
uint8_t rssi_percent = 100;
uint8_t akku_quad = 1;
uint8_t akku_remote = 2;
@ -112,37 +129,71 @@ void LCD_state_fly::update(void)
unsigned long time_in_ms = millis() - this->time_enter;
unsigned long time_in_s = time_in_ms/1000; // to sec
snprintf(line, sizeof(line), "fly mode %02lu sec", time_in_s);
lcd.setCursor(0,1);
lcd.print(line);
this->print_time(time_in_s);
this->print_akku(akku_quad, akku_remote);
this->print_rssi(rssi_percent);
uint32_t end__ = micros();
uint32_t start = micros();
uint32_t next_callback_time;
next_callback_time = initFrSky_2way();
input.update();
// init for bind
frsky2way_init(1);
input.print();
while(1) {
start = end__;
next_callback_time = ReadFrSky_2way();
if (state == FRSKY_DATA1) {
// update time
time_in_ms = millis() - this->time_enter;
time_in_s = time_in_ms/1000; // to sec
//if (next_callback_time > 9000) {
if (next_callback_time > 9000) {
input.update();
// print on lcd
this->print_time(time_in_s);
if (input.is_menu_triggered()) {
debug("%lu menu button trigger\n", millis());
input.print();
break;
}
rssi_percent += 1;
this->print_time(rssi_percent);
akku_quad += 1;
akku_remote += 2;
this->print_akku(akku_quad, akku_remote);
// print on lcd
call +=1;
if(call > 5)
call= 0;
switch(call)
{
case 1:
rssi_percent += 1;
if(rssi_percent > 100)
rssi_percent = 0;
this->print_rssi(rssi_percent);
break;
case 2:
// update time
time_in_ms = millis() - this->time_enter;
time_in_s = time_in_ms/1000; // to sec
this->print_time(time_in_s);
break;
case 3:
// update akku
akku_quad += 1;
akku_remote += 2;
if(akku_quad > 100)
akku_quad = 0;
if(akku_remote > 100)
akku_remote = 0;
this->print_akku(akku_quad, akku_remote);
break;
default:
break;
}
input.update();
}
@ -153,10 +204,6 @@ void LCD_state_fly::update(void)
delayMicroseconds(wait);
}
end__ = micros();
if (input.is_menu_triggered() == 0)
break;
}
// cange to menu when done

6
remote/src/state_init.cpp

@ -44,6 +44,12 @@ void LCD_state_init::update(void)
struct Input::ch_config ch_config[Input::CH_COUNT];
eeprom_config.get_ch_config(ch_config);
input.set_calibration(ch_config);
uint32_t master_id = 0;
eeprom_config.get_master_id(&master_id);
set_rx_tx_addr(master_id);
}
}
void LCD_state_init::leave(void)

1
remote/src/state_menu.cpp

@ -41,6 +41,7 @@ void LCD_state_menu::update(void)
lcd.setCursor(0,1);
lcd.print(curr[1]);
input.update();
if (false == input.is_centered(Input::MENU_UP_DOWN)) {
if (input.is_low(Input::MENU_UP_DOWN)){
this->curr_selected +=1;

Loading…
Cancel
Save