cancel
Showing results for 
Search instead for 
Did you mean: 

After enabling the SCB cache, screen flickering occurs during display refresh.

Lyu.1
Senior

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!

0 REPLIES 0