Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32l4xx_hal_uart.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_uart.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief UART HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). 00010 * + Initialization and de-initialization functions 00011 * + IO operation functions 00012 * + Peripheral Control functions 00013 * 00014 * 00015 @verbatim 00016 =============================================================================== 00017 ##### How to use this driver ##### 00018 =============================================================================== 00019 [..] 00020 The UART HAL driver can be used as follows: 00021 00022 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). 00023 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: 00024 (++) Enable the USARTx interface clock. 00025 (++) UART pins configuration: 00026 (+++) Enable the clock for the UART GPIOs. 00027 (+++) Configure these UART pins as alternate function pull-up. 00028 (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() 00029 and HAL_UART_Receive_IT() APIs): 00030 (+++) Configure the USARTx interrupt priority. 00031 (+++) Enable the NVIC USART IRQ handle. 00032 (++) UART interrupts handling: 00033 -@@- The specific UART interrupts (Transmission complete interrupt, 00034 RXNE interrupt and Error Interrupts) are managed using the macros 00035 __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive processes. 00036 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() 00037 and HAL_UART_Receive_DMA() APIs): 00038 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00039 (+++) Enable the DMAx interface clock. 00040 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00041 (+++) Configure the DMA Tx/Rx channel. 00042 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. 00043 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. 00044 00045 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware 00046 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. 00047 00048 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) 00049 in the huart handle AdvancedInit structure. 00050 00051 (#) For the UART asynchronous mode, initialize the UART registers by calling 00052 the HAL_UART_Init() API. 00053 00054 (#) For the UART Half duplex mode, initialize the UART registers by calling 00055 the HAL_HalfDuplex_Init() API. 00056 00057 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers 00058 by calling the HAL_LIN_Init() API. 00059 00060 (#) For the UART Multiprocessor mode, initialize the UART registers 00061 by calling the HAL_MultiProcessor_Init() API. 00062 00063 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers 00064 by calling the HAL_RS485Ex_Init() API. 00065 00066 [..] 00067 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), 00068 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by 00069 calling the customized HAL_UART_MspInit() API. 00070 00071 @endverbatim 00072 ****************************************************************************** 00073 * @attention 00074 * 00075 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00076 * 00077 * Redistribution and use in source and binary forms, with or without modification, 00078 * are permitted provided that the following conditions are met: 00079 * 1. Redistributions of source code must retain the above copyright notice, 00080 * this list of conditions and the following disclaimer. 00081 * 2. Redistributions in binary form must reproduce the above copyright notice, 00082 * this list of conditions and the following disclaimer in the documentation 00083 * and/or other materials provided with the distribution. 00084 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00085 * may be used to endorse or promote products derived from this software 00086 * without specific prior written permission. 00087 * 00088 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00089 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00090 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00091 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00092 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00093 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00094 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00095 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00096 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00097 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00098 * 00099 ****************************************************************************** 00100 */ 00101 00102 /* Includes ------------------------------------------------------------------*/ 00103 #include "stm32l4xx_hal.h" 00104 00105 /** @addtogroup STM32L4xx_HAL_Driver 00106 * @{ 00107 */ 00108 00109 /** @defgroup UART UART 00110 * @brief HAL UART module driver 00111 * @{ 00112 */ 00113 00114 #ifdef HAL_UART_MODULE_ENABLED 00115 00116 /* Private typedef -----------------------------------------------------------*/ 00117 /* Private define ------------------------------------------------------------*/ 00118 /** @defgroup UART_Private_Constants UART Private Constants 00119 * @{ 00120 */ 00121 #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ 00122 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ 00123 00124 #define UART_LPUART_BRR_MIN ((uint32_t)0x00000300) /* LPUART BRR minimum authorized value */ 00125 #define UART_LPUART_BRR_MAX ((uint32_t)0x000FFFFF) /* LPUART BRR maximum authorized value */ 00126 /** 00127 * @} 00128 */ 00129 00130 /* Private macros ------------------------------------------------------------*/ 00131 /* Private variables ---------------------------------------------------------*/ 00132 /* Private function prototypes -----------------------------------------------*/ 00133 /** @addtogroup UART_Private_Functions 00134 * @{ 00135 */ 00136 static void UART_EndTxTransfer(UART_HandleTypeDef *huart); 00137 static void UART_EndRxTransfer(UART_HandleTypeDef *huart); 00138 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00139 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00140 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00141 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00142 static void UART_DMAError(DMA_HandleTypeDef *hdma); 00143 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); 00144 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); 00145 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); 00146 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); 00147 /** 00148 * @} 00149 */ 00150 00151 /* Exported functions --------------------------------------------------------*/ 00152 00153 /** @defgroup UART_Exported_Functions UART Exported Functions 00154 * @{ 00155 */ 00156 00157 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions 00158 * @brief Initialization and Configuration functions 00159 * 00160 @verbatim 00161 =============================================================================== 00162 ##### Initialization and Configuration functions ##### 00163 =============================================================================== 00164 [..] 00165 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 00166 in asynchronous mode. 00167 (+) For the asynchronous mode the parameters below can be configured: 00168 (++) Baud Rate 00169 (++) Word Length 00170 (++) Stop Bit 00171 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00172 in the data register is transmitted but is changed by the parity bit. 00173 (++) Hardware flow control 00174 (++) Receiver/transmitter modes 00175 (++) Over Sampling Method 00176 (++) One-Bit Sampling Method 00177 (+) For the asynchronous mode, the following advanced features can be configured as well: 00178 (++) TX and/or RX pin level inversion 00179 (++) data logical level inversion 00180 (++) RX and TX pins swap 00181 (++) RX overrun detection disabling 00182 (++) DMA disabling on RX error 00183 (++) MSB first on communication line 00184 (++) auto Baud rate detection 00185 [..] 00186 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API 00187 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode 00188 and UART multiprocessor mode configuration procedures (details for the procedures 00189 are available in reference manual). 00190 00191 @endverbatim 00192 00193 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00194 8-bit or 9-bit), the possible UART formats are listed in the 00195 following table. 00196 00197 Table 1. UART frame format. 00198 +-----------------------------------------------------------------------+ 00199 | M1 bit | M0 bit | PCE bit | UART frame | 00200 |---------|---------|-----------|---------------------------------------| 00201 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00202 |---------|---------|-----------|---------------------------------------| 00203 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00204 |---------|---------|-----------|---------------------------------------| 00205 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00206 |---------|---------|-----------|---------------------------------------| 00207 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00208 |---------|---------|-----------|---------------------------------------| 00209 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00210 |---------|---------|-----------|---------------------------------------| 00211 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00212 +-----------------------------------------------------------------------+ 00213 00214 * @{ 00215 */ 00216 00217 /** 00218 * @brief Initialize the UART mode according to the specified 00219 * parameters in the UART_InitTypeDef and initialize the associated handle. 00220 * @param huart: UART handle. 00221 * @retval HAL status 00222 */ 00223 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) 00224 { 00225 /* Check the UART handle allocation */ 00226 if(huart == NULL) 00227 { 00228 return HAL_ERROR; 00229 } 00230 00231 if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) 00232 { 00233 /* Check the parameters */ 00234 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); 00235 } 00236 else 00237 { 00238 /* Check the parameters */ 00239 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); 00240 } 00241 00242 if(huart->gState == HAL_UART_STATE_RESET) 00243 { 00244 /* Allocate lock resource and initialize it */ 00245 huart->Lock = HAL_UNLOCKED; 00246 00247 /* Init the low level hardware : GPIO, CLOCK */ 00248 HAL_UART_MspInit(huart); 00249 } 00250 00251 huart->gState = HAL_UART_STATE_BUSY; 00252 00253 /* Disable the Peripheral */ 00254 __HAL_UART_DISABLE(huart); 00255 00256 /* Set the UART Communication parameters */ 00257 if (UART_SetConfig(huart) == HAL_ERROR) 00258 { 00259 return HAL_ERROR; 00260 } 00261 00262 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00263 { 00264 UART_AdvFeatureConfig(huart); 00265 } 00266 00267 /* In asynchronous mode, the following bits must be kept cleared: 00268 - LINEN and CLKEN bits in the USART_CR2 register, 00269 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ 00270 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); 00271 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); 00272 00273 /* Enable the Peripheral */ 00274 __HAL_UART_ENABLE(huart); 00275 00276 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00277 return (UART_CheckIdleState(huart)); 00278 } 00279 00280 /** 00281 * @brief Initialize the half-duplex mode according to the specified 00282 * parameters in the UART_InitTypeDef and creates the associated handle. 00283 * @param huart: UART handle. 00284 * @retval HAL status 00285 */ 00286 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) 00287 { 00288 /* Check the UART handle allocation */ 00289 if(huart == NULL) 00290 { 00291 return HAL_ERROR; 00292 } 00293 00294 /* Check UART instance */ 00295 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); 00296 00297 if(huart->gState == HAL_UART_STATE_RESET) 00298 { 00299 /* Allocate lock resource and initialize it */ 00300 huart->Lock = HAL_UNLOCKED; 00301 00302 /* Init the low level hardware : GPIO, CLOCK */ 00303 HAL_UART_MspInit(huart); 00304 } 00305 00306 huart->gState = HAL_UART_STATE_BUSY; 00307 00308 /* Disable the Peripheral */ 00309 __HAL_UART_DISABLE(huart); 00310 00311 /* Set the UART Communication parameters */ 00312 if (UART_SetConfig(huart) == HAL_ERROR) 00313 { 00314 return HAL_ERROR; 00315 } 00316 00317 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00318 { 00319 UART_AdvFeatureConfig(huart); 00320 } 00321 00322 /* In half-duplex mode, the following bits must be kept cleared: 00323 - LINEN and CLKEN bits in the USART_CR2 register, 00324 - SCEN and IREN bits in the USART_CR3 register.*/ 00325 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); 00326 huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN); 00327 00328 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ 00329 huart->Instance->CR3 |= USART_CR3_HDSEL; 00330 00331 /* Enable the Peripheral */ 00332 __HAL_UART_ENABLE(huart); 00333 00334 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00335 return (UART_CheckIdleState(huart)); 00336 } 00337 00338 00339 /** 00340 * @brief Initialize the LIN mode according to the specified 00341 * parameters in the UART_InitTypeDef and creates the associated handle . 00342 * @param huart: UART handle. 00343 * @param BreakDetectLength: specifies the LIN break detection length. 00344 * This parameter can be one of the following values: 00345 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection 00346 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection 00347 * @retval HAL status 00348 */ 00349 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) 00350 { 00351 /* Check the UART handle allocation */ 00352 if(huart == NULL) 00353 { 00354 return HAL_ERROR; 00355 } 00356 00357 /* Check the LIN UART instance */ 00358 assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); 00359 /* Check the Break detection length parameter */ 00360 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); 00361 00362 /* LIN mode limited to 16-bit oversampling only */ 00363 if(huart->Init.OverSampling == UART_OVERSAMPLING_8) 00364 { 00365 return HAL_ERROR; 00366 } 00367 /* LIN mode limited to 8-bit data length */ 00368 if(huart->Init.WordLength != UART_WORDLENGTH_8B) 00369 { 00370 return HAL_ERROR; 00371 } 00372 00373 if(huart->gState == HAL_UART_STATE_RESET) 00374 { 00375 /* Allocate lock resource and initialize it */ 00376 huart->Lock = HAL_UNLOCKED; 00377 00378 /* Init the low level hardware : GPIO, CLOCK */ 00379 HAL_UART_MspInit(huart); 00380 } 00381 00382 huart->gState = HAL_UART_STATE_BUSY; 00383 00384 /* Disable the Peripheral */ 00385 __HAL_UART_DISABLE(huart); 00386 00387 /* Set the UART Communication parameters */ 00388 if (UART_SetConfig(huart) == HAL_ERROR) 00389 { 00390 return HAL_ERROR; 00391 } 00392 00393 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00394 { 00395 UART_AdvFeatureConfig(huart); 00396 } 00397 00398 /* In LIN mode, the following bits must be kept cleared: 00399 - LINEN and CLKEN bits in the USART_CR2 register, 00400 - SCEN and IREN bits in the USART_CR3 register.*/ 00401 huart->Instance->CR2 &= ~(USART_CR2_CLKEN); 00402 huart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN); 00403 00404 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ 00405 huart->Instance->CR2 |= USART_CR2_LINEN; 00406 00407 /* Set the USART LIN Break detection length. */ 00408 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength); 00409 00410 /* Enable the Peripheral */ 00411 __HAL_UART_ENABLE(huart); 00412 00413 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00414 return (UART_CheckIdleState(huart)); 00415 } 00416 00417 00418 /** 00419 * @brief Initialize the multiprocessor mode according to the specified 00420 * parameters in the UART_InitTypeDef and initialize the associated handle. 00421 * @param huart: UART handle. 00422 * @param Address: UART node address (4-, 6-, 7- or 8-bit long). 00423 * @param WakeUpMethod: specifies the UART wakeup method. 00424 * This parameter can be one of the following values: 00425 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection 00426 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark 00427 * @note If the user resorts to idle line detection wake up, the Address parameter 00428 * is useless and ignored by the initialization function. 00429 * @note If the user resorts to address mark wake up, the address length detection 00430 * is configured by default to 4 bits only. For the UART to be able to 00431 * manage 6-, 7- or 8-bit long addresses detection, the API 00432 * HAL_MultiProcessorEx_AddressLength_Set() must be called after 00433 * HAL_MultiProcessor_Init(). 00434 * @retval HAL status 00435 */ 00436 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) 00437 { 00438 /* Check the UART handle allocation */ 00439 if(huart == NULL) 00440 { 00441 return HAL_ERROR; 00442 } 00443 00444 /* Check the wake up method parameter */ 00445 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); 00446 00447 if(huart->gState == HAL_UART_STATE_RESET) 00448 { 00449 /* Allocate lock resource and initialize it */ 00450 huart->Lock = HAL_UNLOCKED; 00451 00452 /* Init the low level hardware : GPIO, CLOCK */ 00453 HAL_UART_MspInit(huart); 00454 } 00455 00456 huart->gState = HAL_UART_STATE_BUSY; 00457 00458 /* Disable the Peripheral */ 00459 __HAL_UART_DISABLE(huart); 00460 00461 /* Set the UART Communication parameters */ 00462 if (UART_SetConfig(huart) == HAL_ERROR) 00463 { 00464 return HAL_ERROR; 00465 } 00466 00467 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00468 { 00469 UART_AdvFeatureConfig(huart); 00470 } 00471 00472 /* In multiprocessor mode, the following bits must be kept cleared: 00473 - LINEN and CLKEN bits in the USART_CR2 register, 00474 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ 00475 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); 00476 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); 00477 00478 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) 00479 { 00480 /* If address mark wake up method is chosen, set the USART address node */ 00481 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); 00482 } 00483 00484 /* Set the wake up method by setting the WAKE bit in the CR1 register */ 00485 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); 00486 00487 /* Enable the Peripheral */ 00488 __HAL_UART_ENABLE(huart); 00489 00490 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00491 return (UART_CheckIdleState(huart)); 00492 } 00493 00494 00495 /** 00496 * @brief DeInitialize the UART peripheral. 00497 * @param huart: UART handle. 00498 * @retval HAL status 00499 */ 00500 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) 00501 { 00502 /* Check the UART handle allocation */ 00503 if(huart == NULL) 00504 { 00505 return HAL_ERROR; 00506 } 00507 00508 /* Check the parameters */ 00509 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); 00510 00511 huart->gState = HAL_UART_STATE_BUSY; 00512 00513 /* Disable the Peripheral */ 00514 __HAL_UART_DISABLE(huart); 00515 00516 huart->Instance->CR1 = 0x0; 00517 huart->Instance->CR2 = 0x0; 00518 huart->Instance->CR3 = 0x0; 00519 00520 /* DeInit the low level hardware */ 00521 HAL_UART_MspDeInit(huart); 00522 00523 huart->ErrorCode = HAL_UART_ERROR_NONE; 00524 huart->gState = HAL_UART_STATE_RESET; 00525 huart->RxState = HAL_UART_STATE_RESET; 00526 00527 /* Process Unlock */ 00528 __HAL_UNLOCK(huart); 00529 00530 return HAL_OK; 00531 } 00532 00533 /** 00534 * @brief Initialize the UART MSP. 00535 * @param huart: UART handle. 00536 * @retval None 00537 */ 00538 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) 00539 { 00540 /* Prevent unused argument(s) compilation warning */ 00541 UNUSED(huart); 00542 00543 /* NOTE : This function should not be modified, when the callback is needed, 00544 the HAL_UART_MspInit can be implemented in the user file 00545 */ 00546 } 00547 00548 /** 00549 * @brief DeInitialize the UART MSP. 00550 * @param huart: UART handle. 00551 * @retval None 00552 */ 00553 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) 00554 { 00555 /* Prevent unused argument(s) compilation warning */ 00556 UNUSED(huart); 00557 00558 /* NOTE : This function should not be modified, when the callback is needed, 00559 the HAL_UART_MspDeInit can be implemented in the user file 00560 */ 00561 } 00562 00563 /** 00564 * @} 00565 */ 00566 00567 /** @defgroup UART_Exported_Functions_Group2 IO operation functions 00568 * @brief UART Transmit/Receive functions 00569 * 00570 @verbatim 00571 =============================================================================== 00572 ##### IO operation functions ##### 00573 =============================================================================== 00574 This subsection provides a set of functions allowing to manage the UART asynchronous 00575 and Half duplex data transfers. 00576 00577 (#) There are two mode of transfer: 00578 (+) Blocking mode: The communication is performed in polling mode. 00579 The HAL status of all data processing is returned by the same function 00580 after finishing transfer. 00581 (+) No-Blocking mode: The communication is performed using Interrupts 00582 or DMA, These API's return the HAL status. 00583 The end of the data processing will be indicated through the 00584 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when 00585 using DMA mode. 00586 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks 00587 will be executed respectively at the end of the transmit or Receive process 00588 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected 00589 00590 (#) Blocking mode API's are : 00591 (+) HAL_UART_Transmit() 00592 (+) HAL_UART_Receive() 00593 00594 (#) Non-Blocking mode API's with Interrupt are : 00595 (+) HAL_UART_Transmit_IT() 00596 (+) HAL_UART_Receive_IT() 00597 (+) HAL_UART_IRQHandler() 00598 00599 (#) No-Blocking mode API's with DMA are : 00600 (+) HAL_UART_Transmit_DMA() 00601 (+) HAL_UART_Receive_DMA() 00602 (+) HAL_UART_DMAPause() 00603 (+) HAL_UART_DMAResume() 00604 (+) HAL_UART_DMAStop() 00605 00606 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: 00607 (+) HAL_UART_TxHalfCpltCallback() 00608 (+) HAL_UART_TxCpltCallback() 00609 (+) HAL_UART_RxHalfCpltCallback() 00610 (+) HAL_UART_RxCpltCallback() 00611 (+) HAL_UART_ErrorCallback() 00612 00613 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. 00614 Errors are handled as follows : 00615 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 00616 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . 00617 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, 00618 and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side. 00619 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. 00620 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. 00621 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed. 00622 00623 -@- In the Half duplex communication, it is forbidden to run the transmit 00624 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. 00625 00626 @endverbatim 00627 * @{ 00628 */ 00629 00630 /** 00631 * @brief Send an amount of data in blocking mode. 00632 * @param huart: UART handle. 00633 * @param pData: Pointer to data buffer. 00634 * @param Size: Amount of data to be sent. 00635 * @param Timeout: Timeout duration. 00636 * @retval HAL status 00637 */ 00638 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00639 { 00640 uint16_t* tmp; 00641 uint32_t tickstart = 0; 00642 00643 /* Check that a Tx process is not already ongoing */ 00644 if(huart->gState == HAL_UART_STATE_READY) 00645 { 00646 if((pData == NULL ) || (Size == 0)) 00647 { 00648 return HAL_ERROR; 00649 } 00650 00651 /* Process Locked */ 00652 __HAL_LOCK(huart); 00653 00654 huart->ErrorCode = HAL_UART_ERROR_NONE; 00655 huart->gState = HAL_UART_STATE_BUSY_TX; 00656 00657 /* Init tickstart for timeout managment*/ 00658 tickstart = HAL_GetTick(); 00659 00660 huart->TxXferSize = Size; 00661 huart->TxXferCount = Size; 00662 while(huart->TxXferCount > 0) 00663 { 00664 huart->TxXferCount--; 00665 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) 00666 { 00667 return HAL_TIMEOUT; 00668 } 00669 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 00670 { 00671 tmp = (uint16_t*) pData; 00672 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); 00673 pData += 2; 00674 } 00675 else 00676 { 00677 huart->Instance->TDR = (*pData++ & (uint8_t)0xFF); 00678 } 00679 } 00680 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00681 { 00682 return HAL_TIMEOUT; 00683 } 00684 00685 /* At end of Tx process, restore huart->gState to Ready */ 00686 huart->gState = HAL_UART_STATE_READY; 00687 00688 /* Process Unlocked */ 00689 __HAL_UNLOCK(huart); 00690 00691 return HAL_OK; 00692 } 00693 else 00694 { 00695 return HAL_BUSY; 00696 } 00697 } 00698 00699 /** 00700 * @brief Receive an amount of data in blocking mode. 00701 * @param huart: UART handle. 00702 * @param pData: pointer to data buffer. 00703 * @param Size: amount of data to be received. 00704 * @param Timeout: Timeout duration. 00705 * @retval HAL status 00706 */ 00707 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00708 { 00709 uint16_t* tmp; 00710 uint16_t uhMask; 00711 uint32_t tickstart = 0; 00712 00713 /* Check that a Rx process is not already ongoing */ 00714 if(huart->RxState == HAL_UART_STATE_READY) 00715 { 00716 if((pData == NULL ) || (Size == 0)) 00717 { 00718 return HAL_ERROR; 00719 } 00720 00721 /* Process Locked */ 00722 __HAL_LOCK(huart); 00723 00724 huart->ErrorCode = HAL_UART_ERROR_NONE; 00725 huart->RxState = HAL_UART_STATE_BUSY_RX; 00726 00727 /* Init tickstart for timeout managment*/ 00728 tickstart = HAL_GetTick(); 00729 00730 huart->RxXferSize = Size; 00731 huart->RxXferCount = Size; 00732 00733 /* Computation of UART mask to apply to RDR register */ 00734 UART_MASK_COMPUTATION(huart); 00735 uhMask = huart->Mask; 00736 00737 /* as long as data have to be received */ 00738 while(huart->RxXferCount > 0) 00739 { 00740 huart->RxXferCount--; 00741 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 00742 { 00743 return HAL_TIMEOUT; 00744 } 00745 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 00746 { 00747 tmp = (uint16_t*) pData ; 00748 *tmp = (uint16_t)(huart->Instance->RDR & uhMask); 00749 pData +=2; 00750 } 00751 else 00752 { 00753 *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); 00754 } 00755 } 00756 00757 /* At end of Rx process, restore huart->RxState to Ready */ 00758 huart->RxState = HAL_UART_STATE_READY; 00759 00760 /* Process Unlocked */ 00761 __HAL_UNLOCK(huart); 00762 00763 return HAL_OK; 00764 } 00765 else 00766 { 00767 return HAL_BUSY; 00768 } 00769 } 00770 00771 /** 00772 * @brief Send an amount of data in interrupt mode. 00773 * @param huart: UART handle. 00774 * @param pData: pointer to data buffer. 00775 * @param Size: amount of data to be sent. 00776 * @retval HAL status 00777 */ 00778 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00779 { 00780 /* Check that a Tx process is not already ongoing */ 00781 if(huart->gState == HAL_UART_STATE_READY) 00782 { 00783 if((pData == NULL ) || (Size == 0)) 00784 { 00785 return HAL_ERROR; 00786 } 00787 00788 /* Process Locked */ 00789 __HAL_LOCK(huart); 00790 00791 huart->pTxBuffPtr = pData; 00792 huart->TxXferSize = Size; 00793 huart->TxXferCount = Size; 00794 00795 huart->ErrorCode = HAL_UART_ERROR_NONE; 00796 huart->gState = HAL_UART_STATE_BUSY_TX; 00797 00798 /* Process Unlocked */ 00799 __HAL_UNLOCK(huart); 00800 00801 /* Enable the UART Transmit Data Register Empty Interrupt */ 00802 SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 00803 00804 return HAL_OK; 00805 } 00806 else 00807 { 00808 return HAL_BUSY; 00809 } 00810 } 00811 00812 /** 00813 * @brief Receive an amount of data in interrupt mode. 00814 * @param huart: UART handle. 00815 * @param pData: pointer to data buffer. 00816 * @param Size: amount of data to be received. 00817 * @retval HAL status 00818 */ 00819 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00820 { 00821 /* Check that a Rx process is not already ongoing */ 00822 if(huart->RxState == HAL_UART_STATE_READY) 00823 { 00824 if((pData == NULL ) || (Size == 0)) 00825 { 00826 return HAL_ERROR; 00827 } 00828 00829 /* Process Locked */ 00830 __HAL_LOCK(huart); 00831 00832 huart->pRxBuffPtr = pData; 00833 huart->RxXferSize = Size; 00834 huart->RxXferCount = Size; 00835 00836 /* Computation of UART mask to apply to RDR register */ 00837 UART_MASK_COMPUTATION(huart); 00838 00839 huart->ErrorCode = HAL_UART_ERROR_NONE; 00840 huart->RxState = HAL_UART_STATE_BUSY_RX; 00841 00842 /* Process Unlocked */ 00843 __HAL_UNLOCK(huart); 00844 00845 /* Enable the UART Parity Error Interrupt */ 00846 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 00847 00848 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 00849 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 00850 00851 /* Enable the UART Data Register not empty Interrupt */ 00852 SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE); 00853 00854 return HAL_OK; 00855 } 00856 else 00857 { 00858 return HAL_BUSY; 00859 } 00860 } 00861 00862 /** 00863 * @brief Send an amount of data in DMA mode. 00864 * @param huart: UART handle. 00865 * @param pData: pointer to data buffer. 00866 * @param Size: amount of data to be sent. 00867 * @retval HAL status 00868 */ 00869 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00870 { 00871 uint32_t *tmp; 00872 00873 /* Check that a Tx process is not already ongoing */ 00874 if(huart->gState == HAL_UART_STATE_READY) 00875 { 00876 if((pData == NULL ) || (Size == 0)) 00877 { 00878 return HAL_ERROR; 00879 } 00880 00881 /* Process Locked */ 00882 __HAL_LOCK(huart); 00883 00884 huart->pTxBuffPtr = pData; 00885 huart->TxXferSize = Size; 00886 huart->TxXferCount = Size; 00887 00888 huart->ErrorCode = HAL_UART_ERROR_NONE; 00889 huart->gState = HAL_UART_STATE_BUSY_TX; 00890 00891 /* Set the UART DMA transfer complete callback */ 00892 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; 00893 00894 /* Set the UART DMA Half transfer complete callback */ 00895 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; 00896 00897 /* Set the DMA error callback */ 00898 huart->hdmatx->XferErrorCallback = UART_DMAError; 00899 00900 /* Set the DMA abort callback */ 00901 huart->hdmatx->XferAbortCallback = NULL; 00902 00903 /* Enable the UART transmit DMA channel */ 00904 tmp = (uint32_t*)&pData; 00905 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, Size); 00906 00907 /* Clear the TC flag in the ICR register */ 00908 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); 00909 00910 /* Process Unlocked */ 00911 __HAL_UNLOCK(huart); 00912 00913 /* Enable the DMA transfer for transmit request by setting the DMAT bit 00914 in the UART CR3 register */ 00915 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 00916 00917 return HAL_OK; 00918 } 00919 else 00920 { 00921 return HAL_BUSY; 00922 } 00923 } 00924 00925 /** 00926 * @brief Receive an amount of data in DMA mode. 00927 * @param huart: UART handle. 00928 * @param pData: pointer to data buffer. 00929 * @param Size: amount of data to be received. 00930 * @note When the UART parity is enabled (PCE = 1), the received data contain 00931 * the parity bit (MSB position). 00932 * @retval HAL status 00933 */ 00934 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00935 { 00936 uint32_t *tmp; 00937 00938 /* Check that a Rx process is not already ongoing */ 00939 if(huart->RxState == HAL_UART_STATE_READY) 00940 { 00941 if((pData == NULL ) || (Size == 0)) 00942 { 00943 return HAL_ERROR; 00944 } 00945 00946 /* Process Locked */ 00947 __HAL_LOCK(huart); 00948 00949 huart->pRxBuffPtr = pData; 00950 huart->RxXferSize = Size; 00951 00952 huart->ErrorCode = HAL_UART_ERROR_NONE; 00953 huart->RxState = HAL_UART_STATE_BUSY_RX; 00954 00955 /* Set the UART DMA transfer complete callback */ 00956 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; 00957 00958 /* Set the UART DMA Half transfer complete callback */ 00959 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; 00960 00961 /* Set the DMA error callback */ 00962 huart->hdmarx->XferErrorCallback = UART_DMAError; 00963 00964 /* Set the DMA abort callback */ 00965 huart->hdmarx->XferAbortCallback = NULL; 00966 00967 /* Enable the DMA channel */ 00968 tmp = (uint32_t*)&pData; 00969 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size); 00970 00971 /* Process Unlocked */ 00972 __HAL_UNLOCK(huart); 00973 00974 /* Enable the UART Parity Error Interrupt */ 00975 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 00976 00977 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 00978 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 00979 00980 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 00981 in the UART CR3 register */ 00982 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 00983 00984 return HAL_OK; 00985 } 00986 else 00987 { 00988 return HAL_BUSY; 00989 } 00990 } 00991 00992 /** 00993 * @brief Pause the DMA Transfer. 00994 * @param huart: UART handle. 00995 * @retval HAL status 00996 */ 00997 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) 00998 { 00999 /* Process Locked */ 01000 __HAL_LOCK(huart); 01001 01002 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && 01003 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))) 01004 { 01005 /* Disable the UART DMA Tx request */ 01006 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01007 } 01008 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && 01009 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) 01010 { 01011 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01012 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 01013 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01014 01015 /* Disable the UART DMA Rx request */ 01016 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01017 } 01018 01019 /* Process Unlocked */ 01020 __HAL_UNLOCK(huart); 01021 01022 return HAL_OK; 01023 } 01024 01025 /** 01026 * @brief Resume the DMA Transfer. 01027 * @param huart: UART handle. 01028 * @retval HAL status 01029 */ 01030 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) 01031 { 01032 /* Process Locked */ 01033 __HAL_LOCK(huart); 01034 01035 if(huart->gState == HAL_UART_STATE_BUSY_TX) 01036 { 01037 /* Enable the UART DMA Tx request */ 01038 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01039 } 01040 if(huart->RxState == HAL_UART_STATE_BUSY_RX) 01041 { 01042 /* Clear the Overrun flag before resuming the Rx transfer */ 01043 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); 01044 01045 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01046 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 01047 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 01048 01049 /* Enable the UART DMA Rx request */ 01050 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01051 } 01052 01053 /* Process Unlocked */ 01054 __HAL_UNLOCK(huart); 01055 01056 return HAL_OK; 01057 } 01058 01059 /** 01060 * @brief Stop the DMA Transfer. 01061 * @param huart: UART handle. 01062 * @retval HAL status 01063 */ 01064 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) 01065 { 01066 /* The Lock is not implemented on this API to allow the user application 01067 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / 01068 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback: 01069 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 01070 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 01071 the stream and the corresponding call back is executed. */ 01072 01073 /* Stop UART DMA Tx request if ongoing */ 01074 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && 01075 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))) 01076 { 01077 UART_EndTxTransfer(huart); 01078 01079 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01080 01081 /* Abort the UART DMA Tx channel */ 01082 if(huart->hdmatx != NULL) 01083 { 01084 HAL_DMA_Abort(huart->hdmatx); 01085 } 01086 } 01087 01088 /* Stop UART DMA Rx request if ongoing */ 01089 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && 01090 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) 01091 { 01092 UART_EndRxTransfer(huart); 01093 01094 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01095 01096 /* Abort the UART DMA Rx channel */ 01097 if(huart->hdmarx != NULL) 01098 { 01099 HAL_DMA_Abort(huart->hdmarx); 01100 } 01101 } 01102 01103 return HAL_OK; 01104 } 01105 01106 /** 01107 * @brief Handle UART interrupt request. 01108 * @param huart: UART handle. 01109 * @retval None 01110 */ 01111 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 01112 { 01113 uint32_t isrflags = READ_REG(huart->Instance->ISR); 01114 uint32_t cr1its = READ_REG(huart->Instance->CR1); 01115 uint32_t cr3its; 01116 uint32_t errorflags; 01117 01118 /* If no error occurs */ 01119 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); 01120 if (errorflags == RESET) 01121 { 01122 /* UART in mode Receiver ---------------------------------------------------*/ 01123 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01124 { 01125 UART_Receive_IT(huart); 01126 return; 01127 } 01128 } 01129 01130 /* If some errors occur */ 01131 cr3its = READ_REG(huart->Instance->CR3); 01132 if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET)) 01133 { 01134 /* UART parity error interrupt occurred -------------------------------------*/ 01135 if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) 01136 { 01137 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF); 01138 01139 huart->ErrorCode |= HAL_UART_ERROR_PE; 01140 } 01141 01142 /* UART frame error interrupt occurred --------------------------------------*/ 01143 if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01144 { 01145 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF); 01146 01147 huart->ErrorCode |= HAL_UART_ERROR_FE; 01148 } 01149 01150 /* UART noise error interrupt occurred --------------------------------------*/ 01151 if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01152 { 01153 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF); 01154 01155 huart->ErrorCode |= HAL_UART_ERROR_NE; 01156 } 01157 01158 /* UART Over-Run interrupt occurred -----------------------------------------*/ 01159 if(((isrflags & USART_ISR_ORE) != RESET) && 01160 (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) 01161 { 01162 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); 01163 01164 huart->ErrorCode |= HAL_UART_ERROR_ORE; 01165 } 01166 01167 /* Call UART Error Call back function if need be --------------------------*/ 01168 if(huart->ErrorCode != HAL_UART_ERROR_NONE) 01169 { 01170 /* UART in mode Receiver ---------------------------------------------------*/ 01171 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01172 { 01173 UART_Receive_IT(huart); 01174 } 01175 01176 /* If Overrun error occurs, or if any error occurs in DMA mode reception, 01177 consider error as blocking */ 01178 if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || 01179 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) 01180 { 01181 /* Blocking error : transfer is aborted 01182 Set the UART state ready to be able to start again the process, 01183 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ 01184 UART_EndRxTransfer(huart); 01185 01186 /* Disable the UART DMA Rx request if enabled */ 01187 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 01188 { 01189 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01190 01191 /* Abort the UART DMA Rx channel */ 01192 if(huart->hdmarx != NULL) 01193 { 01194 /* Set the UART DMA Abort callback : 01195 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ 01196 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; 01197 01198 /* Abort DMA RX */ 01199 if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 01200 { 01201 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ 01202 huart->hdmarx->XferAbortCallback(huart->hdmarx); 01203 } 01204 } 01205 else 01206 { 01207 /* Call user error callback */ 01208 HAL_UART_ErrorCallback(huart); 01209 } 01210 } 01211 else 01212 { 01213 /* Call user error callback */ 01214 HAL_UART_ErrorCallback(huart); 01215 } 01216 } 01217 else 01218 { 01219 /* Non Blocking error : transfer could go on. 01220 Error is notified to user through user error callback */ 01221 HAL_UART_ErrorCallback(huart); 01222 huart->ErrorCode = HAL_UART_ERROR_NONE; 01223 } 01224 } 01225 return; 01226 01227 } /* End if some error occurs */ 01228 01229 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ 01230 cr3its = READ_REG(huart->Instance->CR3); 01231 if(((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET)) 01232 { 01233 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF); 01234 /* Set the UART state ready to be able to start again the process */ 01235 huart->gState = HAL_UART_STATE_READY; 01236 huart->RxState = HAL_UART_STATE_READY; 01237 HAL_UARTEx_WakeupCallback(huart); 01238 return; 01239 } 01240 01241 /* UART in mode Transmitter ------------------------------------------------*/ 01242 if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) 01243 { 01244 UART_Transmit_IT(huart); 01245 return; 01246 } 01247 01248 /* UART in mode Transmitter (transmission end) -----------------------------*/ 01249 if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) 01250 { 01251 UART_EndTransmit_IT(huart); 01252 return; 01253 } 01254 01255 } 01256 01257 /** 01258 * @brief Tx Transfer completed callback. 01259 * @param huart: UART handle. 01260 * @retval None 01261 */ 01262 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) 01263 { 01264 /* Prevent unused argument(s) compilation warning */ 01265 UNUSED(huart); 01266 01267 /* NOTE : This function should not be modified, when the callback is needed, 01268 the HAL_UART_TxCpltCallback can be implemented in the user file. 01269 */ 01270 } 01271 01272 /** 01273 * @brief Tx Half Transfer completed callback. 01274 * @param huart: UART handle. 01275 * @retval None 01276 */ 01277 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) 01278 { 01279 /* Prevent unused argument(s) compilation warning */ 01280 UNUSED(huart); 01281 01282 /* NOTE: This function should not be modified, when the callback is needed, 01283 the HAL_UART_TxHalfCpltCallback can be implemented in the user file. 01284 */ 01285 } 01286 01287 /** 01288 * @brief Rx Transfer completed callback. 01289 * @param huart: UART handle. 01290 * @retval None 01291 */ 01292 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 01293 { 01294 /* Prevent unused argument(s) compilation warning */ 01295 UNUSED(huart); 01296 01297 /* NOTE : This function should not be modified, when the callback is needed, 01298 the HAL_UART_RxCpltCallback can be implemented in the user file. 01299 */ 01300 } 01301 01302 /** 01303 * @brief Rx Half Transfer completed callback. 01304 * @param huart: UART handle. 01305 * @retval None 01306 */ 01307 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) 01308 { 01309 /* Prevent unused argument(s) compilation warning */ 01310 UNUSED(huart); 01311 01312 /* NOTE: This function should not be modified, when the callback is needed, 01313 the HAL_UART_RxHalfCpltCallback can be implemented in the user file. 01314 */ 01315 } 01316 01317 /** 01318 * @brief UART error callback. 01319 * @param huart: UART handle. 01320 * @retval None 01321 */ 01322 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) 01323 { 01324 /* Prevent unused argument(s) compilation warning */ 01325 UNUSED(huart); 01326 01327 /* NOTE : This function should not be modified, when the callback is needed, 01328 the HAL_UART_ErrorCallback can be implemented in the user file. 01329 */ 01330 } 01331 01332 /** 01333 * @} 01334 */ 01335 01336 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions 01337 * @brief UART control functions 01338 * 01339 @verbatim 01340 =============================================================================== 01341 ##### Peripheral Control functions ##### 01342 =============================================================================== 01343 [..] 01344 This subsection provides a set of functions allowing to control the UART. 01345 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode 01346 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode 01347 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode 01348 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode 01349 (+) UART_SetConfig() API configures the UART peripheral 01350 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features 01351 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization 01352 (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters 01353 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter 01354 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver 01355 (+) HAL_LIN_SendBreak() API transmits the break characters 01356 @endverbatim 01357 * @{ 01358 */ 01359 01360 /** 01361 * @brief Enable UART in mute mode (does not mean UART enters mute mode; 01362 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). 01363 * @param huart: UART handle. 01364 * @retval HAL status 01365 */ 01366 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) 01367 { 01368 /* Process Locked */ 01369 __HAL_LOCK(huart); 01370 01371 huart->gState = HAL_UART_STATE_BUSY; 01372 01373 /* Enable USART mute mode by setting the MME bit in the CR1 register */ 01374 SET_BIT(huart->Instance->CR1, USART_CR1_MME); 01375 01376 huart->gState = HAL_UART_STATE_READY; 01377 01378 return (UART_CheckIdleState(huart)); 01379 } 01380 01381 /** 01382 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode 01383 * as it may not have been in mute mode at this very moment). 01384 * @param huart: UART handle. 01385 * @retval HAL status 01386 */ 01387 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) 01388 { 01389 /* Process Locked */ 01390 __HAL_LOCK(huart); 01391 01392 huart->gState = HAL_UART_STATE_BUSY; 01393 01394 /* Disable USART mute mode by clearing the MME bit in the CR1 register */ 01395 CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); 01396 01397 huart->gState = HAL_UART_STATE_READY; 01398 01399 return (UART_CheckIdleState(huart)); 01400 } 01401 01402 /** 01403 * @brief Enter UART mute mode (means UART actually enters mute mode). 01404 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. 01405 * @param huart: UART handle. 01406 * @retval None 01407 */ 01408 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) 01409 { 01410 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); 01411 } 01412 01413 /** 01414 * @brief Enable the UART transmitter and disable the UART receiver. 01415 * @param huart: UART handle. 01416 * @retval HAL status 01417 */ 01418 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) 01419 { 01420 /* Process Locked */ 01421 __HAL_LOCK(huart); 01422 huart->gState = HAL_UART_STATE_BUSY; 01423 01424 /* Clear TE and RE bits */ 01425 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); 01426 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ 01427 SET_BIT(huart->Instance->CR1, USART_CR1_TE); 01428 01429 huart->gState = HAL_UART_STATE_READY; 01430 01431 /* Process Unlocked */ 01432 __HAL_UNLOCK(huart); 01433 01434 return HAL_OK; 01435 } 01436 01437 /** 01438 * @brief Enable the UART receiver and disable the UART transmitter. 01439 * @param huart: UART handle. 01440 * @retval HAL status. 01441 */ 01442 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) 01443 { 01444 /* Process Locked */ 01445 __HAL_LOCK(huart); 01446 huart->gState = HAL_UART_STATE_BUSY; 01447 01448 /* Clear TE and RE bits */ 01449 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); 01450 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ 01451 SET_BIT(huart->Instance->CR1, USART_CR1_RE); 01452 01453 huart->gState = HAL_UART_STATE_READY; 01454 /* Process Unlocked */ 01455 __HAL_UNLOCK(huart); 01456 01457 return HAL_OK; 01458 } 01459 01460 01461 /** 01462 * @brief Transmit break characters. 01463 * @param huart: UART handle. 01464 * @retval HAL status 01465 */ 01466 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) 01467 { 01468 /* Check the parameters */ 01469 assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); 01470 01471 /* Process Locked */ 01472 __HAL_LOCK(huart); 01473 01474 huart->gState = HAL_UART_STATE_BUSY; 01475 01476 /* Send break characters */ 01477 huart->Instance->RQR |= UART_SENDBREAK_REQUEST; 01478 01479 huart->gState = HAL_UART_STATE_READY; 01480 01481 /* Process Unlocked */ 01482 __HAL_UNLOCK(huart); 01483 01484 return HAL_OK; 01485 } 01486 01487 01488 /** 01489 * @} 01490 */ 01491 01492 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions 01493 * @brief UART Peripheral State functions 01494 * 01495 @verbatim 01496 ============================================================================== 01497 ##### Peripheral State and Error functions ##### 01498 ============================================================================== 01499 [..] 01500 This subsection provides functions allowing to : 01501 (+) Return the UART handle state. 01502 (+) Return the UART handle error code 01503 01504 @endverbatim 01505 * @{ 01506 */ 01507 01508 /** 01509 * @brief Return the UART handle state. 01510 * @param huart Pointer to a UART_HandleTypeDef structure that contains 01511 * the configuration information for the specified UART. 01512 * @retval HAL state 01513 */ 01514 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) 01515 { 01516 uint32_t temp1= 0x00, temp2 = 0x00; 01517 temp1 = huart->gState; 01518 temp2 = huart->RxState; 01519 01520 return (HAL_UART_StateTypeDef)(temp1 | temp2); 01521 } 01522 01523 /** 01524 * @brief Return the UART handle error code. 01525 * @param huart Pointer to a UART_HandleTypeDef structure that contains 01526 * the configuration information for the specified UART. 01527 * @retval UART Error Code 01528 */ 01529 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) 01530 { 01531 return huart->ErrorCode; 01532 } 01533 /** 01534 * @} 01535 */ 01536 01537 /** 01538 * @} 01539 */ 01540 01541 /** @defgroup UART_Private_Functions UART Private Functions 01542 * @{ 01543 */ 01544 01545 /** 01546 * @brief Configure the UART peripheral. 01547 * @param huart: UART handle. 01548 * @retval HAL status 01549 */ 01550 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) 01551 { 01552 uint32_t tmpreg = 0x00000000; 01553 UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED; 01554 uint16_t brrtemp = 0x0000; 01555 uint16_t usartdiv = 0x0000; 01556 HAL_StatusTypeDef ret = HAL_OK; 01557 01558 /* Check the parameters */ 01559 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); 01560 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); 01561 if(UART_INSTANCE_LOWPOWER(huart)) 01562 { 01563 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits)); 01564 } 01565 else 01566 { 01567 assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); 01568 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling)); 01569 } 01570 01571 assert_param(IS_UART_PARITY(huart->Init.Parity)); 01572 assert_param(IS_UART_MODE(huart->Init.Mode)); 01573 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); 01574 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); 01575 01576 01577 /*-------------------------- USART CR1 Configuration -----------------------*/ 01578 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure 01579 * the UART Word Length, Parity, Mode and oversampling: 01580 * set the M bits according to huart->Init.WordLength value 01581 * set PCE and PS bits according to huart->Init.Parity value 01582 * set TE and RE bits according to huart->Init.Mode value 01583 * set OVER8 bit according to huart->Init.OverSampling value */ 01584 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ; 01585 MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg); 01586 01587 /*-------------------------- USART CR2 Configuration -----------------------*/ 01588 /* Configure the UART Stop Bits: Set STOP[13:12] bits according 01589 * to huart->Init.StopBits value */ 01590 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); 01591 01592 /*-------------------------- USART CR3 Configuration -----------------------*/ 01593 /* Configure 01594 * - UART HardWare Flow Control: set CTSE and RTSE bits according 01595 * to huart->Init.HwFlowCtl value 01596 * - one-bit sampling method versus three samples' majority rule according 01597 * to huart->Init.OneBitSampling (not applicable to LPUART) */ 01598 tmpreg = (uint32_t)huart->Init.HwFlowCtl; 01599 if (!(UART_INSTANCE_LOWPOWER(huart))) 01600 { 01601 tmpreg |= huart->Init.OneBitSampling; 01602 } 01603 MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), tmpreg); 01604 01605 /*-------------------------- USART BRR Configuration -----------------------*/ 01606 UART_GETCLOCKSOURCE(huart, clocksource); 01607 01608 /* Check LPUART instance */ 01609 if(UART_INSTANCE_LOWPOWER(huart)) 01610 { 01611 /* Retrieve frequency clock */ 01612 tmpreg = 0; 01613 01614 switch (clocksource) 01615 { 01616 case UART_CLOCKSOURCE_PCLK1: 01617 tmpreg = HAL_RCC_GetPCLK1Freq(); 01618 break; 01619 case UART_CLOCKSOURCE_HSI: 01620 tmpreg = (uint32_t) HSI_VALUE; 01621 break; 01622 case UART_CLOCKSOURCE_SYSCLK: 01623 tmpreg = HAL_RCC_GetSysClockFreq(); 01624 break; 01625 case UART_CLOCKSOURCE_LSE: 01626 tmpreg = (uint32_t) LSE_VALUE; 01627 break; 01628 case UART_CLOCKSOURCE_UNDEFINED: 01629 default: 01630 ret = HAL_ERROR; 01631 break; 01632 } 01633 01634 /* if proper clock source reported */ 01635 if (tmpreg != 0) 01636 { 01637 /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ 01638 if ( (tmpreg < (3 * huart->Init.BaudRate) ) || 01639 (tmpreg > (4096 * huart->Init.BaudRate) )) 01640 { 01641 ret = HAL_ERROR; 01642 } 01643 else 01644 { 01645 switch (clocksource) 01646 { 01647 case UART_CLOCKSOURCE_PCLK1: 01648 tmpreg = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); 01649 break; 01650 case UART_CLOCKSOURCE_HSI: 01651 tmpreg = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate)); 01652 break; 01653 case UART_CLOCKSOURCE_SYSCLK: 01654 tmpreg = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); 01655 break; 01656 case UART_CLOCKSOURCE_LSE: 01657 tmpreg = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate)); 01658 break; 01659 case UART_CLOCKSOURCE_UNDEFINED: 01660 default: 01661 ret = HAL_ERROR; 01662 break; 01663 } 01664 01665 if ((tmpreg >= UART_LPUART_BRR_MIN) && (tmpreg <= UART_LPUART_BRR_MAX)) 01666 { 01667 huart->Instance->BRR = tmpreg; 01668 } 01669 else 01670 { 01671 ret = HAL_ERROR; 01672 } 01673 } /* if ( (tmpreg < (3 * huart->Init.BaudRate) ) || (tmpreg > (4096 * huart->Init.BaudRate) )) */ 01674 } /* if (tmpreg != 0) */ 01675 } 01676 /* Check UART Over Sampling to set Baud Rate Register */ 01677 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) 01678 { 01679 switch (clocksource) 01680 { 01681 case UART_CLOCKSOURCE_PCLK1: 01682 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); 01683 break; 01684 case UART_CLOCKSOURCE_PCLK2: 01685 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); 01686 break; 01687 case UART_CLOCKSOURCE_HSI: 01688 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate)); 01689 break; 01690 case UART_CLOCKSOURCE_SYSCLK: 01691 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); 01692 break; 01693 case UART_CLOCKSOURCE_LSE: 01694 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate)); 01695 break; 01696 case UART_CLOCKSOURCE_UNDEFINED: 01697 default: 01698 ret = HAL_ERROR; 01699 break; 01700 } 01701 01702 brrtemp = usartdiv & 0xFFF0; 01703 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U); 01704 huart->Instance->BRR = brrtemp; 01705 } 01706 else 01707 { 01708 switch (clocksource) 01709 { 01710 case UART_CLOCKSOURCE_PCLK1: 01711 huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); 01712 break; 01713 case UART_CLOCKSOURCE_PCLK2: 01714 huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); 01715 break; 01716 case UART_CLOCKSOURCE_HSI: 01717 huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate)); 01718 break; 01719 case UART_CLOCKSOURCE_SYSCLK: 01720 huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); 01721 break; 01722 case UART_CLOCKSOURCE_LSE: 01723 huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate)); 01724 break; 01725 case UART_CLOCKSOURCE_UNDEFINED: 01726 default: 01727 ret = HAL_ERROR; 01728 break; 01729 } 01730 } 01731 01732 return ret; 01733 01734 } 01735 01736 /** 01737 * @brief Configure the UART peripheral advanced features. 01738 * @param huart: UART handle. 01739 * @retval None 01740 */ 01741 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) 01742 { 01743 /* Check whether the set of advanced features to configure is properly set */ 01744 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); 01745 01746 /* if required, configure TX pin active level inversion */ 01747 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) 01748 { 01749 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); 01750 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); 01751 } 01752 01753 /* if required, configure RX pin active level inversion */ 01754 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) 01755 { 01756 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); 01757 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); 01758 } 01759 01760 /* if required, configure data inversion */ 01761 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) 01762 { 01763 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); 01764 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); 01765 } 01766 01767 /* if required, configure RX/TX pins swap */ 01768 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) 01769 { 01770 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); 01771 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); 01772 } 01773 01774 /* if required, configure RX overrun detection disabling */ 01775 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) 01776 { 01777 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); 01778 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); 01779 } 01780 01781 /* if required, configure DMA disabling on reception error */ 01782 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) 01783 { 01784 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); 01785 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); 01786 } 01787 01788 /* if required, configure auto Baud rate detection scheme */ 01789 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) 01790 { 01791 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); 01792 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); 01793 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); 01794 /* set auto Baudrate detection parameters if detection is enabled */ 01795 if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) 01796 { 01797 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); 01798 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); 01799 } 01800 } 01801 01802 /* if required, configure MSB first on communication line */ 01803 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) 01804 { 01805 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); 01806 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); 01807 } 01808 } 01809 01810 /** 01811 * @brief Check the UART Idle State. 01812 * @param huart: UART handle. 01813 * @retval HAL status 01814 */ 01815 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) 01816 { 01817 uint32_t tickstart = 0; 01818 01819 /* Initialize the UART ErrorCode */ 01820 huart->ErrorCode = HAL_UART_ERROR_NONE; 01821 01822 /* Init tickstart for timeout managment*/ 01823 tickstart = HAL_GetTick(); 01824 01825 /* Check if the Transmitter is enabled */ 01826 if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 01827 { 01828 /* Wait until TEACK flag is set */ 01829 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 01830 { 01831 /* Timeout occurred */ 01832 return HAL_TIMEOUT; 01833 } 01834 } 01835 /* Check if the Receiver is enabled */ 01836 if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 01837 { 01838 /* Wait until REACK flag is set */ 01839 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 01840 { 01841 /* Timeout occurred */ 01842 return HAL_TIMEOUT; 01843 } 01844 } 01845 01846 /* Initialize the UART State */ 01847 huart->gState= HAL_UART_STATE_READY; 01848 huart->RxState= HAL_UART_STATE_READY; 01849 01850 /* Process Unlocked */ 01851 __HAL_UNLOCK(huart); 01852 01853 return HAL_OK; 01854 } 01855 01856 /** 01857 * @brief Handle UART Communication Timeout. 01858 * @param huart: UART handle. 01859 * @param Flag Specifies the UART flag to check 01860 * @param Status Flag status (SET or RESET) 01861 * @param Tickstart Tick start value 01862 * @param Timeout Timeout duration 01863 * @retval HAL status 01864 */ 01865 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) 01866 { 01867 /* Wait until flag is set */ 01868 while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) 01869 { 01870 /* Check for the Timeout */ 01871 if(Timeout != HAL_MAX_DELAY) 01872 { 01873 if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) 01874 { 01875 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 01876 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 01877 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01878 01879 huart->gState = HAL_UART_STATE_READY; 01880 huart->RxState = HAL_UART_STATE_READY; 01881 01882 /* Process Unlocked */ 01883 __HAL_UNLOCK(huart); 01884 01885 return HAL_TIMEOUT; 01886 } 01887 } 01888 } 01889 return HAL_OK; 01890 } 01891 01892 01893 /** 01894 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). 01895 * @param huart: UART handle. 01896 * @retval None 01897 */ 01898 static void UART_EndTxTransfer(UART_HandleTypeDef *huart) 01899 { 01900 /* At end of Tx process, restore huart->gState to Ready */ 01901 huart->gState = HAL_UART_STATE_READY; 01902 01903 /* Disable TXEIE and TCIE interrupts */ 01904 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 01905 } 01906 01907 01908 /** 01909 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). 01910 * @param huart: UART handle. 01911 * @retval None 01912 */ 01913 static void UART_EndRxTransfer(UART_HandleTypeDef *huart) 01914 { 01915 /* At end of Rx process, restore huart->RxState to Ready */ 01916 huart->RxState = HAL_UART_STATE_READY; 01917 01918 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01919 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01920 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01921 } 01922 01923 01924 /** 01925 * @brief DMA UART transmit process complete callback. 01926 * @param hdma: DMA handle. 01927 * @retval None 01928 */ 01929 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) 01930 { 01931 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01932 01933 /* DMA Normal mode */ 01934 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01935 { 01936 huart->TxXferCount = 0; 01937 01938 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 01939 in the UART CR3 register */ 01940 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01941 01942 /* Enable the UART Transmit Complete Interrupt */ 01943 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 01944 } 01945 /* DMA Circular mode */ 01946 else 01947 { 01948 HAL_UART_TxCpltCallback(huart); 01949 } 01950 01951 } 01952 01953 /** 01954 * @brief DMA UART transmit process half complete callback. 01955 * @param hdma : DMA handle. 01956 * @retval None 01957 */ 01958 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01959 { 01960 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 01961 01962 HAL_UART_TxHalfCpltCallback(huart); 01963 } 01964 01965 /** 01966 * @brief DMA UART receive process complete callback. 01967 * @param hdma: DMA handle. 01968 * @retval None 01969 */ 01970 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 01971 { 01972 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01973 01974 /* DMA Normal mode */ 01975 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01976 { 01977 huart->RxXferCount = 0; 01978 01979 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01980 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 01981 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01982 01983 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 01984 in the UART CR3 register */ 01985 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01986 01987 /* At end of Rx process, restore huart->RxState to Ready */ 01988 huart->RxState = HAL_UART_STATE_READY; 01989 } 01990 01991 HAL_UART_RxCpltCallback(huart); 01992 } 01993 01994 /** 01995 * @brief DMA UART receive process half complete callback. 01996 * @param hdma : DMA handle. 01997 * @retval None 01998 */ 01999 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 02000 { 02001 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 02002 02003 HAL_UART_RxHalfCpltCallback(huart); 02004 } 02005 02006 /** 02007 * @brief DMA UART communication error callback. 02008 * @param hdma: DMA handle. 02009 * @retval None 02010 */ 02011 static void UART_DMAError(DMA_HandleTypeDef *hdma) 02012 { 02013 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 02014 huart->RxXferCount = 0; 02015 huart->TxXferCount = 0; 02016 02017 /* Stop UART DMA Tx request if ongoing */ 02018 if ( (huart->gState == HAL_UART_STATE_BUSY_TX) 02019 &&(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) ) 02020 { 02021 UART_EndTxTransfer(huart); 02022 } 02023 02024 /* Stop UART DMA Rx request if ongoing */ 02025 if ( (huart->RxState == HAL_UART_STATE_BUSY_RX) 02026 &&(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ) 02027 { 02028 UART_EndRxTransfer(huart); 02029 } 02030 02031 huart->ErrorCode |= HAL_UART_ERROR_DMA; 02032 HAL_UART_ErrorCallback(huart); 02033 } 02034 02035 /** 02036 * @brief DMA UART communication abort callback, when call by HAL services on Error 02037 * (To be called at end of DMA Abort procedure following error occurrence). 02038 * @param hdma: DMA handle. 02039 * @retval None 02040 */ 02041 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) 02042 { 02043 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 02044 huart->RxXferCount = 0; 02045 huart->TxXferCount = 0; 02046 02047 HAL_UART_ErrorCallback(huart); 02048 } 02049 02050 /** 02051 * @brief Send an amount of data in interrupt mode. 02052 * @note Function is called under interruption only, once 02053 * interruptions have been enabled by HAL_UART_Transmit_IT(). 02054 * @param huart: UART handle. 02055 * @retval HAL status 02056 */ 02057 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) 02058 { 02059 uint16_t* tmp; 02060 02061 /* Check that a Tx process is ongoing */ 02062 if (huart->gState == HAL_UART_STATE_BUSY_TX) 02063 { 02064 02065 if(huart->TxXferCount == 0) 02066 { 02067 /* Disable the UART Transmit Data Register Empty Interrupt */ 02068 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 02069 02070 /* Enable the UART Transmit Complete Interrupt */ 02071 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 02072 02073 return HAL_OK; 02074 } 02075 else 02076 { 02077 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 02078 { 02079 tmp = (uint16_t*) huart->pTxBuffPtr; 02080 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF); 02081 huart->pTxBuffPtr += 2; 02082 } 02083 else 02084 { 02085 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF); 02086 } 02087 02088 huart->TxXferCount--; 02089 02090 return HAL_OK; 02091 } 02092 } 02093 else 02094 { 02095 return HAL_BUSY; 02096 } 02097 } 02098 02099 02100 /** 02101 * @brief Wrap up transmission in non-blocking mode. 02102 * @param huart: pointer to a UART_HandleTypeDef structure that contains 02103 * the configuration information for the specified UART module. 02104 * @retval HAL status 02105 */ 02106 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) 02107 { 02108 /* Disable the UART Transmit Complete Interrupt */ 02109 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); 02110 02111 /* Tx process is ended, restore huart->gState to Ready */ 02112 huart->gState = HAL_UART_STATE_READY; 02113 02114 HAL_UART_TxCpltCallback(huart); 02115 02116 return HAL_OK; 02117 } 02118 02119 02120 /** 02121 * @brief Receive an amount of data in interrupt mode. 02122 * @note Function is called under interruption only, once 02123 * interruptions have been enabled by HAL_UART_Receive_IT() 02124 * @param huart: UART handle. 02125 * @retval HAL status 02126 */ 02127 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) 02128 { 02129 uint16_t* tmp; 02130 uint16_t uhMask = huart->Mask; 02131 uint16_t uhdata; 02132 02133 /* Check that a Rx process is ongoing */ 02134 if(huart->RxState == HAL_UART_STATE_BUSY_RX) 02135 { 02136 uhdata = (uint16_t) READ_REG(huart->Instance->RDR); 02137 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 02138 { 02139 tmp = (uint16_t*) huart->pRxBuffPtr ; 02140 *tmp = (uint16_t)(uhdata & uhMask); 02141 huart->pRxBuffPtr +=2; 02142 } 02143 else 02144 { 02145 *huart->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask); 02146 } 02147 02148 if(--huart->RxXferCount == 0) 02149 { 02150 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ 02151 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 02152 02153 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 02154 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 02155 02156 /* Rx process is completed, restore huart->RxState to Ready */ 02157 huart->RxState = HAL_UART_STATE_READY; 02158 02159 HAL_UART_RxCpltCallback(huart); 02160 02161 return HAL_OK; 02162 } 02163 02164 return HAL_OK; 02165 } 02166 else 02167 { 02168 /* Clear RXNE interrupt flag */ 02169 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 02170 02171 return HAL_BUSY; 02172 } 02173 } 02174 02175 /** 02176 * @} 02177 */ 02178 02179 #endif /* HAL_UART_MODULE_ENABLED */ 02180 /** 02181 * @} 02182 */ 02183 02184 /** 02185 * @} 02186 */ 02187 02188 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 10:59:59 by
