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