diff --git a/radio/src/fonts/lvgl/lv_font_roboto_bl_16.c b/radio/src/fonts/lvgl/lv_font_roboto_bl_16.c index 11476f578..cbf9e1ae1 100644 --- a/radio/src/fonts/lvgl/lv_font_roboto_bl_16.c +++ b/radio/src/fonts/lvgl/lv_font_roboto_bl_16.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 16 px * Bpp: 2 - * Opts: --no-prefilter --bpp 2 --size 16 --font ../Roboto/Roboto-Regular.ttf -r 0x20-0x7F --font ../../thirdparty/libopenui/thirdparty/lvgl/scripts/built_in_font/FontAwesome5-Solid+Brands+Regular.woff -r 61671,63650,63426,61453,61787,61452 --format lvgl -o lv_font_roboto_bl_16.c --force-fast-kern-format + * Opts: --no-prefilter --bpp 2 --size 16 --font ../Roboto/Roboto-Regular.ttf -r 0x20-0x7F --font ../../thirdparty/libopenui/thirdparty/lvgl/scripts/built_in_font/FontAwesome5-Solid+Brands+Regular.woff -r 61671,63650,63426,61453,61787,61452,61931 --format lvgl -o lv_font_roboto_bl_16.c --force-fast-kern-format ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -520,6 +520,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xfe, 0x3f, 0xfe, 0xe, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x40, + /* U+F1EB "" */ + 0xf, 0xfe, 0x6b, 0x7f, 0xa4, 0x3f, 0x3f, 0xff, + 0xc0, 0x43, 0x3f, 0xea, 0xdf, 0xe4, 0x7f, 0x21, + 0xf9, 0xfc, 0xfc, 0x87, 0xff, 0x1, 0xf8, 0x83, + 0x37, 0xe9, 0xd, 0x7, 0x3f, 0xfe, 0x43, 0xe7, + 0xf5, 0x6f, 0xc8, 0x7d, 0xe4, 0x3c, 0xf8, 0x3f, + 0xfa, 0x8f, 0x90, 0xff, 0xe2, 0x7e, 0xf, 0xfe, + 0x27, 0xe0, 0xff, 0xe2, 0x3e, 0x43, 0xf0, + /* U+F7C2 "" */ 0xa, 0xff, 0x90, 0x5f, 0xfc, 0x5c, 0x64, 0x9e, 0xbd, 0x19, 0x27, 0xf4, 0x64, 0x9f, 0xff, 0xff, @@ -639,8 +648,9 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 1989, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 2018, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, {.bitmap_index = 2056, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2074, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2095, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1} + {.bitmap_index = 2074, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2129, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2150, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1} }; /*--------------------- @@ -648,7 +658,7 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { *--------------------*/ static const uint16_t unicode_list_1[] = { - 0x0, 0x1, 0xdb, 0x14f, 0x7b6, 0x896 + 0x0, 0x1, 0xdb, 0x14f, 0x1df, 0x7b6, 0x896 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -660,7 +670,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 61452, .range_length = 2199, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 6, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 7, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -684,7 +694,7 @@ static const uint8_t kern_left_class_mapping[] = 0, 31, 0, 0, 32, 0, 31, 31, 33, 27, 0, 34, 0, 35, 0, 36, 37, 38, 36, 39, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; /*Map glyph_ids to kern right classes*/ @@ -702,7 +712,7 @@ static const uint8_t kern_right_class_mapping[] = 23, 0, 0, 0, 0, 0, 25, 25, 26, 25, 23, 27, 28, 29, 30, 31, 32, 33, 31, 34, 0, 0, 35, 0, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; /*Kern values between classes*/ diff --git a/radio/src/fonts/lvgl/make_fonts.sh b/radio/src/fonts/lvgl/make_fonts.sh index b3497eda6..3e76057a9 100755 --- a/radio/src/fonts/lvgl/make_fonts.sh +++ b/radio/src/fonts/lvgl/make_fonts.sh @@ -51,8 +51,8 @@ function make_font_no_sym() { } # LV_SYMBOL_CHARGE, LV_SYMBOL_NEW_LINE, LV_SYMBOL_SD_CARD, LV_SYMBOL_CLOSE -# LV_SYMBOL_FILE, LV_SYMBOL_OK -BL_SYMBOLS="61671,63650,63426,61453,61787,61452" +# LV_SYMBOL_FILE, LV_SYMBOL_OK, LV_SYMBOL_WIFI +BL_SYMBOLS="61671,63650,63426,61453,61787,61452,61931" function make_bootloader_font() { local name=$1 diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index b5bf4d303..875a8b2ae 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -227,6 +227,10 @@ void bootloaderInitApp() AUX2_SERIAL_RCC_APB2Periph, ENABLE); +#if defined(HAVE_BOARD_BOOTLOADER_INIT) + boardBootloaderInit(); +#endif + pwrInit(); keysInit(); @@ -299,6 +303,7 @@ int bootloaderMain() { BootloaderState state = ST_START; uint32_t vpos = 0; + uint32_t radioMenuItem = 0; uint8_t index = 0; FRESULT fr; uint32_t nameCount = 0; @@ -322,7 +327,8 @@ int bootloaderMain() if (tenms) { tenms = 0; - if (state != ST_USB && state != ST_FLASHING && state != ST_FLASH_DONE) { + if (state != ST_USB && state != ST_FLASHING + && state != ST_FLASH_DONE && state != ST_RADIO_MENU) { if (usbPlugged()) { state = ST_USB; if (!unlocked) { @@ -358,7 +364,7 @@ int bootloaderMain() bootloaderDrawScreen(state, vpos); if (event == EVT_KEY_FIRST(KEY_DOWN)) { - if (vpos < MAIN_MENU_LEN - 1) { vpos++; } + if (vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN) - 1) { vpos++; } continue; } else if (event == EVT_KEY_FIRST(KEY_UP)) { @@ -378,7 +384,13 @@ int bootloaderMain() break; #endif default: - state = ST_REBOOT; + if(vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN-1)) + { + state = ST_RADIO_MENU; + radioMenuItem = vpos - MAIN_MENU_LEN - 1; + } else { + state = ST_REBOOT; + } break; } @@ -513,6 +525,13 @@ int bootloaderMain() state = ST_FLASH_DONE; // Backstop } #endif + } else if (state == ST_RADIO_MENU) { + if(bootloaderRadioMenu(radioMenuItem, event)) + { + state = ST_START; + vpos = 0; + bootloaderDrawScreen(state, vpos); + } } if (state == ST_FLASH_DONE) { @@ -567,6 +586,6 @@ int bootloaderMain() return 0; } -#if defined(PCBHORUS) || defined(PCBNV14) +#if !defined(SIMU) && (defined(PCBHORUS) || defined(PCBNV14)) void *__dso_handle = nullptr; #endif diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.h b/radio/src/targets/common/arm/stm32/bootloader/boot.h index ec1ab8e31..06975bc61 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.h +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.h @@ -24,6 +24,7 @@ #include #include "stamp.h" +#include "keys.h" #if LCD_W < 212 #if defined(VERSION_TAG) @@ -70,6 +71,7 @@ enum BootloaderState { ST_FLASH_DONE, ST_RESTORE_MENU, ST_USB, + ST_RADIO_MENU, ST_REBOOT, }; @@ -92,6 +94,13 @@ 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); +// get menu item count for main menu, by adding 1 to the baseCount, when a radio specific menu is used +uint32_t bootloaderGetMenuItemCount(int baseCount); + +// when a radio specifc menu is used, all events are forwarded to that menu code +// returns true on submenu exit +bool bootloaderRadioMenu(uint32_t menuItem, event_t event); + void blExit(); #endif diff --git a/radio/src/targets/horus/bootloader/boot_menu.cpp b/radio/src/targets/horus/bootloader/boot_menu.cpp index 812669f92..d2d7bc2e6 100644 --- a/radio/src/targets/horus/bootloader/boot_menu.cpp +++ b/radio/src/targets/horus/bootloader/boot_menu.cpp @@ -216,6 +216,16 @@ void bootloaderDrawFilename(const char* str, uint8_t line, bool selected) } } +uint32_t bootloaderGetMenuItemCount(int baseCount) +{ + return baseCount; +} + +bool bootloaderRadioMenu(uint32_t menuItem, event_t event) +{ + return true; +} + void blExit(void) { lcdClear(); diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index 3eb6b02a7..4093d0945 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -112,6 +112,46 @@ void delay_self(int count) EXTMODULE_RCC_APB2Periph \ ) +static uint8_t boardGetPcbRev() +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(INTMODULE_RCC_AHB1Periph, ENABLE); + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN; + GPIO_Init(INTMODULE_PWR_GPIO, &GPIO_InitStructure); + delay_ms(1); // delay to let the input settle, else it does not work properly + + // detect NV14 vs EL18 + if (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) { + // pull-up connected: EL18 + return PCBREV_EL18; + } else { + // pull-down connected: NV14 + return PCBREV_NV14; + } +} + +void boardBootloaderInit() +{ +#if defined(USB_SW_PIN) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = USB_SW_PIN; + GPIO_Init(USB_SW_GPOIO, &GPIO_InitStructure); + RCC_AHB1PeriphClockCmd(USB_SW_AHB1Periph_GPIO, ENABLE); +#endif + + // detect NV14 vs EL18 + hardwareOptions.pcbrev = boardGetPcbRev(); +} + void boardInit() { #if defined(SEMIHOSTING) @@ -129,13 +169,7 @@ void boardInit() #endif // detect NV14 vs EL18 - if (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) { - // pull-up connected: EL18 - hardwareOptions.pcbrev = PCBREV_EL18; - } else { - // pull-down connected: NV14 - hardwareOptions.pcbrev = PCBREV_NV14; - } + hardwareOptions.pcbrev = boardGetPcbRev(); #if defined(DEBUG) serialInit(SP_AUX1, UART_MODE_DEBUG); diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index c1f75cfa5..4951412ea 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -53,6 +53,10 @@ extern uint16_t sessionTimer; #define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) #define TRAINER_CONNECTED() (true) +// initilizes the board for the bootloader +#define HAVE_BOARD_BOOTLOADER_INIT 1 +void boardBootloaderInit(); + // Board driver void boardInit(); void boardOff(); diff --git a/radio/src/targets/nv14/bootloader/boot_menu.cpp b/radio/src/targets/nv14/bootloader/boot_menu.cpp index a4849f444..dfb98c310 100644 --- a/radio/src/targets/nv14/bootloader/boot_menu.cpp +++ b/radio/src/targets/nv14/bootloader/boot_menu.cpp @@ -28,6 +28,11 @@ #include +#define RADIO_MENU_LEN 2 + +#define USB_SW_TO_INTERNAL_MODULE() GPIO_SetBits(USB_SW_GPOIO, USB_SW_PIN); +#define USB_SW_TO_MCU() GPIO_ResetBits(USB_SW_GPOIO, USB_SW_PIN); + #define SELECTED_COLOR (INVERS | COLOR_THEME_SECONDARY1) #define DEFAULT_PADDING 28 #define DOUBLE_PADDING 56 @@ -56,6 +61,8 @@ LZ4Bitmap BMP_BACKGROUND(BMP_ARGB4444, __bmp_background); extern BitmapBuffer * lcd; +static bool rfUsbAccess = false; + void bootloaderInitScreen() { lcdInitDisplayDriver(); @@ -107,18 +114,26 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str) int center = LCD_W/2; if (st == ST_START) { + int yOffset = 0; bootloaderDrawTitle(BOOTLOADER_TITLE); lcd->drawText(62, 75, LV_SYMBOL_CHARGE, BL_FOREGROUND); coord_t pos = lcd->drawText(84, 75, "Write Firmware", BL_FOREGROUND); pos += 8; + if(hardwareOptions.pcbrev == PCBREV_EL18) + { + lcd->drawText(57, 110, LV_SYMBOL_WIFI, BL_FOREGROUND); + lcd->drawText(84, 110, "RF USB access", BL_FOREGROUND); + pos += 8; + yOffset = 35; + } - lcd->drawText(60, 110, LV_SYMBOL_NEW_LINE, BL_FOREGROUND); - lcd->drawText(84, 110, "Exit", BL_FOREGROUND); + lcd->drawText(60, 110 + yOffset, LV_SYMBOL_NEW_LINE, BL_FOREGROUND); + lcd->drawText(84, 110 + yOffset, "Exit", BL_FOREGROUND); pos -= 79; - lcd->drawSolidRect(79, (opt == 0) ? 72 : 107, pos, 26, 2, BL_SELECTED); + lcd->drawSolidRect(79, 72 + (opt * 35), pos, 26, 2, BL_SELECTED); lcd->drawBitmap(center - 55, 165, (const BitmapBuffer*)&BMP_PLUG_USB); lcd->drawText(center, 250, "Or plug in a USB cable", CENTERED | BL_FOREGROUND); @@ -221,6 +236,18 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str) lcd->drawText(DOUBLE_PADDING, LCD_H - DEFAULT_PADDING, LV_SYMBOL_NEW_LINE " [L TRIM] to exit", BL_FOREGROUND); } + } else if (st == ST_RADIO_MENU) { + bootloaderDrawTitle("RF USB access"); + + lcd->drawText(62, 75, LV_SYMBOL_USB, BL_FOREGROUND); + coord_t pos = lcd->drawText(84, 75, rfUsbAccess?"Disable":"Enable", BL_FOREGROUND); + pos += 8; + + lcd->drawText(60, 110, LV_SYMBOL_NEW_LINE, BL_FOREGROUND); + lcd->drawText(84, 110, "Exit", BL_FOREGROUND); + + pos -= 79; + lcd->drawSolidRect(79, 72 + (opt * 35), pos, 26, 2, BL_SELECTED); } _first_screen = false; @@ -238,8 +265,52 @@ void bootloaderDrawFilename(const char* str, uint8_t line, bool selected) } } +uint32_t bootloaderGetMenuItemCount(int baseCount) +{ + if(hardwareOptions.pcbrev == PCBREV_EL18) + return baseCount+1; + + return baseCount; +} + +bool bootloaderRadioMenu(uint32_t menuItem, event_t event) +{ + static int pos = 0; + + if (event == EVT_KEY_FIRST(KEY_DOWN)) { + if (pos < RADIO_MENU_LEN-1) + pos++; + } else if (event == EVT_KEY_FIRST(KEY_UP)) { + if (pos > 0) + pos--; + } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { + switch (pos) { + case 0: + if (rfUsbAccess) + { + rfUsbAccess = false; + INTERNAL_MODULE_OFF(); + USB_SW_TO_MCU(); + } else { + rfUsbAccess = true; + INTERNAL_MODULE_ON(); + USB_SW_TO_INTERNAL_MODULE(); + } + break; + case 1: // fall through + default: + USB_SW_TO_MCU(); + pos = 0; + return true; + } + } + bootloaderDrawScreen(ST_RADIO_MENU, pos, nullptr); + return false; +} + void blExit(void) { + USB_SW_TO_MCU(); lcdClear(); lcdRefresh(); lcdRefreshWait(); diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index a5d571d7e..1a87d703f 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -245,6 +245,10 @@ #define USB_GPIO_PinSource_DP GPIO_PinSource12 #define USB_GPIO_AF GPIO_AF_OTG1_FS +#define USB_SW_AHB1Periph_GPIO RCC_AHB1Periph_GPIOI +#define USB_SW_GPOIO GPIOI +#define USB_SW_PIN GPIO_Pin_10 + // LCD #define LCD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_GPIOK | RCC_AHB1Periph_DMA2D) #define LCD_RCC_APB1Periph 0 diff --git a/radio/src/targets/taranis/bootloader/boot_menu.cpp b/radio/src/targets/taranis/bootloader/boot_menu.cpp index 92fc752d4..7014393cd 100644 --- a/radio/src/targets/taranis/bootloader/boot_menu.cpp +++ b/radio/src/targets/taranis/bootloader/boot_menu.cpp @@ -120,6 +120,16 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char *str) } } +uint32_t bootloaderGetMenuItemCount(int baseCount) +{ + return baseCount; +} + +bool bootloaderRadioMenu(uint32_t menuItem, event_t event) +{ + return true; +} + void blExit(void) { #if defined(RADIO_COMMANDO8)