Modified version of the mbed library for use with the Nucleo boards.
Dependents: EEPROMWrite Full-Project
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_uart.c
- Revision:
- 630:825f75ca301e
- Parent:
- 441:d2c15dda23c1
--- a/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_uart.c Mon Sep 28 10:30:09 2015 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_uart.c Mon Sep 28 10:45:10 2015 +0100 @@ -2,69 +2,68 @@ ****************************************************************************** * @file stm32f0xx_hal_uart.c * @author MCD Application Team - * @version V1.2.0 - * @date 11-December-2014 + * @version V1.3.0 + * @date 26-June-2015 * @brief UART HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral: * + Initialization and de-initialization functions * + IO operation functions - * + Peripheral Control functions - * + Peripheral State and Errors functions - @verbatim + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + @verbatim + =============================================================================== + ##### How to use this driver ##### =============================================================================== - ##### How to use this driver ##### -================================================================================ - [..] + [..] The UART HAL driver can be used as follows: - - (#) Declare a UART_HandleTypeDef handle structure. - (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit ()API: - (##) Enable the USARTx interface clock. - (##) UART pins configuration: + (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). + (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: + (++) Enable the USARTx interface clock. + (++) UART pins configuration: (+++) Enable the clock for the UART GPIOs. (+++) Configure these UART pins as alternate function pull-up. - (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() + (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() and HAL_UART_Receive_IT() APIs): (+++) Configure the USARTx interrupt priority. (+++) Enable the NVIC USART IRQ handle. - (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() + (++) UART interrupts handling: + -@@- The specific UART interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) are managed using the macros + __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive processes. + (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() and HAL_UART_Receive_DMA() APIs): (+++) Declare a DMA handle structure for the Tx/Rx channel. (+++) Enable the DMAx interface clock. - (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. (+++) Configure the DMA Tx/Rx channel. - (+++) Associate the initilalized DMA handle to the UART DMA Tx/Rx handle. + (+++) 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. - (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware - flow control and Mode(Receiver/Transmitter) in the huart Init structure. - + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. + (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) - in the huart AdvancedInit structure. + in the huart handle AdvancedInit structure. (#) For the UART asynchronous mode, initialize the UART registers by calling the HAL_UART_Init() API. - - (#) For the UART Half duplex mode, initialize the UART registers by calling - the HAL_HalfDuplex_Init() API. - - (#) For the UART Multiprocessor mode, initialize the UART registers - by calling the HAL_MultiProcessor_Init() API. - (#) For the UART RS485 Driver Enabled mode, initialize the UART registers - by calling the HAL_RS485Ex_Init() API. + (#) For the UART Half duplex mode, initialize the UART registers by calling + the HAL_HalfDuplex_Init() API. + + (#) For the UART Multiprocessor mode, initialize the UART registers + by calling the HAL_MultiProcessor_Init() API. - [..] - (@) The specific UART interrupts (Transmission complete interrupt, - RXNE interrupt and Error Interrupts) will be managed using the macros - __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive process. + (#) For the UART RS485 Driver Enabled mode, initialize the UART registers + by calling the HAL_RS485Ex_Init() API. - [..] + [..] (@) These APIs(HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_MultiProcessor_Init(), - also configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by - calling the customed HAL_UART_MspInit() API. + also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by + calling the customized HAL_UART_MspInit() API. Three operation modes are available within this driver : @@ -128,7 +127,7 @@ ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -152,7 +151,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -162,25 +161,27 @@ * @{ */ -/** @defgroup UART UART HAL module driver +/** @defgroup UART UART * @brief HAL UART module driver * @{ */ + #ifdef HAL_UART_MODULE_ENABLED - + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -/** @defgroup UART_Private_Constants UART Private Constants +/** @defgroup UART_Private_Constants UART Private Constants * @{ */ -#define HAL_UART_TXDMA_TIMEOUTVALUE 22000 +#define UART_TEACK_REACK_TIMEOUT ((uint32_t) 1000) /*!< UART TX or RX enable acknowledge time-out value */ +#define UART_TXDMA_TIMEOUTVALUE 22000 #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ - USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ /** * @} */ -/* Private macro -------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /** @addtogroup UART_Private_Functions UART Private Functions @@ -190,50 +191,64 @@ static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); -static void UART_DMAError(DMA_HandleTypeDef *hdma); +static void UART_DMAError(DMA_HandleTypeDef *hdma); /** * @} */ -/* Exported functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ /** @defgroup UART_Exported_Functions UART Exported Functions * @{ */ -/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions +/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * -@verbatim +@verbatim =============================================================================== ##### Initialization and Configuration functions ##### - =============================================================================== + =============================================================================== [..] - This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy in asynchronous mode. - (+) For the asynchronous mode only these parameters can be configured: + (+) For the asynchronous mode the parameters below can be configured: (++) Baud Rate - (++) Word Length + (++) Word Length (++) Stop Bit (++) Parity: If the parity is enabled, then the MSB bit of the data written in the data register is transmitted but is changed by the parity bit. - Depending on the frame length defined by the M bit (8-bits or 9-bits), - the possible UART frame formats are as listed in the following table: - |-----------|-----------|---------------------------------------| - | M1M0 bits | PCE bit | UART frame | - |-----------------------|---------------------------------------| - | 00 | 0 | | SB | 8-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 00 | 1 | | SB | 7-bit data | PB | STB | | - |-----------|-----------|---------------------------------------| - | 01 | 0 | | SB | 9-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 01 | 1 | | SB | 8-bit data | PB | STB | | - +---------------------------------------------------------------+ - | 10 | 0 | | SB | 7-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 10 | 1 | | SB | 6-bit data | PB | STB | | - +---------------------------------------------------------------+ + According to device capability (support or not of 7-bit word length), + frame length is either defined by the M bit (8-bits or 9-bits) + or by the M1 and M0 bits (7-bit, 8-bit or 9-bit). + Possible UART frame formats are as listed in the following table: + + (+++) Table 1. UART frame format. + (+++) +-----------------------------------------------------------------------+ + (+++) | M bit | PCE bit | UART frame | + (+++) |-------------------|-----------|---------------------------------------| + (+++) | 0 | 0 | | SB | 8-bit data | STB | | + (+++) |-------------------|-----------|---------------------------------------| + (+++) | 0 | 1 | | SB | 7-bit data | PB | STB | | + (+++) |-------------------|-----------|---------------------------------------| + (+++) | 1 | 0 | | SB | 9-bit data | STB | | + (+++) |-------------------|-----------|---------------------------------------| + (+++) | 1 | 1 | | SB | 8-bit data | PB | STB | | + (+++) +-----------------------------------------------------------------------+ + (+++) | M1 bit | M0 bit | PCE bit | UART frame | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 0 | 0 | 0 | | SB | 8 bit data | STB | | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 0 | 1 | 0 | | SB | 9 bit data | STB | | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 1 | 0 | 0 | | SB | 7 bit data | STB | | + (+++) |---------|---------|-----------|---------------------------------------| + (+++) | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + (+++) +-----------------------------------------------------------------------+ (++) Hardware flow control (++) Receiver/transmitter modes (++) Over Sampling Method @@ -247,8 +262,8 @@ (++) MSB first on communication line (++) auto Baud rate detection [..] - The HAL_UART_Init(), HAL_HalfDuplex_Init() and HAL_MultiProcessor_Init() - API follow respectively the UART asynchronous, UART Half duplex and multiprocessor + The HAL_UART_Init(), HAL_HalfDuplex_Init() and HAL_MultiProcessor_Init() + API follow respectively the UART asynchronous, UART Half duplex and multiprocessor mode configuration procedures (details for the procedures are available in reference manual). @endverbatim @@ -256,9 +271,9 @@ */ /** - * @brief Initializes the UART mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle + * @brief Initialize the UART mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) @@ -268,7 +283,7 @@ { return HAL_ERROR; } - + if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { /* Check the parameters */ @@ -279,46 +294,49 @@ /* Check the parameters */ assert_param(IS_UART_INSTANCE(huart->Instance)); } - + if(huart->State == HAL_UART_STATE_RESET) - { + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->State = HAL_UART_STATE_BUSY; /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ if (UART_SetConfig(huart) == HAL_ERROR) { return HAL_ERROR; - } - + } + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In asynchronous mode, the following bits must be kept cleared: + + /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ - huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); - huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); - + huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); + huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - + /* TEACK and/or REACK to check before moving huart->State to Ready */ return (UART_CheckIdleState(huart)); } /** - * @brief Initializes the half-duplex mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle + * @brief Initialize the half-duplex mode according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) @@ -328,65 +346,68 @@ { return HAL_ERROR; } - + /* Check UART instance */ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); - + if(huart->State == HAL_UART_STATE_RESET) - { + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->State = HAL_UART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ if (UART_SetConfig(huart) == HAL_ERROR) { return HAL_ERROR; - } - + } + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In half-duplex mode, the following bits must be kept cleared: + + /* In half-duplex mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN and IREN bits in the USART_CR3 register.*/ huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN); - + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ huart->Instance->CR3 |= USART_CR3_HDSEL; - + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - + /* TEACK and/or REACK to check before moving huart->State to Ready */ return (UART_CheckIdleState(huart)); } /** - * @brief Initializes the multiprocessor mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle. - * @param huart: UART handle - * @param Address: UART node address (4-, 6-, 7- or 8-bit long) + * @brief Initialize the multiprocessor mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart: UART handle. + * @param Address: UART node address (4-, 6-, 7- or 8-bit long). * @param WakeUpMethod: specifies the UART wakeup method. * This parameter can be one of the following values: * @arg UART_WAKEUPMETHOD_IDLELINE: WakeUp by an idle line detection * @arg UART_WAKEUPMETHOD_ADDRESSMARK: WakeUp by an address mark * @note If the user resorts to idle line detection wake up, the Address parameter - * is useless and ignored by the initialization function. - * @note If the user resorts to address mark wake up, the address length detection - * is configured by default to 4 bits only. For the UART to be able to + * is useless and ignored by the initialization function. + * @note If the user resorts to address mark wake up, the address length detection + * is configured by default to 4 bits only. For the UART to be able to * manage 6-, 7- or 8-bit long addresses detection, the API - * HAL_MultiProcessorEx_AddressLength_Set() must be called after - * HAL_MultiProcessor_Init(). + * HAL_MultiProcessorEx_AddressLength_Set() must be called after + * HAL_MultiProcessor_Init(). * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) @@ -399,54 +420,57 @@ /* Check the wake up method parameter */ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); - + if(huart->State == HAL_UART_STATE_RESET) - { + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->State = HAL_UART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ if (UART_SetConfig(huart) == HAL_ERROR) { return HAL_ERROR; - } - + } + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In multiprocessor mode, the following bits must be kept cleared: + + /* In multiprocessor mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); - + if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) { /* If address mark wake up method is chosen, set the USART address node */ MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); } - + /* Set the wake up method by setting the WAKE bit in the CR1 register */ MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); - + /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - + __HAL_UART_ENABLE(huart); + /* TEACK and/or REACK to check before moving huart->State to Ready */ return (UART_CheckIdleState(huart)); } /** - * @brief DeInitializes the UART peripheral - * @param huart: uart handle + * @brief DeInitialize the UART peripheral. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) @@ -456,141 +480,138 @@ { return HAL_ERROR; } - + /* Check the parameters */ assert_param(IS_UART_INSTANCE(huart->Instance)); huart->State = HAL_UART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + huart->Instance->CR1 = 0x0; huart->Instance->CR2 = 0x0; huart->Instance->CR3 = 0x0; - + /* DeInit the low level hardware */ HAL_UART_MspDeInit(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->State = HAL_UART_STATE_RESET; - + /* Process Unlock */ __HAL_UNLOCK(huart); - + return HAL_OK; } /** - * @brief UART MSP Init - * @param huart: uart handle + * @brief Initialize the UART MSP. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) { /* NOTE : This function should not be modified, when the callback is needed, the HAL_UART_MspInit can be implemented in the user file - */ + */ } /** - * @brief UART MSP DeInit - * @param huart: uart handle + * @brief DeInitialize the UART MSP. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) { /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_MspDeInit could be implemented in the user file - */ + the HAL_UART_MspDeInit can be implemented in the user file + */ } /** * @} */ -/** @defgroup UART_Exported_Functions_Group2 IO operation functions - * @brief UART Transmit and Receive functions +/** @defgroup UART_Exported_Functions_Group2 IO operation functions + * @brief UART Transmit/Receive functions * -@verbatim - ============================================================================== +@verbatim + =============================================================================== ##### IO operation functions ##### - ============================================================================== - [..] + =============================================================================== This subsection provides a set of functions allowing to manage the UART asynchronous and Half duplex data transfers. (#) There are two mode of transfer: - (++) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (++) No-Blocking mode: The communication is performed using Interrupts - or DMA, These APIs return the HAL status. - The end of the data processing will be indicated through the - dedicated UART IRQ when using Interrupt mode or the DMA IRQ when + (+) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (+) No-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. - The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks - will be executed respectivelly at the end of the transmit or Receive process + The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected - (#) Blocking mode APIs are : - (++) HAL_UART_Transmit() - (++) HAL_UART_Receive() - - (#) Non Blocking mode APIs with Interrupt are : - (++) HAL_UART_Transmit_IT() - (++) HAL_UART_Receive_IT() - (++) HAL_UART_IRQHandler() - (++) UART_Transmit_IT() - (++) UART_Receive_IT() + (#) Blocking mode API's are : + (+) HAL_UART_Transmit() + (+) HAL_UART_Receive() + + (#) Non-Blocking mode API's with Interrupt are : + (+) HAL_UART_Transmit_IT() + (+) HAL_UART_Receive_IT() + (+) HAL_UART_IRQHandler() - (#) Non Blocking mode APIs with DMA are : - (++) HAL_UART_Transmit_DMA() - (++) HAL_UART_Receive_DMA() - (++) HAL_UART_DMAPause() - (++) HAL_UART_DMAResume() - (++) HAL_UART_DMAStop() + (#) No-Blocking mode API's with DMA are : + (+) HAL_UART_Transmit_DMA() + (+) HAL_UART_Receive_DMA() + (+) HAL_UART_DMAPause() + (+) HAL_UART_DMAResume() + (+) HAL_UART_DMAStop() - (#) A set of Transfer Complete Callbacks are provided in non blocking mode: - (++) HAL_UART_TxHalfCpltCallback() - (++) HAL_UART_TxCpltCallback() - (++) HAL_UART_RxHalfCpltCallback() - (++) HAL_UART_RxCpltCallback() - (++) HAL_UART_ErrorCallback() + (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (+) HAL_UART_TxHalfCpltCallback() + (+) HAL_UART_TxCpltCallback() + (+) HAL_UART_RxHalfCpltCallback() + (+) HAL_UART_RxCpltCallback() + (+) HAL_UART_ErrorCallback() - [..] - (@) In the Half duplex communication, it is forbidden to run the transmit + + -@- 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. - + @endverbatim * @{ */ /** - * @brief Send an amount of data in blocking mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @param Timeout : Timeout duration + * @brief Send an amount of data in blocking mode. + * @param huart: UART handle. + * @param pData: Pointer to data buffer. + * @param Size: Amount of data to be sent. + * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - uint16_t* tmp; + uint16_t* tmp; if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX)) { - if((pData == NULL ) || (Size == 0)) + if((pData == NULL ) || (Size == 0)) { return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a non-blocking receive process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_RX) + if(huart->State == HAL_UART_STATE_BUSY_RX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -598,33 +619,33 @@ { huart->State = HAL_UART_STATE_BUSY_TX; } - + huart->TxXferSize = Size; huart->TxXferCount = Size; while(huart->TxXferCount > 0) { huart->TxXferCount--; - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK) - { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { tmp = (uint16_t*) pData; - huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); + huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); pData += 2; } else { - huart->Instance->TDR = (*pData++ & (uint8_t)0xFF); - } + huart->Instance->TDR = (*pData++ & (uint8_t)0xFF); + } } - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK) - { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } /* Check if a non-blocking receive Process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_RX; } @@ -632,10 +653,10 @@ { huart->State = HAL_UART_STATE_READY; } - + /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_OK; } else @@ -645,31 +666,31 @@ } /** - * @brief Receive an amount of data in blocking mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout : Timeout duration + * @brief Receive an amount of data in blocking mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. + * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ +{ uint16_t* tmp; uint16_t uhMask; if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX)) - { - if((pData == NULL ) || (Size == 0)) + { + if((pData == NULL ) || (Size == 0)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a non-blocking transmit process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX) + if(huart->State == HAL_UART_STATE_BUSY_TX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -677,22 +698,22 @@ { huart->State = HAL_UART_STATE_BUSY_RX; } - - huart->RxXferSize = Size; + + huart->RxXferSize = Size; huart->RxXferCount = Size; - + /* Computation of UART mask to apply to RDR register */ - __HAL_UART_MASK_COMPUTATION(huart); + UART_MASK_COMPUTATION(huart); uhMask = huart->Mask; - + /* as long as data have to be received */ while(huart->RxXferCount > 0) { huart->RxXferCount--; - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { return HAL_TIMEOUT; - } + } if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { tmp = (uint16_t*) pData ; @@ -701,56 +722,56 @@ } else { - *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); - } + *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); + } } - + /* Check if a non-blocking transmit Process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_TX; } else { huart->State = HAL_UART_STATE_READY; - } + } /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in interrupt mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in interrupt mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be sent. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ +{ if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX)) { - if((pData == NULL ) || (Size == 0)) + if((pData == NULL ) || (Size == 0)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->pTxBuffPtr = pData; huart->TxXferSize = Size; huart->TxXferCount = Size; - + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a receive process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_RX) + if(huart->State == HAL_UART_STATE_BUSY_RX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -758,53 +779,53 @@ { huart->State = HAL_UART_STATE_BUSY_TX; } - + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); - + /* Process Unlocked */ - __HAL_UNLOCK(huart); - + __HAL_UNLOCK(huart); + /* Enable the UART Transmit Data Register Empty Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in interrupt mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in interrupt mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ +{ if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX)) { - if((pData == NULL ) || (Size == 0)) + if((pData == NULL ) || (Size == 0)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->pRxBuffPtr = pData; huart->RxXferSize = Size; huart->RxXferCount = Size; - + /* Computation of UART mask to apply to RDR register */ - __HAL_UART_MASK_COMPUTATION(huart); - + UART_MASK_COMPUTATION(huart); + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a transmit process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX) + if(huart->State == HAL_UART_STATE_BUSY_TX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -812,55 +833,55 @@ { huart->State = HAL_UART_STATE_BUSY_RX; } - + /* Enable the UART Parity Error Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_PE); - + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); - + /* Process Unlocked */ __HAL_UNLOCK(huart); - + /* Enable the UART Data Register not empty Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in DMA mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in DMA mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be sent. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { uint32_t *tmp; - + if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX)) { - if((pData == NULL ) || (Size == 0)) + if((pData == NULL ) || (Size == 0)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->pTxBuffPtr = pData; huart->TxXferSize = Size; - huart->TxXferCount = Size; - + huart->TxXferCount = Size; + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a receive process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_RX) + if(huart->State == HAL_UART_STATE_BUSY_RX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -868,64 +889,67 @@ { huart->State = HAL_UART_STATE_BUSY_TX; } - + /* Set the UART DMA transfer complete callback */ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; - + /* Set the UART DMA Half transfer complete callback */ - huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; - + huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; + /* Set the DMA error callback */ huart->hdmatx->XferErrorCallback = UART_DMAError; /* Enable the UART transmit DMA channel */ tmp = (uint32_t*)&pData; HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, Size); - + + /* Clear the TC flag in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + /* Enable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ huart->Instance->CR3 |= USART_CR3_DMAT; - + /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in DMA mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @note When the UART parity is enabled (PCE = 1), the received data contain - * the parity bit (MSB position) + * @brief Receive an amount of data in DMA mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. + * @note When the UART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { uint32_t *tmp; - + if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX)) { - if((pData == NULL ) || (Size == 0)) + if((pData == NULL ) || (Size == 0)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ __HAL_LOCK(huart); - + huart->pRxBuffPtr = pData; huart->RxXferSize = Size; - + huart->ErrorCode = HAL_UART_ERROR_NONE; /* Check if a transmit process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX) + if(huart->State == HAL_UART_STATE_BUSY_TX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } @@ -933,13 +957,13 @@ { huart->State = HAL_UART_STATE_BUSY_RX; } - + /* 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; @@ -947,31 +971,31 @@ tmp = (uint32_t*)&pData; HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size); - /* Enable the DMA transfer for the receiver request by setting the DMAR bit + /* Enable the DMA transfer for the receiver request by setting the DMAR bit in the UART CR3 register */ huart->Instance->CR3 |= USART_CR3_DMAR; - + /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Pauses the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Pause the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); - + if(huart->State == HAL_UART_STATE_BUSY_TX) { /* Disable the UART DMA Tx request */ @@ -989,23 +1013,23 @@ /* Disable the UART DMA Rx request */ huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); } - + /* Process Unlocked */ __HAL_UNLOCK(huart); - - return HAL_OK; + + return HAL_OK; } /** - * @brief Resumes the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Resume the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); - + if(huart->State == HAL_UART_STATE_BUSY_TX) { /* Enable the UART DMA Tx request */ @@ -1013,42 +1037,49 @@ } else if(huart->State == HAL_UART_STATE_BUSY_RX) { + /* Clear the Overrun flag before resumming the Rx transfer*/ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + /* Enable the UART DMA Rx request */ huart->Instance->CR3 |= USART_CR3_DMAR; } else if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { + /* Clear the Overrun flag before resumming the Rx transfer*/ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + /* Enable the UART DMA Rx request before the DMA Tx request */ huart->Instance->CR3 |= USART_CR3_DMAR; + /* Enable the UART DMA Tx request */ huart->Instance->CR3 |= USART_CR3_DMAT; } - /* If the UART peripheral is still not enabled, enable it */ - if ((huart->Instance->CR1 & USART_CR1_UE) == 0) - { - /* Enable UART peripheral */ - __HAL_UART_ENABLE(huart); - } - - /* TEACK and/or REACK to check before moving huart->State to Ready */ - return (UART_CheckIdleState(huart)); + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; } /** - * @brief Stops the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Stop the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) { - /* Process Locked */ - __HAL_LOCK(huart); + /* The Lock is not implemented on this API to allow the user application + to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / + HAL_UART_TxHalfCpltCallback() / HAL_UART_RxHalfCpltCallback (): + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete interrupt is + generated if the DMA transfer interruption occurs at the middle or at the end of the stream + and the corresponding call back is executed. + */ /* Disable the UART Tx/Rx DMA requests */ huart->Instance->CR3 &= ~USART_CR3_DMAT; huart->Instance->CR3 &= ~USART_CR3_DMAR; - + /* Abort the UART DMA tx channel */ if(huart->hdmatx != NULL) { @@ -1059,219 +1090,218 @@ { HAL_DMA_Abort(huart->hdmarx); } - - /* Disable UART peripheral */ - __HAL_UART_DISABLE(huart); - + huart->State = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - + return HAL_OK; } - + /** - * @brief Tx Transfer completed callbacks - * @param huart: uart handle + * @brief Tx Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback can be implemented in the user file - */ + the HAL_UART_TxCpltCallback can be implemented in the user file. + */ } /** - * @brief Tx Half Transfer completed callbacks. - * @param huart: UART handle + * @brief Tx Half Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) { /* NOTE: This function should not be modified, when the callback is needed, - the HAL_UART_TxHalfCpltCallback can be implemented in the user file - */ + the HAL_UART_TxHalfCpltCallback can be implemented in the user file. + */ } /** - * @brief Rx Transfer completed callbacks - * @param huart: uart handle + * @brief Rx Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_RxCpltCallback can be implemented in the user file + the HAL_UART_RxCpltCallback can be implemented in the user file. */ } /** - * @brief Rx Half Transfer completed callbacks. - * @param huart: UART handle + * @brief Rx Half Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { /* NOTE: This function should not be modified, when the callback is needed, - the HAL_UART_RxHalfCpltCallback can be implemented in the user file + the HAL_UART_RxHalfCpltCallback can be implemented in the user file. */ } /** - * @brief UART error callbacks - * @param huart: uart handle + * @brief UART error callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_ErrorCallback can be implemented in the user file - */ + the HAL_UART_ErrorCallback can be implemented in the user file. + */ } /** * @} - */ + */ -/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions - * @brief UART control functions +/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions + * @brief UART control functions * -@verbatim +@verbatim =============================================================================== ##### Peripheral Control functions ##### - =============================================================================== + =============================================================================== [..] This subsection provides a set of functions allowing to control the UART. - (+) HAL_UART_GetState() API is helpful to check in run-time the state of the UART peripheral. (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode - (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode - (+) HAL_UART_EnableStopMode() API enables the UART to wake up the MCU from stop mode - (+) HAL_UART_DisableStopMode() API disables the above functionality - (+) UART_SetConfig() API configures the UART peripheral - (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features - (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization - (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters - (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter - (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver + (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter + (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver @endverbatim * @{ */ /** - * @brief Enable UART in mute mode (doesn't mean UART enters mute mode; - * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called) - * @param huart: UART handle + * @brief Enable UART in mute mode (does not mean UART enters mute mode; + * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) -{ +{ /* Process Locked */ __HAL_LOCK(huart); - + huart->State = HAL_UART_STATE_BUSY; - + /* Enable USART mute mode by setting the MME bit in the CR1 register */ huart->Instance->CR1 |= USART_CR1_MME; - + huart->State = HAL_UART_STATE_READY; - + return (UART_CheckIdleState(huart)); } /** - * @brief Disable UART mute mode (doesn't mean it actually wakes up the software, + * @brief Disable UART mute mode (does not mean the UART actually exits mute mode * as it may not have been in mute mode at this very moment). - * @param huart: uart handle + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) -{ +{ /* Process Locked */ __HAL_LOCK(huart); - + huart->State = HAL_UART_STATE_BUSY; - + /* Disable USART mute mode by clearing the MME bit in the CR1 register */ huart->Instance->CR1 &= ~(USART_CR1_MME); - + huart->State = HAL_UART_STATE_READY; - + return (UART_CheckIdleState(huart)); } /** * @brief Enter UART mute mode (means UART actually enters mute mode). - * To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. - * @param huart: uart handle - * @retval HAL status + * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. + * @param huart: UART handle. + * @retval None */ void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) -{ +{ __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); } /** - * @brief Enables the UART transmitter and disables the UART receiver. - * @param huart: UART handle + * @brief Enable the UART transmitter and disable the UART receiver. + * @param huart: UART handle. * @retval HAL status - * @retval None */ HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); huart->State = HAL_UART_STATE_BUSY; - + /* Clear TE and RE bits */ 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); - + huart->State = HAL_UART_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(huart); - - return HAL_OK; + + return HAL_OK; } /** - * @brief Enables the UART receiver and disables the UART transmitter. - * @param huart: UART handle - * @retval HAL status + * @brief Enable the UART receiver and disable the UART transmitter. + * @param huart: UART handle. + * @retval HAL status. */ HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); huart->State = HAL_UART_STATE_BUSY; - + /* Clear TE and RE bits */ 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); - + huart->State = HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); - return HAL_OK; + return HAL_OK; } /** * @} - */ - -/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions + */ + +/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions + * @brief UART Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the UART handle state. + (+) Return the UART handle error code + +@endverbatim * @{ */ /** - * @brief return the UART state - * @param huart: uart handle + * @brief Return the UART handle state. + * @param huart : pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. * @retval HAL state */ HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) @@ -1280,7 +1310,7 @@ } /** -* @brief Return the UART error code +* @brief Return the UART handle error code. * @param huart : pointer to a UART_HandleTypeDef structure that contains * the configuration information for the specified UART. * @retval UART Error Code @@ -1289,187 +1319,268 @@ { return huart->ErrorCode; } +/** + * @} + */ /** * @} - */ - -/** - * @} - */ - + */ + /** @defgroup UART_Private_Functions UART Private Functions * @{ */ - + /** - * @brief Send an amount of data in interrupt mode - * Function called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT() - * @param huart: UART handle + * @brief Configure the UART peripheral. + * @param huart: UART handle. * @retval HAL status */ -HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) +HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) { - uint16_t* tmp; + uint32_t tmpreg = 0x00000000; + UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED; + uint16_t brrtemp = 0x0000; + uint16_t usartdiv = 0x0000; + HAL_StatusTypeDef ret = HAL_OK; + + /* Check the parameters */ + assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); + assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); + assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); + assert_param(IS_UART_PARITY(huart->Init.Parity)); + assert_param(IS_UART_MODE(huart->Init.Mode)); + assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); + assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling)); + assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure + * the UART Word Length, Parity, Mode and oversampling: + * set the M bits according to huart->Init.WordLength value + * set PCE and PS bits according to huart->Init.Parity value + * 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 ; + MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg); + + /*-------------------------- USART CR2 Configuration -----------------------*/ + /* Configure the UART Stop Bits: Set STOP[13:12] bits according + * to huart->Init.StopBits value */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Configure + * - UART HardWare Flow Control: set CTSE and RTSE bits according + * to huart->Init.HwFlowCtl value + * - one-bit sampling method versus three samples' majority rule according + * to huart->Init.OneBitSampling */ + tmpreg = (uint32_t)huart->Init.HwFlowCtl | huart->Init.OneBitSampling ; + MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), tmpreg); + + /*-------------------------- USART BRR Configuration -----------------------*/ + UART_GETCLOCKSOURCE(huart, clocksource); - if ((huart->State == HAL_UART_STATE_BUSY_TX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX)) + /* Check UART Over Sampling to set Baud Rate Register */ + if (huart->Init.OverSampling == UART_OVERSAMPLING_8) { - - if(huart->TxXferCount == 0) + switch (clocksource) { - /* Disable the UART Transmit Data Register Empty Interrupt */ - __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); - - /* Enable the UART Transmit Complete Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_TC); - - return HAL_OK; + case UART_CLOCKSOURCE_PCLK1: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_HSI: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_SYSCLK: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_LSE: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_UNDEFINED: + default: + ret = HAL_ERROR; + break; } - else - { - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - tmp = (uint16_t*) huart->pTxBuffPtr; - huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); - huart->pTxBuffPtr += 2; - } - else - { - huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF); - } - huart->TxXferCount--; - - return HAL_OK; - } + brrtemp = usartdiv & 0xFFF0; + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U); + huart->Instance->BRR = brrtemp; } else { - return HAL_BUSY; + switch (clocksource) + { + case UART_CLOCKSOURCE_PCLK1: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_HSI: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_SYSCLK: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_LSE: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_UNDEFINED: + default: + ret = HAL_ERROR; + break; + } + } + + return ret; + +} + +/** + * @brief Configure the UART peripheral advanced features. + * @param huart: UART handle. + * @retval None + */ +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 TX pin active level inversion */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); + } + + /* if required, configure RX pin active level inversion */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); + } + + /* if required, configure data inversion */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); + 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)) + { + assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); + MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); + } + + /* if required, configure DMA disabling on reception error */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) + { + assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); + MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); + } + + /* if required, configure auto Baud rate detection scheme */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) + { + assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); + assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); + /* set auto Baudrate detection parameters if detection is enabled */ + if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) + { + assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); + } + } + + /* if required, configure MSB first on communication line */ + if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) + { + assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); } } /** - * @brief Receive an amount of data in interrupt mode - * Function called under interruption only, once - * interruptions have been enabled by HAL_UART_Receive_IT() - * @param huart: UART handle - * @retval HAL status - */ -HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) -{ - uint16_t* tmp; - uint16_t uhMask = huart->Mask; - - if((huart->State == HAL_UART_STATE_BUSY_RX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX)) - { - - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - tmp = (uint16_t*) huart->pRxBuffPtr ; - *tmp = (uint16_t)(huart->Instance->RDR & uhMask); - huart->pRxBuffPtr +=2; - } - else - { - *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); - } - - if(--huart->RxXferCount == 0) - { - __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); - - /* Check if a transmit Process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX_RX) - { - huart->State = HAL_UART_STATE_BUSY_TX; - } - else - { - /* Disable the UART Parity Error Interrupt */ - __HAL_UART_DISABLE_IT(huart, UART_IT_PE); - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); - - huart->State = HAL_UART_STATE_READY; - } - - HAL_UART_RxCpltCallback(huart); - - return HAL_OK; - } - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Check the UART Idle State - * @param huart: uart handle + * @brief Check the UART Idle State. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) { /* Initialize the UART ErrorCode */ huart->ErrorCode = HAL_UART_ERROR_NONE; - - /* Check if the Transmitter is enabled */ - if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + + /* TEACK and REACK bits in ISR are checked only when available (not available on all F0 devices). + Bits are defined for some specific devices, and are available only for UART instances supporting WakeUp from Stop Mode feature. + */ +#if !defined(STM32F030x6) && !defined(STM32F030x8)&& !defined(STM32F070xB)&& !defined(STM32F070x6)&& !defined(STM32F030xC) + if (IS_UART_WAKEUP_INSTANCE(huart->Instance)) { - /* Wait until TEACK flag is set */ - if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, HAL_UART_TIMEOUT_VALUE) != HAL_OK) - { - /* Timeout Occured */ - return HAL_TIMEOUT; - } - } - /* Check if the Receiver is enabled */ - if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) - { - /* Wait until REACK flag is set */ - if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, HAL_UART_TIMEOUT_VALUE) != HAL_OK) - { - /* Timeout Occured */ - return HAL_TIMEOUT; + /* Check if the Transmitter is enabled */ + if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, UART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Check if the Receiver is enabled */ + if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, UART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } } } +#endif /* !defined(STM32F030x6) && !defined(STM32F030x8)&& !defined(STM32F070xB)&& !defined(STM32F070x6)&& !defined(STM32F030xC) */ /* Initialize the UART State */ - huart->State= HAL_UART_STATE_READY; + huart->State= HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); - + return HAL_OK; } + /** - * @brief This function handles UART Communication Timeout. - * @param huart: UART handle + * @brief Handle UART Communication Timeout. + * @param huart: UART handle. * @param Flag: specifies the UART flag to check. - * @param Status: The new Flag status (SET or RESET). - * @param Timeout: Timeout duration + * @param Status: the Flag status (SET or RESET). + * @param Timeout: Timeout duration. * @retval HAL status */ -HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) { uint32_t tickstart = HAL_GetTick(); /* Wait until flag is set */ if(Status == RESET) - { + { while(__HAL_UART_GET_FLAG(huart, Flag) == RESET) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { - if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) + if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); @@ -1494,7 +1605,7 @@ /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { - if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) + if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); @@ -1512,49 +1623,41 @@ } } } - return HAL_OK; + return HAL_OK; } /** - * @brief DMA UART transmit process complete callback - * @param hdma: DMA handle + * @brief DMA UART transmit process complete callback. + * @param hdma: DMA handle. * @retval None */ -static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - huart->TxXferCount = 0; - /* Disable the DMA transfer for transmit request by setting the DMAT bit - in the UART CR3 register */ - huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) + { + huart->TxXferCount = 0; - /* Wait for UART TC Flag */ - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, HAL_UART_TXDMA_TIMEOUTVALUE) != HAL_OK) - { - /* Timeout Occured */ - huart->State = HAL_UART_STATE_TIMEOUT; - HAL_UART_ErrorCallback(huart); + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the UART CR3 register */ + huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); + + /* Enable the UART Transmit Complete Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_TC); } + /* DMA Circular mode */ else { - /* No Timeout */ - /* Check if a receive process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX_RX) - { - huart->State = HAL_UART_STATE_BUSY_RX; - } - else - { - huart->State = HAL_UART_STATE_READY; - } HAL_UART_TxCpltCallback(huart); } + } /** - * @brief DMA UART transmit process half complete callback - * @param hdma : DMA handle + * @brief DMA UART transmit process half complete callback. + * @param hdma : DMA handle. * @retval None */ static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) @@ -1565,49 +1668,55 @@ } /** - * @brief DMA UART receive process complete callback - * @param hdma: DMA handle + * @brief DMA UART receive process complete callback. + * @param hdma: DMA handle. * @retval None */ -static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - huart->RxXferCount = 0; - - /* Disable the DMA transfer for the receiver request by setting the DMAR bit - in the UART CR3 register */ - huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); - /* Check if a transmit Process is ongoing or not */ - if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { - huart->State = HAL_UART_STATE_BUSY_TX; + huart->RxXferCount = 0; + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the UART CR3 register */ + huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); + + /* Check if a transmit Process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + huart->State = HAL_UART_STATE_READY; + } } - else - { - huart->State = HAL_UART_STATE_READY; - } + HAL_UART_RxCpltCallback(huart); } /** - * @brief DMA UART receive process half complete callback - * @param hdma : DMA handle + * @brief DMA UART receive process half complete callback. + * @param hdma : DMA handle. * @retval None */ static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; - HAL_UART_RxHalfCpltCallback(huart); + HAL_UART_RxHalfCpltCallback(huart); } /** - * @brief DMA UART communication error callback - * @param hdma: DMA handle + * @brief DMA UART communication error callback. + * @param hdma: DMA handle. * @retval None */ -static void UART_DMAError(DMA_HandleTypeDef *hdma) +static void UART_DMAError(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; huart->RxXferCount = 0; @@ -1618,187 +1727,147 @@ } /** - * @brief Configure the UART peripheral - * @param huart: uart handle - * @retval None + * @brief Send an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart: UART handle. + * @retval HAL status */ -HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) +HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) { - uint32_t tmpreg = 0x00000000; - UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED; - uint16_t brrtemp = 0x0000; - uint16_t usartdiv = 0x0000; - HAL_StatusTypeDef ret = HAL_OK; - - /* Check the parameters */ - assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); - assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); - assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); - assert_param(IS_UART_PARITY(huart->Init.Parity)); - assert_param(IS_UART_MODE(huart->Init.Mode)); - assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); - assert_param(IS_UART_ONEBIT_SAMPLING(huart->Init.OneBitSampling)); + uint16_t* tmp; + + if ((huart->State == HAL_UART_STATE_BUSY_TX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX)) + { + + if(huart->TxXferCount == 0) + { + /* Disable the UART Transmit Data Register Empty Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); + + /* Enable the UART Transmit Complete Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_TC); + + return HAL_OK; + } + else + { + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + tmp = (uint16_t*) huart->pTxBuffPtr; + huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); + huart->pTxBuffPtr += 2; + } + else + { + huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF); + } + + huart->TxXferCount--; + + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} - /*-------------------------- USART CR1 Configuration -----------------------*/ - /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure - * the UART Word Length, Parity, Mode and oversampling: - * set the M bits according to huart->Init.WordLength value - * set PCE and PS bits according to huart->Init.Parity value - * 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 ; - MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg); +/** + * @brief Wrap up transmission in non-blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable the UART Transmit Complete Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TC); - /*-------------------------- USART CR2 Configuration -----------------------*/ - /* Configure the UART Stop Bits: Set STOP[13:12] bits according - * to huart->Init.StopBits value */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); - - /*-------------------------- USART CR3 Configuration -----------------------*/ - /* Configure - * - UART HardWare Flow Control: set CTSE and RTSE bits according - * to huart->Init.HwFlowCtl value - * - one-bit sampling method versus three samples' majority rule according - * to huart->Init.OneBitSampling */ - tmpreg = (uint32_t)huart->Init.HwFlowCtl | huart->Init.OneBitSampling ; - MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), tmpreg); - - /*-------------------------- USART BRR Configuration -----------------------*/ - __HAL_UART_GETCLOCKSOURCE(huart, clocksource); - - /* Check the Over Sampling to set Baud Rate Register */ - if (huart->Init.OverSampling == UART_OVERSAMPLING_8) + /* Check if a receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - usartdiv = (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_HSI: - usartdiv = (uint16_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_SYSCLK: - usartdiv = (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_LSE: - usartdiv = (uint16_t)(__DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_UNDEFINED: - default: - ret = HAL_ERROR; - break; - } - - brrtemp = usartdiv & 0xFFF0; - brrtemp |= (uint16_t) ((usartdiv & (uint16_t)0x000F) >> 1U); - huart->Instance->BRR = brrtemp; + huart->State = HAL_UART_STATE_BUSY_RX; } else { - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_HSI: - huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_SYSCLK: - huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_LSE: - huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_UNDEFINED: - default: - ret = HAL_ERROR; - break; - } + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State = HAL_UART_STATE_READY; } - return ret; + HAL_UART_TxCpltCallback(huart); + return HAL_OK; } + /** - * @brief Configure the UART peripheral advanced feautures - * @param huart: uart handle - * @retval None + * @brief Receive an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Receive_IT() + * @param huart: UART handle. + * @retval HAL status */ -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 TX pin active level inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); - } - - /* if required, configure RX pin active level inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); - } - - /* if required, configure data inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); - 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)) +HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + uint16_t uhMask = huart->Mask; + + if((huart->State == HAL_UART_STATE_BUSY_RX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX)) { - 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)) - { - assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); - MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); - } - - /* if required, configure DMA disabling on reception error */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) - { - assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); - MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); + + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + tmp = (uint16_t*) huart->pRxBuffPtr ; + *tmp = (uint16_t)(huart->Instance->RDR & uhMask); + huart->pRxBuffPtr +=2; + } + else + { + *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); + } + + if(--huart->RxXferCount == 0) + { + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); + + /* Check if a transmit Process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + /* Disable the UART Parity Error Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State = HAL_UART_STATE_READY; + } + + HAL_UART_RxCpltCallback(huart); + + return HAL_OK; + } + + return HAL_OK; } - - /* if required, configure auto Baud rate detection scheme */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) + else { - assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); - assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); - /* set auto Baudrate detection parameters if detection is enabled */ - if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) - { - assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); - } - } - - /* if required, configure MSB first on communication line */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) - { - assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); + return HAL_BUSY; } } /** * @} */ - + #endif /* HAL_UART_MODULE_ENABLED */ /** * @}