硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2195|回复: 4
收起左侧

[STM32H7] STM32H7的DMA HAL库的开关锁操作__HAL_LOCK和__HAL_UNLOCK不在一个函数,强迫症看到好难受

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
发表于 2019-1-23 01:55:10 | 显示全部楼层 |阅读模式
比如查询方式启动,上锁了
QQ截图20190123015128.jpg

解锁在函数HAL_DMA_Abort或者HAL_DMA_PollForTransfer里面,看着很难受。
  1. /**
  2.   * @brief  Aborts the DMA Transfer in Interrupt mode.
  3.   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
  4.   *                 the configuration information for the specified DMA Stream.
  5.   * @retval HAL status
  6.   */
  7. HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
  8. {
  9.   /* Check the DMA peripheral handle */
  10.   if(hdma == NULL)
  11.   {
  12.     return HAL_ERROR;
  13.   }

  14.   if(hdma->State != HAL_DMA_STATE_BUSY)
  15.   {
  16.     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
  17.     return HAL_ERROR;
  18.   }
  19.   else
  20.   {
  21.     if(IS_D2_DMA_INSTANCE(hdma) != RESET) /* D2 Domain DMA : DMA1 or DMA2*/
  22.     {
  23.       /* Set Abort State  */
  24.       hdma->State = HAL_DMA_STATE_ABORT;

  25.       /* Disable the stream */
  26.       __HAL_DMA_DISABLE(hdma);
  27.     }
  28.     else /* D3 Domain BDMA */
  29.     {
  30.       /* Disable DMA All Interrupts  */
  31.       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);

  32.       /* Disable the channel */
  33.       __HAL_DMA_DISABLE(hdma);

  34.       /* disable the DMAMUX sync overrun IT*/
  35.       hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;

  36.       /* Clear all flags */
  37.       BDMA->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex));

  38.       /* Clear the DMAMUX synchro overrun flag */
  39.       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;

  40.       if(hdma->DMAmuxRequestGen != 0U)
  41.       {
  42.         /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
  43.         /* disable the request gen overrun IT*/
  44.         hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;

  45.         /* Clear the DMAMUX request generator overrun flag */
  46.         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
  47.       }

  48.       /* Process Unlocked */
  49.       __HAL_UNLOCK(hdma);

  50.       /* Change the DMA state */
  51.       hdma->State = HAL_DMA_STATE_READY;

  52.       /* Call User Abort callback */
  53.       if(hdma->XferAbortCallback != NULL)
  54.       {
  55.         hdma->XferAbortCallback(hdma);
  56.       }
  57.     }
  58.   }

  59.   return HAL_OK;
  60. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
 楼主| 发表于 2019-1-23 01:56:14 | 显示全部楼层
DMA中断方式:
QQ截图20190123015555.jpg

解锁在函数HAL_DMA_IRQHandler里面,或者调用DMA终止函数也可以的
  1. /**
  2.   * @brief  Handles DMA interrupt request.
  3.   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  4.   *               the configuration information for the specified DMA Stream.
  5.   * @retval None
  6.   */
  7. void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
  8. {
  9.   uint32_t tmpisr = 0U;
  10.   __IO uint32_t *ccr_reg = NULL;
  11.   __IO uint32_t count = 0U;
  12.   uint32_t timeout = SystemCoreClock / 9600U;

  13.   /* calculate DMA base and stream number */
  14.   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;

  15.   tmpisr = regs->ISR;

  16.   if(IS_D2_DMA_INSTANCE(hdma) != RESET)  /*D2 domain DMA : DMA1 or DMA2*/
  17.   {
  18.     /* Transfer Error Interrupt management ***************************************/
  19.     if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
  20.     {
  21.       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
  22.       {
  23.         /* Disable the transfer error interrupt */
  24.         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TE);

  25.         /* Clear the transfer error flag */
  26.         regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;

  27.         /* Update error code */
  28.         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
  29.       }
  30.     }
  31.     /* FIFO Error Interrupt management ******************************************/
  32.     if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
  33.     {
  34.       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
  35.       {
  36.         /* Clear the FIFO error flag */
  37.         regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;

  38.         /* Update error code */
  39.         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
  40.       }
  41.     }
  42.     /* Direct Mode Error Interrupt management ***********************************/
  43.     if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
  44.     {
  45.       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
  46.       {
  47.         /* Clear the direct mode error flag */
  48.         regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;

  49.         /* Update error code */
  50.         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
  51.       }
  52.     }
  53.     /* Half Transfer Complete Interrupt management ******************************/
  54.     if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
  55.     {
  56.       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
  57.       {
  58.         /* Clear the half transfer complete flag */
  59.         regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;

  60.         /* Multi_Buffering mode enabled */
  61.         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
  62.         {
  63.           /* Current memory buffer used is Memory 0 */
  64.           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == RESET)
  65.           {
  66.             if(hdma->XferHalfCpltCallback != NULL)
  67.             {
  68.               /* Half transfer callback */
  69.               hdma->XferHalfCpltCallback(hdma);
  70.             }
  71.           }
  72.           /* Current memory buffer used is Memory 1 */
  73.           else
  74.           {
  75.             if(hdma->XferM1HalfCpltCallback != NULL)
  76.             {
  77.               /* Half transfer callback */
  78.               hdma->XferM1HalfCpltCallback(hdma);
  79.             }
  80.           }
  81.         }
  82.         else
  83.         {
  84.           /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
  85.           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == RESET)
  86.           {
  87.             /* Disable the half transfer interrupt */
  88.             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
  89.           }

  90.           if(hdma->XferHalfCpltCallback != NULL)
  91.           {
  92.             /* Half transfer callback */
  93.             hdma->XferHalfCpltCallback(hdma);
  94.           }
  95.         }
  96.       }
  97.     }
  98.     /* Transfer Complete Interrupt management ***********************************/
  99.     if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
  100.     {
  101.       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
  102.       {
  103.         /* Clear the transfer complete flag */
  104.         regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;

  105.         if(HAL_DMA_STATE_ABORT == hdma->State)
  106.         {
  107.           /* Disable all the transfer interrupts */
  108.           ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
  109.           ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);

  110.           if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
  111.           {
  112.             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
  113.           }

  114.           /* Clear all interrupt flags at correct offset within the register */
  115.           regs->IFCR = 0x3FU << hdma->StreamIndex;

  116.           /* Process Unlocked */
  117.           __HAL_UNLOCK(hdma);

  118.           /* Change the DMA state */
  119.           hdma->State = HAL_DMA_STATE_READY;

  120.           if(hdma->XferAbortCallback != NULL)
  121.           {
  122.             hdma->XferAbortCallback(hdma);
  123.           }
  124.           return;
  125.         }

  126.         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
  127.         {
  128.           /* Current memory buffer used is Memory 0 */
  129.           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == RESET)
  130.           {
  131.             if(hdma->XferM1CpltCallback != NULL)
  132.             {
  133.               /* Transfer complete Callback for memory1 */
  134.               hdma->XferM1CpltCallback(hdma);
  135.             }
  136.           }
  137.           /* Current memory buffer used is Memory 1 */
  138.           else
  139.           {
  140.             if(hdma->XferCpltCallback != NULL)
  141.             {
  142.               /* Transfer complete Callback for memory0 */
  143.               hdma->XferCpltCallback(hdma);
  144.             }
  145.           }
  146.         }
  147.         /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
  148.         else
  149.         {
  150.           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == RESET)
  151.           {
  152.             /* Disable the transfer complete interrupt */
  153.             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC);

  154.             /* Process Unlocked */
  155.             __HAL_UNLOCK(hdma);

  156.             /* Change the DMA state */
  157.             hdma->State = HAL_DMA_STATE_READY;
  158.           }

  159.           if(hdma->XferCpltCallback != NULL)
  160.           {
  161.             /* Transfer complete callback */
  162.             hdma->XferCpltCallback(hdma);
  163.           }
  164.         }
  165.       }
  166.     }

  167.     /* manage error case */
  168.     if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
  169.     {
  170.       if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
  171.       {
  172.         hdma->State = HAL_DMA_STATE_ABORT;

  173.         /* Disable the stream */
  174.         __HAL_DMA_DISABLE(hdma);

  175.         do
  176.         {
  177.           if (++count > timeout)
  178.           {
  179.             break;
  180.           }
  181.         }
  182.         while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != RESET);

  183.         /* Process Unlocked */
  184.         __HAL_UNLOCK(hdma);

  185.         if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != RESET)
  186.         {
  187.           /* Change the DMA state to error if DMA disable fails */
  188.           hdma->State = HAL_DMA_STATE_ERROR;
  189.         }
  190.         else
  191.         {
  192.           /* Change the DMA state to Ready if DMA disable success */
  193.           hdma->State = HAL_DMA_STATE_READY;
  194.         }
  195.       }

  196.       if(hdma->XferErrorCallback != NULL)
  197.       {
  198.         /* Transfer error callback */
  199.         hdma->XferErrorCallback(hdma);
  200.       }
  201.     }
  202.   }
  203.   else if(IS_D3_DMA_INSTANCE(hdma) != RESET)  /*D3 domain BDMA */
  204.   {
  205.     ccr_reg = &(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR);

  206.     /* Half Transfer Complete Interrupt management ******************************/
  207.     if ((RESET != (BDMA->ISR & (BDMA_FLAG_HT0 << hdma->StreamIndex))) && (RESET != ((*ccr_reg) & BDMA_CCR_HTIE)))
  208.     {
  209.         /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
  210.         if(((*ccr_reg) & BDMA_CCR_CIRC) == 0U)
  211.         {
  212.           /* Disable the half transfer interrupt */
  213.           (*ccr_reg) &= ~BDMA_CCR_HTIE;
  214.         }
  215.         /* Clear the half transfer complete flag */
  216.         BDMA->IFCR  |= (BDMA_ISR_HTIF0 << hdma->StreamIndex);

  217.         /* DMA peripheral state is not updated in Half Transfer */
  218.         /* but in Transfer Complete case */

  219.        if(hdma->XferHalfCpltCallback != NULL)
  220.         {
  221.           /* Half transfer callback */
  222.           hdma->XferHalfCpltCallback(hdma);
  223.         }
  224.     }

  225.     /* Transfer Complete Interrupt management ***********************************/
  226.     else if ((RESET != (BDMA->ISR & (BDMA_FLAG_TC0 << hdma->StreamIndex))) && (RESET != ((*ccr_reg) & BDMA_CCR_TCIE)))
  227.     {
  228.       if(((*ccr_reg) & BDMA_CCR_CIRC) == 0U)
  229.       {
  230.         /* Disable TE & TC */
  231.         (*ccr_reg) &= ~(BDMA_CCR_TEIE | BDMA_CCR_TCIE);

  232.       /* Process Unlocked */
  233.       __HAL_UNLOCK(hdma);

  234.         /* Change the DMA state */
  235.         hdma->State = HAL_DMA_STATE_READY;
  236.       }
  237.       /* Clear the transfer complete flag */
  238.       BDMA->IFCR |= (BDMA_ISR_TCIF0 << hdma->StreamIndex);

  239.       if(hdma->XferCpltCallback != NULL)
  240.       {
  241.         /* Transfer complete callback */
  242.         hdma->XferCpltCallback(hdma);
  243.       }
  244.     }

  245.     /* Transfer Error Interrupt management **************************************/
  246.     else if (( RESET != (BDMA->ISR & (BDMA_FLAG_TE0 << hdma->StreamIndex))) && (RESET != ((*ccr_reg) & BDMA_CCR_TEIE)))
  247.     {
  248.       /* When a DMA transfer error occurs */
  249.       /* A hardware clear of its EN bits is performed */
  250.       /* Disable ALL DMA IT */
  251.       (*ccr_reg) &= ~(BDMA_CCR_TEIE | BDMA_CCR_TCIE | BDMA_CCR_HTIE);

  252.       /* Clear all flags */
  253.       BDMA->IFCR  |= (BDMA_ISR_GIF0 << hdma->StreamIndex);

  254.       /* Update error code */
  255.       hdma->ErrorCode = HAL_DMA_ERROR_TE;

  256.       /* Process Unlocked */
  257.       __HAL_UNLOCK(hdma);

  258.       /* Change the DMA state */
  259.       hdma->State = HAL_DMA_STATE_READY;

  260.       if (hdma->XferErrorCallback != NULL)
  261.       {
  262.         /* Transfer error callback */
  263.         hdma->XferErrorCallback(hdma);
  264.       }
  265.     }
  266.   }
  267. }
复制代码




回复

使用道具 举报

56

主题

905

回帖

1073

积分

至尊会员

积分
1073
发表于 2019-1-23 08:13:01 | 显示全部楼层
估计写这个库的是传统型的 没弄过rtos
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2019-1-24 09:26:04 | 显示全部楼层
是__HAL_UNLOCK();
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
 楼主| 发表于 2019-1-24 09:42:08 | 显示全部楼层

已改。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-22 03:45 , Processed in 0.165705 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表