fix(driver_spi): support un-aligned dma transaction and psram transaction

This commit is contained in:
wanckl
2025-08-18 22:12:43 +08:00
parent 3924afbf28
commit 32895539f2
14 changed files with 202 additions and 164 deletions

View File

@@ -23,4 +23,13 @@ menu "Example Configuration"
in practice the driver chips work fine with a higher clock rate, and using that gives a better framerate.
Select this to try using the out-of-spec clock rate.
config LCD_BUFFER_IN_PSRAM
bool
prompt "Malloc LCD buffer from PSRAM, it can save internal RAM"
depends on SPIRAM && SOC_PSRAM_DMA_CAPABLE
default "y"
help
Driver is now support using PSRAM memory as LCD buffer directly
without additional internal copy, using it is able to save internal
memory space, and without CPU cost.
endmenu

View File

@@ -19,6 +19,10 @@ uint16_t *pixels;
//Grab a rgb16 pixel from the esp32_tiles image
static inline uint16_t get_bgnd_pixel(int x, int y)
{
// Clamp coordinates to valid image bounds
x = (x < 0) ? 0 : (x >= IMAGE_W) ? IMAGE_W - 1 : x;
y = (y < 0) ? 0 : (y >= IMAGE_H) ? IMAGE_H - 1 : y;
//Get color of the pixel on x,y coords
return (uint16_t) * (pixels + (y * IMAGE_W) + x);
}
@@ -26,7 +30,7 @@ static inline uint16_t get_bgnd_pixel(int x, int y)
//This variable is used to detect the next frame.
static int prev_frame = -1;
//Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then re-use
//Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then reuse
//these as we go through all the pixels in the frame. This is much, much faster.
static int8_t xofs[320], yofs[240];
static int8_t xcomp[320], ycomp[240];

View File

@@ -343,7 +343,11 @@ static void send_lines(spi_device_handle_t spi, int ypos, uint16_t *linedata)
trans[4].tx_data[0] = 0x2C; //memory write
trans[5].tx_buffer = linedata; //finally send the line data
trans[5].length = 320 * 2 * 8 * PARALLEL_LINES; //Data length, in bits
#if CONFIG_LCD_BUFFER_IN_PSRAM
trans[5].flags = SPI_TRANS_DMA_USE_PSRAM; //using PSRAM
#else
trans[5].flags = 0; //undo SPI_TRANS_USE_TXDATA flag
#endif
//Queue all transactions.
for (x = 0; x < 6; x++) {
@@ -375,9 +379,17 @@ static void send_line_finish(spi_device_handle_t spi)
static void display_pretty_colors(spi_device_handle_t spi)
{
uint16_t *lines[2];
#if CONFIG_LCD_BUFFER_IN_PSRAM
uint32_t mem_cap = MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA;
printf("Get LCD buffer from PSRAM\n");
#else
uint32_t mem_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
printf("Get LCD buffer from internal\n");
#endif
//Allocate memory for the pixel buffers
for (int i = 0; i < 2; i++) {
lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), 0);
lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), mem_cap);
assert(lines[i] != NULL);
}
int frame = 0;