Merge branch 'development' of https://github.com/arendst/Tasmota into development

This commit is contained in:
Theo Arends committed 2026-10-09 15:23:28 +02:00
commit 696fdb4bb2
2 files changed
+24 -5

No files matched your search

@@ -10,6 +10,7 @@
#include "esp_ldo_regulator.h"
#include "driver/gpio.h"
#include <rom/cache.h>
#include "esp_rom_sys.h"
extern void AddLog(uint32_t loglevel, const char* formatP, ...);
@@ -215,7 +216,25 @@ bool DSIPanel::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
}
bool DSIPanel::pushColors(uint16_t *data, uint32_t len, bool not_swapped) {
esp_err_t ret = esp_lcd_panel_draw_bitmap(panel_handle, window_x0, window_y0, window_x1, window_y1, data);
esp_err_t ret;
uint16_t retries = 0;
// esp_lcd_panel_draw_bitmap's DMA2D path takes the draw semaphore with a 0 timeout and
// returns ESP_ERR_INVALID_STATE (without drawing anything) if the previous async transfer
// hasn't completed yet - retry instead of silently dropping this chunk, which would leave
// stale framebuffer content on screen for that region. A ~60KB chunk transfer typically
// completes in well under 1ms, so poll in short bursts rather than in 1ms FreeRTOS ticks -
// the completion ISR isn't blocked by this busy-wait, so it doesn't delay noticing success.
const uint16_t max_retries = 300;
do {
ret = esp_lcd_panel_draw_bitmap(panel_handle, window_x0, window_y0, window_x1, window_y1, data);
if (ret == ESP_ERR_INVALID_STATE) {
esp_rom_delay_us(50);
retries++;
}
} while (ret == ESP_ERR_INVALID_STATE && retries < max_retries);
if (ret != ESP_OK) {
AddLog(3, "DSI: draw_bitmap failed after %d retries: %d", retries, ret);
}
return (ret == ESP_OK);
}
+4 -4
View File
@@ -95,19 +95,19 @@ void lv_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *color
}
uint32_t pixels_len = width * height;
uint32_t chrono_start = millis();
uint32_t chrono_start = micros();
renderer->setAddrWindow(area->x1, area->y1, area->x1+width, area->y1+height);
renderer->pushColors((uint16_t *)color_p, pixels_len, true);
renderer->setAddrWindow(0,0,0,0);
renderer->Updateframe();
uint32_t chrono_time = millis() - chrono_start;
uint32_t chrono_time = micros() - chrono_start;
lv_disp_flush_ready(disp);
if (pixels_len >= 10000 && (!renderer->lvgl_param.use_dma)) {
if (HighestLogLevel() >= LOG_LEVEL_DEBUG_MORE) {
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_LVGL "Refreshed %d pixels in %d ms (%i pix/ms)", pixels_len, chrono_time,
chrono_time > 0 ? pixels_len / chrono_time : -1);
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_LVGL "Refreshed %d pixels in %d us (%i pix/ms)", pixels_len, chrono_time,
chrono_time > 0 ? (pixels_len * 1000 / chrono_time) : -1);
}
}
// if there is a display callback, call it