Browse Source

fix eeprom and add fly state implementation

master
Schoenberger, Philipp 6 years ago
parent
commit
fdd5004e34
No known key found for this signature in database GPG Key ID: 77E9DF7A0452BF64
  1. 1
      remote/include/FrSkyD_cc2500.h
  2. 13
      remote/include/state.h
  3. 9
      remote/src/FrSkyD_cc2500.cpp
  4. 39
      remote/src/Multiprotocol.cpp
  5. 16
      remote/src/eeprom.cpp
  6. 2
      remote/src/input.cpp
  7. 42
      remote/src/state.cpp
  8. 4
      remote/src/state_bind.cpp
  9. 140
      remote/src/state_fly.cpp
  10. 21
      remote/src/state_init.cpp
  11. 19
      remote/src/state_joy_calib.cpp

1
remote/include/FrSkyD_cc2500.h

@ -17,6 +17,7 @@
#define _FRSKYD_CC2500_H_ #define _FRSKYD_CC2500_H_
#include <stdint.h> #include <stdint.h>
extern uint16_t state;
void Frsky_init_hop(void); void Frsky_init_hop(void);
void frsky2way_init(uint8_t bind); void frsky2way_init(uint8_t bind);

13
remote/include/state.h

@ -5,8 +5,16 @@
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include <stdint.h> #include <stdint.h>
extern LiquidCrystal_I2C lcd; extern LiquidCrystal_I2C lcd;
enum lcd_special_chars {
battery_char = 0,
rssiantenna= 1,
rssi_bars = 2,
clock_char = 3,
MAX_SPECIAL_CHARS =8,
};
void init_state(void); void init_state(void);
void update_state(void); void update_state(void);
@ -53,6 +61,9 @@ public:
class LCD_state_fly: public State { class LCD_state_fly: public State {
private: private:
unsigned long time_enter; unsigned long time_enter;
void print_akku(uint8_t akku_quad, uint8_t akku_remote);
void print_rssi(uint8_t rssi_percent);
void print_time(uint16_t time);
public: public:
LCD_state_fly(void); LCD_state_fly(void);

9
remote/src/FrSkyD_cc2500.cpp

@ -18,8 +18,10 @@
#include "Multiprotocol.h" #include "Multiprotocol.h"
#include "input.h" #include "input.h"
#include "FrSkyD_cc2500.h" #include "FrSkyD_cc2500.h"
#include "common.h"
uint8_t hopping_frequency[50]; uint8_t hopping_frequency[50];
uint16_t state;
uint16_t counter; uint16_t counter;
void frsky2way_init(uint8_t bind) void frsky2way_init(uint8_t bind)
@ -30,7 +32,7 @@ void frsky2way_init(uint8_t bind)
CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]); CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
CC2500_Strobe(CC2500_SIDLE); // Go to idle... CC2500_Strobe(CC2500_SIDLE); // Go to idle...
//
CC2500_WriteReg(CC2500_0A_CHANNR, 0x00); CC2500_WriteReg(CC2500_0A_CHANNR, 0x00);
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89); CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
CC2500_Strobe(CC2500_SFRX); CC2500_Strobe(CC2500_SFRX);
@ -104,7 +106,6 @@ uint16_t initFrSky_2way()
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
frsky2way_init(1);
state = FRSKY_BIND; state = FRSKY_BIND;
debugln("initFrSky_2way bind"); debugln("initFrSky_2way bind");
} else { } else {
@ -140,10 +141,11 @@ uint16_t ReadFrSky_2way_bind(void)
uint16_t ReadFrSky_2way() uint16_t ReadFrSky_2way()
{ {
if (state <= FRSKY_BIND_DONE) { if (state <= FRSKY_BIND_DONE) {
frsky2way_init(0);
//debugln("%s bind done",__func__); //debugln("%s bind done",__func__);
state = FRSKY_DATA2; state = FRSKY_DATA2;
frsky2way_init(0);
counter = 0; counter = 0;
} else if (state == FRSKY_DATA5) { } else if (state == FRSKY_DATA5) {
CC2500_Strobe(CC2500_SRX);//0x34 RX enable CC2500_Strobe(CC2500_SRX);//0x34 RX enable
@ -189,6 +191,7 @@ uint16_t ReadFrSky_2way()
} }
CC2500_Strobe(CC2500_SIDLE); CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]); CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
if ( prev_option != option ) { if ( prev_option != option ) {
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
prev_option = option ; prev_option = option ;

39
remote/src/Multiprotocol.cpp

@ -75,7 +75,6 @@ uint8_t flags;
uint16_t crc; uint16_t crc;
uint8_t crc8; uint8_t crc8;
uint16_t failsafe_count; uint16_t failsafe_count;
uint16_t state;
uint8_t len; uint8_t len;
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO) #if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO)
@ -248,11 +247,9 @@ void loop()
uint32_t s; uint32_t s;
s =micros(); s =micros();
input.update(); input.update();
debug("input took %lu", (micros()-s));
s =micros(); s =micros();
update_state(); update_state();
debugln("state took %lu", (micros()-s));
return; return;
uint32_t next_callback; uint32_t next_callback;
@ -282,7 +279,6 @@ void loop()
uint32_t wait = next_callback; uint32_t wait = next_callback;
wait -= ((end__-start)); wait -= ((end__-start));
delayMicroseconds(wait); delayMicroseconds(wait);
end__ += wait;
} }
end__ = micros(); end__ = micros();
} }
@ -328,39 +324,4 @@ void set_rx_tx_addr(uint32_t id)
uint32_t random_id(bool create_new) uint32_t random_id(bool create_new)
{ {
#ifdef FORCE_GLOBAL_ID
(void)create_new;
return FORCE_GLOBAL_ID;
#else
uint32_t id=0;
if (eeprom_read_byte((EE_ADDR)(10))==0xf0 && !create_new) {
// TXID exists in EEPROM
for(uint8_t i=4;i>0;i--) {
id<<=8;
id|=eeprom_read_byte((EE_ADDR)i-1);
}
if(id!=0x2AD141A7) //ID with seed=0
{
debugln("Read ID from EEPROM");
return id;
}
}
// Generate a random ID from UUID
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
if (!create_new) {
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
debugln("Generated ID from STM32 UUID %x", id);
} else {
id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
}
#if 0
for(uint8_t i=0;i<4;i++)
eeprom_write_byte((EE_ADDR)address+i,id >> (i*8));
eeprom_write_byte((EE_ADDR)(address+10),0xf0);//write bind flag in eeprom.
#endif
return id;
#endif
} }

16
remote/src/eeprom.cpp

@ -2,6 +2,8 @@
#include <Arduino.h> #include <Arduino.h>
#include <stdint.h> #include <stdint.h>
#include <debug.h>
#include "tx_def.h" #include "tx_def.h"
#include "eeprom.h" #include "eeprom.h"
#include "crc.h" #include "crc.h"
@ -25,29 +27,37 @@ int Eeprom_config::validate() {
uint32_t crc_calc = 0; uint32_t crc_calc = 0;
if (this->sucessfull_read == false) { if (this->sucessfull_read == false) {
debugln("no read\n");
return -1; return -1;
} }
if (this->current_config.version != CURRENT_VERSION) { if (this->current_config.version != CURRENT_VERSION) {
debugln("wrong version %d vs %d \n", this->current_config.version, CURRENT_VERSION);
return -1; return -1;
} }
crc_calc = tiny_crc32(&(this->current_config.data), sizeof(this->current_config.data)); crc_calc = tiny_crc32(&(this->current_config.data), sizeof(this->current_config.data));
if (crc_calc != this->current_config.data_crc) { if (crc_calc != this->current_config.data_crc) {
debugln("wrong version %d vs %d \n", crc_calc, this->current_config.data_crc);
return -1; return -1;
} }
return 0;
debugln("valid config\n");
return 1;
} }
int Eeprom_config::read(void) { int Eeprom_config::read(void) {
uint8_t *data = NULL; uint8_t *data = NULL;
debugln("enter \n");
data = (uint8_t *) &this->current_config; data = (uint8_t *) &this->current_config;
for (uint8_t i = 0; i < sizeof(struct eeprom_data_v1) ; i = 0) {
debugln("for start\n");
for (uint8_t i = 0; i < sizeof(struct eeprom_data_v1) ; i++) {
data[i] = EEPROM.read(0x10 + i); data[i] = EEPROM.read(0x10 + i);
debugln("Read %d\n",i);
} }
debugln("Read end\n");
this->sucessfull_read = true; this->sucessfull_read = true;
return 0; return 0;
} }
@ -59,7 +69,7 @@ int Eeprom_config::write(void) {
this->current_config.version = CURRENT_VERSION; this->current_config.version = CURRENT_VERSION;
this->current_config.data_crc = tiny_crc32(&(this->current_config.data), sizeof(this->current_config.data)); this->current_config.data_crc = tiny_crc32(&(this->current_config.data), sizeof(this->current_config.data));
for (uint8_t i = 0; i < sizeof(struct eeprom_data_v1) ; i = 0) {
for (uint8_t i = 0; i < sizeof(struct eeprom_data_v1) ; i++) {
EEPROM.write(0x10 + i , data[i]); EEPROM.write(0x10 + i , data[i]);
} }

2
remote/src/input.cpp

@ -138,7 +138,7 @@ bool Input::is_low(enum Input::input_channels ch) {
} }
bool Input::is_menu_triggered(void) { bool Input::is_menu_triggered(void) {
return this->curr->menu;
return this->curr->menu != this->old->menu;
} }
void Input::invert_ch(enum Input::input_channels ch) { void Input::invert_ch(enum Input::input_channels ch) {

42
remote/src/state.cpp

@ -20,47 +20,6 @@ State *s_joy = NULL;
State *s_menu = NULL; State *s_menu = NULL;
enum lcd_special_chars {
battery_66 = 0,
battery_33 = 1,
battery_0 = 2,
battery_100 = 3,
rssiantenna = 4,
rssi_bars_1 = 5,
rssi_bars_2 = 6,
rssi_bars_3 = 7,
MAX_SPECIAL_CHARS =8,
};
// 6 Byte-Arrays für 6 verschiedene Batteriesymbole
__extension__ struct lcd_special_chars_data { byte data[MAX_SPECIAL_CHARS]; }
lcd_special_chars_data[MAX_SPECIAL_CHARS] =
{
//[battery_0] =
{ 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111 },
//[battery_33] =
{ 0b01110, 0b11011, 0b10001, 0b10001, 0b10001, 0b11111, 0b11111, 0b11111 },
//[battery_66] =
{ 0b01110, 0b11011, 0b10001, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 },
//[battery_100] =
{ 0b01110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 },
//[rssiantenna] =
{ 0b10101, 0b10101, 0b01110, 0b00100, 0b00100, 0b00101, 0b00101, 0b00101 },
//[rssi_bars_1] =
{ 0b00001, 0b00001, 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101 },
//[rssi_bars_2] =
{ 0b00001, 0b00001, 0b00001, 0b00001, 0b10101, 0b10101, 0b10101, 0b10101 },
//[rssi_bars_3] =
{ 0b00001, 0b00001, 0b00101, 0b00101, 0b10101, 0b10101, 0b10101, 0b10101 },
};
void install_special_caracters(void)
{
for(int i = 0; i < MAX_SPECIAL_CHARS; i ++) {
lcd.createChar(i, lcd_special_chars_data[i].data);
}
}
void init_state(void) { void init_state(void) {
#if 0 #if 0
Wire.setSDA(PB9); Wire.setSDA(PB9);
@ -78,7 +37,6 @@ void init_state(void) {
curr_state = NULL; curr_state = NULL;
new_state = s_init; new_state = s_init;
install_special_caracters();
update_state(); update_state();
} }

4
remote/src/state_bind.cpp

@ -23,7 +23,6 @@ void LCD_state_bind::enter(void) {
void LCD_state_bind::update(void) void LCD_state_bind::update(void)
{ {
debugln("blubber\n");
char line[17]; char line[17];
unsigned long time_in_ms = millis() - this->time_enter; unsigned long time_in_ms = millis() - this->time_enter;
unsigned long time_in_s = time_in_ms/1000; // to sec unsigned long time_in_s = time_in_ms/1000; // to sec
@ -37,6 +36,9 @@ void LCD_state_bind::update(void)
uint32_t start = micros(); uint32_t start = micros();
uint32_t next_callback_time; uint32_t next_callback_time;
next_callback_time = initFrSky_2way(); next_callback_time = initFrSky_2way();
// init for bind
frsky2way_init(1);
while(1) { while(1) {
start = end__; start = end__;
next_callback_time = ReadFrSky_2way_bind(); next_callback_time = ReadFrSky_2way_bind();

140
remote/src/state_fly.cpp

@ -7,6 +7,7 @@
#include "eeprom.h" #include "eeprom.h"
#include "debug.h" #include "debug.h"
#include "tx_def.h" #include "tx_def.h"
#include "common.h"
LCD_state_fly::LCD_state_fly(void) { LCD_state_fly::LCD_state_fly(void) {
} }
@ -19,8 +20,147 @@ void LCD_state_fly::enter(void) {
this->time_enter = millis(); 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] = {
0b01110,
0b10101,
0b10101,
0b10111,
0b10001,
0b10001,
0b01110,
0b00000
};
lcd.createChar(clock_char, clock_char_data);
lcd.write(clock_char);
snprintf(line, sizeof(line), "%*d", 3, time);
lcd.print(line);
}
void LCD_state_fly::print_akku(uint8_t akku_quad, uint8_t akku_remote)
{
/**
* 0123456789012345
* fly mode A PP
* T SSS AA PP A PP
**/
byte battery_char_data[8];
char line[17];
uint8_t akku[] = {akku_remote, akku_quad};
for (uint8_t i = 0; i < 2; ++i) {
lcd.setCursor(12,i);
battery_char_data[0] = 0b01110;
battery_char_data[1] = ( akku[i] > 90) ? 0b11111 : 0b11011;
battery_char_data[2] = ( akku[i] > 75) ? 0b11111 : 0b10001;
battery_char_data[3] = ( akku[i] > 60) ? 0b11111 : 0b10001;
battery_char_data[4] = ( akku[i] > 45) ? 0b11111 : 0b10001;
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.print(line);
}
}
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.print(line);
}
void LCD_state_fly::update(void) void LCD_state_fly::update(void)
{ {
uint8_t rssi_percent = 100;
uint8_t akku_quad = 1;
uint8_t akku_remote = 2;
char line[17];
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);
uint32_t end__ = micros();
uint32_t start = micros();
uint32_t next_callback_time;
next_callback_time = initFrSky_2way();
// init for bind
frsky2way_init(1);
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
// print on lcd
this->print_time(time_in_s);
rssi_percent += 1;
this->print_time(rssi_percent);
akku_quad += 1;
akku_remote += 2;
this->print_akku(akku_quad, akku_remote);
input.update();
}
end__ = micros();
if (end__ - start < next_callback_time) {
uint32_t wait = next_callback_time;
wait -= (end__ - start);
delayMicroseconds(wait);
}
end__ = micros();
if (input.is_menu_triggered() == 0)
break;
}
// cange to menu when done
new_state = s_menu;
} }
void LCD_state_fly::leave(void) void LCD_state_fly::leave(void)

21
remote/src/state_init.cpp

@ -20,9 +20,30 @@ void LCD_state_init::enter(void) {
void LCD_state_init::update(void) void LCD_state_init::update(void)
{ {
uint32_t diff; uint32_t diff;
delay(100);
diff = millis() - this->time_enter; diff = millis() - this->time_enter;
if (diff > 5 * 1000) { if (diff > 5 * 1000) {
new_state = s_joy; new_state = s_joy;
debugln("read start");
delay(1000);
if ( 0 > eeprom_config.read()) {
debugln("failed to read");
return;
}
debugln("read fin");
debugln("val start");
if ( 0 > eeprom_config.validate()) {
debugln("failed to validate");
return;
}
debugln("val fin");
new_state = s_menu;
struct Input::ch_config ch_config[Input::CH_COUNT];
eeprom_config.get_ch_config(ch_config);
input.set_calibration(ch_config);
} }
} }
void LCD_state_init::leave(void) void LCD_state_init::leave(void)

19
remote/src/state_joy_calib.cpp

@ -96,6 +96,25 @@ void LCD_state_joy_calibration::update(void) {
struct Input::ch_config ch_config[Input::CH_COUNT]; struct Input::ch_config ch_config[Input::CH_COUNT];
input.get_calibration(ch_config); input.get_calibration(ch_config);
eeprom_config.set_ch_config(ch_config);
uint32_t id=0;
#ifdef FORCE_GLOBAL_ID
id = FORCE_GLOBAL_ID;
#else
// Generate a random ID from UUID
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
#endif
debugln("Generated new master ID %x", id);
eeprom_config.set_master_id(id);
eeprom_config.write();
eeprom_config.read();
if (eeprom_config.validate()) {
debugln("ok calib\n");
}else {
debugln("failed calib\n");
}
lcd.setCursor(0,0); lcd.setCursor(0,0);

Loading…
Cancel
Save