/** * @brief DeInitializes the DMA peripheral * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Stream. * @retval HAL status */ static HAL_StatusTypeDef _HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) { /* Check the DMA peripheral state */ if(hdma == NULL) { return HAL_ERROR; } /* Check the DMA peripheral state */ if(hdma->State == HAL_DMA_STATE_BUSY) { return HAL_ERROR; } /* Disable the selected DMA Streamx */ __HAL_DMA_DISABLE(hdma); /* Reset DMA Streamx control register */ hdma->Instance->CR = 0; /* Reset DMA Streamx number of data to transfer register */ hdma->Instance->NDTR = 0; /* Reset DMA Streamx peripheral address register */ hdma->Instance->PAR = 0; /* Reset DMA Streamx memory 0 address register */ hdma->Instance->M0AR = 0; /* Reset DMA Streamx memory 1 address register */ hdma->Instance->M1AR = 0; /* Reset DMA Streamx FIFO control register */ hdma->Instance->FCR = (uint32_t)0x00000021; /* Clear all flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Initialize the DMA state */ hdma->State = HAL_DMA_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief DeInitializes the DMA peripheral * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) { /* Check the DMA handle allocation */ if(hdma == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); /* Check the DMA peripheral state */ if(hdma->State == HAL_DMA_STATE_BUSY) { return HAL_ERROR; } /* Disable the selected DMA Channelx */ __HAL_DMA_DISABLE(hdma); /* Reset DMA Channel control register */ hdma->Instance->CCR = 0; /* Reset DMA Channel Number of Data to Transfer register */ hdma->Instance->CNDTR = 0; /* Reset DMA Channel peripheral address register */ hdma->Instance->CPAR = 0; /* Reset DMA Channel memory address register */ hdma->Instance->CMAR = 0; /* Clear all flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Initialize the DMA state */ hdma->State = HAL_DMA_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Polling for transfer complete. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param CompleteLevel: Specifies the DMA level complete. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) { uint32_t temp; uint32_t tickstart = 0U; if(HAL_DMA_STATE_BUSY != hdma->State) { /* no transfer ongoing */ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Polling mode not supported in circular mode */ if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) { hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; return HAL_ERROR; } /* Get the level transfer complete flag */ if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Transfer Complete flag */ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); } else { /* Half Transfer Complete flag */ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); } /* Get tick */ tickstart = HAL_GetTick(); while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) { if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) { /* When a DMA transfer error occurs */ /* A hardware clear of its EN bits is performed */ /* Clear all flags */ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); /* Change the DMA state */ hdma->State= HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } } } if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers are complete) */ hdma->State = HAL_DMA_STATE_READY; } else { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); } /* Process unlocked */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Handles DMA interrupt request. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @retval None */ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) { /* Transfer Error Interrupt management ***************************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) { /* Disable the transfer error interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE); /* Clear the transfer error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); if (hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } } /* Half Transfer Complete Interrupt management ******************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) { /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the half transfer interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); } /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF; if(hdma->XferHalfCpltCallback != NULL) { /* Half transfer callback */ hdma->XferHalfCpltCallback(hdma); } } } /* Transfer Complete Interrupt management ***********************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) { if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the transfer complete interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC); } /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferCpltCallback != NULL) { /* Transfer complete callback */ hdma->XferCpltCallback(hdma); } } } }
/** * @brief Polling for transfer complete. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param CompleteLevel: Specifies the DMA level complete. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) { uint32_t temp; uint32_t tickstart = 0x00; /* Get the level transfer complete flag */ if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Transfer Complete flag */ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); } else { /* Half Transfer Complete flag */ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); } /* Get tick */ tickstart = HAL_GetTick(); while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) { if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) { /* Clear the transfer error flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); /* Change the DMA state */ hdma->State= HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_TIMEOUT; } } } if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers are complete) */ hdma->State = HAL_DMA_STATE_READY; } else { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers of half buffer are complete) */ hdma->State = HAL_DMA_STATE_READY_HALF; } /* Process unlocked */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Starts the multi_buffer DMA Transfer with interrupt enabled. * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Stream. * @param SrcAddress The source memory Buffer address * @param DstAddress The destination memory Buffer address * @param SecondMemAddress The second memory Buffer address in case of multi buffer Transfer * @param DataLength The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Memory-to-memory transfer not supported in double buffering mode */ if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY) { hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; return HAL_ERROR; } /* Check callback functions */ if ((NULL == hdma->XferCpltCallback) || (NULL == hdma->XferM1CpltCallback) || (NULL == hdma->XferErrorCallback)) { hdma->ErrorCode = HAL_DMA_ERROR_PARAM; return HAL_ERROR; } /* Process locked */ __HAL_LOCK(hdma); if(HAL_DMA_STATE_READY == hdma->State) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Enable the Double buffer mode */ hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM; /* Configure DMA Stream destination address */ hdma->Instance->M1AR = SecondMemAddress; /* Configure the source, destination address and the data length */ DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Clear all flags */ __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); /* Enable Common interrupts*/ hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; hdma->Instance->FCR |= DMA_IT_FE; if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) { hdma->Instance->CR |= DMA_IT_HT; } /* Enable the peripheral */ __HAL_DMA_ENABLE(hdma); } else { /* Process unlocked */ __HAL_UNLOCK(hdma); /* Return error status */ status = HAL_BUSY; } return status; }
/** * @brief Handles DMA interrupt request. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Stream. * @retval None */ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) { /* Transfer Error Interrupt management ***************************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) { /* Disable the transfer error interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE); /* Clear the transfer error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Update error code */ hdma->ErrorCode |= HAL_DMA_ERROR_TE; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } } /* FIFO Error Interrupt management ******************************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET) { /* Disable the FIFO Error interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE); /* Clear the FIFO error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); /* Update error code */ hdma->ErrorCode |= HAL_DMA_ERROR_FE; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } } /* Direct Mode Error Interrupt management ***********************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET) { /* Disable the direct mode Error interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME); /* Clear the direct mode error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); /* Update error code */ hdma->ErrorCode |= HAL_DMA_ERROR_DME; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } } /* Half Transfer Complete Interrupt management ******************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) { /* Multi_Buffering mode enabled */ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Current memory buffer used is Memory 0 */ if((hdma->Instance->CR & DMA_SxCR_CT) == 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; } /* Current memory buffer used is Memory 1 */ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM1; } } else { /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) { /* Disable the half transfer interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); } /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; } if(hdma->XferHalfCpltCallback != NULL) { /* Half transfer callback */ hdma->XferHalfCpltCallback(hdma); } } } /* Transfer Complete Interrupt management ***********************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) { if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* Current memory buffer used is Memory 1 */ if((hdma->Instance->CR & DMA_SxCR_CT) == 0) { if(hdma->XferM1CpltCallback != NULL) { /* Transfer complete Callback for memory1 */ hdma->XferM1CpltCallback(hdma); } } /* Current memory buffer used is Memory 0 */ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) { if(hdma->XferCpltCallback != NULL) { /* Transfer complete Callback for memory0 */ hdma->XferCpltCallback(hdma); } } } /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */ else { if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) { /* Disable the transfer complete interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC); } /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* Update error code */ hdma->ErrorCode |= HAL_DMA_ERROR_NONE; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY_MEM0; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferCpltCallback != NULL) { /* Transfer complete callback */ hdma->XferCpltCallback(hdma); } } } } }
/** * @brief Polling for transfer complete. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Stream. * @param CompleteLevel: Specifies the DMA level complete. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) { uint32_t temp, tmp, tmp1, tmp2; uint32_t timeout = 0x00; /* Get the level transfer complete flag */ if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Transfer Complete flag */ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); } else { /* Half Transfer Complete flag */ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); } /* Get timeout */ timeout = HAL_GetTick() + Timeout; while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) { tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET)) { /* Clear the transfer error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Clear the FIFO error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); /* Clear the DIrect Mode error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); /* Change the DMA state */ hdma->State= HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if(HAL_GetTick() >= timeout) { /* Update error code */ hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hdma); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_TIMEOUT; return HAL_TIMEOUT; } } } /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Multi_Buffering mode enabled */ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* Current memory buffer used is Memory 0 */ if((hdma->Instance->CR & DMA_SxCR_CT) == 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_MEM0; } /* Current memory buffer used is Memory 1 */ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_MEM1; } } else { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers are complete) */ hdma->State = HAL_DMA_STATE_READY_MEM0; } /* Process Unlocked */ __HAL_UNLOCK(hdma); } else { /* Multi_Buffering mode enabled */ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Current memory buffer used is Memory 0 */ if((hdma->Instance->CR & DMA_SxCR_CT) == 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; } /* Current memory buffer used is Memory 1 */ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM1; } } else { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; } } return HAL_OK; }
/** * @brief DeInitializes the DMA peripheral * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) { /* Check the DMA peripheral state */ if(hdma->State == HAL_DMA_STATE_BUSY) { return HAL_ERROR; } /* Disable the selected DMA Channelx */ __HAL_DMA_DISABLE(hdma); /* Reset DMA Channel control register */ hdma->Instance->CCR = 0; /* Reset DMA Channel Number of Data to Transfer register */ hdma->Instance->CNDTR = 0; /* Reset DMA Channel peripheral address register */ hdma->Instance->CPAR = 0; /* Reset DMA Channel memory address register */ hdma->Instance->CMAR = 0; /* Clear all flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Reset DMA channel selection register */ if (hdma->Instance == DMA1_Channel1) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S; } else if (hdma->Instance == DMA1_Channel2) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S; } else if (hdma->Instance == DMA1_Channel3) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S; } else if (hdma->Instance == DMA1_Channel4) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C4S; } else if (hdma->Instance == DMA1_Channel5) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C5S; } else if (hdma->Instance == DMA1_Channel6) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C6S; } else if (hdma->Instance == DMA1_Channel7) { /*Reset DMA request*/ DMA1_CSELR->CSELR &= ~DMA_CSELR_C7S; } /* Initialise the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Initialize the DMA state */ hdma->State = HAL_DMA_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Get the DMA Stream pending flags * @param handle_dma DMA handle * @retval The state of FLAG (SET or RESET) */ uint32_t Get_DMA_Flag_Status(DMA_HandleTypeDef *handle_dma) { return (__HAL_DMA_GET_FLAG(handle_dma, __HAL_DMA_GET_TE_FLAG_INDEX(handle_dma))); }