stm32f4xx_hal_uart.c
1 /** 2 ****************************************************************************** 3 * @file stm32f4xx_hal_uart.c 4 * @author MCD Application Team 5 * @brief UART HAL module driver. 6 * This file provides firmware functions to manage the following 7 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). 8 * + Initialization and de-initialization functions 9 * + IO operation functions 10 * + Peripheral Control functions 11 * + Peripheral State and Errors functions 12 * 13 ****************************************************************************** 14 * @attention 15 * 16 * Copyright (c) 2016 STMicroelectronics. 17 * All rights reserved. 18 * 19 * This software is licensed under terms that can be found in the LICENSE file 20 * in the root directory of this software component. 21 * If no LICENSE file comes with this software, it is provided AS-IS. 22 * 23 ****************************************************************************** 24 @verbatim 25 ============================================================================== 26 ##### How to use this driver ##### 27 ============================================================================== 28 [..] 29 The UART HAL driver can be used as follows: 30 31 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). 32 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: 33 (##) Enable the USARTx interface clock. 34 (##) UART pins configuration: 35 (+++) Enable the clock for the UART GPIOs. 36 (+++) Configure the UART TX/RX pins as alternate function pull-up. 37 (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() 38 and HAL_UART_Receive_IT() APIs): 39 (+++) Configure the USARTx interrupt priority. 40 (+++) Enable the NVIC USART IRQ handle. 41 (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() 42 and HAL_UART_Receive_DMA() APIs): 43 (+++) Declare a DMA handle structure for the Tx/Rx stream. 44 (+++) Enable the DMAx interface clock. 45 (+++) Configure the declared DMA handle structure with the required 46 Tx/Rx parameters. 47 (+++) Configure the DMA Tx/Rx stream. 48 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. 49 (+++) Configure the priority and enable the NVIC for the transfer complete 50 interrupt on the DMA Tx/Rx stream. 51 (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle 52 (used for last byte sending completion detection in DMA non circular mode) 53 54 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware 55 flow control and Mode(Receiver/Transmitter) in the huart Init structure. 56 57 (#) For the UART asynchronous mode, initialize the UART registers by calling 58 the HAL_UART_Init() API. 59 60 (#) For the UART Half duplex mode, initialize the UART registers by calling 61 the HAL_HalfDuplex_Init() API. 62 63 (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API. 64 65 (#) For the Multi-Processor mode, initialize the UART registers by calling 66 the HAL_MultiProcessor_Init() API. 67 68 [..] 69 (@) The specific UART interrupts (Transmission complete interrupt, 70 RXNE interrupt and Error Interrupts) will be managed using the macros 71 __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit 72 and receive process. 73 74 [..] 75 (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the 76 low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized 77 HAL_UART_MspInit() API. 78 79 ##### Callback registration ##### 80 ================================== 81 82 [..] 83 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1 84 allows the user to configure dynamically the driver callbacks. 85 86 [..] 87 Use Function HAL_UART_RegisterCallback() to register a user callback. 88 Function HAL_UART_RegisterCallback() allows to register following callbacks: 89 (+) TxHalfCpltCallback : Tx Half Complete Callback. 90 (+) TxCpltCallback : Tx Complete Callback. 91 (+) RxHalfCpltCallback : Rx Half Complete Callback. 92 (+) RxCpltCallback : Rx Complete Callback. 93 (+) ErrorCallback : Error Callback. 94 (+) AbortCpltCallback : Abort Complete Callback. 95 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 96 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 97 (+) MspInitCallback : UART MspInit. 98 (+) MspDeInitCallback : UART MspDeInit. 99 This function takes as parameters the HAL peripheral handle, the Callback ID 100 and a pointer to the user callback function. 101 102 [..] 103 Use function HAL_UART_UnRegisterCallback() to reset a callback to the default 104 weak (surcharged) function. 105 HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, 106 and the Callback ID. 107 This function allows to reset following callbacks: 108 (+) TxHalfCpltCallback : Tx Half Complete Callback. 109 (+) TxCpltCallback : Tx Complete Callback. 110 (+) RxHalfCpltCallback : Rx Half Complete Callback. 111 (+) RxCpltCallback : Rx Complete Callback. 112 (+) ErrorCallback : Error Callback. 113 (+) AbortCpltCallback : Abort Complete Callback. 114 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 115 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 116 (+) MspInitCallback : UART MspInit. 117 (+) MspDeInitCallback : UART MspDeInit. 118 119 [..] 120 For specific callback RxEventCallback, use dedicated registration/reset functions: 121 respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback(). 122 123 [..] 124 By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET 125 all callbacks are set to the corresponding weak (surcharged) functions: 126 examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback(). 127 Exception done for MspInit and MspDeInit functions that are respectively 128 reset to the legacy weak (surcharged) functions in the HAL_UART_Init() 129 and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). 130 If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit() 131 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 132 133 [..] 134 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only. 135 Exception done MspInit/MspDeInit that can be registered/unregistered 136 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user) 137 MspInit/DeInit callbacks can be used during the Init/DeInit. 138 In that case first register the MspInit/MspDeInit user callbacks 139 using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit() 140 or HAL_UART_Init() function. 141 142 [..] 143 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or 144 not defined, the callback registration feature is not available 145 and weak (surcharged) callbacks are used. 146 147 [..] 148 Three operation modes are available within this driver : 149 150 *** Polling mode IO operation *** 151 ================================= 152 [..] 153 (+) Send an amount of data in blocking mode using HAL_UART_Transmit() 154 (+) Receive an amount of data in blocking mode using HAL_UART_Receive() 155 156 *** Interrupt mode IO operation *** 157 =================================== 158 [..] 159 (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT() 160 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can 161 add his own code by customization of function pointer HAL_UART_TxCpltCallback 162 (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT() 163 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can 164 add his own code by customization of function pointer HAL_UART_RxCpltCallback 165 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can 166 add his own code by customization of function pointer HAL_UART_ErrorCallback 167 168 *** DMA mode IO operation *** 169 ============================== 170 [..] 171 (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() 172 (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can 173 add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback 174 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can 175 add his own code by customization of function pointer HAL_UART_TxCpltCallback 176 (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA() 177 (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can 178 add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback 179 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can 180 add his own code by customization of function pointer HAL_UART_RxCpltCallback 181 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can 182 add his own code by customization of function pointer HAL_UART_ErrorCallback 183 (+) Pause the DMA Transfer using HAL_UART_DMAPause() 184 (+) Resume the DMA Transfer using HAL_UART_DMAResume() 185 (+) Stop the DMA Transfer using HAL_UART_DMAStop() 186 187 188 [..] This subsection also provides a set of additional functions providing enhanced reception 189 services to user. (For example, these functions allow application to handle use cases 190 where number of data to be received is unknown). 191 192 (#) Compared to standard reception services which only consider number of received 193 data elements as reception completion criteria, these functions also consider additional events 194 as triggers for updating reception status to caller : 195 (+) Detection of inactivity period (RX line has not been active for a given period). 196 (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) 197 for 1 frame time, after last received byte. 198 199 (#) There are two mode of transfer: 200 (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received, 201 or till IDLE event occurs. Reception is handled only during function execution. 202 When function exits, no data reception could occur. HAL status and number of actually received data elements, 203 are returned by function after finishing transfer. 204 (+) Non-Blocking mode: The reception is performed using Interrupts or DMA. 205 These API's return the HAL status. 206 The end of the data processing will be indicated through the 207 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. 208 The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process 209 The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected. 210 211 (#) Blocking mode API: 212 (+) HAL_UARTEx_ReceiveToIdle() 213 214 (#) Non-Blocking mode API with Interrupt: 215 (+) HAL_UARTEx_ReceiveToIdle_IT() 216 217 (#) Non-Blocking mode API with DMA: 218 (+) HAL_UARTEx_ReceiveToIdle_DMA() 219 220 221 *** UART HAL driver macros list *** 222 ============================================= 223 [..] 224 Below the list of most used macros in UART HAL driver. 225 226 (+) __HAL_UART_ENABLE: Enable the UART peripheral 227 (+) __HAL_UART_DISABLE: Disable the UART peripheral 228 (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not 229 (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag 230 (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt 231 (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt 232 (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not 233 234 [..] 235 (@) You can refer to the UART HAL driver header file for more useful macros 236 237 @endverbatim 238 [..] 239 (@) Additional remark: If the parity is enabled, then the MSB bit of the data written 240 in the data register is transmitted but is changed by the parity bit. 241 Depending on the frame length defined by the M bit (8-bits or 9-bits), 242 the possible UART frame formats are as listed in the following table: 243 +-------------------------------------------------------------+ 244 | M bit | PCE bit | UART frame | 245 |---------------------|---------------------------------------| 246 | 0 | 0 | | SB | 8 bit data | STB | | 247 |---------|-----------|---------------------------------------| 248 | 0 | 1 | | SB | 7 bit data | PB | STB | | 249 |---------|-----------|---------------------------------------| 250 | 1 | 0 | | SB | 9 bit data | STB | | 251 |---------|-----------|---------------------------------------| 252 | 1 | 1 | | SB | 8 bit data | PB | STB | | 253 +-------------------------------------------------------------+ 254 ****************************************************************************** 255 */ 256 257 /* Includes ------------------------------------------------------------------*/ 258 #include "stm32f4xx_hal.h" 259 260 /** @addtogroup STM32F4xx_HAL_Driver 261 * @{ 262 */ 263 264 /** @defgroup UART UART 265 * @brief HAL UART module driver 266 * @{ 267 */ 268 #ifdef HAL_UART_MODULE_ENABLED 269 270 /* Private typedef -----------------------------------------------------------*/ 271 /* Private define ------------------------------------------------------------*/ 272 /** @addtogroup UART_Private_Constants 273 * @{ 274 */ 275 /** 276 * @} 277 */ 278 /* Private macro -------------------------------------------------------------*/ 279 /* Private variables ---------------------------------------------------------*/ 280 /* Private function prototypes -----------------------------------------------*/ 281 /** @addtogroup UART_Private_Functions UART Private Functions 282 * @{ 283 */ 284 285 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 286 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart); 287 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 288 static void UART_EndTxTransfer(UART_HandleTypeDef *huart); 289 static void UART_EndRxTransfer(UART_HandleTypeDef *huart); 290 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); 291 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 292 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 293 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 294 static void UART_DMAError(DMA_HandleTypeDef *hdma); 295 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); 296 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); 297 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); 298 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 299 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 300 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); 301 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); 302 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); 303 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, 304 uint32_t Tickstart, uint32_t Timeout); 305 static void UART_SetConfig(UART_HandleTypeDef *huart); 306 307 /** 308 * @} 309 */ 310 311 /* Exported functions ---------------------------------------------------------*/ 312 /** @defgroup UART_Exported_Functions UART Exported Functions 313 * @{ 314 */ 315 316 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions 317 * @brief Initialization and Configuration functions 318 * 319 @verbatim 320 =============================================================================== 321 ##### Initialization and Configuration functions ##### 322 =============================================================================== 323 [..] 324 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 325 in asynchronous mode. 326 (+) For the asynchronous mode only these parameters can be configured: 327 (++) Baud Rate 328 (++) Word Length 329 (++) Stop Bit 330 (++) Parity: If the parity is enabled, then the MSB bit of the data written 331 in the data register is transmitted but is changed by the parity bit. 332 Depending on the frame length defined by the M bit (8-bits or 9-bits), 333 please refer to Reference manual for possible UART frame formats. 334 (++) Hardware flow control 335 (++) Receiver/transmitter modes 336 (++) Over Sampling Method 337 [..] 338 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs 339 follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration 340 procedures (details for the procedures are available in reference manual 341 (RM0430 for STM32F4X3xx MCUs and RM0402 for STM32F412xx MCUs 342 RM0383 for STM32F411xC/E MCUs and RM0401 for STM32F410xx MCUs 343 RM0090 for STM32F4X5xx/STM32F4X7xx/STM32F429xx/STM32F439xx MCUs 344 RM0390 for STM32F446xx MCUs and RM0386 for STM32F469xx/STM32F479xx MCUs)). 345 346 @endverbatim 347 * @{ 348 */ 349 350 /** 351 * @brief Initializes the UART mode according to the specified parameters in 352 * the UART_InitTypeDef and create the associated handle. 353 * @param huart Pointer to a UART_HandleTypeDef structure that contains 354 * the configuration information for the specified UART module. 355 * @retval HAL status 356 */ 357 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) 358 { 359 /* Check the UART handle allocation */ 360 if (huart == NULL) 361 { 362 return HAL_ERROR; 363 } 364 365 /* Check the parameters */ 366 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) 367 { 368 /* The hardware flow control is available only for USART1, USART2, USART3 and USART6. 369 Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5. 370 */ 371 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); 372 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); 373 } 374 else 375 { 376 assert_param(IS_UART_INSTANCE(huart->Instance)); 377 } 378 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); 379 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); 380 381 if (huart->gState == HAL_UART_STATE_RESET) 382 { 383 /* Allocate lock resource and initialize it */ 384 huart->Lock = HAL_UNLOCKED; 385 386 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 387 UART_InitCallbacksToDefault(huart); 388 389 if (huart->MspInitCallback == NULL) 390 { 391 huart->MspInitCallback = HAL_UART_MspInit; 392 } 393 394 /* Init the low level hardware */ 395 huart->MspInitCallback(huart); 396 #else 397 /* Init the low level hardware : GPIO, CLOCK */ 398 HAL_UART_MspInit(huart); 399 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 400 } 401 402 huart->gState = HAL_UART_STATE_BUSY; 403 404 /* Disable the peripheral */ 405 __HAL_UART_DISABLE(huart); 406 407 /* Set the UART Communication parameters */ 408 UART_SetConfig(huart); 409 410 /* In asynchronous mode, the following bits must be kept cleared: 411 - LINEN and CLKEN bits in the USART_CR2 register, 412 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ 413 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 414 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); 415 416 /* Enable the peripheral */ 417 __HAL_UART_ENABLE(huart); 418 419 /* Initialize the UART state */ 420 huart->ErrorCode = HAL_UART_ERROR_NONE; 421 huart->gState = HAL_UART_STATE_READY; 422 huart->RxState = HAL_UART_STATE_READY; 423 huart->RxEventType = HAL_UART_RXEVENT_TC; 424 425 return HAL_OK; 426 } 427 428 /** 429 * @brief Initializes the half-duplex mode according to the specified 430 * parameters in the UART_InitTypeDef and create the associated handle. 431 * @param huart Pointer to a UART_HandleTypeDef structure that contains 432 * the configuration information for the specified UART module. 433 * @retval HAL status 434 */ 435 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) 436 { 437 /* Check the UART handle allocation */ 438 if (huart == NULL) 439 { 440 return HAL_ERROR; 441 } 442 443 /* Check the parameters */ 444 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); 445 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); 446 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); 447 448 if (huart->gState == HAL_UART_STATE_RESET) 449 { 450 /* Allocate lock resource and initialize it */ 451 huart->Lock = HAL_UNLOCKED; 452 453 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 454 UART_InitCallbacksToDefault(huart); 455 456 if (huart->MspInitCallback == NULL) 457 { 458 huart->MspInitCallback = HAL_UART_MspInit; 459 } 460 461 /* Init the low level hardware */ 462 huart->MspInitCallback(huart); 463 #else 464 /* Init the low level hardware : GPIO, CLOCK */ 465 HAL_UART_MspInit(huart); 466 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 467 } 468 469 huart->gState = HAL_UART_STATE_BUSY; 470 471 /* Disable the peripheral */ 472 __HAL_UART_DISABLE(huart); 473 474 /* Set the UART Communication parameters */ 475 UART_SetConfig(huart); 476 477 /* In half-duplex mode, the following bits must be kept cleared: 478 - LINEN and CLKEN bits in the USART_CR2 register, 479 - SCEN and IREN bits in the USART_CR3 register.*/ 480 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 481 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); 482 483 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ 484 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); 485 486 /* Enable the peripheral */ 487 __HAL_UART_ENABLE(huart); 488 489 /* Initialize the UART state*/ 490 huart->ErrorCode = HAL_UART_ERROR_NONE; 491 huart->gState = HAL_UART_STATE_READY; 492 huart->RxState = HAL_UART_STATE_READY; 493 huart->RxEventType = HAL_UART_RXEVENT_TC; 494 495 return HAL_OK; 496 } 497 498 /** 499 * @brief Initializes the LIN mode according to the specified 500 * parameters in the UART_InitTypeDef and create the associated handle. 501 * @param huart Pointer to a UART_HandleTypeDef structure that contains 502 * the configuration information for the specified UART module. 503 * @param BreakDetectLength Specifies the LIN break detection length. 504 * This parameter can be one of the following values: 505 * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection 506 * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection 507 * @retval HAL status 508 */ 509 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) 510 { 511 /* Check the UART handle allocation */ 512 if (huart == NULL) 513 { 514 return HAL_ERROR; 515 } 516 517 /* Check the LIN UART instance */ 518 assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); 519 520 /* Check the Break detection length parameter */ 521 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); 522 assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength)); 523 assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling)); 524 525 if (huart->gState == HAL_UART_STATE_RESET) 526 { 527 /* Allocate lock resource and initialize it */ 528 huart->Lock = HAL_UNLOCKED; 529 530 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 531 UART_InitCallbacksToDefault(huart); 532 533 if (huart->MspInitCallback == NULL) 534 { 535 huart->MspInitCallback = HAL_UART_MspInit; 536 } 537 538 /* Init the low level hardware */ 539 huart->MspInitCallback(huart); 540 #else 541 /* Init the low level hardware : GPIO, CLOCK */ 542 HAL_UART_MspInit(huart); 543 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 544 } 545 546 huart->gState = HAL_UART_STATE_BUSY; 547 548 /* Disable the peripheral */ 549 __HAL_UART_DISABLE(huart); 550 551 /* Set the UART Communication parameters */ 552 UART_SetConfig(huart); 553 554 /* In LIN mode, the following bits must be kept cleared: 555 - CLKEN bits in the USART_CR2 register, 556 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ 557 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN)); 558 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); 559 560 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ 561 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); 562 563 /* Set the USART LIN Break detection length. */ 564 CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL); 565 SET_BIT(huart->Instance->CR2, BreakDetectLength); 566 567 /* Enable the peripheral */ 568 __HAL_UART_ENABLE(huart); 569 570 /* Initialize the UART state*/ 571 huart->ErrorCode = HAL_UART_ERROR_NONE; 572 huart->gState = HAL_UART_STATE_READY; 573 huart->RxState = HAL_UART_STATE_READY; 574 huart->RxEventType = HAL_UART_RXEVENT_TC; 575 576 return HAL_OK; 577 } 578 579 /** 580 * @brief Initializes the Multi-Processor mode according to the specified 581 * parameters in the UART_InitTypeDef and create the associated handle. 582 * @param huart Pointer to a UART_HandleTypeDef structure that contains 583 * the configuration information for the specified UART module. 584 * @param Address USART address 585 * @param WakeUpMethod specifies the USART wake-up method. 586 * This parameter can be one of the following values: 587 * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection 588 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark 589 * @retval HAL status 590 */ 591 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) 592 { 593 /* Check the UART handle allocation */ 594 if (huart == NULL) 595 { 596 return HAL_ERROR; 597 } 598 599 /* Check the parameters */ 600 assert_param(IS_UART_INSTANCE(huart->Instance)); 601 602 /* Check the Address & wake up method parameters */ 603 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); 604 assert_param(IS_UART_ADDRESS(Address)); 605 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); 606 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); 607 608 if (huart->gState == HAL_UART_STATE_RESET) 609 { 610 /* Allocate lock resource and initialize it */ 611 huart->Lock = HAL_UNLOCKED; 612 613 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 614 UART_InitCallbacksToDefault(huart); 615 616 if (huart->MspInitCallback == NULL) 617 { 618 huart->MspInitCallback = HAL_UART_MspInit; 619 } 620 621 /* Init the low level hardware */ 622 huart->MspInitCallback(huart); 623 #else 624 /* Init the low level hardware : GPIO, CLOCK */ 625 HAL_UART_MspInit(huart); 626 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 627 } 628 629 huart->gState = HAL_UART_STATE_BUSY; 630 631 /* Disable the peripheral */ 632 __HAL_UART_DISABLE(huart); 633 634 /* Set the UART Communication parameters */ 635 UART_SetConfig(huart); 636 637 /* In Multi-Processor mode, the following bits must be kept cleared: 638 - LINEN and CLKEN bits in the USART_CR2 register, 639 - SCEN, HDSEL and IREN bits in the USART_CR3 register */ 640 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 641 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); 642 643 /* Set the USART address node */ 644 CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD); 645 SET_BIT(huart->Instance->CR2, Address); 646 647 /* Set the wake up method by setting the WAKE bit in the CR1 register */ 648 CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE); 649 SET_BIT(huart->Instance->CR1, WakeUpMethod); 650 651 /* Enable the peripheral */ 652 __HAL_UART_ENABLE(huart); 653 654 /* Initialize the UART state */ 655 huart->ErrorCode = HAL_UART_ERROR_NONE; 656 huart->gState = HAL_UART_STATE_READY; 657 huart->RxState = HAL_UART_STATE_READY; 658 huart->RxEventType = HAL_UART_RXEVENT_TC; 659 660 return HAL_OK; 661 } 662 663 /** 664 * @brief DeInitializes the UART peripheral. 665 * @param huart Pointer to a UART_HandleTypeDef structure that contains 666 * the configuration information for the specified UART module. 667 * @retval HAL status 668 */ 669 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) 670 { 671 /* Check the UART handle allocation */ 672 if (huart == NULL) 673 { 674 return HAL_ERROR; 675 } 676 677 /* Check the parameters */ 678 assert_param(IS_UART_INSTANCE(huart->Instance)); 679 680 huart->gState = HAL_UART_STATE_BUSY; 681 682 /* Disable the Peripheral */ 683 __HAL_UART_DISABLE(huart); 684 685 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 686 if (huart->MspDeInitCallback == NULL) 687 { 688 huart->MspDeInitCallback = HAL_UART_MspDeInit; 689 } 690 /* DeInit the low level hardware */ 691 huart->MspDeInitCallback(huart); 692 #else 693 /* DeInit the low level hardware */ 694 HAL_UART_MspDeInit(huart); 695 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 696 697 huart->ErrorCode = HAL_UART_ERROR_NONE; 698 huart->gState = HAL_UART_STATE_RESET; 699 huart->RxState = HAL_UART_STATE_RESET; 700 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 701 huart->RxEventType = HAL_UART_RXEVENT_TC; 702 703 /* Process Unlock */ 704 __HAL_UNLOCK(huart); 705 706 return HAL_OK; 707 } 708 709 /** 710 * @brief UART MSP Init. 711 * @param huart Pointer to a UART_HandleTypeDef structure that contains 712 * the configuration information for the specified UART module. 713 * @retval None 714 */ 715 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) 716 { 717 /* Prevent unused argument(s) compilation warning */ 718 UNUSED(huart); 719 /* NOTE: This function should not be modified, when the callback is needed, 720 the HAL_UART_MspInit could be implemented in the user file 721 */ 722 } 723 724 /** 725 * @brief UART MSP DeInit. 726 * @param huart Pointer to a UART_HandleTypeDef structure that contains 727 * the configuration information for the specified UART module. 728 * @retval None 729 */ 730 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) 731 { 732 /* Prevent unused argument(s) compilation warning */ 733 UNUSED(huart); 734 /* NOTE: This function should not be modified, when the callback is needed, 735 the HAL_UART_MspDeInit could be implemented in the user file 736 */ 737 } 738 739 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 740 /** 741 * @brief Register a User UART Callback 742 * To be used instead of the weak predefined callback 743 * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), 744 * HAL_MultiProcessor_Init() to register callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID 745 * @param huart uart handle 746 * @param CallbackID ID of the callback to be registered 747 * This parameter can be one of the following values: 748 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 749 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID 750 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 751 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID 752 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID 753 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 754 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 755 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 756 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID 757 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID 758 * @param pCallback pointer to the Callback function 759 * @retval HAL status 760 */ 761 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, 762 pUART_CallbackTypeDef pCallback) 763 { 764 HAL_StatusTypeDef status = HAL_OK; 765 766 if (pCallback == NULL) 767 { 768 /* Update the error code */ 769 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 770 771 return HAL_ERROR; 772 } 773 774 if (huart->gState == HAL_UART_STATE_READY) 775 { 776 switch (CallbackID) 777 { 778 case HAL_UART_TX_HALFCOMPLETE_CB_ID : 779 huart->TxHalfCpltCallback = pCallback; 780 break; 781 782 case HAL_UART_TX_COMPLETE_CB_ID : 783 huart->TxCpltCallback = pCallback; 784 break; 785 786 case HAL_UART_RX_HALFCOMPLETE_CB_ID : 787 huart->RxHalfCpltCallback = pCallback; 788 break; 789 790 case HAL_UART_RX_COMPLETE_CB_ID : 791 huart->RxCpltCallback = pCallback; 792 break; 793 794 case HAL_UART_ERROR_CB_ID : 795 huart->ErrorCallback = pCallback; 796 break; 797 798 case HAL_UART_ABORT_COMPLETE_CB_ID : 799 huart->AbortCpltCallback = pCallback; 800 break; 801 802 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : 803 huart->AbortTransmitCpltCallback = pCallback; 804 break; 805 806 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : 807 huart->AbortReceiveCpltCallback = pCallback; 808 break; 809 810 case HAL_UART_MSPINIT_CB_ID : 811 huart->MspInitCallback = pCallback; 812 break; 813 814 case HAL_UART_MSPDEINIT_CB_ID : 815 huart->MspDeInitCallback = pCallback; 816 break; 817 818 default : 819 /* Update the error code */ 820 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 821 822 /* Return error status */ 823 status = HAL_ERROR; 824 break; 825 } 826 } 827 else if (huart->gState == HAL_UART_STATE_RESET) 828 { 829 switch (CallbackID) 830 { 831 case HAL_UART_MSPINIT_CB_ID : 832 huart->MspInitCallback = pCallback; 833 break; 834 835 case HAL_UART_MSPDEINIT_CB_ID : 836 huart->MspDeInitCallback = pCallback; 837 break; 838 839 default : 840 /* Update the error code */ 841 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 842 843 /* Return error status */ 844 status = HAL_ERROR; 845 break; 846 } 847 } 848 else 849 { 850 /* Update the error code */ 851 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 852 853 /* Return error status */ 854 status = HAL_ERROR; 855 } 856 857 return status; 858 } 859 860 /** 861 * @brief Unregister an UART Callback 862 * UART callaback is redirected to the weak predefined callback 863 * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), 864 * HAL_LIN_Init(), HAL_MultiProcessor_Init() to un-register callbacks for HAL_UART_MSPINIT_CB_ID 865 * and HAL_UART_MSPDEINIT_CB_ID 866 * @param huart uart handle 867 * @param CallbackID ID of the callback to be unregistered 868 * This parameter can be one of the following values: 869 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 870 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID 871 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 872 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID 873 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID 874 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 875 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 876 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 877 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID 878 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID 879 * @retval HAL status 880 */ 881 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID) 882 { 883 HAL_StatusTypeDef status = HAL_OK; 884 885 if (HAL_UART_STATE_READY == huart->gState) 886 { 887 switch (CallbackID) 888 { 889 case HAL_UART_TX_HALFCOMPLETE_CB_ID : 890 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 891 break; 892 893 case HAL_UART_TX_COMPLETE_CB_ID : 894 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ 895 break; 896 897 case HAL_UART_RX_HALFCOMPLETE_CB_ID : 898 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 899 break; 900 901 case HAL_UART_RX_COMPLETE_CB_ID : 902 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ 903 break; 904 905 case HAL_UART_ERROR_CB_ID : 906 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ 907 break; 908 909 case HAL_UART_ABORT_COMPLETE_CB_ID : 910 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 911 break; 912 913 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : 914 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ 915 break; 916 917 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : 918 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ 919 break; 920 921 case HAL_UART_MSPINIT_CB_ID : 922 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ 923 break; 924 925 case HAL_UART_MSPDEINIT_CB_ID : 926 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ 927 break; 928 929 default : 930 /* Update the error code */ 931 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 932 933 /* Return error status */ 934 status = HAL_ERROR; 935 break; 936 } 937 } 938 else if (HAL_UART_STATE_RESET == huart->gState) 939 { 940 switch (CallbackID) 941 { 942 case HAL_UART_MSPINIT_CB_ID : 943 huart->MspInitCallback = HAL_UART_MspInit; 944 break; 945 946 case HAL_UART_MSPDEINIT_CB_ID : 947 huart->MspDeInitCallback = HAL_UART_MspDeInit; 948 break; 949 950 default : 951 /* Update the error code */ 952 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 953 954 /* Return error status */ 955 status = HAL_ERROR; 956 break; 957 } 958 } 959 else 960 { 961 /* Update the error code */ 962 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 963 964 /* Return error status */ 965 status = HAL_ERROR; 966 } 967 968 return status; 969 } 970 971 /** 972 * @brief Register a User UART Rx Event Callback 973 * To be used instead of the weak predefined callback 974 * @param huart Uart handle 975 * @param pCallback Pointer to the Rx Event Callback function 976 * @retval HAL status 977 */ 978 HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback) 979 { 980 HAL_StatusTypeDef status = HAL_OK; 981 982 if (pCallback == NULL) 983 { 984 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 985 986 return HAL_ERROR; 987 } 988 989 /* Process locked */ 990 __HAL_LOCK(huart); 991 992 if (huart->gState == HAL_UART_STATE_READY) 993 { 994 huart->RxEventCallback = pCallback; 995 } 996 else 997 { 998 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 999 1000 status = HAL_ERROR; 1001 } 1002 1003 /* Release Lock */ 1004 __HAL_UNLOCK(huart); 1005 1006 return status; 1007 } 1008 1009 /** 1010 * @brief UnRegister the UART Rx Event Callback 1011 * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback 1012 * @param huart Uart handle 1013 * @retval HAL status 1014 */ 1015 HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart) 1016 { 1017 HAL_StatusTypeDef status = HAL_OK; 1018 1019 /* Process locked */ 1020 __HAL_LOCK(huart); 1021 1022 if (huart->gState == HAL_UART_STATE_READY) 1023 { 1024 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */ 1025 } 1026 else 1027 { 1028 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 1029 1030 status = HAL_ERROR; 1031 } 1032 1033 /* Release Lock */ 1034 __HAL_UNLOCK(huart); 1035 return status; 1036 } 1037 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 1038 1039 /** 1040 * @} 1041 */ 1042 1043 /** @defgroup UART_Exported_Functions_Group2 IO operation functions 1044 * @brief UART Transmit and Receive functions 1045 * 1046 @verbatim 1047 =============================================================================== 1048 ##### IO operation functions ##### 1049 =============================================================================== 1050 This subsection provides a set of functions allowing to manage the UART asynchronous 1051 and Half duplex data transfers. 1052 1053 (#) There are two modes of transfer: 1054 (+) Blocking mode: The communication is performed in polling mode. 1055 The HAL status of all data processing is returned by the same function 1056 after finishing transfer. 1057 (+) Non-Blocking mode: The communication is performed using Interrupts 1058 or DMA, these API's return the HAL status. 1059 The end of the data processing will be indicated through the 1060 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when 1061 using DMA mode. 1062 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks 1063 will be executed respectively at the end of the transmit or receive process 1064 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected. 1065 1066 (#) Blocking mode API's are : 1067 (+) HAL_UART_Transmit() 1068 (+) HAL_UART_Receive() 1069 1070 (#) Non-Blocking mode API's with Interrupt are : 1071 (+) HAL_UART_Transmit_IT() 1072 (+) HAL_UART_Receive_IT() 1073 (+) HAL_UART_IRQHandler() 1074 1075 (#) Non-Blocking mode API's with DMA are : 1076 (+) HAL_UART_Transmit_DMA() 1077 (+) HAL_UART_Receive_DMA() 1078 (+) HAL_UART_DMAPause() 1079 (+) HAL_UART_DMAResume() 1080 (+) HAL_UART_DMAStop() 1081 1082 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: 1083 (+) HAL_UART_TxHalfCpltCallback() 1084 (+) HAL_UART_TxCpltCallback() 1085 (+) HAL_UART_RxHalfCpltCallback() 1086 (+) HAL_UART_RxCpltCallback() 1087 (+) HAL_UART_ErrorCallback() 1088 1089 (#) Non-Blocking mode transfers could be aborted using Abort API's : 1090 (+) HAL_UART_Abort() 1091 (+) HAL_UART_AbortTransmit() 1092 (+) HAL_UART_AbortReceive() 1093 (+) HAL_UART_Abort_IT() 1094 (+) HAL_UART_AbortTransmit_IT() 1095 (+) HAL_UART_AbortReceive_IT() 1096 1097 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided: 1098 (+) HAL_UART_AbortCpltCallback() 1099 (+) HAL_UART_AbortTransmitCpltCallback() 1100 (+) HAL_UART_AbortReceiveCpltCallback() 1101 1102 (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services: 1103 (+) HAL_UARTEx_RxEventCallback() 1104 1105 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. 1106 Errors are handled as follows : 1107 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 1108 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . 1109 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, 1110 and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side. 1111 If user wants to abort it, Abort services should be called by user. 1112 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. 1113 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. 1114 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed. 1115 1116 -@- In the Half duplex communication, it is forbidden to run the transmit 1117 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. 1118 1119 @endverbatim 1120 * @{ 1121 */ 1122 1123 /** 1124 * @brief Sends an amount of data in blocking mode. 1125 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1126 * the sent data is handled as a set of u16. In this case, Size must indicate the number 1127 * of u16 provided through pData. 1128 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1129 * the configuration information for the specified UART module. 1130 * @param pData Pointer to data buffer (u8 or u16 data elements). 1131 * @param Size Amount of data elements (u8 or u16) to be sent 1132 * @param Timeout Timeout duration 1133 * @retval HAL status 1134 */ 1135 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) 1136 { 1137 const uint8_t *pdata8bits; 1138 const uint16_t *pdata16bits; 1139 uint32_t tickstart = 0U; 1140 1141 /* Check that a Tx process is not already ongoing */ 1142 if (huart->gState == HAL_UART_STATE_READY) 1143 { 1144 if ((pData == NULL) || (Size == 0U)) 1145 { 1146 return HAL_ERROR; 1147 } 1148 1149 huart->ErrorCode = HAL_UART_ERROR_NONE; 1150 huart->gState = HAL_UART_STATE_BUSY_TX; 1151 1152 /* Init tickstart for timeout management */ 1153 tickstart = HAL_GetTick(); 1154 1155 huart->TxXferSize = Size; 1156 huart->TxXferCount = Size; 1157 1158 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */ 1159 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 1160 { 1161 pdata8bits = NULL; 1162 pdata16bits = (const uint16_t *) pData; 1163 } 1164 else 1165 { 1166 pdata8bits = pData; 1167 pdata16bits = NULL; 1168 } 1169 1170 while (huart->TxXferCount > 0U) 1171 { 1172 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) 1173 { 1174 huart->gState = HAL_UART_STATE_READY; 1175 1176 return HAL_TIMEOUT; 1177 } 1178 if (pdata8bits == NULL) 1179 { 1180 huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU); 1181 pdata16bits++; 1182 } 1183 else 1184 { 1185 huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU); 1186 pdata8bits++; 1187 } 1188 huart->TxXferCount--; 1189 } 1190 1191 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 1192 { 1193 huart->gState = HAL_UART_STATE_READY; 1194 1195 return HAL_TIMEOUT; 1196 } 1197 1198 /* At end of Tx process, restore huart->gState to Ready */ 1199 huart->gState = HAL_UART_STATE_READY; 1200 1201 return HAL_OK; 1202 } 1203 else 1204 { 1205 return HAL_BUSY; 1206 } 1207 } 1208 1209 /** 1210 * @brief Receives an amount of data in blocking mode. 1211 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1212 * the received data is handled as a set of u16. In this case, Size must indicate the number 1213 * of u16 available through pData. 1214 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1215 * the configuration information for the specified UART module. 1216 * @param pData Pointer to data buffer (u8 or u16 data elements). 1217 * @param Size Amount of data elements (u8 or u16) to be received. 1218 * @param Timeout Timeout duration 1219 * @retval HAL status 1220 */ 1221 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 1222 { 1223 uint8_t *pdata8bits; 1224 uint16_t *pdata16bits; 1225 uint32_t tickstart = 0U; 1226 1227 /* Check that a Rx process is not already ongoing */ 1228 if (huart->RxState == HAL_UART_STATE_READY) 1229 { 1230 if ((pData == NULL) || (Size == 0U)) 1231 { 1232 return HAL_ERROR; 1233 } 1234 1235 huart->ErrorCode = HAL_UART_ERROR_NONE; 1236 huart->RxState = HAL_UART_STATE_BUSY_RX; 1237 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 1238 1239 /* Init tickstart for timeout management */ 1240 tickstart = HAL_GetTick(); 1241 1242 huart->RxXferSize = Size; 1243 huart->RxXferCount = Size; 1244 1245 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ 1246 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 1247 { 1248 pdata8bits = NULL; 1249 pdata16bits = (uint16_t *) pData; 1250 } 1251 else 1252 { 1253 pdata8bits = pData; 1254 pdata16bits = NULL; 1255 } 1256 1257 /* Check the remain data to be received */ 1258 while (huart->RxXferCount > 0U) 1259 { 1260 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 1261 { 1262 huart->RxState = HAL_UART_STATE_READY; 1263 1264 return HAL_TIMEOUT; 1265 } 1266 if (pdata8bits == NULL) 1267 { 1268 *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF); 1269 pdata16bits++; 1270 } 1271 else 1272 { 1273 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))) 1274 { 1275 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 1276 } 1277 else 1278 { 1279 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); 1280 } 1281 pdata8bits++; 1282 } 1283 huart->RxXferCount--; 1284 } 1285 1286 /* At end of Rx process, restore huart->RxState to Ready */ 1287 huart->RxState = HAL_UART_STATE_READY; 1288 1289 return HAL_OK; 1290 } 1291 else 1292 { 1293 return HAL_BUSY; 1294 } 1295 } 1296 1297 /** 1298 * @brief Sends an amount of data in non blocking mode. 1299 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1300 * the sent data is handled as a set of u16. In this case, Size must indicate the number 1301 * of u16 provided through pData. 1302 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1303 * the configuration information for the specified UART module. 1304 * @param pData Pointer to data buffer (u8 or u16 data elements). 1305 * @param Size Amount of data elements (u8 or u16) to be sent 1306 * @retval HAL status 1307 */ 1308 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) 1309 { 1310 /* Check that a Tx process is not already ongoing */ 1311 if (huart->gState == HAL_UART_STATE_READY) 1312 { 1313 if ((pData == NULL) || (Size == 0U)) 1314 { 1315 return HAL_ERROR; 1316 } 1317 1318 huart->pTxBuffPtr = pData; 1319 huart->TxXferSize = Size; 1320 huart->TxXferCount = Size; 1321 1322 huart->ErrorCode = HAL_UART_ERROR_NONE; 1323 huart->gState = HAL_UART_STATE_BUSY_TX; 1324 1325 /* Enable the UART Transmit data register empty Interrupt */ 1326 __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); 1327 1328 return HAL_OK; 1329 } 1330 else 1331 { 1332 return HAL_BUSY; 1333 } 1334 } 1335 1336 /** 1337 * @brief Receives an amount of data in non blocking mode. 1338 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1339 * the received data is handled as a set of u16. In this case, Size must indicate the number 1340 * of u16 available through pData. 1341 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1342 * the configuration information for the specified UART module. 1343 * @param pData Pointer to data buffer (u8 or u16 data elements). 1344 * @param Size Amount of data elements (u8 or u16) to be received. 1345 * @retval HAL status 1346 */ 1347 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 1348 { 1349 /* Check that a Rx process is not already ongoing */ 1350 if (huart->RxState == HAL_UART_STATE_READY) 1351 { 1352 if ((pData == NULL) || (Size == 0U)) 1353 { 1354 return HAL_ERROR; 1355 } 1356 1357 /* Set Reception type to Standard reception */ 1358 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 1359 1360 return (UART_Start_Receive_IT(huart, pData, Size)); 1361 } 1362 else 1363 { 1364 return HAL_BUSY; 1365 } 1366 } 1367 1368 /** 1369 * @brief Sends an amount of data in DMA mode. 1370 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1371 * the sent data is handled as a set of u16. In this case, Size must indicate the number 1372 * of u16 provided through pData. 1373 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1374 * the configuration information for the specified UART module. 1375 * @param pData Pointer to data buffer (u8 or u16 data elements). 1376 * @param Size Amount of data elements (u8 or u16) to be sent 1377 * @retval HAL status 1378 */ 1379 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) 1380 { 1381 const uint32_t *tmp; 1382 1383 /* Check that a Tx process is not already ongoing */ 1384 if (huart->gState == HAL_UART_STATE_READY) 1385 { 1386 if ((pData == NULL) || (Size == 0U)) 1387 { 1388 return HAL_ERROR; 1389 } 1390 1391 huart->pTxBuffPtr = pData; 1392 huart->TxXferSize = Size; 1393 huart->TxXferCount = Size; 1394 1395 huart->ErrorCode = HAL_UART_ERROR_NONE; 1396 huart->gState = HAL_UART_STATE_BUSY_TX; 1397 1398 /* Set the UART DMA transfer complete callback */ 1399 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; 1400 1401 /* Set the UART DMA Half transfer complete callback */ 1402 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; 1403 1404 /* Set the DMA error callback */ 1405 huart->hdmatx->XferErrorCallback = UART_DMAError; 1406 1407 /* Set the DMA abort callback */ 1408 huart->hdmatx->XferAbortCallback = NULL; 1409 1410 /* Enable the UART transmit DMA stream */ 1411 tmp = (const uint32_t *)&pData; 1412 HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size); 1413 1414 /* Clear the TC flag in the SR register by writing 0 to it */ 1415 __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC); 1416 1417 /* Enable the DMA transfer for transmit request by setting the DMAT bit 1418 in the UART CR3 register */ 1419 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1420 1421 return HAL_OK; 1422 } 1423 else 1424 { 1425 return HAL_BUSY; 1426 } 1427 } 1428 1429 /** 1430 * @brief Receives an amount of data in DMA mode. 1431 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 1432 * the received data is handled as a set of u16. In this case, Size must indicate the number 1433 * of u16 available through pData. 1434 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1435 * the configuration information for the specified UART module. 1436 * @param pData Pointer to data buffer (u8 or u16 data elements). 1437 * @param Size Amount of data elements (u8 or u16) to be received. 1438 * @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit. 1439 * @retval HAL status 1440 */ 1441 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 1442 { 1443 /* Check that a Rx process is not already ongoing */ 1444 if (huart->RxState == HAL_UART_STATE_READY) 1445 { 1446 if ((pData == NULL) || (Size == 0U)) 1447 { 1448 return HAL_ERROR; 1449 } 1450 1451 /* Set Reception type to Standard reception */ 1452 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 1453 1454 return (UART_Start_Receive_DMA(huart, pData, Size)); 1455 } 1456 else 1457 { 1458 return HAL_BUSY; 1459 } 1460 } 1461 1462 /** 1463 * @brief Pauses the DMA Transfer. 1464 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1465 * the configuration information for the specified UART module. 1466 * @retval HAL status 1467 */ 1468 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) 1469 { 1470 uint32_t dmarequest = 0x00U; 1471 1472 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); 1473 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) 1474 { 1475 /* Disable the UART DMA Tx request */ 1476 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1477 } 1478 1479 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); 1480 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) 1481 { 1482 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 1483 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 1484 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 1485 1486 /* Disable the UART DMA Rx request */ 1487 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 1488 } 1489 1490 return HAL_OK; 1491 } 1492 1493 /** 1494 * @brief Resumes the DMA Transfer. 1495 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1496 * the configuration information for the specified UART module. 1497 * @retval HAL status 1498 */ 1499 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) 1500 { 1501 1502 if (huart->gState == HAL_UART_STATE_BUSY_TX) 1503 { 1504 /* Enable the UART DMA Tx request */ 1505 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1506 } 1507 1508 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 1509 { 1510 /* Clear the Overrun flag before resuming the Rx transfer*/ 1511 __HAL_UART_CLEAR_OREFLAG(huart); 1512 1513 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ 1514 if (huart->Init.Parity != UART_PARITY_NONE) 1515 { 1516 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 1517 } 1518 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 1519 1520 /* Enable the UART DMA Rx request */ 1521 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 1522 } 1523 1524 return HAL_OK; 1525 } 1526 1527 /** 1528 * @brief Stops the DMA Transfer. 1529 * @param huart Pointer to a UART_HandleTypeDef structure that contains 1530 * the configuration information for the specified UART module. 1531 * @retval HAL status 1532 */ 1533 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) 1534 { 1535 uint32_t dmarequest = 0x00U; 1536 /* The Lock is not implemented on this API to allow the user application 1537 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): 1538 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated 1539 and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() 1540 */ 1541 1542 /* Stop UART DMA Tx request if ongoing */ 1543 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); 1544 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) 1545 { 1546 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1547 1548 /* Abort the UART DMA Tx stream */ 1549 if (huart->hdmatx != NULL) 1550 { 1551 HAL_DMA_Abort(huart->hdmatx); 1552 } 1553 UART_EndTxTransfer(huart); 1554 } 1555 1556 /* Stop UART DMA Rx request if ongoing */ 1557 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); 1558 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) 1559 { 1560 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 1561 1562 /* Abort the UART DMA Rx stream */ 1563 if (huart->hdmarx != NULL) 1564 { 1565 HAL_DMA_Abort(huart->hdmarx); 1566 } 1567 UART_EndRxTransfer(huart); 1568 } 1569 1570 return HAL_OK; 1571 } 1572 1573 /** 1574 * @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs. 1575 * @note HAL_OK is returned if reception is completed (expected number of data has been received) 1576 * or if reception is stopped after IDLE event (less than the expected number of data has been received) 1577 * In this case, RxLen output parameter indicates number of data available in reception buffer. 1578 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01), 1579 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 1580 * of uint16_t available through pData. 1581 * @param huart UART handle. 1582 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 1583 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 1584 * @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event) 1585 * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence). 1586 * @retval HAL status 1587 */ 1588 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, 1589 uint32_t Timeout) 1590 { 1591 uint8_t *pdata8bits; 1592 uint16_t *pdata16bits; 1593 uint32_t tickstart; 1594 1595 /* Check that a Rx process is not already ongoing */ 1596 if (huart->RxState == HAL_UART_STATE_READY) 1597 { 1598 if ((pData == NULL) || (Size == 0U)) 1599 { 1600 return HAL_ERROR; 1601 } 1602 1603 huart->ErrorCode = HAL_UART_ERROR_NONE; 1604 huart->RxState = HAL_UART_STATE_BUSY_RX; 1605 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 1606 huart->RxEventType = HAL_UART_RXEVENT_TC; 1607 1608 /* Init tickstart for timeout management */ 1609 tickstart = HAL_GetTick(); 1610 1611 huart->RxXferSize = Size; 1612 huart->RxXferCount = Size; 1613 1614 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ 1615 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 1616 { 1617 pdata8bits = NULL; 1618 pdata16bits = (uint16_t *) pData; 1619 } 1620 else 1621 { 1622 pdata8bits = pData; 1623 pdata16bits = NULL; 1624 } 1625 1626 /* Initialize output number of received elements */ 1627 *RxLen = 0U; 1628 1629 /* as long as data have to be received */ 1630 while (huart->RxXferCount > 0U) 1631 { 1632 /* Check if IDLE flag is set */ 1633 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) 1634 { 1635 /* Clear IDLE flag in ISR */ 1636 __HAL_UART_CLEAR_IDLEFLAG(huart); 1637 1638 /* If Set, but no data ever received, clear flag without exiting loop */ 1639 /* If Set, and data has already been received, this means Idle Event is valid : End reception */ 1640 if (*RxLen > 0U) 1641 { 1642 huart->RxEventType = HAL_UART_RXEVENT_IDLE; 1643 huart->RxState = HAL_UART_STATE_READY; 1644 1645 return HAL_OK; 1646 } 1647 } 1648 1649 /* Check if RXNE flag is set */ 1650 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) 1651 { 1652 if (pdata8bits == NULL) 1653 { 1654 *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); 1655 pdata16bits++; 1656 } 1657 else 1658 { 1659 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))) 1660 { 1661 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 1662 } 1663 else 1664 { 1665 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); 1666 } 1667 1668 pdata8bits++; 1669 } 1670 /* Increment number of received elements */ 1671 *RxLen += 1U; 1672 huart->RxXferCount--; 1673 } 1674 1675 /* Check for the Timeout */ 1676 if (Timeout != HAL_MAX_DELAY) 1677 { 1678 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 1679 { 1680 huart->RxState = HAL_UART_STATE_READY; 1681 1682 return HAL_TIMEOUT; 1683 } 1684 } 1685 } 1686 1687 /* Set number of received elements in output parameter : RxLen */ 1688 *RxLen = huart->RxXferSize - huart->RxXferCount; 1689 /* At end of Rx process, restore huart->RxState to Ready */ 1690 huart->RxState = HAL_UART_STATE_READY; 1691 1692 return HAL_OK; 1693 } 1694 else 1695 { 1696 return HAL_BUSY; 1697 } 1698 } 1699 1700 /** 1701 * @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs. 1702 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 1703 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating 1704 * number of received data elements. 1705 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01), 1706 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 1707 * of uint16_t available through pData. 1708 * @param huart UART handle. 1709 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 1710 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 1711 * @retval HAL status 1712 */ 1713 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 1714 { 1715 HAL_StatusTypeDef status; 1716 1717 /* Check that a Rx process is not already ongoing */ 1718 if (huart->RxState == HAL_UART_STATE_READY) 1719 { 1720 if ((pData == NULL) || (Size == 0U)) 1721 { 1722 return HAL_ERROR; 1723 } 1724 1725 /* Set Reception type to reception till IDLE Event*/ 1726 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 1727 huart->RxEventType = HAL_UART_RXEVENT_TC; 1728 1729 status = UART_Start_Receive_IT(huart, pData, Size); 1730 1731 /* Check Rx process has been successfully started */ 1732 if (status == HAL_OK) 1733 { 1734 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 1735 { 1736 __HAL_UART_CLEAR_IDLEFLAG(huart); 1737 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 1738 } 1739 else 1740 { 1741 /* In case of errors already pending when reception is started, 1742 Interrupts may have already been raised and lead to reception abortion. 1743 (Overrun error for instance). 1744 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 1745 status = HAL_ERROR; 1746 } 1747 } 1748 1749 return status; 1750 } 1751 else 1752 { 1753 return HAL_BUSY; 1754 } 1755 } 1756 1757 /** 1758 * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs. 1759 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 1760 * to DMA services, transferring automatically received data elements in user reception buffer and 1761 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider 1762 * reception phase as ended. In all cases, callback execution will indicate number of received data elements. 1763 * @note When the UART parity is enabled (PCE = 1), the received data contain 1764 * the parity bit (MSB position). 1765 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01), 1766 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 1767 * of uint16_t available through pData. 1768 * @param huart UART handle. 1769 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 1770 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 1771 * @retval HAL status 1772 */ 1773 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 1774 { 1775 HAL_StatusTypeDef status; 1776 1777 /* Check that a Rx process is not already ongoing */ 1778 if (huart->RxState == HAL_UART_STATE_READY) 1779 { 1780 if ((pData == NULL) || (Size == 0U)) 1781 { 1782 return HAL_ERROR; 1783 } 1784 1785 /* Set Reception type to reception till IDLE Event*/ 1786 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 1787 huart->RxEventType = HAL_UART_RXEVENT_TC; 1788 1789 status = UART_Start_Receive_DMA(huart, pData, Size); 1790 1791 /* Check Rx process has been successfully started */ 1792 if (status == HAL_OK) 1793 { 1794 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 1795 { 1796 __HAL_UART_CLEAR_IDLEFLAG(huart); 1797 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 1798 } 1799 else 1800 { 1801 /* In case of errors already pending when reception is started, 1802 Interrupts may have already been raised and lead to reception abortion. 1803 (Overrun error for instance). 1804 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 1805 status = HAL_ERROR; 1806 } 1807 } 1808 1809 return status; 1810 } 1811 else 1812 { 1813 return HAL_BUSY; 1814 } 1815 } 1816 1817 /** 1818 * @brief Provide Rx Event type that has lead to RxEvent callback execution. 1819 * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress 1820 * of reception process is provided to application through calls of Rx Event callback (either default one 1821 * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event, 1822 * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead 1823 * to Rx Event callback execution. 1824 * @note This function is expected to be called within the user implementation of Rx Event Callback, 1825 * in order to provide the accurate value : 1826 * In Interrupt Mode : 1827 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) 1828 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of 1829 * received data is lower than expected one) 1830 * In DMA Mode : 1831 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) 1832 * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received 1833 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of 1834 * received data is lower than expected one). 1835 * In DMA mode, RxEvent callback could be called several times; 1836 * When DMA is configured in Normal Mode, HT event does not stop Reception process; 1837 * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process; 1838 * @param huart UART handle. 1839 * @retval Rx Event Type (returned value will be a value of @ref UART_RxEvent_Type_Values) 1840 */ 1841 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart) 1842 { 1843 /* Return Rx Event type value, as stored in UART handle */ 1844 return(huart->RxEventType); 1845 } 1846 1847 /** 1848 * @brief Abort ongoing transfers (blocking mode). 1849 * @param huart UART handle. 1850 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 1851 * This procedure performs following operations : 1852 * - Disable UART Interrupts (Tx and Rx) 1853 * - Disable the DMA transfer in the peripheral register (if enabled) 1854 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 1855 * - Set handle State to READY 1856 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 1857 * @retval HAL status 1858 */ 1859 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) 1860 { 1861 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 1862 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 1863 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 1864 1865 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 1866 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 1867 { 1868 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 1869 } 1870 1871 /* Disable the UART DMA Tx request if enabled */ 1872 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 1873 { 1874 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1875 1876 /* Abort the UART DMA Tx stream: use blocking DMA Abort API (no callback) */ 1877 if (huart->hdmatx != NULL) 1878 { 1879 /* Set the UART DMA Abort callback to Null. 1880 No call back execution at end of DMA abort procedure */ 1881 huart->hdmatx->XferAbortCallback = NULL; 1882 1883 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) 1884 { 1885 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) 1886 { 1887 /* Set error code to DMA */ 1888 huart->ErrorCode = HAL_UART_ERROR_DMA; 1889 1890 return HAL_TIMEOUT; 1891 } 1892 } 1893 } 1894 } 1895 1896 /* Disable the UART DMA Rx request if enabled */ 1897 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 1898 { 1899 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 1900 1901 /* Abort the UART DMA Rx stream: use blocking DMA Abort API (no callback) */ 1902 if (huart->hdmarx != NULL) 1903 { 1904 /* Set the UART DMA Abort callback to Null. 1905 No call back execution at end of DMA abort procedure */ 1906 huart->hdmarx->XferAbortCallback = NULL; 1907 1908 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) 1909 { 1910 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) 1911 { 1912 /* Set error code to DMA */ 1913 huart->ErrorCode = HAL_UART_ERROR_DMA; 1914 1915 return HAL_TIMEOUT; 1916 } 1917 } 1918 } 1919 } 1920 1921 /* Reset Tx and Rx transfer counters */ 1922 huart->TxXferCount = 0x00U; 1923 huart->RxXferCount = 0x00U; 1924 1925 /* Reset ErrorCode */ 1926 huart->ErrorCode = HAL_UART_ERROR_NONE; 1927 1928 /* Restore huart->RxState and huart->gState to Ready */ 1929 huart->RxState = HAL_UART_STATE_READY; 1930 huart->gState = HAL_UART_STATE_READY; 1931 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 1932 1933 return HAL_OK; 1934 } 1935 1936 /** 1937 * @brief Abort ongoing Transmit transfer (blocking mode). 1938 * @param huart UART handle. 1939 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 1940 * This procedure performs following operations : 1941 * - Disable UART Interrupts (Tx) 1942 * - Disable the DMA transfer in the peripheral register (if enabled) 1943 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 1944 * - Set handle State to READY 1945 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 1946 * @retval HAL status 1947 */ 1948 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) 1949 { 1950 /* Disable TXEIE and TCIE interrupts */ 1951 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 1952 1953 /* Disable the UART DMA Tx request if enabled */ 1954 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 1955 { 1956 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 1957 1958 /* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */ 1959 if (huart->hdmatx != NULL) 1960 { 1961 /* Set the UART DMA Abort callback to Null. 1962 No call back execution at end of DMA abort procedure */ 1963 huart->hdmatx->XferAbortCallback = NULL; 1964 1965 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) 1966 { 1967 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) 1968 { 1969 /* Set error code to DMA */ 1970 huart->ErrorCode = HAL_UART_ERROR_DMA; 1971 1972 return HAL_TIMEOUT; 1973 } 1974 } 1975 } 1976 } 1977 1978 /* Reset Tx transfer counter */ 1979 huart->TxXferCount = 0x00U; 1980 1981 /* Restore huart->gState to Ready */ 1982 huart->gState = HAL_UART_STATE_READY; 1983 1984 return HAL_OK; 1985 } 1986 1987 /** 1988 * @brief Abort ongoing Receive transfer (blocking mode). 1989 * @param huart UART handle. 1990 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 1991 * This procedure performs following operations : 1992 * - Disable UART Interrupts (Rx) 1993 * - Disable the DMA transfer in the peripheral register (if enabled) 1994 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 1995 * - Set handle State to READY 1996 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 1997 * @retval HAL status 1998 */ 1999 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) 2000 { 2001 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 2002 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 2003 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 2004 2005 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 2006 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 2007 { 2008 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 2009 } 2010 2011 /* Disable the UART DMA Rx request if enabled */ 2012 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2013 { 2014 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 2015 2016 /* Abort the UART DMA Rx stream : use blocking DMA Abort API (no callback) */ 2017 if (huart->hdmarx != NULL) 2018 { 2019 /* Set the UART DMA Abort callback to Null. 2020 No call back execution at end of DMA abort procedure */ 2021 huart->hdmarx->XferAbortCallback = NULL; 2022 2023 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) 2024 { 2025 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) 2026 { 2027 /* Set error code to DMA */ 2028 huart->ErrorCode = HAL_UART_ERROR_DMA; 2029 2030 return HAL_TIMEOUT; 2031 } 2032 } 2033 } 2034 } 2035 2036 /* Reset Rx transfer counter */ 2037 huart->RxXferCount = 0x00U; 2038 2039 /* Restore huart->RxState to Ready */ 2040 huart->RxState = HAL_UART_STATE_READY; 2041 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2042 2043 return HAL_OK; 2044 } 2045 2046 /** 2047 * @brief Abort ongoing transfers (Interrupt mode). 2048 * @param huart UART handle. 2049 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 2050 * This procedure performs following operations : 2051 * - Disable UART Interrupts (Tx and Rx) 2052 * - Disable the DMA transfer in the peripheral register (if enabled) 2053 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 2054 * - Set handle State to READY 2055 * - At abort completion, call user abort complete callback 2056 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 2057 * considered as completed only when user abort complete callback is executed (not when exiting function). 2058 * @retval HAL status 2059 */ 2060 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) 2061 { 2062 uint32_t AbortCplt = 0x01U; 2063 2064 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 2065 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 2066 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 2067 2068 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 2069 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 2070 { 2071 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 2072 } 2073 2074 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised 2075 before any call to DMA Abort functions */ 2076 /* DMA Tx Handle is valid */ 2077 if (huart->hdmatx != NULL) 2078 { 2079 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. 2080 Otherwise, set it to NULL */ 2081 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 2082 { 2083 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; 2084 } 2085 else 2086 { 2087 huart->hdmatx->XferAbortCallback = NULL; 2088 } 2089 } 2090 /* DMA Rx Handle is valid */ 2091 if (huart->hdmarx != NULL) 2092 { 2093 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. 2094 Otherwise, set it to NULL */ 2095 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2096 { 2097 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; 2098 } 2099 else 2100 { 2101 huart->hdmarx->XferAbortCallback = NULL; 2102 } 2103 } 2104 2105 /* Disable the UART DMA Tx request if enabled */ 2106 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 2107 { 2108 /* Disable DMA Tx at UART level */ 2109 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 2110 2111 /* Abort the UART DMA Tx stream : use non blocking DMA Abort API (callback) */ 2112 if (huart->hdmatx != NULL) 2113 { 2114 /* UART Tx DMA Abort callback has already been initialised : 2115 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 2116 2117 /* Abort DMA TX */ 2118 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) 2119 { 2120 huart->hdmatx->XferAbortCallback = NULL; 2121 } 2122 else 2123 { 2124 AbortCplt = 0x00U; 2125 } 2126 } 2127 } 2128 2129 /* Disable the UART DMA Rx request if enabled */ 2130 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2131 { 2132 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 2133 2134 /* Abort the UART DMA Rx stream : use non blocking DMA Abort API (callback) */ 2135 if (huart->hdmarx != NULL) 2136 { 2137 /* UART Rx DMA Abort callback has already been initialised : 2138 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 2139 2140 /* Abort DMA RX */ 2141 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 2142 { 2143 huart->hdmarx->XferAbortCallback = NULL; 2144 AbortCplt = 0x01U; 2145 } 2146 else 2147 { 2148 AbortCplt = 0x00U; 2149 } 2150 } 2151 } 2152 2153 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ 2154 if (AbortCplt == 0x01U) 2155 { 2156 /* Reset Tx and Rx transfer counters */ 2157 huart->TxXferCount = 0x00U; 2158 huart->RxXferCount = 0x00U; 2159 2160 /* Reset ErrorCode */ 2161 huart->ErrorCode = HAL_UART_ERROR_NONE; 2162 2163 /* Restore huart->gState and huart->RxState to Ready */ 2164 huart->gState = HAL_UART_STATE_READY; 2165 huart->RxState = HAL_UART_STATE_READY; 2166 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2167 2168 /* As no DMA to be aborted, call directly user Abort complete callback */ 2169 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2170 /* Call registered Abort complete callback */ 2171 huart->AbortCpltCallback(huart); 2172 #else 2173 /* Call legacy weak Abort complete callback */ 2174 HAL_UART_AbortCpltCallback(huart); 2175 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2176 } 2177 2178 return HAL_OK; 2179 } 2180 2181 /** 2182 * @brief Abort ongoing Transmit transfer (Interrupt mode). 2183 * @param huart UART handle. 2184 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 2185 * This procedure performs following operations : 2186 * - Disable UART Interrupts (Tx) 2187 * - Disable the DMA transfer in the peripheral register (if enabled) 2188 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 2189 * - Set handle State to READY 2190 * - At abort completion, call user abort complete callback 2191 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 2192 * considered as completed only when user abort complete callback is executed (not when exiting function). 2193 * @retval HAL status 2194 */ 2195 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) 2196 { 2197 /* Disable TXEIE and TCIE interrupts */ 2198 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 2199 2200 /* Disable the UART DMA Tx request if enabled */ 2201 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 2202 { 2203 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 2204 2205 /* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */ 2206 if (huart->hdmatx != NULL) 2207 { 2208 /* Set the UART DMA Abort callback : 2209 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 2210 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; 2211 2212 /* Abort DMA TX */ 2213 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) 2214 { 2215 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ 2216 huart->hdmatx->XferAbortCallback(huart->hdmatx); 2217 } 2218 } 2219 else 2220 { 2221 /* Reset Tx transfer counter */ 2222 huart->TxXferCount = 0x00U; 2223 2224 /* Restore huart->gState to Ready */ 2225 huart->gState = HAL_UART_STATE_READY; 2226 2227 /* As no DMA to be aborted, call directly user Abort complete callback */ 2228 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2229 /* Call registered Abort Transmit Complete Callback */ 2230 huart->AbortTransmitCpltCallback(huart); 2231 #else 2232 /* Call legacy weak Abort Transmit Complete Callback */ 2233 HAL_UART_AbortTransmitCpltCallback(huart); 2234 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2235 } 2236 } 2237 else 2238 { 2239 /* Reset Tx transfer counter */ 2240 huart->TxXferCount = 0x00U; 2241 2242 /* Restore huart->gState to Ready */ 2243 huart->gState = HAL_UART_STATE_READY; 2244 2245 /* As no DMA to be aborted, call directly user Abort complete callback */ 2246 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2247 /* Call registered Abort Transmit Complete Callback */ 2248 huart->AbortTransmitCpltCallback(huart); 2249 #else 2250 /* Call legacy weak Abort Transmit Complete Callback */ 2251 HAL_UART_AbortTransmitCpltCallback(huart); 2252 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2253 } 2254 2255 return HAL_OK; 2256 } 2257 2258 /** 2259 * @brief Abort ongoing Receive transfer (Interrupt mode). 2260 * @param huart UART handle. 2261 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 2262 * This procedure performs following operations : 2263 * - Disable UART Interrupts (Rx) 2264 * - Disable the DMA transfer in the peripheral register (if enabled) 2265 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 2266 * - Set handle State to READY 2267 * - At abort completion, call user abort complete callback 2268 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 2269 * considered as completed only when user abort complete callback is executed (not when exiting function). 2270 * @retval HAL status 2271 */ 2272 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) 2273 { 2274 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 2275 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 2276 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 2277 2278 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 2279 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 2280 { 2281 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 2282 } 2283 2284 /* Disable the UART DMA Rx request if enabled */ 2285 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2286 { 2287 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 2288 2289 /* Abort the UART DMA Rx stream : use blocking DMA Abort API (no callback) */ 2290 if (huart->hdmarx != NULL) 2291 { 2292 /* Set the UART DMA Abort callback : 2293 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 2294 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; 2295 2296 /* Abort DMA RX */ 2297 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 2298 { 2299 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ 2300 huart->hdmarx->XferAbortCallback(huart->hdmarx); 2301 } 2302 } 2303 else 2304 { 2305 /* Reset Rx transfer counter */ 2306 huart->RxXferCount = 0x00U; 2307 2308 /* Restore huart->RxState to Ready */ 2309 huart->RxState = HAL_UART_STATE_READY; 2310 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2311 2312 /* As no DMA to be aborted, call directly user Abort complete callback */ 2313 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2314 /* Call registered Abort Receive Complete Callback */ 2315 huart->AbortReceiveCpltCallback(huart); 2316 #else 2317 /* Call legacy weak Abort Receive Complete Callback */ 2318 HAL_UART_AbortReceiveCpltCallback(huart); 2319 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2320 } 2321 } 2322 else 2323 { 2324 /* Reset Rx transfer counter */ 2325 huart->RxXferCount = 0x00U; 2326 2327 /* Restore huart->RxState to Ready */ 2328 huart->RxState = HAL_UART_STATE_READY; 2329 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2330 2331 /* As no DMA to be aborted, call directly user Abort complete callback */ 2332 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2333 /* Call registered Abort Receive Complete Callback */ 2334 huart->AbortReceiveCpltCallback(huart); 2335 #else 2336 /* Call legacy weak Abort Receive Complete Callback */ 2337 HAL_UART_AbortReceiveCpltCallback(huart); 2338 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2339 } 2340 2341 return HAL_OK; 2342 } 2343 2344 /** 2345 * @brief This function handles UART interrupt request. 2346 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2347 * the configuration information for the specified UART module. 2348 * @retval None 2349 */ 2350 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 2351 { 2352 uint32_t isrflags = READ_REG(huart->Instance->SR); 2353 uint32_t cr1its = READ_REG(huart->Instance->CR1); 2354 uint32_t cr3its = READ_REG(huart->Instance->CR3); 2355 uint32_t errorflags = 0x00U; 2356 uint32_t dmarequest = 0x00U; 2357 2358 /* If no error occurs */ 2359 errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); 2360 if (errorflags == RESET) 2361 { 2362 /* UART in mode Receiver -------------------------------------------------*/ 2363 if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 2364 { 2365 UART_Receive_IT(huart); 2366 return; 2367 } 2368 } 2369 2370 /* If some errors occur */ 2371 if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) 2372 || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) 2373 { 2374 /* UART parity error interrupt occurred ----------------------------------*/ 2375 if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) 2376 { 2377 huart->ErrorCode |= HAL_UART_ERROR_PE; 2378 } 2379 2380 /* UART noise error interrupt occurred -----------------------------------*/ 2381 if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 2382 { 2383 huart->ErrorCode |= HAL_UART_ERROR_NE; 2384 } 2385 2386 /* UART frame error interrupt occurred -----------------------------------*/ 2387 if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 2388 { 2389 huart->ErrorCode |= HAL_UART_ERROR_FE; 2390 } 2391 2392 /* UART Over-Run interrupt occurred --------------------------------------*/ 2393 if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) 2394 || ((cr3its & USART_CR3_EIE) != RESET))) 2395 { 2396 huart->ErrorCode |= HAL_UART_ERROR_ORE; 2397 } 2398 2399 /* Call UART Error Call back function if need be --------------------------*/ 2400 if (huart->ErrorCode != HAL_UART_ERROR_NONE) 2401 { 2402 /* UART in mode Receiver -----------------------------------------------*/ 2403 if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 2404 { 2405 UART_Receive_IT(huart); 2406 } 2407 2408 /* If Overrun error occurs, or if any error occurs in DMA mode reception, 2409 consider error as blocking */ 2410 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); 2411 if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest) 2412 { 2413 /* Blocking error : transfer is aborted 2414 Set the UART state ready to be able to start again the process, 2415 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ 2416 UART_EndRxTransfer(huart); 2417 2418 /* Disable the UART DMA Rx request if enabled */ 2419 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2420 { 2421 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 2422 2423 /* Abort the UART DMA Rx stream */ 2424 if (huart->hdmarx != NULL) 2425 { 2426 /* Set the UART DMA Abort callback : 2427 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ 2428 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; 2429 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 2430 { 2431 /* Call Directly XferAbortCallback function in case of error */ 2432 huart->hdmarx->XferAbortCallback(huart->hdmarx); 2433 } 2434 } 2435 else 2436 { 2437 /* Call user error callback */ 2438 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2439 /*Call registered error callback*/ 2440 huart->ErrorCallback(huart); 2441 #else 2442 /*Call legacy weak error callback*/ 2443 HAL_UART_ErrorCallback(huart); 2444 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2445 } 2446 } 2447 else 2448 { 2449 /* Call user error callback */ 2450 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2451 /*Call registered error callback*/ 2452 huart->ErrorCallback(huart); 2453 #else 2454 /*Call legacy weak error callback*/ 2455 HAL_UART_ErrorCallback(huart); 2456 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2457 } 2458 } 2459 else 2460 { 2461 /* Non Blocking error : transfer could go on. 2462 Error is notified to user through user error callback */ 2463 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2464 /*Call registered error callback*/ 2465 huart->ErrorCallback(huart); 2466 #else 2467 /*Call legacy weak error callback*/ 2468 HAL_UART_ErrorCallback(huart); 2469 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2470 2471 huart->ErrorCode = HAL_UART_ERROR_NONE; 2472 } 2473 } 2474 return; 2475 } /* End if some error occurs */ 2476 2477 /* Check current reception Mode : 2478 If Reception till IDLE event has been selected : */ 2479 if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 2480 && ((isrflags & USART_SR_IDLE) != 0U) 2481 && ((cr1its & USART_SR_IDLE) != 0U)) 2482 { 2483 __HAL_UART_CLEAR_IDLEFLAG(huart); 2484 2485 /* Check if DMA mode is enabled in UART */ 2486 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 2487 { 2488 /* DMA mode enabled */ 2489 /* Check received length : If all expected data are received, do nothing, 2490 (DMA cplt callback will be called). 2491 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ 2492 uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx); 2493 if ((nb_remaining_rx_data > 0U) 2494 && (nb_remaining_rx_data < huart->RxXferSize)) 2495 { 2496 /* Reception is not complete */ 2497 huart->RxXferCount = nb_remaining_rx_data; 2498 2499 /* In Normal mode, end DMA xfer and HAL UART Rx process*/ 2500 if (huart->hdmarx->Init.Mode != DMA_CIRCULAR) 2501 { 2502 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 2503 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 2504 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 2505 2506 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 2507 in the UART CR3 register */ 2508 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 2509 2510 /* At end of Rx process, restore huart->RxState to Ready */ 2511 huart->RxState = HAL_UART_STATE_READY; 2512 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2513 2514 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 2515 2516 /* Last bytes received, so no need as the abort is immediate */ 2517 (void)HAL_DMA_Abort(huart->hdmarx); 2518 } 2519 2520 /* Initialize type of RxEvent that correspond to RxEvent callback execution; 2521 In this case, Rx Event type is Idle Event */ 2522 huart->RxEventType = HAL_UART_RXEVENT_IDLE; 2523 2524 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2525 /*Call registered Rx Event callback*/ 2526 huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); 2527 #else 2528 /*Call legacy weak Rx Event callback*/ 2529 HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); 2530 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2531 } 2532 return; 2533 } 2534 else 2535 { 2536 /* DMA mode not enabled */ 2537 /* Check received length : If all expected data are received, do nothing. 2538 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ 2539 uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount; 2540 if ((huart->RxXferCount > 0U) 2541 && (nb_rx_data > 0U)) 2542 { 2543 /* Disable the UART Parity Error Interrupt and RXNE interrupts */ 2544 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 2545 2546 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 2547 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 2548 2549 /* Rx process is completed, restore huart->RxState to Ready */ 2550 huart->RxState = HAL_UART_STATE_READY; 2551 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 2552 2553 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 2554 2555 /* Initialize type of RxEvent that correspond to RxEvent callback execution; 2556 In this case, Rx Event type is Idle Event */ 2557 huart->RxEventType = HAL_UART_RXEVENT_IDLE; 2558 2559 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2560 /*Call registered Rx complete callback*/ 2561 huart->RxEventCallback(huart, nb_rx_data); 2562 #else 2563 /*Call legacy weak Rx Event callback*/ 2564 HAL_UARTEx_RxEventCallback(huart, nb_rx_data); 2565 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2566 } 2567 return; 2568 } 2569 } 2570 2571 /* UART in mode Transmitter ------------------------------------------------*/ 2572 if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) 2573 { 2574 UART_Transmit_IT(huart); 2575 return; 2576 } 2577 2578 /* UART in mode Transmitter end --------------------------------------------*/ 2579 if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) 2580 { 2581 UART_EndTransmit_IT(huart); 2582 return; 2583 } 2584 } 2585 2586 /** 2587 * @brief Tx Transfer completed callbacks. 2588 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2589 * the configuration information for the specified UART module. 2590 * @retval None 2591 */ 2592 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) 2593 { 2594 /* Prevent unused argument(s) compilation warning */ 2595 UNUSED(huart); 2596 /* NOTE: This function should not be modified, when the callback is needed, 2597 the HAL_UART_TxCpltCallback could be implemented in the user file 2598 */ 2599 } 2600 2601 /** 2602 * @brief Tx Half Transfer completed callbacks. 2603 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2604 * the configuration information for the specified UART module. 2605 * @retval None 2606 */ 2607 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) 2608 { 2609 /* Prevent unused argument(s) compilation warning */ 2610 UNUSED(huart); 2611 /* NOTE: This function should not be modified, when the callback is needed, 2612 the HAL_UART_TxHalfCpltCallback could be implemented in the user file 2613 */ 2614 } 2615 2616 /** 2617 * @brief Rx Transfer completed callbacks. 2618 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2619 * the configuration information for the specified UART module. 2620 * @retval None 2621 */ 2622 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 2623 { 2624 /* Prevent unused argument(s) compilation warning */ 2625 UNUSED(huart); 2626 /* NOTE: This function should not be modified, when the callback is needed, 2627 the HAL_UART_RxCpltCallback could be implemented in the user file 2628 */ 2629 } 2630 2631 /** 2632 * @brief Rx Half Transfer completed callbacks. 2633 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2634 * the configuration information for the specified UART module. 2635 * @retval None 2636 */ 2637 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) 2638 { 2639 /* Prevent unused argument(s) compilation warning */ 2640 UNUSED(huart); 2641 /* NOTE: This function should not be modified, when the callback is needed, 2642 the HAL_UART_RxHalfCpltCallback could be implemented in the user file 2643 */ 2644 } 2645 2646 /** 2647 * @brief UART error callbacks. 2648 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2649 * the configuration information for the specified UART module. 2650 * @retval None 2651 */ 2652 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) 2653 { 2654 /* Prevent unused argument(s) compilation warning */ 2655 UNUSED(huart); 2656 /* NOTE: This function should not be modified, when the callback is needed, 2657 the HAL_UART_ErrorCallback could be implemented in the user file 2658 */ 2659 } 2660 2661 /** 2662 * @brief UART Abort Complete callback. 2663 * @param huart UART handle. 2664 * @retval None 2665 */ 2666 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) 2667 { 2668 /* Prevent unused argument(s) compilation warning */ 2669 UNUSED(huart); 2670 2671 /* NOTE : This function should not be modified, when the callback is needed, 2672 the HAL_UART_AbortCpltCallback can be implemented in the user file. 2673 */ 2674 } 2675 2676 /** 2677 * @brief UART Abort Complete callback. 2678 * @param huart UART handle. 2679 * @retval None 2680 */ 2681 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) 2682 { 2683 /* Prevent unused argument(s) compilation warning */ 2684 UNUSED(huart); 2685 2686 /* NOTE : This function should not be modified, when the callback is needed, 2687 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. 2688 */ 2689 } 2690 2691 /** 2692 * @brief UART Abort Receive Complete callback. 2693 * @param huart UART handle. 2694 * @retval None 2695 */ 2696 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) 2697 { 2698 /* Prevent unused argument(s) compilation warning */ 2699 UNUSED(huart); 2700 2701 /* NOTE : This function should not be modified, when the callback is needed, 2702 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. 2703 */ 2704 } 2705 2706 /** 2707 * @brief Reception Event Callback (Rx event notification called after use of advanced reception service). 2708 * @param huart UART handle 2709 * @param Size Number of data available in application reception buffer (indicates a position in 2710 * reception buffer until which, data are available) 2711 * @retval None 2712 */ 2713 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) 2714 { 2715 /* Prevent unused argument(s) compilation warning */ 2716 UNUSED(huart); 2717 UNUSED(Size); 2718 2719 /* NOTE : This function should not be modified, when the callback is needed, 2720 the HAL_UARTEx_RxEventCallback can be implemented in the user file. 2721 */ 2722 } 2723 2724 /** 2725 * @} 2726 */ 2727 2728 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions 2729 * @brief UART control functions 2730 * 2731 @verbatim 2732 ============================================================================== 2733 ##### Peripheral Control functions ##### 2734 ============================================================================== 2735 [..] 2736 This subsection provides a set of functions allowing to control the UART: 2737 (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character. 2738 (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode. 2739 (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software. 2740 (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode 2741 (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode 2742 2743 @endverbatim 2744 * @{ 2745 */ 2746 2747 /** 2748 * @brief Transmits break characters. 2749 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2750 * the configuration information for the specified UART module. 2751 * @retval HAL status 2752 */ 2753 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) 2754 { 2755 /* Check the parameters */ 2756 assert_param(IS_UART_INSTANCE(huart->Instance)); 2757 2758 /* Process Locked */ 2759 __HAL_LOCK(huart); 2760 2761 huart->gState = HAL_UART_STATE_BUSY; 2762 2763 /* Send break characters */ 2764 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK); 2765 2766 huart->gState = HAL_UART_STATE_READY; 2767 2768 /* Process Unlocked */ 2769 __HAL_UNLOCK(huart); 2770 2771 return HAL_OK; 2772 } 2773 2774 /** 2775 * @brief Enters the UART in mute mode. 2776 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2777 * the configuration information for the specified UART module. 2778 * @retval HAL status 2779 */ 2780 HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) 2781 { 2782 /* Check the parameters */ 2783 assert_param(IS_UART_INSTANCE(huart->Instance)); 2784 2785 /* Process Locked */ 2786 __HAL_LOCK(huart); 2787 2788 huart->gState = HAL_UART_STATE_BUSY; 2789 2790 /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ 2791 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RWU); 2792 2793 huart->gState = HAL_UART_STATE_READY; 2794 huart->RxEventType = HAL_UART_RXEVENT_TC; 2795 2796 /* Process Unlocked */ 2797 __HAL_UNLOCK(huart); 2798 2799 return HAL_OK; 2800 } 2801 2802 /** 2803 * @brief Exits the UART mute mode: wake up software. 2804 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2805 * the configuration information for the specified UART module. 2806 * @retval HAL status 2807 */ 2808 HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart) 2809 { 2810 /* Check the parameters */ 2811 assert_param(IS_UART_INSTANCE(huart->Instance)); 2812 2813 /* Process Locked */ 2814 __HAL_LOCK(huart); 2815 2816 huart->gState = HAL_UART_STATE_BUSY; 2817 2818 /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ 2819 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU); 2820 2821 huart->gState = HAL_UART_STATE_READY; 2822 huart->RxEventType = HAL_UART_RXEVENT_TC; 2823 2824 /* Process Unlocked */ 2825 __HAL_UNLOCK(huart); 2826 2827 return HAL_OK; 2828 } 2829 2830 /** 2831 * @brief Enables the UART transmitter and disables the UART receiver. 2832 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2833 * the configuration information for the specified UART module. 2834 * @retval HAL status 2835 */ 2836 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) 2837 { 2838 uint32_t tmpreg = 0x00U; 2839 2840 /* Process Locked */ 2841 __HAL_LOCK(huart); 2842 2843 huart->gState = HAL_UART_STATE_BUSY; 2844 2845 /*-------------------------- USART CR1 Configuration -----------------------*/ 2846 tmpreg = huart->Instance->CR1; 2847 2848 /* Clear TE and RE bits */ 2849 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); 2850 2851 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ 2852 tmpreg |= (uint32_t)USART_CR1_TE; 2853 2854 /* Write to USART CR1 */ 2855 WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg); 2856 2857 huart->gState = HAL_UART_STATE_READY; 2858 2859 /* Process Unlocked */ 2860 __HAL_UNLOCK(huart); 2861 2862 return HAL_OK; 2863 } 2864 2865 /** 2866 * @brief Enables the UART receiver and disables the UART transmitter. 2867 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2868 * the configuration information for the specified UART module. 2869 * @retval HAL status 2870 */ 2871 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) 2872 { 2873 uint32_t tmpreg = 0x00U; 2874 2875 /* Process Locked */ 2876 __HAL_LOCK(huart); 2877 2878 huart->gState = HAL_UART_STATE_BUSY; 2879 2880 /*-------------------------- USART CR1 Configuration -----------------------*/ 2881 tmpreg = huart->Instance->CR1; 2882 2883 /* Clear TE and RE bits */ 2884 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); 2885 2886 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ 2887 tmpreg |= (uint32_t)USART_CR1_RE; 2888 2889 /* Write to USART CR1 */ 2890 WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg); 2891 2892 huart->gState = HAL_UART_STATE_READY; 2893 2894 /* Process Unlocked */ 2895 __HAL_UNLOCK(huart); 2896 2897 return HAL_OK; 2898 } 2899 2900 /** 2901 * @} 2902 */ 2903 2904 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions 2905 * @brief UART State and Errors functions 2906 * 2907 @verbatim 2908 ============================================================================== 2909 ##### Peripheral State and Errors functions ##### 2910 ============================================================================== 2911 [..] 2912 This subsection provides a set of functions allowing to return the State of 2913 UART communication process, return Peripheral Errors occurred during communication 2914 process 2915 (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral. 2916 (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication. 2917 2918 @endverbatim 2919 * @{ 2920 */ 2921 2922 /** 2923 * @brief Returns the UART state. 2924 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2925 * the configuration information for the specified UART module. 2926 * @retval HAL state 2927 */ 2928 HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart) 2929 { 2930 uint32_t temp1 = 0x00U, temp2 = 0x00U; 2931 temp1 = huart->gState; 2932 temp2 = huart->RxState; 2933 2934 return (HAL_UART_StateTypeDef)(temp1 | temp2); 2935 } 2936 2937 /** 2938 * @brief Return the UART error code 2939 * @param huart Pointer to a UART_HandleTypeDef structure that contains 2940 * the configuration information for the specified UART. 2941 * @retval UART Error Code 2942 */ 2943 uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart) 2944 { 2945 return huart->ErrorCode; 2946 } 2947 2948 /** 2949 * @} 2950 */ 2951 2952 /** 2953 * @} 2954 */ 2955 2956 /** @defgroup UART_Private_Functions UART Private Functions 2957 * @{ 2958 */ 2959 2960 /** 2961 * @brief Initialize the callbacks to their default values. 2962 * @param huart UART handle. 2963 * @retval none 2964 */ 2965 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 2966 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart) 2967 { 2968 /* Init the UART Callback settings */ 2969 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 2970 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ 2971 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 2972 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ 2973 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ 2974 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 2975 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ 2976 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ 2977 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */ 2978 2979 } 2980 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 2981 2982 /** 2983 * @brief DMA UART transmit process complete callback. 2984 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 2985 * the configuration information for the specified DMA module. 2986 * @retval None 2987 */ 2988 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) 2989 { 2990 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 2991 /* DMA Normal mode*/ 2992 if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) 2993 { 2994 huart->TxXferCount = 0x00U; 2995 2996 /* Disable the DMA transfer for transmit request by setting the DMAT bit 2997 in the UART CR3 register */ 2998 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 2999 3000 /* Enable the UART Transmit Complete Interrupt */ 3001 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 3002 3003 } 3004 /* DMA Circular mode */ 3005 else 3006 { 3007 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3008 /*Call registered Tx complete callback*/ 3009 huart->TxCpltCallback(huart); 3010 #else 3011 /*Call legacy weak Tx complete callback*/ 3012 HAL_UART_TxCpltCallback(huart); 3013 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3014 } 3015 } 3016 3017 /** 3018 * @brief DMA UART transmit process half complete callback 3019 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3020 * the configuration information for the specified DMA module. 3021 * @retval None 3022 */ 3023 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 3024 { 3025 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3026 3027 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3028 /*Call registered Tx complete callback*/ 3029 huart->TxHalfCpltCallback(huart); 3030 #else 3031 /*Call legacy weak Tx complete callback*/ 3032 HAL_UART_TxHalfCpltCallback(huart); 3033 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3034 } 3035 3036 /** 3037 * @brief DMA UART receive process complete callback. 3038 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3039 * the configuration information for the specified DMA module. 3040 * @retval None 3041 */ 3042 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 3043 { 3044 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3045 3046 /* DMA Normal mode*/ 3047 if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) 3048 { 3049 huart->RxXferCount = 0U; 3050 3051 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 3052 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 3053 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 3054 3055 /* Disable the DMA transfer for the receiver request by setting the DMAR bit 3056 in the UART CR3 register */ 3057 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 3058 3059 /* At end of Rx process, restore huart->RxState to Ready */ 3060 huart->RxState = HAL_UART_STATE_READY; 3061 3062 /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ 3063 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 3064 { 3065 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 3066 } 3067 } 3068 3069 /* Initialize type of RxEvent that correspond to RxEvent callback execution; 3070 In this case, Rx Event type is Transfer Complete */ 3071 huart->RxEventType = HAL_UART_RXEVENT_TC; 3072 3073 /* Check current reception Mode : 3074 If Reception till IDLE event has been selected : use Rx Event callback */ 3075 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 3076 { 3077 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3078 /*Call registered Rx Event callback*/ 3079 huart->RxEventCallback(huart, huart->RxXferSize); 3080 #else 3081 /*Call legacy weak Rx Event callback*/ 3082 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 3083 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3084 } 3085 else 3086 { 3087 /* In other cases : use Rx Complete callback */ 3088 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3089 /*Call registered Rx complete callback*/ 3090 huart->RxCpltCallback(huart); 3091 #else 3092 /*Call legacy weak Rx complete callback*/ 3093 HAL_UART_RxCpltCallback(huart); 3094 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3095 } 3096 } 3097 3098 /** 3099 * @brief DMA UART receive process half complete callback 3100 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3101 * the configuration information for the specified DMA module. 3102 * @retval None 3103 */ 3104 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 3105 { 3106 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3107 3108 /* Initialize type of RxEvent that correspond to RxEvent callback execution; 3109 In this case, Rx Event type is Half Transfer */ 3110 huart->RxEventType = HAL_UART_RXEVENT_HT; 3111 3112 /* Check current reception Mode : 3113 If Reception till IDLE event has been selected : use Rx Event callback */ 3114 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 3115 { 3116 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3117 /*Call registered Rx Event callback*/ 3118 huart->RxEventCallback(huart, huart->RxXferSize / 2U); 3119 #else 3120 /*Call legacy weak Rx Event callback*/ 3121 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U); 3122 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3123 } 3124 else 3125 { 3126 /* In other cases : use Rx Half Complete callback */ 3127 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3128 /*Call registered Rx Half complete callback*/ 3129 huart->RxHalfCpltCallback(huart); 3130 #else 3131 /*Call legacy weak Rx Half complete callback*/ 3132 HAL_UART_RxHalfCpltCallback(huart); 3133 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3134 } 3135 } 3136 3137 /** 3138 * @brief DMA UART communication error callback. 3139 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3140 * the configuration information for the specified DMA module. 3141 * @retval None 3142 */ 3143 static void UART_DMAError(DMA_HandleTypeDef *hdma) 3144 { 3145 uint32_t dmarequest = 0x00U; 3146 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3147 3148 /* Stop UART DMA Tx request if ongoing */ 3149 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); 3150 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) 3151 { 3152 huart->TxXferCount = 0x00U; 3153 UART_EndTxTransfer(huart); 3154 } 3155 3156 /* Stop UART DMA Rx request if ongoing */ 3157 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); 3158 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) 3159 { 3160 huart->RxXferCount = 0x00U; 3161 UART_EndRxTransfer(huart); 3162 } 3163 3164 huart->ErrorCode |= HAL_UART_ERROR_DMA; 3165 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3166 /*Call registered error callback*/ 3167 huart->ErrorCallback(huart); 3168 #else 3169 /*Call legacy weak error callback*/ 3170 HAL_UART_ErrorCallback(huart); 3171 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3172 } 3173 3174 /** 3175 * @brief This function handles UART Communication Timeout. It waits 3176 * until a flag is no longer in the specified status. 3177 * @param huart Pointer to a UART_HandleTypeDef structure that contains 3178 * the configuration information for the specified UART module. 3179 * @param Flag specifies the UART flag to check. 3180 * @param Status The actual Flag status (SET or RESET). 3181 * @param Tickstart Tick start value 3182 * @param Timeout Timeout duration 3183 * @retval HAL status 3184 */ 3185 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, 3186 uint32_t Tickstart, uint32_t Timeout) 3187 { 3188 /* Wait until flag is set */ 3189 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) 3190 { 3191 /* Check for the Timeout */ 3192 if (Timeout != HAL_MAX_DELAY) 3193 { 3194 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 3195 { 3196 3197 return HAL_TIMEOUT; 3198 } 3199 3200 if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC)) 3201 { 3202 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET) 3203 { 3204 /* Clear Overrun Error flag*/ 3205 __HAL_UART_CLEAR_OREFLAG(huart); 3206 3207 /* Blocking error : transfer is aborted 3208 Set the UART state ready to be able to start again the process, 3209 Disable Rx Interrupts if ongoing */ 3210 UART_EndRxTransfer(huart); 3211 3212 huart->ErrorCode = HAL_UART_ERROR_ORE; 3213 3214 /* Process Unlocked */ 3215 __HAL_UNLOCK(huart); 3216 3217 return HAL_ERROR; 3218 } 3219 } 3220 } 3221 } 3222 return HAL_OK; 3223 } 3224 3225 /** 3226 * @brief Start Receive operation in interrupt mode. 3227 * @note This function could be called by all HAL UART API providing reception in Interrupt mode. 3228 * @note When calling this function, parameters validity is considered as already checked, 3229 * i.e. Rx State, buffer address, ... 3230 * UART Handle is assumed as Locked. 3231 * @param huart UART handle. 3232 * @param pData Pointer to data buffer (u8 or u16 data elements). 3233 * @param Size Amount of data elements (u8 or u16) to be received. 3234 * @retval HAL status 3235 */ 3236 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 3237 { 3238 huart->pRxBuffPtr = pData; 3239 huart->RxXferSize = Size; 3240 huart->RxXferCount = Size; 3241 3242 huart->ErrorCode = HAL_UART_ERROR_NONE; 3243 huart->RxState = HAL_UART_STATE_BUSY_RX; 3244 3245 if (huart->Init.Parity != UART_PARITY_NONE) 3246 { 3247 /* Enable the UART Parity Error Interrupt */ 3248 __HAL_UART_ENABLE_IT(huart, UART_IT_PE); 3249 } 3250 3251 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 3252 __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); 3253 3254 /* Enable the UART Data Register not empty Interrupt */ 3255 __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); 3256 3257 return HAL_OK; 3258 } 3259 3260 /** 3261 * @brief Start Receive operation in DMA mode. 3262 * @note This function could be called by all HAL UART API providing reception in DMA mode. 3263 * @note When calling this function, parameters validity is considered as already checked, 3264 * i.e. Rx State, buffer address, ... 3265 * UART Handle is assumed as Locked. 3266 * @param huart UART handle. 3267 * @param pData Pointer to data buffer (u8 or u16 data elements). 3268 * @param Size Amount of data elements (u8 or u16) to be received. 3269 * @retval HAL status 3270 */ 3271 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 3272 { 3273 uint32_t *tmp; 3274 3275 huart->pRxBuffPtr = pData; 3276 huart->RxXferSize = Size; 3277 3278 huart->ErrorCode = HAL_UART_ERROR_NONE; 3279 huart->RxState = HAL_UART_STATE_BUSY_RX; 3280 3281 /* Set the UART DMA transfer complete callback */ 3282 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; 3283 3284 /* Set the UART DMA Half transfer complete callback */ 3285 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; 3286 3287 /* Set the DMA error callback */ 3288 huart->hdmarx->XferErrorCallback = UART_DMAError; 3289 3290 /* Set the DMA abort callback */ 3291 huart->hdmarx->XferAbortCallback = NULL; 3292 3293 /* Enable the DMA stream */ 3294 tmp = (uint32_t *)&pData; 3295 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size); 3296 3297 /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */ 3298 __HAL_UART_CLEAR_OREFLAG(huart); 3299 3300 if (huart->Init.Parity != UART_PARITY_NONE) 3301 { 3302 /* Enable the UART Parity Error Interrupt */ 3303 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 3304 } 3305 3306 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 3307 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 3308 3309 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 3310 in the UART CR3 register */ 3311 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 3312 3313 return HAL_OK; 3314 } 3315 3316 /** 3317 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). 3318 * @param huart UART handle. 3319 * @retval None 3320 */ 3321 static void UART_EndTxTransfer(UART_HandleTypeDef *huart) 3322 { 3323 /* Disable TXEIE and TCIE interrupts */ 3324 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 3325 3326 /* At end of Tx process, restore huart->gState to Ready */ 3327 huart->gState = HAL_UART_STATE_READY; 3328 } 3329 3330 /** 3331 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). 3332 * @param huart UART handle. 3333 * @retval None 3334 */ 3335 static void UART_EndRxTransfer(UART_HandleTypeDef *huart) 3336 { 3337 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 3338 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 3339 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 3340 3341 /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */ 3342 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 3343 { 3344 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 3345 } 3346 3347 /* At end of Rx process, restore huart->RxState to Ready */ 3348 huart->RxState = HAL_UART_STATE_READY; 3349 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 3350 } 3351 3352 /** 3353 * @brief DMA UART communication abort callback, when initiated by HAL services on Error 3354 * (To be called at end of DMA Abort procedure following error occurrence). 3355 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3356 * the configuration information for the specified DMA module. 3357 * @retval None 3358 */ 3359 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) 3360 { 3361 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3362 huart->RxXferCount = 0x00U; 3363 huart->TxXferCount = 0x00U; 3364 3365 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3366 /*Call registered error callback*/ 3367 huart->ErrorCallback(huart); 3368 #else 3369 /*Call legacy weak error callback*/ 3370 HAL_UART_ErrorCallback(huart); 3371 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3372 } 3373 3374 /** 3375 * @brief DMA UART Tx communication abort callback, when initiated by user 3376 * (To be called at end of DMA Tx Abort procedure following user abort request). 3377 * @note When this callback is executed, User Abort complete call back is called only if no 3378 * Abort still ongoing for Rx DMA Handle. 3379 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3380 * the configuration information for the specified DMA module. 3381 * @retval None 3382 */ 3383 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) 3384 { 3385 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3386 3387 huart->hdmatx->XferAbortCallback = NULL; 3388 3389 /* Check if an Abort process is still ongoing */ 3390 if (huart->hdmarx != NULL) 3391 { 3392 if (huart->hdmarx->XferAbortCallback != NULL) 3393 { 3394 return; 3395 } 3396 } 3397 3398 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 3399 huart->TxXferCount = 0x00U; 3400 huart->RxXferCount = 0x00U; 3401 3402 /* Reset ErrorCode */ 3403 huart->ErrorCode = HAL_UART_ERROR_NONE; 3404 3405 /* Restore huart->gState and huart->RxState to Ready */ 3406 huart->gState = HAL_UART_STATE_READY; 3407 huart->RxState = HAL_UART_STATE_READY; 3408 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 3409 3410 /* Call user Abort complete callback */ 3411 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3412 /* Call registered Abort complete callback */ 3413 huart->AbortCpltCallback(huart); 3414 #else 3415 /* Call legacy weak Abort complete callback */ 3416 HAL_UART_AbortCpltCallback(huart); 3417 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3418 } 3419 3420 /** 3421 * @brief DMA UART Rx communication abort callback, when initiated by user 3422 * (To be called at end of DMA Rx Abort procedure following user abort request). 3423 * @note When this callback is executed, User Abort complete call back is called only if no 3424 * Abort still ongoing for Tx DMA Handle. 3425 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3426 * the configuration information for the specified DMA module. 3427 * @retval None 3428 */ 3429 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) 3430 { 3431 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3432 3433 huart->hdmarx->XferAbortCallback = NULL; 3434 3435 /* Check if an Abort process is still ongoing */ 3436 if (huart->hdmatx != NULL) 3437 { 3438 if (huart->hdmatx->XferAbortCallback != NULL) 3439 { 3440 return; 3441 } 3442 } 3443 3444 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 3445 huart->TxXferCount = 0x00U; 3446 huart->RxXferCount = 0x00U; 3447 3448 /* Reset ErrorCode */ 3449 huart->ErrorCode = HAL_UART_ERROR_NONE; 3450 3451 /* Restore huart->gState and huart->RxState to Ready */ 3452 huart->gState = HAL_UART_STATE_READY; 3453 huart->RxState = HAL_UART_STATE_READY; 3454 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 3455 3456 /* Call user Abort complete callback */ 3457 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3458 /* Call registered Abort complete callback */ 3459 huart->AbortCpltCallback(huart); 3460 #else 3461 /* Call legacy weak Abort complete callback */ 3462 HAL_UART_AbortCpltCallback(huart); 3463 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3464 } 3465 3466 /** 3467 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to 3468 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) 3469 * (This callback is executed at end of DMA Tx Abort procedure following user abort request, 3470 * and leads to user Tx Abort Complete callback execution). 3471 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3472 * the configuration information for the specified DMA module. 3473 * @retval None 3474 */ 3475 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 3476 { 3477 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3478 3479 huart->TxXferCount = 0x00U; 3480 3481 /* Restore huart->gState to Ready */ 3482 huart->gState = HAL_UART_STATE_READY; 3483 3484 /* Call user Abort complete callback */ 3485 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3486 /* Call registered Abort Transmit Complete Callback */ 3487 huart->AbortTransmitCpltCallback(huart); 3488 #else 3489 /* Call legacy weak Abort Transmit Complete Callback */ 3490 HAL_UART_AbortTransmitCpltCallback(huart); 3491 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3492 } 3493 3494 /** 3495 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to 3496 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) 3497 * (This callback is executed at end of DMA Rx Abort procedure following user abort request, 3498 * and leads to user Rx Abort Complete callback execution). 3499 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 3500 * the configuration information for the specified DMA module. 3501 * @retval None 3502 */ 3503 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 3504 { 3505 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 3506 3507 huart->RxXferCount = 0x00U; 3508 3509 /* Restore huart->RxState to Ready */ 3510 huart->RxState = HAL_UART_STATE_READY; 3511 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 3512 3513 /* Call user Abort complete callback */ 3514 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3515 /* Call registered Abort Receive Complete Callback */ 3516 huart->AbortReceiveCpltCallback(huart); 3517 #else 3518 /* Call legacy weak Abort Receive Complete Callback */ 3519 HAL_UART_AbortReceiveCpltCallback(huart); 3520 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3521 } 3522 3523 /** 3524 * @brief Sends an amount of data in non blocking mode. 3525 * @param huart Pointer to a UART_HandleTypeDef structure that contains 3526 * the configuration information for the specified UART module. 3527 * @retval HAL status 3528 */ 3529 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) 3530 { 3531 const uint16_t *tmp; 3532 3533 /* Check that a Tx process is ongoing */ 3534 if (huart->gState == HAL_UART_STATE_BUSY_TX) 3535 { 3536 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 3537 { 3538 tmp = (const uint16_t *) huart->pTxBuffPtr; 3539 huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); 3540 huart->pTxBuffPtr += 2U; 3541 } 3542 else 3543 { 3544 huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF); 3545 } 3546 3547 if (--huart->TxXferCount == 0U) 3548 { 3549 /* Disable the UART Transmit Data Register Empty Interrupt */ 3550 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); 3551 3552 /* Enable the UART Transmit Complete Interrupt */ 3553 __HAL_UART_ENABLE_IT(huart, UART_IT_TC); 3554 } 3555 return HAL_OK; 3556 } 3557 else 3558 { 3559 return HAL_BUSY; 3560 } 3561 } 3562 3563 /** 3564 * @brief Wraps up transmission in non blocking mode. 3565 * @param huart Pointer to a UART_HandleTypeDef structure that contains 3566 * the configuration information for the specified UART module. 3567 * @retval HAL status 3568 */ 3569 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) 3570 { 3571 /* Disable the UART Transmit Complete Interrupt */ 3572 __HAL_UART_DISABLE_IT(huart, UART_IT_TC); 3573 3574 /* Tx process is ended, restore huart->gState to Ready */ 3575 huart->gState = HAL_UART_STATE_READY; 3576 3577 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3578 /*Call registered Tx complete callback*/ 3579 huart->TxCpltCallback(huart); 3580 #else 3581 /*Call legacy weak Tx complete callback*/ 3582 HAL_UART_TxCpltCallback(huart); 3583 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3584 3585 return HAL_OK; 3586 } 3587 3588 /** 3589 * @brief Receives an amount of data in non blocking mode 3590 * @param huart Pointer to a UART_HandleTypeDef structure that contains 3591 * the configuration information for the specified UART module. 3592 * @retval HAL status 3593 */ 3594 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) 3595 { 3596 uint8_t *pdata8bits; 3597 uint16_t *pdata16bits; 3598 3599 /* Check that a Rx process is ongoing */ 3600 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 3601 { 3602 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 3603 { 3604 pdata8bits = NULL; 3605 pdata16bits = (uint16_t *) huart->pRxBuffPtr; 3606 *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); 3607 huart->pRxBuffPtr += 2U; 3608 } 3609 else 3610 { 3611 pdata8bits = (uint8_t *) huart->pRxBuffPtr; 3612 pdata16bits = NULL; 3613 3614 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))) 3615 { 3616 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 3617 } 3618 else 3619 { 3620 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); 3621 } 3622 huart->pRxBuffPtr += 1U; 3623 } 3624 3625 if (--huart->RxXferCount == 0U) 3626 { 3627 /* Disable the UART Data Register not empty Interrupt */ 3628 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); 3629 3630 /* Disable the UART Parity Error Interrupt */ 3631 __HAL_UART_DISABLE_IT(huart, UART_IT_PE); 3632 3633 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 3634 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); 3635 3636 /* Rx process is completed, restore huart->RxState to Ready */ 3637 huart->RxState = HAL_UART_STATE_READY; 3638 3639 /* Initialize type of RxEvent to Transfer Complete */ 3640 huart->RxEventType = HAL_UART_RXEVENT_TC; 3641 3642 /* Check current reception Mode : 3643 If Reception till IDLE event has been selected : */ 3644 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 3645 { 3646 /* Set reception type to Standard */ 3647 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 3648 3649 /* Disable IDLE interrupt */ 3650 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 3651 3652 /* Check if IDLE flag is set */ 3653 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) 3654 { 3655 /* Clear IDLE flag in ISR */ 3656 __HAL_UART_CLEAR_IDLEFLAG(huart); 3657 } 3658 3659 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3660 /*Call registered Rx Event callback*/ 3661 huart->RxEventCallback(huart, huart->RxXferSize); 3662 #else 3663 /*Call legacy weak Rx Event callback*/ 3664 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 3665 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3666 } 3667 else 3668 { 3669 /* Standard reception API called */ 3670 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 3671 /*Call registered Rx complete callback*/ 3672 huart->RxCpltCallback(huart); 3673 #else 3674 /*Call legacy weak Rx complete callback*/ 3675 HAL_UART_RxCpltCallback(huart); 3676 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 3677 } 3678 3679 return HAL_OK; 3680 } 3681 return HAL_OK; 3682 } 3683 else 3684 { 3685 return HAL_BUSY; 3686 } 3687 } 3688 3689 /** 3690 * @brief Configures the UART peripheral. 3691 * @param huart Pointer to a UART_HandleTypeDef structure that contains 3692 * the configuration information for the specified UART module. 3693 * @retval None 3694 */ 3695 static void UART_SetConfig(UART_HandleTypeDef *huart) 3696 { 3697 uint32_t tmpreg; 3698 uint32_t pclk; 3699 3700 /* Check the parameters */ 3701 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); 3702 assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); 3703 assert_param(IS_UART_PARITY(huart->Init.Parity)); 3704 assert_param(IS_UART_MODE(huart->Init.Mode)); 3705 3706 /*-------------------------- USART CR2 Configuration -----------------------*/ 3707 /* Configure the UART Stop Bits: Set STOP[13:12] bits 3708 according to huart->Init.StopBits value */ 3709 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); 3710 3711 /*-------------------------- USART CR1 Configuration -----------------------*/ 3712 /* Configure the UART Word Length, Parity and mode: 3713 Set the M bits according to huart->Init.WordLength value 3714 Set PCE and PS bits according to huart->Init.Parity value 3715 Set TE and RE bits according to huart->Init.Mode value 3716 Set OVER8 bit according to huart->Init.OverSampling value */ 3717 3718 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling; 3719 MODIFY_REG(huart->Instance->CR1, 3720 (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8), 3721 tmpreg); 3722 3723 /*-------------------------- USART CR3 Configuration -----------------------*/ 3724 /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */ 3725 MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl); 3726 3727 3728 #if defined(USART6) && defined(UART9) && defined(UART10) 3729 if ((huart->Instance == USART1) || (huart->Instance == USART6) || (huart->Instance == UART9) || (huart->Instance == UART10)) 3730 { 3731 pclk = HAL_RCC_GetPCLK2Freq(); 3732 } 3733 #elif defined(USART6) 3734 if ((huart->Instance == USART1) || (huart->Instance == USART6)) 3735 { 3736 pclk = HAL_RCC_GetPCLK2Freq(); 3737 } 3738 #else 3739 if (huart->Instance == USART1) 3740 { 3741 pclk = HAL_RCC_GetPCLK2Freq(); 3742 } 3743 #endif /* USART6 */ 3744 else 3745 { 3746 pclk = HAL_RCC_GetPCLK1Freq(); 3747 } 3748 /*-------------------------- USART BRR Configuration ---------------------*/ 3749 if (huart->Init.OverSampling == UART_OVERSAMPLING_8) 3750 { 3751 huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate); 3752 } 3753 else 3754 { 3755 huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate); 3756 } 3757 } 3758 3759 /** 3760 * @} 3761 */ 3762 3763 #endif /* HAL_UART_MODULE_ENABLED */ 3764 /** 3765 * @} 3766 */ 3767 3768 /** 3769 * @} 3770 */ 3771