2025-09-18 8:42 PM
Hi,Master
MCU: STM32H743II
LVGL: V9.1
Problem Description:
I have an external SDRAM with a size of 32MB.The program is configured as follows:
void sys_cache_enable(void)
{
SCB_EnableICache();
SCB_EnableDCache();
SCB->CACR |= 1 << 2;
}
void mpu_memory_protection(void)
{
// RAM 512K
mpu_set_protection( 0x24000000,
MPU_REGION_SIZE_512KB,
MPU_REGION_NUMBER1,
MPU_REGION_FULL_ACCESS,
MPU_ACCESS_SHAREABLE,
MPU_ACCESS_CACHEABLE,
MPU_ACCESS_NOT_BUFFERABLE);
// EXSDRAM 32M
mpu_set_protection( 0XC0000000,
MPU_REGION_SIZE_32MB,
MPU_REGION_NUMBER2,
MPU_REGION_FULL_ACCESS,
MPU_ACCESS_SHAREABLE,
MPU_ACCESS_CACHEABLE,
MPU_ACCESS_NOT_BUFFERABLE);
}
The LVGL related frame buffers are stored in the external SDRAM as shown below.
static color_t render_buff1[1024 * 600];
static color_t render_buff2[1024 * 600];
static color_t frame_buff[1024 * 600];
// LVGL uses double buffering for rendering.
lv_display_set_buffers(disp, render_buff1, render_buff2,
sizeof(render_buff1),
LV_DISPLAY_RENDER_MODE_PARTIAL);
The process is as follows:
render dma2d ltdc
lvgl-------->double buff---------->frame_buff---------->lcd
// render: Switch between double buffers for rendering.
// dma2d: DMA2D is executed in the LVGL disp_flush callback. The code snippet is as follows:
SCB_CleanDCache_by_Addr((uint32_t*)disp->buf_1->data, 1024 * 600 * sizeof(color_t));
SCB_CleanDCache_by_Addr((uint32_t*)disp->buf_2->data, 1024 * 600 * sizeof(color_t));
__HAL_RCC_DMA2D_CLK_ENABLE(); /* Enable DMA2D clock */
DMA2D->CR &= ~(DMA2D_CR_START); /* Stop DMA2D first */
DMA2D->CR = DMA2D_M2M; /* Memory-to-memory mode */
DMA2D->FGPFCCR = LTDC_PIXFORMAT; /* Set color format */
DMA2D->FGOR = 0; /* Foreground layer line offset is 0 */
DMA2D->OOR = offline; /* Set line offset */
DMA2D->FGMAR = (uint32_t)color; /* Source address */
DMA2D->OMAR = addr; /* Output memory address */
DMA2D->NLR = (pey - psy + 1) | ((pex - psx + 1) << 16); /* Set the number of lines register */
DMA2D->CR |= DMA2D_CR_START; /* Start DMA2D */
In LVGL's flush_wait_cb, wait for the DMA transfer to complete.
int to = 100000;
while(to-- > 0) {
if ((DMA2D->ISR & (DMA2D_FLAG_TC))) break;
delay_us(1);
}
DMA2D->IFCR |= DMA2D_FLAG_TC;
SCB_CleanDCache_by_Addr((uint32_t*)frame_buff, 1024 * 600 * sizeof(color_t));
The flickering issue described above occurs when these functions are enabled. When I comment out sys_cache_enable(), mpu_memory_protection(), and SCB_CleanDCache_by_Addr(), the problem disappears.
I don't know what is causing this issue. I need help. Thank you very much!