SPI DMA error is occurred when the other DMA(memory-to-memory) is used.
When the button on the LCD is pressed, the relevant screen is displayed and data (6000 bytes) must be saved. When the button is pressed, the screen is displayed without any problem, but a DMA error occurred in the process of writing data to the memory using SPI DMA.
DMA is applied to the display driver, and it is also applied to writing in memory (SPI).
SPI DMA works fine if I disable the DMA used for display (disable DMA2_Stream0).
Is there something wrong with the DMA settings?
[SPI_DMA error is occurred when both DMAs are enabled]
[error flag]
DMA2_HISR: FEIF4 (FIFO Error Interrupt Flag) set
SPI5_SR: OVR (Overrun Error Flag) set
[DMA Configurations]
[display driver using DMA2_Stream0]
static void tft_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
// lv_disp_flush_ready(drv);
// return;
SCB_CleanInvalidateDCache();
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : area->x2;
int32_t act_y2 = area->y2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : area->y2;
x1_flush = act_x1;
y1_flush = act_y1;
x2_flush = act_x2;
y2_flush = act_y2;
y_flush_act = act_y1;
buf_to_flush = color_p;
/*Use DMA instead of DMA2D to leave it free for GPU*/
HAL_StatusTypeDef err;
err = HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0,(uint32_t)buf_to_flush, (uint32_t)&lcd_fb[y_flush_act * TFT_HOR_RES + x1_flush],
(x2_flush - x1_flush + 1));
if(err != HAL_OK)
{
while(1); /*Halt on error*/
}
}[write data to serial flash memory W25Q128 using DMA2_Stream4]
void data_mgmt_task(void * argument)
{
uint32_t ulNotifiedValue = 0;
uint32_t ulNotifiedValue_bef = 0;
header.curr_param_addr = PARAM_OFFSET;
header.curr_menu_addr = MENU_OFFSET;
W25qxx_EraseBlock(PARAM_BLOCK_START);
W25qxx_EraseBlock(MENU_BLOCK_START);
while(true)
{
vTaskDelay(pdMS_TO_TICKS(10));
xTaskNotifyWait(0, 0, &ulNotifiedValue, pdMS_TO_TICKS(10));
if(ulNotifiedValue_bef != ulNotifiedValue)
{
ulNotifiedValue_bef = ulNotifiedValue;
W25qxx_WriteSector(HEADER_BUF, HEADER_SECTOR_START, HEADER_OFFSET, countof(HEADER_BUF));
W25qxx_WriteBlock(PARAM_BUF, PARAM_BLOCK_START, header.curr_param_addr, countof(PARAM_BUF));
W25qxx_WriteBlock(MENU_BUF, MENU_BLOCK_START, header.curr_menu_addr, countof(MENU_BUF));
// ......
}
}
}