diff options
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c')
-rw-r--r-- | bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c | 1481 |
1 files changed, 1048 insertions, 433 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c index 0acc23d87e..0d0d2791ea 100644 --- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c +++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c @@ -10,6 +10,17 @@ * + Peripheral Control functions * * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** @verbatim =============================================================================== ##### How to use this driver ##### @@ -39,7 +50,8 @@ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. (+++) Configure the DMA Tx/Rx channel. (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. - (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA Tx/Rx channel. (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. @@ -75,8 +87,8 @@ allows the user to configure dynamically the driver callbacks. [..] - Use Function @ref HAL_UART_RegisterCallback() to register a user callback. - Function @ref HAL_UART_RegisterCallback() allows to register following callbacks: + Use Function HAL_UART_RegisterCallback() to register a user callback. + Function HAL_UART_RegisterCallback() allows to register following callbacks: (+) TxHalfCpltCallback : Tx Half Complete Callback. (+) TxCpltCallback : Tx Complete Callback. (+) RxHalfCpltCallback : Rx Half Complete Callback. @@ -94,9 +106,9 @@ and a pointer to the user callback function. [..] - Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default + Use function HAL_UART_UnRegisterCallback() to reset a callback to the default weak (surcharged) function. - @ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, + HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, and the Callback ID. This function allows to reset following callbacks: (+) TxHalfCpltCallback : Tx Half Complete Callback. @@ -114,13 +126,17 @@ (+) MspDeInitCallback : UART MspDeInit. [..] - By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET + For specific callback RxEventCallback, use dedicated registration/reset functions: + respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback(). + + [..] + By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET all callbacks are set to the corresponding weak (surcharged) functions: - examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback(). + examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback(). Exception done for MspInit and MspDeInit functions that are respectively - reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init() - and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). - If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit() + reset to the legacy weak (surcharged) functions in the HAL_UART_Init() + and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit() keep and use the user MspInit/MspDeInit callbacks (registered beforehand). [..] @@ -129,8 +145,8 @@ in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. In that case first register the MspInit/MspDeInit user callbacks - using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit() - or @ref HAL_UART_Init() function. + using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit() + or HAL_UART_Init() function. [..] When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or @@ -140,17 +156,6 @@ @endverbatim ****************************************************************************** - * @attention - * - * <h2><center>© Copyright (c) 2017 STMicroelectronics. - * All rights reserved.</center></h2> - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -174,25 +179,22 @@ * @ingroup RTEMSBSPsARMSTM32H7 * @{ */ -#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ - USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8| \ - USART_CR1_FIFOEN )) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ +#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ + USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ -#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT| \ - USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ +#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \ + USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ #define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */ #define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */ #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */ #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */ - /** * @} */ /* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /** @addtogroup UART_Private_Functions * @{ @@ -222,6 +224,16 @@ static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); * @} */ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup UART_Private_variables + * @{ + */ +const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; +/** + * @} + */ + +/* Exported Constants --------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @defgroup UART_Exported_Functions UART Exported Functions @@ -340,15 +352,17 @@ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) __HAL_UART_DISABLE(huart); - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { - return HAL_ERROR; + UART_AdvFeatureConfig(huart); } - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) { - UART_AdvFeatureConfig(huart); + return HAL_ERROR; } /* In asynchronous mode, the following bits must be kept cleared: @@ -405,15 +419,17 @@ HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) __HAL_UART_DISABLE(huart); - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { - return HAL_ERROR; + UART_AdvFeatureConfig(huart); } - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) { - UART_AdvFeatureConfig(huart); + return HAL_ERROR; } /* In half-duplex mode, the following bits must be kept cleared: @@ -491,15 +507,17 @@ HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLe __HAL_UART_DISABLE(huart); - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { - return HAL_ERROR; + UART_AdvFeatureConfig(huart); } - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) { - UART_AdvFeatureConfig(huart); + return HAL_ERROR; } /* In LIN mode, the following bits must be kept cleared: @@ -575,15 +593,17 @@ HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Add __HAL_UART_DISABLE(huart); - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { - return HAL_ERROR; + UART_AdvFeatureConfig(huart); } - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) { - UART_AdvFeatureConfig(huart); + return HAL_ERROR; } /* In multiprocessor mode, the following bits must be kept cleared: @@ -647,6 +667,8 @@ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_RESET; huart->RxState = HAL_UART_STATE_RESET; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + huart->RxEventType = HAL_UART_RXEVENT_TC; __HAL_UNLOCK(huart); @@ -689,6 +711,9 @@ __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) /** * @brief Register a User UART Callback * To be used instead of the weak predefined callback + * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), + * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to register + * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID * @param huart uart handle * @param CallbackID ID of the callback to be registered * This parameter can be one of the following values: @@ -720,8 +745,6 @@ HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_ return HAL_ERROR; } - __HAL_LOCK(huart); - if (huart->gState == HAL_UART_STATE_READY) { switch (CallbackID) @@ -811,14 +834,15 @@ HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_ status = HAL_ERROR; } - __HAL_UNLOCK(huart); - return status; } /** * @brief Unregister an UART Callback * UART callaback is redirected to the weak predefined callback + * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), + * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to un-register + * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID * @param huart uart handle * @param CallbackID ID of the callback to be unregistered * This parameter can be one of the following values: @@ -841,62 +865,62 @@ HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UAR { HAL_StatusTypeDef status = HAL_OK; - __HAL_LOCK(huart); - if (HAL_UART_STATE_READY == huart->gState) { switch (CallbackID) { case HAL_UART_TX_HALFCOMPLETE_CB_ID : - huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ break; case HAL_UART_TX_COMPLETE_CB_ID : - huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ + huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ break; case HAL_UART_RX_HALFCOMPLETE_CB_ID : - huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ break; case HAL_UART_RX_COMPLETE_CB_ID : - huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ + huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ break; case HAL_UART_ERROR_CB_ID : - huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ + huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ break; case HAL_UART_ABORT_COMPLETE_CB_ID : - huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ break; case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : - huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ + huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak + AbortTransmitCpltCallback */ break; case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : - huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ + huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak + AbortReceiveCpltCallback */ break; case HAL_UART_WAKEUP_CB_ID : - huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ + huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ break; case HAL_UART_RX_FIFO_FULL_CB_ID : - huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ break; case HAL_UART_TX_FIFO_EMPTY_CB_ID : - huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ break; case HAL_UART_MSPINIT_CB_ID : - huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ + huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ break; case HAL_UART_MSPDEINIT_CB_ID : - huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ + huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ break; default : @@ -932,10 +956,76 @@ HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UAR status = HAL_ERROR; } + return status; +} + +/** + * @brief Register a User UART Rx Event Callback + * To be used instead of the weak predefined callback + * @param huart Uart handle + * @param pCallback Pointer to the Rx Event Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(huart); + + if (huart->gState == HAL_UART_STATE_READY) + { + huart->RxEventCallback = pCallback; + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + /* Release Lock */ __HAL_UNLOCK(huart); return status; } + +/** + * @brief UnRegister the UART Rx Event Callback + * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback + * @param huart Uart handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(huart); + + if (huart->gState == HAL_UART_STATE_READY) + { + huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */ + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(huart); + return status; +} + #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ /** @@ -1002,16 +1092,23 @@ HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UAR (+) HAL_UART_AbortTransmitCpltCallback() (+) HAL_UART_AbortReceiveCpltCallback() + (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced + reception services: + (+) HAL_UARTEx_RxEventCallback() + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. Errors are handled as follows : (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is - to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . - Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, - and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side. + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error + in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user + to identify error type, and HAL_UART_ErrorCallback() user callback is executed. + Transfer is kept ongoing on UART side. If user wants to abort it, Abort services should be called by user. (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. - Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed. + Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() + user callback is executed. -@- In the Half duplex communication, it is forbidden to run the transmit and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. @@ -1035,10 +1132,10 @@ HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UAR * @param Timeout Timeout duration. * @retval HAL status */ -HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) +HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) { - uint8_t *pdata8bits; - uint16_t *pdata16bits; + const uint8_t *pdata8bits; + const uint16_t *pdata16bits; uint32_t tickstart; /* Check that a Tx process is not already ongoing */ @@ -1049,12 +1146,10 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u return HAL_ERROR; } - __HAL_LOCK(huart); - huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; - /* Init tickstart for timeout managment*/ + /* Init tickstart for timeout management */ tickstart = HAL_GetTick(); huart->TxXferSize = Size; @@ -1064,7 +1159,7 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { pdata8bits = NULL; - pdata16bits = (uint16_t *) pData; + pdata16bits = (const uint16_t *) pData; } else { @@ -1076,6 +1171,9 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u { if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) { + + huart->gState = HAL_UART_STATE_READY; + return HAL_TIMEOUT; } if (pdata8bits == NULL) @@ -1093,14 +1191,14 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) { + huart->gState = HAL_UART_STATE_READY; + return HAL_TIMEOUT; } /* At end of Tx process, restore huart->gState to Ready */ huart->gState = HAL_UART_STATE_READY; - __HAL_UNLOCK(huart); - return HAL_OK; } else @@ -1139,12 +1237,11 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui return HAL_ERROR; } - __HAL_LOCK(huart); - huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - /* Init tickstart for timeout managment*/ + /* Init tickstart for timeout management */ tickstart = HAL_GetTick(); huart->RxXferSize = Size; @@ -1171,6 +1268,8 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui { if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) { + huart->RxState = HAL_UART_STATE_READY; + return HAL_TIMEOUT; } if (pdata8bits == NULL) @@ -1189,8 +1288,6 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui /* At end of Rx process, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; - __HAL_UNLOCK(huart); - return HAL_OK; } else @@ -1209,7 +1306,7 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui * @param Size Amount of data elements (u8 or u16) to be sent. * @retval HAL status */ -HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) { /* Check that a Tx process is not already ongoing */ if (huart->gState == HAL_UART_STATE_READY) @@ -1219,8 +1316,6 @@ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData return HAL_ERROR; } - __HAL_LOCK(huart); - huart->pTxBuffPtr = pData; huart->TxXferSize = Size; huart->TxXferCount = Size; @@ -1242,10 +1337,8 @@ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData huart->TxISR = UART_TxISR_8BIT_FIFOEN; } - __HAL_UNLOCK(huart); - /* Enable the TX FIFO threshold interrupt */ - SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); } else { @@ -1259,10 +1352,8 @@ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData huart->TxISR = UART_TxISR_8BIT; } - __HAL_UNLOCK(huart); - /* Enable the Transmit Data Register Empty interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); } return HAL_OK; @@ -1293,60 +1384,20 @@ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, return HAL_ERROR; } - __HAL_LOCK(huart); - - huart->pRxBuffPtr = pData; - huart->RxXferSize = Size; - huart->RxXferCount = Size; - huart->RxISR = NULL; - - /* Computation of UART mask to apply to RDR register */ - UART_MASK_COMPUTATION(huart); - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + /* Set Reception type to Standard reception */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - /* Configure Rx interrupt processing*/ - if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) + if (!(IS_LPUART_INSTANCE(huart->Instance))) { - /* Set the Rx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) { - huart->RxISR = UART_RxISR_16BIT_FIFOEN; + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); } - else - { - huart->RxISR = UART_RxISR_8BIT_FIFOEN; - } - - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); - } - else - { - /* Set the Rx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->RxISR = UART_RxISR_16BIT; - } - else - { - huart->RxISR = UART_RxISR_8BIT; - } - - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); } - return HAL_OK; + return (UART_Start_Receive_IT(huart, pData, Size)); } else { @@ -1364,7 +1415,7 @@ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, * @param Size Amount of data elements (u8 or u16) to be sent. * @retval HAL status */ -HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) { /* Check that a Tx process is not already ongoing */ if (huart->gState == HAL_UART_STATE_READY) @@ -1374,8 +1425,6 @@ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pDat return HAL_ERROR; } - __HAL_LOCK(huart); - huart->pTxBuffPtr = pData; huart->TxXferSize = Size; huart->TxXferCount = Size; @@ -1403,8 +1452,6 @@ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pDat /* Set error code to DMA */ huart->ErrorCode = HAL_UART_ERROR_DMA; - __HAL_UNLOCK(huart); - /* Restore huart->gState to ready */ huart->gState = HAL_UART_STATE_READY; @@ -1414,11 +1461,9 @@ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pDat /* Clear the TC flag in the ICR register */ __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); - __HAL_UNLOCK(huart); - /* Enable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ - SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); return HAL_OK; } @@ -1450,55 +1495,20 @@ HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData return HAL_ERROR; } - __HAL_LOCK(huart); + /* Set Reception type to Standard reception */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - huart->pRxBuffPtr = pData; - huart->RxXferSize = Size; - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - - if (huart->hdmarx != NULL) + if (!(IS_LPUART_INSTANCE(huart->Instance))) { - /* Set the UART DMA transfer complete callback */ - huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; - - /* Set the UART DMA Half transfer complete callback */ - huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; - - /* Set the DMA error callback */ - huart->hdmarx->XferErrorCallback = UART_DMAError; - - /* Set the DMA abort callback */ - huart->hdmarx->XferAbortCallback = NULL; - - /* Enable the DMA channel */ - if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK) + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - __HAL_UNLOCK(huart); - - /* Restore huart->gState to ready */ - huart->gState = HAL_UART_STATE_READY; - - return HAL_ERROR; + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); } } - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - SET_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the UART CR3 register */ - SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - return HAL_OK; + return (UART_Start_Receive_DMA(huart, pData, Size)); } else { @@ -1516,27 +1526,23 @@ HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) const HAL_UART_StateTypeDef gstate = huart->gState; const HAL_UART_StateTypeDef rxstate = huart->RxState; - __HAL_LOCK(huart); - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && (gstate == HAL_UART_STATE_BUSY_TX)) { /* Disable the UART DMA Tx request */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); } if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && (rxstate == HAL_UART_STATE_BUSY_RX)) { /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Disable the UART DMA Rx request */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); } - __HAL_UNLOCK(huart); - return HAL_OK; } @@ -1547,28 +1553,27 @@ HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) */ HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) { - __HAL_LOCK(huart); - if (huart->gState == HAL_UART_STATE_BUSY_TX) { /* Enable the UART DMA Tx request */ - SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); } if (huart->RxState == HAL_UART_STATE_BUSY_RX) { /* Clear the Overrun flag before resuming the Rx transfer */ __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ - SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Enable the UART DMA Rx request */ - SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); } - __HAL_UNLOCK(huart); - return HAL_OK; } @@ -1593,7 +1598,7 @@ HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && (gstate == HAL_UART_STATE_BUSY_TX)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Abort the UART DMA Tx channel */ if (huart->hdmatx != NULL) @@ -1617,7 +1622,7 @@ HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && (rxstate == HAL_UART_STATE_BUSY_RX)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel */ if (huart->hdmarx != NULL) @@ -1655,13 +1660,21 @@ HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) { /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | + USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE); - /* Disable the UART DMA Tx request if enabled */ + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + + /* Abort the UART DMA Tx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ if (huart->hdmatx != NULL) @@ -1683,10 +1696,11 @@ HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) } } - /* Disable the UART DMA Rx request if enabled */ + /* Abort the UART DMA Rx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ if (huart->hdmarx != NULL) @@ -1727,6 +1741,7 @@ HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) /* Restore huart->gState and huart->RxState to Ready */ huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; huart->ErrorCode = HAL_UART_ERROR_NONE; @@ -1748,13 +1763,14 @@ HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) { /* Disable TCIE, TXEIE and TXFTIE interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); - /* Disable the UART DMA Tx request if enabled */ + /* Abort the UART DMA Tx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ if (huart->hdmatx != NULL) @@ -1806,13 +1822,20 @@ HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) { /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE); - /* Disable the UART DMA Rx request if enabled */ + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + + /* Abort the UART DMA Rx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ if (huart->hdmarx != NULL) @@ -1845,6 +1868,7 @@ HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) /* Restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; return HAL_OK; } @@ -1868,8 +1892,15 @@ HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) uint32_t abortcplt = 1U; /* Disable interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_TXEIE_TXFNFIE)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | + USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised before any call to DMA Abort functions */ @@ -1902,11 +1933,11 @@ HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) } } - /* Disable the UART DMA Tx request if enabled */ + /* Abort the UART DMA Tx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) { /* Disable DMA Tx at UART level */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ if (huart->hdmatx != NULL) @@ -1926,10 +1957,11 @@ HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) } } - /* Disable the UART DMA Rx request if enabled */ + /* Abort the UART DMA Rx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ if (huart->hdmarx != NULL) @@ -1979,6 +2011,7 @@ HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) /* Restore huart->gState and huart->RxState to Ready */ huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* As no DMA to be aborted, call directly user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -2010,13 +2043,14 @@ HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) { /* Disable interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); - /* Disable the UART DMA Tx request if enabled */ + /* Abort the UART DMA Tx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ if (huart->hdmatx != NULL) @@ -2100,13 +2134,20 @@ HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) { /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); - /* Disable the UART DMA Rx request if enabled */ + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + + /* Abort the UART DMA Rx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ if (huart->hdmarx != NULL) @@ -2138,6 +2179,7 @@ HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) /* Restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* As no DMA to be aborted, call directly user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -2162,6 +2204,7 @@ HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) /* Restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* As no DMA to be aborted, call directly user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -2282,10 +2325,11 @@ void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ UART_EndRxTransfer(huart); - /* Disable the UART DMA Rx request if enabled */ + /* Abort the UART DMA Rx channel if enabled */ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) { - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel */ if (huart->hdmarx != NULL) @@ -2344,6 +2388,103 @@ void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) } /* End if some error occurs */ + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + && ((isrflags & USART_ISR_IDLE) != 0U) + && ((cr1its & USART_ISR_IDLE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + + /* Check if DMA mode is enabled in UART */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* DMA mode enabled */ + /* Check received length : If all expected data are received, do nothing, + (DMA cplt callback will be called). + Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ + uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx); + if ((nb_remaining_rx_data > 0U) + && (nb_remaining_rx_data < huart->RxXferSize)) + { + /* Reception is not complete */ + huart->RxXferCount = nb_remaining_rx_data; + + /* In Normal mode, end DMA xfer and HAL UART Rx process*/ + if (huart->hdmarx->Init.Mode != DMA_CIRCULAR) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the UART CR3 register */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Last bytes received, so no need as the abort is immediate */ + (void)HAL_DMA_Abort(huart->hdmarx); + } + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + return; + } + else + { + /* DMA mode not enabled */ + /* Check received length : If all expected data are received, do nothing. + Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ + uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount; + if ((huart->RxXferCount > 0U) + && (nb_rx_data > 0U)) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxEventCallback(huart, nb_rx_data); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, nb_rx_data); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + return; + } + } + /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U)) { @@ -2529,6 +2670,24 @@ __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) } /** + * @brief Reception Event Callback (Rx event notification called after use of advanced reception service). + * @param huart UART handle + * @param Size Number of data available in application reception buffer (indicates a position in + * reception buffer until which, data are available) + * @retval None + */ +__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + UNUSED(Size); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UARTEx_RxEventCallback can be implemented in the user file. + */ +} + +/** * @} */ @@ -2664,7 +2823,7 @@ HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; /* Enable USART mute mode by setting the MME bit in the CR1 register */ - SET_BIT(huart->Instance->CR1, USART_CR1_MME); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME); huart->gState = HAL_UART_STATE_READY; @@ -2684,7 +2843,7 @@ HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; /* Disable USART mute mode by clearing the MME bit in the CR1 register */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); huart->gState = HAL_UART_STATE_READY; @@ -2713,10 +2872,10 @@ HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; /* Clear TE and RE bits */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ - SET_BIT(huart->Instance->CR1, USART_CR1_TE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE); huart->gState = HAL_UART_STATE_READY; @@ -2736,10 +2895,10 @@ HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; /* Clear TE and RE bits */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ - SET_BIT(huart->Instance->CR1, USART_CR1_RE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE); huart->gState = HAL_UART_STATE_READY; @@ -2800,7 +2959,7 @@ HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) * the configuration information for the specified UART. * @retval HAL state */ -HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) +HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart) { uint32_t temp1; uint32_t temp2; @@ -2816,7 +2975,7 @@ HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) * the configuration information for the specified UART. * @retval UART Error Code */ -uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) +uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart) { return huart->ErrorCode; } @@ -2853,6 +3012,7 @@ void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart) huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */ } #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ @@ -2867,9 +3027,9 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) uint32_t tmpreg; uint16_t brrtemp; UART_ClockSourceTypeDef clocksource; - uint32_t usartdiv = 0x00000000U; + uint32_t usartdiv; HAL_StatusTypeDef ret = HAL_OK; - uint32_t lpuart_ker_ck_pres = 0x00000000U; + uint32_t lpuart_ker_ck_pres; PLL2_ClocksTypeDef pll2_clocks; PLL3_ClocksTypeDef pll3_clocks; uint32_t pclk; @@ -2901,7 +3061,6 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) * set TE and RE bits according to huart->Init.Mode value * set OVER8 bit according to huart->Init.OverSampling value */ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ; - tmpreg |= (uint32_t)huart->FifoMode; MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg); /*-------------------------- USART CR2 Configuration -----------------------*/ @@ -2938,41 +3097,45 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) switch (clocksource) { case UART_CLOCKSOURCE_D3PCLK1: - lpuart_ker_ck_pres = (HAL_RCCEx_GetD3PCLK1Freq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = HAL_RCCEx_GetD3PCLK1Freq(); break; case UART_CLOCKSOURCE_PLL2: HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); - lpuart_ker_ck_pres = (pll2_clocks.PLL2_Q_Frequency / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = pll2_clocks.PLL2_Q_Frequency; break; case UART_CLOCKSOURCE_PLL3: HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); - lpuart_ker_ck_pres = (pll3_clocks.PLL3_Q_Frequency / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = pll3_clocks.PLL3_Q_Frequency; break; case UART_CLOCKSOURCE_HSI: if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) { - lpuart_ker_ck_pres = ((uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)) / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); } else { - lpuart_ker_ck_pres = ((uint32_t) HSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = (uint32_t) HSI_VALUE; } break; case UART_CLOCKSOURCE_CSI: - lpuart_ker_ck_pres = ((uint32_t)CSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = (uint32_t) CSI_VALUE; break; case UART_CLOCKSOURCE_LSE: - lpuart_ker_ck_pres = ((uint32_t)LSE_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler)); + pclk = (uint32_t) LSE_VALUE; break; default: + pclk = 0U; ret = HAL_ERROR; break; } - /* if proper clock source reported */ - if (lpuart_ker_ck_pres != 0U) + /* If proper clock source reported */ + if (pclk != 0U) { - /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ + /* Compute clock after Prescaler */ + lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]); + + /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) || (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate))) { @@ -2980,42 +3143,9 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) } else { - switch (clocksource) - { - case UART_CLOCKSOURCE_D3PCLK1: - pclk = HAL_RCCEx_GetD3PCLK1Freq(); - usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - break; - case UART_CLOCKSOURCE_PLL2: - HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); - usartdiv = (uint32_t)(UART_DIV_LPUART(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - break; - case UART_CLOCKSOURCE_PLL3: - HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); - usartdiv = (uint32_t)(UART_DIV_LPUART(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - break; - case UART_CLOCKSOURCE_HSI: - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) - { - usartdiv = (uint32_t)(UART_DIV_LPUART((uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler)); - } - else - { - usartdiv = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - } - break; - case UART_CLOCKSOURCE_CSI: - usartdiv = (uint32_t)(UART_DIV_LPUART(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - break; - case UART_CLOCKSOURCE_LSE: - usartdiv = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - break; - default: - ret = HAL_ERROR; - break; - } - - /* It is forbidden to write values lower than 0x300 in the LPUART_BRR register */ + /* Check computed UsartDiv value is in allocated range + (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */ + usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) { huart->Instance->BRR = usartdiv; @@ -3024,8 +3154,9 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) { ret = HAL_ERROR; } - } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */ - } /* if (lpuart_ker_ck_pres != 0) */ + } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || + (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */ + } /* if (pclk != 0) */ } /* Check UART Over Sampling to set Baud Rate Register */ else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) @@ -3034,51 +3165,54 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) { case UART_CLOCKSOURCE_D2PCLK1: pclk = HAL_RCC_GetPCLK1Freq(); - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); break; case UART_CLOCKSOURCE_D2PCLK2: pclk = HAL_RCC_GetPCLK2Freq(); - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); break; case UART_CLOCKSOURCE_PLL2: HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = pll2_clocks.PLL2_Q_Frequency; break; case UART_CLOCKSOURCE_PLL3: HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = pll3_clocks.PLL3_Q_Frequency; break; case UART_CLOCKSOURCE_HSI: if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) { - usartdiv = (uint16_t)(UART_DIV_SAMPLING8((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); } else { - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) HSI_VALUE; } break; case UART_CLOCKSOURCE_CSI: - usartdiv = (uint16_t)(UART_DIV_SAMPLING8(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) CSI_VALUE; break; case UART_CLOCKSOURCE_LSE: - usartdiv = (uint16_t)(UART_DIV_SAMPLING8((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) LSE_VALUE; break; default: + pclk = 0U; ret = HAL_ERROR; break; } /* USARTDIV must be greater than or equal to 0d16 */ - if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) + if (pclk != 0U) { - brrtemp = (uint16_t)(usartdiv & 0xFFF0U); - brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); - huart->Instance->BRR = brrtemp; - } - else - { - ret = HAL_ERROR; + usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) + { + brrtemp = (uint16_t)(usartdiv & 0xFFF0U); + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + huart->Instance->BRR = brrtemp; + } + else + { + ret = HAL_ERROR; + } } } else @@ -3087,49 +3221,52 @@ HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) { case UART_CLOCKSOURCE_D2PCLK1: pclk = HAL_RCC_GetPCLK1Freq(); - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); break; case UART_CLOCKSOURCE_D2PCLK2: pclk = HAL_RCC_GetPCLK2Freq(); - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); break; case UART_CLOCKSOURCE_PLL2: HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = pll2_clocks.PLL2_Q_Frequency; break; case UART_CLOCKSOURCE_PLL3: HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = pll3_clocks.PLL3_Q_Frequency; break; case UART_CLOCKSOURCE_HSI: if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) { - usartdiv = (uint16_t)(UART_DIV_SAMPLING16((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); } else { - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) HSI_VALUE; } break; case UART_CLOCKSOURCE_CSI: - usartdiv = (uint16_t)(UART_DIV_SAMPLING16(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) CSI_VALUE; break; case UART_CLOCKSOURCE_LSE: - usartdiv = (uint16_t)(UART_DIV_SAMPLING16((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + pclk = (uint32_t) LSE_VALUE; break; default: + pclk = 0U; ret = HAL_ERROR; break; } - /* USARTDIV must be greater than or equal to 0d16 */ - if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) - { - huart->Instance->BRR = usartdiv; - } - else + if (pclk != 0U) { - ret = HAL_ERROR; + /* USARTDIV must be greater than or equal to 0d16 */ + usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) + { + huart->Instance->BRR = (uint16_t)usartdiv; + } + else + { + ret = HAL_ERROR; + } } } @@ -3154,6 +3291,13 @@ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) /* Check whether the set of advanced features to configure is properly set */ assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); + /* if required, configure RX/TX pins swap */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) + { + assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); + } + /* if required, configure TX pin active level inversion */ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) { @@ -3175,13 +3319,6 @@ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); } - /* if required, configure RX/TX pins swap */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) - { - assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); - } - /* if required, configure RX overrun detection disabling */ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) { @@ -3230,7 +3367,7 @@ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) /* Initialize the UART ErrorCode */ huart->ErrorCode = HAL_UART_ERROR_NONE; - /* Init tickstart for timeout managment*/ + /* Init tickstart for timeout management */ tickstart = HAL_GetTick(); /* Check if the Transmitter is enabled */ @@ -3239,6 +3376,13 @@ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) /* Wait until TEACK flag is set */ if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) { + /* Disable TXE interrupt for the interrupt process */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE)); + + huart->gState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + /* Timeout occurred */ return HAL_TIMEOUT; } @@ -3250,6 +3394,15 @@ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) /* Wait until REACK flag is set */ if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) { + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) + interrupts for the interrupt process */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + huart->RxState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + /* Timeout occurred */ return HAL_TIMEOUT; } @@ -3258,6 +3411,8 @@ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) /* Initialize the UART State */ huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + huart->RxEventType = HAL_UART_RXEVENT_TC; __HAL_UNLOCK(huart); @@ -3265,10 +3420,11 @@ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) } /** - * @brief Handle UART Communication Timeout. + * @brief This function handles UART Communication Timeout. It waits + * until a flag is no longer in the specified status. * @param huart UART handle. * @param Flag Specifies the UART flag to check - * @param Status Flag status (SET or RESET) + * @param Status The actual Flag status (SET or RESET) * @param Tickstart Tick start value * @param Timeout Timeout duration * @retval HAL status @@ -3284,36 +3440,44 @@ HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_ { if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - - __HAL_UNLOCK(huart); return HAL_TIMEOUT; } if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) { + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET) + { + /* Clear Overrun Error flag*/ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts if ongoing */ + UART_EndRxTransfer(huart); + + huart->ErrorCode = HAL_UART_ERROR_ORE; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_ERROR; + } if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET) { /* Clear Receiver Timeout flag*/ __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); - - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE)); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts if ongoing */ + UART_EndRxTransfer(huart); + huart->ErrorCode = HAL_UART_ERROR_RTO; - + /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_TIMEOUT; } } @@ -3322,6 +3486,140 @@ HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_ return HAL_OK; } +/** + * @brief Start Receive operation in interrupt mode. + * @note This function could be called by all HAL UART API providing reception in Interrupt mode. + * @note When calling this function, parameters validity is considered as already checked, + * i.e. Rx State, buffer address, ... + * UART Handle is assumed as Locked. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + huart->RxXferCount = Size; + huart->RxISR = NULL; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Configure Rx interrupt processing */ + if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT_FIFOEN; + } + else + { + huart->RxISR = UART_RxISR_8BIT_FIFOEN; + } + + /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + } + else + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT; + } + else + { + huart->RxISR = UART_RxISR_8BIT; + } + + /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + else + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + return HAL_OK; +} + +/** + * @brief Start Receive operation in DMA mode. + * @note This function could be called by all HAL UART API providing reception in DMA mode. + * @note When calling this function, parameters validity is considered as already checked, + * i.e. Rx State, buffer address, ... + * UART Handle is assumed as Locked. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + if (huart->hdmarx != NULL) + { + /* Set the UART DMA transfer complete callback */ + huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmarx->XferErrorCallback = UART_DMAError; + + /* Set the DMA abort callback */ + huart->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + /* Restore huart->RxState to ready */ + huart->RxState = HAL_UART_STATE_READY; + + return HAL_ERROR; + } + } + + /* Enable the UART Parity Error Interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + return HAL_OK; +} + /** * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). @@ -3331,8 +3629,8 @@ HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_ static void UART_EndTxTransfer(UART_HandleTypeDef *huart) { /* Disable TXEIE, TCIE, TXFT interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE)); /* At end of Tx process, restore huart->gState to Ready */ huart->gState = HAL_UART_STATE_READY; @@ -3347,11 +3645,18 @@ static void UART_EndTxTransfer(UART_HandleTypeDef *huart) static void UART_EndRxTransfer(UART_HandleTypeDef *huart) { /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } /* At end of Rx process, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* Reset RxIsr function pointer */ huart->RxISR = NULL; @@ -3374,10 +3679,10 @@ static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) /* Disable the DMA transfer for transmit request by resetting the DMAT bit in the UART CR3 register */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Enable the UART Transmit Complete Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); } /* DMA Circular mode */ else @@ -3425,24 +3730,50 @@ static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) huart->RxXferCount = 0U; /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Disable the DMA transfer for the receiver request by resetting the DMAR bit in the UART CR3 register */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* At end of Rx process, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + + /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } } + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + /* Check current reception Mode : + If Reception till IDLE event has been selected : use Rx Event callback */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + else + { + /* In other cases : use Rx Complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); #else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } /** @@ -3454,13 +3785,33 @@ static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Half Transfer */ + huart->RxEventType = HAL_UART_RXEVENT_HT; + + /* Check current reception Mode : + If Reception till IDLE event has been selected : use Rx Event callback */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Half complete callback*/ - huart->RxHalfCpltCallback(huart); + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize / 2U); #else - /*Call legacy weak Rx Half complete callback*/ - HAL_UART_RxHalfCpltCallback(huart); + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + else + { + /* In other cases : use Rx Half Complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Half complete callback*/ + huart->RxHalfCpltCallback(huart); +#else + /*Call legacy weak Rx Half complete callback*/ + HAL_UART_RxHalfCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } /** @@ -3565,6 +3916,7 @@ static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) /* Restore huart->gState and huart->RxState to Ready */ huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* Call user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -3616,6 +3968,7 @@ static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) /* Restore huart->gState and huart->RxState to Ready */ huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* Call user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -3683,6 +4036,7 @@ static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) /* Restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; /* Call user Abort complete callback */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) @@ -3695,7 +4049,7 @@ static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) } /** - * @brief TX interrrupt handler for 7 or 8 bits data word length . + * @brief TX interrupt handler for 7 or 8 bits data word length . * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Transmit_IT(). * @param huart UART handle. @@ -3709,10 +4063,10 @@ static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) if (huart->TxXferCount == 0U) { /* Disable the UART Transmit Data Register Empty Interrupt */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); /* Enable the UART Transmit Complete Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); } else { @@ -3724,7 +4078,7 @@ static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) } /** - * @brief TX interrrupt handler for 9 bits data word length. + * @brief TX interrupt handler for 9 bits data word length. * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Transmit_IT(). * @param huart UART handle. @@ -3732,7 +4086,7 @@ static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) */ static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) { - uint16_t *tmp; + const uint16_t *tmp; /* Check that a Tx process is ongoing */ if (huart->gState == HAL_UART_STATE_BUSY_TX) @@ -3740,14 +4094,14 @@ static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) if (huart->TxXferCount == 0U) { /* Disable the UART Transmit Data Register Empty Interrupt */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); /* Enable the UART Transmit Complete Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); } else { - tmp = (uint16_t *) huart->pTxBuffPtr; + tmp = (const uint16_t *) huart->pTxBuffPtr; huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); huart->pTxBuffPtr += 2U; huart->TxXferCount--; @@ -3756,7 +4110,7 @@ static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) } /** - * @brief TX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. + * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Transmit_IT(). * @param huart UART handle. @@ -3774,10 +4128,10 @@ static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) if (huart->TxXferCount == 0U) { /* Disable the TX FIFO threshold interrupt */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); /* Enable the UART Transmit Complete Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); break; /* force exit loop */ } @@ -3796,7 +4150,7 @@ static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) } /** - * @brief TX interrrupt handler for 9 bits data word length and FIFO mode is enabled. + * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled. * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Transmit_IT(). * @param huart UART handle. @@ -3804,7 +4158,7 @@ static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) */ static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) { - uint16_t *tmp; + const uint16_t *tmp; uint16_t nb_tx_data; /* Check that a Tx process is ongoing */ @@ -3815,16 +4169,16 @@ static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) if (huart->TxXferCount == 0U) { /* Disable the TX FIFO threshold interrupt */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); /* Enable the UART Transmit Complete Interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); break; /* force exit loop */ } else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) { - tmp = (uint16_t *) huart->pTxBuffPtr; + tmp = (const uint16_t *) huart->pTxBuffPtr; huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); huart->pTxBuffPtr += 2U; huart->TxXferCount--; @@ -3846,7 +4200,7 @@ static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) static void UART_EndTransmit_IT(UART_HandleTypeDef *huart) { /* Disable the UART Transmit Complete Interrupt */ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); /* Tx process is ended, restore huart->gState to Ready */ huart->gState = HAL_UART_STATE_READY; @@ -3864,7 +4218,7 @@ static void UART_EndTransmit_IT(UART_HandleTypeDef *huart) } /** - * @brief RX interrrupt handler for 7 or 8 bits data word length . + * @brief RX interrupt handler for 7 or 8 bits data word length . * @param huart UART handle. * @retval None */ @@ -3884,10 +4238,10 @@ static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) if (huart->RxXferCount == 0U) { /* Disable the UART Parity Error Interrupt and RXNE interrupts */ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; @@ -3895,13 +4249,54 @@ static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) /* Clear RxISR function pointer */ huart->RxISR = NULL; + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); #else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } } else @@ -3912,7 +4307,7 @@ static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) } /** - * @brief RX interrrupt handler for 9 bits data word length . + * @brief RX interrupt handler for 9 bits data word length . * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Receive_IT() * @param huart UART handle. @@ -3936,10 +4331,10 @@ static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) if (huart->RxXferCount == 0U) { /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; @@ -3947,13 +4342,54 @@ static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) /* Clear RxISR function pointer */ huart->RxISR = NULL; + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); #else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } } else @@ -3964,7 +4400,7 @@ static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) } /** - * @brief RX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. + * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Receive_IT() * @param huart UART handle. @@ -3974,26 +4410,75 @@ static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) { uint16_t uhMask = huart->Mask; uint16_t uhdata; - uint16_t nb_rx_data; + uint16_t nb_rx_data; uint16_t rxdatacount; + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its = READ_REG(huart->Instance->CR3); /* Check that a Rx process is ongoing */ if (huart->RxState == HAL_UART_STATE_BUSY_RX) { - for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--) + nb_rx_data = huart->NbRxDataToProcess; + while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) { uhdata = (uint16_t) READ_REG(huart->Instance->RDR); *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); huart->pRxBuffPtr++; huart->RxXferCount--; + isrflags = READ_REG(huart->Instance->ISR); + + /* If some non blocking errors occurred */ + if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* Call UART Error Call back function if need be ----------------------------*/ + if (huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } if (huart->RxXferCount == 0U) { /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; @@ -4001,13 +4486,54 @@ static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) /* Clear RxISR function pointer */ huart->RxISR = NULL; + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); #else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } } @@ -4019,13 +4545,13 @@ static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) { /* Disable the UART RXFT interrupt*/ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); /* Update the RxISR function pointer */ huart->RxISR = UART_RxISR_8BIT; /* Enable the UART Data Register Not Empty interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); } } else @@ -4036,7 +4562,7 @@ static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) } /** - * @brief RX interrrupt handler for 9 bits data word length and FIFO mode is enabled. + * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled. * @note Function is called under interruption only, once * interruptions have been enabled by HAL_UART_Receive_IT() * @param huart UART handle. @@ -4047,27 +4573,76 @@ static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) uint16_t *tmp; uint16_t uhMask = huart->Mask; uint16_t uhdata; - uint16_t nb_rx_data; + uint16_t nb_rx_data; uint16_t rxdatacount; + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its = READ_REG(huart->Instance->CR3); /* Check that a Rx process is ongoing */ if (huart->RxState == HAL_UART_STATE_BUSY_RX) { - for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--) + nb_rx_data = huart->NbRxDataToProcess; + while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) { uhdata = (uint16_t) READ_REG(huart->Instance->RDR); tmp = (uint16_t *) huart->pRxBuffPtr ; *tmp = (uint16_t)(uhdata & uhMask); huart->pRxBuffPtr += 2U; huart->RxXferCount--; + isrflags = READ_REG(huart->Instance->ISR); + + /* If some non blocking errors occurred */ + if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* Call UART Error Call back function if need be ----------------------------*/ + if (huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } if (huart->RxXferCount == 0U) { /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ - CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; @@ -4075,13 +4650,54 @@ static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) /* Clear RxISR function pointer */ huart->RxISR = NULL; + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); #else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } } } @@ -4093,13 +4709,13 @@ static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) { /* Disable the UART RXFT interrupt*/ - CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); /* Update the RxISR function pointer */ huart->RxISR = UART_RxISR_16BIT; /* Enable the UART Data Register Not Empty interrupt */ - SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); } } else @@ -4122,4 +4738,3 @@ static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |