mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-07-20 13:17:49 -06:00
🚸 Improve MKS UI with LVGL v6.1.2 (#27889)
This commit is contained in:
parent
d0e8edad3c
commit
c20c6b61f1
7 changed files with 1277 additions and 60 deletions
|
@ -579,7 +579,7 @@ char *creat_title_text() {
|
|||
update_spi_flash();
|
||||
}
|
||||
card.closefile();
|
||||
#endif
|
||||
#endif // HAS_MEDIA
|
||||
}
|
||||
|
||||
void gcode_preview(char *path, int xpos_pixel, int ypos_pixel) {
|
||||
|
@ -662,27 +662,27 @@ char *creat_title_text() {
|
|||
}
|
||||
|
||||
void draw_default_preview(int xpos_pixel, int ypos_pixel, uint8_t sel) {
|
||||
int index;
|
||||
static constexpr uint16_t draw_col_count = 40; // Number of rows displayed each time, determines the size of bmp_public_buf
|
||||
static constexpr int draw_count = 200 / draw_col_count; // Total number of times to be displayed
|
||||
static constexpr uint32_t pixel_count = (DEFAULT_VIEW_MAX_SIZE) / draw_count; // Number of pixels read per time (uint8_t)
|
||||
int y_off = 0;
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
for (index = 0; index < 10; index++) { // 200*200
|
||||
for (int index = 0; index < draw_count; index++) { // 200*200
|
||||
#if HAS_BAK_VIEW_IN_FLASH
|
||||
if (sel == 1) {
|
||||
flash_view_Read(bmp_public_buf, 8000); // 20k
|
||||
flash_view_Read(bmp_public_buf, pixel_count); // 16k
|
||||
}
|
||||
else {
|
||||
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
|
||||
default_view_Read(bmp_public_buf, pixel_count); // 16k
|
||||
}
|
||||
#else
|
||||
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
|
||||
default_view_Read(bmp_public_buf, pixel_count); // 8k
|
||||
#endif
|
||||
|
||||
SPI_TFT.setWindow(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
SPI_TFT.tftio.writeSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20);
|
||||
SPI_TFT.setWindow(xpos_pixel, y_off * draw_col_count + ypos_pixel, 200, draw_col_count); // 200 * draw_col_count
|
||||
SPI_TFT.tftio.writeSequence((uint16_t*)(bmp_public_buf), uint16_t(pixel_count / 2));
|
||||
|
||||
y_off++;
|
||||
}
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
}
|
||||
|
||||
void disp_pre_gcode(int xpos_pixel, int ypos_pixel) {
|
||||
|
@ -700,6 +700,7 @@ char *creat_title_text() {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_GCODE_PREVIEW
|
||||
|
||||
void print_time_run() {
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if ENABLED(USE_HASH_TABLE)
|
||||
#include "uthash.h"
|
||||
#endif
|
||||
|
||||
extern uint16_t DeviceCode;
|
||||
|
||||
#if HAS_MEDIA
|
||||
|
@ -92,7 +96,7 @@ static FSTR_P const assets[] = {
|
|||
F("bmp_file.bin"),
|
||||
|
||||
// Move motor screen
|
||||
// TODO: 6 equal icons, just in diffenct rotation... it may be optimized too
|
||||
// TODO: 6 equal icons, just in different rotation... it may be optimized too
|
||||
F("bmp_xAdd.bin"),
|
||||
F("bmp_xDec.bin"),
|
||||
F("bmp_yAdd.bin"),
|
||||
|
@ -223,42 +227,98 @@ static FSTR_P const assets[] = {
|
|||
static FSTR_P const fonts[] = { F("FontUNIGBK.bin") };
|
||||
#endif
|
||||
|
||||
uint8_t currentFlashPage = 0;
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
uint8_t currentFlashPage = 0;
|
||||
#endif
|
||||
|
||||
uint32_t lv_get_pic_addr(uint8_t *Pname) {
|
||||
uint8_t Pic_cnt;
|
||||
uint8_t i, j;
|
||||
PIC_MSG PIC;
|
||||
uint32_t tmp_cnt = 0;
|
||||
uint32_t addr = 0;
|
||||
#if ENABLED(USE_HASH_TABLE)
|
||||
|
||||
currentFlashPage = 0;
|
||||
typedef struct {
|
||||
char name[PIC_NAME_MAX_LEN - PIC_NAME_OFFSET]; /* key */
|
||||
uint32_t addr;
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
} PicHashEntry;
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
SERIAL_ECHOLNPGM("Getting picture SPI Flash Address: ", (const char*)Pname);
|
||||
#endif
|
||||
PicHashEntry* pic_hash = NULL;
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
// Initialize the image address hash table
|
||||
void init_img_map() {
|
||||
uint8_t Pic_cnt;
|
||||
W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
|
||||
if (Pic_cnt == 0xFF) Pic_cnt = 0;
|
||||
|
||||
W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
|
||||
if (Pic_cnt == 0xFF) Pic_cnt = 0;
|
||||
for (i = 0; i < Pic_cnt; i++) {
|
||||
j = 0;
|
||||
do {
|
||||
W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1);
|
||||
tmp_cnt++;
|
||||
} while (PIC.name[j++] != '\0');
|
||||
uint32_t tmp_cnt = 0;
|
||||
for (uint8_t i = 0; i < Pic_cnt; i++) {
|
||||
char name[PIC_NAME_MAX_LEN - PIC_NAME_OFFSET];
|
||||
uint8_t j = 0;
|
||||
do {
|
||||
W25QXX.SPI_FLASH_BufferRead((uint8_t*)&name[j], PIC_NAME_ADDR + tmp_cnt, 1);
|
||||
tmp_cnt++;
|
||||
} while (name[j++] != '\0');
|
||||
|
||||
if ((strcasecmp((char*)Pname, (char*)PIC.name)) == 0) {
|
||||
uint32_t addr;
|
||||
if (DeviceCode == 0x9488 || DeviceCode == 0x5761)
|
||||
addr = PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35;
|
||||
else
|
||||
addr = PIC_DATA_ADDR_TFT32 + i * PER_PIC_MAX_SPACE_TFT32;
|
||||
return addr;
|
||||
|
||||
// Add to hash table, don't save "bmp_"
|
||||
PicHashEntry* entry = (PicHashEntry*)malloc(sizeof(*entry));
|
||||
strncpy(entry->name, (name + PIC_NAME_OFFSET), sizeof(name));
|
||||
entry->addr = addr;
|
||||
HASH_ADD_STR(pic_hash, name, entry);
|
||||
}
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
SERIAL_ECHOLNPGM("Image Hash Table Count: ", HASH_COUNT(pic_hash), ", Size(Bytes): ", HASH_OVERHEAD(hh, pic_hash));
|
||||
#endif
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint32_t lv_get_pic_addr(uint8_t *Pname) {
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
SERIAL_ECHOLNPGM("Getting picture SPI Flash Address: ", (const char*)Pname);
|
||||
#endif
|
||||
|
||||
PicHashEntry* entry;
|
||||
HASH_FIND_STR(pic_hash, (char*)(Pname + PIC_NAME_OFFSET), entry);
|
||||
return entry ? entry->addr : 0;
|
||||
}
|
||||
|
||||
#else // !USE_HASH_TABLE
|
||||
|
||||
uint32_t lv_get_pic_addr(uint8_t *Pname) {
|
||||
uint8_t Pic_cnt;
|
||||
uint8_t i, j;
|
||||
PIC_MSG PIC;
|
||||
uint32_t tmp_cnt = 0;
|
||||
uint32_t addr = 0;
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
SERIAL_ECHOLNPGM("Getting picture SPI Flash Address: ", (const char*)Pname);
|
||||
#endif
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
|
||||
W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
|
||||
if (Pic_cnt == 0xFF) Pic_cnt = 0;
|
||||
for (i = 0; i < Pic_cnt; i++) {
|
||||
j = 0;
|
||||
do {
|
||||
W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1);
|
||||
tmp_cnt++;
|
||||
} while (PIC.name[j++] != '\0');
|
||||
|
||||
if ((strcasecmp((char*)Pname, (char*)PIC.name)) == 0) {
|
||||
if (DeviceCode == 0x9488 || DeviceCode == 0x5761)
|
||||
addr = PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35;
|
||||
else
|
||||
addr = PIC_DATA_ADDR_TFT32 + i * PER_PIC_MAX_SPACE_TFT32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
#endif // !USE_HASH_TABLE
|
||||
|
||||
const char *assetsPath = "assets";
|
||||
const char *bakPath = "_assets";
|
||||
|
@ -309,8 +369,8 @@ uint8_t picLogoWrite(uint8_t *LogoName, uint8_t *Logo_Wbuff, uint32_t LogoWriteS
|
|||
|
||||
uint32_t TitleLogoWrite_Addroffset = 0;
|
||||
uint8_t picTitleLogoWrite(uint8_t *TitleLogoName, uint8_t *TitleLogo_Wbuff, uint32_t TitleLogoWriteSize) {
|
||||
if (TitleLogoWriteSize <= 0)
|
||||
return 0;
|
||||
if (TitleLogoWriteSize <= 0) return 0;
|
||||
|
||||
if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761))
|
||||
W25QXX.SPI_FLASH_BufferWrite(TitleLogo_Wbuff, PIC_ICON_LOGO_ADDR_TFT35 + TitleLogoWrite_Addroffset, TitleLogoWriteSize);
|
||||
else
|
||||
|
@ -341,9 +401,7 @@ uint32_t picInfoWrite(uint8_t *P_name, uint32_t P_size) {
|
|||
union union32 size_tmp;
|
||||
|
||||
W25QXX.SPI_FLASH_BufferRead(&pic_counter, PIC_COUNTER_ADDR, 1);
|
||||
|
||||
if (pic_counter == 0xFF)
|
||||
pic_counter = 0;
|
||||
if (pic_counter == 0xFF) pic_counter = 0;
|
||||
|
||||
if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761))
|
||||
picSaveAddr = PIC_DATA_ADDR_TFT35 + pic_counter * PER_PIC_MAX_SPACE_TFT35;
|
||||
|
@ -416,6 +474,7 @@ uint32_t picInfoWrite(uint8_t *P_name, uint32_t P_size) {
|
|||
}
|
||||
|
||||
hal.watchdog_refresh();
|
||||
disp_string(100, 165, FTOP(F(" ")), 0xFFFF, 0x0000); // clean string
|
||||
disp_assets_update_progress(fn);
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
|
@ -449,16 +508,18 @@ uint32_t picInfoWrite(uint8_t *P_name, uint32_t P_size) {
|
|||
}
|
||||
else if (assetType == ASSET_TYPE_ICON) {
|
||||
Pic_Write_Addr = picInfoWrite((uint8_t*)fn, pfileSize);
|
||||
SPIFlash.beginWrite(Pic_Write_Addr);
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
SPIFlash.beginWrite(Pic_Write_Addr);
|
||||
do {
|
||||
hal.watchdog_refresh();
|
||||
pbr = file.read(public_buf, SPI_FLASH_PageSize);
|
||||
TERN_(MARLIN_DEV_MODE, totalSizes += pbr);
|
||||
SPIFlash.writeData(public_buf, SPI_FLASH_PageSize);
|
||||
} while (pbr >= SPI_FLASH_PageSize);
|
||||
SPIFlash.endWrite();
|
||||
#else
|
||||
do {
|
||||
hal.watchdog_refresh();
|
||||
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
|
||||
W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr);
|
||||
Pic_Write_Addr += pbr;
|
||||
|
@ -468,7 +529,6 @@ uint32_t picInfoWrite(uint8_t *P_name, uint32_t P_size) {
|
|||
SERIAL_ECHOLNPGM("Space used: ", fn, " - ", (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize / 1024, "KB");
|
||||
totalCompressed += (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize;
|
||||
#endif
|
||||
SPIFlash.endWrite();
|
||||
}
|
||||
else if (assetType == ASSET_TYPE_FONT) {
|
||||
Pic_Write_Addr = UNIGBK_FLASH_ADDR;
|
||||
|
@ -557,8 +617,7 @@ void picRead(uint8_t *Pname, uint8_t *P_Rbuff) {
|
|||
PIC_MSG PIC;
|
||||
|
||||
W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
|
||||
if (Pic_cnt == 0xFF)
|
||||
Pic_cnt = 0;
|
||||
if (Pic_cnt == 0xFF) Pic_cnt = 0;
|
||||
|
||||
for (i = 0; i < Pic_cnt; i++) {
|
||||
j = 0;
|
||||
|
@ -578,12 +637,12 @@ void picRead(uint8_t *Pname, uint8_t *P_Rbuff) {
|
|||
|
||||
void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size) {
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
if (currentFlashPage == 0)
|
||||
if (currentFlashPage == 0) {
|
||||
currentFlashPage = 1;
|
||||
SPIFlash.beginRead(addr);
|
||||
}
|
||||
SPIFlash.readData(P_Rbuff, size);
|
||||
currentFlashPage++;
|
||||
#else
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
W25QXX.SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, addr, size);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "SPIFlashStorage.h"
|
||||
|
||||
#define USE_HASH_TABLE
|
||||
|
||||
#ifndef HAS_SPI_FLASH_FONT
|
||||
#define HAS_SPI_FLASH_FONT 1 // Disabled until fix the font load code
|
||||
|
@ -53,7 +56,8 @@
|
|||
#endif
|
||||
|
||||
#define PIC_MAX_CN 100 // Maximum number of pictures
|
||||
#define PIC_NAME_MAX_LEN 50 // Picture name maximum length
|
||||
#define PIC_NAME_MAX_LEN 30 // Picture name maximum length
|
||||
#define PIC_NAME_OFFSET 4 // Same picture filename section
|
||||
|
||||
#define LOGO_MAX_SIZE_TFT35 (300 * 1024)
|
||||
#define LOGO_MAX_SIZE_TFT32 (150 * 1024)
|
||||
|
@ -61,7 +65,11 @@
|
|||
#define DEFAULT_VIEW_MAX_SIZE (200 * 200 * 2)
|
||||
#define FLASH_VIEW_MAX_SIZE (200 * 200 * 2)
|
||||
|
||||
#define PER_PIC_MAX_SPACE_TFT35 (9 * 1024)
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
#define PER_PIC_MAX_SPACE_TFT35 ( 9 * 1024)
|
||||
#else
|
||||
#define PER_PIC_MAX_SPACE_TFT35 (32 * 1024)
|
||||
#endif
|
||||
#define PER_PIC_MAX_SPACE_TFT32 (16 * 1024)
|
||||
#define PER_FONT_MAX_SPACE (16 * 1024)
|
||||
|
||||
|
@ -154,6 +162,9 @@ typedef struct pic_msg PIC_MSG;
|
|||
#define PIC_SIZE_xM 6
|
||||
#define FONT_SIZE_xM 2
|
||||
|
||||
#if ENABLED(USE_HASH_TABLE)
|
||||
void init_img_map();
|
||||
#endif
|
||||
void picRead(uint8_t *Pname, uint8_t *P_Rbuff);
|
||||
void picLogoRead(uint8_t *LogoName, uint8_t *Logo_Rbuff, uint32_t LogoReadsize);
|
||||
void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size);
|
||||
|
|
|
@ -85,7 +85,7 @@ lv_group_t* g;
|
|||
uint16_t DeviceCode = 0x9488;
|
||||
extern uint8_t sel_id;
|
||||
|
||||
uint8_t bmp_public_buf[14 * 1024];
|
||||
uint8_t bmp_public_buf[16 * 1024];
|
||||
uint8_t public_buf[513];
|
||||
|
||||
extern bool flash_preview_begin, default_preview_flg, gcode_preview_over;
|
||||
|
@ -149,9 +149,14 @@ void tft_lvgl_init() {
|
|||
|
||||
touch.init();
|
||||
|
||||
#if ENABLED(USE_HASH_TABLE)
|
||||
init_img_map(); // Initialize the image address hash table
|
||||
hal.watchdog_refresh(); // Hash table init takes time
|
||||
#endif
|
||||
|
||||
lv_init();
|
||||
|
||||
lv_disp_buf_init(&disp_buf, bmp_public_buf, nullptr, LV_HOR_RES_MAX * 14); // Initialize the display buffer
|
||||
lv_disp_buf_init(&disp_buf, bmp_public_buf, nullptr, LV_HOR_RES_MAX * 17); // Initialize the display buffer
|
||||
|
||||
lv_disp_drv_t disp_drv; // Descriptor of a display driver
|
||||
lv_disp_drv_init(&disp_drv); // Basic initialization
|
||||
|
@ -268,8 +273,6 @@ void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * co
|
|||
SPI_TFT.tftio.writeSequence((uint16_t*)color_p, width * height);
|
||||
lv_disp_flush_ready(disp_drv_p); // Indicate you are ready with the flushing
|
||||
#endif
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
}
|
||||
|
||||
#if ENABLED(USE_SPI_DMA_TC)
|
||||
|
@ -327,20 +330,26 @@ bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
|
|||
return false; // No more data to read so return false
|
||||
}
|
||||
|
||||
extern uint8_t currentFlashPage;
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
extern uint8_t currentFlashPage;
|
||||
#endif
|
||||
|
||||
// spi_flash
|
||||
uint32_t pic_read_base_addr = 0, pic_read_addr_offset = 0;
|
||||
lv_fs_res_t spi_flash_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) {
|
||||
static char last_path_name[30];
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
currentFlashPage = 0;
|
||||
#endif
|
||||
if (strcasecmp(last_path_name, path) != 0) {
|
||||
pic_read_base_addr = lv_get_pic_addr((uint8_t *)path);
|
||||
// clean lvgl image cache
|
||||
char cache_path_name[30 + 3] = {0};
|
||||
strcat(cache_path_name, "F:/");
|
||||
strcat(cache_path_name, (const char *)last_path_name);
|
||||
lv_img_cache_invalidate_src(cache_path_name);
|
||||
strcpy(last_path_name, path);
|
||||
}
|
||||
else {
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
currentFlashPage = 0;
|
||||
}
|
||||
pic_read_addr_offset = pic_read_base_addr;
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <lvgl.h>
|
||||
|
||||
extern uint8_t bmp_public_buf[14 * 1024];
|
||||
extern uint8_t bmp_public_buf[16 * 1024];
|
||||
extern uint8_t public_buf[513];
|
||||
|
||||
void tft_lvgl_init();
|
||||
|
|
1137
Marlin/src/lcd/extui/mks_ui/uthash.h
Normal file
1137
Marlin/src/lcd/extui/mks_ui/uthash.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@
|
|||
|
||||
[features]
|
||||
YHCB2004 = LiquidCrystal_AIP31068=https://github.com/ellensp/LiquidCrystal_AIP31068/archive/3fc43b7.zip, red-scorp/SoftSPIB@^1.1.1
|
||||
HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/a3ebe98bc6.zip
|
||||
HAS_TFT_LVGL_UI = lvgl=https://github.com/staff1010/LVGL-6.1.1-MKS/archive/v6.1.2.zip
|
||||
build_src_filter=+<src/lcd/extui/mks_ui>
|
||||
extra_scripts=download_mks_assets.py
|
||||
MARLIN_TEST_BUILD = build_src_filter=+<src/tests>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue