diff options
Diffstat (limited to 'components')
| -rw-r--r-- | components/axs15231b/axs15231b.c | 38 |
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; | |||
| 37 | static uint16_t *s_fb = NULL; | 37 | static uint16_t *s_fb = NULL; |
| 38 | static int s_width = AXS15231B_WIDTH; | 38 | static int s_width = AXS15231B_WIDTH; |
| 39 | static int s_height = AXS15231B_HEIGHT; | 39 | static int s_height = AXS15231B_HEIGHT; |
| 40 | static uint8_t *s_swap_buf = NULL; | ||
| 41 | #define SWAP_BUF_PIXELS 2048 | ||
| 40 | 42 | ||
| 41 | typedef struct { | 43 | typedef 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 | ||
| 305 | void axs15231b_flush(void) { | 314 | void 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 | } |