Remove legacy fonts and make the bootloader compile with LVGL

This commit is contained in:
Raphael Coeffic
2022-06-11 15:38:08 +02:00
committed by Raphael Coeffic
parent 0404919667
commit ee0c37157d
74 changed files with 2027 additions and 775 deletions
+2 -10
View File
@@ -517,8 +517,6 @@ void testDrawSolidFilledRoundedRectangle()
ROUND | COLOR_THEME_SECONDARY3);
}
void testDrawBlackOverlay() { lcdDrawBlackOverlay(); }
void testDrawSolidHorizontalLine1() { lcdDrawSolidHorizontalLine(0, 0, 1, 0); }
void testDrawSolidHorizontalLine2()
@@ -1275,11 +1273,7 @@ int cliDisplay(const char ** argv)
if (!strcmp(argv[1], "keys")) {
for (int i=0; i<TRM_BASE; i++) {
char name[8];
uint8_t len = STR_VKEYS[0];
strncpy(name, STR_VKEYS+1+len*i, len);
name[len] = '\0';
cliSerialPrint("[%s] = %s", name, keys[i].state() ? "on" : "off");
cliSerialPrint("[%s] = %s", STR_VKEYS[i]+1, keys[i].state() ? "on" : "off");
}
#if defined(ROTARY_ENCODER_NAVIGATION)
cliSerialPrint("[Enc.] = %d", rotencValue / ROTARY_ENCODER_GRANULARITY);
@@ -1290,10 +1284,8 @@ int cliDisplay(const char ** argv)
for (int i=MIXSRC_FIRST_SWITCH; i<=MIXSRC_LAST_SWITCH; i++) {
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
if (SWITCH_EXISTS(sw)) {
char swName[LEN_SWITCH_NAME + 1];
strAppend(swName, STR_VSWITCHES+1+sw*STR_VSWITCHES[0], STR_VSWITCHES[0]);
static const char * const SWITCH_POSITIONS[] = { "down", "mid", "up" };
cliSerialPrint("[%s] = %s", swName, SWITCH_POSITIONS[1 + getValue(i) / 1024]);
cliSerialPrint("[%s] = %s", STR_VSWITCHES[sw]+1, SWITCH_POSITIONS[1 + getValue(i) / 1024]);
}
}
}
+2
View File
@@ -21,6 +21,7 @@
#pragma once
#if !defined(BOOT)
#include "datastructs_private.h"
#if !defined(BACKUP)
@@ -149,3 +150,4 @@ static inline void check_struct()
#undef CHKSIZE
}
#endif /* BACKUP */
#endif /* !BOOT */
-45
View File
@@ -1,48 +1,3 @@
string(TOLOWER ${TRANSLATIONS} subset)
#
# libopenui fonts
#
if( (${subset} STREQUAL "cn") OR (${subset} STREQUAL "tw"))
# Use this font for CJK languages
set(FONT "Noto/NotoSansCJKsc-Regular")
set(FONT_BOLD "Noto/NotoSansCJKsc-Bold")
set(FONT_OFFSET -3)
else()
# Use this font for non-CJK languages
set(FONT "Roboto/Roboto-Regular")
set(FONT_BOLD "Roboto/Roboto-Bold")
set(FONT_OFFSET 0)
#set(FONT "Kanit/Kanit-Regular")
#set(FONT_BOLD "Kanit/Kanit-Bold")
#set(FONT "Ubuntu/Ubuntu-Regular")
#set(FONT_BOLD "Ubuntu/Ubuntu-Bold")
endif()
add_truetype_font_target(9 9 ${subset} none "${FONT_ARGS}")
add_truetype_font_target(13 13 ${subset} none "${FONT_ARGS}")
add_truetype_font_target(15 15 ${subset} none "${FONT_ARGS}")
add_truetype_font_target(16 16 ${subset} none "${FONT_ARGS}")
add_truetype_font_target(16en 16 en none "${FONT_ARGS}")
add_truetype_font_target(bold16 16 ${subset} bold "${FONT_ARGS}")
add_truetype_font_target(17 17 ${subset} none "${FONT_ARGS}")
add_truetype_font_target(17en 17 en none "${FONT_ARGS}")
add_truetype_font_target(bold17 17 ${subset} bold "${FONT_ARGS}")
add_truetype_font_target(24 24 ${subset} none "${FONT_ARGS}")
if(${subset} STREQUAL "cn")
add_truetype_font_target(32 30 ${subset} bold "${FONT_ARGS}")
elseif(${subset} STREQUAL "tw")
add_truetype_font_target(32 24 ${subset} bold "${FONT_ARGS}")
else()
add_truetype_font_target(32 32 ${subset} bold "${FONT_ARGS}")
endif()
add_truetype_font_target(64 64 en bold "${FONT_ARGS}")
add_custom_target(truetype_fonts DEPENDS ${truetype_fonts_targets})
#
# LVGL fonts
#
File diff suppressed because it is too large Load Diff
+14
View File
@@ -25,6 +25,19 @@ function make_font() {
--format lvgl -o lv_font_${name}_${size}.c --force-fast-kern-format
}
# LV_SYMBOL_CHARGE, LV_SYMBOL_NEW_LINE, LV_SYMBOL_SD_CARD, LV_SYMBOL_CLOSE
BL_SYMBOLS="61671,63650,63426,61453"
function make_bootloader_font() {
local name=$1
local ttf=$2
local size=$3
lv_font_conv --no-prefilter --bpp 4 --size ${size} \
--font ${TTF_DIR}${ttf} -r ${ASCII} \
--font ${SYMBOLS_FONT} -r ${BL_SYMBOLS} \
--format lvgl -o lv_font_${name}_${size}.c --force-fast-kern-format
}
make_font "roboto" "Roboto/Roboto-Regular.ttf" 9
make_font "roboto" "Roboto/Roboto-Regular.ttf" 13
make_font "roboto" "Roboto/Roboto-Regular.ttf" 14
@@ -38,4 +51,5 @@ make_font "roboto_bold" "Roboto/Roboto-Bold.ttf" 17
make_font "roboto_bold" "Roboto/Roboto-Bold.ttf" 16
make_font "roboto_bold" "Roboto/Roboto-Bold.ttf" 32
make_font "roboto_bold" "Roboto/Roboto-Bold.ttf" 64
make_bootloader_font "roboto_bl" "Roboto/Roboto-Regular.ttf" 16
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program 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.
*/
#pragma once
#include "stamp.h"
#if defined(COLORLCD)
extern const char fw_stamp[];
extern const char vers_stamp[];
extern const char date_stamp[];
extern const char time_stamp[];
extern const char cfgv_stamp[];
#else
extern const char vers_stamp[];
#endif
#if defined(STM32)
/**
* Tries to find opentx version in the first 1024 byte of either firmware/bootloader
* (the one not running) or the buffer
* @param buffer If non-null find the firmware version in the buffer instead
*/
const char * getFirmwareVersion(const char * buffer = nullptr);
#endif
+1
View File
@@ -24,6 +24,7 @@
#include "definitions.h"
#include "dataconstants.h"
#include "opentx_types.h"
PACK(struct GlobalData {
uint8_t unexpectedShutdown:1;
+7 -68
View File
@@ -26,8 +26,6 @@
LvglWrapper* LvglWrapper::_instance = nullptr;
static lv_disp_t* disp;
static lv_disp_draw_buf_t disp_buf;
static lv_indev_drv_t touchDriver;
static lv_indev_drv_t keyboard_drv;
static lv_indev_drv_t rotaryDriver;
@@ -50,38 +48,6 @@ TouchState getLastTochState()
}
#endif
void newLcdRefresh(uint16_t* buffer, const rect_t& copy_area);
static void flushLcd(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lv_area_t refr_area;
lv_area_copy(&refr_area, area);
#if defined(LCD_VERTICAL_INVERT)
lv_coord_t tmp_coord;
tmp_coord = refr_area.y2;
refr_area.y2 = LCD_H - refr_area.y1 - 1;
refr_area.y1 = LCD_H - tmp_coord - 1;
tmp_coord = refr_area.x2;
refr_area.x2 = LCD_W - refr_area.x1 - 1;
refr_area.x1 = LCD_W - tmp_coord - 1;
#endif
if (refr_area.x1 != 0 || refr_area.x2 != 479 || refr_area.y1 != 0 ||
refr_area.y2 != 271) {
TRACE("partial refresh @ 0x%p {%d,%d,%d,%d}", color_p, refr_area.x1,
refr_area.y1, refr_area.x2, refr_area.y2);
} else {
TRACE("full refresh @ 0x%p", color_p);
}
rect_t copy_area = {refr_area.x1, refr_area.y1,
refr_area.x2 - refr_area.x1 + 1,
refr_area.y2 - refr_area.y1 + 1};
newLcdRefresh((uint16_t*)color_p, copy_area);
lv_disp_flush_ready(disp_drv);
}
extern "C" void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
// if there is a keyboard event then call checkevents
@@ -197,41 +163,15 @@ lv_color_t makeLvColor(uint32_t colorFlags)
return lv_color_make(GET_RED(color), GET_GREEN(color), GET_BLUE(color));
}
extern BitmapBuffer * lcdFront;
extern BitmapBuffer * lcd;
static lv_disp_drv_t disp_drv;
void init_disp_drv()
{
lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(), LCD_W*LCD_H);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
disp_drv.flush_cb = flushLcd; /*Set a flush callback to draw to the display*/
disp_drv.hor_res = LCD_PHYS_W; /*Set the horizontal resolution in pixels*/
disp_drv.ver_res = LCD_PHYS_H; /*Set the vertical resolution in pixels*/
disp_drv.full_refresh = 0;
disp_drv.direct_mode = 0;
#if defined (LCD_VERTICAL_INVERT)
disp_drv.rotated = LV_DISP_ROT_180;
#endif
// disp_drv.rotated = LV_DISP_ROT_90;
disp_drv.sw_rotate = 1;
// Register the driver and save the created display objects
disp = lv_disp_drv_register(&disp_drv);
}
static void init_lvgl_drivers()
{
// Register the driver and save the created display object
lcdInitDisplayDriver();
// add all lvgl object automatically to a input handling group
inputGroup = lv_group_create();
lv_group_set_default(inputGroup);
// Register the driver and save the created display objects
init_disp_drv();
// Register the driver in LVGL and save the created input device object
lv_indev_drv_init(&touchDriver); /*Basic initialization*/
touchDriver.type = LV_INDEV_TYPE_POINTER; /*See below.*/
@@ -341,7 +281,6 @@ static void init_theme()
LvglWrapper::LvglWrapper()
{
lv_init();
init_lvgl_drivers();
init_theme();
@@ -352,8 +291,8 @@ LvglWrapper::LvglWrapper()
void LvglWrapper::run()
{
tmr10ms_t tick = get_tmr10ms();
lv_tick_inc((tick - lastTick) * 10);
lastTick = tick;
lv_timer_handler();
tmr10ms_t tick = get_tmr10ms();
lv_tick_inc((tick - lastTick) * 10);
lastTick = tick;
lv_timer_handler();
}
+4 -3
View File
@@ -19,19 +19,20 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "libopenui_config.h"
#include "font.h"
#if !defined(BOOT)
static const lv_font_t* lvglFontTable[FONTS_COUNT] = {
LV_FONT_DEFAULT, // FONT_STD_INDEX
#if !defined(BOOT)
&lv_font_roboto_bold_16, // FONT_BOLD_INDEX
&lv_font_roboto_9, // FONT_XXS_INDEX
&lv_font_roboto_13, // FONT_XS_INDEX
&lv_font_roboto_24, // FONT_L_INDEX
&lv_font_roboto_bold_32, // FONT_XL_INDEX
&lv_font_roboto_bold_64, // FONT_XXL_INDEX
#endif
};
#endif
const lv_font_t* getFont(LcdFlags flags)
{
+99 -3
View File
@@ -20,13 +20,109 @@
*/
#include "lcd.h"
#include "opentx.h"
#include <lvgl/lvgl.h>
void lcdSetContrast()
extern BitmapBuffer * lcdFront;
extern BitmapBuffer * lcd;
static lv_disp_draw_buf_t disp_buf;
static lv_disp_drv_t disp_drv;
static lv_disp_t* disp = nullptr;
static lv_area_t screen_area = {
0, 0, LCD_W-1, LCD_H-1
};
void newLcdRefresh(uint16_t* buffer, const rect_t& copy_area);
static void flushLcd(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lcdSetRefVolt(g_eeGeneral.contrast);
lv_area_t refr_area;
lv_area_copy(&refr_area, area);
#if defined(LCD_VERTICAL_INVERT)
lv_coord_t tmp_coord;
tmp_coord = refr_area.y2;
refr_area.y2 = LCD_H - refr_area.y1 - 1;
refr_area.y1 = LCD_H - tmp_coord - 1;
tmp_coord = refr_area.x2;
refr_area.x2 = LCD_W - refr_area.x1 - 1;
refr_area.x1 = LCD_W - tmp_coord - 1;
#endif
if (refr_area.x1 != 0 || refr_area.x2 != LCD_W-1 || refr_area.y1 != 0 ||
refr_area.y2 != LCD_H-1) {
TRACE("partial refresh @ 0x%p {%d,%d,%d,%d}", color_p, refr_area.x1,
refr_area.y1, refr_area.x2, refr_area.y2);
} else {
TRACE("full refresh @ 0x%p", color_p);
}
rect_t copy_area = {refr_area.x1, refr_area.y1,
refr_area.x2 - refr_area.x1 + 1,
refr_area.y2 - refr_area.y1 + 1};
newLcdRefresh((uint16_t*)color_p, copy_area);
lv_disp_flush_ready(disp_drv);
}
void lcdInitDisplayDriver()
{
lv_init();
lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(), LCD_W*LCD_H);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
disp_drv.flush_cb = flushLcd; /*Set a flush callback to draw to the display*/
disp_drv.hor_res = LCD_W; /*Set the horizontal resolution in pixels*/
disp_drv.ver_res = LCD_H; /*Set the vertical resolution in pixels*/
disp_drv.full_refresh = 0;
disp_drv.direct_mode = 0;
#if defined (LCD_VERTICAL_INVERT)
disp_drv.rotated = LV_DISP_ROT_180;
#endif
disp_drv.sw_rotate = 1;
// Register the driver and save the created display object
disp = lv_disp_drv_register(&disp_drv);
// remove all styles on default screen (makes it transparent as well)
lv_obj_remove_style_all(lv_scr_act());
// transparent background:
// - this prevents LVGL overwritting things drawn directly into the bitmap buffer
lv_disp_set_bg_opa(disp, LV_OPA_TRANSP);
// allow drawing at any moment
_lv_refr_set_disp_refreshing(disp);
lv_draw_ctx_t * draw_ctx = disp->driver->draw_ctx;
lcd->setDrawCtx(draw_ctx);
lcdFront->setDrawCtx(draw_ctx);
}
void lcdInitDirectDrawing()
{
lv_draw_ctx_t* draw_ctx = disp->driver->draw_ctx;
draw_ctx->buf = disp->driver->draw_buf->buf_act;
draw_ctx->buf_area = &screen_area;
draw_ctx->clip_area = &screen_area;
lcd->setData((pixel_t*)draw_ctx->buf);
}
void lcdRefresh()
{
_lv_inv_area(nullptr, &screen_area);
lv_refr_now(nullptr);
}
void lcdFlushed()
{
lv_disp_t* disp = _lv_refr_get_disp_refreshing();
lv_disp_flush_ready(disp->driver);
}
//TODO: move this somewhere else
event_t getWindowEvent()
{
return getEvent(false);
+11 -17
View File
@@ -25,28 +25,11 @@
#include "bitmapbuffer.h"
#include "opentx_types.h"
#if LCD_W >= 480
#define LCD_COLS 40
#else
#define LCD_COLS 30
#endif
#define CENTER
#include "colors.h"
#define DISPLAY_PIXELS_COUNT (LCD_W * LCD_H)
#define DISPLAY_BUFFER_SIZE (DISPLAY_PIXELS_COUNT)
extern coord_t lcdNextPos;
inline void lcdClear()
{
lcd->clear();
}
void lcdDrawBlackOverlay();
#if defined(BOOT)
#define BLINK_ON_PHASE (0)
#else
@@ -55,4 +38,15 @@ void lcdDrawBlackOverlay();
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
#endif
// Init LVGL and its display driver
void lcdInitDisplayDriver();
// Patch the draw context to allow for direct drawing
void lcdInitDirectDrawing();
inline void lcdClear() { lcd->clear(); }
void lcdRefresh();
void lcdFlushed();
#endif // _LCD_H_
+3 -37
View File
@@ -19,9 +19,9 @@
* GNU General Public License for more details.
*/
#ifndef _LIBOPENUI_H_
#define _LIBOPENUI_H_
#pragma once
#if !defined(BOOT)
#include "libopenui_config.h"
#include "libopenui_file.h"
#include "font.h"
@@ -58,38 +58,4 @@
#include "draw_functions.h"
#include "textedits.h"
#include "LvglWrapper.h"
inline MessageDialog * createPopupInformation(const char * message)
{
return new MessageDialog(MainWindow::instance(), "Message", message);
}
inline MessageDialog * createPopupWarning(const char * message)
{
return new MessageDialog(MainWindow::instance(), "Warning", message);
}
inline void POPUP_INFORMATION(const char * message)
{
auto popup = createPopupInformation(message);
while (popup->getParent()) {
WDG_RESET();
MainWindow::instance()->run(false);
LvglWrapper::instance()->run();
}
}
inline void POPUP_WARNING(const char * message, const char * info = nullptr)
{
auto popup = createPopupWarning(message);
if (info) {
popup->setInfoText(std::string(info));
}
while (popup->getParent()) {
WDG_RESET();
MainWindow::instance()->run(false);
LvglWrapper::instance()->run();
}
}
#endif // _LIBOPENUI_H_
#endif
+34
View File
@@ -22,8 +22,42 @@
#ifndef _POPUPS_H_
#define _POPUPS_H_
#include "libopenui.h"
#include <functional>
typedef std::function<void(const char *, const char *, int, int)> ProgressHandler;
inline MessageDialog * createPopupInformation(const char * message)
{
return new MessageDialog(MainWindow::instance(), "Message", message);
}
inline MessageDialog * createPopupWarning(const char * message)
{
return new MessageDialog(MainWindow::instance(), "Warning", message);
}
inline void POPUP_INFORMATION(const char * message)
{
auto popup = createPopupInformation(message);
while (popup->getParent()) {
WDG_RESET();
MainWindow::instance()->run(false);
LvglWrapper::instance()->run();
}
}
inline void POPUP_WARNING(const char * message, const char * info = nullptr)
{
auto popup = createPopupWarning(message);
if (info) {
popup->setInfoText(std::string(info));
}
while (popup->getParent()) {
WDG_RESET();
MainWindow::instance()->run(false);
LvglWrapper::instance()->run();
}
}
#endif // _POPUPS_H_
+2
View File
@@ -23,6 +23,8 @@
#include "opentx.h"
#include "options.h"
#include "libopenui.h"
#include "fw_version.h"
#if defined(CROSSFIRE)
#include "mixer_scheduler.h"
#endif
-7
View File
@@ -55,13 +55,6 @@ void ViewTextWindow::extractNameSansExt()
openFromEnd = !strcmp(ext, LOGS_EXT);
}
void ViewTextWindow::buildBody(Window *window)
{
GridLayout grid(window);
grid.spacer();
int i;
FIL file;
// assume average characte is 10 pixels wide, round the string length to tens.
// Font is not fixed width, so this is for the worst case...
maxLineLength = static_cast<int>(window->width() / 10 / 10) * 10 - 2;
+1
View File
@@ -69,6 +69,7 @@ class ViewTextWindow : public Page
Page::paint(dc);
drawVerticalScrollbar(dc);
}
void checkEvents() override;
#if defined(DEBUG_WINDOWS)
+2
View File
@@ -33,9 +33,11 @@
#define HIDDEN_ROW ((uint8_t)-2)
#if defined(ROTARY_ENCODER_NAVIGATION)
#define CASE_ROTARY_ENCODER(x) x,
#define CASE_EVT_ROTARY_LEFT case EVT_ROTARY_LEFT:
#define CASE_EVT_ROTARY_RIGHT case EVT_ROTARY_RIGHT:
#else
#define CASE_ROTARY_ENCODER(x)
#define CASE_EVT_ROTARY_LEFT
#define CASE_EVT_ROTARY_RIGHT
#endif
+146
View File
@@ -201,4 +201,150 @@ uint16_t getAnalogValue(uint8_t index)
else
return adcValues[index];
}
static uint32_t s_anaFilt[NUM_ANALOGS];
#define JITTER_ALPHA (1<<JITTER_FILTER_STRENGTH)
#define ANALOG_MULTIPLIER (1<<ANALOG_SCALE)
#define ANA_FILT(chan) (s_anaFilt[chan] / (JITTER_ALPHA * ANALOG_MULTIPLIER))
#if (JITTER_ALPHA * ANALOG_MULTIPLIER > 32)
#error "JITTER_FILTER_STRENGTH and ANALOG_SCALE are too big, their summ should be <= 5 !!!"
#endif
uint16_t anaIn(uint8_t chan)
{
return ANA_FILT(chan);
}
#if defined(JITTER_MEASURE)
JitterMeter<uint16_t> rawJitter[NUM_ANALOGS];
JitterMeter<uint16_t> avgJitter[NUM_ANALOGS];
tmr10ms_t jitterResetTime = 0;
#endif
uint16_t getBatteryVoltage()
{
// using filtered ADC value on purpose
int32_t instant_vbat = anaIn(TX_VOLTAGE);
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration)) /
BATTERY_DIVIDER);
}
extern uint16_t get_flysky_hall_adc_value(uint8_t ch);
void getADC()
{
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
// reset jitter measurement every second
for (uint32_t x=0; x<NUM_ANALOGS; x++) {
rawJitter[x].reset();
avgJitter[x].reset();
}
jitterResetTime = get_tmr10ms() + 100; //every second
}
#endif
DEBUG_TIMER_START(debugTimerAdcRead);
if (!adcRead())
TRACE("adcRead failed");
DEBUG_TIMER_STOP(debugTimerAdcRead);
for (uint8_t x=0; x<NUM_ANALOGS; x++) {
uint32_t v;
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
if (globalData.flyskygimbals)
{
if (x < 4) {
v = get_flysky_hall_adc_value(x) >> (1 - ANALOG_SCALE);
} else {
v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
}
}
else
#endif
{
v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
}
// Jitter filter:
// * pass trough any big change directly
// * for small change use Modified moving average (MMA) filter
//
// Explanation:
//
// Normal MMA filter has this formula:
// <out> = ((ALPHA-1)*<out> + <in>)/ALPHA
//
// If calculation is done this way with integer arithmetics, then any small change in
// input signal is lost. One way to combat that, is to rearrange the formula somewhat,
// to store a more precise (larger) number between iterations. The basic idea is to
// store undivided value between iterations. Therefore an new variable <filtered> is
// used. The new formula becomes:
// <filtered> = <filtered> - <filtered>/ALPHA + <in>
// <out> = <filtered>/ALPHA (use only when out is needed)
//
// The above formula with a maximum allowed ALPHA value (we are limited by
// the 16 bit s_anaFilt[]) was tested on the radio. The resulting signal still had
// some jitter (a value of 1 was observed). The jitter might be bigger on other
// radios.
//
// So another idea is to use larger input values for filtering. So instead of using
// input in a range from 0 to 2047, we use twice larger number (temp[x] is divided less)
//
// This also means that ALPHA must be lowered (remember 16 bit limit), but test results
// have proved that this kind of filtering gives better results. So the recommended values
// for filter are:
// JITTER_FILTER_STRENGTH 4
// ANALOG_SCALE 1
//
// Variables mapping:
// * <in> = v
// * <out> = s_anaFilt[x]
uint32_t previous = s_anaFilt[x] / JITTER_ALPHA;
uint32_t diff = (v > previous) ? (v - previous) : (previous - v);
// Combine ADC jitter filter setting form radio and model.
// Model can override (on or off) or use setting from radio setup.
// Model setting is active when 1, radio setting is active when 0
uint8_t useJitterFilter = 0;
if (g_model.jitterFilter == OVERRIDE_GLOBAL) {
// Use radio setting - which is inverted
useJitterFilter = !g_eeGeneral.noJitterFilter;
} else {
// Enable if value is "On", disable if "Off"
useJitterFilter = (g_model.jitterFilter == OVERRIDE_ON)?1:0;
}
if (useJitterFilter && diff < (10*ANALOG_MULTIPLIER)) {
// apply jitter filter
s_anaFilt[x] = (s_anaFilt[x] - previous) + v;
}
else {
// use unfiltered value
s_anaFilt[x] = v * JITTER_ALPHA;
}
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE()) {
avgJitter[x].measure(ANA_FILT(x));
}
#endif
#define ANAFILT_MAX (2 * RESX * JITTER_ALPHA * ANALOG_MULTIPLIER - 1)
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[x];
if (IS_POT_MULTIPOS(x) && IS_MULTIPOS_CALIBRATED(calib)) {
// TODO: consider adding another low pass filter to eliminate multipos switching glitches
uint8_t vShifted = ANA_FILT(x) >> 4;
s_anaFilt[x] = ANAFILT_MAX;
for (uint32_t i=0; i<calib->count; i++) {
if (vShifted < calib->steps[i]) {
s_anaFilt[x] = (i * ANAFILT_MAX) / calib->count;
break;
}
}
}
}
}
#endif // #if !defined(SIMU)
+19
View File
@@ -56,5 +56,24 @@ bool adcInit(const etx_hal_adc_driver_t* driver);
// void adcDeInit();
bool adcRead();
uint16_t getBatteryVoltage();
uint16_t getRTCBatteryVoltage();
uint16_t getAnalogValue(uint8_t index);
#define JITTER_FILTER_STRENGTH 4 // tune this value, bigger value - more filtering (range: 1-5) (see explanation below)
#define ANALOG_SCALE 1 // tune this value, bigger value - more filtering (range: 0-1) (see explanation below)
#if defined(JITTER_MEASURE)
extern JitterMeter<uint16_t> rawJitter[NUM_ANALOGS];
extern JitterMeter<uint16_t> avgJitter[NUM_ANALOGS];
#if defined(PCBHORUS) || defined(PCBTARANIS)
#define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuRadioDiagAnalogs)
#elif defined(CLI)
#define JITTER_MEASURE_ACTIVE() (1)
#else
#define JITTER_MEASURE_ACTIVE() (0)
#endif
#endif
void getADC();
uint16_t anaIn(uint8_t chan);
+3 -1
View File
@@ -19,7 +19,9 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "keys.h"
#include "timers.h"
#include "opentx_helpers.h"
#define KEY_LONG_DELAY 32 // long key press minimum duration (x10ms), must be less than KEY_REPEAT_DELAY
#define KEY_REPEAT_DELAY 40 // press longer than this enables repeat (but does not fire it yet)
+8
View File
@@ -205,4 +205,12 @@ bool keyDown();
extern uint8_t rotencSpeed;
#endif
struct InactivityData
{
uint16_t counter;
uint8_t sum;
};
extern InactivityData inactivity;
#endif // _KEYS_H_
+61 -4
View File
@@ -105,7 +105,13 @@
/*Enable complex draw engine.
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
#define LV_DRAW_COMPLEX 1
#if defined(BOOT)
#define LV_DRAW_COMPLEX 0
#else
#define LV_DRAW_COMPLEX 1
#endif
#if LV_DRAW_COMPLEX != 0
/*Allow buffering some shadow calculation.
@@ -369,7 +375,9 @@
/*Optionally declare custom fonts here.
*You can use these fonts as default font too and they will be available globally.
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
#define LV_FONT_CUSTOM_DECLARE \
#if !defined(BOOT)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_roboto_9) \
LV_FONT_DECLARE(lv_font_roboto_14) \
LV_FONT_DECLARE(lv_font_roboto_13) \
@@ -383,8 +391,13 @@
LV_FONT_DECLARE(lv_font_roboto_bold_32) \
LV_FONT_DECLARE(lv_font_roboto_bold_64)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_roboto_16
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_roboto_16
#else
/* Bootloader font */
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(lv_font_roboto_bl_16)
#define LV_FONT_DEFAULT &lv_font_roboto_bl_16
#endif
/*Enable handling large font and/or fonts with a lot of characters.
*The limit depends on the font size, font face and bpp.
@@ -453,6 +466,7 @@
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
#if !defined(BOOT)
#define LV_USE_ARC 1
#define LV_USE_ANIMIMG 1
@@ -584,6 +598,45 @@
/*A layout similar to Grid in CSS.*/
#define LV_USE_GRID 1
#else
#define LV_USE_ARC 0
#define LV_USE_ANIMIMG 0
#define LV_USE_BAR 0
#define LV_USE_BTN 0
#define LV_USE_BTNMATRIX 0
#define LV_USE_CANVAS 0
#define LV_USE_CHECKBOX 0
#define LV_USE_DROPDOWN 0 /*Requires: lv_label*/
#define LV_USE_IMG 0 /*Requires: lv_label*/
#define LV_USE_LABEL 0
#define LV_USE_LINE 0
#define LV_USE_ROLLER 0 /*Requires: lv_label*/
#define LV_USE_SLIDER 0 /*Requires: lv_bar*/
#define LV_USE_SWITCH 0
#define LV_USE_TEXTAREA 0 /*Requires: lv_label*/
#define LV_USE_TABLE 0
#define LV_USE_CALENDAR 0
#define LV_USE_CHART 0
#define LV_USE_COLORWHEEL 0
#define LV_USE_IMGBTN 0
#define LV_USE_KEYBOARD 0
#define LV_USE_LED 0
#define LV_USE_LIST 0
#define LV_USE_MENU 0
#define LV_USE_METER 0
#define LV_USE_MSGBOX 0
#define LV_USE_SPINBOX 0
#define LV_USE_SPINNER 0
#define LV_USE_TABVIEW 0
#define LV_USE_TILEVIEW 0
#define LV_USE_WIN 0
#define LV_USE_SPAN 0
#define LV_USE_THEME_DEFAULT 0
#define LV_USE_THEME_BASIC 0
#define LV_USE_THEME_MONO 0
#define LV_USE_FLEX 0
#define LV_USE_GRID 0
#endif
/*---------------------
* 3rd party libraries
*--------------------*/
@@ -622,10 +675,14 @@
#endif
/*PNG decoder library*/
#if !defined(BOOT)
#define LV_USE_PNG 1
#endif
/*BMP decoder library*/
#if !defined(BOOT)
#define LV_USE_BMP 1
#endif
/* JPG + split JPG decoder library.
* Split JPG is a custom format optimized for embedded systems. */
-1
View File
@@ -158,7 +158,6 @@ void handleUsbConnection()
if (getSelectedUsbMode() == USB_MASS_STORAGE_MODE) {
opentxClose(false);
usbPluggedIn();
}
#if defined(USB_SERIAL)
else if (getSelectedUsbMode() == USB_SERIAL_MODE) {
+2 -1
View File
@@ -24,6 +24,7 @@
#include "datastructs.h"
#include "libopenui/src/bitfield.h"
#include "storage/yaml/yaml_defs.h"
#if defined(SDCARD_YAML)
#define EEPROM_VER 221
@@ -105,7 +106,7 @@
#define ALTERNATE_VIEW 0x10
#if defined(COLORLCD)
#if defined(COLORLCD) && !defined(BOOT)
#include "layout.h"
#include "theme.h"
#include "topbar.h"
+33 -152
View File
@@ -30,14 +30,11 @@
#include "radio_calibration.h"
#include "view_main.h"
#include "view_text.h"
#include "lvgl/lvgl.h"
#include "gui/colorlcd/LvglWrapper.h"
#endif
extern uint16_t get_flysky_hall_adc_value(uint8_t ch);
RadioData g_eeGeneral;
ModelData g_model;
@@ -92,12 +89,6 @@ const uint8_t modn12x3[] = {
3, 2, 1, 0 };
volatile uint8_t rtc_count = 0;
uint32_t watchdogTimeout = 0;
void watchdogSuspend(uint32_t timeout)
{
watchdogTimeout = timeout;
}
#if defined(DEBUG_LATENCY)
void toggleLatencySwitch()
@@ -118,15 +109,37 @@ void toggleLatencySwitch()
}
#endif
static void readKeysAndTrims()
{
uint32_t i;
uint8_t index = 0;
uint32_t keys_input = readKeys();
for (i = 0; i < TRM_BASE; i++) {
keys[index++].input(keys_input & (1 << i));
}
uint32_t trims_input = readTrims();
for (i = 1; i <= 1 << (TRM_LAST-TRM_BASE); i <<= 1) {
keys[index++].input(trims_input & i);
}
#if defined(PWR_BUTTON_PRESS)
if ((keys_input || trims_input || pwrPressed()) &&
(g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
#else
if ((keys_input || trims_input) &&
(g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
#endif
// on keypress turn the light on
resetBacklightTimeout();
}
}
void per10ms()
{
g_tmr10ms++;
if (watchdogTimeout) {
watchdogTimeout -= 1;
WDG_RESET(); // Retrigger hardware watchdog
}
#if defined(GUI)
if (lightOffCounter) lightOffCounter--;
if (flashCounter) flashCounter--;
@@ -200,6 +213,11 @@ void per10ms()
cw = new_cw;
lastEvent = g_tmr10ms;
}
if (g_eeGeneral.backlightMode & e_backlight_mode_keys) {
resetBacklightTimeout();
}
inactivity.counter = 0;
}
}
#endif
@@ -1061,142 +1079,6 @@ void checkTrims()
}
}
#if !defined(SIMU)
uint32_t s_anaFilt[NUM_ANALOGS];
#endif
#if defined(JITTER_MEASURE)
JitterMeter<uint16_t> rawJitter[NUM_ANALOGS];
JitterMeter<uint16_t> avgJitter[NUM_ANALOGS];
tmr10ms_t jitterResetTime = 0;
#endif
#define ANA_FILT(chan) (s_anaFilt[chan] / (JITTER_ALPHA * ANALOG_MULTIPLIER))
#if !defined(SIMU)
uint16_t anaIn(uint8_t chan)
{
return ANA_FILT(chan);
}
void getADC()
{
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
// reset jitter measurement every second
for (uint32_t x=0; x<NUM_ANALOGS; x++) {
rawJitter[x].reset();
avgJitter[x].reset();
}
jitterResetTime = get_tmr10ms() + 100; //every second
}
#endif
DEBUG_TIMER_START(debugTimerAdcRead);
if (!adcRead())
TRACE("adcRead failed");
DEBUG_TIMER_STOP(debugTimerAdcRead);
for (uint8_t x=0; x<NUM_ANALOGS; x++) {
uint32_t v;
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
if (globalData.flyskygimbals)
{
if (x < 4) {
v = get_flysky_hall_adc_value(x) >> (1 - ANALOG_SCALE);
} else {
v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
}
}
else
#endif
{
v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
}
// Jitter filter:
// * pass trough any big change directly
// * for small change use Modified moving average (MMA) filter
//
// Explanation:
//
// Normal MMA filter has this formula:
// <out> = ((ALPHA-1)*<out> + <in>)/ALPHA
//
// If calculation is done this way with integer arithmetics, then any small change in
// input signal is lost. One way to combat that, is to rearrange the formula somewhat,
// to store a more precise (larger) number between iterations. The basic idea is to
// store undivided value between iterations. Therefore an new variable <filtered> is
// used. The new formula becomes:
// <filtered> = <filtered> - <filtered>/ALPHA + <in>
// <out> = <filtered>/ALPHA (use only when out is needed)
//
// The above formula with a maximum allowed ALPHA value (we are limited by
// the 16 bit s_anaFilt[]) was tested on the radio. The resulting signal still had
// some jitter (a value of 1 was observed). The jitter might be bigger on other
// radios.
//
// So another idea is to use larger input values for filtering. So instead of using
// input in a range from 0 to 2047, we use twice larger number (temp[x] is divided less)
//
// This also means that ALPHA must be lowered (remember 16 bit limit), but test results
// have proved that this kind of filtering gives better results. So the recommended values
// for filter are:
// JITTER_FILTER_STRENGTH 4
// ANALOG_SCALE 1
//
// Variables mapping:
// * <in> = v
// * <out> = s_anaFilt[x]
uint32_t previous = s_anaFilt[x] / JITTER_ALPHA;
uint32_t diff = (v > previous) ? (v - previous) : (previous - v);
// Combine ADC jitter filter setting form radio and model.
// Model can override (on or off) or use setting from radio setup.
// Model setting is active when 1, radio setting is active when 0
uint8_t useJitterFilter = 0;
if (g_model.jitterFilter == OVERRIDE_GLOBAL) {
// Use radio setting - which is inverted
useJitterFilter = !g_eeGeneral.noJitterFilter;
} else {
// Enable if value is "On", disable if "Off"
useJitterFilter = (g_model.jitterFilter == OVERRIDE_ON)?1:0;
}
if (useJitterFilter && diff < (10*ANALOG_MULTIPLIER)) {
// apply jitter filter
s_anaFilt[x] = (s_anaFilt[x] - previous) + v;
}
else {
// use unfiltered value
s_anaFilt[x] = v * JITTER_ALPHA;
}
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE()) {
avgJitter[x].measure(ANA_FILT(x));
}
#endif
#define ANAFILT_MAX (2 * RESX * JITTER_ALPHA * ANALOG_MULTIPLIER - 1)
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[x];
if (IS_POT_MULTIPOS(x) && IS_MULTIPOS_CALIBRATED(calib)) {
// TODO: consider adding another low pass filter to eliminate multipos switching glitches
uint8_t vShifted = ANA_FILT(x) >> 4;
s_anaFilt[x] = ANAFILT_MAX;
for (uint32_t i=0; i<calib->count; i++) {
if (vShifted < calib->steps[i]) {
s_anaFilt[x] = (i * ANAFILT_MAX) / calib->count;
break;
}
}
}
}
}
#endif // SIMU
uint8_t g_vbat100mV = 0;
uint16_t lightOffCounter;
uint8_t flashCounter = 0;
@@ -1764,7 +1646,6 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
}
#if defined(ROTARY_ENCODER_NAVIGATION)
volatile rotenc_t rotencValue = 0;
uint8_t rotencSpeed;
#endif
@@ -1933,7 +1814,7 @@ void opentxInit()
}
#endif
#if defined(GUI)
#if defined(GUI) && !defined(COLORLCD)
lcdSetContrast();
#endif
+2 -85
View File
@@ -275,12 +275,6 @@ void memswap(void * a, void * b, uint8_t size);
#define IS_SWITCH_MULTIPOS(x) (false)
#endif
#if defined(PWR_BUTTON_PRESS)
#define pwrOffPressed() pwrPressed()
#else
#define pwrOffPressed() (!pwrPressed())
#endif
#define GET_LOWRES_POT_POSITION(i) (getValue(MIXSRC_FIRST_POT+(i)) >> 4)
#define SAVE_POT_POSITION(i) g_model.potsWarnPosition[i] = GET_LOWRES_POT_POSITION(i)
@@ -372,23 +366,6 @@ inline bool SPLASH_NEEDED()
#define SPLASH_TIMEOUT (4 * 100) // 4 seconds
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
#define CASE_ROTARY_ENCODER(x) x,
#define IS_ROTARY_ENCODER_NAVIGATION_ENABLE() true
extern volatile rotenc_t rotencValue;
#define ROTARY_ENCODER_NAVIGATION_VALUE rotencValue
#define ROTENC_LOWSPEED 1
#define ROTENC_MIDSPEED 5
#define ROTENC_HIGHSPEED 50
#define ROTENC_DELAY_MIDSPEED 32
#define ROTENC_DELAY_HIGHSPEED 16
#else
#define CASE_ROTARY_ENCODER(x)
#if defined(RADIO_T8)
constexpr uint8_t rotencSpeed = 1;
#endif
#endif
constexpr uint8_t HEART_TIMER_10MS = 0x01;
constexpr uint8_t HEART_TIMER_PULSES = 0x02; // when multiple modules this is the first one
@@ -403,23 +380,8 @@ constexpr uint8_t HEART_WDT_CHECK = HEART_TIMER_10MS
extern uint8_t heartbeat;
#if !defined(BOOT)
void watchdogSuspend(uint32_t timeout);
#define WATCHDOG_SUSPEND(x) watchdogSuspend(x)
#else
#define WATCHDOG_SUSPEND(...)
#endif
#define MAX_ALERT_TIME 60
struct InactivityData
{
uint16_t counter;
uint8_t sum;
};
extern InactivityData inactivity;
#define LEN_STD_CHARS 40
#if defined(TRANSLATIONS_CZ)
@@ -437,7 +399,6 @@ extern uint8_t potsPos[NUM_XPOTS];
#endif
bool trimDown(uint8_t idx);
void readKeysAndTrims();
#if defined(KEYS_GPIO_REG_BIND)
void bindButtonHandler(event_t event);
@@ -562,8 +523,6 @@ int getTrimValue(uint8_t phase, uint8_t idx);
bool setTrimValue(uint8_t phase, uint8_t idx, int trim);
#define ROTARY_ENCODER_GRANULARITY (2)
#include "gvars.h"
void flightReset(uint8_t check=true);
@@ -668,23 +627,6 @@ inline int calcRESXto100(int x)
return divRoundClosest(x*100, RESX);
}
#if defined(COLORLCD)
extern const char fw_stamp[];
extern const char vers_stamp[];
extern const char date_stamp[];
extern const char time_stamp[];
extern const char cfgv_stamp[];
#else
extern const char vers_stamp[];
#endif
/**
* Tries to find opentx version in the first 1024 byte of either firmware/bootloader (the one not running) or the buffer
* @param buffer If non-null find the firmware version in the buffer instead
* @return The opentx version string starting with "opentx-" or "no version found" if the version string is not found
*/
const char * getFirmwareVersion(const char * buffer = nullptr);
#define g_blinkTmr10ms (*(uint8_t*)&g_tmr10ms)
#include "trainer.h"
@@ -1078,11 +1020,13 @@ union ReusableBuffer
int8_t preset;
} curveEdit;
#if !defined(COLORLCD)
struct {
char filename[TEXT_FILENAME_MAXLEN];
char lines[NUM_BODY_LINES][LCD_COLS + 1];
int linesCount;
} viewText;
#endif
struct {
bool longNames;
@@ -1179,8 +1123,6 @@ void varioWakeup();
extern const unsigned char logo_taranis[];
#endif
void usbPluggedIn();
#include "lua/lua_api.h"
#if defined(SDCARD)
@@ -1212,31 +1154,6 @@ struct Clipboard {
extern Clipboard clipboard;
#endif
#if !defined(SIMU)
extern uint32_t s_anaFilt[NUM_ANALOGS];
#endif
#define JITTER_FILTER_STRENGTH 4 // tune this value, bigger value - more filtering (range: 1-5) (see explanation below)
#define ANALOG_SCALE 1 // tune this value, bigger value - more filtering (range: 0-1) (see explanation below)
#define JITTER_ALPHA (1<<JITTER_FILTER_STRENGTH)
#define ANALOG_MULTIPLIER (1<<ANALOG_SCALE)
#if (JITTER_ALPHA * ANALOG_MULTIPLIER > 32)
#error "JITTER_FILTER_STRENGTH and ANALOG_SCALE are too big, their summ should be <= 5 !!!"
#endif
#if defined(JITTER_MEASURE)
extern JitterMeter<uint16_t> rawJitter[NUM_ANALOGS];
extern JitterMeter<uint16_t> avgJitter[NUM_ANALOGS];
#if defined(PCBHORUS) || defined(PCBTARANIS)
#define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuRadioDiagAnalogs)
#elif defined(CLI)
#define JITTER_MEASURE_ACTIVE() (1)
#else
#define JITTER_MEASURE_ACTIVE() (0)
#endif
#endif
#if defined(INTERNAL_GPS)
#include "gps.h"
#endif
-1
View File
@@ -25,7 +25,6 @@
#include "thirdparty/libopenui/src/libopenui_types.h"
typedef uint32_t tmr10ms_t;
typedef int32_t rotenc_t;
typedef int32_t getvalue_t;
typedef uint32_t mixsrc_t;
typedef int32_t swsrc_t;
+3 -1
View File
@@ -19,8 +19,10 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "serial.h"
#include "board.h"
#include "debug.h"
#include <stdarg.h>
#include <stdio.h>
#include "aux_serial_driver.h"
+10
View File
@@ -489,7 +489,12 @@ long OpenTxSim::onTimeout(FXObject*, FXSelector, void*)
#endif
}
#if !defined(SIMU_BOOTLOADER)
per10ms();
#else
void interrupt10ms();
interrupt10ms();
#endif
static int timeToRefresh;
if (++timeToRefresh >= 5) {
timeToRefresh = 0;
@@ -518,6 +523,9 @@ void OpenTxSim::setPixel(int x, int y, FXColor color)
#endif
}
// from lcd driver
void lcdFlushed();
void OpenTxSim::refreshDisplay()
{
static bool lightEnabled = (bool)isBacklightEnabled();
@@ -575,6 +583,7 @@ void OpenTxSim::refreshDisplay()
bmf->setImage(bmp);
simuLcdRefresh = false;
lcdFlushed();
}
}
@@ -629,6 +638,7 @@ int main(int argc, char ** argv)
#if defined(EEPROM) || defined(EEPROM_RLC)
startEepromThread(argc >= 2 ? argv[1] : "eeprom.bin");
#endif
startAudioThread();
simuStart(true/*false*/, argc >= 3 ? argv[2] : 0, argc >= 4 ? argv[3] : 0);
+10 -2
View File
@@ -19,8 +19,11 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "stamp.h"
#include "definitions.h"
#include "board.h"
#include "fw_version.h"
#include <string.h>
#define STR2(s) #s
#define DEFNUMSTR(s) STR2(s)
@@ -113,4 +116,9 @@ const char * getFirmwareVersion(const char * buffer)
return "no version found";
}
#else
const char * getFirmwareVersion(const char * buffer)
{
return "edgetx-" FLAVOUR "-" VERSION DISPLAY_VERSION " (" GIT_STR ")";
}
#endif
+5 -16
View File
@@ -20,10 +20,11 @@
*/
#include "strhelpers.h"
#include "opentx.h"
#include <string.h>
#if !defined(BOOT)
#include "opentx.h"
const char s_charTab[] = "_-.,";
char hex2zchar(uint8_t hex) { return (hex >= 10 ? hex - 9 : 27 + hex); }
@@ -406,20 +407,6 @@ char *getFlightModeString(char *dest, int8_t idx)
return dest;
}
// char * getSwitchWarningString(char * dest, swsrc_t idx)
// {
// char * s = dest;
// uint8_t state = g_model.switchWarningState >> (3*idx) & 0x07;
// *s++ = 'A' + idx;
// if (state == 0)
// *s = '\0';
// else {
// *s++ = "x\300-\301"[state];
// *s = '\0';
// }
// return dest;
// }
int getRawSwitchIdx(char sw)
{
if (sw < 'A' || sw > 'Z')
@@ -763,6 +750,8 @@ char *strAppendFilename(char *dest, const char *filename, const int size)
}
#if defined(LIBOPENUI)
#include "bitmapbuffer.h"
std::string formatNumberAsString(int32_t val, LcdFlags flags, uint8_t len,
const char *prefix, const char *suffix)
{
@@ -21,11 +21,9 @@
#include "stm32_hal_ll.h"
#include "stm32_usart_driver.h"
#include "opentx.h"
#include "targets/horus/board.h"
#include "aux_serial_driver.h"
#include "board.h"
#include "fifo.h"
#include "dmafifo.h"
@@ -132,6 +132,13 @@ void delay_ms(uint32_t count);
}
#endif
#if !defined(BOOT)
void watchdogSuspend(uint32_t timeout);
#define WATCHDOG_SUSPEND(x) watchdogSuspend(x)
#else
#define WATCHDOG_SUSPEND(...)
#endif
#define INIT_KEYS_PINS(GPIO) \
GPIO_InitStructure.GPIO_Pin = KEYS_ ## GPIO ## _PINS; \
GPIO_Init(GPIO, &GPIO_InitStructure)
@@ -141,4 +148,26 @@ void delay_ms(uint32_t count);
GPIO_Init(GPIO, &GPIO_InitStructure); \
GPIO_SetBits(GPIO, KEYS_ ## GPIO ## _PINS)
#if defined(ROTARY_ENCODER_NAVIGATION)
typedef int32_t rotenc_t;
extern volatile rotenc_t rotencValue;
#define IS_ROTARY_ENCODER_NAVIGATION_ENABLE() true
#define ROTARY_ENCODER_NAVIGATION_VALUE rotencValue
#define ROTENC_LOWSPEED 1
#define ROTENC_MIDSPEED 5
#define ROTENC_HIGHSPEED 50
#define ROTENC_DELAY_MIDSPEED 32
#define ROTENC_DELAY_HIGHSPEED 16
#elif defined(RADIO_T8)
constexpr uint8_t rotencSpeed = 1;
#endif
#define ROTARY_ENCODER_GRANULARITY (2)
#if defined(PWR_BUTTON_PRESS)
#define pwrOffPressed() pwrPressed()
#else
#define pwrOffPressed() (!pwrPressed())
#endif
#endif
@@ -114,7 +114,7 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
${BOOTLOADER_SRC}
../../../../../gui/colorlcd/fonts.cpp
../../../../../gui/colorlcd/colors.cpp
../../../../../fonts/lvgl/lv_font_roboto_16.c
../../../../../fonts/lvgl/lv_font_roboto_bl_16.c
../../../../../thirdparty/libopenui/src/bitmapbuffer.cpp
../../../../../targets/${TARGET_DIR}/sdram_driver.c
../../../../../targets/common/arm/stm32/sdio_sd.c
@@ -124,7 +124,7 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
)
# Add LVGL sources
foreach(LVGL_FILE ${LVGL_SRC_FILES})
foreach(LVGL_FILE ${LVGL_SRC_FILES_MINIMAL})
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ../../../../../${LVGL_FILE})
endforeach()
@@ -174,15 +174,9 @@ set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC
# use smaller nano libc
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=nano.specs")
add_executable(bootloader EXCLUDE_FROM_ALL
${BOOTLOADER_SRC}
)
add_executable(bootloader EXCLUDE_FROM_ALL ${BOOTLOADER_SRC})
add_dependencies(bootloader ${BITMAPS_TARGET} radio_translations)
if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
add_dependencies(bootloader truetype_fonts)
endif()
add_custom_command(
TARGET bootloader POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary bootloader.elf ${CMAKE_BINARY_DIR}/bootloader.bin
@@ -19,9 +19,11 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "boot.h"
#include "sdcard.h"
#include "bin_files.h"
#include "fw_version.h"
#include "strhelpers.h"
// 'private'
static DIR dir;
@@ -22,7 +22,8 @@
#ifndef _bin_files_h_
#define _bin_files_h_
#include "opentx.h"
#include <FatFs/ff.h>
#include "bitmapbuffer.h"
enum MemoryType {
MEM_FLASH,
@@ -19,9 +19,11 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
#include "boot.h"
#include "bin_files.h"
#include "dataconstants.h"
#include "lcd.h"
#if defined(PCBXLITE)
#define BOOTLOADER_KEYS 0x0F
@@ -47,16 +49,14 @@ typedef void (*voidFunction)(void);
jumpFn(); \
} while(0)
#if !defined(SIMU)
// Bootloader marker:
// -> used to detect valid bootloader files
const uint8_t bootloaderVersion[] __attribute__ ((section(".version"), used)) =
{'B', 'O', 'O', 'T', '1', '0'};
#if defined(ROTARY_ENCODER_NAVIGATION)
volatile rotenc_t rotencValue = 0;
#endif
#if defined(DEBUG)
#if defined(DEBUG) && !defined(SIMU)
volatile tmr10ms_t g_tmr10ms;
#endif
@@ -113,14 +113,17 @@ void init10msTimer()
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn);
}
#if !defined(SIMU)
extern "C" void INTERRUPT_xMS_IRQHandler()
{
INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF;
interrupt10ms();
}
#endif
uint32_t isValidBufferStart(const uint8_t * buffer)
{
#if !defined(SIMU)
#if defined(EEPROM)
if (memoryType == MEM_FLASH)
return isFirmwareStart(buffer);
@@ -129,6 +132,9 @@ uint32_t isValidBufferStart(const uint8_t * buffer)
#else
return isFirmwareStart(buffer);
#endif
#else
return 1;
#endif
}
FlashCheckRes checkFlashFile(unsigned int index, FlashCheckRes res)
@@ -175,7 +181,9 @@ void flashWriteBlock()
{
uint32_t blockOffset = 0;
while (BlockCount) {
#if !defined(SIMU)
flashWrite((uint32_t *)firmwareAddress, (uint32_t *)&Block_buffer[blockOffset]);
#endif
blockOffset += FLASH_PAGESIZE;
firmwareAddress += FLASH_PAGESIZE;
if (BlockCount > FLASH_PAGESIZE) {
@@ -195,14 +203,9 @@ void writeEepromBlock()
}
#endif
int main()
#if !defined(SIMU)
void bootloaderInitApp()
{
BootloaderState state = ST_START;
uint32_t vpos = 0;
uint8_t index = 0;
FRESULT fr;
uint32_t nameCount = 0;
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph |
LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph |
AUX_SERIAL_RCC_AHB1Periph | AUX2_SERIAL_RCC_AHB1Periph |
@@ -281,6 +284,22 @@ int main()
// SD card detect pin
sdInit();
usbInit();
}
int main()
#else // SIMU
void bootloaderInitApp() {}
int bootloaderMain()
#endif
{
BootloaderState state = ST_START;
uint32_t vpos = 0;
uint8_t index = 0;
FRESULT fr;
uint32_t nameCount = 0;
// init hardware (may jump to app)
bootloaderInitApp();
// init screen
bootloaderInitScreen();
@@ -305,15 +324,18 @@ int main()
unlocked = 1;
unlockFlash();
}
#if !defined(SIMU)
usbStart();
usbPluggedIn();
#endif
}
}
if (state == ST_USB) {
if (usbPlugged() == 0) {
vpos = 0;
#if !defined(SIMU)
usbStop();
#endif
if (unlocked) {
lockFlash();
unlocked = 0;
@@ -528,12 +550,16 @@ int main()
lcdRefresh();
lcdRefreshWait();
#if !defined(SIMU)
#if defined(RTC_BACKUP_RAM)
rtcInit();
RTC->BKP0R = SOFTRESET_REQUEST;
#endif
NVIC_SystemReset();
#else
exit(1);
#endif
}
}
@@ -22,6 +22,7 @@
#ifndef _boot_h_
#define _boot_h_
#include <stdint.h>
#include "stamp.h"
#if LCD_W < 212
@@ -86,7 +87,7 @@ void bootloaderInitScreen();
// Depending on the state, up to two optional parameters are passed.
// See boot.cpp/main for more details
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str = NULL);
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str = nullptr);
// Once for each file in a filename list on screen
void bootloaderDrawFilename(const char* str, uint8_t line, bool selected);
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void waitFlashIdle()
{
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void pwrInit()
{
@@ -19,10 +19,10 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "heartbeat_driver.h"
#include "board.h"
uint8_t rotencPosition;
static uint8_t rotencPosition;
volatile rotenc_t rotencValue;
void rotaryEncoderInit()
{
@@ -123,12 +123,6 @@ void rotaryEncoderCheck()
rotencValue += INC_ROT;
}
rotencPosition = newPosition;
#endif
#if !defined(BOOT)
if (g_eeGeneral.backlightMode & e_backlight_mode_keys) {
resetBacklightTimeout();
}
inactivity.counter = 0;
#endif
}
}
@@ -19,7 +19,8 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
#include "rtc.h"
void rtcSetTime(const struct gtm * t)
{
@@ -52,7 +52,14 @@ void stop1msTimer()
NVIC_DisableIRQ(INTERRUPT_xMS_IRQn);
}
static void interrupt1ms()
static uint32_t watchdogTimeout = 0;
void watchdogSuspend(uint32_t timeout)
{
watchdogTimeout = timeout;
}
void interrupt1ms()
{
static uint8_t pre_scale; // Used to get 10 Hz counter
@@ -78,6 +85,12 @@ static void interrupt1ms()
// 10ms loop
if (pre_scale == 10) {
pre_scale = 0;
if (watchdogTimeout) {
watchdogTimeout -= 1;
WDG_RESET(); // Retrigger hardware watchdog
}
DEBUG_TIMER_START(debugTimerPer10ms);
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
per10ms();
@@ -19,24 +19,18 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "debug.h"
#include "usb_driver.h"
extern "C" {
#include "usb_conf.h"
#include "usb_dcd_int.h"
#include "usb_bsp.h"
#include "usbd_cdc_core.h"
#include "usbd_msc_core.h"
#include "usbd_hid_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
#include "usbd_conf.h"
}
#include "board.h"
#include "debug.h"
#include "debounce.h"
static bool usbDriverStarted = false;
#if defined(BOOT)
static usbMode selectedUsbMode = USB_MASS_STORAGE_MODE;
@@ -75,6 +69,8 @@ void usbInit()
usbDriverStarted = false;
}
extern void usbInitLUNs();
void usbStart()
{
switch (getSelectedUsbMode()) {
@@ -93,6 +89,7 @@ void usbStart()
default:
case USB_MASS_STORAGE_MODE:
// initialize USB as MSC device
usbInitLUNs();
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_MSC_cb, &USR_cb);
break;
}
@@ -111,6 +108,8 @@ bool usbStarted()
}
#if !defined(BOOT)
#include "globals.h"
/*
Prepare and send new USB data packet
@@ -20,9 +20,13 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "opentx.h"
#include "FatFs/diskio.h"
#include "stamp.h"
#include "fw_version.h"
#include "board.h"
#include "debug.h"
#include <string.h>
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
@@ -168,7 +172,7 @@ int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_si
uint8_t lunReady[STORAGE_LUN_NBR];
void usbPluggedIn()
void usbInitLUNs()
{
lunReady[STORAGE_SDCARD_LUN] = 1;
lunReady[STORAGE_EEPROM_LUN] = 1;
@@ -20,7 +20,6 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "opentx.h"
extern "C" {
#include "usbd_usr.h"
-1
View File
@@ -179,7 +179,6 @@ add_definitions(-DPCBREV_${PCBREV})
set(RADIO_DEPENDENCIES
${RADIO_DEPENDENCIES}
${BITMAPS_TARGET}
truetype_fonts
)
set(FIRMWARE_DEPENDENCIES datacopy)
+2 -1
View File
@@ -19,7 +19,8 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "board.h"
void backlightInit()
{
+6 -14
View File
@@ -20,13 +20,17 @@
*/
#include "stm32_hal_ll.h"
#include "opentx.h"
#include "hal/adc_driver.h"
#include "hal/serial_driver.h"
#include "hal/serial_port.h"
#include "board.h"
#include "timers_driver.h"
#include "dataconstants.h"
#include "opentx_types.h"
#include "globals.h"
#include "sdcard.h"
#include "debug.h"
#if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
#include "aux_serial_driver.h"
@@ -317,18 +321,6 @@ void boardOff()
}
}
#if defined (RADIO_TX16S)
#define BATTERY_DIVIDER 1495
#else
#define BATTERY_DIVIDER 1629
#endif
uint16_t getBatteryVoltage()
{
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration)) / BATTERY_DIVIDER);
}
bool isBacklightEnabled()
{
if(globalData.unexpectedShutdown)
+10 -6
View File
@@ -24,6 +24,10 @@
#include "definitions.h"
#include "opentx_constants.h"
// Defines used in board_common.h
#define ROTARY_ENCODER_NAVIGATION
#include "board_common.h"
#include "hal.h"
#include "hal/serial_port.h"
@@ -310,7 +314,6 @@ uint32_t readTrims();
#define TRIMS_PRESSED() (readTrims())
// Rotary encoder driver
#define ROTARY_ENCODER_NAVIGATION
void rotaryEncoderInit();
void rotaryEncoderCheck();
@@ -530,17 +533,12 @@ void ledBlue();
#define LCD_PHYS_W LCD_W
#define LCD_DEPTH 16
void lcdInit();
void lcdRefresh();
void lcdCopy(void * dest, void * src);
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
void lcdStoreBackupBuffer();
int lcdRestoreBackupBuffer();
void lcdSetContrast();
#define lcdOff() backlightEnable(0) /* just disable the backlight */
#define lcdSetRefVolt(...)
#define lcdRefreshWait(...)
// Backlight driver
@@ -677,4 +675,10 @@ void bluetoothWriteWakeup();
uint8_t bluetoothIsWriting();
void bluetoothDisable();
#if defined (RADIO_TX16S)
#define BATTERY_DIVIDER 1495
#else
#define BATTERY_DIVIDER 1629
#endif
#endif // _BOARD_H_
@@ -19,9 +19,14 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "../../common/arm/stm32/bootloader/boot.h"
#include "../../common/arm/stm32/bootloader/bin_files.h"
#include "board.h"
#include "fw_version.h"
#include "lcd.h"
#include "targets/common/arm/stm32/bootloader/boot.h"
#include "targets/common/arm/stm32/bootloader/bin_files.h"
#include <lvgl/lvgl.h>
const uint8_t __bmp_plug_usb_rle[] {
#include "bmp_plug_usb.lbm"
@@ -38,26 +43,12 @@ const uint8_t __bmp_background_rle[] {
};
RLEBitmap BMP_BACKGROUND(BMP_ARGB4444, __bmp_background_rle);
const uint8_t LBM_FLASH[] = {
#include "icon_flash.lbm"
};
const uint8_t LBM_EXIT[] = {
#include "icon_exit.lbm"
};
const uint8_t LBM_SD[] = {
#include "icon_sd.lbm"
};
//TODO: replace with LV_SYMBOL_FILE
const uint8_t LBM_FILE[] = {
#include "icon_file.lbm"
};
const uint8_t LBM_ERROR[] = {
#include "icon_error.lbm"
};
//TODO: replace with LV_SYMBOL_OK
const uint8_t LBM_OK[] = {
#include "icon_ok.lbm"
};
@@ -68,11 +59,12 @@ const uint8_t LBM_OK[] = {
#define BL_FOREGROUND COLOR2FLAGS(WHITE)
#define BL_SELECTED COLOR2FLAGS(RGB(11, 65, 244)) // deep blue
extern BitmapBuffer * lcd;
void bootloaderInitScreen()
{
backlightEnable(BACKLIGHT_LEVEL_MAX);
// TODO: init LVGL
lcdInitDisplayDriver();
}
static void bootloaderDrawTitle(unsigned int x, const char* text)
@@ -113,18 +105,21 @@ static void bootloaderDrawBackground()
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
{
lcdInitDirectDrawing();
bootloaderDrawBackground();
if (st == ST_START) {
bootloaderDrawTitle(88, BOOTLOADER_TITLE);
bootloaderDrawTitle(88, BOOTLOADER_TITLE);
lcd->drawBitmapPattern(90, 72, LBM_FLASH, BL_FOREGROUND);
lcd->drawText(124, 75, "Write Firmware", BL_FOREGROUND);
lcd->drawText(102, 75, LV_SYMBOL_CHARGE, BL_FOREGROUND);
coord_t pos = lcd->drawText(124, 75, "Write Firmware", BL_FOREGROUND);
pos += 8;
lcd->drawBitmapPattern(90, 107, LBM_EXIT, BL_FOREGROUND);
lcd->drawText(100, 110, LV_SYMBOL_NEW_LINE, BL_FOREGROUND);
lcd->drawText(124, 110, "Exit", BL_FOREGROUND);
lcd->drawSolidRect(119, (opt == 0) ? 72 : 107, 270, 26, 2, BL_SELECTED);
pos -= 92;
lcd->drawSolidRect(92, (opt == 0) ? 72 : 107, pos, 26, 2, BL_SELECTED);
lcd->drawBitmap(60, 166, &BMP_PLUG_USB);
lcd->drawText(195, 175, "Or plug in a USB cable", BL_FOREGROUND);
@@ -141,62 +136,55 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
else if (st == ST_FILE_LIST || st == ST_DIR_CHECK || st == ST_FLASH_CHECK ||
st == ST_FLASHING || st == ST_FLASH_DONE) {
bootloaderDrawTitle(126, "SD>FIRMWARE");
lcd->drawBitmapPattern(87, 16, LBM_SD, BL_FOREGROUND);
bootloaderDrawTitle(88, LV_SYMBOL_SD_CARD " /FIRMWARE");
if (st == ST_FLASHING || st == ST_FLASH_DONE) {
LcdFlags color = BL_RED;
LcdFlags color = BL_RED;
if (st == ST_FLASH_DONE) {
color = BL_GREEN;
opt = 100; // Completed > 100%
}
if (st == ST_FLASH_DONE) {
color = BL_GREEN;
opt = 100; // Completed > 100%
}
lcd->drawRect(70, 120, 340, 31, 2, SOLID, BL_SELECTED);
lcd->drawSolidFilledRect(74, 124, (332 * opt) / 100, 23, color);
} else if (st == ST_DIR_CHECK) {
if (opt == FR_NO_PATH) {
lcd->drawText(90, 168, LV_SYMBOL_CLOSE " Directory is missing",
BL_FOREGROUND);
} else {
lcd->drawText(90, 168, LV_SYMBOL_CLOSE " Directory is empty",
BL_FOREGROUND);
}
} else if (st == ST_FLASH_CHECK) {
bootloaderDrawFilename(str, 0, true);
lcd->drawRect(70, 120, 340, 31, 2, SOLID, BL_SELECTED);
lcd->drawSolidFilledRect(74, 124, (332 * opt) / 100, 23, color);
if (opt == FC_ERROR) {
lcd->drawText(94, 168, LV_SYMBOL_CLOSE " " STR_INVALID_FIRMWARE,
BL_FOREGROUND);
} else if (opt == FC_OK) {
VersionTag tag;
memset(&tag, 0, sizeof(tag));
extractFirmwareVersion(&tag);
lcd->drawText(168, 138, "Fork:", RIGHT | BL_FOREGROUND);
lcd->drawSizedText(174, 138, tag.fork, 6, BL_FOREGROUND);
lcd->drawText(168, 158, "Version:", RIGHT | BL_FOREGROUND);
lcd->drawText(174, 158, tag.version, BL_FOREGROUND);
lcd->drawText(168, 178, "Radio:", RIGHT | BL_FOREGROUND);
lcd->drawText(174, 178, tag.flavour, BL_FOREGROUND);
lcd->drawBitmapPattern(356, 158, LBM_OK, BL_GREEN);
}
}
else if (st == ST_DIR_CHECK) {
if (opt == FR_NO_PATH) {
lcd->drawText(90, 168, "Directory is missing", BL_FOREGROUND);
}
else {
lcd->drawText(90, 168, "Directory is empty", BL_FOREGROUND);
}
lcd->drawBitmapPattern(356, 158, LBM_ERROR, BL_RED);
}
else if (st == ST_FLASH_CHECK) {
bootloaderDrawFilename(str, 0, true);
if (opt == FC_ERROR) {
lcd->drawText(94, 168, STR_INVALID_FIRMWARE, BL_FOREGROUND);
lcd->drawBitmapPattern(356, 158, LBM_ERROR, BL_RED);
}
else if (opt == FC_OK) {
VersionTag tag;
memset(&tag, 0, sizeof(tag));
extractFirmwareVersion(&tag);
lcd->drawText(168, 138, "Fork:", RIGHT | BL_FOREGROUND);
lcd->drawSizedText(174, 138, tag.fork, 6, BL_FOREGROUND);
lcd->drawText(168, 158, "Version:", RIGHT | BL_FOREGROUND);
lcd->drawText(174, 158, tag.version, BL_FOREGROUND);
lcd->drawText(168, 178, "Radio:", RIGHT | BL_FOREGROUND);
lcd->drawText(174, 178, tag.flavour, BL_FOREGROUND);
lcd->drawBitmapPattern(356, 158, LBM_OK, BL_GREEN);
}
}
bootloaderDrawFooter();
if ( st != ST_DIR_CHECK && (st != ST_FLASH_CHECK || opt == FC_OK)) {
lcd->drawBitmapPattern(28, 242, LBM_FLASH, BL_FOREGROUND);
lcd->drawText(28, 242, LV_SYMBOL_CHARGE, BL_FOREGROUND);
if (st == ST_FILE_LIST) {
lcd->drawText(56, 244, "[ENT] to select file", BL_FOREGROUND);
@@ -213,14 +201,11 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
}
if (st != ST_FLASHING) {
lcd->drawBitmapPattern(305, 242, LBM_EXIT, BL_FOREGROUND);
//lcd->drawBitmapPattern(305, 242, LBM_EXIT, BL_FOREGROUND);
lcd->drawText(305, 244, LV_SYMBOL_NEW_LINE, BL_FOREGROUND);
lcd->drawText(335, 244, "[RTN] to exit", BL_FOREGROUND);
}
}
// wait for next frame
// while ((LTDC->CDSR & LTDC_CDSR_VSYNCS) == 0);
// while ((LTDC->CDSR & LTDC_CDSR_VSYNCS) != 0);
}
void bootloaderDrawFilename(const char* str, uint8_t line, bool selected)
+8 -2
View File
@@ -26,10 +26,11 @@
/*-----------------------------------------------------------------------*/
#include "diskio.h"
#include <string.h>
#include "opentx.h"
#include "debug.h"
#include "targets/common/arm/stm32/sdio_sd.h"
#include <string.h>
/*-----------------------------------------------------------------------*/
/* Lock / unlock functions */
/*-----------------------------------------------------------------------*/
@@ -328,6 +329,11 @@ void sdInit(void)
}
}
#else
#include "audio.h"
#include "sdcard.h"
#include "disk_cache.h"
void sdInit()
{
TRACE("sdInit");
+1 -1
View File
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void hapticOff(void)
{
+3 -23
View File
@@ -19,7 +19,9 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "board.h"
#include "keys.h"
uint32_t readKeys()
{
@@ -90,28 +92,6 @@ bool keyDown()
return readKeys() || readTrims();
}
/* TODO common to ARM */
void readKeysAndTrims()
{
uint32_t i;
uint8_t index = 0;
uint32_t keys_input = readKeys();
for (i = 0; i < TRM_BASE; i++) {
keys[index++].input(keys_input & (1 << i));
}
uint32_t trims_input = readTrims();
for (i = 1; i <= 1 << (TRM_LAST-TRM_BASE); i <<= 1) {
keys[index++].input(trims_input & i);
}
if ((keys_input || trims_input) && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
// on keypress turn the light on
resetBacklightTimeout();
}
}
#define ADD_2POS_CASE(x) \
case SW_S ## x ## 0: \
xxx = SWITCHES_GPIO_REG_ ## x & SWITCHES_GPIO_PIN_ ## x ; \
+6 -7
View File
@@ -19,7 +19,9 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "libopenui_config.h"
#include "lcd.h"
#if defined(RADIO_T18)
#define HBP 43
@@ -279,7 +281,7 @@ void LCD_LayerInit()
Active high width = LCD_W
number of bytes per pixel = 2 (pixel_format : RGB565)
*/
LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD__PHYS_W * 2) + 3);
LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PHYS_W * 2) + 3);
/* the pitch is the increment from the start of one line of pixels to the
start of the next line in bytes, then :
Pitch = Active high width x number of bytes per pixel */
@@ -657,8 +659,9 @@ static void lcdSwitchLayers()
while(_frameBufferAddressReloaded == 0);
}
void newLcdRefresh(uint16_t * buffer)
void newLcdRefresh(uint16_t * buffer, const rect_t& refr_area)
{
(void)refr_area;
#if 0
lcdSwitchLayers();
#else
@@ -669,7 +672,3 @@ void newLcdRefresh(uint16_t * buffer)
#endif
}
void lcdRefresh()
{
//lcdSwitchLayers();
}
+1 -1
View File
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void ledInit()
{
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void usbChargerInit()
{
@@ -34,6 +34,8 @@ void usbChargerInit()
bool usbChargerLed()
{
return GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_USBDet_GPIO_PIN) == 0 ? 0 : GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_CHARGER_GPIO_PIN) == Bit_RESET;
}
if (GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_USBDet_GPIO_PIN) == 0)
return 0;
return GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_CHARGER_GPIO_PIN) == Bit_RESET;
}
+1 -1
View File
@@ -62,7 +62,7 @@ set(LUA_EXPORT lua_export_nv14)
set(TOUCH_DRIVER touch_driver.cpp)
set(HARDWARE_TOUCH YES)
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET} truetype_fonts)
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
set(FIRMWARE_DEPENDENCIES datacopy)
set(HARDWARE_TOUCH ON)
+2 -1
View File
@@ -19,7 +19,8 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "board.h"
void backlightInit()
{
@@ -188,9 +188,3 @@ void handle_battery_charge(uint32_t last_press_time)
}
#endif
}
uint16_t getBatteryVoltage()
{
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration)) / 2942);
}
+9 -1
View File
@@ -19,13 +19,21 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
#include "globals.h"
#include "sdcard.h"
#include "touch.h"
#include "debug.h"
#include "hal/adc_driver.h"
#include "stm32_hal_adc.h"
#include "timers_driver.h"
#include "bitmapbuffer.h"
#include "colors.h"
#include <string.h>
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
+2 -5
View File
@@ -403,18 +403,13 @@ const etx_serial_port_t* auxSerialGetPort(int port_nr);
#define LCD_DEPTH 16
#define LCD_CONTRAST_DEFAULT 20
void lcdInit();
void lcdRefresh();
void lcdCopy(void * dest, void * src);
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
void lcdStoreBackupBuffer();
int lcdRestoreBackupBuffer();
void lcdSetContrast();
void lcdOff();
void lcdOn();
#define lcdSetRefVolt(...)
#define lcdRefreshWait(...)
// Backlight driver
@@ -521,4 +516,6 @@ bool touchPanelEventOccured();
struct TouchState touchPanelRead();
struct TouchState getInternalTouchState();
#define BATTERY_DIVIDER 2942
#endif // _BOARD_H_
@@ -19,10 +19,14 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
#include "fw_version.h"
#include "../../common/arm/stm32/bootloader/boot.h"
#include "../../common/arm/stm32/bootloader/bin_files.h"
#include <lvgl/lvgl.h>
#define SELECTED_COLOR (INVERS | COLOR_THEME_SECONDARY1)
#define DEFAULT_PADDING 28
#define DOUBLE_PADDING 56
@@ -73,10 +77,69 @@ const uint8_t LBM_OK[] = {
#define BL_FOREGROUND COLOR2FLAGS(WHITE)
#define BL_SELECTED COLOR2FLAGS(RGB(11, 65, 244)) // deep blue
extern BitmapBuffer * lcdFront;
extern BitmapBuffer * lcd;
static lv_disp_t* disp = nullptr;
static lv_disp_drv_t disp_drv;
static lv_disp_draw_buf_t disp_buf;
void newLcdRefresh(uint16_t* buffer, const rect_t& copy_area);
static void flushLcd(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lv_area_t refr_area;
lv_area_copy(&refr_area, area);
#if defined(LCD_VERTICAL_INVERT)
lv_coord_t tmp_coord;
tmp_coord = refr_area.y2;
refr_area.y2 = LCD_H - refr_area.y1 - 1;
refr_area.y1 = LCD_H - tmp_coord - 1;
tmp_coord = refr_area.x2;
refr_area.x2 = LCD_W - refr_area.x1 - 1;
refr_area.x1 = LCD_W - tmp_coord - 1;
#endif
if (refr_area.x1 != 0 || refr_area.x2 != 479 || refr_area.y1 != 0 ||
refr_area.y2 != 271) {
TRACE("partial refresh @ 0x%p {%d,%d,%d,%d}", color_p, refr_area.x1,
refr_area.y1, refr_area.x2, refr_area.y2);
} else {
TRACE("full refresh @ 0x%p", color_p);
}
rect_t copy_area = {refr_area.x1, refr_area.y1,
refr_area.x2 - refr_area.x1 + 1,
refr_area.y2 - refr_area.y1 + 1};
newLcdRefresh((uint16_t*)color_p, copy_area);
lv_disp_flush_ready(disp_drv);
}
static void init_disp_drv()
{
lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(), LCD_W*LCD_H);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
disp_drv.flush_cb = flushLcd; /*Set a flush callback to draw to the display*/
disp_drv.hor_res = LCD_W; /*Set the horizontal resolution in pixels*/
disp_drv.ver_res = LCD_H; /*Set the vertical resolution in pixels*/
disp_drv.full_refresh = 0;
disp_drv.direct_mode = 0;
#if defined (LCD_VERTICAL_INVERT)
disp_drv.rotated = LV_DISP_ROT_180;
#endif
disp_drv.sw_rotate = 1;
// Register the driver and save the created display objects
disp = lv_disp_drv_register(&disp_drv);
}
void bootloaderInitScreen()
{
backlightEnable(BACKLIGHT_LEVEL_MAX);
// TODO: init LVGL
lv_init();
init_disp_drv();
}
static void bootloaderDrawTitle(const char* text)
+8 -2
View File
@@ -26,10 +26,11 @@
/*-----------------------------------------------------------------------*/
#include "diskio.h"
#include <string.h>
#include "opentx.h"
#include "debug.h"
#include "targets/common/arm/stm32/sdio_sd.h"
#include <string.h>
// TODO share this with Horus (and perhaps other STM32)
/*-----------------------------------------------------------------------*/
@@ -325,6 +326,11 @@ void sdInit(void)
}
}
#else
#include "audio.h"
#include "sdcard.h"
#include "disk_cache.h"
void sdInit()
{
TRACE("sdInit");
+1 -1
View File
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void EXTERNAL_MODULE_ON()
{
+1 -1
View File
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "board.h"
void hapticOff(void)
{
+8 -24
View File
@@ -19,9 +19,16 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "board.h"
#include "keys.h"
#include "hal/adc_driver.h"
#if defined(LUA)
#include "lua/lua_api.h"
#endif
bool trimsAsButtons = false;
void setTrimsAsButtons(bool val) { trimsAsButtons = val; }
@@ -106,29 +113,6 @@ bool keyDown()
return readKeys() || readTrims();
}
/* TODO common to ARM */
void readKeysAndTrims()
{
int i;
uint8_t index = 0;
uint32_t in = readKeys();
uint32_t trims = readTrims();
for (i = 0; i < TRM_BASE; i++) {
keys[index++].input(in & (1 << i));
}
for (i = 1; i <= 1 << (TRM_LAST-TRM_BASE); i <<= 1) {
keys[index++].input(trims & i);
}
if ((in || trims) && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
// on keypress turn the light on
resetBacklightTimeout();
}
}
#if !defined(BOOT)
uint32_t switchState(uint8_t index)
{
+3 -1
View File
@@ -19,7 +19,9 @@
* GNU General Public License for more details.
*/
#include "opentx.h"
#include "opentx_types.h"
#include "libopenui_config.h"
#include "lcd.h"
#define LCD_FIRST_LAYER 0
#define LCD_SECOND_LAYER 1
+9
View File
@@ -38,6 +38,15 @@ if(SIMU_LUA_COMPILER)
add_definitions(-DLUA_COMPILER)
endif()
if(SIMU_BOOTLOADER)
add_definitions(-DSIMU_BOOTLOADER)
set(SIMU_SRC ${SIMU_SRC}
../../targets/common/arm/stm32/bootloader/bin_files.cpp
../../targets/common/arm/stm32/bootloader/boot.cpp
../../targets/${TARGET_DIR}/bootloader/boot_menu.cpp
)
endif()
if(Qt5Widgets_FOUND)
set(SIMULATOR_FLAVOUR edgetx-${FLAVOUR})
set(SIMULATOR_TARGET ${SIMULATOR_FLAVOUR}-simulator)
+20 -18
View File
@@ -137,6 +137,15 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
switchesStates[swtch] = state;
}
#if defined(SIMU_BOOTLOADER)
int bootloaderMain();
static void* bootloaderThread(void*)
{
bootloaderMain();
return nullptr;
}
#endif
void simuStart(bool tests, const char * sdPath, const char * settingsPath)
{
if (simu_running)
@@ -195,7 +204,18 @@ void simuStart(bool tests, const char * sdPath, const char * settingsPath)
try {
#endif
#if !defined(SIMU_BOOTLOADER)
simuMain();
#else
pthread_attr_t attr;
pthread_attr_init(&attr);
struct sched_param sp;
sp.sched_priority = SCHED_RR;
pthread_attr_setschedparam(&attr, &sp);
pthread_t bl_pid;
pthread_create(&bl_pid, &attr, &bootloaderThread, nullptr);
#endif
simu_running = true;
@@ -464,24 +484,6 @@ void pwrInit() {}
void pwrOn() {}
void pwrOff() {}
void readKeysAndTrims()
{
uint8_t index = 0;
auto keysInput = readKeys();
for (auto mask = (1 << 0); mask < (1 << TRM_BASE); mask <<= 1) {
keys[index++].input(keysInput & mask);
}
auto trimsInput = readTrims();
for (auto mask = (1 << 0); mask < (1 << NUM_TRIMS_KEYS); mask <<= 1) {
keys[index++].input(trimsInput & mask);
}
if (keysInput || trimsInput) {
resetBacklightTimeout();
}
}
bool keyDown()
{
return readKeys();
-44
View File
@@ -59,9 +59,6 @@ void lcdRefresh()
pixel_t displayBuf1[DISPLAY_BUFFER_SIZE];
pixel_t displayBuf2[DISPLAY_BUFFER_SIZE];
pixel_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE];
BitmapBuffer lcdBackup(BMP_RGB565, LCD_W, LCD_H, LCD_BACKUP_FRAME_BUFFER);
BitmapBuffer _lcd1(BMP_RGB565, LCD_W, LCD_H, displayBuf1);
BitmapBuffer _lcd2(BMP_RGB565, LCD_W, LCD_H, displayBuf2);
@@ -69,20 +66,6 @@ BitmapBuffer _lcd2(BMP_RGB565, LCD_W, LCD_H, displayBuf2);
BitmapBuffer * lcd = &_lcd1;
BitmapBuffer * lcdFront = &_lcd2;
void lcdStoreBackupBuffer()
{
memcpy(simuLcdBackupBuf, lcd->getData(),
DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
}
int lcdRestoreBackupBuffer()
{
memcpy(lcd->getData(), simuLcdBackupBuf,
DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
return 1;
}
void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area)
{
@@ -111,33 +94,6 @@ void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area)
// Mark screen dirty for async refresh
simuLcdRefresh = true;
// // .. and wait for refresh
// auto start = RTOS_GET_MS();
// while(simuLcdRefresh ||
// (RTOS_GET_MS() - start <= 100));
}
void lcdRefresh()
{
// Mark screen dirty for async refresh
simuLcdRefresh = true;
pixel_t* lcdData = lcd->getData();
#if defined(LCD_VERTICAL_INVERT)
auto src = lcdData + DISPLAY_BUFFER_SIZE - 1;
auto dst = simuLcdBuf;
auto end = dst + DISPLAY_BUFFER_SIZE;
while (dst != end) {
*(dst++) = *(src--);
}
#else
memcpy(simuLcdBuf, lcdData, DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
#endif
// Swap back & front buffers
std::swap(lcd, lcdFront);
}
void lcdInit()
-24
View File
@@ -140,30 +140,6 @@ bool keyDown()
return readKeys() || readTrims();
}
/* TODO common to ARM */
void readKeysAndTrims()
{
uint8_t index = 0;
uint32_t keys_input = readKeys();
for (unsigned i = 1; i != unsigned(1 << TRM_BASE); i <<= 1) {
keys[index++].input(keys_input & i);
}
uint32_t trims_input = readTrims();
for (uint8_t i = 1; i != uint8_t(1 << 8); i <<= 1) {
keys[index++].input(trims_input & i);
}
#if defined(PWR_BUTTON_PRESS)
if ((keys_input || trims_input || pwrPressed()) && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
#else
if ((keys_input || trims_input) && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
#endif
// on keypress turn the light on
resetBacklightTimeout();
}
}
#if defined(PCBX9E)
#define ADD_2POS_CASE(x) \
case SW_S ## x ## 2: \
+4
View File
@@ -21,6 +21,10 @@
#include "opentx.h"
#if defined(COLORLCD)
#define CENTER
#endif
#define ISTR(x) const char STR_##x[] = LEN_##x TR_##x
#if defined(COLORLCD)