Actually I’m embarrassed to say that that was not the solution. I was so excited, I didn’t notice that I was flashing the ESP32. Well when I eventually noticed, I had to reduce the the buffer line height back to 20, as in the code below.
When I set to theme dark mode, I uncovered another possibly related problem.
static void loadassist_lv_port_disp_init(void)
{
static lv_disp_draw_buf_t draw_buf_dsc; // contains internal graphic buffer(s) called draw buffer(s)
size_t disp_buf_height = 20;
/* Using static space for display buffer */
/**
* @brief OK 2022-01-06 After >16 hours of debugging and changing parameters,
* it appears that on the S3, if the disp_buf_height is set to 40, only every second
* buffer is transmitted to the LCD RAM. Setting to 20 solves the banding issue.
* Thx to Kisvegabor for pointing that out.
*/
static lv_color_t p_disp_buf1[LCD_WIDTH * 20];
static lv_color_t p_disp_buf2[LCD_WIDTH * 20];
/* Initialize display buffer */
lv_disp_draw_buf_init(&draw_buf_dsc, p_disp_buf1, p_disp_buf2, LCD_WIDTH * disp_buf_height);
ESP_LOGI(TAG, "Register display driver to LVGL");
lv_disp_drv_init(&disp_drv);
disp_drv.full_refresh = 0;
/*Set the resolution of the display*/
disp_drv.hor_res = LCD_WIDTH;
disp_drv.ver_res = LCD_HEIGHT;
/* Used to copy the buffer's content to the display */
disp_drv.flush_cb = disp_flush;
disp_drv.draw_buf = &draw_buf_dsc;
/* Use lcd_trans_done_cb to inform the graphics library that flush already done */
loadassist_lcd_set_cb(loadassist_lv_port_flush_ready, NULL);
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
It appears that the last pixel of the flushed buffer area is not set. This results in dots at the far right of the screen spaced at exactly every 20 lines.
Also there are dots, at the bottom right corner of each refreshed smaller area on the screen.
See images:
This problem is present on both the ESP32-S3 and ESP32.
ESP32 (just the 1st flushed buffer. Note last pixel - flush size 40 X 480):
ESP32 (full screen with all the artefacts. Notice the smaller updated area).
And then the ESP32-S3 (The full screen with buffer set to 20 lines, thus dots more frequently spaced).
Flush routine as follows:
static esp_err_t panel_ili9488_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data)
{
//!ESP_LOGI(TAG, "Draw the bitmap to the screen.....");
size_t len = (x_end - x_start) * (y_end - y_start);
ESP_LOGI(TAG, "LEN: %d x_end: %d x_start: %d y_end: %d y_start: %d", len, x_end, x_start, y_end, y_start);
//!ESP_LOGI(TAG, "Allocate DMA Memory for the 16Bit to 18Bit conversion %d.....", 3 * len * sizeof(uint8_t));
lv_color16_t *buffer_16bit = (lv_color16_t *) color_data;
uint8_t *mybuf;
do {
//heap_caps_print_heap_info(MALLOC_CAP_DMA);
mybuf = (uint8_t *) heap_caps_malloc(3 * len * sizeof(uint8_t), MALLOC_CAP_DMA);
if (mybuf == NULL) ESP_LOGE(TAG, "Could not allocate enough DMA memory for conversion 16bits to 18 bits! %d", 3 * len * sizeof(uint8_t));
} while (mybuf == NULL);
uint32_t LD = 0;
uint32_t j = 0;
for (uint32_t i = 0; i < len; i++) {
LD = buffer_16bit[i].full;
mybuf[j] = (uint8_t) (((LD & 0xF800) >> 8) | ((LD & 0x8000) >> 13));
j++;
mybuf[j] = (uint8_t) ((LD & 0x07E0) >> 3);
j++;
mybuf[j] = (uint8_t) (((LD & 0x001F) << 3) | ((LD & 0x0010) >> 2));
j++;
}
//!ESP_LOGI(TAG, "Converted 16bits color to 18 bits color!");
ili9488_panel_t *ili9488 = __containerof(panel, ili9488_panel_t, base);
assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position");
esp_lcd_panel_io_handle_t io = ili9488->io;
x_start += ili9488->x_gap;
x_end += ili9488->x_gap;
y_start += ili9488->y_gap;
y_end += ili9488->y_gap;
//define an area of frame memory where MCU can access
//ILI9488_CMD_COLUMN_ADDRESS_SET 0X2A
esp_lcd_panel_io_tx_param(io, LCD_CMD_CASET, (uint8_t[]) {
(x_start >> 8) & 0xFF,
x_start & 0xFF,
((x_end - 1) >> 8) & 0xFF,
(x_end - 1) & 0xFF,
}, 4);
//ILI9488_CMD_PAGE_ADDRESS_SET 0x2B
esp_lcd_panel_io_tx_param(io, LCD_CMD_RASET , (uint8_t[]) {
(y_start >> 8) & 0xFF,
y_start & 0xFF,
((y_end - 1) >> 8) & 0xFF,
(y_end - 1) & 0xFF,
}, 4);
// transfer frame buffer
//ILI9488_CMD_MEMORY_WRITE 0x2C
//ili9488_send_color((void *) mybuf, size * 3);
//!ESP_LOGI(TAG, "Writing to memory....");
//size_t len = (x_end - x_start) * (y_end - y_start) * ili9488->bits_per_pixel / 8; This only supports 8 and 16bit SPI
esp_lcd_panel_io_tx_color(io, LCD_CMD_RAMWR, (void *) mybuf, len * 3); //need 3 X uint8_t for converted 18 bits.
heap_caps_free(mybuf);
return ESP_OK;
}