upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-18 18:47:54 +0530
committerYour Name <you@example.com>2026-05-18 18:47:54 +0530
commita02a0dbbf4e945ad00433e3fc9fd2b40550d3e82 (patch)
treed36e349ac6030dd70548e7b91b4c54cc513e844a /components
parent067a5700e26518d9a3f8bd92966c8957d17f0817 (diff)
Fix display colors with internal DMA byte-swap buffer
- Allocate 4KB internal DMA buffer (MALLOC_CAP_DMA) for pixel byte-swap - Byte-swap from PSRAM framebuffer into DMA buffer in 2048-pixel chunks - Matches ArduinoGFX approach: separate DMA buffer avoids PSRAM cache issues - Restore render-on-change logic (only redraw on state/QR mode change) - Use saturated colors: cyan 0x07FF for title, yellow 0xFFE0 for subtitle - Remove debug flush log message
Diffstat (limited to 'components')
-rw-r--r--components/axs15231b/axs15231b.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/components/axs15231b/axs15231b.c b/components/axs15231b/axs15231b.c
index d64c9bc..49122a1 100644
--- a/components/axs15231b/axs15231b.c
+++ b/components/axs15231b/axs15231b.c
@@ -37,6 +37,8 @@ static spi_device_handle_t s_spi = NULL;
37static uint16_t *s_fb = NULL; 37static uint16_t *s_fb = NULL;
38static int s_width = AXS15231B_WIDTH; 38static int s_width = AXS15231B_WIDTH;
39static int s_height = AXS15231B_HEIGHT; 39static int s_height = AXS15231B_HEIGHT;
40static uint8_t *s_swap_buf = NULL;
41#define SWAP_BUF_PIXELS 2048
40 42
41typedef struct { 43typedef struct {
42 uint8_t cmd; 44 uint8_t cmd;
@@ -248,6 +250,13 @@ esp_err_t axs15231b_init(void) {
248 memset(s_fb, 0, fb_size); 250 memset(s_fb, 0, fb_size);
249 ESP_LOGI(TAG, "Framebuffer allocated: %zu bytes in PSRAM", fb_size); 251 ESP_LOGI(TAG, "Framebuffer allocated: %zu bytes in PSRAM", fb_size);
250 252
253 s_swap_buf = heap_caps_aligned_alloc(16, SWAP_BUF_PIXELS * 2, MALLOC_CAP_DMA);
254 if (!s_swap_buf) {
255 ESP_LOGE(TAG, "Failed to allocate DMA swap buffer (%d bytes)", SWAP_BUF_PIXELS * 2);
256 return ESP_ERR_NO_MEM;
257 }
258 ESP_LOGI(TAG, "DMA swap buffer: %d bytes in internal RAM", SWAP_BUF_PIXELS * 2);
259
251 gpio_config_t bl_cfg = { 260 gpio_config_t bl_cfg = {
252 .pin_bit_mask = (1ULL << AXS15231B_PIN_BL), 261 .pin_bit_mask = (1ULL << AXS15231B_PIN_BL),
253 .mode = GPIO_MODE_OUTPUT, 262 .mode = GPIO_MODE_OUTPUT,
@@ -303,23 +312,26 @@ void axs15231b_fill_rect(int x, int y, int w, int h, uint16_t color) {
303} 312}
304 313
305void axs15231b_flush(void) { 314void axs15231b_flush(void) {
306 if (!s_spi || !s_fb) return; 315 if (!s_spi || !s_fb || !s_swap_buf) return;
307
308 ESP_LOGI(TAG, "Flush %dx%d", s_width, s_height);
309 316
310 qspi_write_cmd_d16d16(CASET, 0, s_width - 1); 317 qspi_write_cmd_d16d16(CASET, 0, s_width - 1);
311 qspi_write_cmd_d16d16(RASET, 0, s_height - 1); 318 qspi_write_cmd_d16d16(RASET, 0, s_height - 1);
312 319
313 int total_bytes = s_width * s_height * 2; 320 int total_pixels = s_width * s_height;
314 int chunk_size = 32768; 321 int pixel_offset = 0;
315 int offset = 0;
316 uint8_t *fb_bytes = (uint8_t *)s_fb;
317 bool first = true; 322 bool first = true;
318 323
319 cs_low(); 324 cs_low();
320 while (offset < total_bytes) { 325 while (pixel_offset < total_pixels) {
321 int remaining = total_bytes - offset; 326 int remaining = total_pixels - pixel_offset;
322 int this_chunk = remaining < chunk_size ? remaining : chunk_size; 327 int chunk_pixels = remaining < SWAP_BUF_PIXELS ? remaining : SWAP_BUF_PIXELS;
328 int chunk_bytes = chunk_pixels * 2;
329
330 uint8_t *src = (uint8_t *)(s_fb + pixel_offset);
331 for (int i = 0; i < chunk_bytes; i += 2) {
332 s_swap_buf[i] = src[i + 1];
333 s_swap_buf[i + 1] = src[i];
334 }
323 335
324 spi_transaction_ext_t t = {0}; 336 spi_transaction_ext_t t = {0};
325 if (first) { 337 if (first) {
@@ -331,10 +343,10 @@ void axs15231b_flush(void) {
331 t.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD | 343 t.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
332 SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY; 344 SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
333 } 345 }
334 t.base.tx_buffer = fb_bytes + offset; 346 t.base.tx_buffer = s_swap_buf;
335 t.base.length = this_chunk * 8; 347 t.base.length = chunk_pixels * 16;
336 spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); 348 spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t);
337 offset += this_chunk; 349 pixel_offset += chunk_pixels;
338 } 350 }
339 cs_high(); 351 cs_high();
340} 352}