2021-10-26 05:44 PM
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));
// ......
}
}
}
Solved! Go to Solution.
2021-11-03 02:47 PM
In case of SPI Master Tx, there's no data loss as SPI simply stops the clocks if it does not have data to transmit. So it's safe to ignore DMA's FEIF.
As I've said above, SPI's OVF is an Rx error, because you didn't pick the first received frame before the second (and others) arrived. But you don't care about SPI's Rx anyway so it's safe to ignore it too.
Cube/HAL is mainly an implementation for the clicky (CubeMX), and as any "library", it inevitably caters only for a fraction of possible usage cases, those deemed by authors as "typical", whatever that is. If you want anything beyond this "typical", Cube/HAL effectively gets into your way.
JW
2021-10-26 07:38 PM
Put the time-sensitive DMA request (SPI) at a higher priority than the memory to memory transfer.
2021-10-26 09:57 PM
As you said, it was a matter of priorities. When the priority of the SPI DMA request and the priority of the task executing SPI DMA were increased, no DMA error occurred. Thanks a lot.
2021-10-26 10:01 PM
Which STM32?
While swapping priorities will change things, you can also safely ignore FIFO error in DMA stream which has FIFO switched off. SPI OVF is an Rx error, because you don't read out the Rx data, that's again safe to ignore if you only Tx on that SPI.
JW
2021-10-26 10:17 PM
STM32F767
Is it okay to ignore FIFO errors and OVR errors when not in use?
When a SPI DMA error occurred, it was not confirmed that other error flags were set other than the FEIF and OVR flags. Is there any other reason for the DMA error to occur? The problem is that once you enter the SPI DMA error routine, the HAL Library will turn DMA off.
2021-11-03 02:47 PM
In case of SPI Master Tx, there's no data loss as SPI simply stops the clocks if it does not have data to transmit. So it's safe to ignore DMA's FEIF.
As I've said above, SPI's OVF is an Rx error, because you didn't pick the first received frame before the second (and others) arrived. But you don't care about SPI's Rx anyway so it's safe to ignore it too.
Cube/HAL is mainly an implementation for the clicky (CubeMX), and as any "library", it inevitably caters only for a fraction of possible usage cases, those deemed by authors as "typical", whatever that is. If you want anything beyond this "typical", Cube/HAL effectively gets into your way.
JW