ST意法半导体
直播中

李艳

7年用户 1435经验值
私信 关注
[问答]

使用SPI DMA向内存写入数据时发生DMA错误是何原因

当按下 LCD 上的按钮时,将显示相关屏幕并且必须保存数据(6000 字节)。当按下按钮时,屏幕显示没有任何问题,但是在使用SPI DMA向内存写入数据的过程中发生了DMA错误。
DMA应用于显示驱动,也应用于内存写入(SPI)。
如果我禁用用于显示的 DMA (禁用 DMA2_Stream0), SPI DMA 工作正常。
是不是DMA设置有问题?
[当两个 DMA 都启用时发生 SPI_DMA 错误]

[错误标志]
DMA2_HISR:FEIF4(FIFO 错误中断标志)设置
SPI5_SR:OVR(溢出错误标志)设置
[DMA 配置]

[使用 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*/
  •         }
  • }
【使用DMA2_Stream4向串行闪存W25Q128写入数据】
  • 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));
  •        // ......
  •        }
  •     }
  • }










回帖(1)

李凤津

2022-12-19 15:01:10

在 SPI Master Tx 的情况下,没有数据丢失,因为如果没有数据要传输,SPI 会简单地停止时钟。所以忽略 DMA 的 FEIF 是安全的。
正如我上面所说,SPI 的 OVF 是一个 Rx 错误,因为您没有在第二个(和其他)帧到达之前选择第一个接收到的帧。但是无论如何您都不关心 SPI 的 Rx,因此也可以安全地忽略它。
Cube/HAL 主要是 clicky (CubeMX) 的实现,作为任何“库”,它不可避免地只满足一小部分可能的用例,那些被作者认为是“典型”的,不管是什么。如果你想要超出这个“典型”的任何东西,Cube/HAL 会有效地妨碍你。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分