/* * ST7701S + RGB panel, 480x480 round. * * Two things about the configuration here are deliberate and load-bearing: * * No bounce buffers. The bounce-buffer refill ISR reads PSRAM, which shares * the cache with flash on the S3, so any NVS write while the panel runs faults * with "Cache disabled but cached memory region accessed" (PRD 8.2). This * project writes settings to NVS at runtime, so instead of pausing the panel * around every write we simply do not use bounce buffers: the LCD DMA reads * the framebuffer out of PSRAM directly and never touches the cache. * * Two framebuffers. Writing into the framebuffer currently being scanned * races the LCD's reads, and the corruption persists because LVGL does not * know those pixels are wrong and never reinvalidates them (PRD 8.2). With * num_fbs=2 the panel driver swaps whole buffers instead. * * 480x480x2 bytes x 2 buffers is ~920KB of the 8MB PSRAM. */ #pragma once #include #include #include "esp_err.h" #include "esp_lcd_panel_ops.h" #define DISPLAY_H_RES 480 #define DISPLAY_V_RES 480 /* * Bring up the panel: expander power/reset sequencing, 3-wire SPI init, * RGB bus, backlight. * * Requires i2c_bus_init() and pcf8574_init() to have run. PRD 8.2 also wants * WiFi up before this point. */ esp_err_t display_init(void); /* The esp_lcd panel handle, for the LVGL port. */ esp_lcd_panel_handle_t display_panel(void); /* * Hand a completed frame (one of the two framebuffers) to the panel and block * until the swap has latched at vsync. * * esp_lcd_panel_draw_bitmap() only *queues* the framebuffer switch — the RGB * driver latches it at the next frame boundary. Returning before that point * lets the caller start rendering into the other buffer while it is still * being scanned out, which is exactly the persistent-corruption race PRD 8.2 * warns about. All frame presentation goes through here so that cannot happen. */ esp_err_t display_present_frame(void *fb); /* Both framebuffers, for LVGL to render into directly. */ esp_err_t display_get_framebuffers(void **fb0, void **fb1); /* Backlight, 0-100. */ void display_set_backlight(uint8_t percent); /* * Fill the screen with vertical colour bars, bypassing LVGL. * * This is the PRD phase-2 check: it proves the init sequence, the RGB bus and * the timings independently of anything LVGL does. */ void display_test_pattern(void);