void bt_step() { if (bt_module_state == BT_MOD_STATE_OFF) return; if (bt_reset_counter) { if (bt_reset_counter > task_get_ms_tick()) return; DEBUG("BT RESET STEP: %d\n", bt_reset_counter_step); switch(bt_reset_counter_step) { case(0): GpioWrite(BT_EN, HIGH); bt_reset_counter = task_get_ms_tick() + 500; bt_reset_counter_step = 1; break; case(1): //enable bt uart BT_UART_PWR_ON; bt_uart.Init(BT_UART, 115200); bt_uart.SetInterruptPriority(MEDIUM); // while(1) // { // _delay_ms(100); // bt_uart.Write(0x00); // _delay_ms(1); // bt_uart.Write(0xAA); // ewdt_reset(); // } bt_reset_counter = task_get_ms_tick() + 10; bt_reset_counter_step = 2; break; case(2): GpioWrite(BT_RESET, HIGH); bt_reset_counter_step = 0; bt_reset_counter = 0; break; } return; } if (bt_module_type == BT_PAN1322) bt_pan1322.Step(); if (bt_module_type == BT_PAN1026) bt_pan1026.Step(); if (bt_module_type == BT_UNKNOWN) bt_unknown_parser(); }
void gui_page_menu_irqh(uint8_t type, uint8_t * buff) { if (type == TASK_IRQ_BUTTON_R && *buff == BE_HOLD) { gui_switch_task(GUI_SETTINGS); } if (type == TASK_IRQ_BUTTON_L && *buff == BE_HOLD) { gui_switch_task(GUI_LAYOUTS); } if (type == TASK_IRQ_BUTTON_M && *buff == BE_HOLD) { gui_page_power_off(); } if (type == TASK_IRQ_BUTTON_M && *buff == BE_RELEASED) { if (page_state_step > 0) page_state_dir = REVERSE; else { page_state_dir = WAIT; page_state_timer = task_get_ms_tick() + PAGE_MENU_WAIT; } } }
void gui_pages_idle_irqh(uint8_t type, uint8_t * buff) { switch(type) { case(TASK_IRQ_BUTTON_L): if (*buff == BE_CLICK) { page_switch(false); } break; case(TASK_IRQ_BUTTON_R): if (*buff == BE_CLICK) { page_switch(true); } break; case(TASK_IRQ_BUTTON_M): if (*buff == BE_CLICK) { if (page_widgets_have_menu()) { page_select_first_widget(); page_state = PAGE_WIDGET_SELECT; page_state_timer = task_get_ms_tick() + PAGE_WIDGET_SELECT_DURATION * 1000; } } break; } }
void gui_pages_select_irqh(uint8_t type, uint8_t * buff) { uint8_t wtype = widget_get_type(active_page, active_widget); switch(type) { case(TASK_IRQ_BUTTON_L): widget_array[wtype].menu_irqh(type, buff, widget_array[wtype].flags); break; case(TASK_IRQ_BUTTON_R): widget_array[wtype].menu_irqh(type, buff, widget_array[wtype].flags); break; case(TASK_IRQ_BUTTON_M): if (*buff == BE_CLICK) { if (page_select_next_widget()) { page_state = PAGE_WIDGET_SELECT; page_state_timer = task_get_ms_tick() + PAGE_WIDGET_SELECT_DURATION * 1000; } else page_state = PAGE_IDLE; } else widget_array[wtype].menu_irqh(type, buff, widget_array[wtype].flags); break; } }
void protocol_step() { if (protocol_next_step > task_get_ms_tick()) return; char buffer[128]; switch (config.connectivity.protocol) { case(PROTOCOL_DIGIFLY): protocol_digifly_step(buffer); break; case(PROTOCOL_LK8EX1): protocol_lk8ex1_step(buffer); break; case(PROTOCOL_BLUEFLY): protocol_bluefly_step(buffer); break; case(PROTOCOL_FLYNET): protocol_flynet_step(buffer); break; } //XXX:outputs if (config.connectivity.uart_function > UART_FORWARD_OFF) uart_send(buffer); bt_send(buffer); // DEBUG("%s", buffer); }
void pan1322::Step() { while (!this->usart->isRxBufferEmpty()) { // uint8_t c = this->usart->Peek(); // DEBUG("1322>%02X %c (%d)\n", c, c, this->usart->rx_len); this->Parse(this->usart->Read()); } if (this->p_cmd != pan_cmd_none) { DEBUG("cmd %d\n", this->p_cmd); switch(this->p_cmd) { case(pan_cmd_set_name): this->SetName(PSTR("SkyDrop Pan1322")); break; case(pan_cmd_create_service): this->CreateService(PSTR("0000110100001000800000805f9b34fb"), PSTR("SPP"), 01, PSTR("080510")); break; case(pan_cmd_set_discoverable): this->SetDiscoverable(true); break; case(pan_cmd_accept_connection): this->AcceptConnection(); break; } this->p_last_cmd = this->p_cmd; this->p_cmd = pan_cmd_none; } if (this->timer != BT_NO_TIMEOUT && this->timer < task_get_ms_tick()) { DEBUG("PAN1322 timeout, last cmd %d\n", this->p_last_cmd); this->timer = BT_NO_TIMEOUT; switch (this->p_last_cmd) { case(pan_cmd_reset): //ROK not recieved bt_irgh(BT_IRQ_INIT_FAIL, 0); break; case(pan_cmd_set_name): this->SetName(PSTR("SkyDrop Pan1322")); break; case(pan_cmd_accept_connection): this->SetName(PSTR("SkyDrop Pan1322")); break; } } }
void protocol_step() { if (protocol_next_step > task_get_ms_tick()) return; char buffer[512]; switch (config.system.protocol) { case(PROTOCOL_DIGIFLY): protocol_digifly_step(buffer); break; case(PROTOCOL_LK8EX1): protocol_lk8ex1_step(buffer); break; case(PROTOCOL_BLUEFLY): protocol_bluefly_step(buffer); break; } //XXX:outputs bt_send(buffer); // DEBUG("%s", buffer); }
void fc_landing() { DEBUG("Landing\n"); gui_dialog_set_P(PSTR("Landing"), PSTR(""), GUI_STYLE_STATS, fc_landing_cb); fc_landing_old_gui_task = gui_task; gui_switch_task(GUI_DIALOG); fc.flight.state = FLIGHT_LAND; fc.flight.autostart_timer = task_get_ms_tick(); fc.flight.timer = task_get_ms_tick() - fc.flight.timer; audio_off(); logger_stop(); }
void fc_log_battery() { if (fc_log_battery_next > task_get_ms_tick()) return; fc_log_battery_next = task_get_ms_tick() + FC_LOG_BATTERY_EVERY; char text[32]; if (battery_per == BATTERY_CHARGING) sprintf_P(text, PSTR("bat: chrg")); else if (battery_per == BATTERY_FULL) sprintf_P(text, PSTR("bat: full")); else sprintf_P(text, PSTR("bat: %u%% (%u)"), battery_per, battery_adc_raw); logger_comment(text); }
//returns true if this is a first time bool gui_enter_widget_menu() { uint8_t old_state = page_state; page_state = PAGE_WIDGET_MENU; page_state_timer = task_get_ms_tick() + PAGE_WIDGET_MENU_DURATION * 1000; return (old_state != page_state); }
void gui_list_set(gui_list_gen * f_ptr, gui_list_act * f_act, uint8_t size, uint8_t back) { gui_list_gen_f = f_ptr; gui_list_act_f = f_act; gui_list_size = size + 1; gui_list_back = back; gui_list_y_offset = 0; gui_list_middle_hold = task_get_ms_tick(); }
void bt_module_reset() { GpioWrite(BT_EN, LOW); GpioWrite(BT_RESET, LOW); bt_uart.Stop(); BT_UART_PWR_OFF; bt_reset_counter = task_get_ms_tick() + 4000; bt_reset_counter_step = 0; }
void widget_flight_time_draw(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t flags) { uint8_t lh = widget_label_P(PSTR("FTime"), x, y); char tmp[7]; if (fc.flight_state == FLIGHT_FLIGHT) { uint32_t diff = (task_get_ms_tick() - fc.flight_timer) / 1000; uint8_t hour, min; hour = diff / 3600; diff %= 3600; min = diff / 60; diff %= 60; if (hour > 0) { sprintf_P(tmp, PSTR("%02d:%02d"), hour, min); } else sprintf_P(tmp, PSTR("%02d.%02d"), min, diff); widget_value_int(tmp, x, y + lh, w, h - lh); } if (fc.flight_state == FLIGHT_LAND) { uint32_t diff = fc.flight_timer / 1000; uint8_t hour, min; hour = diff / 3600; diff %= 3600; min = diff / 60; diff %= 60; if (hour > 0) { sprintf_P(tmp, PSTR("%02d:%02d"), hour, min); } else sprintf_P(tmp, PSTR("%02d.%02d"), min, diff); widget_value_int(tmp, x, y + lh, w, h - lh); } if (fc.flight_state == FLIGHT_WAIT) { sprintf_P(tmp, PSTR("Start")); widget_value_txt(tmp, x, y + lh, w, h - lh); } }
void fc_reset() { //autostart timer reset fc.flight.autostart_timer = task_get_ms_tick(); fc.flight.state = FLIGHT_WAIT; //statistic fc.flight.stats.max_alt = -32678; fc.flight.stats.min_alt = 32677; fc.flight.stats.max_climb = 0; fc.flight.stats.max_sink = 0; }
void logger_step() { if (!logger_active()) return; if (logger_next > task_get_ms_tick()) return; if (!fc.baro_valid) return; //RAW is running as fast as it can! if (config.logger.format != LOGGER_RAW) { if (fc.gps_data.new_sample) { logger_next = task_get_ms_tick() + 1000; fc.gps_data.new_sample = false; } } switch (config.logger.format) { case(LOGGER_IGC): igc_step(); break; case(LOGGER_KML): kml_step(); break; case(LOGGER_RAW): raw_step(); break; } }
void fc_takeoff() { if (!fc.vario.valid) return; gui_showmessage_P(PSTR("Take off")); fc.flight.state = FLIGHT_FLIGHT; fc.flight.timer = task_get_ms_tick(); //reset timer and altitude for autoland fc.flight.autostart_altitude = fc.altitude1; fc.flight.autostart_timer = task_get_ms_tick(); //reset battery info timer fc_log_battery_next = 0; //zero altimeters at take off for (uint8_t i = 0; i < NUMBER_OF_ALTIMETERS; i++) { if (config.altitude.altimeter[i].flags & ALT_AUTO_ZERO) fc_zero_alt(i + 1); } }
void aero_step() { uint32_t time = task_get_ms_tick(); uint16_t diff = time - aero_last_time; uint32_t g_value; g_value = (int32_t)fc.acc.raw.x * (int32_t)fc.acc.raw.x; g_value += (int32_t)fc.acc.raw.y * (int32_t)fc.acc.raw.y; g_value += (int32_t)fc.acc.raw.z * (int32_t)fc.acc.raw.z; // DEBUG("aero_step\n"); // DEBUG(" diff %u\n", diff); // DEBUG(" g_value %ld %ld\n", g_value, AERO_G_THOLD_RAW); if (diff < AERO_SAMLE_TIME && g_value < AERO_G_THOLD_RAW && aero_last_time != 0) return; // DEBUG("writing\n"); uint8_t line[5]; uint16_t wl; uint8_t l = 5; if (aero_last_time == 0) diff = 0; aero_last_time = time; line[0] = 0xAA; memcpy(line + 1, (void *)&diff, 2); g_value >>= 16; memcpy(line + 3, (void *)(&g_value), 2); // for (uint8_t i = 0; i < 5; i++) // DEBUG("%02X ", line[i]); // DEBUG("\n"); assert(f_write(&log_file, line, l, &wl) == FR_OK); assert(wl == l); assert(f_sync(&log_file) == FR_OK); }
void protocol_step() { if (protocol_next_step > task_get_ms_tick()) return; switch (config.connectivity.protocol) { case(PROTOCOL_DIGIFLY): protocol_digifly_step(); break; case(PROTOCOL_LK8EX1): protocol_lk8ex1_step(); break; case(PROTOCOL_BLUEFLY): protocol_bluefly_step(); break; case(PROTOCOL_SKYBEAN): protocol_skybean_step(); break; } }
void gui_list_draw() { char tmp_text[64]; char tmp_sub_text[32]; uint8_t flags; disp.LoadFont(F_TEXT_M); uint8_t t_h = disp.GetTextHeight(); int16_t y = gui_list_y_offset; int8_t height; int16_t total_height = 0; uint8_t sub_height; //emulate middle click if (button_in_reset(B_MIDDLE)) { if (task_get_ms_tick() - gui_list_middle_hold > BUTTON_LONG) { gui_switch_task(gui_list_back); if (config.gui.menu_audio_flags & CFG_AUDIO_MENU_BUTTONS && gui_buttons_override == false) seq_start(&snd_menu_exit, config.gui.menu_volume); } } else gui_list_middle_hold = task_get_ms_tick(); for (uint8_t i = 0; i < gui_list_size; i++) { height = 1 + t_h; flags = 0; if (i < gui_list_size - 1) { gui_list_gen_f(i, tmp_text, &flags, tmp_sub_text); } else { strcpy_P(tmp_text, PSTR("back")); flags = GUI_LIST_BACK; } uint8_t x_val = 5; switch(flags & GUI_LIST_T_MASK) { case(GUI_LIST_FOLDER): x_val = 5; break; case(GUI_LIST_BACK): x_val = 2; break; } if ((flags & GUI_LIST_T_MASK) == GUI_LIST_SUB_TEXT) { sub_height = disp.GetTextHeight(); height += sub_height; } if (gui_list_index[gui_task] == i) { if (y < 0) gui_list_y_offset = -total_height; if (y > GUI_DISP_HEIGHT - height) gui_list_y_offset = -total_height + GUI_DISP_HEIGHT - height; } if (y > GUI_DISP_HEIGHT) continue; disp.GotoXY(x_val, y + 1); fprintf_P(lcd_out, PSTR("%s"), tmp_text); //sub text if ((flags & GUI_LIST_T_MASK) == GUI_LIST_SUB_TEXT) gui_raligh_text(tmp_sub_text, GUI_DISP_WIDTH - 3, y + t_h + 1); //tick if ((flags & GUI_LIST_T_MASK) == GUI_LIST_CHECK_OFF || (flags & GUI_LIST_T_MASK) == GUI_LIST_CHECK_ON) { disp.DrawRectangle(GUI_DISP_WIDTH - 9, y + 1, GUI_DISP_WIDTH - 3, y + 7, 1, 0); if ((flags & GUI_LIST_T_MASK) == GUI_LIST_CHECK_ON) { disp.DrawLine(GUI_DISP_WIDTH - 8, y + 5, GUI_DISP_WIDTH - 7, y + 6, 1); disp.DrawLine(GUI_DISP_WIDTH - 6, y + 5, GUI_DISP_WIDTH - 4, y + 3, 1); } } if (flags & GUI_LIST_DISABLED) { for (uint8_t cx = 0; cx < GUI_DISP_WIDTH - 1; cx++) for (uint8_t cy = y + cx % 2 + 1; cy < y + t_h; cy += 2) disp.PutPixel(cx, cy, 0); } if (gui_list_index[gui_task] == i) { disp.Invert(0, y, GUI_DISP_WIDTH - 1, y + height - 1); disp.PutPixel(0, y, 0); disp.PutPixel(GUI_DISP_WIDTH - 1, y, 0); disp.PutPixel(GUI_DISP_WIDTH - 1, y + height - 1, 0); disp.PutPixel(0, y + height - 1, 0); } y += height; total_height += height; } }
void gui_pages_loop() { uint8_t start_x; uint8_t wtype; switch (page_state) { case(PAGE_IDLE): widgets_draw(active_page); gui_statusbar(); break; case(PAGE_WIDGET_SELECT): //draw widgets widgets_draw(active_page); gui_statusbar(); //Highlight selected widget uint8_t x, y, w, h; layout_get_widget_rect(pages[active_page].type, active_widget, &x, &y, &w, &h); disp.Invert(x, y, x + w - 1, y + h - 1); disp.InvertPixel(x, y); disp.InvertPixel(x + w - 1, y); disp.InvertPixel(x, y + h - 1); disp.InvertPixel(x + w - 1, y + h - 1); if (page_state_timer < task_get_ms_tick()) page_state = PAGE_IDLE; break; case(PAGE_WIDGET_MENU): wtype = widget_get_type(active_page, active_widget); widget_array[wtype].menu_loop(widget_array[wtype].flags); if (page_state_timer < task_get_ms_tick()) page_state = PAGE_IDLE; break; case(PAGE_CHANGE): page_state_step--; int8_t split; if (page_change_dir) split = (n5110_width / PAGE_SWITCH_STEPS) * page_state_step; else split = n5110_width - ((n5110_width / PAGE_SWITCH_STEPS) * page_state_step); disp.SetDrawLayer(1); disp.ClearBuffer(); widgets_draw((!page_change_dir) ? active_page : old_page); gui_statusbar(); disp.CopyToLayerX(0, split - n5110_width); disp.ClearBuffer(); widgets_draw((!page_change_dir) ? old_page : active_page); gui_statusbar(); disp.CopyToLayerX(0, split); start_x = ( -NUMBER_OF_PAGES * (8 + 4) + 4 + n5110_width) / 2; disp.ClearPart(4, start_x, 5, start_x + NUMBER_OF_PAGES * (8 + 4) + (8 + 4)); for (uint8_t i = 0; i < NUMBER_OF_PAGES; i++) { uint8_t x = start_x + i * 12; disp.DrawRectangle(x, 8 * 4, x + 8 - 1, 8 * 5 - 1, 1, (i == active_page) ? 1 : 0); disp.CopyToLayerPart(0, 4, x, 5, x + 8); } if (page_state_step == 0) { page_state_step = PAGE_INFO_STEPS; page_state = PAGE_CHANGE_INFO; } disp.SetDrawLayer(0); break; case(PAGE_CHANGE_INFO): widgets_draw(active_page); gui_statusbar(); disp.SetDrawLayer(1); start_x = ( -NUMBER_OF_PAGES * (8 + 4) + 4 + n5110_width) / 2; disp.ClearPart(4, start_x, 5, start_x + NUMBER_OF_PAGES * (8 + 4) + (8 + 4)); for (uint8_t i = 0; i < NUMBER_OF_PAGES; i++) { uint8_t x = start_x + i * 12; disp.DrawRectangle(x, 8 * 4, x + 8 - 1, 8 * 5 - 1, 1, (i == active_page) ? 1 : 0); disp.CopyToLayerPart(0, 4, x, 5, x + 8); } page_state_step--; if (page_state_step == 0) { page_state = PAGE_IDLE; } disp.SetDrawLayer(0); break; case(PAGE_MENU): widgets_draw(active_page); gui_statusbar(); uint8_t top = GUI_DISP_HEIGHT - PAGE_MENU_HEIGHT + (PAGE_MENU_HEIGHT * ((float)page_state_step/PAGE_MENU_STEPS)); switch (page_state_dir) { case (NORMAL): if (page_state_step > 0) page_state_step--; else { page_state_dir = HOLD; page_state_timer = task_get_ms_tick() + PAGE_MENU_POWEROFF; } break; case (HOLD): if (page_state_timer < task_get_ms_tick()) { gui_page_power_off(); } break; case (WAIT): if (task_get_ms_tick() > page_state_timer) page_state_dir = REVERSE; break; case (REVERSE): if (page_state_step < PAGE_MENU_STEPS) page_state_step++; else page_state = PAGE_IDLE; break; } disp.DrawRectangle(1, top + 1, GUI_DISP_WIDTH - 2, GUI_DISP_HEIGHT - 1, 0, 1); disp.DrawLine(1, top, GUI_DISP_WIDTH - 2, top, 1); disp.DrawLine(0, GUI_DISP_HEIGHT - 1, 0, top + 1, 1); disp.DrawLine(GUI_DISP_WIDTH - 1, GUI_DISP_HEIGHT - 1, GUI_DISP_WIDTH - 1, top + 1, 1); //pwr if ((page_state_timer - task_get_ms_tick() > PAGE_MENU_POWEROFF_BLIK) || GUI_BLINK_TGL(200) || page_state_dir != HOLD) disp.DrawImage(img_pwr, 36, top + 2); //menu disp.DrawImage(img_menu, 69, top + 4); //layout disp.DrawImage(img_layout, 3, top + 4); break; } }
void button_handle(uint8_t index, uint8_t state) { uint32_t time = task_get_ms_tick(); uint8_t res; if (state == 1) //button is pressed { switch(buttons_state[index]) { case(BS_IDLE): res = BE_HOLD; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_1DOWN; buttons_counter[index] = time; break; case(BS_1DOWN): if (time - buttons_counter[index] > BUTTON_LONG) { res = BE_LONG; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_PRESSED; } break; case(BS_WAIT): if (time - buttons_counter[index] < BUTTON_WAIT) { res = BE_DBL_CLICK; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_2DOWN; } else { res = BE_HOLD; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_1DOWN; buttons_counter[index] = time; } break; } } else // button is released { switch(buttons_state[index]) { case(BS_RESET): buttons_state[index] = BS_IDLE; break; case(BS_1DOWN): { res = BE_CLICK; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_WAIT; buttons_counter[index] = time; } break; case(BS_WAIT): if (time - buttons_counter[index] > BUTTON_WAIT) buttons_state[index] = BS_IDLE; break; case(BS_2DOWN): buttons_state[index] = BS_IDLE; break; case(BS_PRESSED): res = BE_RELEASED; task_irqh(TASK_IRQ_BUTTON_L + index, &res); buttons_state[index] = BS_IDLE; break; } } }
void pan1322::WaitForOK() { // DEBUG("Wait for ok\n"); this->timer = task_get_ms_tick() + BT_TIMEOUT; }
void protocol_set_next_step(uint32_t diff) { protocol_next_step = (uint32_t)task_get_ms_tick() + (uint32_t)diff; }
void fc_step() { //using fake data #ifdef FAKE_ENABLE return; #endif gps_step(); bt_step(); protocol_step(); logger_step(); wind_step(); //logger always enabled if (config.autostart.flags & AUTOSTART_ALWAYS_ENABLED) { if (fc.vario.valid && fc.flight.state == FLIGHT_WAIT) { fc_takeoff(); } } else { //auto start // baro valid, waiting to take off or landed, and enabled auto start if (fc.vario.valid && (fc.flight.state == FLIGHT_WAIT || fc.flight.state == FLIGHT_LAND) && config.autostart.start_sensititvity > 0) { if (abs(fc.altitude1 - fc.flight.autostart_altitude) > config.autostart.start_sensititvity) { fc_takeoff(); } else { uint32_t t = task_get_ms_tick(); if(t < fc.flight.autostart_timer) { assert(0); DEBUG("old %lu\n", fc.flight.autostart_timer); DEBUG("act %lu\n", t); } //reset wait timer if (t - fc.flight.autostart_timer > (uint32_t)config.autostart.timeout * 1000ul) { fc.flight.autostart_timer = t; fc.flight.autostart_altitude = fc.altitude1; } } } //auto land // flying and auto land enabled if (fc.flight.state == FLIGHT_FLIGHT && config.autostart.land_sensititvity > 0) { if (abs(fc.altitude1 - fc.flight.autostart_altitude) < config.autostart.land_sensititvity) { uint32_t tick = task_get_ms_tick(); if (tick < fc.flight.autostart_timer) { assert(0); DEBUG("TT %lu\n", tick); DEBUG("AT %lu\n", fc.flight.autostart_timer); } else if (tick - fc.flight.autostart_timer > (uint32_t)config.autostart.timeout * 1000ul) { //reduce timeout from flight time fc.flight.timer += (uint32_t)config.autostart.timeout * 1000ul; gui_reset_timeout(); fc_landing(); } } else { fc.flight.autostart_altitude = fc.altitude1; fc.flight.autostart_timer = task_get_ms_tick(); } } } //gps time sync if ((config.system.time_flags & TIME_SYNC) && fc.gps_data.fix_cnt == GPS_FIX_TIME_SYNC) { if (config.gui.menu_audio_flags & CFG_AUDIO_MENU_GPS) seq_start(&gps_ready, config.gui.alert_volume); fc_sync_gps_time(); fc.gps_data.fix_cnt++; } //glide ratio //when you have GPS, baro and speed is higher than 2km/h and you are sinking <= -0.01 if (fc.gps_data.valid && fc.vario.valid && fc.gps_data.groud_speed > FC_GLIDE_MIN_KNOTS && fc.vario.avg <= FC_GLIDE_MIN_SINK) { float spd_m = fc.gps_data.groud_speed * FC_KNOTS_TO_MPS; fc.glide_ratio = spd_m / abs(fc.vario.avg); fc.glide_ratio_valid = true; } else { fc.glide_ratio_valid = false; } //flight logger if (config.logger.enabled) { if (fc.flight.state == FLIGHT_FLIGHT && !logger_active() && time_is_set() && !logger_error()) { logger_start(); } } //flight statistic if (fc.flight.state == FLIGHT_FLIGHT) { int16_t t_vario = fc.vario.avg * 100; if (fc.altitude1 > fc.flight.stats.max_alt) fc.flight.stats.max_alt = fc.altitude1; if (fc.altitude1 < fc.flight.stats.min_alt) fc.flight.stats.min_alt = fc.altitude1; if (t_vario > fc.flight.stats.max_climb) fc.flight.stats.max_climb = t_vario; if (t_vario < fc.flight.stats.max_sink) fc.flight.stats.max_sink = t_vario; } }
void gui_exit_widget_menu() { page_state = PAGE_WIDGET_SELECT; page_state_timer = task_get_ms_tick() + PAGE_WIDGET_SELECT_DURATION * 1000; }