mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_irda.c
- Revision:
- 167:e84263d55307
- Parent:
- 149:156823d33999
--- a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_irda.c Thu Jun 08 15:02:37 2017 +0100 +++ b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_irda.c Wed Jun 21 17:46:44 2017 +0100 @@ -2,8 +2,8 @@ ****************************************************************************** * @file stm32f2xx_hal_irda.c * @author MCD Application Team - * @version V1.1.3 - * @date 29-June-2016 + * @version V1.2.1 + * @date 14-April-2017 * @brief IRDA HAL module driver. * This file provides firmware functions to manage the following * functionalities of the IrDA SIR ENDEC block (IrDA): @@ -90,14 +90,15 @@ (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt - + + [..] (@) You can refer to the IRDA HAL driver header file for more useful macros @endverbatim ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> + * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -162,6 +163,10 @@ static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); static void IRDA_DMAError(DMA_HandleTypeDef *hdma); static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart,uint32_t Timeout); static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda); static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda); @@ -404,7 +409,7 @@ /* Check that a Tx process is not already ongoing */ if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -420,7 +425,7 @@ hirda->TxXferSize = Size; hirda->TxXferCount = Size; - while(hirda->TxXferCount > 0U) + while(hirda->TxXferCount > 0) { hirda->TxXferCount--; if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) @@ -430,14 +435,14 @@ return HAL_TIMEOUT; } tmp = (uint16_t*) pData; - hirda->Instance->DR = (*tmp & (uint16_t)0x01FFU); + hirda->Instance->DR = (*tmp & (uint16_t)0x01FF); if(hirda->Init.Parity == IRDA_PARITY_NONE) { - pData +=2U; + pData +=2; } else { - pData +=1U; + pData +=1; } } else @@ -446,7 +451,7 @@ { return HAL_TIMEOUT; } - hirda->Instance->DR = (*pData++ & (uint8_t)0xFFU); + hirda->Instance->DR = (*pData++ & (uint8_t)0xFF); } } @@ -486,7 +491,7 @@ /* Check that a Rx process is not already ongoing */ if(hirda->RxState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -503,7 +508,7 @@ hirda->RxXferSize = Size; hirda->RxXferCount = Size; /* Check the remain data to be received */ - while(hirda->RxXferCount > 0U) + while(hirda->RxXferCount > 0) { hirda->RxXferCount--; if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) @@ -515,13 +520,13 @@ tmp = (uint16_t*) pData ; if(hirda->Init.Parity == IRDA_PARITY_NONE) { - *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FFU); - pData +=2U; + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF); + pData +=2; } else { - *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FFU); - pData +=1U; + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF); + pData +=1; } } else @@ -532,11 +537,11 @@ } if(hirda->Init.Parity == IRDA_PARITY_NONE) { - *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FFU); + *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF); } else { - *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007FU); + *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F); } } } @@ -568,7 +573,7 @@ /* Check that a Tx process is not already ongoing */ if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -608,7 +613,7 @@ /* Check that a Rx process is not already ongoing */ if(hirda->RxState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -624,13 +629,13 @@ /* Process Unlocked */ __HAL_UNLOCK(hirda); - + /* Enable the IRDA Parity Error and Data Register not empty Interrupts */ SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE); /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); - + return HAL_OK; } else @@ -654,7 +659,7 @@ /* Check that a Tx process is not already ongoing */ if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -718,7 +723,7 @@ /* Check that a Rx process is not already ongoing */ if(hirda->RxState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } @@ -746,6 +751,9 @@ /* Enable the DMA Stream */ tmp = (uint32_t*)&pData; HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size); + + /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */ + __HAL_IRDA_CLEAR_OREFLAG(hirda); /* Process Unlocked */ __HAL_UNLOCK(hirda); @@ -886,6 +894,408 @@ } /** + * @brief Abort ongoing transfers (blocking mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmatx); + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmarx); + } + } + + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0x00U; + hirda->RxXferCount = 0x00U; + + /* Reset ErrorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Restore hirda->RxState and hirda->gState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + hirda->gState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the IRDA DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmatx); + } + } + + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0x00U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmarx); + } + } + + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0x00U; + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda) +{ + uint32_t AbortCplt = 1U; + + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if(hirda->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback; + } + else + { + hirda->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if(hirda->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback; + } + else + { + hirda->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the IRDA DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at IRDA level */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmatx != NULL) + { + /* IRDA Tx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + hirda->hdmatx->XferAbortCallback = NULL; + } + else + { + AbortCplt = 0x00U; + } + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmarx != NULL) + { + /* IRDA Rx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + hirda->hdmarx->XferAbortCallback = NULL; + AbortCplt = 0x01U; + } + else + { + AbortCplt = 0x00U; + } + } + } + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if(AbortCplt == 0x01U) + { + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0x00U; + hirda->RxXferCount = 0x00U; + + /* Reset ErrorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the IRDA DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */ + hirda->hdmatx->XferAbortCallback(hirda->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0x00U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); + } + } + else + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0x00U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param hirda IRDA handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable PPP Interrupts + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ + hirda->hdmarx->XferAbortCallback(hirda->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0x00U; + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); + } + } + else + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0x00U; + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); + } + + return HAL_OK; +} + +/** * @brief This function handles IRDA interrupt request. * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. @@ -1050,10 +1460,128 @@ static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hirda->RxXferCount = 0x00; + hirda->TxXferCount = 0x00; + + HAL_IRDA_ErrorCallback(hirda); +} + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hirda->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hirda->hdmarx != NULL) + { + if(hirda->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0x00U; hirda->RxXferCount = 0x00U; + + /* Reset ErrorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +} + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hirda->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hirda->hdmatx != NULL) + { + if(hirda->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0x00U; + hirda->RxXferCount = 0x00U; + + /* Reset ErrorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +} + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hirda->TxXferCount = 0x00U; - HAL_IRDA_ErrorCallback(hirda); + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); +} + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hirda->RxXferCount = 0x00U; + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); } /** @@ -1132,6 +1660,51 @@ } /** + * @brief IRDA Abort Complete callback. + * @param hirda IRDA handle. + * @retval None + */ +__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Transmit Complete callback. + * @param hirda IRDA handle. + * @retval None + */ +__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort ReceiveComplete callback. + * @param hirda IRDA handle. + * @retval None + */ +__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file. + */ +} + +/** * @} */ @@ -1193,7 +1766,7 @@ /* DMA Normal mode */ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) { - hirda->TxXferCount = 0U; + hirda->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the IRDA CR3 register */ @@ -1233,7 +1806,7 @@ /* DMA Normal mode */ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) { - hirda->RxXferCount = 0U; + hirda->RxXferCount = 0; /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); @@ -1276,7 +1849,7 @@ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT); if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest) { - hirda->TxXferCount = 0U; + hirda->TxXferCount = 0; IRDA_EndTxTransfer(hirda); } @@ -1284,7 +1857,7 @@ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR); if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest) { - hirda->RxXferCount = 0U; + hirda->RxXferCount = 0; IRDA_EndRxTransfer(hirda); } @@ -1346,22 +1919,22 @@ if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { tmp = (uint16_t*) hirda->pTxBuffPtr; - hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FFU); + hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); if(hirda->Init.Parity == IRDA_PARITY_NONE) { - hirda->pTxBuffPtr += 2U; + hirda->pTxBuffPtr += 2; } else { - hirda->pTxBuffPtr += 1U; + hirda->pTxBuffPtr += 1; } } else { - hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FFU); + hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF); } - if(--hirda->TxXferCount == 0U) + if(--hirda->TxXferCount == 0) { /* Disable the IRDA Transmit Data Register Empty Interrupt */ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE); @@ -1420,28 +1993,28 @@ tmp = (uint16_t*) hirda->pRxBuffPtr; if(hirda->Init.Parity == IRDA_PARITY_NONE) { - *tmp = (uint16_t)(uhdata & (uint16_t)0x01FFU); - hirda->pRxBuffPtr += 2U; + *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF); + hirda->pRxBuffPtr += 2; } else { - *tmp = (uint16_t)(uhdata & (uint16_t)0x00FFU); - hirda->pRxBuffPtr += 1U; + *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF); + hirda->pRxBuffPtr += 1; } } else { if(hirda->Init.Parity == IRDA_PARITY_NONE) { - *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FFU); + *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF); } else { - *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007FU); + *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F); } } - if(--hirda->RxXferCount == 0U) + if(--hirda->RxXferCount == 0) { /* Disable the IRDA Data Register not empty Interrupt */ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);