diff --git a/remote/include/FrSkyD_cc2500.h b/remote/include/FrSkyD_cc2500.h index 09417c3..f14888b 100644 --- a/remote/include/FrSkyD_cc2500.h +++ b/remote/include/FrSkyD_cc2500.h @@ -17,6 +17,7 @@ #define _FRSKYD_CC2500_H_ #include +extern uint16_t state; void Frsky_init_hop(void); void frsky2way_init(uint8_t bind); diff --git a/remote/include/state.h b/remote/include/state.h index 27371f6..8555f3f 100644 --- a/remote/include/state.h +++ b/remote/include/state.h @@ -5,8 +5,16 @@ #include #include - 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 update_state(void); @@ -53,6 +61,9 @@ public: class LCD_state_fly: public State { private: 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: LCD_state_fly(void); diff --git a/remote/src/FrSkyD_cc2500.cpp b/remote/src/FrSkyD_cc2500.cpp index 73acc6c..fc55255 100644 --- a/remote/src/FrSkyD_cc2500.cpp +++ b/remote/src/FrSkyD_cc2500.cpp @@ -18,19 +18,21 @@ #include "Multiprotocol.h" #include "input.h" #include "FrSkyD_cc2500.h" +#include "common.h" uint8_t hopping_frequency[50]; +uint16_t state; uint16_t counter; void frsky2way_init(uint8_t bind) { - //debugln("frsky2way_init"); + //debugln("frsky2way_init"); FRSKY_init_cc2500(FRSKYD_cc2500_conf); CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]); CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); CC2500_Strobe(CC2500_SIDLE); // Go to idle... - // + CC2500_WriteReg(CC2500_0A_CHANNR, 0x00); CC2500_WriteReg(CC2500_23_FSCAL3, 0x89); CC2500_Strobe(CC2500_SFRX); @@ -104,7 +106,6 @@ uint16_t initFrSky_2way() if(IS_BIND_IN_PROGRESS) { - frsky2way_init(1); state = FRSKY_BIND; debugln("initFrSky_2way bind"); } else { @@ -140,15 +141,16 @@ uint16_t ReadFrSky_2way_bind(void) uint16_t ReadFrSky_2way() { if (state <= FRSKY_BIND_DONE) { - //debugln("%s bind done",__func__); - state = FRSKY_DATA2; frsky2way_init(0); + //debugln("%s bind done",__func__); + + state = FRSKY_DATA2; counter = 0; } else if (state == FRSKY_DATA5) { - CC2500_Strobe(CC2500_SRX);//0x34 RX enable - state = FRSKY_DATA1; - return 9200; + CC2500_Strobe(CC2500_SRX);//0x34 RX enable + state = FRSKY_DATA1; + return 9200; } counter = (counter + 1) % 188; @@ -189,6 +191,7 @@ 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 ; diff --git a/remote/src/Multiprotocol.cpp b/remote/src/Multiprotocol.cpp index 797287d..e589792 100644 --- a/remote/src/Multiprotocol.cpp +++ b/remote/src/Multiprotocol.cpp @@ -75,7 +75,6 @@ uint8_t flags; uint16_t crc; uint8_t crc8; uint16_t failsafe_count; -uint16_t state; uint8_t len; #if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO) @@ -248,11 +247,9 @@ void loop() uint32_t s; s =micros(); input.update(); - debug("input took %lu", (micros()-s)); s =micros(); update_state(); - debugln("state took %lu", (micros()-s)); return; uint32_t next_callback; @@ -282,7 +279,6 @@ void loop() uint32_t wait = next_callback; wait -= ((end__-start)); delayMicroseconds(wait); - end__ += wait; } end__ = micros(); } @@ -328,39 +324,4 @@ void set_rx_tx_addr(uint32_t id) 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 - } diff --git a/remote/src/eeprom.cpp b/remote/src/eeprom.cpp index 5464884..a117468 100644 --- a/remote/src/eeprom.cpp +++ b/remote/src/eeprom.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include "tx_def.h" #include "eeprom.h" #include "crc.h" @@ -25,29 +27,37 @@ int Eeprom_config::validate() { uint32_t crc_calc = 0; if (this->sucessfull_read == false) { + debugln("no read\n"); return -1; } if (this->current_config.version != CURRENT_VERSION) { + debugln("wrong version %d vs %d \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); return -1; } - return 0; + debugln("valid config\n"); + return 1; } int Eeprom_config::read(void) { uint8_t *data = NULL; + debugln("enter \n"); 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); + debugln("Read %d\n",i); } + debugln("Read end\n"); this->sucessfull_read = true; return 0; } @@ -59,7 +69,7 @@ int Eeprom_config::write(void) { this->current_config.version = CURRENT_VERSION; 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]); } diff --git a/remote/src/input.cpp b/remote/src/input.cpp index 06d9bff..dfdab8c 100644 --- a/remote/src/input.cpp +++ b/remote/src/input.cpp @@ -138,7 +138,7 @@ bool Input::is_low(enum Input::input_channels ch) { } 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) { diff --git a/remote/src/state.cpp b/remote/src/state.cpp index b9069a9..bd3b669 100644 --- a/remote/src/state.cpp +++ b/remote/src/state.cpp @@ -20,47 +20,6 @@ State *s_joy = 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) { #if 0 Wire.setSDA(PB9); @@ -78,7 +37,6 @@ void init_state(void) { curr_state = NULL; new_state = s_init; - install_special_caracters(); update_state(); } diff --git a/remote/src/state_bind.cpp b/remote/src/state_bind.cpp index 9f1f075..8561766 100644 --- a/remote/src/state_bind.cpp +++ b/remote/src/state_bind.cpp @@ -23,20 +23,22 @@ void LCD_state_bind::enter(void) { void LCD_state_bind::update(void) { - debugln("blubber\n"); - char line[17]; - 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; + char line[17]; + 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(line,sizeof(line),"remaining sec %02lu",remain_s); - lcd.setCursor(0,1); - lcd.print(line); + snprintf(line,sizeof(line),"remaining sec %02lu",remain_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_bind(); diff --git a/remote/src/state_fly.cpp b/remote/src/state_fly.cpp index d61a92d..e61baa0 100644 --- a/remote/src/state_fly.cpp +++ b/remote/src/state_fly.cpp @@ -7,6 +7,7 @@ #include "eeprom.h" #include "debug.h" #include "tx_def.h" +#include "common.h" LCD_state_fly::LCD_state_fly(void) { } @@ -19,8 +20,147 @@ void LCD_state_fly::enter(void) { 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) { + 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) diff --git a/remote/src/state_init.cpp b/remote/src/state_init.cpp index 1c4885c..c7db9d9 100644 --- a/remote/src/state_init.cpp +++ b/remote/src/state_init.cpp @@ -20,9 +20,30 @@ void LCD_state_init::enter(void) { void LCD_state_init::update(void) { uint32_t diff; + delay(100); diff = millis() - this->time_enter; if (diff > 5 * 1000) { 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) diff --git a/remote/src/state_joy_calib.cpp b/remote/src/state_joy_calib.cpp index 3283b1d..bfc959e 100644 --- a/remote/src/state_joy_calib.cpp +++ b/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]; 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);